Devicetree
 help / color / mirror / Atom feed
* [PATCH v2 05/18] mfd: madera: Register map tables for Cirrus Logic CS47L85
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones, broonie, linus.walleij, gnurou, robh+dt, tglx, jason
  Cc: alsa-devel, patches, linux-gpio, devicetree, linux-kernel
In-Reply-To: <1493050124-5970-1-git-send-email-rf@opensource.wolfsonmicro.com>

Regmap configuration tables for Cirrus Logic CS47L85 codecs.

Signed-off-by: Nariman Poushin <nariman@opensource.wolfsonmicro.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
Changes since V1:
- select PINCTRL build option from here instead of having PINCTRL
  derive it using a "default y if" formula

 drivers/mfd/Kconfig          |    7 +
 drivers/mfd/Makefile         |    3 +
 drivers/mfd/cs47l85-tables.c | 3169 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 3179 insertions(+)
 create mode 100644 drivers/mfd/cs47l85-tables.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 918b2a2..bfcafc2 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -239,6 +239,13 @@ config MFD_CS47L35
 	help
 	  Support for Cirrus Logic CS47L35 Smart Codec
 
+config MFD_CS47L85
+	bool "Cirrus Logic CS47L85"
+	select PINCTRL_CS47L85
+	depends on MFD_MADERA
+	help
+	  Support for Cirrus Logic CS47L85 Smart Codec
+
 config MFD_ASIC3
 	bool "Compaq ASIC3"
 	depends on GPIOLIB && ARM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 5cd0b72..e522774 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -76,6 +76,9 @@ obj-$(CONFIG_MFD_MADERA)	+= madera-core.o
 ifeq ($(CONFIG_MFD_CS47L35),y)
 obj-$(CONFIG_MFD_MADERA)	+= cs47l35-tables.o
 endif
+ifeq ($(CONFIG_MFD_CS47L85),y)
+obj-$(CONFIG_MFD_MADERA)	+= cs47l85-tables.o
+endif
 obj-$(CONFIG_MFD_MADERA_I2C)	+= madera-i2c.o
 obj-$(CONFIG_MFD_MADERA_SPI)	+= madera-spi.o
 
diff --git a/drivers/mfd/cs47l85-tables.c b/drivers/mfd/cs47l85-tables.c
new file mode 100644
index 0000000..92512d5
--- /dev/null
+++ b/drivers/mfd/cs47l85-tables.c
@@ -0,0 +1,3169 @@
+/*
+ * Regmap tables for CS47L85 codec
+ *
+ * Copyright 2015-2016 Cirrus Logic
+ *
+ * Author: Nariman Poushin <nariman@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/registers.h>
+
+#include "madera.h"
+
+static const struct reg_sequence cs47l85_reva_16_patch[] = {
+	{ 0x80,  0x0003 },
+	{ 0x213, 0x03E4 },
+	{ 0x177, 0x0281 },
+	{ 0x197, 0x0281 },
+	{ 0x1B7, 0x0281 },
+	{ 0x4B1, 0x010A },
+	{ 0x4CF, 0x0933 },
+	{ 0x36C, 0x011B },
+	{ 0x4B8, 0x1120 },
+	{ 0x4A0, 0x3280 },
+	{ 0x4A1, 0x3200 },
+	{ 0x4A2, 0x3200 },
+	{ 0x441, 0xC050 },
+	{ 0x4A4, 0x000B },
+	{ 0x4A5, 0x000B },
+	{ 0x4A6, 0x000B },
+	{ 0x4E2, 0x1E1D },
+	{ 0x4E3, 0x1E1D },
+	{ 0x4E4, 0x1E1D },
+	{ 0x293, 0x0080 },
+	{ 0x17D, 0x0303 },
+	{ 0x19D, 0x0303 },
+	{ 0x27E, 0x0000 },
+	{ 0x80,  0x0000 },
+	{ 0x80,  0x0000 },
+	{ 0x448, 0x003f },
+};
+
+static const struct reg_sequence cs47l85_revc_16_patch[] = {
+	{ 0x27E, 0x0000 },
+	{ 0x2C2, 0x0005 },
+	{ 0x448, 0x003f },
+};
+
+static const struct reg_sequence cs47l85_reva_32_patch[] = {
+	{ 0x3000, 0xC2253632 },
+	{ 0x3002, 0xC2300001 },
+	{ 0x3004, 0x8225100E },
+	{ 0x3006, 0x22251803 },
+	{ 0x3008, 0x82310B00 },
+	{ 0x300A, 0xE231023B },
+	{ 0x300C, 0x02313B01 },
+	{ 0x300E, 0x62300000 },
+	{ 0x3010, 0xE2314288 },
+	{ 0x3012, 0x02310B00 },
+	{ 0x3014, 0x02310B00 },
+	{ 0x3016, 0x04050100 },
+	{ 0x3018, 0x42310C02 },
+	{ 0x301A, 0xE2310227 },
+	{ 0x301C, 0x02313B01 },
+	{ 0x301E, 0xE2314266 },
+	{ 0x3020, 0xE2315294 },
+	{ 0x3022, 0x02310B00 },
+	{ 0x3024, 0x02310B00 },
+	{ 0x3026, 0x02251100 },
+	{ 0x3028, 0x02251401 },
+	{ 0x302A, 0x02250200 },
+	{ 0x302C, 0x02251001 },
+	{ 0x302E, 0x02250200 },
+	{ 0x3030, 0xE2310266 },
+	{ 0x3032, 0x82314B15 },
+	{ 0x3034, 0x82310B15 },
+	{ 0x3036, 0xE2315294 },
+	{ 0x3038, 0x02310B00 },
+	{ 0x303A, 0x8225160D },
+	{ 0x303C, 0x0225F501 },
+	{ 0x303E, 0x8225061C },
+	{ 0x3040, 0x02251000 },
+	{ 0x3042, 0x04051101 },
+	{ 0x3044, 0x02251800 },
+	{ 0x3046, 0x42251203 },
+	{ 0x3048, 0x02251101 },
+	{ 0x304A, 0xC2251300 },
+	{ 0x304C, 0x2225FB02 },
+	{ 0x3050, 0xC2263632 },
+	{ 0x3052, 0xC2300001 },
+	{ 0x3054, 0x8226100E },
+	{ 0x3056, 0x22261803 },
+	{ 0x3058, 0x82310B02 },
+	{ 0x305A, 0xE231023B },
+	{ 0x305C, 0x02313B01 },
+	{ 0x305E, 0x62300000 },
+	{ 0x3060, 0xE2314288 },
+	{ 0x3062, 0x02310B00 },
+	{ 0x3064, 0x02310B00 },
+	{ 0x3066, 0x04050000 },
+	{ 0x3068, 0x42310C03 },
+	{ 0x306A, 0xE2310227 },
+	{ 0x306C, 0x02313B01 },
+	{ 0x306E, 0xE2314266 },
+	{ 0x3070, 0xE2315294 },
+	{ 0x3072, 0x02310B00 },
+	{ 0x3074, 0x02310B00 },
+	{ 0x3076, 0x02261100 },
+	{ 0x3078, 0x02261401 },
+	{ 0x307A, 0x02260200 },
+	{ 0x307C, 0x02261001 },
+	{ 0x307E, 0x02260200 },
+	{ 0x3080, 0xE2310266 },
+	{ 0x3082, 0x82314B17 },
+	{ 0x3084, 0x82310B17 },
+	{ 0x3086, 0xE2315294 },
+	{ 0x3088, 0x02310B00 },
+	{ 0x308A, 0x8226160D },
+	{ 0x308C, 0x0226F501 },
+	{ 0x308E, 0x8226061C },
+	{ 0x3090, 0x02261000 },
+	{ 0x3092, 0x04051101 },
+	{ 0x3094, 0x02261800 },
+	{ 0x3096, 0x42261203 },
+	{ 0x3098, 0x02261101 },
+	{ 0x309A, 0xC2261300 },
+	{ 0x309C, 0x2226FB02 },
+	{ 0x309E, 0x0000F000 },
+	{ 0x30A0, 0xC2273632 },
+	{ 0x30A2, 0xC2400001 },
+	{ 0x30A4, 0x8227100E },
+	{ 0x30A6, 0x22271803 },
+	{ 0x30A8, 0x82410B00 },
+	{ 0x30AA, 0xE241023B },
+	{ 0x30AC, 0x02413B01 },
+	{ 0x30AE, 0x62400000 },
+	{ 0x30B0, 0xE2414288 },
+	{ 0x30B2, 0x02410B00 },
+	{ 0x30B4, 0x02410B00 },
+	{ 0x30B6, 0x04050300 },
+	{ 0x30B8, 0x42410C02 },
+	{ 0x30BA, 0xE2410227 },
+	{ 0x30BC, 0x02413B01 },
+	{ 0x30BE, 0xE2414266 },
+	{ 0x30C0, 0xE2415294 },
+	{ 0x30C2, 0x02410B00 },
+	{ 0x30C4, 0x02410B00 },
+	{ 0x30C6, 0x02271100 },
+	{ 0x30C8, 0x02271401 },
+	{ 0x30CA, 0x02270200 },
+	{ 0x30CC, 0x02271001 },
+	{ 0x30CE, 0x02270200 },
+	{ 0x30D0, 0xE2410266 },
+	{ 0x30D2, 0x82414B15 },
+	{ 0x30D4, 0x82410B15 },
+	{ 0x30D6, 0xE2415294 },
+	{ 0x30D8, 0x02410B00 },
+	{ 0x30DA, 0x8227160D },
+	{ 0x30DC, 0x0227F501 },
+	{ 0x30DE, 0x8227061C },
+	{ 0x30E0, 0x02271000 },
+	{ 0x30E2, 0x04051101 },
+	{ 0x30E4, 0x02271800 },
+	{ 0x30E6, 0x42271203 },
+	{ 0x30E8, 0x02271101 },
+	{ 0x30EA, 0xC2271300 },
+	{ 0x30EC, 0x2227FB02 },
+	{ 0x30F0, 0xC2283632 },
+	{ 0x30F2, 0xC2400001 },
+	{ 0x30F4, 0x8228100E },
+	{ 0x30F6, 0x22281803 },
+	{ 0x30F8, 0x82410B02 },
+	{ 0x30FA, 0xE241023B },
+	{ 0x30FC, 0x02413B01 },
+	{ 0x30FE, 0x62400000 },
+	{ 0x3100, 0xE2414288 },
+	{ 0x3102, 0x02410B00 },
+	{ 0x3104, 0x02410B00 },
+	{ 0x3106, 0x04050200 },
+	{ 0x3108, 0x42410C03 },
+	{ 0x310A, 0xE2410227 },
+	{ 0x310C, 0x02413B01 },
+	{ 0x310E, 0xE2414266 },
+	{ 0x3110, 0xE2415294 },
+	{ 0x3112, 0x02410B00 },
+	{ 0x3114, 0x02410B00 },
+	{ 0x3116, 0x02281100 },
+	{ 0x3118, 0x02281401 },
+	{ 0x311A, 0x02280200 },
+	{ 0x311C, 0x02281001 },
+	{ 0x311E, 0x02280200 },
+	{ 0x3120, 0xE2410266 },
+	{ 0x3122, 0x82414B17 },
+	{ 0x3124, 0x82410B17 },
+	{ 0x3126, 0xE2415294 },
+	{ 0x3128, 0x02410B00 },
+	{ 0x312A, 0x8228160D },
+	{ 0x312C, 0x0228F501 },
+	{ 0x312E, 0x8228061C },
+	{ 0x3130, 0x02281000 },
+	{ 0x3132, 0x04051101 },
+	{ 0x3134, 0x02281800 },
+	{ 0x3136, 0x42281203 },
+	{ 0x3138, 0x02281101 },
+	{ 0x313A, 0xC2281300 },
+	{ 0x313C, 0x2228FB02 },
+	{ 0x3140, 0xC2293632 },
+	{ 0x3142, 0xC2500001 },
+	{ 0x3144, 0x8229100E },
+	{ 0x3146, 0x22291803 },
+	{ 0x3148, 0x82510B00 },
+	{ 0x314A, 0xE251023B },
+	{ 0x314C, 0x02513B01 },
+	{ 0x314E, 0x62500000 },
+	{ 0x3150, 0xE2514288 },
+	{ 0x3152, 0x02510B00 },
+	{ 0x3154, 0x02510B00 },
+	{ 0x3156, 0x04050500 },
+	{ 0x3158, 0x42510C02 },
+	{ 0x315A, 0xE2510227 },
+	{ 0x315C, 0x02513B01 },
+	{ 0x315E, 0xE2514266 },
+	{ 0x3160, 0xE2515294 },
+	{ 0x3162, 0x02510B00 },
+	{ 0x3164, 0x02510B00 },
+	{ 0x3166, 0x02291100 },
+	{ 0x3168, 0x02291401 },
+	{ 0x316A, 0x02290200 },
+	{ 0x316C, 0x02291001 },
+	{ 0x316E, 0x02290200 },
+	{ 0x3170, 0xE2510266 },
+	{ 0x3172, 0x82514B15 },
+	{ 0x3174, 0x82510B15 },
+	{ 0x3176, 0xE2515294 },
+	{ 0x3178, 0x02510B00 },
+	{ 0x317A, 0x8229160D },
+	{ 0x317C, 0x0229F501 },
+	{ 0x317E, 0x8229061C },
+	{ 0x3180, 0x02291000 },
+	{ 0x3182, 0x04051101 },
+	{ 0x3184, 0x02291800 },
+	{ 0x3186, 0x42291203 },
+	{ 0x3188, 0x02291101 },
+	{ 0x318A, 0xC2291300 },
+	{ 0x318C, 0x2229FB02 },
+	{ 0x3190, 0xC22A3632 },
+	{ 0x3192, 0xC2500001 },
+	{ 0x3194, 0x822A100E },
+	{ 0x3196, 0x222A1803 },
+	{ 0x3198, 0x82510B02 },
+	{ 0x319A, 0xE251023B },
+	{ 0x319C, 0x02513B01 },
+	{ 0x319E, 0x62500000 },
+	{ 0x31A0, 0xE2514288 },
+	{ 0x31A2, 0x02510B00 },
+	{ 0x31A4, 0x02510B00 },
+	{ 0x31A6, 0x04050400 },
+	{ 0x31A8, 0x42510C03 },
+	{ 0x31AA, 0xE2510227 },
+	{ 0x31AC, 0x02513B01 },
+	{ 0x31AE, 0xE2514266 },
+	{ 0x31B0, 0xE2515294 },
+	{ 0x31B2, 0x02510B00 },
+	{ 0x31B4, 0x02510B00 },
+	{ 0x31B6, 0x022A1100 },
+	{ 0x31B8, 0x022A1401 },
+	{ 0x31BA, 0x022A0200 },
+	{ 0x31BC, 0x022A1001 },
+	{ 0x31BE, 0x022A0200 },
+	{ 0x31C0, 0xE2510266 },
+	{ 0x31C2, 0x82514B17 },
+	{ 0x31C4, 0x82510B17 },
+	{ 0x31C6, 0xE2515294 },
+	{ 0x31C8, 0x02510B00 },
+	{ 0x31CA, 0x822A160D },
+	{ 0x31CC, 0x022AF501 },
+	{ 0x31CE, 0x822A061C },
+	{ 0x31D0, 0x022A1000 },
+	{ 0x31D2, 0x04051101 },
+	{ 0x31D4, 0x022A1800 },
+	{ 0x31D6, 0x422A1203 },
+	{ 0x31D8, 0x022A1101 },
+	{ 0x31DA, 0xC22A1300 },
+	{ 0x31DC, 0x222AFB02 },
+};
+
+static const struct reg_sequence cs47l85_revc_32_patch[] = {
+	{ 0x3380, 0xE4103066 },
+	{ 0x3382, 0xE4103070 },
+	{ 0x3384, 0xE4103078 },
+	{ 0x3386, 0xE4103080 },
+	{ 0x3388, 0xE410F080 },
+	{ 0x338A, 0xE4143066 },
+	{ 0x338C, 0xE4143070 },
+	{ 0x338E, 0xE4143078 },
+	{ 0x3390, 0xE4143080 },
+	{ 0x3392, 0xE414F080 },
+	{ 0x3394, 0xE4103078 },
+	{ 0x3396, 0xE4103070 },
+	{ 0x3398, 0xE4103066 },
+	{ 0x339A, 0xE410F056 },
+	{ 0x339C, 0xE4143078 },
+	{ 0x339E, 0xE4143070 },
+	{ 0x33A0, 0xE4143066 },
+	{ 0x33A2, 0xE414F056 },
+};
+
+int cs47l85_patch(struct madera *madera)
+{
+	int ret = 0;
+	const struct reg_sequence *patch16;
+	const struct reg_sequence *patch32;
+	unsigned int num16, num32;
+
+	switch (madera->rev) {
+	case 0:
+	case 1:
+		patch16 = cs47l85_reva_16_patch;
+		num16 = ARRAY_SIZE(cs47l85_reva_16_patch);
+
+		patch32 = cs47l85_reva_32_patch;
+		num32 = ARRAY_SIZE(cs47l85_reva_32_patch);
+		break;
+	default:
+		patch16 = cs47l85_revc_16_patch;
+		num16 = ARRAY_SIZE(cs47l85_revc_16_patch);
+
+		patch32 = cs47l85_revc_32_patch;
+		num32 = ARRAY_SIZE(cs47l85_revc_32_patch);
+		break;
+	}
+
+	ret = regmap_register_patch(madera->regmap, patch16, num16);
+	if (ret < 0) {
+		dev_err(madera->dev,
+			"Error in applying 16-bit patch: %d\n", ret);
+		return ret;
+	}
+
+	ret = regmap_register_patch(madera->regmap_32bit, patch32, num32);
+	if (ret < 0) {
+		dev_err(madera->dev,
+			"Error in applying 32-bit patch: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cs47l85_patch);
+
+static const struct reg_default cs47l85_reg_default[] = {
+	{ 0x00000020, 0x0000 }, /* R32 (0x20) - Tone Generator 1 */
+	{ 0x00000021, 0x1000 }, /* R33 (0x21) - Tone Generator 2 */
+	{ 0x00000022, 0x0000 }, /* R34 (0x22) - Tone Generator 3 */
+	{ 0x00000023, 0x1000 }, /* R35 (0x23) - Tone Generator 4 */
+	{ 0x00000024, 0x0000 }, /* R36 (0x24) - Tone Generator 5 */
+	{ 0x00000030, 0x0000 }, /* R48 (0x30) - PWM Drive 1 */
+	{ 0x00000031, 0x0100 }, /* R49 (0x31) - PWM Drive 2 */
+	{ 0x00000032, 0x0100 }, /* R50 (0x32) - PWM Drive 3 */
+	{ 0x00000061, 0x01ff }, /* R97 (0x61) - Sample Rate Sequence Select 1 */
+	{ 0x00000062, 0x01ff }, /* R98 (0x62) - Sample Rate Sequence Select 2 */
+	{ 0x00000063, 0x01ff }, /* R99 (0x63) - Sample Rate Sequence Select 3 */
+	{ 0x00000064, 0x01ff }, /* R100 (0x64) - Sample Rate Sequence Select 4 */
+	{ 0x00000066, 0x01ff }, /* R102 (0x66) - Always On Triggers Sequence Select 1*/
+	{ 0x00000067, 0x01ff }, /* R103 (0x67) - Always On Triggers Sequence Select 2*/
+	{ 0x00000090, 0x0000 }, /* R144 (0x90) - Haptics Control 1 */
+	{ 0x00000091, 0x7fff }, /* R145 (0x91) - Haptics Control 2 */
+	{ 0x00000092, 0x0000 }, /* R146 (0x92) - Haptics phase 1 intensity */
+	{ 0x00000093, 0x0000 }, /* R147 (0x93) - Haptics phase 1 duration */
+	{ 0x00000094, 0x0000 }, /* R148 (0x94) - Haptics phase 2 intensity */
+	{ 0x00000095, 0x0000 }, /* R149 (0x95) - Haptics phase 2 duration */
+	{ 0x00000096, 0x0000 }, /* R150 (0x96) - Haptics phase 3 intensity */
+	{ 0x00000097, 0x0000 }, /* R151 (0x97) - Haptics phase 3 duration */
+	{ 0x000000a0, 0x0000 }, /* R160 (0xa0) - Comfort Noise Generator */
+	{ 0x00000100, 0x0002 }, /* R256 (0x100) - Clock 32k 1 */
+	{ 0x00000101, 0x0404 }, /* R257 (0x101) - System Clock 1 */
+	{ 0x00000102, 0x0011 }, /* R258 (0x102) - Sample rate 1 */
+	{ 0x00000103, 0x0011 }, /* R259 (0x103) - Sample rate 2 */
+	{ 0x00000104, 0x0011 }, /* R260 (0x104) - Sample rate 3 */
+	{ 0x00000112, 0x0305 }, /* R274 (0x112) - Async clock 1 */
+	{ 0x00000113, 0x0011 }, /* R275 (0x113) - Async sample rate 1 */
+	{ 0x00000114, 0x0011 }, /* R276 (0x114) - Async sample rate 2 */
+	{ 0x00000120, 0x0305 }, /* R288 (0x120) - DSP Clock 1 */
+	{ 0x00000122, 0x0000 }, /* R290 (0x122) - DSP Clock 2 */
+	{ 0x00000149, 0x0000 }, /* R329 (0x149) - Output system clock */
+	{ 0x0000014a, 0x0000 }, /* R330 (0x14a) - Output async clock */
+	{ 0x00000152, 0x0000 }, /* R338 (0x152) - Rate Estimator 1 */
+	{ 0x00000153, 0x0000 }, /* R339 (0x153) - Rate Estimator 2 */
+	{ 0x00000154, 0x0000 }, /* R340 (0x154) - Rate Estimator 3 */
+	{ 0x00000155, 0x0000 }, /* R341 (0x155) - Rate Estimator 4 */
+	{ 0x00000156, 0x0000 }, /* R342 (0x156) - Rate Estimator 5 */
+	{ 0x00000171, 0x0002 }, /* R369 (0x171) - FLL1 Control 1 */
+	{ 0x00000172, 0x0008 }, /* R370 (0x172) - FLL1 Control 2 */
+	{ 0x00000173, 0x0018 }, /* R371 (0x173) - FLL1 Control 3 */
+	{ 0x00000174, 0x007d }, /* R372 (0x174) - FLL1 Control 4 */
+	{ 0x00000175, 0x0000 }, /* R373 (0x175) - FLL1 Control 5 */
+	{ 0x00000176, 0x0000 }, /* R374 (0x176) - FLL1 Control 6 */
+	{ 0x00000177, 0x0281 }, /* R375 (0x177) - FLL1 Loop Filter Test 1 */
+	{ 0x00000179, 0x0000 }, /* R377 (0x179) - FLL1 Control 7 */
+	{ 0x00000181, 0x0000 }, /* R385 (0x181) - FLL1 Synchroniser 1 */
+	{ 0x00000182, 0x0000 }, /* R386 (0x182) - FLL1 Synchroniser 2 */
+	{ 0x00000183, 0x0000 }, /* R387 (0x183) - FLL1 Synchroniser 3 */
+	{ 0x00000184, 0x0000 }, /* R388 (0x184) - FLL1 Synchroniser 4 */
+	{ 0x00000185, 0x0000 }, /* R389 (0x185) - FLL1 Synchroniser 5 */
+	{ 0x00000186, 0x0000 }, /* R390 (0x186) - FLL1 Synchroniser 6 */
+	{ 0x00000187, 0x0001 }, /* R391 (0x187) - FLL1 Synchroniser 7 */
+	{ 0x00000189, 0x0000 }, /* R393 (0x189) - FLL1 Spread Spectrum */
+	{ 0x0000018a, 0x000c }, /* R394 (0x18a) - FLL1 GPIO Clock */
+	{ 0x00000191, 0x0002 }, /* R401 (0x191) - FLL2 Control 1 */
+	{ 0x00000192, 0x0008 }, /* R402 (0x192) - FLL2 Control 2 */
+	{ 0x00000193, 0x0018 }, /* R403 (0x193) - FLL2 Control 3 */
+	{ 0x00000194, 0x007d }, /* R404 (0x194) - FLL2 Control 4 */
+	{ 0x00000195, 0x0000 }, /* R405 (0x195) - FLL2 Control 5 */
+	{ 0x00000196, 0x0000 }, /* R406 (0x196) - FLL2 Control 6 */
+	{ 0x00000197, 0x0281 }, /* R407 (0x197) - FLL2 Loop Filter Test 1 */
+	{ 0x00000199, 0x0000 }, /* R409 (0x199) - FLL2 Control 7 */
+	{ 0x000001a1, 0x0000 }, /* R417 (0x1a1) - FLL2 Synchroniser 1 */
+	{ 0x000001a2, 0x0000 }, /* R418 (0x1a2) - FLL2 Synchroniser 2 */
+	{ 0x000001a3, 0x0000 }, /* R419 (0x1a3) - FLL2 Synchroniser 3 */
+	{ 0x000001a4, 0x0000 }, /* R420 (0x1a4) - FLL2 Synchroniser 4 */
+	{ 0x000001a5, 0x0000 }, /* R421 (0x1a5) - FLL2 Synchroniser 5 */
+	{ 0x000001a6, 0x0000 }, /* R422 (0x1a6) - FLL2 Synchroniser 6 */
+	{ 0x000001a7, 0x0001 }, /* R423 (0x1a7) - FLL2 Synchroniser 7 */
+	{ 0x000001a9, 0x0000 }, /* R425 (0x1a9) - FLL2 Spread Spectrum */
+	{ 0x000001aa, 0x000c }, /* R426 (0x1aa) - FLL2 GPIO Clock */
+	{ 0x000001b1, 0x0002 }, /* R433 (0x1b1) - FLL3 Control 1 */
+	{ 0x000001b2, 0x0008 }, /* R434 (0x1b2) - FLL3 Control 2 */
+	{ 0x000001b3, 0x0018 }, /* R435 (0x1b3) - FLL3 Control 3 */
+	{ 0x000001b4, 0x007d }, /* R436 (0x1b4) - FLL3 Control 4 */
+	{ 0x000001b5, 0x0000 }, /* R437 (0x1b5) - FLL3 Control 5 */
+	{ 0x000001b6, 0x0000 }, /* R438 (0x1b6) - FLL3 Control 6 */
+	{ 0x000001b7, 0x0281 }, /* R439 (0x1b7) - FLL3 Loop Filter Test 1 */
+	{ 0x000001b9, 0x0000 }, /* R441 (0x1b9) - FLL3 Control 7 */
+	{ 0x000001c1, 0x0000 }, /* R449 (0x1c1) - FLL3 Synchroniser 1 */
+	{ 0x000001c2, 0x0000 }, /* R450 (0x1c2) - FLL3 Synchroniser 2 */
+	{ 0x000001c3, 0x0000 }, /* R451 (0x1c3) - FLL3 Synchroniser 3 */
+	{ 0x000001c4, 0x0000 }, /* R452 (0x1c4) - FLL3 Synchroniser 4 */
+	{ 0x000001c5, 0x0000 }, /* R453 (0x1c5) - FLL3 Synchroniser 5 */
+	{ 0x000001c6, 0x0000 }, /* R454 (0x1c6) - FLL3 Synchroniser 6 */
+	{ 0x000001c7, 0x0001 }, /* R455 (0x1c7) - FLL3 Synchroniser 7 */
+	{ 0x000001c9, 0x0000 }, /* R457 (0x1c9) - FLL3 Spread Spectrum */
+	{ 0x000001ca, 0x000C }, /* R458 (0x1ca) - FLL3 GPIO Clock */
+	{ 0x00000200, 0x0006 }, /* R512 (0x200) - Mic Charge Pump 1 */
+	{ 0x0000020b, 0x0400 }, /* R523 (0x20B) - HP Charge Pump 8 */
+	{ 0x00000210, 0x0184 }, /* R528 (0x210) - LDO1 Control 1 */
+	{ 0x00000213, 0x03e4 }, /* R531 (0x213) - LDO2 Control 1 */
+	{ 0x00000218, 0x00e6 }, /* R536 (0x218) - Mic Bias Ctrl 1 */
+	{ 0x00000219, 0x00e6 }, /* R537 (0x219) - Mic Bias Ctrl 2 */
+	{ 0x0000021a, 0x00e6 }, /* R538 (0x21a) - Mic Bias Ctrl 3 */
+	{ 0x0000021b, 0x00e6 }, /* R539 (0x21b) - Mic Bias Ctrl 4 */
+	{ 0x0000027e, 0x0000 }, /* R638 (0x27e) - EDRE HP stereo control */
+	{ 0x00000293, 0x0000 }, /* R659 (0x293) - Accessory Detect Mode 1 */
+	{ 0x0000029b, 0x0000 }, /* R667 (0x29b) - Headphone Detect 1 */
+	{ 0x000002a3, 0x1102 }, /* R675 (0x2a3) - Mic Detect Control 1 */
+	{ 0x000002a4, 0x009f }, /* R676 (0x2a4) - Mic Detect Control 2 */
+	{ 0x000002a6, 0x3737 }, /* R678 (0x2a6) - Mic Detect Level 1 */
+	{ 0x000002a7, 0x2c37 }, /* R679 (0x2a7) - Mic Detect Level 2 */
+	{ 0x000002a8, 0x1422 }, /* R680 (0x2a8) - Mic Detect Level 3 */
+	{ 0x000002a9, 0x030a }, /* R681 (0x2a9) - Mic Detect Level 4 */
+	{ 0x000002c6, 0x0010 }, /* R710 (0x2c6) - Mic Clamp control */
+	{ 0x000002c8, 0x0000 }, /* R712 (0x2c8) - GP switch 1 */
+	{ 0x000002d3, 0x0000 }, /* R723 (0x2d3) - Jack detect analogue */
+	{ 0x00000300, 0x0000 }, /* R768 (0x300) - Input Enables */
+	{ 0x00000308, 0x0000 }, /* R776 (0x308) - Input Rate */
+	{ 0x00000309, 0x0022 }, /* R777 (0x309) - Input Volume Ramp */
+	{ 0x0000030c, 0x0002 }, /* R780 (0x30c) - HPF Control */
+	{ 0x00000310, 0x0080 }, /* R784 (0x310) - IN1L Control */
+	{ 0x00000311, 0x0180 }, /* R785 (0x311) - ADC Digital Volume 1L */
+	{ 0x00000312, 0x0500 }, /* R786 (0x312) - DMIC1L Control */
+	{ 0x00000314, 0x0080 }, /* R788 (0x314) - IN1R Control */
+	{ 0x00000315, 0x0180 }, /* R789 (0x315) - ADC Digital Volume 1R */
+	{ 0x00000316, 0x0000 }, /* R790 (0x316) - DMIC1R Control */
+	{ 0x00000318, 0x0080 }, /* R792 (0x318) - IN2L Control */
+	{ 0x00000319, 0x0180 }, /* R793 (0x319) - ADC Digital Volume 2L */
+	{ 0x0000031a, 0x0500 }, /* R794 (0x31a) - DMIC2L Control */
+	{ 0x0000031c, 0x0080 }, /* R796 (0x31c) - IN2R Control */
+	{ 0x0000031d, 0x0180 }, /* R797 (0x31d) - ADC Digital Volume 2R */
+	{ 0x0000031e, 0x0000 }, /* R798 (0x31e) - DMIC2R Control */
+	{ 0x00000320, 0x0080 }, /* R800 (0x320) - IN3L Control */
+	{ 0x00000321, 0x0180 }, /* R801 (0x321) - ADC Digital Volume 3L */
+	{ 0x00000322, 0x0500 }, /* R802 (0x322) - DMIC3L Control */
+	{ 0x00000324, 0x0080 }, /* R804 (0x324) - IN3R Control */
+	{ 0x00000325, 0x0180 }, /* R805 (0x325) - ADC Digital Volume 3R */
+	{ 0x00000326, 0x0000 }, /* R806 (0x326) - DMIC3R Control */
+	{ 0x00000328, 0x0000 }, /* R808 (0x328) - IN4 Control */
+	{ 0x00000329, 0x0180 }, /* R809 (0x329) - ADC Digital Volume 4L */
+	{ 0x0000032a, 0x0500 }, /* R810 (0x32a) - DMIC4L Control */
+	{ 0x0000032c, 0x0000 }, /* R812 (0x32c) - IN4R Control */
+	{ 0x0000032d, 0x0180 }, /* R813 (0x32d) - ADC Digital Volume 4R */
+	{ 0x0000032e, 0x0000 }, /* R814 (0x32e) - DMIC4R Control */
+	{ 0x00000330, 0x0000 }, /* R816 (0x330) - IN5L Control */
+	{ 0x00000331, 0x0180 }, /* R817 (0x331) - ADC Digital Volume 5L */
+	{ 0x00000332, 0x0500 }, /* R818 (0x332) - DMIC5L Control */
+	{ 0x00000334, 0x0000 }, /* R820 (0x334) - IN5R Control */
+	{ 0x00000335, 0x0180 }, /* R821 (0x335) - ADC Digital Volume 5R */
+	{ 0x00000336, 0x0000 }, /* R822 (0x336) - DMIC5R Control */
+	{ 0x00000338, 0x0000 }, /* R824 (0x338) - IN6L Control */
+	{ 0x00000339, 0x0180 }, /* R825 (0x339) - ADC Digital Volume 6L */
+	{ 0x0000033a, 0x0500 }, /* R826 (0x33a) - DMIC6L Control */
+	{ 0x0000033c, 0x0000 }, /* R828 (0x33c) - IN6R Control */
+	{ 0x0000033d, 0x0180 }, /* R829 (0x33d) - ADC Digital Volume 6R */
+	{ 0x0000033e, 0x0000 }, /* R830 (0x33e) - DMIC6R Control */
+	{ 0x00000400, 0x0000 }, /* R1024 (0x400) - Output Enables 1 */
+	{ 0x00000408, 0x0000 }, /* R1032 (0x408) - Output Rate 1 */
+	{ 0x00000409, 0x0022 }, /* R1033 (0x409) - Output Volume Ramp */
+	{ 0x00000410, 0x0080 }, /* R1040 (0x410) - Output Path Config 1L */
+	{ 0x00000411, 0x0180 }, /* R1041 (0x411) - DAC Digital Volume 1L */
+	{ 0x00000413, 0x0001 }, /* R1043 (0x413) - Noise Gate Select 1L */
+	{ 0x00000414, 0x0080 }, /* R1044 (0x414) - Output Path Config 1R */
+	{ 0x00000415, 0x0180 }, /* R1045 (0x415) - DAC Digital Volume 1R */
+	{ 0x00000417, 0x0002 }, /* R1047 (0x417) - Noise Gate Select 1R */
+	{ 0x00000418, 0x0080 }, /* R1048 (0x418) - Output Path Config 2L */
+	{ 0x00000419, 0x0180 }, /* R1049 (0x419) - DAC Digital Volume 2L */
+	{ 0x0000041b, 0x0004 }, /* R1051 (0x41b) - Noise Gate Select 2L */
+	{ 0x0000041c, 0x0080 }, /* R1052 (0x41c) - Output Path Config 2R */
+	{ 0x0000041d, 0x0180 }, /* R1053 (0x41d) - DAC Digital Volume 2R */
+	{ 0x0000041f, 0x0008 }, /* R1055 (0x41f) - Noise Gate Select 2R */
+	{ 0x00000420, 0x0080 }, /* R1056 (0x420) - Output Path Config 3L */
+	{ 0x00000421, 0x0180 }, /* R1057 (0x421) - DAC Digital Volume 3L */
+	{ 0x00000423, 0x0010 }, /* R1059 (0x423) - Noise Gate Select 3L */
+	{ 0x00000424, 0x0080 }, /* R1060 (0x424) - Output Path Config 3R */
+	{ 0x00000425, 0x0180 }, /* R1061 (0x425) - DAC Digital Volume 3R */
+	{ 0x00000427, 0x0020 }, /* R1063 (0x427) - Noise Gate Select 3R */
+	{ 0x00000428, 0x0000 }, /* R1064 (0x428) - Output Path Config 4L */
+	{ 0x00000429, 0x0180 }, /* R1065 (0x429) - DAC Digital Volume 4L */
+	{ 0x0000042b, 0x0040 }, /* R1067 (0x42b) - Noise Gate Select 4L */
+	{ 0x0000042c, 0x0000 }, /* R1068 (0x42c) - Output Path Config 4R */
+	{ 0x0000042d, 0x0180 }, /* R1069 (0x42d) - DAC Digital Volume 4R */
+	{ 0x0000042f, 0x0080 }, /* R1071 (0x42f) - Noise Gate Select 4R */
+	{ 0x00000430, 0x0000 }, /* R1072 (0x430) - Output Path Config 5L */
+	{ 0x00000431, 0x0180 }, /* R1073 (0x431) - DAC Digital Volume 5L */
+	{ 0x00000433, 0x0100 }, /* R1075 (0x433) - Noise Gate Select 5L */
+	{ 0x00000434, 0x0000 }, /* R1076 (0x434) - Output Path Config 5R */
+	{ 0x00000435, 0x0180 }, /* R1077 (0x435) - DAC Digital Volume 5R */
+	{ 0x00000437, 0x0200 }, /* R1079 (0x437) - Noise Gate Select 5R */
+	{ 0x00000438, 0x0000 }, /* R1080 (0x438) - Output Path Config 6L */
+	{ 0x00000439, 0x0180 }, /* R1081 (0x439) - DAC Digital Volume 6L */
+	{ 0x0000043b, 0x0400 }, /* R1083 (0x43b) - Noise Gate Select 6L */
+	{ 0x0000043c, 0x0000 }, /* R1084 (0x43c) - Output Path Config 6R */
+	{ 0x0000043d, 0x0180 }, /* R1085 (0x43d) - DAC Digital Volume 6R */
+	{ 0x0000043f, 0x0800 }, /* R1087 (0x43f) - Noise Gate Select 6R */
+	{ 0x00000440, 0x003f }, /* R1088 (0x440) - DRE Enable */
+	{ 0x00000448, 0x003f }, /* R1096 (0x448) - EDRE Enable */
+	{ 0x0000044a, 0x0000 }, /* R1098 (0x44a) - EDRE Manual */
+	{ 0x00000450, 0x0000 }, /* R1104 (0x450) - DAC AEC Control 1 */
+	{ 0x00000451, 0x0000 }, /* R1105 (0x451) - DAC AEC Control 2 */
+	{ 0x00000458, 0x0000 }, /* R1112 (0x458) - Noise Gate Control */
+	{ 0x00000490, 0x0069 }, /* R1168 (0x490) - PDM SPK1 CTRL 1 */
+	{ 0x00000491, 0x0000 }, /* R1169 (0x491) - PDM SPK1 CTRL 2 */
+	{ 0x00000492, 0x0069 }, /* R1170 (0x492) - PDM SPK2 CTRL 1 */
+	{ 0x00000493, 0x0000 }, /* R1171 (0x493) - PDM SPK2 CTRL 2 */
+	{ 0x000004a0, 0x3210 }, /* R1184 (0x4a0) - HP1 Short Circuit Ctrl */
+	{ 0x000004a1, 0x3200 }, /* R1185 (0x4a1) - HP2 Short Circuit Ctrl */
+	{ 0x000004a2, 0x3200 }, /* R1186 (0x4a2) - HP3 Short Circuit Ctrl */
+	{ 0x000004a8, 0x7020 }, /* R1192 (0x4a8) - HP Test Ctrl 5 */
+	{ 0x000004a9, 0x7020 }, /* R1193 (0x4a9) - HP Test Ctrl 6 */
+	{ 0x00000500, 0x000c }, /* R1280 (0x500) - AIF1 BCLK Ctrl */
+	{ 0x00000501, 0x0000 }, /* R1281 (0x501) - AIF1 Tx Pin Ctrl */
+	{ 0x00000502, 0x0000 }, /* R1282 (0x502) - AIF1 Rx Pin Ctrl */
+	{ 0x00000503, 0x0000 }, /* R1283 (0x503) - AIF1 Rate Ctrl */
+	{ 0x00000504, 0x0000 }, /* R1284 (0x504) - AIF1 Format */
+	{ 0x00000506, 0x0040 }, /* R1286 (0x506) - AIF1 Rx BCLK Rate */
+	{ 0x00000507, 0x1818 }, /* R1287 (0x507) - AIF1 Frame Ctrl 1 */
+	{ 0x00000508, 0x1818 }, /* R1288 (0x508) - AIF1 Frame Ctrl 2 */
+	{ 0x00000509, 0x0000 }, /* R1289 (0x509) - AIF1 Frame Ctrl 3 */
+	{ 0x0000050a, 0x0001 }, /* R1290 (0x50a) - AIF1 Frame Ctrl 4 */
+	{ 0x0000050b, 0x0002 }, /* R1291 (0x50b) - AIF1 Frame Ctrl 5 */
+	{ 0x0000050c, 0x0003 }, /* R1292 (0x50c) - AIF1 Frame Ctrl 6 */
+	{ 0x0000050d, 0x0004 }, /* R1293 (0x50d) - AIF1 Frame Ctrl 7 */
+	{ 0x0000050e, 0x0005 }, /* R1294 (0x50e) - AIF1 Frame Ctrl 8 */
+	{ 0x0000050f, 0x0006 }, /* R1295 (0x50f) - AIF1 Frame Ctrl 9 */
+	{ 0x00000510, 0x0007 }, /* R1296 (0x510) - AIF1 Frame Ctrl 10 */
+	{ 0x00000511, 0x0000 }, /* R1297 (0x511) - AIF1 Frame Ctrl 11 */
+	{ 0x00000512, 0x0001 }, /* R1298 (0x512) - AIF1 Frame Ctrl 12 */
+	{ 0x00000513, 0x0002 }, /* R1299 (0x513) - AIF1 Frame Ctrl 13 */
+	{ 0x00000514, 0x0003 }, /* R1300 (0x514) - AIF1 Frame Ctrl 14 */
+	{ 0x00000515, 0x0004 }, /* R1301 (0x515) - AIF1 Frame Ctrl 15 */
+	{ 0x00000516, 0x0005 }, /* R1302 (0x516) - AIF1 Frame Ctrl 16 */
+	{ 0x00000517, 0x0006 }, /* R1303 (0x517) - AIF1 Frame Ctrl 17 */
+	{ 0x00000518, 0x0007 }, /* R1304 (0x518) - AIF1 Frame Ctrl 18 */
+	{ 0x00000519, 0x0000 }, /* R1305 (0x519) - AIF1 Tx Enables */
+	{ 0x0000051a, 0x0000 }, /* R1306 (0x51a) - AIF1 Rx Enables */
+	{ 0x00000540, 0x000c }, /* R1344 (0x540) - AIF2 BCLK Ctrl */
+	{ 0x00000541, 0x0000 }, /* R1345 (0x541) - AIF2 Tx Pin Ctrl */
+	{ 0x00000542, 0x0000 }, /* R1346 (0x542) - AIF2 Rx Pin Ctrl */
+	{ 0x00000543, 0x0000 }, /* R1347 (0x543) - AIF2 Rate Ctrl */
+	{ 0x00000544, 0x0000 }, /* R1348 (0x544) - AIF2 Format */
+	{ 0x00000546, 0x0040 }, /* R1350 (0x546) - AIF2 Rx BCLK Rate */
+	{ 0x00000547, 0x1818 }, /* R1351 (0x547) - AIF2 Frame Ctrl 1 */
+	{ 0x00000548, 0x1818 }, /* R1352 (0x548) - AIF2 Frame Ctrl 2 */
+	{ 0x00000549, 0x0000 }, /* R1353 (0x549) - AIF2 Frame Ctrl 3 */
+	{ 0x0000054a, 0x0001 }, /* R1354 (0x54a) - AIF2 Frame Ctrl 4 */
+	{ 0x0000054b, 0x0002 }, /* R1355 (0x54b) - AIF2 Frame Ctrl 5 */
+	{ 0x0000054c, 0x0003 }, /* R1356 (0x54c) - AIF2 Frame Ctrl 6 */
+	{ 0x0000054d, 0x0004 }, /* R1357 (0x54d) - AIF2 Frame Ctrl 7 */
+	{ 0x0000054e, 0x0005 }, /* R1358 (0x54e) - AIF2 Frame Ctrl 8 */
+	{ 0x0000054f, 0x0006 }, /* R1359 (0x54f) - AIF2 Frame Ctrl 9 */
+	{ 0x00000550, 0x0007 }, /* R1360 (0x550) - AIF2 Frame Ctrl 10 */
+	{ 0x00000551, 0x0000 }, /* R1361 (0x551) - AIF2 Frame Ctrl 11 */
+	{ 0x00000552, 0x0001 }, /* R1362 (0x552) - AIF2 Frame Ctrl 12 */
+	{ 0x00000553, 0x0002 }, /* R1363 (0x553) - AIF2 Frame Ctrl 13 */
+	{ 0x00000554, 0x0003 }, /* R1364 (0x554) - AIF2 Frame Ctrl 14 */
+	{ 0x00000555, 0x0004 }, /* R1365 (0x555) - AIF2 Frame Ctrl 15 */
+	{ 0x00000556, 0x0005 }, /* R1366 (0x556) - AIF2 Frame Ctrl 16 */
+	{ 0x00000557, 0x0006 }, /* R1367 (0x557) - AIF2 Frame Ctrl 17 */
+	{ 0x00000558, 0x0007 }, /* R1368 (0x558) - AIF2 Frame Ctrl 18 */
+	{ 0x00000559, 0x0000 }, /* R1369 (0x559) - AIF2 Tx Enables */
+	{ 0x0000055a, 0x0000 }, /* R1370 (0x55a) - AIF2 Rx Enables */
+	{ 0x00000580, 0x000c }, /* R1408 (0x580) - AIF3 BCLK Ctrl */
+	{ 0x00000581, 0x0000 }, /* R1409 (0x581) - AIF3 Tx Pin Ctrl */
+	{ 0x00000582, 0x0000 }, /* R1410 (0x582) - AIF3 Rx Pin Ctrl */
+	{ 0x00000583, 0x0000 }, /* R1411 (0x583) - AIF3 Rate Ctrl */
+	{ 0x00000584, 0x0000 }, /* R1412 (0x584) - AIF3 Format */
+	{ 0x00000586, 0x0040 }, /* R1414 (0x586) - AIF3 Rx BCLK Rate */
+	{ 0x00000587, 0x1818 }, /* R1415 (0x587) - AIF3 Frame Ctrl 1 */
+	{ 0x00000588, 0x1818 }, /* R1416 (0x588) - AIF3 Frame Ctrl 2 */
+	{ 0x00000589, 0x0000 }, /* R1417 (0x589) - AIF3 Frame Ctrl 3 */
+	{ 0x0000058a, 0x0001 }, /* R1418 (0x58a) - AIF3 Frame Ctrl 4 */
+	{ 0x00000591, 0x0000 }, /* R1425 (0x591) - AIF3 Frame Ctrl 11 */
+	{ 0x00000592, 0x0001 }, /* R1426 (0x592) - AIF3 Frame Ctrl 12 */
+	{ 0x00000599, 0x0000 }, /* R1433 (0x599) - AIF3 Tx Enables */
+	{ 0x0000059a, 0x0000 }, /* R1434 (0x59a) - AIF3 Rx Enables */
+	{ 0x000005a0, 0x000c }, /* R1440 (0x5a0) - AIF4 BCLK Ctrl */
+	{ 0x000005a1, 0x0000 }, /* R1441 (0x5a1) - AIF4 Tx Pin Ctrl */
+	{ 0x000005a2, 0x0000 }, /* R1442 (0x5a2) - AIF4 Rx Pin Ctrl */
+	{ 0x000005a3, 0x0000 }, /* R1443 (0x5a3) - AIF4 Rate Ctrl */
+	{ 0x000005a4, 0x0000 }, /* R1444 (0x5a4) - AIF4 Format */
+	{ 0x000005a6, 0x0040 }, /* R1446 (0x5a6) - AIF4 Rx BCLK Rate */
+	{ 0x000005a7, 0x1818 }, /* R1447 (0x5a7) - AIF4 Frame Ctrl 1 */
+	{ 0x000005a8, 0x1818 }, /* R1448 (0x5a8) - AIF4 Frame Ctrl 2 */
+	{ 0x000005a9, 0x0000 }, /* R1449 (0x5a9) - AIF4 Frame Ctrl 3 */
+	{ 0x000005aa, 0x0001 }, /* R1450 (0x5aa) - AIF4 Frame Ctrl 4 */
+	{ 0x000005b1, 0x0000 }, /* R1457 (0x5b1) - AIF4 Frame Ctrl 11 */
+	{ 0x000005b2, 0x0001 }, /* R1458 (0x5b2) - AIF4 Frame Ctrl 12 */
+	{ 0x000005b9, 0x0000 }, /* R1465 (0x5b9) - AIF4 Tx Enables */
+	{ 0x000005ba, 0x0000 }, /* R1466 (0x5ba) - AIF4 Rx Enables */
+	{ 0x000005c2, 0x0000 }, /* R1474 (0x5c2) - SPD1 TX Control */
+	{ 0x000005e3, 0x0000 }, /* R1507 (0x5e3) - SLIMbus Framer Ref Gear */
+	{ 0x000005e5, 0x0000 }, /* R1509 (0x5e5) - SLIMbus Rates 1 */
+	{ 0x000005e6, 0x0000 }, /* R1510 (0x5e6) - SLIMbus Rates 2 */
+	{ 0x000005e7, 0x0000 }, /* R1511 (0x5e7) - SLIMbus Rates 3 */
+	{ 0x000005e8, 0x0000 }, /* R1512 (0x5e8) - SLIMbus Rates 4 */
+	{ 0x000005e9, 0x0000 }, /* R1513 (0x5e9) - SLIMbus Rates 5 */
+	{ 0x000005ea, 0x0000 }, /* R1514 (0x5ea) - SLIMbus Rates 6 */
+	{ 0x000005eb, 0x0000 }, /* R1515 (0x5eb) - SLIMbus Rates 7 */
+	{ 0x000005ec, 0x0000 }, /* R1516 (0x5ec) - SLIMbus Rates 8 */
+	{ 0x000005f5, 0x0000 }, /* R1525 (0x5f5) - SLIMbus RX Channel Enable */
+	{ 0x000005f6, 0x0000 }, /* R1526 (0x5F6) - SLIMbus TX Channel Enable */
+	{ 0x00000640, 0x0000 }, /* R1600 (0x640) - PWM1MIX Input 1 Source */
+	{ 0x00000641, 0x0080 }, /* R1601 (0x641) - PWM1MIX Input 1 Volume */
+	{ 0x00000642, 0x0000 }, /* R1602 (0x642) - PWM1MIX Input 2 Source */
+	{ 0x00000643, 0x0080 }, /* R1603 (0x643) - PWM1MIX Input 2 Volume */
+	{ 0x00000644, 0x0000 }, /* R1604 (0x644) - PWM1MIX Input 3 Source */
+	{ 0x00000645, 0x0080 }, /* R1605 (0x645) - PWM1MIX Input 3 Volume */
+	{ 0x00000646, 0x0000 }, /* R1606 (0x646) - PWM1MIX Input 4 Source */
+	{ 0x00000647, 0x0080 }, /* R1607 (0x647) - PWM1MIX Input 4 Volume */
+	{ 0x00000648, 0x0000 }, /* R1608 (0x648) - PWM2MIX Input 1 Source */
+	{ 0x00000649, 0x0080 }, /* R1609 (0x649) - PWM2MIX Input 1 Volume */
+	{ 0x0000064a, 0x0000 }, /* R1610 (0x64a) - PWM2MIX Input 2 Source */
+	{ 0x0000064b, 0x0080 }, /* R1611 (0x64b) - PWM2MIX Input 2 Volume */
+	{ 0x0000064c, 0x0000 }, /* R1612 (0x64c) - PWM2MIX Input 3 Source */
+	{ 0x0000064d, 0x0080 }, /* R1613 (0x64d) - PWM2MIX Input 3 Volume */
+	{ 0x0000064e, 0x0000 }, /* R1614 (0x64e) - PWM2MIX Input 4 Source */
+	{ 0x0000064f, 0x0080 }, /* R1615 (0x64f) - PWM2MIX Input 4 Volume */
+	{ 0x00000680, 0x0000 }, /* R1664 (0x680) - OUT1LMIX Input 1 Source */
+	{ 0x00000681, 0x0080 }, /* R1665 (0x681) - OUT1LMIX Input 1 Volume */
+	{ 0x00000682, 0x0000 }, /* R1666 (0x682) - OUT1LMIX Input 2 Source */
+	{ 0x00000683, 0x0080 }, /* R1667 (0x683) - OUT1LMIX Input 2 Volume */
+	{ 0x00000684, 0x0000 }, /* R1668 (0x684) - OUT1LMIX Input 3 Source */
+	{ 0x00000685, 0x0080 }, /* R1669 (0x685) - OUT1LMIX Input 3 Volume */
+	{ 0x00000686, 0x0000 }, /* R1670 (0x686) - OUT1LMIX Input 4 Source */
+	{ 0x00000687, 0x0080 }, /* R1671 (0x687) - OUT1LMIX Input 4 Volume */
+	{ 0x00000688, 0x0000 }, /* R1672 (0x688) - OUT1RMIX Input 1 Source */
+	{ 0x00000689, 0x0080 }, /* R1673 (0x689) - OUT1RMIX Input 1 Volume */
+	{ 0x0000068a, 0x0000 }, /* R1674 (0x68a) - OUT1RMIX Input 2 Source */
+	{ 0x0000068b, 0x0080 }, /* R1675 (0x68b) - OUT1RMIX Input 2 Volume */
+	{ 0x0000068c, 0x0000 }, /* R1672 (0x68c) - OUT1RMIX Input 3 Source */
+	{ 0x0000068d, 0x0080 }, /* R1673 (0x68d) - OUT1RMIX Input 3 Volume */
+	{ 0x0000068e, 0x0000 }, /* R1674 (0x68e) - OUT1RMIX Input 4 Source */
+	{ 0x0000068f, 0x0080 }, /* R1675 (0x68f) - OUT1RMIX Input 4 Volume */
+	{ 0x00000690, 0x0000 }, /* R1680 (0x690) - OUT2LMIX Input 1 Source */
+	{ 0x00000691, 0x0080 }, /* R1681 (0x691) - OUT2LMIX Input 1 Volume */
+	{ 0x00000692, 0x0000 }, /* R1682 (0x692) - OUT2LMIX Input 2 Source */
+	{ 0x00000693, 0x0080 }, /* R1683 (0x693) - OUT2LMIX Input 2 Volume */
+	{ 0x00000694, 0x0000 }, /* R1684 (0x694) - OUT2LMIX Input 3 Source */
+	{ 0x00000695, 0x0080 }, /* R1685 (0x695) - OUT2LMIX Input 3 Volume */
+	{ 0x00000696, 0x0000 }, /* R1686 (0x696) - OUT2LMIX Input 4 Source */
+	{ 0x00000697, 0x0080 }, /* R1687 (0x697) - OUT2LMIX Input 4 Volume */
+	{ 0x00000698, 0x0000 }, /* R1688 (0x698) - OUT2RMIX Input 1 Source */
+	{ 0x00000699, 0x0080 }, /* R1689 (0x699) - OUT2RMIX Input 1 Volume */
+	{ 0x0000069a, 0x0000 }, /* R1690 (0x69a) - OUT2RMIX Input 2 Source */
+	{ 0x0000069b, 0x0080 }, /* R1691 (0x69b) - OUT2RMIX Input 2 Volume */
+	{ 0x0000069c, 0x0000 }, /* R1692 (0x69c) - OUT2RMIX Input 3 Source */
+	{ 0x0000069d, 0x0080 }, /* R1693 (0x69d) - OUT2RMIX Input 3 Volume */
+	{ 0x0000069e, 0x0000 }, /* R1694 (0x69e) - OUT2RMIX Input 4 Source */
+	{ 0x0000069f, 0x0080 }, /* R1695 (0x69f) - OUT2RMIX Input 4 Volume */
+	{ 0x000006a0, 0x0000 }, /* R1696 (0x6a0) - OUT3LMIX Input 1 Source */
+	{ 0x000006a1, 0x0080 }, /* R1697 (0x6a1) - OUT3LMIX Input 1 Volume */
+	{ 0x000006a2, 0x0000 }, /* R1698 (0x6a2) - OUT3LMIX Input 2 Source */
+	{ 0x000006a3, 0x0080 }, /* R1699 (0x6a3) - OUT3LMIX Input 2 Volume */
+	{ 0x000006a4, 0x0000 }, /* R1700 (0x6a4) - OUT3LMIX Input 3 Source */
+	{ 0x000006a5, 0x0080 }, /* R1701 (0x6a5) - OUT3LMIX Input 3 Volume */
+	{ 0x000006a6, 0x0000 }, /* R1702 (0x6a6) - OUT3LMIX Input 4 Source */
+	{ 0x000006a7, 0x0080 }, /* R1703 (0x6a7) - OUT3LMIX Input 4 Volume */
+	{ 0x000006a8, 0x0000 }, /* R1704 (0x6a8) - OUT3RMIX Input 1 Source */
+	{ 0x000006a9, 0x0080 }, /* R1705 (0x6a9) - OUT3RMIX Input 1 Volume */
+	{ 0x000006aa, 0x0000 }, /* R1706 (0x6aa) - OUT3RMIX Input 2 Source */
+	{ 0x000006ab, 0x0080 }, /* R1707 (0x6ab) - OUT3RMIX Input 2 Volume */
+	{ 0x000006ac, 0x0000 }, /* R1708 (0x6ac) - OUT3RMIX Input 3 Source */
+	{ 0x000006ad, 0x0080 }, /* R1709 (0x6ad) - OUT3RMIX Input 3 Volume */
+	{ 0x000006ae, 0x0000 }, /* R1710 (0x6ae) - OUT3RMIX Input 4 Source */
+	{ 0x000006af, 0x0080 }, /* R1711 (0x6af) - OUT3RMIX Input 4 Volume */
+	{ 0x000006b0, 0x0000 }, /* R1712 (0x6b0) - OUT4LMIX Input 1 Source */
+	{ 0x000006b1, 0x0080 }, /* R1713 (0x6b1) - OUT4LMIX Input 1 Volume */
+	{ 0x000006b2, 0x0000 }, /* R1714 (0x6b2) - OUT4LMIX Input 2 Source */
+	{ 0x000006b3, 0x0080 }, /* R1715 (0x6b3) - OUT4LMIX Input 2 Volume */
+	{ 0x000006b4, 0x0000 }, /* R1716 (0x6b4) - OUT4LMIX Input 3 Source */
+	{ 0x000006b5, 0x0080 }, /* R1717 (0x6b5) - OUT4LMIX Input 3 Volume */
+	{ 0x000006b6, 0x0000 }, /* R1718 (0x6b6) - OUT4LMIX Input 4 Source */
+	{ 0x000006b7, 0x0080 }, /* R1719 (0x6b7) - OUT4LMIX Input 4 Volume */
+	{ 0x000006b8, 0x0000 }, /* R1720 (0x6b8) - OUT4RMIX Input 1 Source */
+	{ 0x000006b9, 0x0080 }, /* R1721 (0x6b9) - OUT4RMIX Input 1 Volume */
+	{ 0x000006ba, 0x0000 }, /* R1722 (0x6ba) - OUT4RMIX Input 2 Source */
+	{ 0x000006bb, 0x0080 }, /* R1723 (0x6bb) - OUT4RMIX Input 2 Volume */
+	{ 0x000006bc, 0x0000 }, /* R1724 (0x6bc) - OUT4RMIX Input 3 Source */
+	{ 0x000006bd, 0x0080 }, /* R1725 (0x6bd) - OUT4RMIX Input 3 Volume */
+	{ 0x000006be, 0x0000 }, /* R1726 (0x6be) - OUT4RMIX Input 4 Source */
+	{ 0x000006bf, 0x0080 }, /* R1727 (0x6bf) - OUT4RMIX Input 4 Volume */
+	{ 0x000006c0, 0x0000 }, /* R1728 (0x6c0) - OUT5LMIX Input 1 Source */
+	{ 0x000006c1, 0x0080 }, /* R1729 (0x6c1) - OUT5LMIX Input 1 Volume */
+	{ 0x000006c2, 0x0000 }, /* R1730 (0x6c2) - OUT5LMIX Input 2 Source */
+	{ 0x000006c3, 0x0080 }, /* R1731 (0x6c3) - OUT5LMIX Input 2 Volume */
+	{ 0x000006c4, 0x0000 }, /* R1732 (0x6c4) - OUT5LMIX Input 3 Source */
+	{ 0x000006c5, 0x0080 }, /* R1733 (0x6c5) - OUT5LMIX Input 3 Volume */
+	{ 0x000006c6, 0x0000 }, /* R1734 (0x6c6) - OUT5LMIX Input 4 Source */
+	{ 0x000006c7, 0x0080 }, /* R1735 (0x6c7) - OUT5LMIX Input 4 Volume */
+	{ 0x000006c8, 0x0000 }, /* R1736 (0x6c8) - OUT5RMIX Input 1 Source */
+	{ 0x000006c9, 0x0080 }, /* R1737 (0x6c9) - OUT5RMIX Input 1 Volume */
+	{ 0x000006ca, 0x0000 }, /* R1738 (0x6ca) - OUT5RMIX Input 2 Source */
+	{ 0x000006cb, 0x0080 }, /* R1739 (0x6cb) - OUT5RMIX Input 2 Volume */
+	{ 0x000006cc, 0x0000 }, /* R1740 (0x6cc) - OUT5RMIX Input 3 Source */
+	{ 0x000006cd, 0x0080 }, /* R1741 (0x6cd) - OUT5RMIX Input 3 Volume */
+	{ 0x000006ce, 0x0000 }, /* R1742 (0x6ce) - OUT5RMIX Input 4 Source */
+	{ 0x000006cf, 0x0080 }, /* R1743 (0x6cf) - OUT5RMIX Input 4 Volume */
+	{ 0x000006d0, 0x0000 }, /* R1744 (0x6d0) - OUT6LMIX Input 1 Source */
+	{ 0x000006d1, 0x0080 }, /* R1745 (0x6d1) - OUT6LMIX Input 1 Volume */
+	{ 0x000006d2, 0x0000 }, /* R1746 (0x6d2) - OUT6LMIX Input 2 Source */
+	{ 0x000006d3, 0x0080 }, /* R1747 (0x6d3) - OUT6LMIX Input 2 Volume */
+	{ 0x000006d4, 0x0000 }, /* R1748 (0x6d4) - OUT6LMIX Input 3 Source */
+	{ 0x000006d5, 0x0080 }, /* R1749 (0x6d5) - OUT6LMIX Input 3 Volume */
+	{ 0x000006d6, 0x0000 }, /* R1750 (0x6d6) - OUT6LMIX Input 4 Source */
+	{ 0x000006d7, 0x0080 }, /* R1751 (0x6d7) - OUT6LMIX Input 4 Volume */
+	{ 0x000006d8, 0x0000 }, /* R1752 (0x6d8) - OUT6RMIX Input 1 Source */
+	{ 0x000006d9, 0x0080 }, /* R1753 (0x6d9) - OUT6RMIX Input 1 Volume */
+	{ 0x000006da, 0x0000 }, /* R1754 (0x6da) - OUT6RMIX Input 2 Source */
+	{ 0x000006db, 0x0080 }, /* R1755 (0x6db) - OUT6RMIX Input 2 Volume */
+	{ 0x000006dc, 0x0000 }, /* R1756 (0x6dc) - OUT6RMIX Input 3 Source */
+	{ 0x000006dd, 0x0080 }, /* R1757 (0x6dd) - OUT6RMIX Input 3 Volume */
+	{ 0x000006de, 0x0000 }, /* R1758 (0x6de) - OUT6RMIX Input 4 Source */
+	{ 0x000006df, 0x0080 }, /* R1759 (0x6df) - OUT6RMIX Input 4 Volume */
+	{ 0x00000700, 0x0000 }, /* R1792 (0x700) - AIF1TX1MIX Input 1 Source */
+	{ 0x00000701, 0x0080 }, /* R1793 (0x701) - AIF1TX1MIX Input 1 Volume */
+	{ 0x00000702, 0x0000 }, /* R1794 (0x702) - AIF1TX1MIX Input 2 Source */
+	{ 0x00000703, 0x0080 }, /* R1795 (0x703) - AIF1TX1MIX Input 2 Volume */
+	{ 0x00000704, 0x0000 }, /* R1796 (0x704) - AIF1TX1MIX Input 3 Source */
+	{ 0x00000705, 0x0080 }, /* R1797 (0x705) - AIF1TX1MIX Input 3 Volume */
+	{ 0x00000706, 0x0000 }, /* R1798 (0x706) - AIF1TX1MIX Input 4 Source */
+	{ 0x00000707, 0x0080 }, /* R1799 (0x707) - AIF1TX1MIX Input 4 Volume */
+	{ 0x00000708, 0x0000 }, /* R1800 (0x708) - AIF1TX2MIX Input 1 Source */
+	{ 0x00000709, 0x0080 }, /* R1801 (0x709) - AIF1TX2MIX Input 1 Volume */
+	{ 0x0000070a, 0x0000 }, /* R1802 (0x70a) - AIF1TX2MIX Input 2 Source */
+	{ 0x0000070b, 0x0080 }, /* R1803 (0x70b) - AIF1TX2MIX Input 2 Volume */
+	{ 0x0000070c, 0x0000 }, /* R1804 (0x70c) - AIF1TX2MIX Input 3 Source */
+	{ 0x0000070d, 0x0080 }, /* R1805 (0x70d) - AIF1TX2MIX Input 3 Volume */
+	{ 0x0000070e, 0x0000 }, /* R1806 (0x70e) - AIF1TX2MIX Input 4 Source */
+	{ 0x0000070f, 0x0080 }, /* R1807 (0x70f) - AIF1TX2MIX Input 4 Volume */
+	{ 0x00000710, 0x0000 }, /* R1808 (0x710) - AIF1TX3MIX Input 1 Source */
+	{ 0x00000711, 0x0080 }, /* R1809 (0x711) - AIF1TX3MIX Input 1 Volume */
+	{ 0x00000712, 0x0000 }, /* R1810 (0x712) - AIF1TX3MIX Input 2 Source */
+	{ 0x00000713, 0x0080 }, /* R1811 (0x713) - AIF1TX3MIX Input 2 Volume */
+	{ 0x00000714, 0x0000 }, /* R1812 (0x714) - AIF1TX3MIX Input 3 Source */
+	{ 0x00000715, 0x0080 }, /* R1813 (0x715) - AIF1TX3MIX Input 3 Volume */
+	{ 0x00000716, 0x0000 }, /* R1814 (0x716) - AIF1TX3MIX Input 4 Source */
+	{ 0x00000717, 0x0080 }, /* R1815 (0x717) - AIF1TX3MIX Input 4 Volume */
+	{ 0x00000718, 0x0000 }, /* R1816 (0x718) - AIF1TX4MIX Input 1 Source */
+	{ 0x00000719, 0x0080 }, /* R1817 (0x719) - AIF1TX4MIX Input 1 Volume */
+	{ 0x0000071a, 0x0000 }, /* R1818 (0x71a) - AIF1TX4MIX Input 2 Source */
+	{ 0x0000071b, 0x0080 }, /* R1819 (0x71b) - AIF1TX4MIX Input 2 Volume */
+	{ 0x0000071c, 0x0000 }, /* R1820 (0x71c) - AIF1TX4MIX Input 3 Source */
+	{ 0x0000071d, 0x0080 }, /* R1821 (0x71d) - AIF1TX4MIX Input 3 Volume */
+	{ 0x0000071e, 0x0000 }, /* R1822 (0x71e) - AIF1TX4MIX Input 4 Source */
+	{ 0x0000071f, 0x0080 }, /* R1823 (0x71f) - AIF1TX4MIX Input 4 Volume */
+	{ 0x00000720, 0x0000 }, /* R1824 (0x720) - AIF1TX5MIX Input 1 Source */
+	{ 0x00000721, 0x0080 }, /* R1825 (0x721) - AIF1TX5MIX Input 1 Volume */
+	{ 0x00000722, 0x0000 }, /* R1826 (0x722) - AIF1TX5MIX Input 2 Source */
+	{ 0x00000723, 0x0080 }, /* R1827 (0x723) - AIF1TX5MIX Input 2 Volume */
+	{ 0x00000724, 0x0000 }, /* R1828 (0x724) - AIF1TX5MIX Input 3 Source */
+	{ 0x00000725, 0x0080 }, /* R1829 (0x725) - AIF1TX5MIX Input 3 Volume */
+	{ 0x00000726, 0x0000 }, /* R1830 (0x726) - AIF1TX5MIX Input 4 Source */
+	{ 0x00000727, 0x0080 }, /* R1831 (0x727) - AIF1TX5MIX Input 4 Volume */
+	{ 0x00000728, 0x0000 }, /* R1832 (0x728) - AIF1TX6MIX Input 1 Source */
+	{ 0x00000729, 0x0080 }, /* R1833 (0x729) - AIF1TX6MIX Input 1 Volume */
+	{ 0x0000072a, 0x0000 }, /* R1834 (0x72a) - AIF1TX6MIX Input 2 Source */
+	{ 0x0000072b, 0x0080 }, /* R1835 (0x72b) - AIF1TX6MIX Input 2 Volume */
+	{ 0x0000072c, 0x0000 }, /* R1836 (0x72c) - AIF1TX6MIX Input 3 Source */
+	{ 0x0000072d, 0x0080 }, /* R1837 (0x72d) - AIF1TX6MIX Input 3 Volume */
+	{ 0x0000072e, 0x0000 }, /* R1838 (0x72e) - AIF1TX6MIX Input 4 Source */
+	{ 0x0000072f, 0x0080 }, /* R1839 (0x72f) - AIF1TX6MIX Input 4 Volume */
+	{ 0x00000730, 0x0000 }, /* R1840 (0x730) - AIF1TX7MIX Input 1 Source */
+	{ 0x00000731, 0x0080 }, /* R1841 (0x731) - AIF1TX7MIX Input 1 Volume */
+	{ 0x00000732, 0x0000 }, /* R1842 (0x732) - AIF1TX7MIX Input 2 Source */
+	{ 0x00000733, 0x0080 }, /* R1843 (0x733) - AIF1TX7MIX Input 2 Volume */
+	{ 0x00000734, 0x0000 }, /* R1844 (0x734) - AIF1TX7MIX Input 3 Source */
+	{ 0x00000735, 0x0080 }, /* R1845 (0x735) - AIF1TX7MIX Input 3 Volume */
+	{ 0x00000736, 0x0000 }, /* R1846 (0x736) - AIF1TX7MIX Input 4 Source */
+	{ 0x00000737, 0x0080 }, /* R1847 (0x737) - AIF1TX7MIX Input 4 Volume */
+	{ 0x00000738, 0x0000 }, /* R1848 (0x738) - AIF1TX8MIX Input 1 Source */
+	{ 0x00000739, 0x0080 }, /* R1849 (0x739) - AIF1TX8MIX Input 1 Volume */
+	{ 0x0000073a, 0x0000 }, /* R1850 (0x73a) - AIF1TX8MIX Input 2 Source */
+	{ 0x0000073b, 0x0080 }, /* R1851 (0x73b) - AIF1TX8MIX Input 2 Volume */
+	{ 0x0000073c, 0x0000 }, /* R1852 (0x73c) - AIF1TX8MIX Input 3 Source */
+	{ 0x0000073d, 0x0080 }, /* R1853 (0x73d) - AIF1TX8MIX Input 3 Volume */
+	{ 0x0000073e, 0x0000 }, /* R1854 (0x73e) - AIF1TX8MIX Input 4 Source */
+	{ 0x0000073f, 0x0080 }, /* R1855 (0x73f) - AIF1TX8MIX Input 4 Volume */
+	{ 0x00000740, 0x0000 }, /* R1856 (0x740) - AIF2TX1MIX Input 1 Source */
+	{ 0x00000741, 0x0080 }, /* R1857 (0x741) - AIF2TX1MIX Input 1 Volume */
+	{ 0x00000742, 0x0000 }, /* R1858 (0x742) - AIF2TX1MIX Input 2 Source */
+	{ 0x00000743, 0x0080 }, /* R1859 (0x743) - AIF2TX1MIX Input 2 Volume */
+	{ 0x00000744, 0x0000 }, /* R1860 (0x744) - AIF2TX1MIX Input 3 Source */
+	{ 0x00000745, 0x0080 }, /* R1861 (0x745) - AIF2TX1MIX Input 3 Volume */
+	{ 0x00000746, 0x0000 }, /* R1862 (0x746) - AIF2TX1MIX Input 4 Source */
+	{ 0x00000747, 0x0080 }, /* R1863 (0x747) - AIF2TX1MIX Input 4 Volume */
+	{ 0x00000748, 0x0000 }, /* R1864 (0x748) - AIF2TX2MIX Input 1 Source */
+	{ 0x00000749, 0x0080 }, /* R1865 (0x749) - AIF2TX2MIX Input 1 Volume */
+	{ 0x0000074a, 0x0000 }, /* R1866 (0x74a) - AIF2TX2MIX Input 2 Source */
+	{ 0x0000074b, 0x0080 }, /* R1867 (0x74b) - AIF2TX2MIX Input 2 Volume */
+	{ 0x0000074c, 0x0000 }, /* R1868 (0x74c) - AIF2TX2MIX Input 3 Source */
+	{ 0x0000074d, 0x0080 }, /* R1869 (0x74d) - AIF2TX2MIX Input 3 Volume */
+	{ 0x0000074e, 0x0000 }, /* R1870 (0x74e) - AIF2TX2MIX Input 4 Source */
+	{ 0x0000074f, 0x0080 }, /* R1871 (0x74f) - AIF2TX2MIX Input 4 Volume */
+	{ 0x00000750, 0x0000 }, /* R1872 (0x750) - AIF2TX3MIX Input 1 Source */
+	{ 0x00000751, 0x0080 }, /* R1873 (0x751) - AIF2TX3MIX Input 1 Volume */
+	{ 0x00000752, 0x0000 }, /* R1874 (0x752) - AIF2TX3MIX Input 2 Source */
+	{ 0x00000753, 0x0080 }, /* R1875 (0x753) - AIF2TX3MIX Input 2 Volume */
+	{ 0x00000754, 0x0000 }, /* R1876 (0x754) - AIF2TX3MIX Input 3 Source */
+	{ 0x00000755, 0x0080 }, /* R1877 (0x755) - AIF2TX3MIX Input 3 Volume */
+	{ 0x00000756, 0x0000 }, /* R1878 (0x756) - AIF2TX3MIX Input 4 Source */
+	{ 0x00000757, 0x0080 }, /* R1879 (0x757) - AIF2TX3MIX Input 4 Volume */
+	{ 0x00000758, 0x0000 }, /* R1880 (0x758) - AIF2TX4MIX Input 1 Source */
+	{ 0x00000759, 0x0080 }, /* R1881 (0x759) - AIF2TX4MIX Input 1 Volume */
+	{ 0x0000075a, 0x0000 }, /* R1882 (0x75a) - AIF2TX4MIX Input 2 Source */
+	{ 0x0000075b, 0x0080 }, /* R1883 (0x75b) - AIF2TX4MIX Input 2 Volume */
+	{ 0x0000075c, 0x0000 }, /* R1884 (0x75c) - AIF2TX4MIX Input 3 Source */
+	{ 0x0000075d, 0x0080 }, /* R1885 (0x75d) - AIF2TX4MIX Input 3 Volume */
+	{ 0x0000075e, 0x0000 }, /* R1886 (0x75e) - AIF2TX4MIX Input 4 Source */
+	{ 0x0000075f, 0x0080 }, /* R1887 (0x75f) - AIF2TX4MIX Input 4 Volume */
+	{ 0x00000760, 0x0000 }, /* R1888 (0x760) - AIF2TX5MIX Input 1 Source */
+	{ 0x00000761, 0x0080 }, /* R1889 (0x761) - AIF2TX5MIX Input 1 Volume */
+	{ 0x00000762, 0x0000 }, /* R1890 (0x762) - AIF2TX5MIX Input 2 Source */
+	{ 0x00000763, 0x0080 }, /* R1891 (0x763) - AIF2TX5MIX Input 2 Volume */
+	{ 0x00000764, 0x0000 }, /* R1892 (0x764) - AIF2TX5MIX Input 3 Source */
+	{ 0x00000765, 0x0080 }, /* R1893 (0x765) - AIF2TX5MIX Input 3 Volume */
+	{ 0x00000766, 0x0000 }, /* R1894 (0x766) - AIF2TX5MIX Input 4 Source */
+	{ 0x00000767, 0x0080 }, /* R1895 (0x767) - AIF2TX5MIX Input 4 Volume */
+	{ 0x00000768, 0x0000 }, /* R1896 (0x768) - AIF2TX6MIX Input 1 Source */
+	{ 0x00000769, 0x0080 }, /* R1897 (0x769) - AIF2TX6MIX Input 1 Volume */
+	{ 0x0000076a, 0x0000 }, /* R1898 (0x76a) - AIF2TX6MIX Input 2 Source */
+	{ 0x0000076b, 0x0080 }, /* R1899 (0x76b) - AIF2TX6MIX Input 2 Volume */
+	{ 0x0000076c, 0x0000 }, /* R1900 (0x76c) - AIF2TX6MIX Input 3 Source */
+	{ 0x0000076d, 0x0080 }, /* R1901 (0x76d) - AIF2TX6MIX Input 3 Volume */
+	{ 0x0000076e, 0x0000 }, /* R1902 (0x76e) - AIF2TX6MIX Input 4 Source */
+	{ 0x0000076f, 0x0080 }, /* R1903 (0x76f) - AIF2TX6MIX Input 4 Volume */
+	{ 0x00000770, 0x0000 }, /* R1904 (0x770) - AIF2TX7MIX Input 1 Source */
+	{ 0x00000771, 0x0080 }, /* R1905 (0x771) - AIF2TX7MIX Input 1 Volume */
+	{ 0x00000772, 0x0000 }, /* R1906 (0x772) - AIF2TX7MIX Input 2 Source */
+	{ 0x00000773, 0x0080 }, /* R1907 (0x773) - AIF2TX7MIX Input 2 Volume */
+	{ 0x00000774, 0x0000 }, /* R1908 (0x774) - AIF2TX7MIX Input 3 Source */
+	{ 0x00000775, 0x0080 }, /* R1909 (0x775) - AIF2TX7MIX Input 3 Volume */
+	{ 0x00000776, 0x0000 }, /* R1910 (0x776) - AIF2TX7MIX Input 4 Source */
+	{ 0x00000777, 0x0080 }, /* R1911 (0x777) - AIF2TX7MIX Input 4 Volume */
+	{ 0x00000778, 0x0000 }, /* R1912 (0x778) - AIF2TX8MIX Input 1 Source */
+	{ 0x00000779, 0x0080 }, /* R1913 (0x779) - AIF2TX8MIX Input 1 Volume */
+	{ 0x0000077a, 0x0000 }, /* R1914 (0x77a) - AIF2TX8MIX Input 2 Source */
+	{ 0x0000077b, 0x0080 }, /* R1915 (0x77b) - AIF2TX8MIX Input 2 Volume */
+	{ 0x0000077c, 0x0000 }, /* R1916 (0x77c) - AIF2TX8MIX Input 3 Source */
+	{ 0x0000077d, 0x0080 }, /* R1917 (0x77d) - AIF2TX8MIX Input 3 Volume */
+	{ 0x0000077e, 0x0000 }, /* R1918 (0x77e) - AIF2TX8MIX Input 4 Source */
+	{ 0x0000077f, 0x0080 }, /* R1919 (0x77f) - AIF2TX8MIX Input 4 Volume */
+	{ 0x00000780, 0x0000 }, /* R1920 (0x780) - AIF3TX1MIX Input 1 Source */
+	{ 0x00000781, 0x0080 }, /* R1921 (0x781) - AIF3TX1MIX Input 1 Volume */
+	{ 0x00000782, 0x0000 }, /* R1922 (0x782) - AIF3TX1MIX Input 2 Source */
+	{ 0x00000783, 0x0080 }, /* R1923 (0x783) - AIF3TX1MIX Input 2 Volume */
+	{ 0x00000784, 0x0000 }, /* R1924 (0x784) - AIF3TX1MIX Input 3 Source */
+	{ 0x00000785, 0x0080 }, /* R1925 (0x785) - AIF3TX1MIX Input 3 Volume */
+	{ 0x00000786, 0x0000 }, /* R1926 (0x786) - AIF3TX1MIX Input 4 Source */
+	{ 0x00000787, 0x0080 }, /* R1927 (0x787) - AIF3TX1MIX Input 4 Volume */
+	{ 0x00000788, 0x0000 }, /* R1928 (0x788) - AIF3TX2MIX Input 1 Source */
+	{ 0x00000789, 0x0080 }, /* R1929 (0x789) - AIF3TX2MIX Input 1 Volume */
+	{ 0x0000078a, 0x0000 }, /* R1930 (0x78a) - AIF3TX2MIX Input 2 Source */
+	{ 0x0000078b, 0x0080 }, /* R1931 (0x78b) - AIF3TX2MIX Input 2 Volume */
+	{ 0x0000078c, 0x0000 }, /* R1932 (0x78c) - AIF3TX2MIX Input 3 Source */
+	{ 0x0000078d, 0x0080 }, /* R1933 (0x78d) - AIF3TX2MIX Input 3 Volume */
+	{ 0x0000078e, 0x0000 }, /* R1934 (0x78e) - AIF3TX2MIX Input 4 Source */
+	{ 0x0000078f, 0x0080 }, /* R1935 (0x78f) - AIF3TX2MIX Input 4 Volume */
+	{ 0x000007a0, 0x0000 }, /* R1952 (0x7a0) - AIF4TX1MIX Input 1 Source */
+	{ 0x000007a1, 0x0080 }, /* R1953 (0x7a1) - AIF4TX1MIX Input 1 Volume */
+	{ 0x000007a2, 0x0000 }, /* R1954 (0x7a2) - AIF4TX1MIX Input 2 Source */
+	{ 0x000007a3, 0x0080 }, /* R1955 (0x7a3) - AIF4TX1MIX Input 2 Volume */
+	{ 0x000007a4, 0x0000 }, /* R1956 (0x7a4) - AIF4TX1MIX Input 3 Source */
+	{ 0x000007a5, 0x0080 }, /* R1957 (0x7a5) - AIF4TX1MIX Input 3 Volume */
+	{ 0x000007a6, 0x0000 }, /* R1958 (0x7a6) - AIF4TX1MIX Input 4 Source */
+	{ 0x000007a7, 0x0080 }, /* R1959 (0x7a7) - AIF4TX1MIX Input 4 Volume */
+	{ 0x000007a8, 0x0000 }, /* R1960 (0x7a8) - AIF4TX2MIX Input 1 Source */
+	{ 0x000007a9, 0x0080 }, /* R1961 (0x7a9) - AIF4TX2MIX Input 1 Volume */
+	{ 0x000007aa, 0x0000 }, /* R1962 (0x7aa) - AIF4TX2MIX Input 2 Source */
+	{ 0x000007ab, 0x0080 }, /* R1963 (0x7ab) - AIF4TX2MIX Input 2 Volume */
+	{ 0x000007ac, 0x0000 }, /* R1964 (0x7ac) - AIF4TX2MIX Input 3 Source */
+	{ 0x000007ad, 0x0080 }, /* R1965 (0x7ad) - AIF4TX2MIX Input 3 Volume */
+	{ 0x000007ae, 0x0000 }, /* R1966 (0x7ae) - AIF4TX2MIX Input 4 Source */
+	{ 0x000007af, 0x0080 }, /* R1967 (0x7af) - AIF4TX2MIX Input 4 Volume */
+	{ 0x000007c0, 0x0000 }, /* R1984 (0x7c0) - SLIMTX1MIX Input 1 Source */
+	{ 0x000007c1, 0x0080 }, /* R1985 (0x7c1) - SLIMTX1MIX Input 1 Volume */
+	{ 0x000007c2, 0x0000 }, /* R1986 (0x7c2) - SLIMTX1MIX Input 2 Source */
+	{ 0x000007c3, 0x0080 }, /* R1987 (0x7c3) - SLIMTX1MIX Input 2 Volume */
+	{ 0x000007c4, 0x0000 }, /* R1988 (0x7c4) - SLIMTX1MIX Input 3 Source */
+	{ 0x000007c5, 0x0080 }, /* R1989 (0x7c5) - SLIMTX1MIX Input 3 Volume */
+	{ 0x000007c6, 0x0000 }, /* R1990 (0x7c6) - SLIMTX1MIX Input 4 Source */
+	{ 0x000007c7, 0x0080 }, /* R1991 (0x7c7) - SLIMTX1MIX Input 4 Volume */
+	{ 0x000007c8, 0x0000 }, /* R1992 (0x7c8) - SLIMTX2MIX Input 1 Source */
+	{ 0x000007c9, 0x0080 }, /* R1993 (0x7c9) - SLIMTX2MIX Input 1 Volume */
+	{ 0x000007ca, 0x0000 }, /* R1994 (0x7ca) - SLIMTX2MIX Input 2 Source */
+	{ 0x000007cb, 0x0080 }, /* R1995 (0x7cb) - SLIMTX2MIX Input 2 Volume */
+	{ 0x000007cc, 0x0000 }, /* R1996 (0x7cc) - SLIMTX2MIX Input 3 Source */
+	{ 0x000007cd, 0x0080 }, /* R1997 (0x7cd) - SLIMTX2MIX Input 3 Volume */
+	{ 0x000007ce, 0x0000 }, /* R1998 (0x7ce) - SLIMTX2MIX Input 4 Source */
+	{ 0x000007cf, 0x0080 }, /* R1999 (0x7cf) - SLIMTX2MIX Input 4 Volume */
+	{ 0x000007d0, 0x0000 }, /* R2000 (0x7d0) - SLIMTX3MIX Input 1 Source */
+	{ 0x000007d1, 0x0080 }, /* R2001 (0x7d1) - SLIMTX3MIX Input 1 Volume */
+	{ 0x000007d2, 0x0000 }, /* R2002 (0x7d2) - SLIMTX3MIX Input 2 Source */
+	{ 0x000007d3, 0x0080 }, /* R2003 (0x7d3) - SLIMTX3MIX Input 2 Volume */
+	{ 0x000007d4, 0x0000 }, /* R2004 (0x7d4) - SLIMTX3MIX Input 3 Source */
+	{ 0x000007d5, 0x0080 }, /* R2005 (0x7d5) - SLIMTX3MIX Input 3 Volume */
+	{ 0x000007d6, 0x0000 }, /* R2006 (0x7d6) - SLIMTX3MIX Input 4 Source */
+	{ 0x000007d7, 0x0080 }, /* R2007 (0x7d7) - SLIMTX3MIX Input 4 Volume */
+	{ 0x000007d8, 0x0000 }, /* R2008 (0x7d8) - SLIMTX4MIX Input 1 Source */
+	{ 0x000007d9, 0x0080 }, /* R2009 (0x7d9) - SLIMTX4MIX Input 1 Volume */
+	{ 0x000007da, 0x0000 }, /* R2010 (0x7da) - SLIMTX4MIX Input 2 Source */
+	{ 0x000007db, 0x0080 }, /* R2011 (0x7db) - SLIMTX4MIX Input 2 Volume */
+	{ 0x000007dc, 0x0000 }, /* R2012 (0x7dc) - SLIMTX4MIX Input 3 Source */
+	{ 0x000007dd, 0x0080 }, /* R2013 (0x7dd) - SLIMTX4MIX Input 3 Volume */
+	{ 0x000007de, 0x0000 }, /* R2014 (0x7de) - SLIMTX4MIX Input 4 Source */
+	{ 0x000007df, 0x0080 }, /* R2015 (0x7df) - SLIMTX4MIX Input 4 Volume */
+	{ 0x000007e0, 0x0000 }, /* R2016 (0x7e0) - SLIMTX5MIX Input 1 Source */
+	{ 0x000007e1, 0x0080 }, /* R2017 (0x7e1) - SLIMTX5MIX Input 1 Volume */
+	{ 0x000007e2, 0x0000 }, /* R2018 (0x7e2) - SLIMTX5MIX Input 2 Source */
+	{ 0x000007e3, 0x0080 }, /* R2019 (0x7e3) - SLIMTX5MIX Input 2 Volume */
+	{ 0x000007e4, 0x0000 }, /* R2020 (0x7e4) - SLIMTX5MIX Input 3 Source */
+	{ 0x000007e5, 0x0080 }, /* R2021 (0x7e5) - SLIMTX5MIX Input 3 Volume */
+	{ 0x000007e6, 0x0000 }, /* R2022 (0x7e6) - SLIMTX5MIX Input 4 Source */
+	{ 0x000007e7, 0x0080 }, /* R2023 (0x7e7) - SLIMTX5MIX Input 4 Volume */
+	{ 0x000007e8, 0x0000 }, /* R2024 (0x7e8) - SLIMTX6MIX Input 1 Source */
+	{ 0x000007e9, 0x0080 }, /* R2025 (0x7e9) - SLIMTX6MIX Input 1 Volume */
+	{ 0x000007ea, 0x0000 }, /* R2026 (0x7ea) - SLIMTX6MIX Input 2 Source */
+	{ 0x000007eb, 0x0080 }, /* R2027 (0x7eb) - SLIMTX6MIX Input 2 Volume */
+	{ 0x000007ec, 0x0000 }, /* R2028 (0x7ec) - SLIMTX6MIX Input 3 Source */
+	{ 0x000007ed, 0x0080 }, /* R2029 (0x7ed) - SLIMTX6MIX Input 3 Volume */
+	{ 0x000007ee, 0x0000 }, /* R2030 (0x7ee) - SLIMTX6MIX Input 4 Source */
+	{ 0x000007ef, 0x0080 }, /* R2031 (0x7ef) - SLIMTX6MIX Input 4 Volume */
+	{ 0x000007f0, 0x0000 }, /* R2032 (0x7f0) - SLIMTX7MIX Input 1 Source */
+	{ 0x000007f1, 0x0080 }, /* R2033 (0x7f1) - SLIMTX7MIX Input 1 Volume */
+	{ 0x000007f2, 0x0000 }, /* R2034 (0x7f2) - SLIMTX7MIX Input 2 Source */
+	{ 0x000007f3, 0x0080 }, /* R2035 (0x7f3) - SLIMTX7MIX Input 2 Volume */
+	{ 0x000007f4, 0x0000 }, /* R2036 (0x7f4) - SLIMTX7MIX Input 3 Source */
+	{ 0x000007f5, 0x0080 }, /* R2037 (0x7f5) - SLIMTX7MIX Input 3 Volume */
+	{ 0x000007f6, 0x0000 }, /* R2038 (0x7f6) - SLIMTX7MIX Input 4 Source */
+	{ 0x000007f7, 0x0080 }, /* R2039 (0x7f7) - SLIMTX7MIX Input 4 Volume */
+	{ 0x000007f8, 0x0000 }, /* R2040 (0x7f8) - SLIMTX8MIX Input 1 Source */
+	{ 0x000007f9, 0x0080 }, /* R2041 (0x7f9) - SLIMTX8MIX Input 1 Volume */
+	{ 0x000007fa, 0x0000 }, /* R2042 (0x7fa) - SLIMTX8MIX Input 2 Source */
+	{ 0x000007fb, 0x0080 }, /* R2043 (0x7fb) - SLIMTX8MIX Input 2 Volume */
+	{ 0x000007fc, 0x0000 }, /* R2044 (0x7fc) - SLIMTX8MIX Input 3 Source */
+	{ 0x000007fd, 0x0080 }, /* R2045 (0x7fd) - SLIMTX8MIX Input 3 Volume */
+	{ 0x000007fe, 0x0000 }, /* R2046 (0x7fe) - SLIMTX8MIX Input 4 Source */
+	{ 0x000007ff, 0x0080 }, /* R2047 (0x7ff) - SLIMTX8MIX Input 4 Volume */
+	{ 0x00000800, 0x0000 }, /* R2048 (0x800) - SPDIF1TX1MIX Input 1 Source */
+	{ 0x00000801, 0x0080 }, /* R2049 (0x801) - SPDIF1TX1MIX Input 1 Volume */
+	{ 0x00000808, 0x0000 }, /* R2056 (0x808) - SPDIF1TX2MIX Input 1 Source */
+	{ 0x00000809, 0x0080 }, /* R2057 (0x809) - SPDIF1TX2MIX Input 1 Volume */
+	{ 0x00000880, 0x0000 }, /* R2176 (0x880) - EQ1MIX Input 1 Source */
+	{ 0x00000881, 0x0080 }, /* R2177 (0x881) - EQ1MIX Input 1 Volume */
+	{ 0x00000882, 0x0000 }, /* R2178 (0x882) - EQ1MIX Input 2 Source */
+	{ 0x00000883, 0x0080 }, /* R2179 (0x883) - EQ1MIX Input 2 Volume */
+	{ 0x00000884, 0x0000 }, /* R2180 (0x884) - EQ1MIX Input 3 Source */
+	{ 0x00000885, 0x0080 }, /* R2181 (0x885) - EQ1MIX Input 3 Volume */
+	{ 0x00000886, 0x0000 }, /* R2182 (0x886) - EQ1MIX Input 4 Source */
+	{ 0x00000887, 0x0080 }, /* R2183 (0x887) - EQ1MIX Input 4 Volume */
+	{ 0x00000888, 0x0000 }, /* R2184 (0x888) - EQ2MIX Input 1 Source */
+	{ 0x00000889, 0x0080 }, /* R2185 (0x889) - EQ2MIX Input 1 Volume */
+	{ 0x0000088a, 0x0000 }, /* R2186 (0x88a) - EQ2MIX Input 2 Source */
+	{ 0x0000088b, 0x0080 }, /* R2187 (0x88b) - EQ2MIX Input 2 Volume */
+	{ 0x0000088c, 0x0000 }, /* R2188 (0x88c) - EQ2MIX Input 3 Source */
+	{ 0x0000088d, 0x0080 }, /* R2189 (0x88d) - EQ2MIX Input 3 Volume */
+	{ 0x0000088e, 0x0000 }, /* R2190 (0x88e) - EQ2MIX Input 4 Source */
+	{ 0x0000088f, 0x0080 }, /* R2191 (0x88f) - EQ2MIX Input 4 Volume */
+	{ 0x00000890, 0x0000 }, /* R2192 (0x890) - EQ3MIX Input 1 Source */
+	{ 0x00000891, 0x0080 }, /* R2193 (0x891) - EQ3MIX Input 1 Volume */
+	{ 0x00000892, 0x0000 }, /* R2194 (0x892) - EQ3MIX Input 2 Source */
+	{ 0x00000893, 0x0080 }, /* R2195 (0x893) - EQ3MIX Input 2 Volume */
+	{ 0x00000894, 0x0000 }, /* R2196 (0x894) - EQ3MIX Input 3 Source */
+	{ 0x00000895, 0x0080 }, /* R2197 (0x895) - EQ3MIX Input 3 Volume */
+	{ 0x00000896, 0x0000 }, /* R2198 (0x896) - EQ3MIX Input 4 Source */
+	{ 0x00000897, 0x0080 }, /* R2199 (0x897) - EQ3MIX Input 4 Volume */
+	{ 0x00000898, 0x0000 }, /* R2200 (0x898) - EQ4MIX Input 1 Source */
+	{ 0x00000899, 0x0080 }, /* R2201 (0x899) - EQ4MIX Input 1 Volume */
+	{ 0x0000089a, 0x0000 }, /* R2202 (0x89a) - EQ4MIX Input 2 Source */
+	{ 0x0000089b, 0x0080 }, /* R2203 (0x89b) - EQ4MIX Input 2 Volume */
+	{ 0x0000089c, 0x0000 }, /* R2204 (0x89c) - EQ4MIX Input 3 Source */
+	{ 0x0000089d, 0x0080 }, /* R2205 (0x89d) - EQ4MIX Input 3 Volume */
+	{ 0x0000089e, 0x0000 }, /* R2206 (0x89e) - EQ4MIX Input 4 Source */
+	{ 0x0000089f, 0x0080 }, /* R2207 (0x89f) - EQ4MIX Input 4 Volume */
+	{ 0x000008c0, 0x0000 }, /* R2240 (0x8c0) - DRC1LMIX Input 1 Source */
+	{ 0x000008c1, 0x0080 }, /* R2241 (0x8c1) - DRC1LMIX Input 1 Volume */
+	{ 0x000008c2, 0x0000 }, /* R2242 (0x8c2) - DRC1LMIX Input 2 Source */
+	{ 0x000008c3, 0x0080 }, /* R2243 (0x8c3) - DRC1LMIX Input 2 Volume */
+	{ 0x000008c4, 0x0000 }, /* R2244 (0x8c4) - DRC1LMIX Input 3 Source */
+	{ 0x000008c5, 0x0080 }, /* R2245 (0x8c5) - DRC1LMIX Input 3 Volume */
+	{ 0x000008c6, 0x0000 }, /* R2246 (0x8c6) - DRC1LMIX Input 4 Source */
+	{ 0x000008c7, 0x0080 }, /* R2247 (0x8c7) - DRC1LMIX Input 4 Volume */
+	{ 0x000008c8, 0x0000 }, /* R2248 (0x8c8) - DRC1RMIX Input 1 Source */
+	{ 0x000008c9, 0x0080 }, /* R2249 (0x8c9) - DRC1RMIX Input 1 Volume */
+	{ 0x000008ca, 0x0000 }, /* R2250 (0x8ca) - DRC1RMIX Input 2 Source */
+	{ 0x000008cb, 0x0080 }, /* R2251 (0x8cb) - DRC1RMIX Input 2 Volume */
+	{ 0x000008cc, 0x0000 }, /* R2252 (0x8cc) - DRC1RMIX Input 3 Source */
+	{ 0x000008cd, 0x0080 }, /* R2253 (0x8cd) - DRC1RMIX Input 3 Volume */
+	{ 0x000008ce, 0x0000 }, /* R2254 (0x8ce) - DRC1RMIX Input 4 Source */
+	{ 0x000008cf, 0x0080 }, /* R2255 (0x8cf) - DRC1RMIX Input 4 Volume */
+	{ 0x000008d0, 0x0000 }, /* R2256 (0x8d0) - DRC2LMIX Input 1 Source */
+	{ 0x000008d1, 0x0080 }, /* R2257 (0x8d1) - DRC2LMIX Input 1 Volume */
+	{ 0x000008d2, 0x0000 }, /* R2258 (0x8d2) - DRC2LMIX Input 2 Source */
+	{ 0x000008d3, 0x0080 }, /* R2259 (0x8d3) - DRC2LMIX Input 2 Volume */
+	{ 0x000008d4, 0x0000 }, /* R2260 (0x8d4) - DRC2LMIX Input 3 Source */
+	{ 0x000008d5, 0x0080 }, /* R2261 (0x8d5) - DRC2LMIX Input 3 Volume */
+	{ 0x000008d6, 0x0000 }, /* R2262 (0x8d6) - DRC2LMIX Input 4 Source */
+	{ 0x000008d7, 0x0080 }, /* R2263 (0x8d7) - DRC2LMIX Input 4 Volume */
+	{ 0x000008d8, 0x0000 }, /* R2264 (0x8d8) - DRC2RMIX Input 1 Source */
+	{ 0x000008d9, 0x0080 }, /* R2265 (0x8d9) - DRC2RMIX Input 1 Volume */
+	{ 0x000008da, 0x0000 }, /* R2266 (0x8da) - DRC2RMIX Input 2 Source */
+	{ 0x000008db, 0x0080 }, /* R2267 (0x8db) - DRC2RMIX Input 2 Volume */
+	{ 0x000008dc, 0x0000 }, /* R2268 (0x8dc) - DRC2RMIX Input 3 Source */
+	{ 0x000008dd, 0x0080 }, /* R2269 (0x8dd) - DRC2RMIX Input 3 Volume */
+	{ 0x000008de, 0x0000 }, /* R2270 (0x8de) - DRC2RMIX Input 4 Source */
+	{ 0x000008df, 0x0080 }, /* R2271 (0x8df) - DRC2RMIX Input 4 Volume */
+	{ 0x00000900, 0x0000 }, /* R2304 (0x900) - HPLP1MIX Input 1 Source */
+	{ 0x00000901, 0x0080 }, /* R2305 (0x901) - HPLP1MIX Input 1 Volume */
+	{ 0x00000902, 0x0000 }, /* R2306 (0x902) - HPLP1MIX Input 2 Source */
+	{ 0x00000903, 0x0080 }, /* R2307 (0x903) - HPLP1MIX Input 2 Volume */
+	{ 0x00000904, 0x0000 }, /* R2308 (0x904) - HPLP1MIX Input 3 Source */
+	{ 0x00000905, 0x0080 }, /* R2309 (0x905) - HPLP1MIX Input 3 Volume */
+	{ 0x00000906, 0x0000 }, /* R2310 (0x906) - HPLP1MIX Input 4 Source */
+	{ 0x00000907, 0x0080 }, /* R2311 (0x907) - HPLP1MIX Input 4 Volume */
+	{ 0x00000908, 0x0000 }, /* R2312 (0x908) - HPLP2MIX Input 1 Source */
+	{ 0x00000909, 0x0080 }, /* R2313 (0x909) - HPLP2MIX Input 1 Volume */
+	{ 0x0000090a, 0x0000 }, /* R2314 (0x90a) - HPLP2MIX Input 2 Source */
+	{ 0x0000090b, 0x0080 }, /* R2315 (0x90b) - HPLP2MIX Input 2 Volume */
+	{ 0x0000090c, 0x0000 }, /* R2316 (0x90c) - HPLP2MIX Input 3 Source */
+	{ 0x0000090d, 0x0080 }, /* R2317 (0x90d) - HPLP2MIX Input 3 Volume */
+	{ 0x0000090e, 0x0000 }, /* R2318 (0x90e) - HPLP2MIX Input 4 Source */
+	{ 0x0000090f, 0x0080 }, /* R2319 (0x90f) - HPLP2MIX Input 4 Volume */
+	{ 0x00000910, 0x0000 }, /* R2320 (0x910) - HPLP3MIX Input 1 Source */
+	{ 0x00000911, 0x0080 }, /* R2321 (0x911) - HPLP3MIX Input 1 Volume */
+	{ 0x00000912, 0x0000 }, /* R2322 (0x912) - HPLP3MIX Input 2 Source */
+	{ 0x00000913, 0x0080 }, /* R2323 (0x913) - HPLP3MIX Input 2 Volume */
+	{ 0x00000914, 0x0000 }, /* R2324 (0x914) - HPLP3MIX Input 3 Source */
+	{ 0x00000915, 0x0080 }, /* R2325 (0x915) - HPLP3MIX Input 3 Volume */
+	{ 0x00000916, 0x0000 }, /* R2326 (0x916) - HPLP3MIX Input 4 Source */
+	{ 0x00000917, 0x0080 }, /* R2327 (0x917) - HPLP3MIX Input 4 Volume */
+	{ 0x00000918, 0x0000 }, /* R2328 (0x918) - HPLP4MIX Input 1 Source */
+	{ 0x00000919, 0x0080 }, /* R2329 (0x919) - HPLP4MIX Input 1 Volume */
+	{ 0x0000091a, 0x0000 }, /* R2330 (0x91a) - HPLP4MIX Input 2 Source */
+	{ 0x0000091b, 0x0080 }, /* R2331 (0x91b) - HPLP4MIX Input 2 Volume */
+	{ 0x0000091c, 0x0000 }, /* R2332 (0x91c) - HPLP4MIX Input 3 Source */
+	{ 0x0000091d, 0x0080 }, /* R2333 (0x91d) - HPLP4MIX Input 3 Volume */
+	{ 0x0000091e, 0x0000 }, /* R2334 (0x91e) - HPLP4MIX Input 4 Source */
+	{ 0x0000091f, 0x0080 }, /* R2335 (0x91f) - HPLP4MIX Input 4 Volume */
+	{ 0x00000940, 0x0000 }, /* R2368 (0x940) - DSP1LMIX Input 1 Source */
+	{ 0x00000941, 0x0080 }, /* R2369 (0x941) - DSP1LMIX Input 1 Volume */
+	{ 0x00000942, 0x0000 }, /* R2370 (0x942) - DSP1LMIX Input 2 Source */
+	{ 0x00000943, 0x0080 }, /* R2371 (0x943) - DSP1LMIX Input 2 Volume */
+	{ 0x00000944, 0x0000 }, /* R2372 (0x944) - DSP1LMIX Input 3 Source */
+	{ 0x00000945, 0x0080 }, /* R2373 (0x945) - DSP1LMIX Input 3 Volume */
+	{ 0x00000946, 0x0000 }, /* R2374 (0x946) - DSP1LMIX Input 4 Source */
+	{ 0x00000947, 0x0080 }, /* R2375 (0x947) - DSP1LMIX Input 4 Volume */
+	{ 0x00000948, 0x0000 }, /* R2376 (0x948) - DSP1RMIX Input 1 Source */
+	{ 0x00000949, 0x0080 }, /* R2377 (0x949) - DSP1RMIX Input 1 Volume */
+	{ 0x0000094a, 0x0000 }, /* R2378 (0x94a) - DSP1RMIX Input 2 Source */
+	{ 0x0000094b, 0x0080 }, /* R2379 (0x94b) - DSP1RMIX Input 2 Volume */
+	{ 0x0000094c, 0x0000 }, /* R2380 (0x94c) - DSP1RMIX Input 3 Source */
+	{ 0x0000094d, 0x0080 }, /* R2381 (0x94d) - DSP1RMIX Input 3 Volume */
+	{ 0x0000094e, 0x0000 }, /* R2382 (0x94e) - DSP1RMIX Input 4 Source */
+	{ 0x0000094f, 0x0080 }, /* R2383 (0x94f) - DSP1RMIX Input 4 Volume */
+	{ 0x00000950, 0x0000 }, /* R2384 (0x950) - DSP1AUX1MIX Input 1 Source */
+	{ 0x00000958, 0x0000 }, /* R2392 (0x958) - DSP1AUX2MIX Input 1 Source */
+	{ 0x00000960, 0x0000 }, /* R2400 (0x960) - DSP1AUX3MIX Input 1 Source */
+	{ 0x00000968, 0x0000 }, /* R2408 (0x968) - DSP1AUX4MIX Input 1 Source */
+	{ 0x00000970, 0x0000 }, /* R2416 (0x970) - DSP1AUX5MIX Input 1 Source */
+	{ 0x00000978, 0x0000 }, /* R2424 (0x978) - DSP1AUX6MIX Input 1 Source */
+	{ 0x00000980, 0x0000 }, /* R2432 (0x980) - DSP2LMIX Input 1 Source */
+	{ 0x00000981, 0x0080 }, /* R2433 (0x981) - DSP2LMIX Input 1 Volume */
+	{ 0x00000982, 0x0000 }, /* R2434 (0x982) - DSP2LMIX Input 2 Source */
+	{ 0x00000983, 0x0080 }, /* R2435 (0x983) - DSP2LMIX Input 2 Volume */
+	{ 0x00000984, 0x0000 }, /* R2436 (0x984) - DSP2LMIX Input 3 Source */
+	{ 0x00000985, 0x0080 }, /* R2437 (0x985) - DSP2LMIX Input 3 Volume */
+	{ 0x00000986, 0x0000 }, /* R2438 (0x986) - DSP2LMIX Input 4 Source */
+	{ 0x00000987, 0x0080 }, /* R2439 (0x987) - DSP2LMIX Input 4 Volume */
+	{ 0x00000988, 0x0000 }, /* R2440 (0x988) - DSP2RMIX Input 1 Source */
+	{ 0x00000989, 0x0080 }, /* R2441 (0x989) - DSP2RMIX Input 1 Volume */
+	{ 0x0000098a, 0x0000 }, /* R2442 (0x98a) - DSP2RMIX Input 2 Source */
+	{ 0x0000098b, 0x0080 }, /* R2443 (0x98b) - DSP2RMIX Input 2 Volume */
+	{ 0x0000098c, 0x0000 }, /* R2444 (0x98c) - DSP2RMIX Input 3 Source */
+	{ 0x0000098d, 0x0080 }, /* R2445 (0x98d) - DSP2RMIX Input 3 Volume */
+	{ 0x0000098e, 0x0000 }, /* R2446 (0x98e) - DSP2RMIX Input 4 Source */
+	{ 0x0000098f, 0x0080 }, /* R2447 (0x98f) - DSP2RMIX Input 4 Volume */
+	{ 0x00000990, 0x0000 }, /* R2448 (0x990) - DSP2AUX1MIX Input 1 Source */
+	{ 0x00000998, 0x0000 }, /* R2456 (0x998) - DSP2AUX2MIX Input 1 Source */
+	{ 0x000009a0, 0x0000 }, /* R2464 (0x9a0) - DSP2AUX3MIX Input 1 Source */
+	{ 0x000009a8, 0x0000 }, /* R2472 (0x9a8) - DSP2AUX4MIX Input 1 Source */
+	{ 0x000009b0, 0x0000 }, /* R2480 (0x9b0) - DSP2AUX5MIX Input 1 Source */
+	{ 0x000009b8, 0x0000 }, /* R2488 (0x9b8) - DSP2AUX6MIX Input 1 Source */
+	{ 0x000009c0, 0x0000 }, /* R2496 (0x9c0) - DSP3LMIX Input 1 Source */
+	{ 0x000009c1, 0x0080 }, /* R2497 (0x9c1) - DSP3LMIX Input 1 Volume */
+	{ 0x000009c2, 0x0000 }, /* R2498 (0x9c2) - DSP3LMIX Input 2 Source */
+	{ 0x000009c3, 0x0080 }, /* R2499 (0x9c3) - DSP3LMIX Input 2 Volume */
+	{ 0x000009c4, 0x0000 }, /* R2500 (0x9c4) - DSP3LMIX Input 3 Source */
+	{ 0x000009c5, 0x0080 }, /* R2501 (0x9c5) - DSP3LMIX Input 3 Volume */
+	{ 0x000009c6, 0x0000 }, /* R2502 (0x9c6) - DSP3LMIX Input 4 Source */
+	{ 0x000009c7, 0x0080 }, /* R2503 (0x9c7) - DSP3LMIX Input 4 Volume */
+	{ 0x000009c8, 0x0000 }, /* R2504 (0x9c8) - DSP3RMIX Input 1 Source */
+	{ 0x000009c9, 0x0080 }, /* R2505 (0x9c9) - DSP3RMIX Input 1 Volume */
+	{ 0x000009ca, 0x0000 }, /* R2506 (0x9ca) - DSP3RMIX Input 2 Source */
+	{ 0x000009cb, 0x0080 }, /* R2507 (0x9cb) - DSP3RMIX Input 2 Volume */
+	{ 0x000009cc, 0x0000 }, /* R2508 (0x9cc) - DSP3RMIX Input 3 Source */
+	{ 0x000009cd, 0x0080 }, /* R2509 (0x9cd) - DSP3RMIX Input 3 Volume */
+	{ 0x000009ce, 0x0000 }, /* R2510 (0x9ce) - DSP3RMIX Input 4 Source */
+	{ 0x000009cf, 0x0080 }, /* R2511 (0x9cf) - DSP3RMIX Input 4 Volume */
+	{ 0x000009d0, 0x0000 }, /* R2512 (0x9d0) - DSP3AUX1MIX Input 1 Source */
+	{ 0x000009d8, 0x0000 }, /* R2520 (0x9d8) - DSP3AUX2MIX Input 1 Source */
+	{ 0x000009e0, 0x0000 }, /* R2528 (0x9e0) - DSP3AUX3MIX Input 1 Source */
+	{ 0x000009e8, 0x0000 }, /* R2536 (0x9e8) - DSP3AUX4MIX Input 1 Source */
+	{ 0x000009f0, 0x0000 }, /* R2544 (0x9f0) - DSP3AUX5MIX Input 1 Source */
+	{ 0x000009f8, 0x0000 }, /* R2552 (0x9f8) - DSP3AUX6MIX Input 1 Source */
+	{ 0x00000a00, 0x0000 }, /* R2560 (0xa00) - DSP4LMIX Input 1 Source */
+	{ 0x00000a01, 0x0080 }, /* R2561 (0xa01) - DSP4LMIX Input 1 Volume */
+	{ 0x00000a02, 0x0000 }, /* R2562 (0xa02) - DSP4LMIX Input 2 Source */
+	{ 0x00000a03, 0x0080 }, /* R2563 (0xa03) - DSP4LMIX Input 2 Volume */
+	{ 0x00000a04, 0x0000 }, /* R2564 (0xa04) - DSP4LMIX Input 3 Source */
+	{ 0x00000a05, 0x0080 }, /* R2565 (0xa05) - DSP4LMIX Input 3 Volume */
+	{ 0x00000a06, 0x0000 }, /* R2566 (0xa06) - DSP4LMIX Input 4 Source */
+	{ 0x00000a07, 0x0080 }, /* R2567 (0xa07) - DSP4LMIX Input 4 Volume */
+	{ 0x00000a08, 0x0000 }, /* R2568 (0xa08) - DSP4RMIX Input 1 Source */
+	{ 0x00000a09, 0x0080 }, /* R2569 (0xa09) - DSP4RMIX Input 1 Volume */
+	{ 0x00000a0a, 0x0000 }, /* R2570 (0xa0a) - DSP4RMIX Input 2 Source */
+	{ 0x00000a0b, 0x0080 }, /* R2571 (0xa0b) - DSP4RMIX Input 2 Volume */
+	{ 0x00000a0c, 0x0000 }, /* R2572 (0xa0c) - DSP4RMIX Input 3 Source */
+	{ 0x00000a0d, 0x0080 }, /* R2573 (0xa0d) - DSP4RMIX Input 3 Volume */
+	{ 0x00000a0e, 0x0000 }, /* R2574 (0xa0e) - DSP4RMIX Input 4 Source */
+	{ 0x00000a0f, 0x0080 }, /* R2575 (0xa0f) - DSP4RMIX Input 4 Volume */
+	{ 0x00000a10, 0x0000 }, /* R2576 (0xa10) - DSP4AUX1MIX Input 1 Source */
+	{ 0x00000a18, 0x0000 }, /* R2584 (0xa18) - DSP4AUX2MIX Input 1 Source */
+	{ 0x00000a20, 0x0000 }, /* R2592 (0xa20) - DSP4AUX3MIX Input 1 Source */
+	{ 0x00000a28, 0x0000 }, /* R2600 (0xa28) - DSP4AUX4MIX Input 1 Source */
+	{ 0x00000a30, 0x0000 }, /* R2608 (0xa30) - DSP4AUX5MIX Input 1 Source */
+	{ 0x00000a38, 0x0000 }, /* R2616 (0xa38) - DSP4AUX6MIX Input 1 Source */
+	{ 0x00000a40, 0x0000 }, /* R2624 (0xa40) - DSP5LMIX Input 1 Source */
+	{ 0x00000a41, 0x0080 }, /* R2625 (0xa41) - DSP5LMIX Input 1 Volume */
+	{ 0x00000a42, 0x0000 }, /* R2626 (0xa42) - DSP5LMIX Input 2 Source */
+	{ 0x00000a43, 0x0080 }, /* R2627 (0xa43) - DSP5LMIX Input 2 Volume */
+	{ 0x00000a44, 0x0000 }, /* R2628 (0xa44) - DSP5LMIX Input 3 Source */
+	{ 0x00000a45, 0x0080 }, /* R2629 (0xa45) - DSP5LMIX Input 3 Volume */
+	{ 0x00000a46, 0x0000 }, /* R2630 (0xa46) - DSP5LMIX Input 4 Source */
+	{ 0x00000a47, 0x0080 }, /* R2631 (0xa47) - DSP5LMIX Input 4 Volume */
+	{ 0x00000a48, 0x0000 }, /* R2632 (0xa48) - DSP5RMIX Input 1 Source */
+	{ 0x00000a49, 0x0080 }, /* R2633 (0xa49) - DSP5RMIX Input 1 Volume */
+	{ 0x00000a4a, 0x0000 }, /* R2634 (0xa4a) - DSP5RMIX Input 2 Source */
+	{ 0x00000a4b, 0x0080 }, /* R2635 (0xa4b) - DSP5RMIX Input 2 Volume */
+	{ 0x00000a4c, 0x0000 }, /* R2636 (0xa4c) - DSP5RMIX Input 3 Source */
+	{ 0x00000a4d, 0x0080 }, /* R2637 (0xa4d) - DSP5RMIX Input 3 Volume */
+	{ 0x00000a4e, 0x0000 }, /* R2638 (0xa4e) - DSP5RMIX Input 4 Source */
+	{ 0x00000a4f, 0x0080 }, /* R2639 (0xa4f) - DSP5RMIX Input 4 Volume */
+	{ 0x00000a50, 0x0000 }, /* R2640 (0xa50) - DSP5AUX1MIX Input 1 Source */
+	{ 0x00000a58, 0x0000 }, /* R2658 (0xa58) - DSP5AUX2MIX Input 1 Source */
+	{ 0x00000a60, 0x0000 }, /* R2656 (0xa60) - DSP5AUX3MIX Input 1 Source */
+	{ 0x00000a68, 0x0000 }, /* R2664 (0xa68) - DSP5AUX4MIX Input 1 Source */
+	{ 0x00000a70, 0x0000 }, /* R2672 (0xa70) - DSP5AUX5MIX Input 1 Source */
+	{ 0x00000a78, 0x0000 }, /* R2680 (0xa78) - DSP5AUX6MIX Input 1 Source */
+	{ 0x00000a80, 0x0000 }, /* R2688 (0xa80) - ASRC1_1LMIX Input 1 Source */
+	{ 0x00000a88, 0x0000 }, /* R2696 (0xa88) - ASRC1_1RMIX Input 1 Source */
+	{ 0x00000a90, 0x0000 }, /* R2704 (0xa90) - ASRC1_2LMIX Input 1 Source */
+	{ 0x00000a98, 0x0000 }, /* R2712 (0xa98) - ASRC1_2RMIX Input 1 Source */
+	{ 0x00000aa0, 0x0000 }, /* R2720 (0xaa0) - ASRC2_1LMIX Input 1 Source */
+	{ 0x00000aa8, 0x0000 }, /* R2728 (0xaa8) - ASRC2_1RMIX Input 1 Source */
+	{ 0x00000ab0, 0x0000 }, /* R2736 (0xab0) - ASRC2_2LMIX Input 1 Source */
+	{ 0x00000ab8, 0x0000 }, /* R2744 (0xab8) - ASRC2_2RMIX Input 1 Source */
+	{ 0x00000b00, 0x0000 }, /* R2816 (0xb00) - ISRC1DEC1MIX Input 1 Source*/
+	{ 0x00000b08, 0x0000 }, /* R2824 (0xb08) - ISRC1DEC2MIX Input 1 Source*/
+	{ 0x00000b10, 0x0000 }, /* R2832 (0xb10) - ISRC1DEC3MIX Input 1 Source*/
+	{ 0x00000b18, 0x0000 }, /* R2840 (0xb18) - ISRC1DEC4MIX Input 1 Source*/
+	{ 0x00000b20, 0x0000 }, /* R2848 (0xb20) - ISRC1INT1MIX Input 1 Source*/
+	{ 0x00000b28, 0x0000 }, /* R2856 (0xb28) - ISRC1INT2MIX Input 1 Source*/
+	{ 0x00000b30, 0x0000 }, /* R2864 (0xb30) - ISRC1INT3MIX Input 1 Source*/
+	{ 0x00000b38, 0x0000 }, /* R2872 (0xb38) - ISRC1INT4MIX Input 1 Source*/
+	{ 0x00000b40, 0x0000 }, /* R2880 (0xb40) - ISRC2DEC1MIX Input 1 Source*/
+	{ 0x00000b48, 0x0000 }, /* R2888 (0xb48) - ISRC2DEC2MIX Input 1 Source*/
+	{ 0x00000b50, 0x0000 }, /* R2896 (0xb50) - ISRC2DEC3MIX Input 1 Source*/
+	{ 0x00000b58, 0x0000 }, /* R2904 (0xb58) - ISRC2DEC4MIX Input 1 Source*/
+	{ 0x00000b60, 0x0000 }, /* R2912 (0xb60) - ISRC2INT1MIX Input 1 Source*/
+	{ 0x00000b68, 0x0000 }, /* R2920 (0xb68) - ISRC2INT2MIX Input 1 Source*/
+	{ 0x00000b70, 0x0000 }, /* R2928 (0xb70) - ISRC2INT3MIX Input 1 Source*/
+	{ 0x00000b78, 0x0000 }, /* R2936 (0xb78) - ISRC2INT4MIX Input 1 Source*/
+	{ 0x00000b80, 0x0000 }, /* R2944 (0xb80) - ISRC3DEC1MIX Input 1 Source*/
+	{ 0x00000b88, 0x0000 }, /* R2952 (0xb88) - ISRC3DEC2MIX Input 1 Source*/
+	{ 0x00000ba0, 0x0000 }, /* R2976 (0xb80) - ISRC3INT1MIX Input 1 Source*/
+	{ 0x00000ba8, 0x0000 }, /* R2984 (0xb88) - ISRC3INT2MIX Input 1 Source*/
+	{ 0x00000bc0, 0x0000 }, /* R3008 (0xbc0) - ISRC4DEC1MIX Input 1 Source */
+	{ 0x00000bc8, 0x0000 }, /* R3016 (0xbc8) - ISRC4DEC2MIX Input 1 Source */
+	{ 0x00000be0, 0x0000 }, /* R3040 (0xbe0) - ISRC4INT1MIX Input 1 Source */
+	{ 0x00000be8, 0x0000 }, /* R3048 (0xbe8) - ISRC4INT2MIX Input 1 Source */
+	{ 0x00000c00, 0x0000 }, /* R3072 (0xc00) - DSP6LMIX Input 1 Source */
+	{ 0x00000c01, 0x0080 }, /* R3073 (0xc01) - DSP6LMIX Input 1 Volume */
+	{ 0x00000c02, 0x0000 }, /* R3074 (0xc02) - DSP6LMIX Input 2 Source */
+	{ 0x00000c03, 0x0080 }, /* R3075 (0xc03) - DSP6LMIX Input 2 Volume */
+	{ 0x00000c04, 0x0000 }, /* R3076 (0xc04) - DSP6LMIX Input 3 Source */
+	{ 0x00000c05, 0x0080 }, /* R3077 (0xc05) - DSP6LMIX Input 3 Volume */
+	{ 0x00000c06, 0x0000 }, /* R3078 (0xc06) - DSP6LMIX Input 4 Source */
+	{ 0x00000c07, 0x0080 }, /* R3079 (0xc07) - DSP6LMIX Input 4 Volume */
+	{ 0x00000c08, 0x0000 }, /* R3080 (0xc08) - DSP6RMIX Input 1 Source */
+	{ 0x00000c09, 0x0080 }, /* R3081 (0xc09) - DSP6RMIX Input 1 Volume */
+	{ 0x00000c0a, 0x0000 }, /* R3082 (0xc0a) - DSP6RMIX Input 2 Source */
+	{ 0x00000c0b, 0x0080 }, /* R3083 (0xc0b) - DSP6RMIX Input 2 Volume */
+	{ 0x00000c0c, 0x0000 }, /* R3084 (0xc0c) - DSP6RMIX Input 3 Source */
+	{ 0x00000c0d, 0x0080 }, /* R3085 (0xc0d) - DSP6RMIX Input 3 Volume */
+	{ 0x00000c0e, 0x0000 }, /* R3086 (0xc0e) - DSP6RMIX Input 4 Source */
+	{ 0x00000c0f, 0x0080 }, /* R3087 (0xc0f) - DSP6RMIX Input 4 Volume */
+	{ 0x00000c10, 0x0000 }, /* R3088 (0xc10) - DSP6AUX1MIX Input 1 Source */
+	{ 0x00000c18, 0x0000 }, /* R3088 (0xc18) - DSP6AUX2MIX Input 1 Source */
+	{ 0x00000c20, 0x0000 }, /* R3088 (0xc20) - DSP6AUX3MIX Input 1 Source */
+	{ 0x00000c28, 0x0000 }, /* R3088 (0xc28) - DSP6AUX4MIX Input 1 Source */
+	{ 0x00000c30, 0x0000 }, /* R3088 (0xc30) - DSP6AUX5MIX Input 1 Source */
+	{ 0x00000c38, 0x0000 }, /* R3088 (0xc38) - DSP6AUX6MIX Input 1 Source */
+	{ 0x00000c40, 0x0000 }, /* R3136 (0xc40) - DSP7LMIX Input 1 Source */
+	{ 0x00000c41, 0x0080 }, /* R3137 (0xc41) - DSP7LMIX Input 1 Volume */
+	{ 0x00000c42, 0x0000 }, /* R3138 (0xc42) - DSP7LMIX Input 2 Source */
+	{ 0x00000c43, 0x0080 }, /* R3139 (0xc43) - DSP7LMIX Input 2 Volume */
+	{ 0x00000c44, 0x0000 }, /* R3140 (0xc44) - DSP7LMIX Input 3 Source */
+	{ 0x00000c45, 0x0080 }, /* R3141 (0xc45) - DSP7lMIX Input 3 Volume */
+	{ 0x00000c46, 0x0000 }, /* R3142 (0xc46) - DSP7lMIX Input 4 Source */
+	{ 0x00000c47, 0x0080 }, /* R3143 (0xc47) - DSP7LMIX Input 4 Volume */
+	{ 0x00000c48, 0x0000 }, /* R3144 (0xc48) - DSP7RMIX Input 1 Source */
+	{ 0x00000c49, 0x0080 }, /* R3145 (0xc49) - DSP7RMIX Input 1 Volume */
+	{ 0x00000c4a, 0x0000 }, /* R3146 (0xc4a) - DSP7RMIX Input 2 Source */
+	{ 0x00000c4b, 0x0080 }, /* R3147 (0xc4b) - DSP7RMIX Input 2 Volume */
+	{ 0x00000c4c, 0x0000 }, /* R3148 (0xc4c) - DSP7RMIX Input 3 Source */
+	{ 0x00000c4d, 0x0080 }, /* R3159 (0xc4d) - DSP7RMIX Input 3 Volume */
+	{ 0x00000c4e, 0x0000 }, /* R3150 (0xc4e) - DSP7RMIX Input 4 Source */
+	{ 0x00000c4f, 0x0080 }, /* R3151 (0xc4f) - DSP7RMIX Input 4 Volume */
+	{ 0x00000c50, 0x0000 }, /* R3152 (0xc50) - DSP7AUX1MIX Input 1 Source */
+	{ 0x00000c58, 0x0000 }, /* R3160 (0xc58) - DSP7AUX2MIX Input 1 Source */
+	{ 0x00000c60, 0x0000 }, /* R3168 (0xc60) - DSP7AUX3MIX Input 1 Source */
+	{ 0x00000c68, 0x0000 }, /* R3176 (0xc68) - DSP7AUX4MIX Input 1 Source */
+	{ 0x00000c70, 0x0000 }, /* R3184 (0xc70) - DSP7AUX5MIX Input 1 Source */
+	{ 0x00000c78, 0x0000 }, /* R3192 (0xc78) - DSP7AUX6MIX Input 1 Source */
+	{ 0x00000e00, 0x0000 }, /* R3584 (0xe00) - FX Ctrl1 */
+	{ 0x00000e10, 0x6318 }, /* R3600 (0xe10) - EQ1_1 */
+	{ 0x00000e11, 0x6300 }, /* R3601 (0xe11) - EQ1_2 */
+	{ 0x00000e12, 0x0fc8 }, /* R3602 (0xe12) - EQ1_3 */
+	{ 0x00000e13, 0x03fe }, /* R3603 (0xe13) - EQ1_4 */
+	{ 0x00000e14, 0x00e0 }, /* R3604 (0xe14) - EQ1_5 */
+	{ 0x00000e15, 0x1ec4 }, /* R3605 (0xe15) - EQ1_6 */
+	{ 0x00000e16, 0xf136 }, /* R3606 (0xe16) - EQ1_7 */
+	{ 0x00000e17, 0x0409 }, /* R3607 (0xe17) - EQ1_8 */
+	{ 0x00000e18, 0x04cc }, /* R3608 (0xe18) - EQ1_9 */
+	{ 0x00000e19, 0x1c9b }, /* R3609 (0xe19) - EQ1_10 */
+	{ 0x00000e1a, 0xf337 }, /* R3610 (0xe1a) - EQ1_11 */
+	{ 0x00000e1b, 0x040b }, /* R3611 (0xe1b) - EQ1_12 */
+	{ 0x00000e1c, 0x0cbb }, /* R3612 (0xe1c) - EQ1_13 */
+	{ 0x00000e1d, 0x16f8 }, /* R3613 (0xe1d) - EQ1_14 */
+	{ 0x00000e1e, 0xf7d9 }, /* R3614 (0xe1e) - EQ1_15 */
+	{ 0x00000e1f, 0x040a }, /* R3615 (0xe1f) - EQ1_16 */
+	{ 0x00000e20, 0x1f14 }, /* R3616 (0xe20) - EQ1_17 */
+	{ 0x00000e21, 0x058c }, /* R3617 (0xe21) - EQ1_18 */
+	{ 0x00000e22, 0x0563 }, /* R3618 (0xe22) - EQ1_19 */
+	{ 0x00000e23, 0x4000 }, /* R3619 (0xe23) - EQ1_20 */
+	{ 0x00000e24, 0x0b75 }, /* R3620 (0xe24) - EQ1_21 */
+	{ 0x00000e26, 0x6318 }, /* R3622 (0xe26) - EQ2_1 */
+	{ 0x00000e27, 0x6300 }, /* R3623 (0xe27) - EQ2_2 */
+	{ 0x00000e28, 0x0fc8 }, /* R3624 (0xe28) - EQ2_3 */
+	{ 0x00000e29, 0x03fe }, /* R3625 (0xe29) - EQ2_4 */
+	{ 0x00000e2a, 0x00e0 }, /* R3626 (0xe2a) - EQ2_5 */
+	{ 0x00000e2b, 0x1ec4 }, /* R3627 (0xe2b) - EQ2_6 */
+	{ 0x00000e2c, 0xf136 }, /* R3628 (0xe2c) - EQ2_7 */
+	{ 0x00000e2d, 0x0409 }, /* R3629 (0xe2d) - EQ2_8 */
+	{ 0x00000e2e, 0x04cc }, /* R3630 (0xe2e) - EQ2_9 */
+	{ 0x00000e2f, 0x1c9b }, /* R3631 (0xe2f) - EQ2_10 */
+	{ 0x00000e30, 0xf337 }, /* R3632 (0xe30) - EQ2_11 */
+	{ 0x00000e31, 0x040b }, /* R3633 (0xe31) - EQ2_12 */
+	{ 0x00000e32, 0x0cbb }, /* R3634 (0xe32) - EQ2_13 */
+	{ 0x00000e33, 0x16f8 }, /* R3635 (0xe33) - EQ2_14 */
+	{ 0x00000e34, 0xf7d9 }, /* R3636 (0xe34) - EQ2_15 */
+	{ 0x00000e35, 0x040a }, /* R3637 (0xe35) - EQ2_16 */
+	{ 0x00000e36, 0x1f14 }, /* R3638 (0xe36) - EQ2_17 */
+	{ 0x00000e37, 0x058c }, /* R3639 (0xe37) - EQ2_18 */
+	{ 0x00000e38, 0x0563 }, /* R3640 (0xe38) - EQ2_19 */
+	{ 0x00000e39, 0x4000 }, /* R3641 (0xe39) - EQ2_20 */
+	{ 0x00000e3a, 0x0b75 }, /* R3642 (0xe3a) - EQ2_21 */
+	{ 0x00000e3c, 0x6318 }, /* R3644 (0xe3c) - EQ3_1 */
+	{ 0x00000e3d, 0x6300 }, /* R3645 (0xe3d) - EQ3_2 */
+	{ 0x00000e3e, 0x0fc8 }, /* R3646 (0xe3e) - EQ3_3 */
+	{ 0x00000e3f, 0x03fe }, /* R3647 (0xe3f) - EQ3_4 */
+	{ 0x00000e40, 0x00e0 }, /* R3648 (0xe40) - EQ3_5 */
+	{ 0x00000e41, 0x1ec4 }, /* R3649 (0xe41) - EQ3_6 */
+	{ 0x00000e42, 0xf136 }, /* R3650 (0xe42) - EQ3_7 */
+	{ 0x00000e43, 0x0409 }, /* R3651 (0xe43) - EQ3_8 */
+	{ 0x00000e44, 0x04cc }, /* R3652 (0xe44) - EQ3_9 */
+	{ 0x00000e45, 0x1c9b }, /* R3653 (0xe45) - EQ3_10 */
+	{ 0x00000e46, 0xf337 }, /* R3654 (0xe46) - EQ3_11 */
+	{ 0x00000e47, 0x040b }, /* R3655 (0xe47) - EQ3_12 */
+	{ 0x00000e48, 0x0cbb }, /* R3656 (0xe48) - EQ3_13 */
+	{ 0x00000e49, 0x16f8 }, /* R3657 (0xe49) - EQ3_14 */
+	{ 0x00000e4a, 0xf7d9 }, /* R3658 (0xe4a) - EQ3_15 */
+	{ 0x00000e4b, 0x040a }, /* R3659 (0xe4b) - EQ3_16 */
+	{ 0x00000e4c, 0x1f14 }, /* R3660 (0xe4c) - EQ3_17 */
+	{ 0x00000e4d, 0x058c }, /* R3661 (0xe4d) - EQ3_18 */
+	{ 0x00000e4e, 0x0563 }, /* R3662 (0xe4e) - EQ3_19 */
+	{ 0x00000e4f, 0x4000 }, /* R3663 (0xe4f) - EQ3_20 */
+	{ 0x00000e50, 0x0b75 }, /* R3664 (0xe50) - EQ3_21 */
+	{ 0x00000e52, 0x6318 }, /* R3666 (0xe52) - EQ4_1 */
+	{ 0x00000e53, 0x6300 }, /* R3667 (0xe53) - EQ4_2 */
+	{ 0x00000e54, 0x0fc8 }, /* R3668 (0xe54) - EQ4_3 */
+	{ 0x00000e55, 0x03fe }, /* R3669 (0xe55) - EQ4_4 */
+	{ 0x00000e56, 0x00e0 }, /* R3670 (0xe56) - EQ4_5 */
+	{ 0x00000e57, 0x1ec4 }, /* R3671 (0xe57) - EQ4_6 */
+	{ 0x00000e58, 0xf136 }, /* R3672 (0xe58) - EQ4_7 */
+	{ 0x00000e59, 0x0409 }, /* R3673 (0xe59) - EQ4_8 */
+	{ 0x00000e5a, 0x04cc }, /* R3674 (0xe5a) - EQ4_9 */
+	{ 0x00000e5b, 0x1c9b }, /* R3675 (0xe5b) - EQ4_10 */
+	{ 0x00000e5c, 0xf337 }, /* R3676 (0xe5c) - EQ4_11 */
+	{ 0x00000e5d, 0x040b }, /* R3677 (0xe5d) - EQ4_12 */
+	{ 0x00000e5e, 0x0cbb }, /* R3678 (0xe5e) - EQ4_13 */
+	{ 0x00000e5f, 0x16f8 }, /* R3679 (0xe5f) - EQ4_14 */
+	{ 0x00000e60, 0xf7d9 }, /* R3680 (0xe60) - EQ4_15 */
+	{ 0x00000e61, 0x040a }, /* R3681 (0xe61) - EQ4_16 */
+	{ 0x00000e62, 0x1f14 }, /* R3682 (0xe62) - EQ4_17 */
+	{ 0x00000e63, 0x058c }, /* R3683 (0xe63) - EQ4_18 */
+	{ 0x00000e64, 0x0563 }, /* R3684 (0xe64) - EQ4_19 */
+	{ 0x00000e65, 0x4000 }, /* R3685 (0xe65) - EQ4_20 */
+	{ 0x00000e66, 0x0b75 }, /* R3686 (0xe66) - EQ4_21 */
+	{ 0x00000e80, 0x0018 }, /* R3712 (0xe80) - DRC1 ctrl1 */
+	{ 0x00000e81, 0x0933 }, /* R3713 (0xe81) - DRC1 ctrl2 */
+	{ 0x00000e82, 0x0018 }, /* R3714 (0xe82) - DRC1 ctrl3 */
+	{ 0x00000e83, 0x0000 }, /* R3715 (0xe83) - DRC1 ctrl4 */
+	{ 0x00000e84, 0x0000 }, /* R3716 (0xe84) - DRC1 ctrl5 */
+	{ 0x00000e88, 0x0933 }, /* R3720 (0xe88) - DRC2 ctrl1 */
+	{ 0x00000e89, 0x0018 }, /* R3721 (0xe89) - DRC2 ctrl2 */
+	{ 0x00000e8a, 0x0000 }, /* R3722 (0xe8a) - DRC2 ctrl3 */
+	{ 0x00000e8b, 0x0000 }, /* R3723 (0xe8b) - DRC2 ctrl4 */
+	{ 0x00000e8c, 0x0040 }, /* R3724 (0xe8c) - DRC2 ctrl5 */
+	{ 0x00000ec0, 0x0000 }, /* R3776 (0xec0) - HPLPF1_1 */
+	{ 0x00000ec1, 0x0000 }, /* R3777 (0xec1) - HPLPF1_2 */
+	{ 0x00000ec4, 0x0000 }, /* R3780 (0xec4) - HPLPF2_1 */
+	{ 0x00000ec5, 0x0000 }, /* R3781 (0xec5) - HPLPF2_2 */
+	{ 0x00000ec8, 0x0000 }, /* R3784 (0xec8) - HPLPF3_1 */
+	{ 0x00000ec9, 0x0000 }, /* R3785 (0xec9) - HPLPF3_2 */
+	{ 0x00000ecc, 0x0000 }, /* R3788 (0xecc) - HPLPF4_1 */
+	{ 0x00000ecd, 0x0000 }, /* R3789 (0xecd) - HPLPF4_2 */
+	{ 0x00000ed0, 0x0000 }, /* R3792 (0xed0) - ASRC2_ENABLE */
+	{ 0x00000ed2, 0x0000 }, /* R3794 (0xed2) - ASRC2_RATE1 */
+	{ 0x00000ed3, 0x4000 }, /* R3795 (0xed3) - ASRC2_RATE2 */
+	{ 0x00000ee0, 0x0000 }, /* R3808 (0xee0) - ASRC1_ENABLE */
+	{ 0x00000ee2, 0x0000 }, /* R3810 (0xee2) - ASRC1_RATE1 */
+	{ 0x00000ee3, 0x4000 }, /* R3811 (0xee3) - ASRC1_RATE2 */
+	{ 0x00000ef0, 0x0000 }, /* R3824 (0xef0) - ISRC 1 CTRL 1 */
+	{ 0x00000ef1, 0x0001 }, /* R3825 (0xef1) - ISRC 1 CTRL 2 */
+	{ 0x00000ef2, 0x0000 }, /* R3826 (0xef2) - ISRC 1 CTRL 3 */
+	{ 0x00000ef3, 0x0000 }, /* R3827 (0xef3) - ISRC 2 CTRL 1 */
+	{ 0x00000ef4, 0x0001 }, /* R3828 (0xef4) - ISRC 2 CTRL 2 */
+	{ 0x00000ef5, 0x0000 }, /* R3829 (0xef5) - ISRC 2 CTRL 3 */
+	{ 0x00000ef6, 0x0000 }, /* R3830 (0xef6) - ISRC 3 CTRL 1 */
+	{ 0x00000ef7, 0x0001 }, /* R3831 (0xef7) - ISRC 3 CTRL 2 */
+	{ 0x00000ef8, 0x0000 }, /* R3832 (0xef8) - ISRC 3 CTRL 3 */
+	{ 0x00000ef9, 0x0000 }, /* R3833 (0xef9) - ISRC 4 CTRL 1 */
+	{ 0x00000efa, 0x0001 }, /* R3834 (0xefa) - ISRC 4 CTRL 2 */
+	{ 0x00000efb, 0x0000 }, /* R3835 (0xefb) - ISRC 4 CTRL 3 */
+	{ 0x00000f01, 0x0000 }, /* R3841 (0xf01) - ANC_SRC */
+	{ 0x00000f02, 0x0000 }, /* R3842 (0xf02) - DSP Status */
+	{ 0x00000f08, 0x001c }, /* R3848 (0xf08) - ANC Coefficient */
+	{ 0x00000f09, 0x0000 }, /* R3849 (0xf09) - ANC Coefficient */
+	{ 0x00000f0a, 0x0000 }, /* R3850 (0xf0a) - ANC Coefficient */
+	{ 0x00000f0b, 0x0000 }, /* R3851 (0xf0b) - ANC Coefficient */
+	{ 0x00000f0c, 0x0000 }, /* R3852 (0xf0c) - ANC Coefficient */
+	{ 0x00000f0d, 0x0000 }, /* R3853 (0xf0d) - ANC Coefficient */
+	{ 0x00000f0e, 0x0000 }, /* R3854 (0xf0e) - ANC Coefficient */
+	{ 0x00000f0f, 0x0000 }, /* R3855 (0xf0f) - ANC Coefficient */
+	{ 0x00000f10, 0x0000 }, /* R3856 (0xf10) - ANC Coefficient */
+	{ 0x00000f11, 0x0000 }, /* R3857 (0xf11) - ANC Coefficient */
+	{ 0x00000f12, 0x0000 }, /* R3858 (0xf12) - ANC Coefficient */
+	{ 0x00000f15, 0x0000 }, /* R3861 (0xf15) - FCL Filter Control */
+	{ 0x00000f17, 0x0004 }, /* R3863 (0xf17) - FCL ADC Reformatter Control */
+	{ 0x00000f18, 0x0004 }, /* R3864 (0xf18) - ANC Coefficient */
+	{ 0x00000f19, 0x0002 }, /* R3865 (0xf19) - ANC Coefficient */
+	{ 0x00000f1a, 0x0000 }, /* R3866 (0xf1a) - ANC Coefficient */
+	{ 0x00000f1b, 0x0010 }, /* R3867 (0xf1b) - ANC Coefficient */
+	{ 0x00000f1c, 0x0000 }, /* R3868 (0xf1c) - ANC Coefficient */
+	{ 0x00000f1d, 0x0000 }, /* R3869 (0xf1d) - ANC Coefficient */
+	{ 0x00000f1e, 0x0000 }, /* R3870 (0xf1e) - ANC Coefficient */
+	{ 0x00000f1f, 0x0000 }, /* R3871 (0xf1f) - ANC Coefficient */
+	{ 0x00000f20, 0x0000 }, /* R3872 (0xf20) - ANC Coefficient */
+	{ 0x00000f21, 0x0000 }, /* R3873 (0xf21) - ANC Coefficient */
+	{ 0x00000f22, 0x0000 }, /* R3874 (0xf22) - ANC Coefficient */
+	{ 0x00000f23, 0x0000 }, /* R3875 (0xf23) - ANC Coefficient */
+	{ 0x00000f24, 0x0000 }, /* R3876 (0xf24) - ANC Coefficient */
+	{ 0x00000f25, 0x0000 }, /* R3877 (0xf25) - ANC Coefficient */
+	{ 0x00000f26, 0x0000 }, /* R3878 (0xf26) - ANC Coefficient */
+	{ 0x00000f27, 0x0000 }, /* R3879 (0xf27) - ANC Coefficient */
+	{ 0x00000f28, 0x0000 }, /* R3880 (0xf28) - ANC Coefficient */
+	{ 0x00000f29, 0x0000 }, /* R3881 (0xf29) - ANC Coefficient */
+	{ 0x00000f2a, 0x0000 }, /* R3882 (0xf2a) - ANC Coefficient */
+	{ 0x00000f2b, 0x0000 }, /* R3883 (0xf2b) - ANC Coefficient */
+	{ 0x00000f2c, 0x0000 }, /* R3884 (0xf2c) - ANC Coefficient */
+	{ 0x00000f2d, 0x0000 }, /* R3885 (0xf2d) - ANC Coefficient */
+	{ 0x00000f2e, 0x0000 }, /* R3886 (0xf2e) - ANC Coefficient */
+	{ 0x00000f2f, 0x0000 }, /* R3887 (0xf2f) - ANC Coefficient */
+	{ 0x00000f30, 0x0000 }, /* R3888 (0xf30) - ANC Coefficient */
+	{ 0x00000f31, 0x0000 }, /* R3889 (0xf31) - ANC Coefficient */
+	{ 0x00000f32, 0x0000 }, /* R3890 (0xf32) - ANC Coefficient */
+	{ 0x00000f33, 0x0000 }, /* R3891 (0xf33) - ANC Coefficient */
+	{ 0x00000f34, 0x0000 }, /* R3892 (0xf34) - ANC Coefficient */
+	{ 0x00000f35, 0x0000 }, /* R3893 (0xf35) - ANC Coefficient */
+	{ 0x00000f36, 0x0000 }, /* R3894 (0xf36) - ANC Coefficient */
+	{ 0x00000f37, 0x0000 }, /* R3895 (0xf37) - ANC Coefficient */
+	{ 0x00000f38, 0x0000 }, /* R3896 (0xf38) - ANC Coefficient */
+	{ 0x00000f39, 0x0000 }, /* R3897 (0xf39) - ANC Coefficient */
+	{ 0x00000f3a, 0x0000 }, /* R3898 (0xf3a) - ANC Coefficient */
+	{ 0x00000f3b, 0x0000 }, /* R3899 (0xf3b) - ANC Coefficient */
+	{ 0x00000f3c, 0x0000 }, /* R3900 (0xf3c) - ANC Coefficient */
+	{ 0x00000f3d, 0x0000 }, /* R3901 (0xf3d) - ANC Coefficient */
+	{ 0x00000f3e, 0x0000 }, /* R3902 (0xf3e) - ANC Coefficient */
+	{ 0x00000f3f, 0x0000 }, /* R3903 (0xf3f) - ANC Coefficient */
+	{ 0x00000f40, 0x0000 }, /* R3904 (0xf40) - ANC Coefficient */
+	{ 0x00000f41, 0x0000 }, /* R3905 (0xf41) - ANC Coefficient */
+	{ 0x00000f42, 0x0000 }, /* R3906 (0xf42) - ANC Coefficient */
+	{ 0x00000f43, 0x0000 }, /* R3907 (0xf43) - ANC Coefficient */
+	{ 0x00000f44, 0x0000 }, /* R3908 (0xf44) - ANC Coefficient */
+	{ 0x00000f45, 0x0000 }, /* R3909 (0xf45) - ANC Coefficient */
+	{ 0x00000f46, 0x0000 }, /* R3910 (0xf46) - ANC Coefficient */
+	{ 0x00000f47, 0x0000 }, /* R3911 (0xf47) - ANC Coefficient */
+	{ 0x00000f48, 0x0000 }, /* R3912 (0xf48) - ANC Coefficient */
+	{ 0x00000f49, 0x0000 }, /* R3913 (0xf49) - ANC Coefficient */
+	{ 0x00000f4a, 0x0000 }, /* R3914 (0xf4a) - ANC Coefficient */
+	{ 0x00000f4b, 0x0000 }, /* R3915 (0xf4b) - ANC Coefficient */
+	{ 0x00000f4c, 0x0000 }, /* R3916 (0xf4c) - ANC Coefficient */
+	{ 0x00000f4d, 0x0000 }, /* R3917 (0xf4d) - ANC Coefficient */
+	{ 0x00000f4e, 0x0000 }, /* R3918 (0xf4e) - ANC Coefficient */
+	{ 0x00000f4f, 0x0000 }, /* R3919 (0xf4f) - ANC Coefficient */
+	{ 0x00000f50, 0x0000 }, /* R3920 (0xf50) - ANC Coefficient */
+	{ 0x00000f51, 0x0000 }, /* R3921 (0xf51) - ANC Coefficient */
+	{ 0x00000f52, 0x0000 }, /* R3922 (0xf52) - ANC Coefficient */
+	{ 0x00000f53, 0x0000 }, /* R3923 (0xf53) - ANC Coefficient */
+	{ 0x00000f54, 0x0000 }, /* R3924 (0xf54) - ANC Coefficient */
+	{ 0x00000f55, 0x0000 }, /* R3925 (0xf55) - ANC Coefficient */
+	{ 0x00000f56, 0x0000 }, /* R3926 (0xf56) - ANC Coefficient */
+	{ 0x00000f57, 0x0000 }, /* R3927 (0xf57) - ANC Coefficient */
+	{ 0x00000f58, 0x0000 }, /* R3928 (0xf58) - ANC Coefficient */
+	{ 0x00000f59, 0x0000 }, /* R3929 (0xf59) - ANC Coefficient */
+	{ 0x00000f5a, 0x0000 }, /* R3930 (0xf5a) - ANC Coefficient */
+	{ 0x00000f5b, 0x0000 }, /* R3931 (0xf5b) - ANC Coefficient */
+	{ 0x00000f5c, 0x0000 }, /* R3932 (0xf5c) - ANC Coefficient */
+	{ 0x00000f5d, 0x0000 }, /* R3933 (0xf5d) - ANC Coefficient */
+	{ 0x00000f5e, 0x0000 }, /* R3934 (0xf5e) - ANC Coefficient */
+	{ 0x00000f5f, 0x0000 }, /* R3935 (0xf5f) - ANC Coefficient */
+	{ 0x00000f60, 0x0000 }, /* R3936 (0xf60) - ANC Coefficient */
+	{ 0x00000f61, 0x0000 }, /* R3937 (0xf61) - ANC Coefficient */
+	{ 0x00000f62, 0x0000 }, /* R3938 (0xf62) - ANC Coefficient */
+	{ 0x00000f63, 0x0000 }, /* R3939 (0xf63) - ANC Coefficient */
+	{ 0x00000f64, 0x0000 }, /* R3940 (0xf64) - ANC Coefficient */
+	{ 0x00000f65, 0x0000 }, /* R3941 (0xf65) - ANC Coefficient */
+	{ 0x00000f66, 0x0000 }, /* R3942 (0xf66) - ANC Coefficient */
+	{ 0x00000f67, 0x0000 }, /* R3943 (0xf67) - ANC Coefficient */
+	{ 0x00000f68, 0x0000 }, /* R3944 (0xf68) - ANC Coefficient */
+	{ 0x00000f69, 0x0000 }, /* R3945 (0xf69) - ANC Coefficient */
+	{ 0x00000f71, 0x0000 }, /* R3953 (0xf71) - FCR Filter Control */
+	{ 0x00000f73, 0x0004 }, /* R3955 (0xf73) - FCR ADC Reformatter Control */
+	{ 0x00000f74, 0x0004 }, /* R3956 (0xf74) - ANC Coefficient */
+	{ 0x00000f75, 0x0002 }, /* R3957 (0xf75) - ANC Coefficient */
+	{ 0x00000f76, 0x0000 }, /* R3958 (0xf76) - ANC Coefficient */
+	{ 0x00000f77, 0x0010 }, /* R3959 (0xf77) - ANC Coefficient */
+	{ 0x00000f78, 0x0000 }, /* R3960 (0xf78) - ANC Coefficient */
+	{ 0x00000f79, 0x0000 }, /* R3961 (0xf79) - ANC Coefficient */
+	{ 0x00000f7a, 0x0000 }, /* R3962 (0xf7a) - ANC Coefficient */
+	{ 0x00000f7b, 0x0000 }, /* R3963 (0xf7b) - ANC Coefficient */
+	{ 0x00000f7c, 0x0000 }, /* R3964 (0xf7c) - ANC Coefficient */
+	{ 0x00000f7d, 0x0000 }, /* R3965 (0xf7d) - ANC Coefficient */
+	{ 0x00000f7e, 0x0000 }, /* R3966 (0xf7e) - ANC Coefficient */
+	{ 0x00000f7f, 0x0000 }, /* R3967 (0xf7f) - ANC Coefficient */
+	{ 0x00000f80, 0x0000 }, /* R3968 (0xf80) - ANC Coefficient */
+	{ 0x00000f81, 0x0000 }, /* R3969 (0xf81) - ANC Coefficient */
+	{ 0x00000f82, 0x0000 }, /* R3970 (0xf82) - ANC Coefficient */
+	{ 0x00000f83, 0x0000 }, /* R3971 (0xf83) - ANC Coefficient */
+	{ 0x00000f84, 0x0000 }, /* R3972 (0xf84) - ANC Coefficient */
+	{ 0x00000f85, 0x0000 }, /* R3973 (0xf85) - ANC Coefficient */
+	{ 0x00000f86, 0x0000 }, /* R3974 (0xf86) - ANC Coefficient */
+	{ 0x00000f87, 0x0000 }, /* R3975 (0xf87) - ANC Coefficient */
+	{ 0x00000f88, 0x0000 }, /* R3976 (0xf88) - ANC Coefficient */
+	{ 0x00000f89, 0x0000 }, /* R3977 (0xf89) - ANC Coefficient */
+	{ 0x00000f8a, 0x0000 }, /* R3978 (0xf8a) - ANC Coefficient */
+	{ 0x00000f8b, 0x0000 }, /* R3979 (0xf8b) - ANC Coefficient */
+	{ 0x00000f8c, 0x0000 }, /* R3980 (0xf8c) - ANC Coefficient */
+	{ 0x00000f8d, 0x0000 }, /* R3981 (0xf8d) - ANC Coefficient */
+	{ 0x00000f8e, 0x0000 }, /* R3982 (0xf8e) - ANC Coefficient */
+	{ 0x00000f8f, 0x0000 }, /* R3983 (0xf8f) - ANC Coefficient */
+	{ 0x00000f90, 0x0000 }, /* R3984 (0xf90) - ANC Coefficient */
+	{ 0x00000f91, 0x0000 }, /* R3985 (0xf91) - ANC Coefficient */
+	{ 0x00000f92, 0x0000 }, /* R3986 (0xf92) - ANC Coefficient */
+	{ 0x00000f93, 0x0000 }, /* R3987 (0xf93) - ANC Coefficient */
+	{ 0x00000f94, 0x0000 }, /* R3988 (0xf94) - ANC Coefficient */
+	{ 0x00000f95, 0x0000 }, /* R3989 (0xf95) - ANC Coefficient */
+	{ 0x00000f96, 0x0000 }, /* R3990 (0xf96) - ANC Coefficient */
+	{ 0x00000f97, 0x0000 }, /* R3991 (0xf97) - ANC Coefficient */
+	{ 0x00000f98, 0x0000 }, /* R3992 (0xf98) - ANC Coefficient */
+	{ 0x00000f99, 0x0000 }, /* R3993 (0xf99) - ANC Coefficient */
+	{ 0x00000f9a, 0x0000 }, /* R3994 (0xf9a) - ANC Coefficient */
+	{ 0x00000f9b, 0x0000 }, /* R3995 (0xf9b) - ANC Coefficient */
+	{ 0x00000f9c, 0x0000 }, /* R3996 (0xf9c) - ANC Coefficient */
+	{ 0x00000f9d, 0x0000 }, /* R3997 (0xf9d) - ANC Coefficient */
+	{ 0x00000f9e, 0x0000 }, /* R3998 (0xf9e) - ANC Coefficient */
+	{ 0x00000f9f, 0x0000 }, /* R3999 (0xf9f) - ANC Coefficient */
+	{ 0x00000fa0, 0x0000 }, /* R4000 (0xfa0) - ANC Coefficient */
+	{ 0x00000fa1, 0x0000 }, /* R4001 (0xfa1) - ANC Coefficient */
+	{ 0x00000fa2, 0x0000 }, /* R4002 (0xfa2) - ANC Coefficient */
+	{ 0x00000fa3, 0x0000 }, /* R4003 (0xfa3) - ANC Coefficient */
+	{ 0x00000fa4, 0x0000 }, /* R4004 (0xfa4) - ANC Coefficient */
+	{ 0x00000fa5, 0x0000 }, /* R4005 (0xfa5) - ANC Coefficient */
+	{ 0x00000fa6, 0x0000 }, /* R4006 (0xfa6) - ANC Coefficient */
+	{ 0x00000fa7, 0x0000 }, /* R4007 (0xfa7) - ANC Coefficient */
+	{ 0x00000fa8, 0x0000 }, /* R4008 (0xfa8) - ANC Coefficient */
+	{ 0x00000fa9, 0x0000 }, /* R4009 (0xfa9) - ANC Coefficient */
+	{ 0x00000faa, 0x0000 }, /* R4010 (0xfaa) - ANC Coefficient */
+	{ 0x00000fab, 0x0000 }, /* R4011 (0xfab) - ANC Coefficient */
+	{ 0x00000fac, 0x0000 }, /* R4012 (0xfac) - ANC Coefficient */
+	{ 0x00000fad, 0x0000 }, /* R4013 (0xfad) - ANC Coefficient */
+	{ 0x00000fae, 0x0000 }, /* R4014 (0xfae) - ANC Coefficient */
+	{ 0x00000faf, 0x0000 }, /* R4015 (0xfaf) - ANC Coefficient */
+	{ 0x00000fb0, 0x0000 }, /* R4016 (0xfb0) - ANC Coefficient */
+	{ 0x00000fb1, 0x0000 }, /* R4017 (0xfb1) - ANC Coefficient */
+	{ 0x00000fb2, 0x0000 }, /* R4018 (0xfb2) - ANC Coefficient */
+	{ 0x00000fb3, 0x0000 }, /* R4019 (0xfb3) - ANC Coefficient */
+	{ 0x00000fb4, 0x0000 }, /* R4020 (0xfb4) - ANC Coefficient */
+	{ 0x00000fb5, 0x0000 }, /* R4021 (0xfb5) - ANC Coefficient */
+	{ 0x00000fb6, 0x0000 }, /* R4022 (0xfb6) - ANC Coefficient */
+	{ 0x00000fb7, 0x0000 }, /* R4023 (0xfb7) - ANC Coefficient */
+	{ 0x00000fb8, 0x0000 }, /* R4024 (0xfb8) - ANC Coefficient */
+	{ 0x00000fb9, 0x0000 }, /* R4025 (0xfb9) - ANC Coefficient */
+	{ 0x00000fba, 0x0000 }, /* R4026 (0xfba) - ANC Coefficient */
+	{ 0x00000fbb, 0x0000 }, /* R4027 (0xfbb) - ANC Coefficient */
+	{ 0x00000fbc, 0x0000 }, /* R4028 (0xfbc) - ANC Coefficient */
+	{ 0x00000fbd, 0x0000 }, /* R4029 (0xfbd) - ANC Coefficient */
+	{ 0x00000fbe, 0x0000 }, /* R4030 (0xfbe) - ANC Coefficient */
+	{ 0x00000fbf, 0x0000 }, /* R4031 (0xfbf) - ANC Coefficient */
+	{ 0x00000fc0, 0x0000 }, /* R4032 (0xfc0) - ANC Coefficient */
+	{ 0x00000fc1, 0x0000 }, /* R4033 (0xfc1) - ANC Coefficient */
+	{ 0x00000fc2, 0x0000 }, /* R4034 (0xfc2) - ANC Coefficient */
+	{ 0x00000fc3, 0x0000 }, /* R4035 (0xfc3) - ANC Coefficient */
+	{ 0x00000fc4, 0x0000 }, /* R4036 (0xfc4) - ANC Coefficient */
+	{ 0x00000fc5, 0x0000 }, /* R4037 (0xfc5) - ANC Coefficient */
+	{ 0x00001300, 0x0000 }, /* R4864 (0x1300) - DAC Comp 1 */
+	{ 0x00001302, 0x0000 }, /* R4866 (0x1302) - DAC Comp 2 */
+	{ 0x00001380, 0x0000 }, /* R4992 (0x1380) - FRF Coefficient 1L 1 */
+	{ 0x00001381, 0x0000 }, /* R4993 (0x1381) - FRF Coefficient 1L 2 */
+	{ 0x00001382, 0x0000 }, /* R4994 (0x1382) - FRF Coefficient 1L 3 */
+	{ 0x00001383, 0x0000 }, /* R4995 (0x1383) - FRF Coefficient 1L 4 */
+	{ 0x00001390, 0x0000 }, /* R5008 (0x1390) - FRF Coefficient 1R 1 */
+	{ 0x00001391, 0x0000 }, /* R5009 (0x1391) - FRF Coefficient 1R 2 */
+	{ 0x00001392, 0x0000 }, /* R5010 (0x1392) - FRF Coefficient 1R 3 */
+	{ 0x00001393, 0x0000 }, /* R5011 (0x1393) - FRF Coefficient 1R 4 */
+	{ 0x000013a0, 0x0000 }, /* R5024 (0x13a0) - FRF Coefficient 2L 1 */
+	{ 0x000013a1, 0x0000 }, /* R5025 (0x13a1) - FRF Coefficient 2L 2 */
+	{ 0x000013a2, 0x0000 }, /* R5026 (0x13a2) - FRF Coefficient 2L 3 */
+	{ 0x000013a3, 0x0000 }, /* R5027 (0x13a3) - FRF Coefficient 2L 4 */
+	{ 0x000013b0, 0x0000 }, /* R5040 (0x13b0) - FRF Coefficient 2R 1 */
+	{ 0x000013b1, 0x0000 }, /* R5041 (0x13b1) - FRF Coefficient 2R 2 */
+	{ 0x000013b2, 0x0000 }, /* R5042 (0x13b2) - FRF Coefficient 2R 3 */
+	{ 0x000013b3, 0x0000 }, /* R5043 (0x13b3) - FRF Coefficient 2R 4 */
+	{ 0x000013c0, 0x0000 }, /* R5040 (0x13c0) - FRF Coefficient 3L 1 */
+	{ 0x000013c1, 0x0000 }, /* R5041 (0x13c1) - FRF Coefficient 3L 2 */
+	{ 0x000013c2, 0x0000 }, /* R5042 (0x13c2) - FRF Coefficient 3L 3 */
+	{ 0x000013c3, 0x0000 }, /* R5043 (0x13c3) - FRF Coefficient 3L 4 */
+	{ 0x000013d0, 0x0000 }, /* R5072 (0x13d0) - FRF Coefficient 3R 1 */
+	{ 0x000013d1, 0x0000 }, /* R5073 (0x13d1) - FRF Coefficient 3R 2 */
+	{ 0x000013d2, 0x0000 }, /* R5074 (0x13d2) - FRF Coefficient 3R 3 */
+	{ 0x000013d3, 0x0000 }, /* R5075 (0x13d3) - FRF Coefficient 3R 4 */
+	{ 0x000013e0, 0x0000 }, /* R5088 (0x13e0) - FRF Coefficient 4L 1 */
+	{ 0x000013e1, 0x0000 }, /* R5089 (0x13e1) - FRF Coefficient 4L 2 */
+	{ 0x000013e2, 0x0000 }, /* R5090 (0x13e2) - FRF Coefficient 4L 3 */
+	{ 0x000013e3, 0x0000 }, /* R5091 (0x13e3) - FRF Coefficient 4L 4 */
+	{ 0x000013f0, 0x0000 }, /* R5104 (0x13f0) - FRF Coefficient 4R 1 */
+	{ 0x000013f1, 0x0000 }, /* R5105 (0x13f1) - FRF Coefficient 4R 2 */
+	{ 0x000013f2, 0x0000 }, /* R5106 (0x13f2) - FRF Coefficient 4R 3 */
+	{ 0x000013f3, 0x0000 }, /* R5107 (0x13f3) - FRF Coefficient 4R 4 */
+	{ 0x00001400, 0x0000 }, /* R5120 (0x1400) - FRF Coefficient 5L 1 */
+	{ 0x00001401, 0x0000 }, /* R5121 (0x1401) - FRF Coefficient 5L 2 */
+	{ 0x00001402, 0x0000 }, /* R5122 (0x1402) - FRF Coefficient 5L 3 */
+	{ 0x00001403, 0x0000 }, /* R5123 (0x1403) - FRF Coefficient 5L 4 */
+	{ 0x00001410, 0x0000 }, /* R5136 (0x1410) - FRF Coefficient 5R 1 */
+	{ 0x00001411, 0x0000 }, /* R5137 (0x1411) - FRF Coefficient 5R 2 */
+	{ 0x00001412, 0x0000 }, /* R5138 (0x1412) - FRF Coefficient 5R 3 */
+	{ 0x00001413, 0x0000 }, /* R5139 (0x1413) - FRF Coefficient 5R 4 */
+	{ 0x00001420, 0x0000 }, /* R5152 (0x1420) - FRF Coefficient 6L 1 */
+	{ 0x00001421, 0x0000 }, /* R5153 (0x1421) - FRF Coefficient 6L 2 */
+	{ 0x00001422, 0x0000 }, /* R5154 (0x1422) - FRF Coefficient 6L 3 */
+	{ 0x00001423, 0x0000 }, /* R5155 (0x1423) - FRF Coefficient 6L 4 */
+	{ 0x00001430, 0x0000 }, /* R5168 (0x1430) - FRF Coefficient 6R 1 */
+	{ 0x00001431, 0x0000 }, /* R5169 (0x1431) - FRF Coefficient 6R 2 */
+	{ 0x00001432, 0x0000 }, /* R5170 (0x1432) - FRF Coefficient 6R 3 */
+	{ 0x00001433, 0x0000 }, /* R5171 (0x1433) - FRF Coefficient 6R 4 */
+	{ 0x00001700, 0x2001 }, /* R5888 (0x1700) - GPIO1 Control 1 */
+	{ 0x00001701, 0xe000 }, /* R5889 (0x1701) - GPIO1 Control 2 */
+	{ 0x00001702, 0x2001 }, /* R5890 (0x1702) - GPIO2 Control 1 */
+	{ 0x00001703, 0xe000 }, /* R5891 (0x1703) - GPIO2 Control 2 */
+	{ 0x00001704, 0x2001 }, /* R5892 (0x1704) - GPIO3 Control 1 */
+	{ 0x00001705, 0xe000 }, /* R5893 (0x1705) - GPIO3 Control 2 */
+	{ 0x00001706, 0x2001 }, /* R5894 (0x1706) - GPIO4 Control 1 */
+	{ 0x00001707, 0xe000 }, /* R5895 (0x1707) - GPIO4 Control 2 */
+	{ 0x00001708, 0x2001 }, /* R5896 (0x1708) - GPIO5 Control 1 */
+	{ 0x00001709, 0xe000 }, /* R5897 (0x1709) - GPIO5 Control 2 */
+	{ 0x0000170a, 0x2001 }, /* R5898 (0x170a) - GPIO6 Control 1 */
+	{ 0x0000170b, 0xe000 }, /* R5899 (0x170b) - GPIO6 Control 2 */
+	{ 0x0000170c, 0x2001 }, /* R5900 (0x170c) - GPIO7 Control 1 */
+	{ 0x0000170d, 0xe000 }, /* R5901 (0x170d) - GPIO7 Control 2 */
+	{ 0x0000170e, 0x2001 }, /* R5902 (0x170e) - GPIO8 Control 1 */
+	{ 0x0000170f, 0xe000 }, /* R5903 (0x170f) - GPIO8 Control 2 */
+	{ 0x00001710, 0x2001 }, /* R5904 (0x1710) - GPIO9 Control 1 */
+	{ 0x00001711, 0xe000 }, /* R5905 (0x1711) - GPIO9 Control 2 */
+	{ 0x00001712, 0x2001 }, /* R5906 (0x1712) - GPIO10 Control 1 */
+	{ 0x00001713, 0xe000 }, /* R5907 (0x1713) - GPIO10 Control 2 */
+	{ 0x00001714, 0x2001 }, /* R5908 (0x1714) - GPIO11 Control 1 */
+	{ 0x00001715, 0xe000 }, /* R5909 (0x1715) - GPIO11 Control 2 */
+	{ 0x00001716, 0x2001 }, /* R5910 (0x1716) - GPIO12 Control 1 */
+	{ 0x00001717, 0xe000 }, /* R5911 (0x1717) - GPIO12 Control 2 */
+	{ 0x00001718, 0x2001 }, /* R5912 (0x1718) - GPIO13 Control 1 */
+	{ 0x00001719, 0xE000 }, /* R5913 (0x1719) - GPIO13 Control 2 */
+	{ 0x0000171a, 0x2001 }, /* R5914 (0x171a) - GPIO14 Control 1 */
+	{ 0x0000171b, 0xE000 }, /* R5915 (0x171b) - GPIO14 Control 2 */
+	{ 0x0000171c, 0x2001 }, /* R5916 (0x171c) - GPIO15 Control 1 */
+	{ 0x0000171d, 0xE000 }, /* R5917 (0x171d) - GPIO15 Control 2 */
+	{ 0x0000171e, 0x2001 }, /* R5918 (0x171e) - GPIO16 Control 1 */
+	{ 0x0000171f, 0xE000 }, /* R5919 (0x171f) - GPIO16 Control 2 */
+	{ 0x00001720, 0x2001 }, /* R5920 (0x1720) - GPIO17 Control 1 */
+	{ 0x00001721, 0xe000 }, /* R5921 (0x1721) - GPIO17 Control 2 */
+	{ 0x00001722, 0x2001 }, /* R5922 (0x1722) - GPIO18 Control 1 */
+	{ 0x00001723, 0xe000 }, /* R5923 (0x1723) - GPIO18 Control 2 */
+	{ 0x00001724, 0x2001 }, /* R5924 (0x1724) - GPIO19 Control 1 */
+	{ 0x00001725, 0xe000 }, /* R5925 (0x1725) - GPIO19 Control 2 */
+	{ 0x00001726, 0x2001 }, /* R5926 (0x1726) - GPIO20 Control 1 */
+	{ 0x00001727, 0xe000 }, /* R5927 (0x1727) - GPIO20 Control 2 */
+	{ 0x00001728, 0x2001 }, /* R5928 (0x1728) - GPIO21 Control 1 */
+	{ 0x00001729, 0xe000 }, /* R5929 (0x1729) - GPIO21 Control 2 */
+	{ 0x0000172a, 0x2001 }, /* R5930 (0x172a) - GPIO22 Control 1 */
+	{ 0x0000172b, 0xe000 }, /* R5931 (0x172b) - GPIO22 Control 2 */
+	{ 0x0000172c, 0x2001 }, /* R5932 (0x172c) - GPIO23 Control 1 */
+	{ 0x0000172d, 0xe000 }, /* R5933 (0x172d) - GPIO23 Control 2 */
+	{ 0x0000172e, 0x2001 }, /* R5934 (0x172e) - GPIO24 Control 1 */
+	{ 0x0000172f, 0xe000 }, /* R5935 (0x172f) - GPIO24 Control 2 */
+	{ 0x00001730, 0x2001 }, /* R5936 (0x1730) - GPIO25 Control 1 */
+	{ 0x00001731, 0xe000 }, /* R5937 (0x1731) - GPIO25 Control 2 */
+	{ 0x00001732, 0x2001 }, /* R5938 (0x1732) - GPIO26 Control 1 */
+	{ 0x00001733, 0xe000 }, /* R5939 (0x1733) - GPIO26 Control 2 */
+	{ 0x00001734, 0x2001 }, /* R5940 (0x1734) - GPIO27 Control 1 */
+	{ 0x00001735, 0xe000 }, /* R5941 (0x1735) - GPIO27 Control 2 */
+	{ 0x00001736, 0x2001 }, /* R5942 (0x1736) - GPIO28 Control 1 */
+	{ 0x00001737, 0xe000 }, /* R5943 (0x1737) - GPIO28 Control 2 */
+	{ 0x00001738, 0x2001 }, /* R5944 (0x1738) - GPIO29 Control 1 */
+	{ 0x00001739, 0xe000 }, /* R5945 (0x1739) - GPIO29 Control 2 */
+	{ 0x0000173a, 0x2001 }, /* R5946 (0x173a) - GPIO30 Control 1 */
+	{ 0x0000173b, 0xe000 }, /* R5947 (0x173b) - GPIO30 Control 2 */
+	{ 0x0000173c, 0x2001 }, /* R5948 (0x173c) - GPIO31 Control 1 */
+	{ 0x0000173d, 0xe000 }, /* R5949 (0x173d) - GPIO31 Control 2 */
+	{ 0x0000173e, 0x2001 }, /* R5950 (0x173e) - GPIO32 Control 1 */
+	{ 0x0000173f, 0xe000 }, /* R5951 (0x173f) - GPIO32 Control 2 */
+	{ 0x00001740, 0x2001 }, /* R5952 (0x1740) - GPIO33 Control 1 */
+	{ 0x00001741, 0xe000 }, /* R5953 (0x1741) - GPIO33 Control 2 */
+	{ 0x00001742, 0x2001 }, /* R5954 (0x1742) - GPIO34 Control 1 */
+	{ 0x00001743, 0xe000 }, /* R5955 (0x1743) - GPIO34 Control 2 */
+	{ 0x00001744, 0x2001 }, /* R5956 (0x1744) - GPIO35 Control 1 */
+	{ 0x00001745, 0xe000 }, /* R5957 (0x1745) - GPIO35 Control 2 */
+	{ 0x00001746, 0x2001 }, /* R5958 (0x1746) - GPIO36 Control 1 */
+	{ 0x00001747, 0xe000 }, /* R5959 (0x1747) - GPIO36 Control 2 */
+	{ 0x00001748, 0x2001 }, /* R5960 (0x1748) - GPIO37 Control 1 */
+	{ 0x00001749, 0xe000 }, /* R5961 (0x1749) - GPIO37 Control 2 */
+	{ 0x0000174a, 0x2001 }, /* R5962 (0x174a) - GPIO38 Control 1 */
+	{ 0x0000174b, 0xe000 }, /* R5963 (0x174b) - GPIO38 Control 2 */
+	{ 0x0000174c, 0x2001 }, /* R5964 (0x174c) - GPIO39 Control 1 */
+	{ 0x0000174d, 0xe000 }, /* R5965 (0x174d) - GPIO39 Control 2 */
+	{ 0x0000174e, 0x2001 }, /* R5966 (0x174e) - GPIO40 Control 1 */
+	{ 0x0000174f, 0xe000 }, /* R5967 (0x174f) - GPIO40 Control 2 */
+	{ 0x00001840, 0xffff }, /* R6208 (0x1840) - IRQ1 Mask 1 */
+	{ 0x00001841, 0xffff }, /* R6209 (0x1841) - IRQ1 Mask 2 */
+	{ 0x00001842, 0xffff }, /* R6210 (0x1842) - IRQ1 Mask 3 */
+	{ 0x00001843, 0xffff }, /* R6211 (0x1843) - IRQ1 Mask 4 */
+	{ 0x00001844, 0xffff }, /* R6212 (0x1844) - IRQ1 Mask 5 */
+	{ 0x00001845, 0xffff }, /* R6213 (0x1845) - IRQ1 Mask 6 */
+	{ 0x00001846, 0xffff }, /* R6214 (0x1846) - IRQ1 Mask 7 */
+	{ 0x00001847, 0xffff }, /* R6215 (0x1847) - IRQ1 Mask 8 */
+	{ 0x00001848, 0xffff }, /* R6216 (0x1848) - IRQ1 Mask 9 */
+	{ 0x00001849, 0xffff }, /* R6217 (0x1849) - IRQ1 Mask 10 */
+	{ 0x0000184a, 0xffff }, /* R6218 (0x184a) - IRQ1 Mask 11 */
+	{ 0x0000184b, 0xffff }, /* R6219 (0x184b) - IRQ1 Mask 12 */
+	{ 0x0000184c, 0xffff }, /* R6220 (0x184c) - IRQ1 Mask 13 */
+	{ 0x0000184d, 0xffff }, /* R6221 (0x184d) - IRQ1 Mask 14 */
+	{ 0x0000184e, 0xffff }, /* R6222 (0x184e) - IRQ1 Mask 15 */
+	{ 0x0000184f, 0xffff }, /* R6223 (0x184f) - IRQ1 Mask 16 */
+	{ 0x00001850, 0xffff }, /* R6224 (0x1850) - IRQ1 Mask 17 */
+	{ 0x00001851, 0xffff }, /* R6225 (0x1851) - IRQ1 Mask 18 */
+	{ 0x00001852, 0xffff }, /* R6226 (0x1852) - IRQ1 Mask 19 */
+	{ 0x00001853, 0xffff }, /* R6227 (0x1853) - IRQ1 Mask 20 */
+	{ 0x00001854, 0xffff }, /* R6228 (0x1854) - IRQ1 Mask 21 */
+	{ 0x00001855, 0xffff }, /* R6229 (0x1855) - IRQ1 Mask 22 */
+	{ 0x00001856, 0xffff }, /* R6230 (0x1856) - IRQ1 Mask 23 */
+	{ 0x00001857, 0xffff }, /* R6231 (0x1857) - IRQ1 Mask 24 */
+	{ 0x00001858, 0xffff }, /* R6232 (0x1858) - IRQ1 Mask 25 */
+	{ 0x00001859, 0xffff }, /* R6233 (0x1859) - IRQ1 Mask 26 */
+	{ 0x0000185a, 0xffff }, /* R6234 (0x185a) - IRQ1 Mask 27 */
+	{ 0x0000185b, 0xffff }, /* R6235 (0x185b) - IRQ1 Mask 28 */
+	{ 0x0000185c, 0xffff }, /* R6236 (0x185c) - IRQ1 Mask 29 */
+	{ 0x0000185d, 0xffff }, /* R6237 (0x185d) - IRQ1 Mask 30 */
+	{ 0x0000185e, 0xffff }, /* R6238 (0x185e) - IRQ1 Mask 31 */
+	{ 0x0000185f, 0xffff }, /* R6239 (0x185f) - IRQ1 Mask 32 */
+	{ 0x00001860, 0xffff }, /* R6240 (0x1860) - IRQ1 Mask 33 */
+	{ 0x00001a06, 0x0000 }, /* R6662 (0x1a06) - Interrupt Debounce 7 */
+	{ 0x00001a80, 0x4400 }, /* R6784 (0x1a80) - IRQ1 CTRL */
+};
+
+static bool cs47l85_is_adsp_memory(unsigned int reg)
+{
+	switch (reg) {
+	case 0x080000 ... 0x085ffe:
+	case 0x0a0000 ... 0x0a7ffe:
+	case 0x0c0000 ... 0x0c1ffe:
+	case 0x0e0000 ... 0x0e1ffe:
+	case 0x100000 ... 0x10effe:
+	case 0x120000 ... 0x12bffe:
+	case 0x136000 ... 0x137ffe:
+	case 0x140000 ... 0x14bffe:
+	case 0x160000 ... 0x161ffe:
+	case 0x180000 ... 0x18effe:
+	case 0x1a0000 ... 0x1b1ffe:
+	case 0x1b6000 ... 0x1b7ffe:
+	case 0x1c0000 ... 0x1cbffe:
+	case 0x1e0000 ... 0x1e1ffe:
+	case 0x200000 ... 0x208ffe:
+	case 0x220000 ... 0x231ffe:
+	case 0x240000 ... 0x24bffe:
+	case 0x260000 ... 0x261ffe:
+	case 0x280000 ... 0x288ffe:
+	case 0x2a0000 ... 0x2a9ffe:
+	case 0x2c0000 ... 0x2c3ffe:
+	case 0x2e0000 ... 0x2e1ffe:
+	case 0x300000 ... 0x305ffe:
+	case 0x320000 ... 0x333ffe:
+	case 0x340000 ... 0x34bffe:
+	case 0x360000 ... 0x361ffe:
+	case 0x380000 ... 0x388ffe:
+	case 0x3a0000 ... 0x3a7ffe:
+	case 0x3c0000 ... 0x3c1ffe:
+	case 0x3e0000 ... 0x3e1ffe:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool cs47l85_16bit_readable_register(struct device *dev,
+					    unsigned int reg)
+{
+	switch (reg) {
+	case MADERA_SOFTWARE_RESET:
+	case MADERA_HARDWARE_REVISION:
+	case MADERA_WRITE_SEQUENCER_CTRL_0:
+	case MADERA_WRITE_SEQUENCER_CTRL_1:
+	case MADERA_WRITE_SEQUENCER_CTRL_2:
+	case MADERA_TONE_GENERATOR_1:
+	case MADERA_TONE_GENERATOR_2:
+	case MADERA_TONE_GENERATOR_3:
+	case MADERA_TONE_GENERATOR_4:
+	case MADERA_TONE_GENERATOR_5:
+	case MADERA_PWM_DRIVE_1:
+	case MADERA_PWM_DRIVE_2:
+	case MADERA_PWM_DRIVE_3:
+	case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_1:
+	case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_2:
+	case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_3:
+	case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_4:
+	case MADERA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_1:
+	case MADERA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_2:
+	case MADERA_HAPTICS_CONTROL_1:
+	case MADERA_HAPTICS_CONTROL_2:
+	case MADERA_HAPTICS_PHASE_1_INTENSITY:
+	case MADERA_HAPTICS_PHASE_1_DURATION:
+	case MADERA_HAPTICS_PHASE_2_INTENSITY:
+	case MADERA_HAPTICS_PHASE_2_DURATION:
+	case MADERA_HAPTICS_PHASE_3_INTENSITY:
+	case MADERA_HAPTICS_PHASE_3_DURATION:
+	case MADERA_HAPTICS_STATUS:
+	case MADERA_COMFORT_NOISE_GENERATOR:
+	case MADERA_CLOCK_32K_1:
+	case MADERA_SYSTEM_CLOCK_1:
+	case MADERA_SAMPLE_RATE_1:
+	case MADERA_SAMPLE_RATE_2:
+	case MADERA_SAMPLE_RATE_3:
+	case MADERA_SAMPLE_RATE_1_STATUS:
+	case MADERA_SAMPLE_RATE_2_STATUS:
+	case MADERA_SAMPLE_RATE_3_STATUS:
+	case MADERA_ASYNC_CLOCK_1:
+	case MADERA_ASYNC_SAMPLE_RATE_1:
+	case MADERA_ASYNC_SAMPLE_RATE_1_STATUS:
+	case MADERA_ASYNC_SAMPLE_RATE_2:
+	case MADERA_ASYNC_SAMPLE_RATE_2_STATUS:
+	case MADERA_DSP_CLOCK_1:
+	case MADERA_DSP_CLOCK_2:
+	case MADERA_OUTPUT_SYSTEM_CLOCK:
+	case MADERA_OUTPUT_ASYNC_CLOCK:
+	case MADERA_RATE_ESTIMATOR_1:
+	case MADERA_RATE_ESTIMATOR_2:
+	case MADERA_RATE_ESTIMATOR_3:
+	case MADERA_RATE_ESTIMATOR_4:
+	case MADERA_RATE_ESTIMATOR_5:
+	case MADERA_FLL1_CONTROL_1:
+	case MADERA_FLL1_CONTROL_2:
+	case MADERA_FLL1_CONTROL_3:
+	case MADERA_FLL1_CONTROL_4:
+	case MADERA_FLL1_CONTROL_5:
+	case MADERA_FLL1_CONTROL_6:
+	case MADERA_FLL1_CONTROL_7:
+	case MADERA_FLL1_LOOP_FILTER_TEST_1:
+	case MADERA_FLL1_SYNCHRONISER_1:
+	case MADERA_FLL1_SYNCHRONISER_2:
+	case MADERA_FLL1_SYNCHRONISER_3:
+	case MADERA_FLL1_SYNCHRONISER_4:
+	case MADERA_FLL1_SYNCHRONISER_5:
+	case MADERA_FLL1_SYNCHRONISER_6:
+	case MADERA_FLL1_SYNCHRONISER_7:
+	case MADERA_FLL1_SPREAD_SPECTRUM:
+	case MADERA_FLL1_GPIO_CLOCK:
+	case MADERA_FLL2_CONTROL_1:
+	case MADERA_FLL2_CONTROL_2:
+	case MADERA_FLL2_CONTROL_3:
+	case MADERA_FLL2_CONTROL_4:
+	case MADERA_FLL2_CONTROL_5:
+	case MADERA_FLL2_CONTROL_6:
+	case MADERA_FLL2_CONTROL_7:
+	case MADERA_FLL2_LOOP_FILTER_TEST_1:
+	case MADERA_FLL2_SYNCHRONISER_1:
+	case MADERA_FLL2_SYNCHRONISER_2:
+	case MADERA_FLL2_SYNCHRONISER_3:
+	case MADERA_FLL2_SYNCHRONISER_4:
+	case MADERA_FLL2_SYNCHRONISER_5:
+	case MADERA_FLL2_SYNCHRONISER_6:
+	case MADERA_FLL2_SYNCHRONISER_7:
+	case MADERA_FLL2_SPREAD_SPECTRUM:
+	case MADERA_FLL2_GPIO_CLOCK:
+	case MADERA_FLL3_CONTROL_1:
+	case MADERA_FLL3_CONTROL_2:
+	case MADERA_FLL3_CONTROL_3:
+	case MADERA_FLL3_CONTROL_4:
+	case MADERA_FLL3_CONTROL_5:
+	case MADERA_FLL3_CONTROL_6:
+	case MADERA_FLL3_CONTROL_7:
+	case MADERA_FLL3_LOOP_FILTER_TEST_1:
+	case MADERA_FLL3_SYNCHRONISER_1:
+	case MADERA_FLL3_SYNCHRONISER_2:
+	case MADERA_FLL3_SYNCHRONISER_3:
+	case MADERA_FLL3_SYNCHRONISER_4:
+	case MADERA_FLL3_SYNCHRONISER_5:
+	case MADERA_FLL3_SYNCHRONISER_6:
+	case MADERA_FLL3_SYNCHRONISER_7:
+	case MADERA_FLL3_SPREAD_SPECTRUM:
+	case MADERA_FLL3_GPIO_CLOCK:
+	case MADERA_MIC_CHARGE_PUMP_1:
+	case MADERA_HP_CHARGE_PUMP_8:
+	case MADERA_LDO1_CONTROL_1:
+	case MADERA_LDO2_CONTROL_1:
+	case MADERA_MIC_BIAS_CTRL_1:
+	case MADERA_MIC_BIAS_CTRL_2:
+	case MADERA_MIC_BIAS_CTRL_3:
+	case MADERA_MIC_BIAS_CTRL_4:
+	case MADERA_HP_CTRL_1L:
+	case MADERA_HP_CTRL_1R:
+	case MADERA_HP_CTRL_2L:
+	case MADERA_HP_CTRL_2R:
+	case MADERA_HP_CTRL_3L:
+	case MADERA_HP_CTRL_3R:
+	case MADERA_DCS_HP1L_CONTROL:
+	case MADERA_DCS_HP1R_CONTROL:
+	case MADERA_EDRE_HP_STEREO_CONTROL:
+	case MADERA_ACCESSORY_DETECT_MODE_1:
+	case MADERA_HEADPHONE_DETECT_1:
+	case MADERA_HEADPHONE_DETECT_2:
+	case MADERA_HEADPHONE_DETECT_3:
+	case MADERA_HEADPHONE_DETECT_5:
+	case MADERA_MICD_CLAMP_CONTROL:
+	case MADERA_MIC_DETECT_1_CONTROL_1:
+	case MADERA_MIC_DETECT_1_CONTROL_2:
+	case MADERA_MIC_DETECT_1_CONTROL_3:
+	case MADERA_MIC_DETECT_1_LEVEL_1:
+	case MADERA_MIC_DETECT_1_LEVEL_2:
+	case MADERA_MIC_DETECT_1_LEVEL_3:
+	case MADERA_MIC_DETECT_1_LEVEL_4:
+	case MADERA_MIC_DETECT_1_CONTROL_4:
+	case MADERA_GP_SWITCH_1:
+	case MADERA_JACK_DETECT_ANALOGUE:
+	case MADERA_INPUT_ENABLES:
+	case MADERA_INPUT_ENABLES_STATUS:
+	case MADERA_INPUT_RATE:
+	case MADERA_INPUT_VOLUME_RAMP:
+	case MADERA_HPF_CONTROL:
+	case MADERA_IN1L_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_1L:
+	case MADERA_DMIC1L_CONTROL:
+	case MADERA_IN1R_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_1R:
+	case MADERA_DMIC1R_CONTROL:
+	case MADERA_IN2L_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_2L:
+	case MADERA_DMIC2L_CONTROL:
+	case MADERA_IN2R_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_2R:
+	case MADERA_DMIC2R_CONTROL:
+	case MADERA_IN3L_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_3L:
+	case MADERA_DMIC3L_CONTROL:
+	case MADERA_IN3R_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_3R:
+	case MADERA_DMIC3R_CONTROL:
+	case MADERA_IN4L_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_4L:
+	case MADERA_DMIC4L_CONTROL:
+	case MADERA_IN4R_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_4R:
+	case MADERA_DMIC4R_CONTROL:
+	case MADERA_IN5L_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_5L:
+	case MADERA_DMIC5L_CONTROL:
+	case MADERA_IN5R_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_5R:
+	case MADERA_DMIC5R_CONTROL:
+	case MADERA_IN6L_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_6L:
+	case MADERA_DMIC6L_CONTROL:
+	case MADERA_IN6R_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_6R:
+	case MADERA_DMIC6R_CONTROL:
+	case MADERA_OUTPUT_ENABLES_1:
+	case MADERA_OUTPUT_STATUS_1:
+	case MADERA_RAW_OUTPUT_STATUS_1:
+	case MADERA_OUTPUT_RATE_1:
+	case MADERA_OUTPUT_VOLUME_RAMP:
+	case MADERA_OUTPUT_PATH_CONFIG_1L:
+	case MADERA_DAC_DIGITAL_VOLUME_1L:
+	case MADERA_NOISE_GATE_SELECT_1L:
+	case MADERA_OUTPUT_PATH_CONFIG_1R:
+	case MADERA_DAC_DIGITAL_VOLUME_1R:
+	case MADERA_NOISE_GATE_SELECT_1R:
+	case MADERA_OUTPUT_PATH_CONFIG_2L:
+	case MADERA_DAC_DIGITAL_VOLUME_2L:
+	case MADERA_NOISE_GATE_SELECT_2L:
+	case MADERA_OUTPUT_PATH_CONFIG_2R:
+	case MADERA_DAC_DIGITAL_VOLUME_2R:
+	case MADERA_NOISE_GATE_SELECT_2R:
+	case MADERA_OUTPUT_PATH_CONFIG_3L:
+	case MADERA_DAC_DIGITAL_VOLUME_3L:
+	case MADERA_NOISE_GATE_SELECT_3L:
+	case MADERA_OUTPUT_PATH_CONFIG_3R:
+	case MADERA_DAC_DIGITAL_VOLUME_3R:
+	case MADERA_NOISE_GATE_SELECT_3R:
+	case MADERA_OUTPUT_PATH_CONFIG_4L:
+	case MADERA_DAC_DIGITAL_VOLUME_4L:
+	case MADERA_NOISE_GATE_SELECT_4L:
+	case MADERA_OUTPUT_PATH_CONFIG_4R:
+	case MADERA_DAC_DIGITAL_VOLUME_4R:
+	case MADERA_NOISE_GATE_SELECT_4R:
+	case MADERA_OUTPUT_PATH_CONFIG_5L:
+	case MADERA_DAC_DIGITAL_VOLUME_5L:
+	case MADERA_NOISE_GATE_SELECT_5L:
+	case MADERA_OUTPUT_PATH_CONFIG_5R:
+	case MADERA_DAC_DIGITAL_VOLUME_5R:
+	case MADERA_NOISE_GATE_SELECT_5R:
+	case MADERA_OUTPUT_PATH_CONFIG_6L:
+	case MADERA_DAC_DIGITAL_VOLUME_6L:
+	case MADERA_NOISE_GATE_SELECT_6L:
+	case MADERA_OUTPUT_PATH_CONFIG_6R:
+	case MADERA_DAC_DIGITAL_VOLUME_6R:
+	case MADERA_NOISE_GATE_SELECT_6R:
+	case MADERA_DRE_ENABLE:
+	case MADERA_EDRE_ENABLE:
+	case MADERA_EDRE_MANUAL:
+	case MADERA_DAC_AEC_CONTROL_1:
+	case MADERA_DAC_AEC_CONTROL_2:
+	case MADERA_NOISE_GATE_CONTROL:
+	case MADERA_PDM_SPK1_CTRL_1:
+	case MADERA_PDM_SPK1_CTRL_2:
+	case MADERA_PDM_SPK2_CTRL_1:
+	case MADERA_PDM_SPK2_CTRL_2:
+	case MADERA_HP1_SHORT_CIRCUIT_CTRL:
+	case MADERA_HP2_SHORT_CIRCUIT_CTRL:
+	case MADERA_HP3_SHORT_CIRCUIT_CTRL:
+	case MADERA_HP_TEST_CTRL_5:
+	case MADERA_HP_TEST_CTRL_6:
+	case MADERA_AIF1_BCLK_CTRL:
+	case MADERA_AIF1_TX_PIN_CTRL:
+	case MADERA_AIF1_RX_PIN_CTRL:
+	case MADERA_AIF1_RATE_CTRL:
+	case MADERA_AIF1_FORMAT:
+	case MADERA_AIF1_RX_BCLK_RATE:
+	case MADERA_AIF1_FRAME_CTRL_1:
+	case MADERA_AIF1_FRAME_CTRL_2:
+	case MADERA_AIF1_FRAME_CTRL_3:
+	case MADERA_AIF1_FRAME_CTRL_4:
+	case MADERA_AIF1_FRAME_CTRL_5:
+	case MADERA_AIF1_FRAME_CTRL_6:
+	case MADERA_AIF1_FRAME_CTRL_7:
+	case MADERA_AIF1_FRAME_CTRL_8:
+	case MADERA_AIF1_FRAME_CTRL_9:
+	case MADERA_AIF1_FRAME_CTRL_10:
+	case MADERA_AIF1_FRAME_CTRL_11:
+	case MADERA_AIF1_FRAME_CTRL_12:
+	case MADERA_AIF1_FRAME_CTRL_13:
+	case MADERA_AIF1_FRAME_CTRL_14:
+	case MADERA_AIF1_FRAME_CTRL_15:
+	case MADERA_AIF1_FRAME_CTRL_16:
+	case MADERA_AIF1_FRAME_CTRL_17:
+	case MADERA_AIF1_FRAME_CTRL_18:
+	case MADERA_AIF1_TX_ENABLES:
+	case MADERA_AIF1_RX_ENABLES:
+	case MADERA_AIF2_BCLK_CTRL:
+	case MADERA_AIF2_TX_PIN_CTRL:
+	case MADERA_AIF2_RX_PIN_CTRL:
+	case MADERA_AIF2_RATE_CTRL:
+	case MADERA_AIF2_FORMAT:
+	case MADERA_AIF2_RX_BCLK_RATE:
+	case MADERA_AIF2_FRAME_CTRL_1:
+	case MADERA_AIF2_FRAME_CTRL_2:
+	case MADERA_AIF2_FRAME_CTRL_3:
+	case MADERA_AIF2_FRAME_CTRL_4:
+	case MADERA_AIF2_FRAME_CTRL_5:
+	case MADERA_AIF2_FRAME_CTRL_6:
+	case MADERA_AIF2_FRAME_CTRL_7:
+	case MADERA_AIF2_FRAME_CTRL_8:
+	case MADERA_AIF2_FRAME_CTRL_9:
+	case MADERA_AIF2_FRAME_CTRL_10:
+	case MADERA_AIF2_FRAME_CTRL_11:
+	case MADERA_AIF2_FRAME_CTRL_12:
+	case MADERA_AIF2_FRAME_CTRL_13:
+	case MADERA_AIF2_FRAME_CTRL_14:
+	case MADERA_AIF2_FRAME_CTRL_15:
+	case MADERA_AIF2_FRAME_CTRL_16:
+	case MADERA_AIF2_FRAME_CTRL_17:
+	case MADERA_AIF2_FRAME_CTRL_18:
+	case MADERA_AIF2_TX_ENABLES:
+	case MADERA_AIF2_RX_ENABLES:
+	case MADERA_AIF3_BCLK_CTRL:
+	case MADERA_AIF3_TX_PIN_CTRL:
+	case MADERA_AIF3_RX_PIN_CTRL:
+	case MADERA_AIF3_RATE_CTRL:
+	case MADERA_AIF3_FORMAT:
+	case MADERA_AIF3_RX_BCLK_RATE:
+	case MADERA_AIF3_FRAME_CTRL_1:
+	case MADERA_AIF3_FRAME_CTRL_2:
+	case MADERA_AIF3_FRAME_CTRL_3:
+	case MADERA_AIF3_FRAME_CTRL_4:
+	case MADERA_AIF3_FRAME_CTRL_11:
+	case MADERA_AIF3_FRAME_CTRL_12:
+	case MADERA_AIF3_TX_ENABLES:
+	case MADERA_AIF3_RX_ENABLES:
+	case MADERA_AIF4_BCLK_CTRL:
+	case MADERA_AIF4_TX_PIN_CTRL:
+	case MADERA_AIF4_RX_PIN_CTRL:
+	case MADERA_AIF4_RATE_CTRL:
+	case MADERA_AIF4_FORMAT:
+	case MADERA_AIF4_RX_BCLK_RATE:
+	case MADERA_AIF4_FRAME_CTRL_1:
+	case MADERA_AIF4_FRAME_CTRL_2:
+	case MADERA_AIF4_FRAME_CTRL_3:
+	case MADERA_AIF4_FRAME_CTRL_4:
+	case MADERA_AIF4_FRAME_CTRL_11:
+	case MADERA_AIF4_FRAME_CTRL_12:
+	case MADERA_AIF4_TX_ENABLES:
+	case MADERA_AIF4_RX_ENABLES:
+	case MADERA_SPD1_TX_CONTROL:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_1:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_2:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_3:
+	case MADERA_SLIMBUS_FRAMER_REF_GEAR:
+	case MADERA_SLIMBUS_RATES_1:
+	case MADERA_SLIMBUS_RATES_2:
+	case MADERA_SLIMBUS_RATES_3:
+	case MADERA_SLIMBUS_RATES_4:
+	case MADERA_SLIMBUS_RATES_5:
+	case MADERA_SLIMBUS_RATES_6:
+	case MADERA_SLIMBUS_RATES_7:
+	case MADERA_SLIMBUS_RATES_8:
+	case MADERA_SLIMBUS_RX_CHANNEL_ENABLE:
+	case MADERA_SLIMBUS_TX_CHANNEL_ENABLE:
+	case MADERA_SLIMBUS_RX_PORT_STATUS:
+	case MADERA_SLIMBUS_TX_PORT_STATUS:
+	case MADERA_PWM1MIX_INPUT_1_SOURCE:
+	case MADERA_PWM1MIX_INPUT_1_VOLUME:
+	case MADERA_PWM1MIX_INPUT_2_SOURCE:
+	case MADERA_PWM1MIX_INPUT_2_VOLUME:
+	case MADERA_PWM1MIX_INPUT_3_SOURCE:
+	case MADERA_PWM1MIX_INPUT_3_VOLUME:
+	case MADERA_PWM1MIX_INPUT_4_SOURCE:
+	case MADERA_PWM1MIX_INPUT_4_VOLUME:
+	case MADERA_PWM2MIX_INPUT_1_SOURCE:
+	case MADERA_PWM2MIX_INPUT_1_VOLUME:
+	case MADERA_PWM2MIX_INPUT_2_SOURCE:
+	case MADERA_PWM2MIX_INPUT_2_VOLUME:
+	case MADERA_PWM2MIX_INPUT_3_SOURCE:
+	case MADERA_PWM2MIX_INPUT_3_VOLUME:
+	case MADERA_PWM2MIX_INPUT_4_SOURCE:
+	case MADERA_PWM2MIX_INPUT_4_VOLUME:
+	case MADERA_OUT1LMIX_INPUT_1_SOURCE:
+	case MADERA_OUT1LMIX_INPUT_1_VOLUME:
+	case MADERA_OUT1LMIX_INPUT_2_SOURCE:
+	case MADERA_OUT1LMIX_INPUT_2_VOLUME:
+	case MADERA_OUT1LMIX_INPUT_3_SOURCE:
+	case MADERA_OUT1LMIX_INPUT_3_VOLUME:
+	case MADERA_OUT1LMIX_INPUT_4_SOURCE:
+	case MADERA_OUT1LMIX_INPUT_4_VOLUME:
+	case MADERA_OUT1RMIX_INPUT_1_SOURCE:
+	case MADERA_OUT1RMIX_INPUT_1_VOLUME:
+	case MADERA_OUT1RMIX_INPUT_2_SOURCE:
+	case MADERA_OUT1RMIX_INPUT_2_VOLUME:
+	case MADERA_OUT1RMIX_INPUT_3_SOURCE:
+	case MADERA_OUT1RMIX_INPUT_3_VOLUME:
+	case MADERA_OUT1RMIX_INPUT_4_SOURCE:
+	case MADERA_OUT1RMIX_INPUT_4_VOLUME:
+	case MADERA_OUT2LMIX_INPUT_1_SOURCE:
+	case MADERA_OUT2LMIX_INPUT_1_VOLUME:
+	case MADERA_OUT2LMIX_INPUT_2_SOURCE:
+	case MADERA_OUT2LMIX_INPUT_2_VOLUME:
+	case MADERA_OUT2LMIX_INPUT_3_SOURCE:
+	case MADERA_OUT2LMIX_INPUT_3_VOLUME:
+	case MADERA_OUT2LMIX_INPUT_4_SOURCE:
+	case MADERA_OUT2LMIX_INPUT_4_VOLUME:
+	case MADERA_OUT2RMIX_INPUT_1_SOURCE:
+	case MADERA_OUT2RMIX_INPUT_1_VOLUME:
+	case MADERA_OUT2RMIX_INPUT_2_SOURCE:
+	case MADERA_OUT2RMIX_INPUT_2_VOLUME:
+	case MADERA_OUT2RMIX_INPUT_3_SOURCE:
+	case MADERA_OUT2RMIX_INPUT_3_VOLUME:
+	case MADERA_OUT2RMIX_INPUT_4_SOURCE:
+	case MADERA_OUT2RMIX_INPUT_4_VOLUME:
+	case MADERA_OUT3LMIX_INPUT_1_SOURCE:
+	case MADERA_OUT3LMIX_INPUT_1_VOLUME:
+	case MADERA_OUT3LMIX_INPUT_2_SOURCE:
+	case MADERA_OUT3LMIX_INPUT_2_VOLUME:
+	case MADERA_OUT3LMIX_INPUT_3_SOURCE:
+	case MADERA_OUT3LMIX_INPUT_3_VOLUME:
+	case MADERA_OUT3LMIX_INPUT_4_SOURCE:
+	case MADERA_OUT3LMIX_INPUT_4_VOLUME:
+	case MADERA_OUT3RMIX_INPUT_1_SOURCE:
+	case MADERA_OUT3RMIX_INPUT_1_VOLUME:
+	case MADERA_OUT3RMIX_INPUT_2_SOURCE:
+	case MADERA_OUT3RMIX_INPUT_2_VOLUME:
+	case MADERA_OUT3RMIX_INPUT_3_SOURCE:
+	case MADERA_OUT3RMIX_INPUT_3_VOLUME:
+	case MADERA_OUT3RMIX_INPUT_4_SOURCE:
+	case MADERA_OUT3RMIX_INPUT_4_VOLUME:
+	case MADERA_OUT4LMIX_INPUT_1_SOURCE:
+	case MADERA_OUT4LMIX_INPUT_1_VOLUME:
+	case MADERA_OUT4LMIX_INPUT_2_SOURCE:
+	case MADERA_OUT4LMIX_INPUT_2_VOLUME:
+	case MADERA_OUT4LMIX_INPUT_3_SOURCE:
+	case MADERA_OUT4LMIX_INPUT_3_VOLUME:
+	case MADERA_OUT4LMIX_INPUT_4_SOURCE:
+	case MADERA_OUT4LMIX_INPUT_4_VOLUME:
+	case MADERA_OUT4RMIX_INPUT_1_SOURCE:
+	case MADERA_OUT4RMIX_INPUT_1_VOLUME:
+	case MADERA_OUT4RMIX_INPUT_2_SOURCE:
+	case MADERA_OUT4RMIX_INPUT_2_VOLUME:
+	case MADERA_OUT4RMIX_INPUT_3_SOURCE:
+	case MADERA_OUT4RMIX_INPUT_3_VOLUME:
+	case MADERA_OUT4RMIX_INPUT_4_SOURCE:
+	case MADERA_OUT4RMIX_INPUT_4_VOLUME:
+	case MADERA_OUT5LMIX_INPUT_1_SOURCE:
+	case MADERA_OUT5LMIX_INPUT_1_VOLUME:
+	case MADERA_OUT5LMIX_INPUT_2_SOURCE:
+	case MADERA_OUT5LMIX_INPUT_2_VOLUME:
+	case MADERA_OUT5LMIX_INPUT_3_SOURCE:
+	case MADERA_OUT5LMIX_INPUT_3_VOLUME:
+	case MADERA_OUT5LMIX_INPUT_4_SOURCE:
+	case MADERA_OUT5LMIX_INPUT_4_VOLUME:
+	case MADERA_OUT5RMIX_INPUT_1_SOURCE:
+	case MADERA_OUT5RMIX_INPUT_1_VOLUME:
+	case MADERA_OUT5RMIX_INPUT_2_SOURCE:
+	case MADERA_OUT5RMIX_INPUT_2_VOLUME:
+	case MADERA_OUT5RMIX_INPUT_3_SOURCE:
+	case MADERA_OUT5RMIX_INPUT_3_VOLUME:
+	case MADERA_OUT5RMIX_INPUT_4_SOURCE:
+	case MADERA_OUT5RMIX_INPUT_4_VOLUME:
+	case MADERA_OUT6LMIX_INPUT_1_SOURCE:
+	case MADERA_OUT6LMIX_INPUT_1_VOLUME:
+	case MADERA_OUT6LMIX_INPUT_2_SOURCE:
+	case MADERA_OUT6LMIX_INPUT_2_VOLUME:
+	case MADERA_OUT6LMIX_INPUT_3_SOURCE:
+	case MADERA_OUT6LMIX_INPUT_3_VOLUME:
+	case MADERA_OUT6LMIX_INPUT_4_SOURCE:
+	case MADERA_OUT6LMIX_INPUT_4_VOLUME:
+	case MADERA_OUT6RMIX_INPUT_1_SOURCE:
+	case MADERA_OUT6RMIX_INPUT_1_VOLUME:
+	case MADERA_OUT6RMIX_INPUT_2_SOURCE:
+	case MADERA_OUT6RMIX_INPUT_2_VOLUME:
+	case MADERA_OUT6RMIX_INPUT_3_SOURCE:
+	case MADERA_OUT6RMIX_INPUT_3_VOLUME:
+	case MADERA_OUT6RMIX_INPUT_4_SOURCE:
+	case MADERA_OUT6RMIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX1MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX1MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX1MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX1MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX1MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX1MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX1MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX1MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX2MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX2MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX2MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX2MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX2MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX2MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX2MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX2MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX3MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX3MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX3MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX3MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX3MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX3MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX3MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX3MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX4MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX4MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX4MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX4MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX4MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX4MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX4MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX4MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX5MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX5MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX5MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX5MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX5MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX5MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX5MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX5MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX6MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX6MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX6MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX6MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX6MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX6MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX6MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX6MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX7MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX7MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX7MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX7MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX7MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX7MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX7MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX7MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX8MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX8MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX8MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX8MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX8MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX8MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX8MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX8MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX1MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX1MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX1MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX1MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX1MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX1MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX1MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX1MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX2MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX2MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX2MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX2MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX2MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX2MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX2MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX2MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX3MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX3MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX3MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX3MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX3MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX3MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX3MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX3MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX4MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX4MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX4MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX4MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX4MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX4MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX4MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX4MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX5MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX5MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX5MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX5MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX5MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX5MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX5MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX5MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX6MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX6MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX6MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX6MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX6MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX6MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX6MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX6MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX7MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX7MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX7MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX7MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX7MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX7MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX7MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX7MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX8MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX8MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX8MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX8MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX8MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX8MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX8MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX8MIX_INPUT_4_VOLUME:
+	case MADERA_AIF3TX1MIX_INPUT_1_SOURCE:
+	case MADERA_AIF3TX1MIX_INPUT_1_VOLUME:
+	case MADERA_AIF3TX1MIX_INPUT_2_SOURCE:
+	case MADERA_AIF3TX1MIX_INPUT_2_VOLUME:
+	case MADERA_AIF3TX1MIX_INPUT_3_SOURCE:
+	case MADERA_AIF3TX1MIX_INPUT_3_VOLUME:
+	case MADERA_AIF3TX1MIX_INPUT_4_SOURCE:
+	case MADERA_AIF3TX1MIX_INPUT_4_VOLUME:
+	case MADERA_AIF3TX2MIX_INPUT_1_SOURCE:
+	case MADERA_AIF3TX2MIX_INPUT_1_VOLUME:
+	case MADERA_AIF3TX2MIX_INPUT_2_SOURCE:
+	case MADERA_AIF3TX2MIX_INPUT_2_VOLUME:
+	case MADERA_AIF3TX2MIX_INPUT_3_SOURCE:
+	case MADERA_AIF3TX2MIX_INPUT_3_VOLUME:
+	case MADERA_AIF3TX2MIX_INPUT_4_SOURCE:
+	case MADERA_AIF3TX2MIX_INPUT_4_VOLUME:
+	case MADERA_AIF4TX1MIX_INPUT_1_SOURCE:
+	case MADERA_AIF4TX1MIX_INPUT_1_VOLUME:
+	case MADERA_AIF4TX1MIX_INPUT_2_SOURCE:
+	case MADERA_AIF4TX1MIX_INPUT_2_VOLUME:
+	case MADERA_AIF4TX1MIX_INPUT_3_SOURCE:
+	case MADERA_AIF4TX1MIX_INPUT_3_VOLUME:
+	case MADERA_AIF4TX1MIX_INPUT_4_SOURCE:
+	case MADERA_AIF4TX1MIX_INPUT_4_VOLUME:
+	case MADERA_AIF4TX2MIX_INPUT_1_SOURCE:
+	case MADERA_AIF4TX2MIX_INPUT_1_VOLUME:
+	case MADERA_AIF4TX2MIX_INPUT_2_SOURCE:
+	case MADERA_AIF4TX2MIX_INPUT_2_VOLUME:
+	case MADERA_AIF4TX2MIX_INPUT_3_SOURCE:
+	case MADERA_AIF4TX2MIX_INPUT_3_VOLUME:
+	case MADERA_AIF4TX2MIX_INPUT_4_SOURCE:
+	case MADERA_AIF4TX2MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX1MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX1MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX1MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX1MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX1MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX1MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX1MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX1MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX2MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX2MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX2MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX2MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX2MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX2MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX2MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX2MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX3MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX3MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX3MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX3MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX3MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX3MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX3MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX3MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX4MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX4MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX4MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX4MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX4MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX4MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX4MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX4MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX5MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX5MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX5MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX5MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX5MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX5MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX5MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX5MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX6MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX6MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX6MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX6MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX6MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX6MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX6MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX6MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX7MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX7MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX7MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX7MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX7MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX7MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX7MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX7MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX8MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX8MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX8MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX8MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX8MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX8MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX8MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX8MIX_INPUT_4_VOLUME:
+	case MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE:
+	case MADERA_SPDIF1TX1MIX_INPUT_1_VOLUME:
+	case MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE:
+	case MADERA_SPDIF1TX2MIX_INPUT_1_VOLUME:
+	case MADERA_EQ1MIX_INPUT_1_SOURCE:
+	case MADERA_EQ1MIX_INPUT_1_VOLUME:
+	case MADERA_EQ1MIX_INPUT_2_SOURCE:
+	case MADERA_EQ1MIX_INPUT_2_VOLUME:
+	case MADERA_EQ1MIX_INPUT_3_SOURCE:
+	case MADERA_EQ1MIX_INPUT_3_VOLUME:
+	case MADERA_EQ1MIX_INPUT_4_SOURCE:
+	case MADERA_EQ1MIX_INPUT_4_VOLUME:
+	case MADERA_EQ2MIX_INPUT_1_SOURCE:
+	case MADERA_EQ2MIX_INPUT_1_VOLUME:
+	case MADERA_EQ2MIX_INPUT_2_SOURCE:
+	case MADERA_EQ2MIX_INPUT_2_VOLUME:
+	case MADERA_EQ2MIX_INPUT_3_SOURCE:
+	case MADERA_EQ2MIX_INPUT_3_VOLUME:
+	case MADERA_EQ2MIX_INPUT_4_SOURCE:
+	case MADERA_EQ2MIX_INPUT_4_VOLUME:
+	case MADERA_EQ3MIX_INPUT_1_SOURCE:
+	case MADERA_EQ3MIX_INPUT_1_VOLUME:
+	case MADERA_EQ3MIX_INPUT_2_SOURCE:
+	case MADERA_EQ3MIX_INPUT_2_VOLUME:
+	case MADERA_EQ3MIX_INPUT_3_SOURCE:
+	case MADERA_EQ3MIX_INPUT_3_VOLUME:
+	case MADERA_EQ3MIX_INPUT_4_SOURCE:
+	case MADERA_EQ3MIX_INPUT_4_VOLUME:
+	case MADERA_EQ4MIX_INPUT_1_SOURCE:
+	case MADERA_EQ4MIX_INPUT_1_VOLUME:
+	case MADERA_EQ4MIX_INPUT_2_SOURCE:
+	case MADERA_EQ4MIX_INPUT_2_VOLUME:
+	case MADERA_EQ4MIX_INPUT_3_SOURCE:
+	case MADERA_EQ4MIX_INPUT_3_VOLUME:
+	case MADERA_EQ4MIX_INPUT_4_SOURCE:
+	case MADERA_EQ4MIX_INPUT_4_VOLUME:
+	case MADERA_DRC1LMIX_INPUT_1_SOURCE:
+	case MADERA_DRC1LMIX_INPUT_1_VOLUME:
+	case MADERA_DRC1LMIX_INPUT_2_SOURCE:
+	case MADERA_DRC1LMIX_INPUT_2_VOLUME:
+	case MADERA_DRC1LMIX_INPUT_3_SOURCE:
+	case MADERA_DRC1LMIX_INPUT_3_VOLUME:
+	case MADERA_DRC1LMIX_INPUT_4_SOURCE:
+	case MADERA_DRC1LMIX_INPUT_4_VOLUME:
+	case MADERA_DRC1RMIX_INPUT_1_SOURCE:
+	case MADERA_DRC1RMIX_INPUT_1_VOLUME:
+	case MADERA_DRC1RMIX_INPUT_2_SOURCE:
+	case MADERA_DRC1RMIX_INPUT_2_VOLUME:
+	case MADERA_DRC1RMIX_INPUT_3_SOURCE:
+	case MADERA_DRC1RMIX_INPUT_3_VOLUME:
+	case MADERA_DRC1RMIX_INPUT_4_SOURCE:
+	case MADERA_DRC1RMIX_INPUT_4_VOLUME:
+	case MADERA_DRC2LMIX_INPUT_1_SOURCE:
+	case MADERA_DRC2LMIX_INPUT_1_VOLUME:
+	case MADERA_DRC2LMIX_INPUT_2_SOURCE:
+	case MADERA_DRC2LMIX_INPUT_2_VOLUME:
+	case MADERA_DRC2LMIX_INPUT_3_SOURCE:
+	case MADERA_DRC2LMIX_INPUT_3_VOLUME:
+	case MADERA_DRC2LMIX_INPUT_4_SOURCE:
+	case MADERA_DRC2LMIX_INPUT_4_VOLUME:
+	case MADERA_DRC2RMIX_INPUT_1_SOURCE:
+	case MADERA_DRC2RMIX_INPUT_1_VOLUME:
+	case MADERA_DRC2RMIX_INPUT_2_SOURCE:
+	case MADERA_DRC2RMIX_INPUT_2_VOLUME:
+	case MADERA_DRC2RMIX_INPUT_3_SOURCE:
+	case MADERA_DRC2RMIX_INPUT_3_VOLUME:
+	case MADERA_DRC2RMIX_INPUT_4_SOURCE:
+	case MADERA_DRC2RMIX_INPUT_4_VOLUME:
+	case MADERA_HPLP1MIX_INPUT_1_SOURCE:
+	case MADERA_HPLP1MIX_INPUT_1_VOLUME:
+	case MADERA_HPLP1MIX_INPUT_2_SOURCE:
+	case MADERA_HPLP1MIX_INPUT_2_VOLUME:
+	case MADERA_HPLP1MIX_INPUT_3_SOURCE:
+	case MADERA_HPLP1MIX_INPUT_3_VOLUME:
+	case MADERA_HPLP1MIX_INPUT_4_SOURCE:
+	case MADERA_HPLP1MIX_INPUT_4_VOLUME:
+	case MADERA_HPLP2MIX_INPUT_1_SOURCE:
+	case MADERA_HPLP2MIX_INPUT_1_VOLUME:
+	case MADERA_HPLP2MIX_INPUT_2_SOURCE:
+	case MADERA_HPLP2MIX_INPUT_2_VOLUME:
+	case MADERA_HPLP2MIX_INPUT_3_SOURCE:
+	case MADERA_HPLP2MIX_INPUT_3_VOLUME:
+	case MADERA_HPLP2MIX_INPUT_4_SOURCE:
+	case MADERA_HPLP2MIX_INPUT_4_VOLUME:
+	case MADERA_HPLP3MIX_INPUT_1_SOURCE:
+	case MADERA_HPLP3MIX_INPUT_1_VOLUME:
+	case MADERA_HPLP3MIX_INPUT_2_SOURCE:
+	case MADERA_HPLP3MIX_INPUT_2_VOLUME:
+	case MADERA_HPLP3MIX_INPUT_3_SOURCE:
+	case MADERA_HPLP3MIX_INPUT_3_VOLUME:
+	case MADERA_HPLP3MIX_INPUT_4_SOURCE:
+	case MADERA_HPLP3MIX_INPUT_4_VOLUME:
+	case MADERA_HPLP4MIX_INPUT_1_SOURCE:
+	case MADERA_HPLP4MIX_INPUT_1_VOLUME:
+	case MADERA_HPLP4MIX_INPUT_2_SOURCE:
+	case MADERA_HPLP4MIX_INPUT_2_VOLUME:
+	case MADERA_HPLP4MIX_INPUT_3_SOURCE:
+	case MADERA_HPLP4MIX_INPUT_3_VOLUME:
+	case MADERA_HPLP4MIX_INPUT_4_SOURCE:
+	case MADERA_HPLP4MIX_INPUT_4_VOLUME:
+	case MADERA_DSP1LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP1LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP1LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP1LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP1LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP1LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP1LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP1LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP1RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP1RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP1RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP1RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP1RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP1RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP1RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP1RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP1AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP1AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP1AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP1AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP1AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP1AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP2LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP2LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP2LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP2LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP2LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP2LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP2LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP2RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP2RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP2RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP2RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP2RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP2RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP2RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP2RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP2AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP3LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP3LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP3LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP3LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP3LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP3LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP3LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP3RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP3RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP3RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP3RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP3RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP3RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP3RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP3RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP3AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP4LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP4LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP4LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP4LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP4LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP4LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP4LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP4RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP4RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP4RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP4RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP4RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP4RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP4RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP4RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP4AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP5LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP5LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP5LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP5LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP5LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP5LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP5LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP5RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP5RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP5RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP5RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP5RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP5RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP5RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP5RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP5AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_ASRC1_1LMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC1_1RMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC1_2LMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC1_2RMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC2_1LMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC2_1RMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC2_2LMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC2_2RMIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1DEC1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1DEC2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1DEC3MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1DEC4MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1INT1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1INT2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1INT3MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1INT4MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2DEC1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2DEC2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2DEC3MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2DEC4MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2INT1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2INT2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2INT3MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2INT4MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC3DEC1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC3DEC2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC3INT1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC3INT2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC4DEC1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC4DEC2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC4INT1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC4INT2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP6LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP6LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP6LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP6LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP6LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP6LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP6LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP6RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP6RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP6RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP6RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP6RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP6RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP6RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP6RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP6AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP7LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP7LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP7LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP7LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP7LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP7LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP7LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP7RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP7RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP7RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP7RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP7RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP7RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP7RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP7RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP7AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_FX_CTRL1:
+	case MADERA_FX_CTRL2:
+	case MADERA_EQ1_1:
+	case MADERA_EQ1_2:
+	case MADERA_EQ1_3:
+	case MADERA_EQ1_4:
+	case MADERA_EQ1_5:
+	case MADERA_EQ1_6:
+	case MADERA_EQ1_7:
+	case MADERA_EQ1_8:
+	case MADERA_EQ1_9:
+	case MADERA_EQ1_10:
+	case MADERA_EQ1_11:
+	case MADERA_EQ1_12:
+	case MADERA_EQ1_13:
+	case MADERA_EQ1_14:
+	case MADERA_EQ1_15:
+	case MADERA_EQ1_16:
+	case MADERA_EQ1_17:
+	case MADERA_EQ1_18:
+	case MADERA_EQ1_19:
+	case MADERA_EQ1_20:
+	case MADERA_EQ1_21:
+	case MADERA_EQ2_1:
+	case MADERA_EQ2_2:
+	case MADERA_EQ2_3:
+	case MADERA_EQ2_4:
+	case MADERA_EQ2_5:
+	case MADERA_EQ2_6:
+	case MADERA_EQ2_7:
+	case MADERA_EQ2_8:
+	case MADERA_EQ2_9:
+	case MADERA_EQ2_10:
+	case MADERA_EQ2_11:
+	case MADERA_EQ2_12:
+	case MADERA_EQ2_13:
+	case MADERA_EQ2_14:
+	case MADERA_EQ2_15:
+	case MADERA_EQ2_16:
+	case MADERA_EQ2_17:
+	case MADERA_EQ2_18:
+	case MADERA_EQ2_19:
+	case MADERA_EQ2_20:
+	case MADERA_EQ2_21:
+	case MADERA_EQ3_1:
+	case MADERA_EQ3_2:
+	case MADERA_EQ3_3:
+	case MADERA_EQ3_4:
+	case MADERA_EQ3_5:
+	case MADERA_EQ3_6:
+	case MADERA_EQ3_7:
+	case MADERA_EQ3_8:
+	case MADERA_EQ3_9:
+	case MADERA_EQ3_10:
+	case MADERA_EQ3_11:
+	case MADERA_EQ3_12:
+	case MADERA_EQ3_13:
+	case MADERA_EQ3_14:
+	case MADERA_EQ3_15:
+	case MADERA_EQ3_16:
+	case MADERA_EQ3_17:
+	case MADERA_EQ3_18:
+	case MADERA_EQ3_19:
+	case MADERA_EQ3_20:
+	case MADERA_EQ3_21:
+	case MADERA_EQ4_1:
+	case MADERA_EQ4_2:
+	case MADERA_EQ4_3:
+	case MADERA_EQ4_4:
+	case MADERA_EQ4_5:
+	case MADERA_EQ4_6:
+	case MADERA_EQ4_7:
+	case MADERA_EQ4_8:
+	case MADERA_EQ4_9:
+	case MADERA_EQ4_10:
+	case MADERA_EQ4_11:
+	case MADERA_EQ4_12:
+	case MADERA_EQ4_13:
+	case MADERA_EQ4_14:
+	case MADERA_EQ4_15:
+	case MADERA_EQ4_16:
+	case MADERA_EQ4_17:
+	case MADERA_EQ4_18:
+	case MADERA_EQ4_19:
+	case MADERA_EQ4_20:
+	case MADERA_EQ4_21:
+	case MADERA_DRC1_CTRL1:
+	case MADERA_DRC1_CTRL2:
+	case MADERA_DRC1_CTRL3:
+	case MADERA_DRC1_CTRL4:
+	case MADERA_DRC1_CTRL5:
+	case MADERA_DRC2_CTRL1:
+	case MADERA_DRC2_CTRL2:
+	case MADERA_DRC2_CTRL3:
+	case MADERA_DRC2_CTRL4:
+	case MADERA_DRC2_CTRL5:
+	case MADERA_HPLPF1_1:
+	case MADERA_HPLPF1_2:
+	case MADERA_HPLPF2_1:
+	case MADERA_HPLPF2_2:
+	case MADERA_HPLPF3_1:
+	case MADERA_HPLPF3_2:
+	case MADERA_HPLPF4_1:
+	case MADERA_HPLPF4_2:
+	case MADERA_ASRC1_ENABLE:
+	case MADERA_ASRC1_STATUS:
+	case MADERA_ASRC1_RATE1:
+	case MADERA_ASRC1_RATE2:
+	case MADERA_ASRC2_ENABLE:
+	case MADERA_ASRC2_STATUS:
+	case MADERA_ASRC2_RATE1:
+	case MADERA_ASRC2_RATE2:
+	case MADERA_ISRC_1_CTRL_1:
+	case MADERA_ISRC_1_CTRL_2:
+	case MADERA_ISRC_1_CTRL_3:
+	case MADERA_ISRC_2_CTRL_1:
+	case MADERA_ISRC_2_CTRL_2:
+	case MADERA_ISRC_2_CTRL_3:
+	case MADERA_ISRC_3_CTRL_1:
+	case MADERA_ISRC_3_CTRL_2:
+	case MADERA_ISRC_3_CTRL_3:
+	case MADERA_ISRC_4_CTRL_1:
+	case MADERA_ISRC_4_CTRL_2:
+	case MADERA_ISRC_4_CTRL_3:
+	case MADERA_CLOCK_CONTROL:
+	case MADERA_ANC_SRC:
+	case MADERA_DSP_STATUS:
+	case MADERA_ANC_COEFF_START ... MADERA_ANC_COEFF_END:
+	case MADERA_FCL_FILTER_CONTROL:
+	case MADERA_FCL_ADC_REFORMATTER_CONTROL:
+	case MADERA_FCL_COEFF_START ... MADERA_FCL_COEFF_END:
+	case MADERA_FCR_FILTER_CONTROL:
+	case MADERA_FCR_ADC_REFORMATTER_CONTROL:
+	case MADERA_FCR_COEFF_START ... MADERA_FCR_COEFF_END:
+	case MADERA_DAC_COMP_1:
+	case MADERA_DAC_COMP_2:
+	case MADERA_FRF_COEFFICIENT_1L_1:
+	case MADERA_FRF_COEFFICIENT_1L_2:
+	case MADERA_FRF_COEFFICIENT_1L_3:
+	case MADERA_FRF_COEFFICIENT_1L_4:
+	case MADERA_FRF_COEFFICIENT_1R_1:
+	case MADERA_FRF_COEFFICIENT_1R_2:
+	case MADERA_FRF_COEFFICIENT_1R_3:
+	case MADERA_FRF_COEFFICIENT_1R_4:
+	case MADERA_FRF_COEFFICIENT_2L_1:
+	case MADERA_FRF_COEFFICIENT_2L_2:
+	case MADERA_FRF_COEFFICIENT_2L_3:
+	case MADERA_FRF_COEFFICIENT_2L_4:
+	case MADERA_FRF_COEFFICIENT_2R_1:
+	case MADERA_FRF_COEFFICIENT_2R_2:
+	case MADERA_FRF_COEFFICIENT_2R_3:
+	case MADERA_FRF_COEFFICIENT_2R_4:
+	case MADERA_FRF_COEFFICIENT_3L_1:
+	case MADERA_FRF_COEFFICIENT_3L_2:
+	case MADERA_FRF_COEFFICIENT_3L_3:
+	case MADERA_FRF_COEFFICIENT_3L_4:
+	case MADERA_FRF_COEFFICIENT_3R_1:
+	case MADERA_FRF_COEFFICIENT_3R_2:
+	case MADERA_FRF_COEFFICIENT_3R_3:
+	case MADERA_FRF_COEFFICIENT_3R_4:
+	case MADERA_FRF_COEFFICIENT_4L_1:
+	case MADERA_FRF_COEFFICIENT_4L_2:
+	case MADERA_FRF_COEFFICIENT_4L_3:
+	case MADERA_FRF_COEFFICIENT_4L_4:
+	case MADERA_FRF_COEFFICIENT_4R_1:
+	case MADERA_FRF_COEFFICIENT_4R_2:
+	case MADERA_FRF_COEFFICIENT_4R_3:
+	case MADERA_FRF_COEFFICIENT_4R_4:
+	case MADERA_FRF_COEFFICIENT_5L_1:
+	case MADERA_FRF_COEFFICIENT_5L_2:
+	case MADERA_FRF_COEFFICIENT_5L_3:
+	case MADERA_FRF_COEFFICIENT_5L_4:
+	case MADERA_FRF_COEFFICIENT_5R_1:
+	case MADERA_FRF_COEFFICIENT_5R_2:
+	case MADERA_FRF_COEFFICIENT_5R_3:
+	case MADERA_FRF_COEFFICIENT_5R_4:
+	case MADERA_FRF_COEFFICIENT_6L_1:
+	case MADERA_FRF_COEFFICIENT_6L_2:
+	case MADERA_FRF_COEFFICIENT_6L_3:
+	case MADERA_FRF_COEFFICIENT_6L_4:
+	case MADERA_FRF_COEFFICIENT_6R_1:
+	case MADERA_FRF_COEFFICIENT_6R_2:
+	case MADERA_FRF_COEFFICIENT_6R_3:
+	case MADERA_FRF_COEFFICIENT_6R_4:
+	case MADERA_GPIO1_CTRL_1:
+	case MADERA_GPIO1_CTRL_2:
+	case MADERA_GPIO2_CTRL_1:
+	case MADERA_GPIO2_CTRL_2:
+	case MADERA_GPIO3_CTRL_1:
+	case MADERA_GPIO3_CTRL_2:
+	case MADERA_GPIO4_CTRL_1:
+	case MADERA_GPIO4_CTRL_2:
+	case MADERA_GPIO5_CTRL_1:
+	case MADERA_GPIO5_CTRL_2:
+	case MADERA_GPIO6_CTRL_1:
+	case MADERA_GPIO6_CTRL_2:
+	case MADERA_GPIO7_CTRL_1:
+	case MADERA_GPIO7_CTRL_2:
+	case MADERA_GPIO8_CTRL_1:
+	case MADERA_GPIO8_CTRL_2:
+	case MADERA_GPIO9_CTRL_1:
+	case MADERA_GPIO9_CTRL_2:
+	case MADERA_GPIO10_CTRL_1:
+	case MADERA_GPIO10_CTRL_2:
+	case MADERA_GPIO11_CTRL_1:
+	case MADERA_GPIO11_CTRL_2:
+	case MADERA_GPIO12_CTRL_1:
+	case MADERA_GPIO12_CTRL_2:
+	case MADERA_GPIO13_CTRL_1:
+	case MADERA_GPIO13_CTRL_2:
+	case MADERA_GPIO14_CTRL_1:
+	case MADERA_GPIO14_CTRL_2:
+	case MADERA_GPIO15_CTRL_1:
+	case MADERA_GPIO15_CTRL_2:
+	case MADERA_GPIO16_CTRL_1:
+	case MADERA_GPIO16_CTRL_2:
+	case MADERA_GPIO17_CTRL_1:
+	case MADERA_GPIO17_CTRL_2:
+	case MADERA_GPIO18_CTRL_1:
+	case MADERA_GPIO18_CTRL_2:
+	case MADERA_GPIO19_CTRL_1:
+	case MADERA_GPIO19_CTRL_2:
+	case MADERA_GPIO20_CTRL_1:
+	case MADERA_GPIO20_CTRL_2:
+	case MADERA_GPIO21_CTRL_1:
+	case MADERA_GPIO21_CTRL_2:
+	case MADERA_GPIO22_CTRL_1:
+	case MADERA_GPIO22_CTRL_2:
+	case MADERA_GPIO23_CTRL_1:
+	case MADERA_GPIO23_CTRL_2:
+	case MADERA_GPIO24_CTRL_1:
+	case MADERA_GPIO24_CTRL_2:
+	case MADERA_GPIO25_CTRL_1:
+	case MADERA_GPIO25_CTRL_2:
+	case MADERA_GPIO26_CTRL_1:
+	case MADERA_GPIO26_CTRL_2:
+	case MADERA_GPIO27_CTRL_1:
+	case MADERA_GPIO27_CTRL_2:
+	case MADERA_GPIO28_CTRL_1:
+	case MADERA_GPIO28_CTRL_2:
+	case MADERA_GPIO29_CTRL_1:
+	case MADERA_GPIO29_CTRL_2:
+	case MADERA_GPIO30_CTRL_1:
+	case MADERA_GPIO30_CTRL_2:
+	case MADERA_GPIO31_CTRL_1:
+	case MADERA_GPIO31_CTRL_2:
+	case MADERA_GPIO32_CTRL_1:
+	case MADERA_GPIO32_CTRL_2:
+	case MADERA_GPIO33_CTRL_1:
+	case MADERA_GPIO33_CTRL_2:
+	case MADERA_GPIO34_CTRL_1:
+	case MADERA_GPIO34_CTRL_2:
+	case MADERA_GPIO35_CTRL_1:
+	case MADERA_GPIO35_CTRL_2:
+	case MADERA_GPIO36_CTRL_1:
+	case MADERA_GPIO36_CTRL_2:
+	case MADERA_GPIO37_CTRL_1:
+	case MADERA_GPIO37_CTRL_2:
+	case MADERA_GPIO38_CTRL_1:
+	case MADERA_GPIO38_CTRL_2:
+	case MADERA_GPIO39_CTRL_1:
+	case MADERA_GPIO39_CTRL_2:
+	case MADERA_GPIO40_CTRL_1:
+	case MADERA_GPIO40_CTRL_2:
+	case MADERA_IRQ1_STATUS_1 ... MADERA_IRQ1_STATUS_33:
+	case MADERA_IRQ1_MASK_1 ... MADERA_IRQ1_MASK_33:
+	case MADERA_IRQ1_RAW_STATUS_1 ... MADERA_IRQ1_RAW_STATUS_33:
+	case MADERA_INTERRUPT_DEBOUNCE_7:
+	case MADERA_IRQ1_CTRL:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool cs47l85_16bit_volatile_register(struct device *dev,
+					    unsigned int reg)
+{
+	switch (reg) {
+	case MADERA_SOFTWARE_RESET:
+	case MADERA_HARDWARE_REVISION:
+	case MADERA_WRITE_SEQUENCER_CTRL_0:
+	case MADERA_WRITE_SEQUENCER_CTRL_1:
+	case MADERA_WRITE_SEQUENCER_CTRL_2:
+	case MADERA_HAPTICS_STATUS:
+	case MADERA_SAMPLE_RATE_1_STATUS:
+	case MADERA_SAMPLE_RATE_2_STATUS:
+	case MADERA_SAMPLE_RATE_3_STATUS:
+	case MADERA_ASYNC_SAMPLE_RATE_1_STATUS:
+	case MADERA_ASYNC_SAMPLE_RATE_2_STATUS:
+	case MADERA_HP_CTRL_1L:
+	case MADERA_HP_CTRL_1R:
+	case MADERA_HP_CTRL_2L:
+	case MADERA_HP_CTRL_2R:
+	case MADERA_HP_CTRL_3L:
+	case MADERA_HP_CTRL_3R:
+	case MADERA_DCS_HP1L_CONTROL:
+	case MADERA_DCS_HP1R_CONTROL:
+	case MADERA_MIC_DETECT_1_CONTROL_3:
+	case MADERA_MIC_DETECT_1_CONTROL_4:
+	case MADERA_HEADPHONE_DETECT_2:
+	case MADERA_HEADPHONE_DETECT_3:
+	case MADERA_HEADPHONE_DETECT_5:
+	case MADERA_INPUT_ENABLES_STATUS:
+	case MADERA_OUTPUT_STATUS_1:
+	case MADERA_RAW_OUTPUT_STATUS_1:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_1:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_2:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_3:
+	case MADERA_SLIMBUS_RX_PORT_STATUS:
+	case MADERA_SLIMBUS_TX_PORT_STATUS:
+	case MADERA_FX_CTRL2:
+	case MADERA_ASRC2_STATUS:
+	case MADERA_ASRC1_STATUS:
+	case MADERA_CLOCK_CONTROL:
+	case MADERA_IRQ1_STATUS_1 ...MADERA_IRQ1_STATUS_33:
+	case MADERA_IRQ1_RAW_STATUS_1 ... MADERA_IRQ1_RAW_STATUS_33:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool cs47l85_32bit_readable_register(struct device *dev,
+					    unsigned int reg)
+{
+	switch (reg) {
+	case MADERA_WSEQ_SEQUENCE_1 ... MADERA_WSEQ_SEQUENCE_508:
+	case CS47L85_OTP_HPDET_CAL_1 ... CS47L85_OTP_HPDET_CAL_2:
+	case MADERA_DSP1_CONFIG_1 ... MADERA_DSP1_SCRATCH_2:
+	case MADERA_DSP2_CONFIG_1 ... MADERA_DSP2_SCRATCH_2:
+	case MADERA_DSP3_CONFIG_1 ... MADERA_DSP3_SCRATCH_2:
+	case MADERA_DSP4_CONFIG_1 ... MADERA_DSP4_SCRATCH_2:
+	case MADERA_DSP5_CONFIG_1 ... MADERA_DSP5_SCRATCH_2:
+	case MADERA_DSP6_CONFIG_1 ... MADERA_DSP6_SCRATCH_2:
+	case MADERA_DSP7_CONFIG_1 ... MADERA_DSP7_SCRATCH_2:
+		return true;
+	default:
+		return cs47l85_is_adsp_memory(reg);
+	}
+}
+
+static bool cs47l85_32bit_volatile_register(struct device *dev,
+					    unsigned int reg)
+{
+	switch (reg) {
+	case MADERA_WSEQ_SEQUENCE_1 ... MADERA_WSEQ_SEQUENCE_508:
+	case CS47L85_OTP_HPDET_CAL_1 ... CS47L85_OTP_HPDET_CAL_2:
+	case MADERA_DSP1_CONFIG_1 ... MADERA_DSP1_SCRATCH_2:
+	case MADERA_DSP2_CONFIG_1 ... MADERA_DSP2_SCRATCH_2:
+	case MADERA_DSP3_CONFIG_1 ... MADERA_DSP3_SCRATCH_2:
+	case MADERA_DSP4_CONFIG_1 ... MADERA_DSP4_SCRATCH_2:
+	case MADERA_DSP5_CONFIG_1 ... MADERA_DSP5_SCRATCH_2:
+	case MADERA_DSP6_CONFIG_1 ... MADERA_DSP6_SCRATCH_2:
+	case MADERA_DSP7_CONFIG_1 ... MADERA_DSP7_SCRATCH_2:
+		return true;
+	default:
+		return cs47l85_is_adsp_memory(reg);
+	}
+}
+
+const struct regmap_config cs47l85_16bit_spi_regmap = {
+	.name = "cs47l85_16bit",
+	.reg_bits = 32,
+	.pad_bits = 16,
+	.val_bits = 16,
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+	.val_format_endian = REGMAP_ENDIAN_BIG,
+
+	.max_register = 0x2fff,
+	.readable_reg = cs47l85_16bit_readable_register,
+	.volatile_reg = cs47l85_16bit_volatile_register,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = cs47l85_reg_default,
+	.num_reg_defaults = ARRAY_SIZE(cs47l85_reg_default),
+};
+EXPORT_SYMBOL_GPL(cs47l85_16bit_spi_regmap);
+
+const struct regmap_config cs47l85_16bit_i2c_regmap = {
+	.name = "cs47l85_16bit",
+	.reg_bits = 32,
+	.val_bits = 16,
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+	.val_format_endian = REGMAP_ENDIAN_BIG,
+
+	.max_register = 0x2fff,
+	.readable_reg = cs47l85_16bit_readable_register,
+	.volatile_reg = cs47l85_16bit_volatile_register,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = cs47l85_reg_default,
+	.num_reg_defaults = ARRAY_SIZE(cs47l85_reg_default),
+};
+EXPORT_SYMBOL_GPL(cs47l85_16bit_i2c_regmap);
+
+const struct regmap_config cs47l85_32bit_spi_regmap = {
+	.name = "cs47l85_32bit",
+	.reg_bits = 32,
+	.reg_stride = 2,
+	.pad_bits = 16,
+	.val_bits = 32,
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+	.val_format_endian = REGMAP_ENDIAN_BIG,
+
+	.max_register = MADERA_DSP7_SCRATCH_2,
+	.readable_reg = cs47l85_32bit_readable_register,
+	.volatile_reg = cs47l85_32bit_volatile_register,
+
+	.cache_type = REGCACHE_RBTREE,
+};
+EXPORT_SYMBOL_GPL(cs47l85_32bit_spi_regmap);
+
+const struct regmap_config cs47l85_32bit_i2c_regmap = {
+	.name = "cs47l85_32bit",
+	.reg_bits = 32,
+	.reg_stride = 2,
+	.val_bits = 32,
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+	.val_format_endian = REGMAP_ENDIAN_BIG,
+
+	.max_register = MADERA_DSP7_SCRATCH_2,
+	.readable_reg = cs47l85_32bit_readable_register,
+	.volatile_reg = cs47l85_32bit_volatile_register,
+
+	.cache_type = REGCACHE_RBTREE,
+};
+EXPORT_SYMBOL_GPL(cs47l85_32bit_i2c_regmap);
-- 
1.9.1


^ permalink raw reply related

* [PATCH v2 06/18] mfd: madera: Register map tables for Cirrus Logic CS47L90/91
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones-QSEj5FYQhm4dnm+yROfE0A, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	gnurou-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493050124-5970-1-git-send-email-rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>

Regmap configuration tables for Cirrus Logic CS47L90 and CS47L91 codecs.

Signed-off-by: Nikesh Oswal <nikesh-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
Signed-off-by: Richard Fitzgerald <rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
Signed-off-by: Charles Keepax <ckeepax-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
---
Changes since V1:
- select PINCTRL build option from here instead of having PINCTRL
  derive it using a "default y if" formula

 drivers/mfd/Kconfig          |    7 +
 drivers/mfd/Makefile         |    3 +
 drivers/mfd/cs47l90-tables.c | 2830 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 2840 insertions(+)
 create mode 100644 drivers/mfd/cs47l90-tables.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index bfcafc2..34b9480 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -246,6 +246,13 @@ config MFD_CS47L85
 	help
 	  Support for Cirrus Logic CS47L85 Smart Codec
 
+config MFD_CS47L90
+	bool "Cirrus Logic CS47L90/91"
+	select PINCTRL_CS47L90
+	depends on MFD_MADERA
+	help
+	  Support for Cirrus Logic CS47L90 and CS47L91 Smart Codecs
+
 config MFD_ASIC3
 	bool "Compaq ASIC3"
 	depends on GPIOLIB && ARM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index e522774..57ea34e 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -79,6 +79,9 @@ endif
 ifeq ($(CONFIG_MFD_CS47L85),y)
 obj-$(CONFIG_MFD_MADERA)	+= cs47l85-tables.o
 endif
+ifeq ($(CONFIG_MFD_CS47L90),y)
+obj-$(CONFIG_MFD_MADERA)	+= cs47l90-tables.o
+endif
 obj-$(CONFIG_MFD_MADERA_I2C)	+= madera-i2c.o
 obj-$(CONFIG_MFD_MADERA_SPI)	+= madera-spi.o
 
diff --git a/drivers/mfd/cs47l90-tables.c b/drivers/mfd/cs47l90-tables.c
new file mode 100644
index 0000000..52ce50f
--- /dev/null
+++ b/drivers/mfd/cs47l90-tables.c
@@ -0,0 +1,2830 @@
+/*
+ * Regmap tables for CS47L90 codec
+ *
+ * Copyright 2015-2016 Cirrus Logic
+ *
+ * Author: Nikesh Oswal <nikesh-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/registers.h>
+
+#include "madera.h"
+
+static const struct reg_sequence cs47l90_reva_16_patch[] = {
+	{ 0x8A,   0x5555 },
+	{ 0x8A,   0xAAAA },
+	{ 0x4CF,  0x0700 },
+	{ 0x171,  0x0003 },
+	{ 0x101,  0x0444 },
+	{ 0x159,  0x0002 },
+	{ 0x120,  0x0444 },
+	{ 0x1D1,  0x0004 },
+	{ 0x1E0,  0xC084 },
+	{ 0x159,  0x0000 },
+	{ 0x120,  0x0404 },
+	{ 0x101,  0x0404 },
+	{ 0x171,  0x0002 },
+	{ 0x17A,  0x2906 },
+	{ 0x19A,  0x2906 },
+	{ 0x441,  0xC750 },
+	{ 0x340,  0x0001 },
+	{ 0x112,  0x0405 },
+	{ 0x124,  0x0C49 },
+	{ 0x1300, 0x050E },
+	{ 0x1302, 0x0101 },
+	{ 0x1380, 0x0425 },
+	{ 0x1381, 0xF6D8 },
+	{ 0x1382, 0x0632 },
+	{ 0x1383, 0xFEC8 },
+	{ 0x1390, 0x042F },
+	{ 0x1391, 0xF6CA },
+	{ 0x1392, 0x0637 },
+	{ 0x1393, 0xFEC8 },
+	{ 0x281,  0x0000 },
+	{ 0x282,  0x0000 },
+	{ 0x4EA,  0x0100 },
+	{ 0x8A,   0xCCCC },
+	{ 0x8A,   0x3333 },
+};
+
+int cs47l90_patch(struct madera *madera)
+{
+	int ret;
+
+	ret = regmap_register_patch(madera->regmap,
+				    cs47l90_reva_16_patch,
+				    ARRAY_SIZE(cs47l90_reva_16_patch));
+	if (ret < 0) {
+		dev_err(madera->dev,
+			"Error in applying 16-bit patch: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cs47l90_patch);
+
+static const struct reg_default cs47l90_reg_default[] = {
+	{ 0x00000020, 0x0000 }, /* R32 (0x20) - Tone Generator 1 */
+	{ 0x00000021, 0x1000 }, /* R33 (0x21) - Tone Generator 2 */
+	{ 0x00000022, 0x0000 }, /* R34 (0x22) - Tone Generator 3 */
+	{ 0x00000023, 0x1000 }, /* R35 (0x23) - Tone Generator 4 */
+	{ 0x00000024, 0x0000 }, /* R36 (0x24) - Tone Generator 5 */
+	{ 0x00000030, 0x0000 }, /* R48 (0x30) - PWM Drive 1 */
+	{ 0x00000031, 0x0100 }, /* R49 (0x31) - PWM Drive 2 */
+	{ 0x00000032, 0x0100 }, /* R50 (0x32) - PWM Drive 3 */
+	{ 0x00000061, 0x01ff }, /* R97 (0x61) - Sample Rate Sequence Select 1 */
+	{ 0x00000062, 0x01ff }, /* R98 (0x62) - Sample Rate Sequence Select 2 */
+	{ 0x00000063, 0x01ff }, /* R99 (0x63) - Sample Rate Sequence Select 3 */
+	{ 0x00000064, 0x01ff }, /* R100 (0x64) - Sample Rate Sequence Select 4 */
+	{ 0x00000066, 0x01ff }, /* R102 (0x66) - Always On Triggers Sequence Select 1 */
+	{ 0x00000067, 0x01ff }, /* R103 (0x67) - Always On Triggers Sequence Select 2 */
+	{ 0x00000090, 0x0000 }, /* R144 (0x90) - Haptics Control 1 */
+	{ 0x00000091, 0x7fff }, /* R145 (0x91) - Haptics Control 2 */
+	{ 0x00000092, 0x0000 }, /* R146 (0x92) - Haptics phase 1 intensity */
+	{ 0x00000093, 0x0000 }, /* R147 (0x93) - Haptics phase 1 duration */
+	{ 0x00000094, 0x0000 }, /* R148 (0x94) - Haptics phase 2 intensity */
+	{ 0x00000095, 0x0000 }, /* R149 (0x95) - Haptics phase 2 duration */
+	{ 0x00000096, 0x0000 }, /* R150 (0x96) - Haptics phase 3 intensity */
+	{ 0x00000097, 0x0000 }, /* R151 (0x97) - Haptics phase 3 duration */
+	{ 0x000000a0, 0x0000 }, /* R160 (0xa0) - Comfort Noise Generator */
+	{ 0x00000100, 0x0002 }, /* R256 (0x100) - Clock 32k 1 */
+	{ 0x00000101, 0x0404 }, /* R257 (0x101) - System Clock 1 */
+	{ 0x00000102, 0x0011 }, /* R258 (0x102) - Sample rate 1 */
+	{ 0x00000103, 0x0011 }, /* R259 (0x103) - Sample rate 2 */
+	{ 0x00000104, 0x0011 }, /* R260 (0x104) - Sample rate 3 */
+	{ 0x00000112, 0x0405 }, /* R274 (0x112) - Async clock 1 */
+	{ 0x00000113, 0x0011 }, /* R275 (0x113) - Async sample rate 1 */
+	{ 0x00000114, 0x0011 }, /* R276 (0x114) - Async sample rate 2 */
+	{ 0x00000120, 0x0404 }, /* R288 (0x120) - DSP Clock 1 */
+	{ 0x00000122, 0x0000 }, /* R290 (0x122) - DSP Clock 2 */
+	{ 0x00000149, 0x0000 }, /* R329 (0x149) - Output system clock */
+	{ 0x0000014a, 0x0000 }, /* R330 (0x14a) - Output async clock */
+	{ 0x00000152, 0x0000 }, /* R338 (0x152) - Rate Estimator 1 */
+	{ 0x00000153, 0x0000 }, /* R339 (0x153) - Rate Estimator 2 */
+	{ 0x00000154, 0x0000 }, /* R340 (0x154) - Rate Estimator 3 */
+	{ 0x00000155, 0x0000 }, /* R341 (0x155) - Rate Estimator 4 */
+	{ 0x00000156, 0x0000 }, /* R342 (0x156) - Rate Estimator 5 */
+	{ 0x00000171, 0x0002 }, /* R369 (0x171) - FLL1 Control 1 */
+	{ 0x00000172, 0x0008 }, /* R370 (0x172) - FLL1 Control 2 */
+	{ 0x00000173, 0x0018 }, /* R371 (0x173) - FLL1 Control 3 */
+	{ 0x00000174, 0x007d }, /* R372 (0x174) - FLL1 Control 4 */
+	{ 0x00000175, 0x0000 }, /* R373 (0x175) - FLL1 Control 5 */
+	{ 0x00000176, 0x0000 }, /* R374 (0x176) - FLL1 Control 6 */
+	{ 0x00000177, 0x0281 }, /* R375 (0x177) - FLL1 Loop Filter Test 1 */
+	{ 0x00000179, 0x0000 }, /* R377 (0x179) - FLL1 Control 7 */
+	{ 0x0000017a, 0x2906 }, /* R377 (0x17a) - FLL1 Efs 2 */
+	{ 0x00000181, 0x0000 }, /* R385 (0x181) - FLL1 Synchroniser 1 */
+	{ 0x00000182, 0x0000 }, /* R386 (0x182) - FLL1 Synchroniser 2 */
+	{ 0x00000183, 0x0000 }, /* R387 (0x183) - FLL1 Synchroniser 3 */
+	{ 0x00000184, 0x0000 }, /* R388 (0x184) - FLL1 Synchroniser 4 */
+	{ 0x00000185, 0x0000 }, /* R389 (0x185) - FLL1 Synchroniser 5 */
+	{ 0x00000186, 0x0000 }, /* R390 (0x186) - FLL1 Synchroniser 6 */
+	{ 0x00000187, 0x0001 }, /* R391 (0x187) - FLL1 Synchroniser 7 */
+	{ 0x00000189, 0x0000 }, /* R393 (0x189) - FLL1 Spread Spectrum */
+	{ 0x0000018a, 0x0004 }, /* R394 (0x18a) - FLL1 GPIO Clock */
+	{ 0x00000191, 0x0002 }, /* R401 (0x191) - FLL2 Control 1 */
+	{ 0x00000192, 0x0008 }, /* R402 (0x192) - FLL2 Control 2 */
+	{ 0x00000193, 0x0018 }, /* R403 (0x193) - FLL2 Control 3 */
+	{ 0x00000194, 0x007d }, /* R404 (0x194) - FLL2 Control 4 */
+	{ 0x00000195, 0x0000 }, /* R405 (0x195) - FLL2 Control 5 */
+	{ 0x00000196, 0x0000 }, /* R406 (0x196) - FLL2 Control 6 */
+	{ 0x00000197, 0x0281 }, /* R407 (0x197) - FLL2 Loop Filter Test 1 */
+	{ 0x00000199, 0x0000 }, /* R409 (0x199) - FLL2 Control 7 */
+	{ 0x0000019a, 0x2906 }, /* R410 (0x19a) - FLL2 Efs 2 */
+	{ 0x000001a1, 0x0000 }, /* R417 (0x1a1) - FLL2 Synchroniser 1 */
+	{ 0x000001a2, 0x0000 }, /* R418 (0x1a2) - FLL2 Synchroniser 2 */
+	{ 0x000001a3, 0x0000 }, /* R419 (0x1a3) - FLL2 Synchroniser 3 */
+	{ 0x000001a4, 0x0000 }, /* R420 (0x1a4) - FLL2 Synchroniser 4 */
+	{ 0x000001a5, 0x0000 }, /* R421 (0x1a5) - FLL2 Synchroniser 5 */
+	{ 0x000001a6, 0x0000 }, /* R422 (0x1a6) - FLL2 Synchroniser 6 */
+	{ 0x000001a7, 0x0001 }, /* R423 (0x1a7) - FLL2 Synchroniser 7 */
+	{ 0x000001a9, 0x0000 }, /* R425 (0x1a9) - FLL2 Spread Spectrum */
+	{ 0x000001aa, 0x0004 }, /* R426 (0x1aa) - FLL2 GPIO Clock */
+	{ 0x000001d1, 0x0004 }, /* R465 (0x1d1) - FLLAO_CONTROL_1 */
+	{ 0x000001d2, 0x0004 }, /* R466 (0x1d2) - FLLAO_CONTROL_2 */
+	{ 0x000001d3, 0x0000 }, /* R467 (0x1d3) - FLLAO_CONTROL_3 */
+	{ 0x000001d4, 0x0000 }, /* R468 (0x1d4) - FLLAO_CONTROL_4 */
+	{ 0x000001d5, 0x0001 }, /* R469 (0x1d5) - FLLAO_CONTROL_5 */
+	{ 0x000001d6, 0x8004 }, /* R470 (0x1d6) - FLLAO_CONTROL_6 */
+	{ 0x000001d8, 0x0000 }, /* R472 (0x1d8) - FLLAO_CONTROL_7 */
+	{ 0x000001da, 0x0070 }, /* R474 (0x1da) - FLLAO_CONTROL_8 */
+	{ 0x000001db, 0x0000 }, /* R475 (0x1db) - FLLAO_CONTROL_9 */
+	{ 0x000001dc, 0x06da }, /* R476 (0x1dc) - FLLAO_CONTROL_10 */
+	{ 0x000001dd, 0x0011 }, /* R477 (0x1dd) - FLLAO_CONTROL_11 */
+	{ 0x00000200, 0x0006 }, /* R512 (0x200) - Mic Charge Pump 1 */
+	{ 0x00000213, 0x03e4 }, /* R531 (0x213) - LDO2 Control 1 */
+	{ 0x00000218, 0x00e6 }, /* R536 (0x218) - Mic Bias Ctrl 1 */
+	{ 0x00000219, 0x00e6 }, /* R537 (0x219) - Mic Bias Ctrl 2 */
+	{ 0x0000021c, 0x2222 }, /* R540 (0x21c) - Mic Bias Ctrl 5 */
+	{ 0x0000021e, 0x2222 }, /* R542 (0x21e) - Mic Bias Ctrl 6 */
+	{ 0x0000027e, 0x0000 }, /* R638 (0x27e) - EDRE HP stereo control */
+	{ 0x00000293, 0x0080 }, /* R659 (0x293) - Accessory Detect Mode 1 */
+	{ 0x00000299, 0x0000 }, /* R665 (0x299) - Headphone Detect 0 */
+	{ 0x0000029b, 0x0000 }, /* R667 (0x29b) - Headphone Detect 1 */
+	{ 0x000002a2, 0x0010 }, /* R674 (0x2a2) - Mic Detect 1 Control 0 */
+	{ 0x000002a3, 0x1102 }, /* R675 (0x2a3) - Mic Detect 1 Control 1 */
+	{ 0x000002a4, 0x009f }, /* R676 (0x2a4) - Mic Detect 1 Control 2 */
+	{ 0x000002a6, 0x3d3d }, /* R678 (0x2a6) - Mic Detect 1 Level 1 */
+	{ 0x000002a7, 0x3d3d }, /* R679 (0x2a7) - Mic Detect 1 Level 2 */
+	{ 0x000002a8, 0x333d }, /* R680 (0x2a8) - Mic Detect 1 Level 3 */
+	{ 0x000002a9, 0x202d }, /* R681 (0x2a9) - Mic Detect 1 Level 4 */
+	{ 0x000002b2, 0x0010 }, /* R690 (0x2b2) - Mic Detect 2 Control 0 */
+	{ 0x000002b3, 0x1102 }, /* R691 (0x2b3) - Mic Detect 2 Control 1 */
+	{ 0x000002b4, 0x009f }, /* R692 (0x2b4) - Mic Detect 2 Control 2 */
+	{ 0x000002b6, 0x3d3d }, /* R694 (0x2b6) - Mic Detect 2 Level 1 */
+	{ 0x000002b7, 0x3d3d }, /* R695 (0x2b7) - Mic Detect 2 Level 2 */
+	{ 0x000002b8, 0x333d }, /* R696 (0x2b8) - Mic Detect 2 Level 3 */
+	{ 0x000002b9, 0x202d }, /* R697 (0x2b9) - Mic Detect 2 Level 4 */
+	{ 0x000002c6, 0x0010 }, /* R710 (0x2c6) - Mic Clamp control */
+	{ 0x000002c8, 0x0000 }, /* R712 (0x2c8) - GP switch 1 */
+	{ 0x000002d3, 0x0000 }, /* R723 (0x2d3) - Jack detect analogue */
+	{ 0x00000300, 0x0000 }, /* R768 (0x300) - Input Enables */
+	{ 0x00000308, 0x0400 }, /* R776 (0x308) - Input Rate */
+	{ 0x00000309, 0x0022 }, /* R777 (0x309) - Input Volume Ramp */
+	{ 0x0000030c, 0x0002 }, /* R780 (0x30C) - HPF Control */
+	{ 0x00000310, 0x0080 }, /* R784 (0x310) - IN1L Control */
+	{ 0x00000311, 0x0180 }, /* R785 (0x311) - ADC Digital Volume 1L */
+	{ 0x00000312, 0x0500 }, /* R786 (0x312) - DMIC1L Control */
+	{ 0x00000313, 0x0000 }, /* R787 (0x313) - IN1L Rate Control */
+	{ 0x00000314, 0x0080 }, /* R788 (0x314) - IN1R Control */
+	{ 0x00000315, 0x0180 }, /* R789 (0x315) - ADC Digital Volume 1R */
+	{ 0x00000316, 0x0000 }, /* R790 (0x316) - DMIC1R Control */
+	{ 0x00000317, 0x0000 }, /* R791 (0x317) - IN1R Rate Control */
+	{ 0x00000318, 0x0080 }, /* R792 (0x318) - IN2L Control */
+	{ 0x00000319, 0x0180 }, /* R793 (0x319) - ADC Digital Volume 2L */
+	{ 0x0000031a, 0x0500 }, /* R794 (0x31a) - DMIC2L Control */
+	{ 0x0000031b, 0x0000 }, /* R795 (0x31b) - IN2L Rate Control */
+	{ 0x0000031c, 0x0080 }, /* R796 (0x31c) - IN2R Control */
+	{ 0x0000031d, 0x0180 }, /* R797 (0x31d) - ADC Digital Volume 2R */
+	{ 0x0000031e, 0x0000 }, /* R798 (0x31e) - DMIC2R Control */
+	{ 0x0000031f, 0x0000 }, /* R799 (0x31f) - IN2R Rate Control */
+	{ 0x00000320, 0x0000 }, /* R800 (0x320) - IN3L Control */
+	{ 0x00000321, 0x0180 }, /* R801 (0x321) - ADC Digital Volume 3L */
+	{ 0x00000322, 0x0500 }, /* R802 (0x322) - DMIC3L Control */
+	{ 0x00000323, 0x0000 }, /* R803 (0x323) - IN3L Rate Control */
+	{ 0x00000324, 0x0000 }, /* R804 (0x324) - IN3R Control */
+	{ 0x00000325, 0x0180 }, /* R805 (0x325) - ADC Digital Volume 3R */
+	{ 0x00000326, 0x0000 }, /* R806 (0x326) - DMIC3R Control */
+	{ 0x00000327, 0x0000 }, /* R807 (0x327) - IN3R Rate Control */
+	{ 0x00000328, 0x0000 }, /* R808 (0x328) - IN4 Control */
+	{ 0x00000329, 0x0180 }, /* R809 (0x329) - ADC Digital Volume 4L */
+	{ 0x0000032a, 0x0500 }, /* R810 (0x32a) - DMIC4L Control */
+	{ 0x0000032b, 0x0000 }, /* R811 (0x32b) - IN4L Rate Control */
+	{ 0x0000032c, 0x0000 }, /* R812 (0x32c) - IN4R Control */
+	{ 0x0000032d, 0x0180 }, /* R813 (0x32d) - ADC Digital Volume 4R */
+	{ 0x0000032e, 0x0000 }, /* R814 (0x32e) - DMIC4R Control */
+	{ 0x0000032f, 0x0000 }, /* R815 (0x32f) - IN4R Rate Control */
+	{ 0x00000330, 0x0000 }, /* R816 (0x330) - IN5L Control */
+	{ 0x00000331, 0x0180 }, /* R817 (0x331) - ADC Digital Volume 5L */
+	{ 0x00000332, 0x0500 }, /* R818 (0x332) - DMIC5L Control */
+	{ 0x00000333, 0x0000 }, /* R819 (0x333) - IN5L Rate Control */
+	{ 0x00000334, 0x0000 }, /* R820 (0x334) - IN5R Control */
+	{ 0x00000335, 0x0180 }, /* R821 (0x335) - ADC Digital Volume 5R */
+	{ 0x00000336, 0x0000 }, /* R822 (0x336) - DMIC5R Control */
+	{ 0x00000337, 0x0000 }, /* R823 (0x337) - IN5R Rate Control */
+	{ 0x00000400, 0x0000 }, /* R1024 (0x400) - Output Enables 1 */
+	{ 0x00000408, 0x0000 }, /* R1032 (0x408) - Output Rate 1 */
+	{ 0x00000409, 0x0022 }, /* R1033 (0x409) - Output Volume Ramp */
+	{ 0x00000410, 0x0080 }, /* R1040 (0x410) - Output Path Config 1L */
+	{ 0x00000411, 0x0180 }, /* R1041 (0x411) - DAC Digital Volume 1L */
+	{ 0x00000412, 0x0000 }, /* R1042 (0x412) - Output Path Config 1 */
+	{ 0x00000413, 0x0001 }, /* R1043 (0x413) - Noise Gate Select 1L */
+	{ 0x00000414, 0x0080 }, /* R1044 (0x414) - Output Path Config 1R */
+	{ 0x00000415, 0x0180 }, /* R1045 (0x415) - DAC Digital Volume 1R */
+	{ 0x00000417, 0x0002 }, /* R1047 (0x417) - Noise Gate Select 1R */
+	{ 0x00000418, 0x0080 }, /* R1048 (0x418) - Output Path Config 2L */
+	{ 0x00000419, 0x0180 }, /* R1049 (0x419) - DAC Digital Volume 2L */
+	{ 0x0000041a, 0x0002 }, /* R1050 (0x41a) - Output Path Config 2 */
+	{ 0x0000041b, 0x0004 }, /* R1051 (0x41b) - Noise Gate Select 2L */
+	{ 0x0000041c, 0x0080 }, /* R1052 (0x41c) - Output Path Config 2R */
+	{ 0x0000041d, 0x0180 }, /* R1053 (0x41d) - DAC Digital Volume 2R */
+	{ 0x0000041f, 0x0008 }, /* R1055 (0x41f) - Noise Gate Select 2R */
+	{ 0x00000420, 0x0080 }, /* R1056 (0x420) - Output Path Config 3L */
+	{ 0x00000421, 0x0180 }, /* R1057 (0x421) - DAC Digital Volume 3L */
+	{ 0x00000423, 0x0010 }, /* R1059 (0x423) - Noise Gate Select 3L */
+	{ 0x00000424, 0x0080 }, /* R1060 (0x424) - Output Path Config 3R */
+	{ 0x00000425, 0x0180 }, /* R1061 (0x425) - DAC Digital Volume 3R */
+	{ 0x00000427, 0x0020 }, /* R1063 (0x427) - Noise Gate Select 3R */
+	{ 0x00000430, 0x0000 }, /* R1072 (0x430) - Output Path Config 5L */
+	{ 0x00000431, 0x0180 }, /* R1073 (0x431) - DAC Digital Volume 5L */
+	{ 0x00000433, 0x0100 }, /* R1075 (0x433) - Noise Gate Select 5L */
+	{ 0x00000434, 0x0000 }, /* R1076 (0x434) - Output Path Config 5R */
+	{ 0x00000435, 0x0180 }, /* R1077 (0x435) - DAC Digital Volume 5R */
+	{ 0x00000437, 0x0200 }, /* R1079 (0x437) - Noise Gate Select 5R */
+	{ 0x00000440, 0x003f }, /* R1088 (0x440) - DRE Enable */
+	{ 0x00000448, 0x003f }, /* R1096 (0x448) - eDRE Enable */
+	{ 0x00000450, 0x0000 }, /* R1104 (0x450) - DAC AEC Control 1 */
+	{ 0x00000458, 0x0000 }, /* R1112 (0x458) - Noise Gate Control */
+	{ 0x00000490, 0x0069 }, /* R1168 (0x490) - PDM SPK1 CTRL 1 */
+	{ 0x00000491, 0x0000 }, /* R1169 (0x491) - PDM SPK1 CTRL 2 */
+	{ 0x000004a0, 0x3080 }, /* R1184 (0x4a0) - HP1 Short Circuit Ctrl */
+	{ 0x000004a1, 0x3000 }, /* R1185 (0x4a1) - HP2 Short Circuit Ctrl */
+	{ 0x000004a2, 0x3000 }, /* R1186 (0x4a2) - HP3 Short Circuit Ctrl */
+	{ 0x00000500, 0x000c }, /* R1280 (0x500) - AIF1 BCLK Ctrl */
+	{ 0x00000501, 0x0000 }, /* R1281 (0x501) - AIF1 Tx Pin Ctrl */
+	{ 0x00000502, 0x0000 }, /* R1282 (0x502) - AIF1 Rx Pin Ctrl */
+	{ 0x00000503, 0x0000 }, /* R1283 (0x503) - AIF1 Rate Ctrl */
+	{ 0x00000504, 0x0000 }, /* R1284 (0x504) - AIF1 Format */
+	{ 0x00000506, 0x0040 }, /* R1286 (0x506) - AIF1 Rx BCLK Rate */
+	{ 0x00000507, 0x1818 }, /* R1287 (0x507) - AIF1 Frame Ctrl 1 */
+	{ 0x00000508, 0x1818 }, /* R1288 (0x508) - AIF1 Frame Ctrl 2 */
+	{ 0x00000509, 0x0000 }, /* R1289 (0x509) - AIF1 Frame Ctrl 3 */
+	{ 0x0000050a, 0x0001 }, /* R1290 (0x50a) - AIF1 Frame Ctrl 4 */
+	{ 0x0000050b, 0x0002 }, /* R1291 (0x50b) - AIF1 Frame Ctrl 5 */
+	{ 0x0000050c, 0x0003 }, /* R1292 (0x50c) - AIF1 Frame Ctrl 6 */
+	{ 0x0000050d, 0x0004 }, /* R1293 (0x50d) - AIF1 Frame Ctrl 7 */
+	{ 0x0000050e, 0x0005 }, /* R1294 (0x50e) - AIF1 Frame Ctrl 8 */
+	{ 0x0000050f, 0x0006 }, /* R1295 (0x50f) - AIF1 Frame Ctrl 9 */
+	{ 0x00000510, 0x0007 }, /* R1296 (0x510) - AIF1 Frame Ctrl 10 */
+	{ 0x00000511, 0x0000 }, /* R1297 (0x511) - AIF1 Frame Ctrl 11 */
+	{ 0x00000512, 0x0001 }, /* R1298 (0x512) - AIF1 Frame Ctrl 12 */
+	{ 0x00000513, 0x0002 }, /* R1299 (0x513) - AIF1 Frame Ctrl 13 */
+	{ 0x00000514, 0x0003 }, /* R1300 (0x514) - AIF1 Frame Ctrl 14 */
+	{ 0x00000515, 0x0004 }, /* R1301 (0x515) - AIF1 Frame Ctrl 15 */
+	{ 0x00000516, 0x0005 }, /* R1302 (0x516) - AIF1 Frame Ctrl 16 */
+	{ 0x00000517, 0x0006 }, /* R1303 (0x517) - AIF1 Frame Ctrl 17 */
+	{ 0x00000518, 0x0007 }, /* R1304 (0x518) - AIF1 Frame Ctrl 18 */
+	{ 0x00000519, 0x0000 }, /* R1305 (0x519) - AIF1 Tx Enables */
+	{ 0x0000051a, 0x0000 }, /* R1306 (0x51a) - AIF1 Rx Enables */
+	{ 0x00000540, 0x000c }, /* R1344 (0x540) - AIF2 BCLK Ctrl */
+	{ 0x00000541, 0x0000 }, /* R1345 (0x541) - AIF2 Tx Pin Ctrl */
+	{ 0x00000542, 0x0000 }, /* R1346 (0x542) - AIF2 Rx Pin Ctrl */
+	{ 0x00000543, 0x0000 }, /* R1347 (0x543) - AIF2 Rate Ctrl */
+	{ 0x00000544, 0x0000 }, /* R1348 (0x544) - AIF2 Format */
+	{ 0x00000546, 0x0040 }, /* R1350 (0x546) - AIF2 Rx BCLK Rate */
+	{ 0x00000547, 0x1818 }, /* R1351 (0x547) - AIF2 Frame Ctrl 1 */
+	{ 0x00000548, 0x1818 }, /* R1352 (0x548) - AIF2 Frame Ctrl 2 */
+	{ 0x00000549, 0x0000 }, /* R1353 (0x549) - AIF2 Frame Ctrl 3 */
+	{ 0x0000054a, 0x0001 }, /* R1354 (0x54a) - AIF2 Frame Ctrl 4 */
+	{ 0x0000054b, 0x0002 }, /* R1355 (0x54b) - AIF2 Frame Ctrl 5 */
+	{ 0x0000054c, 0x0003 }, /* R1356 (0x54c) - AIF2 Frame Ctrl 6 */
+	{ 0x0000054d, 0x0004 }, /* R1357 (0x54d) - AIF2 Frame Ctrl 7 */
+	{ 0x0000054e, 0x0005 }, /* R1358 (0x54e) - AIF2 Frame Ctrl 8 */
+	{ 0x0000054f, 0x0006 }, /* R1359 (0x54f) - AIF2 Frame Ctrl 9 */
+	{ 0x00000550, 0x0007 }, /* R1360 (0x550) - AIF2 Frame Ctrl 10 */
+	{ 0x00000551, 0x0000 }, /* R1361 (0x551) - AIF2 Frame Ctrl 11 */
+	{ 0x00000552, 0x0001 }, /* R1362 (0x552) - AIF2 Frame Ctrl 12 */
+	{ 0x00000553, 0x0002 }, /* R1363 (0x553) - AIF2 Frame Ctrl 13 */
+	{ 0x00000554, 0x0003 }, /* R1364 (0x554) - AIF2 Frame Ctrl 14 */
+	{ 0x00000555, 0x0004 }, /* R1365 (0x555) - AIF2 Frame Ctrl 15 */
+	{ 0x00000556, 0x0005 }, /* R1366 (0x556) - AIF2 Frame Ctrl 16 */
+	{ 0x00000557, 0x0006 }, /* R1367 (0x557) - AIF2 Frame Ctrl 17 */
+	{ 0x00000558, 0x0007 }, /* R1368 (0x558) - AIF2 Frame Ctrl 18 */
+	{ 0x00000559, 0x0000 }, /* R1369 (0x559) - AIF2 Tx Enables */
+	{ 0x0000055a, 0x0000 }, /* R1370 (0x55a) - AIF2 Rx Enables */
+	{ 0x00000580, 0x000c }, /* R1408 (0x580) - AIF3 BCLK Ctrl */
+	{ 0x00000581, 0x0000 }, /* R1409 (0x581) - AIF3 Tx Pin Ctrl */
+	{ 0x00000582, 0x0000 }, /* R1410 (0x582) - AIF3 Rx Pin Ctrl */
+	{ 0x00000583, 0x0000 }, /* R1411 (0x583) - AIF3 Rate Ctrl */
+	{ 0x00000584, 0x0000 }, /* R1412 (0x584) - AIF3 Format */
+	{ 0x00000586, 0x0040 }, /* R1414 (0x586) - AIF3 Rx BCLK Rate */
+	{ 0x00000587, 0x1818 }, /* R1415 (0x587) - AIF3 Frame Ctrl 1 */
+	{ 0x00000588, 0x1818 }, /* R1416 (0x588) - AIF3 Frame Ctrl 2 */
+	{ 0x00000589, 0x0000 }, /* R1417 (0x589) - AIF3 Frame Ctrl 3 */
+	{ 0x0000058a, 0x0001 }, /* R1418 (0x58a) - AIF3 Frame Ctrl 4 */
+	{ 0x00000591, 0x0000 }, /* R1425 (0x591) - AIF3 Frame Ctrl 11 */
+	{ 0x00000592, 0x0001 }, /* R1426 (0x592) - AIF3 Frame Ctrl 12 */
+	{ 0x00000599, 0x0000 }, /* R1433 (0x599) - AIF3 Tx Enables */
+	{ 0x0000059a, 0x0000 }, /* R1434 (0x59a) - AIF3 Rx Enables */
+	{ 0x000005a0, 0x000c }, /* R1440 (0x5a0) - AIF4 BCLK Ctrl */
+	{ 0x000005a1, 0x0000 }, /* R1441 (0x5a1) - AIF4 Tx Pin Ctrl */
+	{ 0x000005a2, 0x0000 }, /* R1442 (0x5a2) - AIF4 Rx Pin Ctrl */
+	{ 0x000005a3, 0x0000 }, /* R1443 (0x5a3) - AIF4 Rate Ctrl */
+	{ 0x000005a4, 0x0000 }, /* R1444 (0x5a4) - AIF4 Format */
+	{ 0x000005a6, 0x0040 }, /* R1446 (0x5a6) - AIF4 Rx BCLK Rate */
+	{ 0x000005a7, 0x1818 }, /* R1447 (0x5a7) - AIF4 Frame Ctrl 1 */
+	{ 0x000005a8, 0x1818 }, /* R1448 (0x5a8) - AIF4 Frame Ctrl 2 */
+	{ 0x000005a9, 0x0000 }, /* R1449 (0x5a9) - AIF4 Frame Ctrl 3 */
+	{ 0x000005aa, 0x0001 }, /* R1450 (0x5aa) - AIF4 Frame Ctrl 4 */
+	{ 0x000005b1, 0x0000 }, /* R1457 (0x5b1) - AIF4 Frame Ctrl 11 */
+	{ 0x000005b2, 0x0001 }, /* R1458 (0x5b2) - AIF4 Frame Ctrl 12 */
+	{ 0x000005b9, 0x0000 }, /* R1465 (0x5b9) - AIF4 Tx Enables */
+	{ 0x000005ba, 0x0000 }, /* R1466 (0x5ba) - AIF4 Rx Enables */
+	{ 0x000005c2, 0x0000 }, /* R1474 (0x5c2) - SPD1 TX Control */
+	{ 0x000005e3, 0x0000 }, /* R1507 (0x5e3) - SLIMbus Framer Ref Gear */
+	{ 0x000005e5, 0x0000 }, /* R1509 (0x5e5) - SLIMbus Rates 1 */
+	{ 0x000005e6, 0x0000 }, /* R1510 (0x5e6) - SLIMbus Rates 2 */
+	{ 0x000005e7, 0x0000 }, /* R1511 (0x5e7) - SLIMbus Rates 3 */
+	{ 0x000005e8, 0x0000 }, /* R1512 (0x5e8) - SLIMbus Rates 4 */
+	{ 0x000005e9, 0x0000 }, /* R1513 (0x5e9) - SLIMbus Rates 5 */
+	{ 0x000005ea, 0x0000 }, /* R1514 (0x5ea) - SLIMbus Rates 6 */
+	{ 0x000005eb, 0x0000 }, /* R1515 (0x5eb) - SLIMbus Rates 7 */
+	{ 0x000005ec, 0x0000 }, /* R1516 (0x5ec) - SLIMbus Rates 8 */
+	{ 0x000005f5, 0x0000 }, /* R1525 (0x5f5) - SLIMbus RX Channel Enable */
+	{ 0x000005f6, 0x0000 }, /* R1526 (0x5F6) - SLIMbus TX Channel Enable */
+	{ 0x00000640, 0x0000 }, /* R1600 (0x640) - PWM1MIX Input 1 Source */
+	{ 0x00000641, 0x0080 }, /* R1601 (0x641) - PWM1MIX Input 1 Volume */
+	{ 0x00000642, 0x0000 }, /* R1602 (0x642) - PWM1MIX Input 2 Source */
+	{ 0x00000643, 0x0080 }, /* R1603 (0x643) - PWM1MIX Input 2 Volume */
+	{ 0x00000644, 0x0000 }, /* R1604 (0x644) - PWM1MIX Input 3 Source */
+	{ 0x00000645, 0x0080 }, /* R1605 (0x645) - PWM1MIX Input 3 Volume */
+	{ 0x00000646, 0x0000 }, /* R1606 (0x646) - PWM1MIX Input 4 Source */
+	{ 0x00000647, 0x0080 }, /* R1607 (0x647) - PWM1MIX Input 4 Volume */
+	{ 0x00000648, 0x0000 }, /* R1608 (0x648) - PWM2MIX Input 1 Source */
+	{ 0x00000649, 0x0080 }, /* R1609 (0x649) - PWM2MIX Input 1 Volume */
+	{ 0x0000064a, 0x0000 }, /* R1610 (0x64a) - PWM2MIX Input 2 Source */
+	{ 0x0000064b, 0x0080 }, /* R1611 (0x64b) - PWM2MIX Input 2 Volume */
+	{ 0x0000064c, 0x0000 }, /* R1612 (0x64c) - PWM2MIX Input 3 Source */
+	{ 0x0000064d, 0x0080 }, /* R1613 (0x64d) - PWM2MIX Input 3 Volume */
+	{ 0x0000064e, 0x0000 }, /* R1614 (0x64e) - PWM2MIX Input 4 Source */
+	{ 0x0000064f, 0x0080 }, /* R1615 (0x64f) - PWM2MIX Input 4 Volume */
+	{ 0x00000680, 0x0000 }, /* R1664 (0x680) - OUT1LMIX Input 1 Source */
+	{ 0x00000681, 0x0080 }, /* R1665 (0x681) - OUT1LMIX Input 1 Volume */
+	{ 0x00000682, 0x0000 }, /* R1666 (0x682) - OUT1LMIX Input 2 Source */
+	{ 0x00000683, 0x0080 }, /* R1667 (0x683) - OUT1LMIX Input 2 Volume */
+	{ 0x00000684, 0x0000 }, /* R1668 (0x684) - OUT1LMIX Input 3 Source */
+	{ 0x00000685, 0x0080 }, /* R1669 (0x685) - OUT1LMIX Input 3 Volume */
+	{ 0x00000686, 0x0000 }, /* R1670 (0x686) - OUT1LMIX Input 4 Source */
+	{ 0x00000687, 0x0080 }, /* R1671 (0x687) - OUT1LMIX Input 4 Volume */
+	{ 0x00000688, 0x0000 }, /* R1672 (0x688) - OUT1RMIX Input 1 Source */
+	{ 0x00000689, 0x0080 }, /* R1673 (0x689) - OUT1RMIX Input 1 Volume */
+	{ 0x0000068a, 0x0000 }, /* R1674 (0x68a) - OUT1RMIX Input 2 Source */
+	{ 0x0000068b, 0x0080 }, /* R1675 (0x68b) - OUT1RMIX Input 2 Volume */
+	{ 0x0000068c, 0x0000 }, /* R1672 (0x68c) - OUT1RMIX Input 3 Source */
+	{ 0x0000068d, 0x0080 }, /* R1673 (0x68d) - OUT1RMIX Input 3 Volume */
+	{ 0x0000068e, 0x0000 }, /* R1674 (0x68e) - OUT1RMIX Input 4 Source */
+	{ 0x0000068f, 0x0080 }, /* R1675 (0x68f) - OUT1RMIX Input 4 Volume */
+	{ 0x00000690, 0x0000 }, /* R1680 (0x690) - OUT2LMIX Input 1 Source */
+	{ 0x00000691, 0x0080 }, /* R1681 (0x691) - OUT2LMIX Input 1 Volume */
+	{ 0x00000692, 0x0000 }, /* R1682 (0x692) - OUT2LMIX Input 2 Source */
+	{ 0x00000693, 0x0080 }, /* R1683 (0x693) - OUT2LMIX Input 2 Volume */
+	{ 0x00000694, 0x0000 }, /* R1684 (0x694) - OUT2LMIX Input 3 Source */
+	{ 0x00000695, 0x0080 }, /* R1685 (0x695) - OUT2LMIX Input 3 Volume */
+	{ 0x00000696, 0x0000 }, /* R1686 (0x696) - OUT2LMIX Input 4 Source */
+	{ 0x00000697, 0x0080 }, /* R1687 (0x697) - OUT2LMIX Input 4 Volume */
+	{ 0x00000698, 0x0000 }, /* R1688 (0x698) - OUT2RMIX Input 1 Source */
+	{ 0x00000699, 0x0080 }, /* R1689 (0x699) - OUT2RMIX Input 1 Volume */
+	{ 0x0000069a, 0x0000 }, /* R1690 (0x69a) - OUT2RMIX Input 2 Source */
+	{ 0x0000069b, 0x0080 }, /* R1691 (0x69b) - OUT2RMIX Input 2 Volume */
+	{ 0x0000069c, 0x0000 }, /* R1692 (0x69c) - OUT2RMIX Input 3 Source */
+	{ 0x0000069d, 0x0080 }, /* R1693 (0x69d) - OUT2RMIX Input 3 Volume */
+	{ 0x0000069e, 0x0000 }, /* R1694 (0x69e) - OUT2RMIX Input 4 Source */
+	{ 0x0000069f, 0x0080 }, /* R1695 (0x69f) - OUT2RMIX Input 4 Volume */
+	{ 0x000006a0, 0x0000 }, /* R1696 (0x6a0) - OUT3LMIX Input 1 Source */
+	{ 0x000006a1, 0x0080 }, /* R1697 (0x6a1) - OUT3LMIX Input 1 Volume */
+	{ 0x000006a2, 0x0000 }, /* R1698 (0x6a2) - OUT3LMIX Input 2 Source */
+	{ 0x000006a3, 0x0080 }, /* R1699 (0x6a3) - OUT3LMIX Input 2 Volume */
+	{ 0x000006a4, 0x0000 }, /* R1700 (0x6a4) - OUT3LMIX Input 3 Source */
+	{ 0x000006a5, 0x0080 }, /* R1701 (0x6a5) - OUT3LMIX Input 3 Volume */
+	{ 0x000006a6, 0x0000 }, /* R1702 (0x6a6) - OUT3LMIX Input 4 Source */
+	{ 0x000006a7, 0x0080 }, /* R1703 (0x6a7) - OUT3LMIX Input 4 Volume */
+	{ 0x000006a8, 0x0000 }, /* R1704 (0x6a8) - OUT3RMIX Input 1 Source */
+	{ 0x000006a9, 0x0080 }, /* R1705 (0x6a9) - OUT3RMIX Input 1 Volume */
+	{ 0x000006aa, 0x0000 }, /* R1706 (0x6aa) - OUT3RMIX Input 2 Source */
+	{ 0x000006ab, 0x0080 }, /* R1707 (0x6ab) - OUT3RMIX Input 2 Volume */
+	{ 0x000006ac, 0x0000 }, /* R1708 (0x6ac) - OUT3RMIX Input 3 Source */
+	{ 0x000006ad, 0x0080 }, /* R1709 (0x6ad) - OUT3RMIX Input 3 Volume */
+	{ 0x000006ae, 0x0000 }, /* R1710 (0x6ae) - OUT3RMIX Input 4 Source */
+	{ 0x000006af, 0x0080 }, /* R1711 (0x6af) - OUT3RMIX Input 4 Volume */
+	{ 0x000006c0, 0x0000 }, /* R1728 (0x6c0) - OUT5LMIX Input 1 Source */
+	{ 0x000006c1, 0x0080 }, /* R1729 (0x6c1) - OUT5LMIX Input 1 Volume */
+	{ 0x000006c2, 0x0000 }, /* R1730 (0x6c2) - OUT5LMIX Input 2 Source */
+	{ 0x000006c3, 0x0080 }, /* R1731 (0x6c3) - OUT5LMIX Input 2 Volume */
+	{ 0x000006c4, 0x0000 }, /* R1732 (0x6c4) - OUT5LMIX Input 3 Source */
+	{ 0x000006c5, 0x0080 }, /* R1733 (0x6c5) - OUT5LMIX Input 3 Volume */
+	{ 0x000006c6, 0x0000 }, /* R1734 (0x6c6) - OUT5LMIX Input 4 Source */
+	{ 0x000006c7, 0x0080 }, /* R1735 (0x6c7) - OUT5LMIX Input 4 Volume */
+	{ 0x000006c8, 0x0000 }, /* R1736 (0x6c8) - OUT5RMIX Input 1 Source */
+	{ 0x000006c9, 0x0080 }, /* R1737 (0x6c9) - OUT5RMIX Input 1 Volume */
+	{ 0x000006ca, 0x0000 }, /* R1738 (0x6ca) - OUT5RMIX Input 2 Source */
+	{ 0x000006cb, 0x0080 }, /* R1739 (0x6cb) - OUT5RMIX Input 2 Volume */
+	{ 0x000006cc, 0x0000 }, /* R1740 (0x6cc) - OUT5RMIX Input 3 Source */
+	{ 0x000006cd, 0x0080 }, /* R1741 (0x6cd) - OUT5RMIX Input 3 Volume */
+	{ 0x000006ce, 0x0000 }, /* R1742 (0x6ce) - OUT5RMIX Input 4 Source */
+	{ 0x000006cf, 0x0080 }, /* R1743 (0x6cf) - OUT5RMIX Input 4 Volume */
+	{ 0x00000700, 0x0000 }, /* R1792 (0x700) - AIF1TX1MIX Input 1 Source */
+	{ 0x00000701, 0x0080 }, /* R1793 (0x701) - AIF1TX1MIX Input 1 Volume */
+	{ 0x00000702, 0x0000 }, /* R1794 (0x702) - AIF1TX1MIX Input 2 Source */
+	{ 0x00000703, 0x0080 }, /* R1795 (0x703) - AIF1TX1MIX Input 2 Volume */
+	{ 0x00000704, 0x0000 }, /* R1796 (0x704) - AIF1TX1MIX Input 3 Source */
+	{ 0x00000705, 0x0080 }, /* R1797 (0x705) - AIF1TX1MIX Input 3 Volume */
+	{ 0x00000706, 0x0000 }, /* R1798 (0x706) - AIF1TX1MIX Input 4 Source */
+	{ 0x00000707, 0x0080 }, /* R1799 (0x707) - AIF1TX1MIX Input 4 Volume */
+	{ 0x00000708, 0x0000 }, /* R1800 (0x708) - AIF1TX2MIX Input 1 Source */
+	{ 0x00000709, 0x0080 }, /* R1801 (0x709) - AIF1TX2MIX Input 1 Volume */
+	{ 0x0000070a, 0x0000 }, /* R1802 (0x70a) - AIF1TX2MIX Input 2 Source */
+	{ 0x0000070b, 0x0080 }, /* R1803 (0x70b) - AIF1TX2MIX Input 2 Volume */
+	{ 0x0000070c, 0x0000 }, /* R1804 (0x70c) - AIF1TX2MIX Input 3 Source */
+	{ 0x0000070d, 0x0080 }, /* R1805 (0x70d) - AIF1TX2MIX Input 3 Volume */
+	{ 0x0000070e, 0x0000 }, /* R1806 (0x70e) - AIF1TX2MIX Input 4 Source */
+	{ 0x0000070f, 0x0080 }, /* R1807 (0x70f) - AIF1TX2MIX Input 4 Volume */
+	{ 0x00000710, 0x0000 }, /* R1808 (0x710) - AIF1TX3MIX Input 1 Source */
+	{ 0x00000711, 0x0080 }, /* R1809 (0x711) - AIF1TX3MIX Input 1 Volume */
+	{ 0x00000712, 0x0000 }, /* R1810 (0x712) - AIF1TX3MIX Input 2 Source */
+	{ 0x00000713, 0x0080 }, /* R1811 (0x713) - AIF1TX3MIX Input 2 Volume */
+	{ 0x00000714, 0x0000 }, /* R1812 (0x714) - AIF1TX3MIX Input 3 Source */
+	{ 0x00000715, 0x0080 }, /* R1813 (0x715) - AIF1TX3MIX Input 3 Volume */
+	{ 0x00000716, 0x0000 }, /* R1814 (0x716) - AIF1TX3MIX Input 4 Source */
+	{ 0x00000717, 0x0080 }, /* R1815 (0x717) - AIF1TX3MIX Input 4 Volume */
+	{ 0x00000718, 0x0000 }, /* R1816 (0x718) - AIF1TX4MIX Input 1 Source */
+	{ 0x00000719, 0x0080 }, /* R1817 (0x719) - AIF1TX4MIX Input 1 Volume */
+	{ 0x0000071a, 0x0000 }, /* R1818 (0x71a) - AIF1TX4MIX Input 2 Source */
+	{ 0x0000071b, 0x0080 }, /* R1819 (0x71b) - AIF1TX4MIX Input 2 Volume */
+	{ 0x0000071c, 0x0000 }, /* R1820 (0x71c) - AIF1TX4MIX Input 3 Source */
+	{ 0x0000071d, 0x0080 }, /* R1821 (0x71d) - AIF1TX4MIX Input 3 Volume */
+	{ 0x0000071e, 0x0000 }, /* R1822 (0x71e) - AIF1TX4MIX Input 4 Source */
+	{ 0x0000071f, 0x0080 }, /* R1823 (0x71f) - AIF1TX4MIX Input 4 Volume */
+	{ 0x00000720, 0x0000 }, /* R1824 (0x720) - AIF1TX5MIX Input 1 Source */
+	{ 0x00000721, 0x0080 }, /* R1825 (0x721) - AIF1TX5MIX Input 1 Volume */
+	{ 0x00000722, 0x0000 }, /* R1826 (0x722) - AIF1TX5MIX Input 2 Source */
+	{ 0x00000723, 0x0080 }, /* R1827 (0x723) - AIF1TX5MIX Input 2 Volume */
+	{ 0x00000724, 0x0000 }, /* R1828 (0x724) - AIF1TX5MIX Input 3 Source */
+	{ 0x00000725, 0x0080 }, /* R1829 (0x725) - AIF1TX5MIX Input 3 Volume */
+	{ 0x00000726, 0x0000 }, /* R1830 (0x726) - AIF1TX5MIX Input 4 Source */
+	{ 0x00000727, 0x0080 }, /* R1831 (0x727) - AIF1TX5MIX Input 4 Volume */
+	{ 0x00000728, 0x0000 }, /* R1832 (0x728) - AIF1TX6MIX Input 1 Source */
+	{ 0x00000729, 0x0080 }, /* R1833 (0x729) - AIF1TX6MIX Input 1 Volume */
+	{ 0x0000072a, 0x0000 }, /* R1834 (0x72a) - AIF1TX6MIX Input 2 Source */
+	{ 0x0000072b, 0x0080 }, /* R1835 (0x72b) - AIF1TX6MIX Input 2 Volume */
+	{ 0x0000072c, 0x0000 }, /* R1836 (0x72c) - AIF1TX6MIX Input 3 Source */
+	{ 0x0000072d, 0x0080 }, /* R1837 (0x72d) - AIF1TX6MIX Input 3 Volume */
+	{ 0x0000072e, 0x0000 }, /* R1838 (0x72e) - AIF1TX6MIX Input 4 Source */
+	{ 0x0000072f, 0x0080 }, /* R1839 (0x72f) - AIF1TX6MIX Input 4 Volume */
+	{ 0x00000730, 0x0000 }, /* R1840 (0x730) - AIF1TX7MIX Input 1 Source */
+	{ 0x00000731, 0x0080 }, /* R1841 (0x731) - AIF1TX7MIX Input 1 Volume */
+	{ 0x00000732, 0x0000 }, /* R1842 (0x732) - AIF1TX7MIX Input 2 Source */
+	{ 0x00000733, 0x0080 }, /* R1843 (0x733) - AIF1TX7MIX Input 2 Volume */
+	{ 0x00000734, 0x0000 }, /* R1844 (0x734) - AIF1TX7MIX Input 3 Source */
+	{ 0x00000735, 0x0080 }, /* R1845 (0x735) - AIF1TX7MIX Input 3 Volume */
+	{ 0x00000736, 0x0000 }, /* R1846 (0x736) - AIF1TX7MIX Input 4 Source */
+	{ 0x00000737, 0x0080 }, /* R1847 (0x737) - AIF1TX7MIX Input 4 Volume */
+	{ 0x00000738, 0x0000 }, /* R1848 (0x738) - AIF1TX8MIX Input 1 Source */
+	{ 0x00000739, 0x0080 }, /* R1849 (0x739) - AIF1TX8MIX Input 1 Volume */
+	{ 0x0000073a, 0x0000 }, /* R1850 (0x73a) - AIF1TX8MIX Input 2 Source */
+	{ 0x0000073b, 0x0080 }, /* R1851 (0x73b) - AIF1TX8MIX Input 2 Volume */
+	{ 0x0000073c, 0x0000 }, /* R1852 (0x73c) - AIF1TX8MIX Input 3 Source */
+	{ 0x0000073d, 0x0080 }, /* R1853 (0x73d) - AIF1TX8MIX Input 3 Volume */
+	{ 0x0000073e, 0x0000 }, /* R1854 (0x73e) - AIF1TX8MIX Input 4 Source */
+	{ 0x0000073f, 0x0080 }, /* R1855 (0x73f) - AIF1TX8MIX Input 4 Volume */
+	{ 0x00000740, 0x0000 }, /* R1856 (0x740) - AIF2TX1MIX Input 1 Source */
+	{ 0x00000741, 0x0080 }, /* R1857 (0x741) - AIF2TX1MIX Input 1 Volume */
+	{ 0x00000742, 0x0000 }, /* R1858 (0x742) - AIF2TX1MIX Input 2 Source */
+	{ 0x00000743, 0x0080 }, /* R1859 (0x743) - AIF2TX1MIX Input 2 Volume */
+	{ 0x00000744, 0x0000 }, /* R1860 (0x744) - AIF2TX1MIX Input 3 Source */
+	{ 0x00000745, 0x0080 }, /* R1861 (0x745) - AIF2TX1MIX Input 3 Volume */
+	{ 0x00000746, 0x0000 }, /* R1862 (0x746) - AIF2TX1MIX Input 4 Source */
+	{ 0x00000747, 0x0080 }, /* R1863 (0x747) - AIF2TX1MIX Input 4 Volume */
+	{ 0x00000748, 0x0000 }, /* R1864 (0x748) - AIF2TX2MIX Input 1 Source */
+	{ 0x00000749, 0x0080 }, /* R1865 (0x749) - AIF2TX2MIX Input 1 Volume */
+	{ 0x0000074a, 0x0000 }, /* R1866 (0x74a) - AIF2TX2MIX Input 2 Source */
+	{ 0x0000074b, 0x0080 }, /* R1867 (0x74b) - AIF2TX2MIX Input 2 Volume */
+	{ 0x0000074c, 0x0000 }, /* R1868 (0x74c) - AIF2TX2MIX Input 3 Source */
+	{ 0x0000074d, 0x0080 }, /* R1869 (0x74d) - AIF2TX2MIX Input 3 Volume */
+	{ 0x0000074e, 0x0000 }, /* R1870 (0x74e) - AIF2TX2MIX Input 4 Source */
+	{ 0x0000074f, 0x0080 }, /* R1871 (0x74f) - AIF2TX2MIX Input 4 Volume */
+	{ 0x00000750, 0x0000 }, /* R1872 (0x750) - AIF2TX3MIX Input 1 Source */
+	{ 0x00000751, 0x0080 }, /* R1873 (0x751) - AIF2TX3MIX Input 1 Volume */
+	{ 0x00000752, 0x0000 }, /* R1874 (0x752) - AIF2TX3MIX Input 2 Source */
+	{ 0x00000753, 0x0080 }, /* R1875 (0x753) - AIF2TX3MIX Input 2 Volume */
+	{ 0x00000754, 0x0000 }, /* R1876 (0x754) - AIF2TX3MIX Input 3 Source */
+	{ 0x00000755, 0x0080 }, /* R1877 (0x755) - AIF2TX3MIX Input 3 Volume */
+	{ 0x00000756, 0x0000 }, /* R1878 (0x756) - AIF2TX3MIX Input 4 Source */
+	{ 0x00000757, 0x0080 }, /* R1879 (0x757) - AIF2TX3MIX Input 4 Volume */
+	{ 0x00000758, 0x0000 }, /* R1880 (0x758) - AIF2TX4MIX Input 1 Source */
+	{ 0x00000759, 0x0080 }, /* R1881 (0x759) - AIF2TX4MIX Input 1 Volume */
+	{ 0x0000075a, 0x0000 }, /* R1882 (0x75a) - AIF2TX4MIX Input 2 Source */
+	{ 0x0000075b, 0x0080 }, /* R1883 (0x75b) - AIF2TX4MIX Input 2 Volume */
+	{ 0x0000075c, 0x0000 }, /* R1884 (0x75c) - AIF2TX4MIX Input 3 Source */
+	{ 0x0000075d, 0x0080 }, /* R1885 (0x75d) - AIF2TX4MIX Input 3 Volume */
+	{ 0x0000075e, 0x0000 }, /* R1886 (0x75e) - AIF2TX4MIX Input 4 Source */
+	{ 0x0000075f, 0x0080 }, /* R1887 (0x75f) - AIF2TX4MIX Input 4 Volume */
+	{ 0x00000760, 0x0000 }, /* R1888 (0x760) - AIF2TX5MIX Input 1 Source */
+	{ 0x00000761, 0x0080 }, /* R1889 (0x761) - AIF2TX5MIX Input 1 Volume */
+	{ 0x00000762, 0x0000 }, /* R1890 (0x762) - AIF2TX5MIX Input 2 Source */
+	{ 0x00000763, 0x0080 }, /* R1891 (0x763) - AIF2TX5MIX Input 2 Volume */
+	{ 0x00000764, 0x0000 }, /* R1892 (0x764) - AIF2TX5MIX Input 3 Source */
+	{ 0x00000765, 0x0080 }, /* R1893 (0x765) - AIF2TX5MIX Input 3 Volume */
+	{ 0x00000766, 0x0000 }, /* R1894 (0x766) - AIF2TX5MIX Input 4 Source */
+	{ 0x00000767, 0x0080 }, /* R1895 (0x767) - AIF2TX5MIX Input 4 Volume */
+	{ 0x00000768, 0x0000 }, /* R1896 (0x768) - AIF2TX6MIX Input 1 Source */
+	{ 0x00000769, 0x0080 }, /* R1897 (0x769) - AIF2TX6MIX Input 1 Volume */
+	{ 0x0000076a, 0x0000 }, /* R1898 (0x76a) - AIF2TX6MIX Input 2 Source */
+	{ 0x0000076b, 0x0080 }, /* R1899 (0x76b) - AIF2TX6MIX Input 2 Volume */
+	{ 0x0000076c, 0x0000 }, /* R1900 (0x76c) - AIF2TX6MIX Input 3 Source */
+	{ 0x0000076d, 0x0080 }, /* R1901 (0x76d) - AIF2TX6MIX Input 3 Volume */
+	{ 0x0000076e, 0x0000 }, /* R1902 (0x76e) - AIF2TX6MIX Input 4 Source */
+	{ 0x0000076f, 0x0080 }, /* R1903 (0x76f) - AIF2TX6MIX Input 4 Volume */
+	{ 0x00000770, 0x0000 }, /* R1904 (0x770) - AIF2TX7MIX Input 1 Source */
+	{ 0x00000771, 0x0080 }, /* R1905 (0x771) - AIF2TX7MIX Input 1 Volume */
+	{ 0x00000772, 0x0000 }, /* R1906 (0x772) - AIF2TX7MIX Input 2 Source */
+	{ 0x00000773, 0x0080 }, /* R1907 (0x773) - AIF2TX7MIX Input 2 Volume */
+	{ 0x00000774, 0x0000 }, /* R1908 (0x774) - AIF2TX7MIX Input 3 Source */
+	{ 0x00000775, 0x0080 }, /* R1909 (0x775) - AIF2TX7MIX Input 3 Volume */
+	{ 0x00000776, 0x0000 }, /* R1910 (0x776) - AIF2TX7MIX Input 4 Source */
+	{ 0x00000777, 0x0080 }, /* R1911 (0x777) - AIF2TX7MIX Input 4 Volume */
+	{ 0x00000778, 0x0000 }, /* R1912 (0x778) - AIF2TX8MIX Input 1 Source */
+	{ 0x00000779, 0x0080 }, /* R1913 (0x779) - AIF2TX8MIX Input 1 Volume */
+	{ 0x0000077a, 0x0000 }, /* R1914 (0x77a) - AIF2TX8MIX Input 2 Source */
+	{ 0x0000077b, 0x0080 }, /* R1915 (0x77b) - AIF2TX8MIX Input 2 Volume */
+	{ 0x0000077c, 0x0000 }, /* R1916 (0x77c) - AIF2TX8MIX Input 3 Source */
+	{ 0x0000077d, 0x0080 }, /* R1917 (0x77d) - AIF2TX8MIX Input 3 Volume */
+	{ 0x0000077e, 0x0000 }, /* R1918 (0x77e) - AIF2TX8MIX Input 4 Source */
+	{ 0x0000077f, 0x0080 }, /* R1919 (0x77f) - AIF2TX8MIX Input 4 Volume */
+	{ 0x00000780, 0x0000 }, /* R1920 (0x780) - AIF3TX1MIX Input 1 Source */
+	{ 0x00000781, 0x0080 }, /* R1921 (0x781) - AIF3TX1MIX Input 1 Volume */
+	{ 0x00000782, 0x0000 }, /* R1922 (0x782) - AIF3TX1MIX Input 2 Source */
+	{ 0x00000783, 0x0080 }, /* R1923 (0x783) - AIF3TX1MIX Input 2 Volume */
+	{ 0x00000784, 0x0000 }, /* R1924 (0x784) - AIF3TX1MIX Input 3 Source */
+	{ 0x00000785, 0x0080 }, /* R1925 (0x785) - AIF3TX1MIX Input 3 Volume */
+	{ 0x00000786, 0x0000 }, /* R1926 (0x786) - AIF3TX1MIX Input 4 Source */
+	{ 0x00000787, 0x0080 }, /* R1927 (0x787) - AIF3TX1MIX Input 4 Volume */
+	{ 0x00000788, 0x0000 }, /* R1928 (0x788) - AIF3TX2MIX Input 1 Source */
+	{ 0x00000789, 0x0080 }, /* R1929 (0x789) - AIF3TX2MIX Input 1 Volume */
+	{ 0x0000078a, 0x0000 }, /* R1930 (0x78a) - AIF3TX2MIX Input 2 Source */
+	{ 0x0000078b, 0x0080 }, /* R1931 (0x78b) - AIF3TX2MIX Input 2 Volume */
+	{ 0x0000078c, 0x0000 }, /* R1932 (0x78c) - AIF3TX2MIX Input 3 Source */
+	{ 0x0000078d, 0x0080 }, /* R1933 (0x78d) - AIF3TX2MIX Input 3 Volume */
+	{ 0x0000078e, 0x0000 }, /* R1934 (0x78e) - AIF3TX2MIX Input 4 Source */
+	{ 0x0000078f, 0x0080 }, /* R1935 (0x78f) - AIF3TX2MIX Input 4 Volume */
+	{ 0x000007a0, 0x0000 }, /* R1952 (0x7a0) - AIF4TX1MIX Input 1 Source */
+	{ 0x000007a1, 0x0080 }, /* R1953 (0x7a1) - AIF4TX1MIX Input 1 Volume */
+	{ 0x000007a2, 0x0000 }, /* R1954 (0x7a2) - AIF4TX1MIX Input 2 Source */
+	{ 0x000007a3, 0x0080 }, /* R1955 (0x7a3) - AIF4TX1MIX Input 2 Volume */
+	{ 0x000007a4, 0x0000 }, /* R1956 (0x7a4) - AIF4TX1MIX Input 3 Source */
+	{ 0x000007a5, 0x0080 }, /* R1957 (0x7a5) - AIF4TX1MIX Input 3 Volume */
+	{ 0x000007a6, 0x0000 }, /* R1958 (0x7a6) - AIF4TX1MIX Input 4 Source */
+	{ 0x000007a7, 0x0080 }, /* R1959 (0x7a7) - AIF4TX1MIX Input 4 Volume */
+	{ 0x000007a8, 0x0000 }, /* R1960 (0x7a8) - AIF4TX2MIX Input 1 Source */
+	{ 0x000007a9, 0x0080 }, /* R1961 (0x7a9) - AIF4TX2MIX Input 1 Volume */
+	{ 0x000007aa, 0x0000 }, /* R1962 (0x7aa) - AIF4TX2MIX Input 2 Source */
+	{ 0x000007ab, 0x0080 }, /* R1963 (0x7ab) - AIF4TX2MIX Input 2 Volume */
+	{ 0x000007ac, 0x0000 }, /* R1964 (0x7ac) - AIF4TX2MIX Input 3 Source */
+	{ 0x000007ad, 0x0080 }, /* R1965 (0x7ad) - AIF4TX2MIX Input 3 Volume */
+	{ 0x000007ae, 0x0000 }, /* R1966 (0x7ae) - AIF4TX2MIX Input 4 Source */
+	{ 0x000007af, 0x0080 }, /* R1967 (0x7af) - AIF4TX2MIX Input 4 Volume */
+	{ 0x000007c0, 0x0000 }, /* R1984 (0x7c0) - SLIMTX1MIX Input 1 Source */
+	{ 0x000007c1, 0x0080 }, /* R1985 (0x7c1) - SLIMTX1MIX Input 1 Volume */
+	{ 0x000007c2, 0x0000 }, /* R1986 (0x7c2) - SLIMTX1MIX Input 2 Source */
+	{ 0x000007c3, 0x0080 }, /* R1987 (0x7c3) - SLIMTX1MIX Input 2 Volume */
+	{ 0x000007c4, 0x0000 }, /* R1988 (0x7c4) - SLIMTX1MIX Input 3 Source */
+	{ 0x000007c5, 0x0080 }, /* R1989 (0x7c5) - SLIMTX1MIX Input 3 Volume */
+	{ 0x000007c6, 0x0000 }, /* R1990 (0x7c6) - SLIMTX1MIX Input 4 Source */
+	{ 0x000007c7, 0x0080 }, /* R1991 (0x7c7) - SLIMTX1MIX Input 4 Volume */
+	{ 0x000007c8, 0x0000 }, /* R1992 (0x7c8) - SLIMTX2MIX Input 1 Source */
+	{ 0x000007c9, 0x0080 }, /* R1993 (0x7c9) - SLIMTX2MIX Input 1 Volume */
+	{ 0x000007ca, 0x0000 }, /* R1994 (0x7ca) - SLIMTX2MIX Input 2 Source */
+	{ 0x000007cb, 0x0080 }, /* R1995 (0x7cb) - SLIMTX2MIX Input 2 Volume */
+	{ 0x000007cc, 0x0000 }, /* R1996 (0x7cc) - SLIMTX2MIX Input 3 Source */
+	{ 0x000007cd, 0x0080 }, /* R1997 (0x7cd) - SLIMTX2MIX Input 3 Volume */
+	{ 0x000007ce, 0x0000 }, /* R1998 (0x7ce) - SLIMTX2MIX Input 4 Source */
+	{ 0x000007cf, 0x0080 }, /* R1999 (0x7cf) - SLIMTX2MIX Input 4 Volume */
+	{ 0x000007d0, 0x0000 }, /* R2000 (0x7d0) - SLIMTX3MIX Input 1 Source */
+	{ 0x000007d1, 0x0080 }, /* R2001 (0x7d1) - SLIMTX3MIX Input 1 Volume */
+	{ 0x000007d2, 0x0000 }, /* R2002 (0x7d2) - SLIMTX3MIX Input 2 Source */
+	{ 0x000007d3, 0x0080 }, /* R2003 (0x7d3) - SLIMTX3MIX Input 2 Volume */
+	{ 0x000007d4, 0x0000 }, /* R2004 (0x7d4) - SLIMTX3MIX Input 3 Source */
+	{ 0x000007d5, 0x0080 }, /* R2005 (0x7d5) - SLIMTX3MIX Input 3 Volume */
+	{ 0x000007d6, 0x0000 }, /* R2006 (0x7d6) - SLIMTX3MIX Input 4 Source */
+	{ 0x000007d7, 0x0080 }, /* R2007 (0x7d7) - SLIMTX3MIX Input 4 Volume */
+	{ 0x000007d8, 0x0000 }, /* R2008 (0x7d8) - SLIMTX4MIX Input 1 Source */
+	{ 0x000007d9, 0x0080 }, /* R2009 (0x7d9) - SLIMTX4MIX Input 1 Volume */
+	{ 0x000007da, 0x0000 }, /* R2010 (0x7da) - SLIMTX4MIX Input 2 Source */
+	{ 0x000007db, 0x0080 }, /* R2011 (0x7db) - SLIMTX4MIX Input 2 Volume */
+	{ 0x000007dc, 0x0000 }, /* R2012 (0x7dc) - SLIMTX4MIX Input 3 Source */
+	{ 0x000007dd, 0x0080 }, /* R2013 (0x7dd) - SLIMTX4MIX Input 3 Volume */
+	{ 0x000007de, 0x0000 }, /* R2014 (0x7de) - SLIMTX4MIX Input 4 Source */
+	{ 0x000007df, 0x0080 }, /* R2015 (0x7df) - SLIMTX4MIX Input 4 Volume */
+	{ 0x000007e0, 0x0000 }, /* R2016 (0x7e0) - SLIMTX5MIX Input 1 Source */
+	{ 0x000007e1, 0x0080 }, /* R2017 (0x7e1) - SLIMTX5MIX Input 1 Volume */
+	{ 0x000007e2, 0x0000 }, /* R2018 (0x7e2) - SLIMTX5MIX Input 2 Source */
+	{ 0x000007e3, 0x0080 }, /* R2019 (0x7e3) - SLIMTX5MIX Input 2 Volume */
+	{ 0x000007e4, 0x0000 }, /* R2020 (0x7e4) - SLIMTX5MIX Input 3 Source */
+	{ 0x000007e5, 0x0080 }, /* R2021 (0x7e5) - SLIMTX5MIX Input 3 Volume */
+	{ 0x000007e6, 0x0000 }, /* R2022 (0x7e6) - SLIMTX5MIX Input 4 Source */
+	{ 0x000007e7, 0x0080 }, /* R2023 (0x7e7) - SLIMTX5MIX Input 4 Volume */
+	{ 0x000007e8, 0x0000 }, /* R2024 (0x7e8) - SLIMTX6MIX Input 1 Source */
+	{ 0x000007e9, 0x0080 }, /* R2025 (0x7e9) - SLIMTX6MIX Input 1 Volume */
+	{ 0x000007ea, 0x0000 }, /* R2026 (0x7ea) - SLIMTX6MIX Input 2 Source */
+	{ 0x000007eb, 0x0080 }, /* R2027 (0x7eb) - SLIMTX6MIX Input 2 Volume */
+	{ 0x000007ec, 0x0000 }, /* R2028 (0x7ec) - SLIMTX6MIX Input 3 Source */
+	{ 0x000007ed, 0x0080 }, /* R2029 (0x7ed) - SLIMTX6MIX Input 3 Volume */
+	{ 0x000007ee, 0x0000 }, /* R2030 (0x7ee) - SLIMTX6MIX Input 4 Source */
+	{ 0x000007ef, 0x0080 }, /* R2031 (0x7ef) - SLIMTX6MIX Input 4 Volume */
+	{ 0x000007f0, 0x0000 }, /* R2032 (0x7f0) - SLIMTX7MIX Input 1 Source */
+	{ 0x000007f1, 0x0080 }, /* R2033 (0x7f1) - SLIMTX7MIX Input 1 Volume */
+	{ 0x000007f2, 0x0000 }, /* R2034 (0x7f2) - SLIMTX7MIX Input 2 Source */
+	{ 0x000007f3, 0x0080 }, /* R2035 (0x7f3) - SLIMTX7MIX Input 2 Volume */
+	{ 0x000007f4, 0x0000 }, /* R2036 (0x7f4) - SLIMTX7MIX Input 3 Source */
+	{ 0x000007f5, 0x0080 }, /* R2037 (0x7f5) - SLIMTX7MIX Input 3 Volume */
+	{ 0x000007f6, 0x0000 }, /* R2038 (0x7f6) - SLIMTX7MIX Input 4 Source */
+	{ 0x000007f7, 0x0080 }, /* R2039 (0x7f7) - SLIMTX7MIX Input 4 Volume */
+	{ 0x000007f8, 0x0000 }, /* R2040 (0x7f8) - SLIMTX8MIX Input 1 Source */
+	{ 0x000007f9, 0x0080 }, /* R2041 (0x7f9) - SLIMTX8MIX Input 1 Volume */
+	{ 0x000007fa, 0x0000 }, /* R2042 (0x7fa) - SLIMTX8MIX Input 2 Source */
+	{ 0x000007fb, 0x0080 }, /* R2043 (0x7fb) - SLIMTX8MIX Input 2 Volume */
+	{ 0x000007fc, 0x0000 }, /* R2044 (0x7fc) - SLIMTX8MIX Input 3 Source */
+	{ 0x000007fd, 0x0080 }, /* R2045 (0x7fd) - SLIMTX8MIX Input 3 Volume */
+	{ 0x000007fe, 0x0000 }, /* R2046 (0x7fe) - SLIMTX8MIX Input 4 Source */
+	{ 0x000007ff, 0x0080 }, /* R2047 (0x7ff) - SLIMTX8MIX Input 4 Volume */
+	{ 0x00000800, 0x0000 }, /* R2048 (0x800) - SPDIF1TX1MIX Input 1 Source */
+	{ 0x00000801, 0x0080 }, /* R2049 (0x801) - SPDIF1TX1MIX Input 1 Volume */
+	{ 0x00000808, 0x0000 }, /* R2056 (0x808) - SPDIF1TX2MIX Input 1 Source */
+	{ 0x00000809, 0x0080 }, /* R2057 (0x809) - SPDIF1TX2MIX Input 1 Volume */
+	{ 0x00000880, 0x0000 }, /* R2176 (0x880) - EQ1MIX Input 1 Source */
+	{ 0x00000881, 0x0080 }, /* R2177 (0x881) - EQ1MIX Input 1 Volume */
+	{ 0x00000882, 0x0000 }, /* R2178 (0x882) - EQ1MIX Input 2 Source */
+	{ 0x00000883, 0x0080 }, /* R2179 (0x883) - EQ1MIX Input 2 Volume */
+	{ 0x00000884, 0x0000 }, /* R2180 (0x884) - EQ1MIX Input 3 Source */
+	{ 0x00000885, 0x0080 }, /* R2181 (0x885) - EQ1MIX Input 3 Volume */
+	{ 0x00000886, 0x0000 }, /* R2182 (0x886) - EQ1MIX Input 4 Source */
+	{ 0x00000887, 0x0080 }, /* R2183 (0x887) - EQ1MIX Input 4 Volume */
+	{ 0x00000888, 0x0000 }, /* R2184 (0x888) - EQ2MIX Input 1 Source */
+	{ 0x00000889, 0x0080 }, /* R2185 (0x889) - EQ2MIX Input 1 Volume */
+	{ 0x0000088a, 0x0000 }, /* R2186 (0x88a) - EQ2MIX Input 2 Source */
+	{ 0x0000088b, 0x0080 }, /* R2187 (0x88b) - EQ2MIX Input 2 Volume */
+	{ 0x0000088c, 0x0000 }, /* R2188 (0x88c) - EQ2MIX Input 3 Source */
+	{ 0x0000088d, 0x0080 }, /* R2189 (0x88d) - EQ2MIX Input 3 Volume */
+	{ 0x0000088e, 0x0000 }, /* R2190 (0x88e) - EQ2MIX Input 4 Source */
+	{ 0x0000088f, 0x0080 }, /* R2191 (0x88f) - EQ2MIX Input 4 Volume */
+	{ 0x00000890, 0x0000 }, /* R2192 (0x890) - EQ3MIX Input 1 Source */
+	{ 0x00000891, 0x0080 }, /* R2193 (0x891) - EQ3MIX Input 1 Volume */
+	{ 0x00000892, 0x0000 }, /* R2194 (0x892) - EQ3MIX Input 2 Source */
+	{ 0x00000893, 0x0080 }, /* R2195 (0x893) - EQ3MIX Input 2 Volume */
+	{ 0x00000894, 0x0000 }, /* R2196 (0x894) - EQ3MIX Input 3 Source */
+	{ 0x00000895, 0x0080 }, /* R2197 (0x895) - EQ3MIX Input 3 Volume */
+	{ 0x00000896, 0x0000 }, /* R2198 (0x896) - EQ3MIX Input 4 Source */
+	{ 0x00000897, 0x0080 }, /* R2199 (0x897) - EQ3MIX Input 4 Volume */
+	{ 0x00000898, 0x0000 }, /* R2200 (0x898) - EQ4MIX Input 1 Source */
+	{ 0x00000899, 0x0080 }, /* R2201 (0x899) - EQ4MIX Input 1 Volume */
+	{ 0x0000089a, 0x0000 }, /* R2202 (0x89a) - EQ4MIX Input 2 Source */
+	{ 0x0000089b, 0x0080 }, /* R2203 (0x89b) - EQ4MIX Input 2 Volume */
+	{ 0x0000089c, 0x0000 }, /* R2204 (0x89c) - EQ4MIX Input 3 Source */
+	{ 0x0000089d, 0x0080 }, /* R2205 (0x89d) - EQ4MIX Input 3 Volume */
+	{ 0x0000089e, 0x0000 }, /* R2206 (0x89e) - EQ4MIX Input 4 Source */
+	{ 0x0000089f, 0x0080 }, /* R2207 (0x89f) - EQ4MIX Input 4 Volume */
+	{ 0x000008c0, 0x0000 }, /* R2240 (0x8c0) - DRC1LMIX Input 1 Source */
+	{ 0x000008c1, 0x0080 }, /* R2241 (0x8c1) - DRC1LMIX Input 1 Volume */
+	{ 0x000008c2, 0x0000 }, /* R2242 (0x8c2) - DRC1LMIX Input 2 Source */
+	{ 0x000008c3, 0x0080 }, /* R2243 (0x8c3) - DRC1LMIX Input 2 Volume */
+	{ 0x000008c4, 0x0000 }, /* R2244 (0x8c4) - DRC1LMIX Input 3 Source */
+	{ 0x000008c5, 0x0080 }, /* R2245 (0x8c5) - DRC1LMIX Input 3 Volume */
+	{ 0x000008c6, 0x0000 }, /* R2246 (0x8c6) - DRC1LMIX Input 4 Source */
+	{ 0x000008c7, 0x0080 }, /* R2247 (0x8c7) - DRC1LMIX Input 4 Volume */
+	{ 0x000008c8, 0x0000 }, /* R2248 (0x8c8) - DRC1RMIX Input 1 Source */
+	{ 0x000008c9, 0x0080 }, /* R2249 (0x8c9) - DRC1RMIX Input 1 Volume */
+	{ 0x000008ca, 0x0000 }, /* R2250 (0x8ca) - DRC1RMIX Input 2 Source */
+	{ 0x000008cb, 0x0080 }, /* R2251 (0x8cb) - DRC1RMIX Input 2 Volume */
+	{ 0x000008cc, 0x0000 }, /* R2252 (0x8cc) - DRC1RMIX Input 3 Source */
+	{ 0x000008cd, 0x0080 }, /* R2253 (0x8cd) - DRC1RMIX Input 3 Volume */
+	{ 0x000008ce, 0x0000 }, /* R2254 (0x8ce) - DRC1RMIX Input 4 Source */
+	{ 0x000008cf, 0x0080 }, /* R2255 (0x8cf) - DRC1RMIX Input 4 Volume */
+	{ 0x000008d0, 0x0000 }, /* R2256 (0x8d0) - DRC2LMIX Input 1 Source */
+	{ 0x000008d1, 0x0080 }, /* R2257 (0x8d1) - DRC2LMIX Input 1 Volume */
+	{ 0x000008d2, 0x0000 }, /* R2258 (0x8d2) - DRC2LMIX Input 2 Source */
+	{ 0x000008d3, 0x0080 }, /* R2259 (0x8d3) - DRC2LMIX Input 2 Volume */
+	{ 0x000008d4, 0x0000 }, /* R2260 (0x8d4) - DRC2LMIX Input 3 Source */
+	{ 0x000008d5, 0x0080 }, /* R2261 (0x8d5) - DRC2LMIX Input 3 Volume */
+	{ 0x000008d6, 0x0000 }, /* R2262 (0x8d6) - DRC2LMIX Input 4 Source */
+	{ 0x000008d7, 0x0080 }, /* R2263 (0x8d7) - DRC2LMIX Input 4 Volume */
+	{ 0x000008d8, 0x0000 }, /* R2264 (0x8d8) - DRC2RMIX Input 1 Source */
+	{ 0x000008d9, 0x0080 }, /* R2265 (0x8d9) - DRC2RMIX Input 1 Volume */
+	{ 0x000008da, 0x0000 }, /* R2266 (0x8da) - DRC2RMIX Input 2 Source */
+	{ 0x000008db, 0x0080 }, /* R2267 (0x8db) - DRC2RMIX Input 2 Volume */
+	{ 0x000008dc, 0x0000 }, /* R2268 (0x8dc) - DRC2RMIX Input 3 Source */
+	{ 0x000008dd, 0x0080 }, /* R2269 (0x8dd) - DRC2RMIX Input 3 Volume */
+	{ 0x000008de, 0x0000 }, /* R2270 (0x8de) - DRC2RMIX Input 4 Source */
+	{ 0x000008df, 0x0080 }, /* R2271 (0x8df) - DRC2RMIX Input 4 Volume */
+	{ 0x00000900, 0x0000 }, /* R2304 (0x900) - HPLP1MIX Input 1 Source */
+	{ 0x00000901, 0x0080 }, /* R2305 (0x901) - HPLP1MIX Input 1 Volume */
+	{ 0x00000902, 0x0000 }, /* R2306 (0x902) - HPLP1MIX Input 2 Source */
+	{ 0x00000903, 0x0080 }, /* R2307 (0x903) - HPLP1MIX Input 2 Volume */
+	{ 0x00000904, 0x0000 }, /* R2308 (0x904) - HPLP1MIX Input 3 Source */
+	{ 0x00000905, 0x0080 }, /* R2309 (0x905) - HPLP1MIX Input 3 Volume */
+	{ 0x00000906, 0x0000 }, /* R2310 (0x906) - HPLP1MIX Input 4 Source */
+	{ 0x00000907, 0x0080 }, /* R2311 (0x907) - HPLP1MIX Input 4 Volume */
+	{ 0x00000908, 0x0000 }, /* R2312 (0x908) - HPLP2MIX Input 1 Source */
+	{ 0x00000909, 0x0080 }, /* R2313 (0x909) - HPLP2MIX Input 1 Volume */
+	{ 0x0000090a, 0x0000 }, /* R2314 (0x90a) - HPLP2MIX Input 2 Source */
+	{ 0x0000090b, 0x0080 }, /* R2315 (0x90b) - HPLP2MIX Input 2 Volume */
+	{ 0x0000090c, 0x0000 }, /* R2316 (0x90c) - HPLP2MIX Input 3 Source */
+	{ 0x0000090d, 0x0080 }, /* R2317 (0x90d) - HPLP2MIX Input 3 Volume */
+	{ 0x0000090e, 0x0000 }, /* R2318 (0x90e) - HPLP2MIX Input 4 Source */
+	{ 0x0000090f, 0x0080 }, /* R2319 (0x90f) - HPLP2MIX Input 4 Volume */
+	{ 0x00000910, 0x0000 }, /* R2320 (0x910) - HPLP3MIX Input 1 Source */
+	{ 0x00000911, 0x0080 }, /* R2321 (0x911) - HPLP3MIX Input 1 Volume */
+	{ 0x00000912, 0x0000 }, /* R2322 (0x912) - HPLP3MIX Input 2 Source */
+	{ 0x00000913, 0x0080 }, /* R2323 (0x913) - HPLP3MIX Input 2 Volume */
+	{ 0x00000914, 0x0000 }, /* R2324 (0x914) - HPLP3MIX Input 3 Source */
+	{ 0x00000915, 0x0080 }, /* R2325 (0x915) - HPLP3MIX Input 3 Volume */
+	{ 0x00000916, 0x0000 }, /* R2326 (0x916) - HPLP3MIX Input 4 Source */
+	{ 0x00000917, 0x0080 }, /* R2327 (0x917) - HPLP3MIX Input 4 Volume */
+	{ 0x00000918, 0x0000 }, /* R2328 (0x918) - HPLP4MIX Input 1 Source */
+	{ 0x00000919, 0x0080 }, /* R2329 (0x919) - HPLP4MIX Input 1 Volume */
+	{ 0x0000091a, 0x0000 }, /* R2330 (0x91a) - HPLP4MIX Input 2 Source */
+	{ 0x0000091b, 0x0080 }, /* R2331 (0x91b) - HPLP4MIX Input 2 Volume */
+	{ 0x0000091c, 0x0000 }, /* R2332 (0x91c) - HPLP4MIX Input 3 Source */
+	{ 0x0000091d, 0x0080 }, /* R2333 (0x91d) - HPLP4MIX Input 3 Volume */
+	{ 0x0000091e, 0x0000 }, /* R2334 (0x91e) - HPLP4MIX Input 4 Source */
+	{ 0x0000091f, 0x0080 }, /* R2335 (0x91f) - HPLP4MIX Input 4 Volume */
+	{ 0x00000940, 0x0000 }, /* R2368 (0x940) - DSP1LMIX Input 1 Source */
+	{ 0x00000941, 0x0080 }, /* R2369 (0x941) - DSP1LMIX Input 1 Volume */
+	{ 0x00000942, 0x0000 }, /* R2370 (0x942) - DSP1LMIX Input 2 Source */
+	{ 0x00000943, 0x0080 }, /* R2371 (0x943) - DSP1LMIX Input 2 Volume */
+	{ 0x00000944, 0x0000 }, /* R2372 (0x944) - DSP1LMIX Input 3 Source */
+	{ 0x00000945, 0x0080 }, /* R2373 (0x945) - DSP1LMIX Input 3 Volume */
+	{ 0x00000946, 0x0000 }, /* R2374 (0x946) - DSP1LMIX Input 4 Source */
+	{ 0x00000947, 0x0080 }, /* R2375 (0x947) - DSP1LMIX Input 4 Volume */
+	{ 0x00000948, 0x0000 }, /* R2376 (0x948) - DSP1RMIX Input 1 Source */
+	{ 0x00000949, 0x0080 }, /* R2377 (0x949) - DSP1RMIX Input 1 Volume */
+	{ 0x0000094a, 0x0000 }, /* R2378 (0x94a) - DSP1RMIX Input 2 Source */
+	{ 0x0000094b, 0x0080 }, /* R2379 (0x94b) - DSP1RMIX Input 2 Volume */
+	{ 0x0000094c, 0x0000 }, /* R2380 (0x94c) - DSP1RMIX Input 3 Source */
+	{ 0x0000094d, 0x0080 }, /* R2381 (0x94d) - DSP1RMIX Input 3 Volume */
+	{ 0x0000094e, 0x0000 }, /* R2382 (0x94e) - DSP1RMIX Input 4 Source */
+	{ 0x0000094f, 0x0080 }, /* R2383 (0x94f) - DSP1RMIX Input 4 Volume */
+	{ 0x00000950, 0x0000 }, /* R2384 (0x950) - DSP1AUX1MIX Input 1 Source */
+	{ 0x00000958, 0x0000 }, /* R2392 (0x958) - DSP1AUX2MIX Input 1 Source */
+	{ 0x00000960, 0x0000 }, /* R2400 (0x960) - DSP1AUX3MIX Input 1 Source */
+	{ 0x00000968, 0x0000 }, /* R2408 (0x968) - DSP1AUX4MIX Input 1 Source */
+	{ 0x00000970, 0x0000 }, /* R2416 (0x970) - DSP1AUX5MIX Input 1 Source */
+	{ 0x00000978, 0x0000 }, /* R2424 (0x978) - DSP1AUX6MIX Input 1 Source */
+	{ 0x00000980, 0x0000 }, /* R2432 (0x980) - DSP2LMIX Input 1 Source */
+	{ 0x00000981, 0x0080 }, /* R2433 (0x981) - DSP2LMIX Input 1 Volume */
+	{ 0x00000982, 0x0000 }, /* R2434 (0x982) - DSP2LMIX Input 2 Source */
+	{ 0x00000983, 0x0080 }, /* R2435 (0x983) - DSP2LMIX Input 2 Volume */
+	{ 0x00000984, 0x0000 }, /* R2436 (0x984) - DSP2LMIX Input 3 Source */
+	{ 0x00000985, 0x0080 }, /* R2437 (0x985) - DSP2LMIX Input 3 Volume */
+	{ 0x00000986, 0x0000 }, /* R2438 (0x986) - DSP2LMIX Input 4 Source */
+	{ 0x00000987, 0x0080 }, /* R2439 (0x987) - DSP2LMIX Input 4 Volume */
+	{ 0x00000988, 0x0000 }, /* R2440 (0x988) - DSP2RMIX Input 1 Source */
+	{ 0x00000989, 0x0080 }, /* R2441 (0x989) - DSP2RMIX Input 1 Volume */
+	{ 0x0000098a, 0x0000 }, /* R2442 (0x98a) - DSP2RMIX Input 2 Source */
+	{ 0x0000098b, 0x0080 }, /* R2443 (0x98b) - DSP2RMIX Input 2 Volume */
+	{ 0x0000098c, 0x0000 }, /* R2444 (0x98c) - DSP2RMIX Input 3 Source */
+	{ 0x0000098d, 0x0080 }, /* R2445 (0x98d) - DSP2RMIX Input 3 Volume */
+	{ 0x0000098e, 0x0000 }, /* R2446 (0x98e) - DSP2RMIX Input 4 Source */
+	{ 0x0000098f, 0x0080 }, /* R2447 (0x98f) - DSP2RMIX Input 4 Volume */
+	{ 0x00000990, 0x0000 }, /* R2448 (0x990) - DSP2AUX1MIX Input 1 Source */
+	{ 0x00000998, 0x0000 }, /* R2456 (0x998) - DSP2AUX2MIX Input 1 Source */
+	{ 0x000009a0, 0x0000 }, /* R2464 (0x9a0) - DSP2AUX3MIX Input 1 Source */
+	{ 0x000009a8, 0x0000 }, /* R2472 (0x9a8) - DSP2AUX4MIX Input 1 Source */
+	{ 0x000009b0, 0x0000 }, /* R2480 (0x9b0) - DSP2AUX5MIX Input 1 Source */
+	{ 0x000009b8, 0x0000 }, /* R2488 (0x9b8) - DSP2AUX6MIX Input 1 Source */
+	{ 0x000009c0, 0x0000 }, /* R2496 (0x9c0) - DSP3LMIX Input 1 Source */
+	{ 0x000009c1, 0x0080 }, /* R2497 (0x9c1) - DSP3LMIX Input 1 Volume */
+	{ 0x000009c2, 0x0000 }, /* R2498 (0x9c2) - DSP3LMIX Input 2 Source */
+	{ 0x000009c3, 0x0080 }, /* R2499 (0x9c3) - DSP3LMIX Input 2 Volume */
+	{ 0x000009c4, 0x0000 }, /* R2500 (0x9c4) - DSP3LMIX Input 3 Source */
+	{ 0x000009c5, 0x0080 }, /* R2501 (0x9c5) - DSP3LMIX Input 3 Volume */
+	{ 0x000009c6, 0x0000 }, /* R2502 (0x9c6) - DSP3LMIX Input 4 Source */
+	{ 0x000009c7, 0x0080 }, /* R2503 (0x9c7) - DSP3LMIX Input 4 Volume */
+	{ 0x000009c8, 0x0000 }, /* R2504 (0x9c8) - DSP3RMIX Input 1 Source */
+	{ 0x000009c9, 0x0080 }, /* R2505 (0x9c9) - DSP3RMIX Input 1 Volume */
+	{ 0x000009ca, 0x0000 }, /* R2506 (0x9ca) - DSP3RMIX Input 2 Source */
+	{ 0x000009cb, 0x0080 }, /* R2507 (0x9cb) - DSP3RMIX Input 2 Volume */
+	{ 0x000009cc, 0x0000 }, /* R2508 (0x9cc) - DSP3RMIX Input 3 Source */
+	{ 0x000009cd, 0x0080 }, /* R2509 (0x9cd) - DSP3RMIX Input 3 Volume */
+	{ 0x000009ce, 0x0000 }, /* R2510 (0x9ce) - DSP3RMIX Input 4 Source */
+	{ 0x000009cf, 0x0080 }, /* R2511 (0x9cf) - DSP3RMIX Input 4 Volume */
+	{ 0x000009d0, 0x0000 }, /* R2512 (0x9d0) - DSP3AUX1MIX Input 1 Source */
+	{ 0x000009d8, 0x0000 }, /* R2520 (0x9d8) - DSP3AUX2MIX Input 1 Source */
+	{ 0x000009e0, 0x0000 }, /* R2528 (0x9e0) - DSP3AUX3MIX Input 1 Source */
+	{ 0x000009e8, 0x0000 }, /* R2536 (0x9e8) - DSP3AUX4MIX Input 1 Source */
+	{ 0x000009f0, 0x0000 }, /* R2544 (0x9f0) - DSP3AUX5MIX Input 1 Source */
+	{ 0x000009f8, 0x0000 }, /* R2552 (0x9f8) - DSP3AUX6MIX Input 1 Source */
+	{ 0x00000a00, 0x0000 }, /* R2560 (0xa00) - DSP4LMIX Input 1 Source */
+	{ 0x00000a01, 0x0080 }, /* R2561 (0xa01) - DSP4LMIX Input 1 Volume */
+	{ 0x00000a02, 0x0000 }, /* R2562 (0xa02) - DSP4LMIX Input 2 Source */
+	{ 0x00000a03, 0x0080 }, /* R2563 (0xa03) - DSP4LMIX Input 2 Volume */
+	{ 0x00000a04, 0x0000 }, /* R2564 (0xa04) - DSP4LMIX Input 3 Source */
+	{ 0x00000a05, 0x0080 }, /* R2565 (0xa05) - DSP4LMIX Input 3 Volume */
+	{ 0x00000a06, 0x0000 }, /* R2566 (0xa06) - DSP4LMIX Input 4 Source */
+	{ 0x00000a07, 0x0080 }, /* R2567 (0xa07) - DSP4LMIX Input 4 Volume */
+	{ 0x00000a08, 0x0000 }, /* R2568 (0xa08) - DSP4RMIX Input 1 Source */
+	{ 0x00000a09, 0x0080 }, /* R2569 (0xa09) - DSP4RMIX Input 1 Volume */
+	{ 0x00000a0a, 0x0000 }, /* R2570 (0xa0a) - DSP4RMIX Input 2 Source */
+	{ 0x00000a0b, 0x0080 }, /* R2571 (0xa0b) - DSP4RMIX Input 2 Volume */
+	{ 0x00000a0c, 0x0000 }, /* R2572 (0xa0c) - DSP4RMIX Input 3 Source */
+	{ 0x00000a0d, 0x0080 }, /* R2573 (0xa0d) - DSP4RMIX Input 3 Volume */
+	{ 0x00000a0e, 0x0000 }, /* R2574 (0xa0e) - DSP4RMIX Input 4 Source */
+	{ 0x00000a0f, 0x0080 }, /* R2575 (0xa0f) - DSP4RMIX Input 4 Volume */
+	{ 0x00000a10, 0x0000 }, /* R2576 (0xa10) - DSP4AUX1MIX Input 1 Source */
+	{ 0x00000a18, 0x0000 }, /* R2584 (0xa18) - DSP4AUX2MIX Input 1 Source */
+	{ 0x00000a20, 0x0000 }, /* R2592 (0xa20) - DSP4AUX3MIX Input 1 Source */
+	{ 0x00000a28, 0x0000 }, /* R2600 (0xa28) - DSP4AUX4MIX Input 1 Source */
+	{ 0x00000a30, 0x0000 }, /* R2608 (0xa30) - DSP4AUX5MIX Input 1 Source */
+	{ 0x00000a38, 0x0000 }, /* R2616 (0xa38) - DSP4AUX6MIX Input 1 Source */
+	{ 0x00000a40, 0x0000 }, /* R2624 (0xa40) - DSP5LMIX Input 1 Source */
+	{ 0x00000a41, 0x0080 }, /* R2625 (0xa41) - DSP5LMIX Input 1 Volume */
+	{ 0x00000a42, 0x0000 }, /* R2626 (0xa42) - DSP5LMIX Input 2 Source */
+	{ 0x00000a43, 0x0080 }, /* R2627 (0xa43) - DSP5LMIX Input 2 Volume */
+	{ 0x00000a44, 0x0000 }, /* R2628 (0xa44) - DSP5LMIX Input 3 Source */
+	{ 0x00000a45, 0x0080 }, /* R2629 (0xa45) - DSP5LMIX Input 3 Volume */
+	{ 0x00000a46, 0x0000 }, /* R2630 (0xa46) - DSP5LMIX Input 4 Source */
+	{ 0x00000a47, 0x0080 }, /* R2631 (0xa47) - DSP5LMIX Input 4 Volume */
+	{ 0x00000a48, 0x0000 }, /* R2632 (0xa48) - DSP5RMIX Input 1 Source */
+	{ 0x00000a49, 0x0080 }, /* R2633 (0xa49) - DSP5RMIX Input 1 Volume */
+	{ 0x00000a4a, 0x0000 }, /* R2634 (0xa4a) - DSP5RMIX Input 2 Source */
+	{ 0x00000a4b, 0x0080 }, /* R2635 (0xa4b) - DSP5RMIX Input 2 Volume */
+	{ 0x00000a4c, 0x0000 }, /* R2636 (0xa4c) - DSP5RMIX Input 3 Source */
+	{ 0x00000a4d, 0x0080 }, /* R2637 (0xa4d) - DSP5RMIX Input 3 Volume */
+	{ 0x00000a4e, 0x0000 }, /* R2638 (0xa4e) - DSP5RMIX Input 4 Source */
+	{ 0x00000a4f, 0x0080 }, /* R2639 (0xa4f) - DSP5RMIX Input 4 Volume */
+	{ 0x00000a50, 0x0000 }, /* R2640 (0xa50) - DSP5AUX1MIX Input 1 Source */
+	{ 0x00000a58, 0x0000 }, /* R2658 (0xa58) - DSP5AUX2MIX Input 1 Source */
+	{ 0x00000a60, 0x0000 }, /* R2656 (0xa60) - DSP5AUX3MIX Input 1 Source */
+	{ 0x00000a68, 0x0000 }, /* R2664 (0xa68) - DSP5AUX4MIX Input 1 Source */
+	{ 0x00000a70, 0x0000 }, /* R2672 (0xa70) - DSP5AUX5MIX Input 1 Source */
+	{ 0x00000a78, 0x0000 }, /* R2680 (0xa78) - DSP5AUX6MIX Input 1 Source */
+	{ 0x00000a80, 0x0000 }, /* R2688 (0xa80) - ASRC1_1LMIX Input 1 Source */
+	{ 0x00000a88, 0x0000 }, /* R2696 (0xa88) - ASRC1_1RMIX Input 1 Source */
+	{ 0x00000a90, 0x0000 }, /* R2704 (0xa90) - ASRC1_2LMIX Input 1 Source */
+	{ 0x00000a98, 0x0000 }, /* R2712 (0xa98) - ASRC1_2RMIX Input 1 Source */
+	{ 0x00000aa0, 0x0000 }, /* R2720 (0xaa0) - ASRC2_1LMIX Input 1 Source */
+	{ 0x00000aa8, 0x0000 }, /* R2728 (0xaa8) - ASRC2_1RMIX Input 1 Source */
+	{ 0x00000ab0, 0x0000 }, /* R2736 (0xab0) - ASRC2_2LMIX Input 1 Source */
+	{ 0x00000ab8, 0x0000 }, /* R2744 (0xab8) - ASRC2_2RMIX Input 1 Source */
+	{ 0x00000b00, 0x0000 }, /* R2816 (0xb00) - ISRC1DEC1MIX Input 1 Source*/
+	{ 0x00000b08, 0x0000 }, /* R2824 (0xb08) - ISRC1DEC2MIX Input 1 Source*/
+	{ 0x00000b10, 0x0000 }, /* R2832 (0xb10) - ISRC1DEC3MIX Input 1 Source*/
+	{ 0x00000b18, 0x0000 }, /* R2840 (0xb18) - ISRC1DEC4MIX Input 1 Source*/
+	{ 0x00000b20, 0x0000 }, /* R2848 (0xb20) - ISRC1INT1MIX Input 1 Source*/
+	{ 0x00000b28, 0x0000 }, /* R2856 (0xb28) - ISRC1INT2MIX Input 1 Source*/
+	{ 0x00000b30, 0x0000 }, /* R2864 (0xb30) - ISRC1INT3MIX Input 1 Source*/
+	{ 0x00000b38, 0x0000 }, /* R2872 (0xb38) - ISRC1INT4MIX Input 1 Source*/
+	{ 0x00000b40, 0x0000 }, /* R2880 (0xb40) - ISRC2DEC1MIX Input 1 Source*/
+	{ 0x00000b48, 0x0000 }, /* R2888 (0xb48) - ISRC2DEC2MIX Input 1 Source*/
+	{ 0x00000b50, 0x0000 }, /* R2896 (0xb50) - ISRC2DEC3MIX Input 1 Source*/
+	{ 0x00000b58, 0x0000 }, /* R2904 (0xb58) - ISRC2DEC4MIX Input 1 Source*/
+	{ 0x00000b60, 0x0000 }, /* R2912 (0xb60) - ISRC2INT1MIX Input 1 Source*/
+	{ 0x00000b68, 0x0000 }, /* R2920 (0xb68) - ISRC2INT2MIX Input 1 Source*/
+	{ 0x00000b70, 0x0000 }, /* R2928 (0xb70) - ISRC2INT3MIX Input 1 Source*/
+	{ 0x00000b78, 0x0000 }, /* R2936 (0xb78) - ISRC2INT4MIX Input 1 Source*/
+	{ 0x00000b80, 0x0000 }, /* R2944 (0xb80) - ISRC3DEC1MIX Input 1 Source*/
+	{ 0x00000b88, 0x0000 }, /* R2952 (0xb88) - ISRC3DEC2MIX Input 1 Source*/
+	{ 0x00000ba0, 0x0000 }, /* R2976 (0xb80) - ISRC3INT1MIX Input 1 Source*/
+	{ 0x00000ba8, 0x0000 }, /* R2984 (0xb88) - ISRC3INT2MIX Input 1 Source*/
+	{ 0x00000bc0, 0x0000 }, /* R3008 (0xbc0) - ISRC4DEC1MIX Input 1 Source */
+	{ 0x00000bc8, 0x0000 }, /* R3016 (0xbc8) - ISRC4DEC2MIX Input 1 Source */
+	{ 0x00000be0, 0x0000 }, /* R3040 (0xbe0) - ISRC4INT1MIX Input 1 Source */
+	{ 0x00000be8, 0x0000 }, /* R3048 (0xbe8) - ISRC4INT2MIX Input 1 Source */
+	{ 0x00000c00, 0x0000 }, /* R3072 (0xc00) - DSP6LMIX Input 1 Source */
+	{ 0x00000c01, 0x0080 }, /* R3073 (0xc01) - DSP6LMIX Input 1 Volume */
+	{ 0x00000c02, 0x0000 }, /* R3074 (0xc02) - DSP6LMIX Input 2 Source */
+	{ 0x00000c03, 0x0080 }, /* R3075 (0xc03) - DSP6LMIX Input 2 Volume */
+	{ 0x00000c04, 0x0000 }, /* R3076 (0xc04) - DSP6LMIX Input 3 Source */
+	{ 0x00000c05, 0x0080 }, /* R3077 (0xc05) - DSP6LMIX Input 3 Volume */
+	{ 0x00000c06, 0x0000 }, /* R3078 (0xc06) - DSP6LMIX Input 4 Source */
+	{ 0x00000c07, 0x0080 }, /* R3079 (0xc07) - DSP6LMIX Input 4 Volume */
+	{ 0x00000c08, 0x0000 }, /* R3080 (0xc08) - DSP6RMIX Input 1 Source */
+	{ 0x00000c09, 0x0080 }, /* R3081 (0xc09) - DSP6RMIX Input 1 Volume */
+	{ 0x00000c0a, 0x0000 }, /* R3082 (0xc0a) - DSP6RMIX Input 2 Source */
+	{ 0x00000c0b, 0x0080 }, /* R3083 (0xc0b) - DSP6RMIX Input 2 Volume */
+	{ 0x00000c0c, 0x0000 }, /* R3084 (0xc0c) - DSP6RMIX Input 3 Source */
+	{ 0x00000c0d, 0x0080 }, /* R3085 (0xc0d) - DSP6RMIX Input 3 Volume */
+	{ 0x00000c0e, 0x0000 }, /* R3086 (0xc0e) - DSP6RMIX Input 4 Source */
+	{ 0x00000c0f, 0x0080 }, /* R3087 (0xc0f) - DSP6RMIX Input 4 Volume */
+	{ 0x00000c10, 0x0000 }, /* R3088 (0xc10) - DSP6AUX1MIX Input 1 Source */
+	{ 0x00000c18, 0x0000 }, /* R3088 (0xc18) - DSP6AUX2MIX Input 1 Source */
+	{ 0x00000c20, 0x0000 }, /* R3088 (0xc20) - DSP6AUX3MIX Input 1 Source */
+	{ 0x00000c28, 0x0000 }, /* R3088 (0xc28) - DSP6AUX4MIX Input 1 Source */
+	{ 0x00000c30, 0x0000 }, /* R3088 (0xc30) - DSP6AUX5MIX Input 1 Source */
+	{ 0x00000c38, 0x0000 }, /* R3088 (0xc38) - DSP6AUX6MIX Input 1 Source */
+	{ 0x00000c40, 0x0000 }, /* R3136 (0xc40) - DSP7LMIX Input 1 Source */
+	{ 0x00000c41, 0x0080 }, /* R3137 (0xc41) - DSP7LMIX Input 1 Volume */
+	{ 0x00000c42, 0x0000 }, /* R3138 (0xc42) - DSP7LMIX Input 2 Source */
+	{ 0x00000c43, 0x0080 }, /* R3139 (0xc43) - DSP7LMIX Input 2 Volume */
+	{ 0x00000c44, 0x0000 }, /* R3140 (0xc44) - DSP7LMIX Input 3 Source */
+	{ 0x00000c45, 0x0080 }, /* R3141 (0xc45) - DSP7lMIX Input 3 Volume */
+	{ 0x00000c46, 0x0000 }, /* R3142 (0xc46) - DSP7lMIX Input 4 Source */
+	{ 0x00000c47, 0x0080 }, /* R3143 (0xc47) - DSP7LMIX Input 4 Volume */
+	{ 0x00000c48, 0x0000 }, /* R3144 (0xc48) - DSP7RMIX Input 1 Source */
+	{ 0x00000c49, 0x0080 }, /* R3145 (0xc49) - DSP7RMIX Input 1 Volume */
+	{ 0x00000c4a, 0x0000 }, /* R3146 (0xc4a) - DSP7RMIX Input 2 Source */
+	{ 0x00000c4b, 0x0080 }, /* R3147 (0xc4b) - DSP7RMIX Input 2 Volume */
+	{ 0x00000c4c, 0x0000 }, /* R3148 (0xc4c) - DSP7RMIX Input 3 Source */
+	{ 0x00000c4d, 0x0080 }, /* R3159 (0xc4d) - DSP7RMIX Input 3 Volume */
+	{ 0x00000c4e, 0x0000 }, /* R3150 (0xc4e) - DSP7RMIX Input 4 Source */
+	{ 0x00000c4f, 0x0080 }, /* R3151 (0xc4f) - DSP7RMIX Input 4 Volume */
+	{ 0x00000c50, 0x0000 }, /* R3152 (0xc50) - DSP7AUX1MIX Input 1 Source */
+	{ 0x00000c58, 0x0000 }, /* R3160 (0xc58) - DSP7AUX2MIX Input 1 Source */
+	{ 0x00000c60, 0x0000 }, /* R3168 (0xc60) - DSP7AUX3MIX Input 1 Source */
+	{ 0x00000c68, 0x0000 }, /* R3176 (0xc68) - DSP7AUX4MIX Input 1 Source */
+	{ 0x00000c70, 0x0000 }, /* R3184 (0xc70) - DSP7AUX5MIX Input 1 Source */
+	{ 0x00000c78, 0x0000 }, /* R3192 (0xc78) - DSP7AUX6MIX Input 1 Source */
+	{ 0x00000dc0, 0x0000 }, /* R3520 (0xdc0) - DFC1MIX Input 1 Source */
+	{ 0x00000dc8, 0x0000 }, /* R3528 (0xdc8) - DFC2MIX Input 1 Source */
+	{ 0x00000dd0, 0x0000 }, /* R3536 (0xdd0) - DFC3MIX Input 1 Source */
+	{ 0x00000dd8, 0x0000 }, /* R3544 (0xdd8) - DFC4MIX Input 1 Source */
+	{ 0x00000de0, 0x0000 }, /* R3552 (0xde0) - DFC5MIX Input 1 Source */
+	{ 0x00000de8, 0x0000 }, /* R3560 (0xde8) - DFC6MIX Input 1 Source */
+	{ 0x00000df0, 0x0000 }, /* R3568 (0xdf0) - DFC7MIX Input 1 Source */
+	{ 0x00000df8, 0x0000 }, /* R3576 (0xdf8) - DFC8MIX Input 1 Source */
+	{ 0x00000e00, 0x0000 }, /* R3584 (0xe00) - FX_Ctrl1 */
+	{ 0x00000e10, 0x6318 }, /* R3600 (0xe10) - EQ1_1 */
+	{ 0x00000e11, 0x6300 }, /* R3601 (0xe11) - EQ1_2 */
+	{ 0x00000e12, 0x0fc8 }, /* R3602 (0xe12) - EQ1_3 */
+	{ 0x00000e13, 0x03fe }, /* R3603 (0xe13) - EQ1_4 */
+	{ 0x00000e14, 0x00e0 }, /* R3604 (0xe14) - EQ1_5 */
+	{ 0x00000e15, 0x1ec4 }, /* R3605 (0xe15) - EQ1_6 */
+	{ 0x00000e16, 0xf136 }, /* R3606 (0xe16) - EQ1_7 */
+	{ 0x00000e17, 0x0409 }, /* R3607 (0xe17) - EQ1_8 */
+	{ 0x00000e18, 0x04cc }, /* R3608 (0xe18) - EQ1_9 */
+	{ 0x00000e19, 0x1c9b }, /* R3609 (0xe19) - EQ1_10 */
+	{ 0x00000e1a, 0xf337 }, /* R3610 (0xe1a) - EQ1_11 */
+	{ 0x00000e1b, 0x040b }, /* R3611 (0xe1b) - EQ1_12 */
+	{ 0x00000e1c, 0x0cbb }, /* R3612 (0xe1c) - EQ1_13 */
+	{ 0x00000e1d, 0x16f8 }, /* R3613 (0xe1d) - EQ1_14 */
+	{ 0x00000e1e, 0xf7d9 }, /* R3614 (0xe1e) - EQ1_15 */
+	{ 0x00000e1f, 0x040a }, /* R3615 (0xe1f) - EQ1_16 */
+	{ 0x00000e20, 0x1f14 }, /* R3616 (0xe20) - EQ1_17 */
+	{ 0x00000e21, 0x058c }, /* R3617 (0xe21) - EQ1_18 */
+	{ 0x00000e22, 0x0563 }, /* R3618 (0xe22) - EQ1_19 */
+	{ 0x00000e23, 0x4000 }, /* R3619 (0xe23) - EQ1_20 */
+	{ 0x00000e24, 0x0b75 }, /* R3620 (0xe24) - EQ1_21 */
+	{ 0x00000e26, 0x6318 }, /* R3622 (0xe26) - EQ2_1 */
+	{ 0x00000e27, 0x6300 }, /* R3623 (0xe27) - EQ2_2 */
+	{ 0x00000e28, 0x0fc8 }, /* R3624 (0xe28) - EQ2_3 */
+	{ 0x00000e29, 0x03fe }, /* R3625 (0xe29) - EQ2_4 */
+	{ 0x00000e2a, 0x00e0 }, /* R3626 (0xe2a) - EQ2_5 */
+	{ 0x00000e2b, 0x1ec4 }, /* R3627 (0xe2b) - EQ2_6 */
+	{ 0x00000e2c, 0xf136 }, /* R3628 (0xe2c) - EQ2_7 */
+	{ 0x00000e2d, 0x0409 }, /* R3629 (0xe2d) - EQ2_8 */
+	{ 0x00000e2e, 0x04cc }, /* R3630 (0xe2e) - EQ2_9 */
+	{ 0x00000e2f, 0x1c9b }, /* R3631 (0xe2f) - EQ2_10 */
+	{ 0x00000e30, 0xf337 }, /* R3632 (0xe30) - EQ2_11 */
+	{ 0x00000e31, 0x040b }, /* R3633 (0xe31) - EQ2_12 */
+	{ 0x00000e32, 0x0cbb }, /* R3634 (0xe32) - EQ2_13 */
+	{ 0x00000e33, 0x16f8 }, /* R3635 (0xe33) - EQ2_14 */
+	{ 0x00000e34, 0xf7d9 }, /* R3636 (0xe34) - EQ2_15 */
+	{ 0x00000e35, 0x040a }, /* R3637 (0xe35) - EQ2_16 */
+	{ 0x00000e36, 0x1f14 }, /* R3638 (0xe36) - EQ2_17 */
+	{ 0x00000e37, 0x058c }, /* R3639 (0xe37) - EQ2_18 */
+	{ 0x00000e38, 0x0563 }, /* R3640 (0xe38) - EQ2_19 */
+	{ 0x00000e39, 0x4000 }, /* R3641 (0xe39) - EQ2_20 */
+	{ 0x00000e3a, 0x0b75 }, /* R3642 (0xe3a) - EQ2_21 */
+	{ 0x00000e3c, 0x6318 }, /* R3644 (0xe3c) - EQ3_1 */
+	{ 0x00000e3d, 0x6300 }, /* R3645 (0xe3d) - EQ3_2 */
+	{ 0x00000e3e, 0x0fc8 }, /* R3646 (0xe3e) - EQ3_3 */
+	{ 0x00000e3f, 0x03fe }, /* R3647 (0xe3f) - EQ3_4 */
+	{ 0x00000e40, 0x00e0 }, /* R3648 (0xe40) - EQ3_5 */
+	{ 0x00000e41, 0x1ec4 }, /* R3649 (0xe41) - EQ3_6 */
+	{ 0x00000e42, 0xf136 }, /* R3650 (0xe42) - EQ3_7 */
+	{ 0x00000e43, 0x0409 }, /* R3651 (0xe43) - EQ3_8 */
+	{ 0x00000e44, 0x04cc }, /* R3652 (0xe44) - EQ3_9 */
+	{ 0x00000e45, 0x1c9b }, /* R3653 (0xe45) - EQ3_10 */
+	{ 0x00000e46, 0xf337 }, /* R3654 (0xe46) - EQ3_11 */
+	{ 0x00000e47, 0x040b }, /* R3655 (0xe47) - EQ3_12 */
+	{ 0x00000e48, 0x0cbb }, /* R3656 (0xe48) - EQ3_13 */
+	{ 0x00000e49, 0x16f8 }, /* R3657 (0xe49) - EQ3_14 */
+	{ 0x00000e4a, 0xf7d9 }, /* R3658 (0xe4a) - EQ3_15 */
+	{ 0x00000e4b, 0x040a }, /* R3659 (0xe4b) - EQ3_16 */
+	{ 0x00000e4c, 0x1f14 }, /* R3660 (0xe4c) - EQ3_17 */
+	{ 0x00000e4d, 0x058c }, /* R3661 (0xe4d) - EQ3_18 */
+	{ 0x00000e4e, 0x0563 }, /* R3662 (0xe4e) - EQ3_19 */
+	{ 0x00000e4f, 0x4000 }, /* R3663 (0xe4f) - EQ3_20 */
+	{ 0x00000e50, 0x0b75 }, /* R3664 (0xe50) - EQ3_21 */
+	{ 0x00000e52, 0x6318 }, /* R3666 (0xe52) - EQ4_1 */
+	{ 0x00000e53, 0x6300 }, /* R3667 (0xe53) - EQ4_2 */
+	{ 0x00000e54, 0x0fc8 }, /* R3668 (0xe54) - EQ4_3 */
+	{ 0x00000e55, 0x03fe }, /* R3669 (0xe55) - EQ4_4 */
+	{ 0x00000e56, 0x00e0 }, /* R3670 (0xe56) - EQ4_5 */
+	{ 0x00000e57, 0x1ec4 }, /* R3671 (0xe57) - EQ4_6 */
+	{ 0x00000e58, 0xf136 }, /* R3672 (0xe58) - EQ4_7 */
+	{ 0x00000e59, 0x0409 }, /* R3673 (0xe59) - EQ4_8 */
+	{ 0x00000e5a, 0x04cc }, /* R3674 (0xe5a) - EQ4_9 */
+	{ 0x00000e5b, 0x1c9b }, /* R3675 (0xe5b) - EQ4_10 */
+	{ 0x00000e5c, 0xf337 }, /* R3676 (0xe5c) - EQ4_11 */
+	{ 0x00000e5d, 0x040b }, /* R3677 (0xe5d) - EQ4_12 */
+	{ 0x00000e5e, 0x0cbb }, /* R3678 (0xe5e) - EQ4_13 */
+	{ 0x00000e5f, 0x16f8 }, /* R3679 (0xe5f) - EQ4_14 */
+	{ 0x00000e60, 0xf7d9 }, /* R3680 (0xe60) - EQ4_15 */
+	{ 0x00000e61, 0x040a }, /* R3681 (0xe61) - EQ4_16 */
+	{ 0x00000e62, 0x1f14 }, /* R3682 (0xe62) - EQ4_17 */
+	{ 0x00000e63, 0x058c }, /* R3683 (0xe63) - EQ4_18 */
+	{ 0x00000e64, 0x0563 }, /* R3684 (0xe64) - EQ4_19 */
+	{ 0x00000e65, 0x4000 }, /* R3685 (0xe65) - EQ4_20 */
+	{ 0x00000e66, 0x0b75 }, /* R3686 (0xe66) - EQ4_21 */
+	{ 0x00000e80, 0x0018 }, /* R3712 (0xe80) - DRC1 ctrl1 */
+	{ 0x00000e81, 0x0933 }, /* R3713 (0xe81) - DRC1 ctrl2 */
+	{ 0x00000e82, 0x0018 }, /* R3714 (0xe82) - DRC1 ctrl3 */
+	{ 0x00000e83, 0x0000 }, /* R3715 (0xe83) - DRC1 ctrl4 */
+	{ 0x00000e84, 0x0000 }, /* R3716 (0xe84) - DRC1 ctrl5 */
+	{ 0x00000e88, 0x0018 }, /* R3720 (0xe88) - DRC2 ctrl1 */
+	{ 0x00000e89, 0x0933 }, /* R3721 (0xe89) - DRC2 ctrl2 */
+	{ 0x00000e8a, 0x0018 }, /* R3722 (0xe8a) - DRC2 ctrl3 */
+	{ 0x00000e8b, 0x0000 }, /* R3723 (0xe8b) - DRC2 ctrl4 */
+	{ 0x00000e8c, 0x0000 }, /* R3724 (0xe8c) - DRC2 ctrl5 */
+	{ 0x00000ec0, 0x0000 }, /* R3776 (0xec0) - HPLPF1_1 */
+	{ 0x00000ec1, 0x0000 }, /* R3777 (0xec1) - HPLPF1_2 */
+	{ 0x00000ec4, 0x0000 }, /* R3780 (0xec4) - HPLPF2_1 */
+	{ 0x00000ec5, 0x0000 }, /* R3781 (0xec5) - HPLPF2_2 */
+	{ 0x00000ec8, 0x0000 }, /* R3784 (0xec8) - HPLPF3_1 */
+	{ 0x00000ec9, 0x0000 }, /* R3785 (0xec9) - HPLPF3_2 */
+	{ 0x00000ecc, 0x0000 }, /* R3788 (0xecc) - HPLPF4_1 */
+	{ 0x00000ecd, 0x0000 }, /* R3789 (0xecd) - HPLPF4_2 */
+	{ 0x00000ed0, 0x0000 }, /* R3792 (0xed0) - ASRC2_ENABLE */
+	{ 0x00000ed2, 0x0000 }, /* R3794 (0xed2) - ASRC2_RATE1 */
+	{ 0x00000ed3, 0x4000 }, /* R3795 (0xed3) - ASRC2_RATE2 */
+	{ 0x00000ee0, 0x0000 }, /* R3808 (0xee0) - ASRC1_ENABLE */
+	{ 0x00000ee2, 0x0000 }, /* R3810 (0xee2) - ASRC1_RATE1 */
+	{ 0x00000ee3, 0x4000 }, /* R3811 (0xee3) - ASRC1_RATE2 */
+	{ 0x00000ef0, 0x0000 }, /* R3824 (0xef0) - ISRC 1 CTRL 1 */
+	{ 0x00000ef1, 0x0001 }, /* R3825 (0xef1) - ISRC 1 CTRL 2 */
+	{ 0x00000ef2, 0x0000 }, /* R3826 (0xef2) - ISRC 1 CTRL 3 */
+	{ 0x00000ef3, 0x0000 }, /* R3827 (0xef3) - ISRC 2 CTRL 1 */
+	{ 0x00000ef4, 0x0001 }, /* R3828 (0xef4) - ISRC 2 CTRL 2 */
+	{ 0x00000ef5, 0x0000 }, /* R3829 (0xef5) - ISRC 2 CTRL 3 */
+	{ 0x00000ef6, 0x0000 }, /* R3830 (0xef6) - ISRC 3 CTRL 1 */
+	{ 0x00000ef7, 0x0001 }, /* R3831 (0xef7) - ISRC 3 CTRL 2 */
+	{ 0x00000ef8, 0x0000 }, /* R3832 (0xef8) - ISRC 3 CTRL 3 */
+	{ 0x00000ef9, 0x0000 }, /* R3833 (0xef9) - ISRC 4 CTRL 1 */
+	{ 0x00000efa, 0x0001 }, /* R3834 (0xefa) - ISRC 4 CTRL 2 */
+	{ 0x00000efb, 0x0000 }, /* R3835 (0xefb) - ISRC 4 CTRL 3 */
+	{ 0x00000f01, 0x0000 }, /* R3841 (0xf01) - ANC_SRC */
+	{ 0x00000f02, 0x0000 }, /* R3842 (0xf02) - DSP Status */
+	{ 0x00000f08, 0x001c }, /* R3848 (0xf08) - ANC Coefficient */
+	{ 0x00000f09, 0x0000 }, /* R3849 (0xf09) - ANC Coefficient */
+	{ 0x00000f0a, 0x0000 }, /* R3850 (0xf0a) - ANC Coefficient */
+	{ 0x00000f0b, 0x0000 }, /* R3851 (0xf0b) - ANC Coefficient */
+	{ 0x00000f0c, 0x0000 }, /* R3852 (0xf0c) - ANC Coefficient */
+	{ 0x00000f0d, 0x0000 }, /* R3853 (0xf0d) - ANC Coefficient */
+	{ 0x00000f0e, 0x0000 }, /* R3854 (0xf0e) - ANC Coefficient */
+	{ 0x00000f0f, 0x0000 }, /* R3855 (0xf0f) - ANC Coefficient */
+	{ 0x00000f10, 0x0000 }, /* R3856 (0xf10) - ANC Coefficient */
+	{ 0x00000f11, 0x0000 }, /* R3857 (0xf11) - ANC Coefficient */
+	{ 0x00000f12, 0x0000 }, /* R3858 (0xf12) - ANC Coefficient */
+	{ 0x00000f15, 0x0000 }, /* R3861 (0xf15) - FCL Filter Control */
+	{ 0x00000f17, 0x0004 }, /* R3863 (0xf17) - FCL ADC Reformatter Control */
+	{ 0x00000f18, 0x0004 }, /* R3864 (0xf18) - ANC Coefficient */
+	{ 0x00000f19, 0x0002 }, /* R3865 (0xf19) - ANC Coefficient */
+	{ 0x00000f1a, 0x0000 }, /* R3866 (0xf1a) - ANC Coefficient */
+	{ 0x00000f1b, 0x0010 }, /* R3867 (0xf1b) - ANC Coefficient */
+	{ 0x00000f1c, 0x0000 }, /* R3868 (0xf1c) - ANC Coefficient */
+	{ 0x00000f1d, 0x0000 }, /* R3869 (0xf1d) - ANC Coefficient */
+	{ 0x00000f1e, 0x0000 }, /* R3870 (0xf1e) - ANC Coefficient */
+	{ 0x00000f1f, 0x0000 }, /* R3871 (0xf1f) - ANC Coefficient */
+	{ 0x00000f20, 0x0000 }, /* R3872 (0xf20) - ANC Coefficient */
+	{ 0x00000f21, 0x0000 }, /* R3873 (0xf21) - ANC Coefficient */
+	{ 0x00000f22, 0x0000 }, /* R3874 (0xf22) - ANC Coefficient */
+	{ 0x00000f23, 0x0000 }, /* R3875 (0xf23) - ANC Coefficient */
+	{ 0x00000f24, 0x0000 }, /* R3876 (0xf24) - ANC Coefficient */
+	{ 0x00000f25, 0x0000 }, /* R3877 (0xf25) - ANC Coefficient */
+	{ 0x00000f26, 0x0000 }, /* R3878 (0xf26) - ANC Coefficient */
+	{ 0x00000f27, 0x0000 }, /* R3879 (0xf27) - ANC Coefficient */
+	{ 0x00000f28, 0x0000 }, /* R3880 (0xf28) - ANC Coefficient */
+	{ 0x00000f29, 0x0000 }, /* R3881 (0xf29) - ANC Coefficient */
+	{ 0x00000f2a, 0x0000 }, /* R3882 (0xf2a) - ANC Coefficient */
+	{ 0x00000f2b, 0x0000 }, /* R3883 (0xf2b) - ANC Coefficient */
+	{ 0x00000f2c, 0x0000 }, /* R3884 (0xf2c) - ANC Coefficient */
+	{ 0x00000f2d, 0x0000 }, /* R3885 (0xf2d) - ANC Coefficient */
+	{ 0x00000f2e, 0x0000 }, /* R3886 (0xf2e) - ANC Coefficient */
+	{ 0x00000f2f, 0x0000 }, /* R3887 (0xf2f) - ANC Coefficient */
+	{ 0x00000f30, 0x0000 }, /* R3888 (0xf30) - ANC Coefficient */
+	{ 0x00000f31, 0x0000 }, /* R3889 (0xf31) - ANC Coefficient */
+	{ 0x00000f32, 0x0000 }, /* R3890 (0xf32) - ANC Coefficient */
+	{ 0x00000f33, 0x0000 }, /* R3891 (0xf33) - ANC Coefficient */
+	{ 0x00000f34, 0x0000 }, /* R3892 (0xf34) - ANC Coefficient */
+	{ 0x00000f35, 0x0000 }, /* R3893 (0xf35) - ANC Coefficient */
+	{ 0x00000f36, 0x0000 }, /* R3894 (0xf36) - ANC Coefficient */
+	{ 0x00000f37, 0x0000 }, /* R3895 (0xf37) - ANC Coefficient */
+	{ 0x00000f38, 0x0000 }, /* R3896 (0xf38) - ANC Coefficient */
+	{ 0x00000f39, 0x0000 }, /* R3897 (0xf39) - ANC Coefficient */
+	{ 0x00000f3a, 0x0000 }, /* R3898 (0xf3a) - ANC Coefficient */
+	{ 0x00000f3b, 0x0000 }, /* R3899 (0xf3b) - ANC Coefficient */
+	{ 0x00000f3c, 0x0000 }, /* R3900 (0xf3c) - ANC Coefficient */
+	{ 0x00000f3d, 0x0000 }, /* R3901 (0xf3d) - ANC Coefficient */
+	{ 0x00000f3e, 0x0000 }, /* R3902 (0xf3e) - ANC Coefficient */
+	{ 0x00000f3f, 0x0000 }, /* R3903 (0xf3f) - ANC Coefficient */
+	{ 0x00000f40, 0x0000 }, /* R3904 (0xf40) - ANC Coefficient */
+	{ 0x00000f41, 0x0000 }, /* R3905 (0xf41) - ANC Coefficient */
+	{ 0x00000f42, 0x0000 }, /* R3906 (0xf42) - ANC Coefficient */
+	{ 0x00000f43, 0x0000 }, /* R3907 (0xf43) - ANC Coefficient */
+	{ 0x00000f44, 0x0000 }, /* R3908 (0xf44) - ANC Coefficient */
+	{ 0x00000f45, 0x0000 }, /* R3909 (0xf45) - ANC Coefficient */
+	{ 0x00000f46, 0x0000 }, /* R3910 (0xf46) - ANC Coefficient */
+	{ 0x00000f47, 0x0000 }, /* R3911 (0xf47) - ANC Coefficient */
+	{ 0x00000f48, 0x0000 }, /* R3912 (0xf48) - ANC Coefficient */
+	{ 0x00000f49, 0x0000 }, /* R3913 (0xf49) - ANC Coefficient */
+	{ 0x00000f4a, 0x0000 }, /* R3914 (0xf4a) - ANC Coefficient */
+	{ 0x00000f4b, 0x0000 }, /* R3915 (0xf4b) - ANC Coefficient */
+	{ 0x00000f4c, 0x0000 }, /* R3916 (0xf4c) - ANC Coefficient */
+	{ 0x00000f4d, 0x0000 }, /* R3917 (0xf4d) - ANC Coefficient */
+	{ 0x00000f4e, 0x0000 }, /* R3918 (0xf4e) - ANC Coefficient */
+	{ 0x00000f4f, 0x0000 }, /* R3919 (0xf4f) - ANC Coefficient */
+	{ 0x00000f50, 0x0000 }, /* R3920 (0xf50) - ANC Coefficient */
+	{ 0x00000f51, 0x0000 }, /* R3921 (0xf51) - ANC Coefficient */
+	{ 0x00000f52, 0x0000 }, /* R3922 (0xf52) - ANC Coefficient */
+	{ 0x00000f53, 0x0000 }, /* R3923 (0xf53) - ANC Coefficient */
+	{ 0x00000f54, 0x0000 }, /* R3924 (0xf54) - ANC Coefficient */
+	{ 0x00000f55, 0x0000 }, /* R3925 (0xf55) - ANC Coefficient */
+	{ 0x00000f56, 0x0000 }, /* R3926 (0xf56) - ANC Coefficient */
+	{ 0x00000f57, 0x0000 }, /* R3927 (0xf57) - ANC Coefficient */
+	{ 0x00000f58, 0x0000 }, /* R3928 (0xf58) - ANC Coefficient */
+	{ 0x00000f59, 0x0000 }, /* R3929 (0xf59) - ANC Coefficient */
+	{ 0x00000f5a, 0x0000 }, /* R3930 (0xf5a) - ANC Coefficient */
+	{ 0x00000f5b, 0x0000 }, /* R3931 (0xf5b) - ANC Coefficient */
+	{ 0x00000f5c, 0x0000 }, /* R3932 (0xf5c) - ANC Coefficient */
+	{ 0x00000f5d, 0x0000 }, /* R3933 (0xf5d) - ANC Coefficient */
+	{ 0x00000f5e, 0x0000 }, /* R3934 (0xf5e) - ANC Coefficient */
+	{ 0x00000f5f, 0x0000 }, /* R3935 (0xf5f) - ANC Coefficient */
+	{ 0x00000f60, 0x0000 }, /* R3936 (0xf60) - ANC Coefficient */
+	{ 0x00000f61, 0x0000 }, /* R3937 (0xf61) - ANC Coefficient */
+	{ 0x00000f62, 0x0000 }, /* R3938 (0xf62) - ANC Coefficient */
+	{ 0x00000f63, 0x0000 }, /* R3939 (0xf63) - ANC Coefficient */
+	{ 0x00000f64, 0x0000 }, /* R3940 (0xf64) - ANC Coefficient */
+	{ 0x00000f65, 0x0000 }, /* R3941 (0xf65) - ANC Coefficient */
+	{ 0x00000f66, 0x0000 }, /* R3942 (0xf66) - ANC Coefficient */
+	{ 0x00000f67, 0x0000 }, /* R3943 (0xf67) - ANC Coefficient */
+	{ 0x00000f68, 0x0000 }, /* R3944 (0xf68) - ANC Coefficient */
+	{ 0x00000f69, 0x0000 }, /* R3945 (0xf69) - ANC Coefficient */
+	{ 0x00000f71, 0x0000 }, /* R3953 (0xf71) - FCR Filter Control */
+	{ 0x00000f73, 0x0004 }, /* R3955 (0xf73) - FCR ADC Reformatter Control */
+	{ 0x00000f74, 0x0004 }, /* R3956 (0xf74) - ANC Coefficient */
+	{ 0x00000f75, 0x0002 }, /* R3957 (0xf75) - ANC Coefficient */
+	{ 0x00000f76, 0x0000 }, /* R3958 (0xf76) - ANC Coefficient */
+	{ 0x00000f77, 0x0010 }, /* R3959 (0xf77) - ANC Coefficient */
+	{ 0x00000f78, 0x0000 }, /* R3960 (0xf78) - ANC Coefficient */
+	{ 0x00000f79, 0x0000 }, /* R3961 (0xf79) - ANC Coefficient */
+	{ 0x00000f7a, 0x0000 }, /* R3962 (0xf7a) - ANC Coefficient */
+	{ 0x00000f7b, 0x0000 }, /* R3963 (0xf7b) - ANC Coefficient */
+	{ 0x00000f7c, 0x0000 }, /* R3964 (0xf7c) - ANC Coefficient */
+	{ 0x00000f7d, 0x0000 }, /* R3965 (0xf7d) - ANC Coefficient */
+	{ 0x00000f7e, 0x0000 }, /* R3966 (0xf7e) - ANC Coefficient */
+	{ 0x00000f7f, 0x0000 }, /* R3967 (0xf7f) - ANC Coefficient */
+	{ 0x00000f80, 0x0000 }, /* R3968 (0xf80) - ANC Coefficient */
+	{ 0x00000f81, 0x0000 }, /* R3969 (0xf81) - ANC Coefficient */
+	{ 0x00000f82, 0x0000 }, /* R3970 (0xf82) - ANC Coefficient */
+	{ 0x00000f83, 0x0000 }, /* R3971 (0xf83) - ANC Coefficient */
+	{ 0x00000f84, 0x0000 }, /* R3972 (0xf84) - ANC Coefficient */
+	{ 0x00000f85, 0x0000 }, /* R3973 (0xf85) - ANC Coefficient */
+	{ 0x00000f86, 0x0000 }, /* R3974 (0xf86) - ANC Coefficient */
+	{ 0x00000f87, 0x0000 }, /* R3975 (0xf87) - ANC Coefficient */
+	{ 0x00000f88, 0x0000 }, /* R3976 (0xf88) - ANC Coefficient */
+	{ 0x00000f89, 0x0000 }, /* R3977 (0xf89) - ANC Coefficient */
+	{ 0x00000f8a, 0x0000 }, /* R3978 (0xf8a) - ANC Coefficient */
+	{ 0x00000f8b, 0x0000 }, /* R3979 (0xf8b) - ANC Coefficient */
+	{ 0x00000f8c, 0x0000 }, /* R3980 (0xf8c) - ANC Coefficient */
+	{ 0x00000f8d, 0x0000 }, /* R3981 (0xf8d) - ANC Coefficient */
+	{ 0x00000f8e, 0x0000 }, /* R3982 (0xf8e) - ANC Coefficient */
+	{ 0x00000f8f, 0x0000 }, /* R3983 (0xf8f) - ANC Coefficient */
+	{ 0x00000f90, 0x0000 }, /* R3984 (0xf90) - ANC Coefficient */
+	{ 0x00000f91, 0x0000 }, /* R3985 (0xf91) - ANC Coefficient */
+	{ 0x00000f92, 0x0000 }, /* R3986 (0xf92) - ANC Coefficient */
+	{ 0x00000f93, 0x0000 }, /* R3987 (0xf93) - ANC Coefficient */
+	{ 0x00000f94, 0x0000 }, /* R3988 (0xf94) - ANC Coefficient */
+	{ 0x00000f95, 0x0000 }, /* R3989 (0xf95) - ANC Coefficient */
+	{ 0x00000f96, 0x0000 }, /* R3990 (0xf96) - ANC Coefficient */
+	{ 0x00000f97, 0x0000 }, /* R3991 (0xf97) - ANC Coefficient */
+	{ 0x00000f98, 0x0000 }, /* R3992 (0xf98) - ANC Coefficient */
+	{ 0x00000f99, 0x0000 }, /* R3993 (0xf99) - ANC Coefficient */
+	{ 0x00000f9a, 0x0000 }, /* R3994 (0xf9a) - ANC Coefficient */
+	{ 0x00000f9b, 0x0000 }, /* R3995 (0xf9b) - ANC Coefficient */
+	{ 0x00000f9c, 0x0000 }, /* R3996 (0xf9c) - ANC Coefficient */
+	{ 0x00000f9d, 0x0000 }, /* R3997 (0xf9d) - ANC Coefficient */
+	{ 0x00000f9e, 0x0000 }, /* R3998 (0xf9e) - ANC Coefficient */
+	{ 0x00000f9f, 0x0000 }, /* R3999 (0xf9f) - ANC Coefficient */
+	{ 0x00000fa0, 0x0000 }, /* R4000 (0xfa0) - ANC Coefficient */
+	{ 0x00000fa1, 0x0000 }, /* R4001 (0xfa1) - ANC Coefficient */
+	{ 0x00000fa2, 0x0000 }, /* R4002 (0xfa2) - ANC Coefficient */
+	{ 0x00000fa3, 0x0000 }, /* R4003 (0xfa3) - ANC Coefficient */
+	{ 0x00000fa4, 0x0000 }, /* R4004 (0xfa4) - ANC Coefficient */
+	{ 0x00000fa5, 0x0000 }, /* R4005 (0xfa5) - ANC Coefficient */
+	{ 0x00000fa6, 0x0000 }, /* R4006 (0xfa6) - ANC Coefficient */
+	{ 0x00000fa7, 0x0000 }, /* R4007 (0xfa7) - ANC Coefficient */
+	{ 0x00000fa8, 0x0000 }, /* R4008 (0xfa8) - ANC Coefficient */
+	{ 0x00000fa9, 0x0000 }, /* R4009 (0xfa9) - ANC Coefficient */
+	{ 0x00000faa, 0x0000 }, /* R4010 (0xfaa) - ANC Coefficient */
+	{ 0x00000fab, 0x0000 }, /* R4011 (0xfab) - ANC Coefficient */
+	{ 0x00000fac, 0x0000 }, /* R4012 (0xfac) - ANC Coefficient */
+	{ 0x00000fad, 0x0000 }, /* R4013 (0xfad) - ANC Coefficient */
+	{ 0x00000fae, 0x0000 }, /* R4014 (0xfae) - ANC Coefficient */
+	{ 0x00000faf, 0x0000 }, /* R4015 (0xfaf) - ANC Coefficient */
+	{ 0x00000fb0, 0x0000 }, /* R4016 (0xfb0) - ANC Coefficient */
+	{ 0x00000fb1, 0x0000 }, /* R4017 (0xfb1) - ANC Coefficient */
+	{ 0x00000fb2, 0x0000 }, /* R4018 (0xfb2) - ANC Coefficient */
+	{ 0x00000fb3, 0x0000 }, /* R4019 (0xfb3) - ANC Coefficient */
+	{ 0x00000fb4, 0x0000 }, /* R4020 (0xfb4) - ANC Coefficient */
+	{ 0x00000fb5, 0x0000 }, /* R4021 (0xfb5) - ANC Coefficient */
+	{ 0x00000fb6, 0x0000 }, /* R4022 (0xfb6) - ANC Coefficient */
+	{ 0x00000fb7, 0x0000 }, /* R4023 (0xfb7) - ANC Coefficient */
+	{ 0x00000fb8, 0x0000 }, /* R4024 (0xfb8) - ANC Coefficient */
+	{ 0x00000fb9, 0x0000 }, /* R4025 (0xfb9) - ANC Coefficient */
+	{ 0x00000fba, 0x0000 }, /* R4026 (0xfba) - ANC Coefficient */
+	{ 0x00000fbb, 0x0000 }, /* R4027 (0xfbb) - ANC Coefficient */
+	{ 0x00000fbc, 0x0000 }, /* R4028 (0xfbc) - ANC Coefficient */
+	{ 0x00000fbd, 0x0000 }, /* R4029 (0xfbd) - ANC Coefficient */
+	{ 0x00000fbe, 0x0000 }, /* R4030 (0xfbe) - ANC Coefficient */
+	{ 0x00000fbf, 0x0000 }, /* R4031 (0xfbf) - ANC Coefficient */
+	{ 0x00000fc0, 0x0000 }, /* R4032 (0xfc0) - ANC Coefficient */
+	{ 0x00000fc1, 0x0000 }, /* R4033 (0xfc1) - ANC Coefficient */
+	{ 0x00000fc2, 0x0000 }, /* R4034 (0xfc2) - ANC Coefficient */
+	{ 0x00000fc3, 0x0000 }, /* R4035 (0xfc3) - ANC Coefficient */
+	{ 0x00000fc4, 0x0000 }, /* R4036 (0xfc4) - ANC Coefficient */
+	{ 0x00000fc5, 0x0000 }, /* R4037 (0xfc5) - ANC Coefficient */
+	{ 0x00001300, 0x050E }, /* R4864 (0x1300) - DAC Comp 1 */
+	{ 0x00001302, 0x0101 }, /* R4866 (0x1302) - DAC Comp 2 */
+	{ 0x00001380, 0x0425 }, /* R4992 (0x1380) - FRF Coefficient 1L 1 */
+	{ 0x00001381, 0xF6D8 }, /* R4993 (0x1381) - FRF Coefficient 1L 2 */
+	{ 0x00001382, 0x0632 }, /* R4994 (0x1382) - FRF Coefficient 1L 3 */
+	{ 0x00001383, 0xFEC8 }, /* R4995 (0x1383) - FRF Coefficient 1L 4 */
+	{ 0x00001390, 0x042F }, /* R5008 (0x1390) - FRF Coefficient 1R 1 */
+	{ 0x00001391, 0xF6CA }, /* R5009 (0x1391) - FRF Coefficient 1R 2 */
+	{ 0x00001392, 0x0637 }, /* R5010 (0x1392) - FRF Coefficient 1R 3 */
+	{ 0x00001393, 0xFEC8 }, /* R5011 (0x1393) - FRF Coefficient 1R 4 */
+	{ 0x000013a0, 0x0000 }, /* R5024 (0x13a0) - FRF Coefficient 2L 1 */
+	{ 0x000013a1, 0x0000 }, /* R5025 (0x13a1) - FRF Coefficient 2L 2 */
+	{ 0x000013a2, 0x0000 }, /* R5026 (0x13a2) - FRF Coefficient 2L 3 */
+	{ 0x000013a3, 0x0000 }, /* R5027 (0x13a3) - FRF Coefficient 2L 4 */
+	{ 0x000013b0, 0x0000 }, /* R5040 (0x13b0) - FRF Coefficient 2R 1 */
+	{ 0x000013b1, 0x0000 }, /* R5041 (0x13b1) - FRF Coefficient 2R 2 */
+	{ 0x000013b2, 0x0000 }, /* R5042 (0x13b2) - FRF Coefficient 2R 3 */
+	{ 0x000013b3, 0x0000 }, /* R5043 (0x13b3) - FRF Coefficient 2R 4 */
+	{ 0x000013c0, 0x0000 }, /* R5040 (0x13c0) - FRF Coefficient 3L 1 */
+	{ 0x000013c1, 0x0000 }, /* R5041 (0x13c1) - FRF Coefficient 3L 2 */
+	{ 0x000013c2, 0x0000 }, /* R5042 (0x13c2) - FRF Coefficient 3L 3 */
+	{ 0x000013c3, 0x0000 }, /* R5043 (0x13c3) - FRF Coefficient 3L 4 */
+	{ 0x000013d0, 0x0000 }, /* R5072 (0x13d0) - FRF Coefficient 3R 1 */
+	{ 0x000013d1, 0x0000 }, /* R5073 (0x13d1) - FRF Coefficient 3R 2 */
+	{ 0x000013d2, 0x0000 }, /* R5074 (0x13d2) - FRF Coefficient 3R 3 */
+	{ 0x000013d3, 0x0000 }, /* R5075 (0x13d3) - FRF Coefficient 3R 4 */
+	{ 0x00001400, 0x0000 }, /* R5120 (0x1400) - FRF Coefficient 5L 1 */
+	{ 0x00001401, 0x0000 }, /* R5121 (0x1401) - FRF Coefficient 5L 2 */
+	{ 0x00001402, 0x0000 }, /* R5122 (0x1402) - FRF Coefficient 5L 3 */
+	{ 0x00001403, 0x0000 }, /* R5123 (0x1403) - FRF Coefficient 5L 4 */
+	{ 0x00001410, 0x0000 }, /* R5136 (0x1410) - FRF Coefficient 5R 1 */
+	{ 0x00001411, 0x0000 }, /* R5137 (0x1411) - FRF Coefficient 5R 2 */
+	{ 0x00001412, 0x0000 }, /* R5138 (0x1412) - FRF Coefficient 5R 3 */
+	{ 0x00001413, 0x0000 }, /* R5139 (0x1413) - FRF Coefficient 5R 4 */
+	{ 0x00001480, 0x0000 }, /* R5248 (0x1480) - DFC1_CTRL */
+	{ 0x00001482, 0x1f00 }, /* R5250 (0x1482) - DFC1_RX */
+	{ 0x00001484, 0x1f00 }, /* R5252 (0x1486) - DFC1_TX */
+	{ 0x00001486, 0x0000 }, /* R5254 (0x1486) - DFC2_CTRL */
+	{ 0x00001488, 0x1f00 }, /* R5256 (0x1488) - DFC2_RX */
+	{ 0x0000148a, 0x1f00 }, /* R5258 (0x148a) - DFC2_TX */
+	{ 0x0000148c, 0x0000 }, /* R5260 (0x148c) - DFC3_CTRL */
+	{ 0x0000148e, 0x1f00 }, /* R5262 (0x148e) - DFC3_RX */
+	{ 0x00001490, 0x1f00 }, /* R5264 (0x1490) - DFC3_TX */
+	{ 0x00001492, 0x0000 }, /* R5266 (0x1492) - DFC4_CTRL */
+	{ 0x00001494, 0x1f00 }, /* R5268 (0x1494) - DFC4_RX */
+	{ 0x00001496, 0x1f00 }, /* R5270 (0x1496) - DFC4_TX */
+	{ 0x00001498, 0x0000 }, /* R5272 (0x1498) - DFC5_CTRL */
+	{ 0x0000149a, 0x1f00 }, /* R5274 (0x149a) - DFC5_RX */
+	{ 0x0000149c, 0x1f00 }, /* R5276 (0x149c) - DFC5_TX */
+	{ 0x0000149e, 0x0000 }, /* R5278 (0x149e) - DFC6_CTRL */
+	{ 0x000014a0, 0x1f00 }, /* R5280 (0x14a0) - DFC6_RX */
+	{ 0x000014a2, 0x1f00 }, /* R5282 (0x14a2) - DFC6_TX */
+	{ 0x000014a4, 0x0000 }, /* R5284 (0x14a4) - DFC7_CTRL */
+	{ 0x000014a6, 0x1f00 }, /* R5286 (0x14a6) - DFC7_RX */
+	{ 0x000014a8, 0x1f00 }, /* R5288 (0x14a8) - DFC7_TX */
+	{ 0x000014aa, 0x0000 }, /* R5290 (0x14aa) - DFC8_CTRL */
+	{ 0x000014ac, 0x1f00 }, /* R5292 (0x14ac) - DFC8_RX */
+	{ 0x000014ae, 0x1f00 }, /* R5294 (0x14ae) - DFC8_TX */
+	{ 0x00001700, 0x2001 }, /* R5888 (0x1700) - GPIO1 Control 1 */
+	{ 0x00001701, 0xf000 }, /* R5889 (0x1701) - GPIO1 Control 2 */
+	{ 0x00001702, 0x2001 }, /* R5890 (0x1702) - GPIO2 Control 1 */
+	{ 0x00001703, 0xf000 }, /* R5891 (0x1702) - GPIO2 Control 2 */
+	{ 0x00001704, 0x2001 }, /* R5892 (0x1704) - GPIO3 Control 1 */
+	{ 0x00001705, 0xf000 }, /* R5893 (0x1705) - GPIO3 Control 2 */
+	{ 0x00001706, 0x2001 }, /* R5894 (0x1706) - GPIO4 Control 1 */
+	{ 0x00001707, 0xf000 }, /* R5895 (0x1707) - GPIO4 Control 2 */
+	{ 0x00001708, 0x2001 }, /* R5896 (0x1708) - GPIO5 Control 1 */
+	{ 0x00001709, 0xf000 }, /* R5897 (0x1709) - GPIO5 Control 2 */
+	{ 0x0000170a, 0x2001 }, /* R5898 (0x170a) - GPIO6 Control 1 */
+	{ 0x0000170b, 0xf000 }, /* R5899 (0x170b) - GPIO6 Control 2 */
+	{ 0x0000170c, 0x2001 }, /* R5900 (0x170c) - GPIO7 Control 1 */
+	{ 0x0000170d, 0xf000 }, /* R5901 (0x170d) - GPIO7 Control 2 */
+	{ 0x0000170e, 0x2001 }, /* R5902 (0x170e) - GPIO8 Control 1 */
+	{ 0x0000170f, 0xf000 }, /* R5903 (0x170f) - GPIO8 Control 2 */
+	{ 0x00001710, 0x2001 }, /* R5904 (0x1710) - GPIO9 Control 1 */
+	{ 0x00001711, 0xf000 }, /* R5905 (0x1711) - GPIO9 Control 2 */
+	{ 0x00001712, 0x2001 }, /* R5906 (0x1712) - GPIO10 Control 1 */
+	{ 0x00001713, 0xf000 }, /* R5907 (0x1713) - GPIO10 Control 2 */
+	{ 0x00001714, 0x2001 }, /* R5908 (0x1714) - GPIO11 Control 1 */
+	{ 0x00001715, 0xf000 }, /* R5909 (0x1715) - GPIO11 Control 2 */
+	{ 0x00001716, 0x2001 }, /* R5910 (0x1716) - GPIO12 Control 1 */
+	{ 0x00001717, 0xf000 }, /* R5911 (0x1717) - GPIO12 Control 2 */
+	{ 0x00001718, 0x2001 }, /* R5912 (0x1718) - GPIO13 Control 1 */
+	{ 0x00001719, 0xf000 }, /* R5913 (0x1719) - GPIO13 Control 2 */
+	{ 0x0000171a, 0x2001 }, /* R5914 (0x171a) - GPIO14 Control 1 */
+	{ 0x0000171b, 0xf000 }, /* R5915 (0x171b) - GPIO14 Control 2 */
+	{ 0x0000171c, 0x2001 }, /* R5916 (0x171c) - GPIO15 Control 1 */
+	{ 0x0000171d, 0xf000 }, /* R5917 (0x171d) - GPIO15 Control 2 */
+	{ 0x0000171e, 0x2001 }, /* R5918 (0x171e) - GPIO16 Control 1 */
+	{ 0x0000171f, 0xf000 }, /* R5919 (0x171f) - GPIO16 Control 2 */
+	{ 0x00001720, 0x2001 }, /* R5920 (0x1720) - GPIO17 Control 1 */
+	{ 0x00001721, 0xf000 }, /* R5921 (0x1721) - GPIO17 Control 2 */
+	{ 0x00001722, 0x2001 }, /* R5922 (0x1722) - GPIO18 Control 1 */
+	{ 0x00001723, 0xf000 }, /* R5923 (0x1723) - GPIO18 Control 2 */
+	{ 0x00001724, 0x2001 }, /* R5924 (0x1724) - GPIO19 Control 1 */
+	{ 0x00001725, 0xf000 }, /* R5925 (0x1725) - GPIO19 Control 2 */
+	{ 0x00001726, 0x2001 }, /* R5926 (0x1726) - GPIO20 Control 1 */
+	{ 0x00001727, 0xf000 }, /* R5927 (0x1727) - GPIO20 Control 2 */
+	{ 0x00001728, 0x2001 }, /* R5928 (0x1728) - GPIO21 Control 1 */
+	{ 0x00001729, 0xf000 }, /* R5929 (0x1729) - GPIO21 Control 2 */
+	{ 0x0000172a, 0x2001 }, /* R5930 (0x172a) - GPIO22 Control 1 */
+	{ 0x0000172b, 0xf000 }, /* R5931 (0x172b) - GPIO22 Control 2 */
+	{ 0x0000172c, 0x2001 }, /* R5932 (0x172c) - GPIO23 Control 1 */
+	{ 0x0000172d, 0xf000 }, /* R5933 (0x172d) - GPIO23 Control 2 */
+	{ 0x0000172e, 0x2001 }, /* R5934 (0x172e) - GPIO24 Control 1 */
+	{ 0x0000172f, 0xf000 }, /* R5935 (0x172f) - GPIO24 Control 2 */
+	{ 0x00001730, 0x2001 }, /* R5936 (0x1730) - GPIO25 Control 1 */
+	{ 0x00001731, 0xf000 }, /* R5937 (0x1731) - GPIO25 Control 2 */
+	{ 0x00001732, 0x2001 }, /* R5938 (0x1732) - GPIO26 Control 1 */
+	{ 0x00001733, 0xf000 }, /* R5939 (0x1733) - GPIO26 Control 2 */
+	{ 0x00001734, 0x2001 }, /* R5940 (0x1734) - GPIO27 Control 1 */
+	{ 0x00001735, 0xf000 }, /* R5941 (0x1735) - GPIO27 Control 2 */
+	{ 0x00001736, 0x2001 }, /* R5942 (0x1736) - GPIO28 Control 1 */
+	{ 0x00001737, 0xf000 }, /* R5943 (0x1737) - GPIO28 Control 2 */
+	{ 0x00001738, 0x2001 }, /* R5944 (0x1738) - GPIO29 Control 1 */
+	{ 0x00001739, 0xf000 }, /* R5945 (0x1739) - GPIO29 Control 2 */
+	{ 0x0000173a, 0x2001 }, /* R5946 (0x173a) - GPIO30 Control 1 */
+	{ 0x0000173b, 0xf000 }, /* R5947 (0x173b) - GPIO30 Control 2 */
+	{ 0x0000173c, 0x2001 }, /* R5948 (0x173c) - GPIO31 Control 1 */
+	{ 0x0000173d, 0xf000 }, /* R5949 (0x173d) - GPIO31 Control 2 */
+	{ 0x0000173e, 0x2001 }, /* R5950 (0x173e) - GPIO32 Control 1 */
+	{ 0x0000173f, 0xf000 }, /* R5951 (0x173f) - GPIO32 Control 2 */
+	{ 0x00001740, 0x2001 }, /* R5952 (0x1740) - GPIO33 Control 1 */
+	{ 0x00001741, 0xf000 }, /* R5953 (0x1741) - GPIO33 Control 2 */
+	{ 0x00001742, 0x2001 }, /* R5954 (0x1742) - GPIO34 Control 1 */
+	{ 0x00001743, 0xf000 }, /* R5955 (0x1743) - GPIO34 Control 2 */
+	{ 0x00001744, 0x2001 }, /* R5956 (0x1744) - GPIO35 Control 1 */
+	{ 0x00001745, 0xf000 }, /* R5957 (0x1745) - GPIO35 Control 2 */
+	{ 0x00001746, 0x2001 }, /* R5958 (0x1746) - GPIO36 Control 1 */
+	{ 0x00001747, 0xf000 }, /* R5959 (0x1747) - GPIO36 Control 2 */
+	{ 0x00001748, 0x2001 }, /* R5960 (0x1748) - GPIO37 Control 1 */
+	{ 0x00001749, 0xf000 }, /* R5961 (0x1749) - GPIO37 Control 2 */
+	{ 0x0000174a, 0x2001 }, /* R5962 (0x174a) - GPIO38 Control 1 */
+	{ 0x0000174b, 0xf000 }, /* R5963 (0x174b) - GPIO38 Control 2 */
+	{ 0x00001840, 0xffff }, /* R6208 (0x1840) - IRQ1 Mask 1 */
+	{ 0x00001841, 0xffff }, /* R6209 (0x1841) - IRQ1 Mask 2 */
+	{ 0x00001842, 0xffff }, /* R6210 (0x1842) - IRQ1 Mask 3 */
+	{ 0x00001843, 0xffff }, /* R6211 (0x1843) - IRQ1 Mask 4 */
+	{ 0x00001844, 0xffff }, /* R6212 (0x1844) - IRQ1 Mask 5 */
+	{ 0x00001845, 0xffff }, /* R6213 (0x1845) - IRQ1 Mask 6 */
+	{ 0x00001846, 0xffff }, /* R6214 (0x1846) - IRQ1 Mask 7 */
+	{ 0x00001847, 0xffff }, /* R6215 (0x1847) - IRQ1 Mask 8 */
+	{ 0x00001848, 0xffff }, /* R6216 (0x1848) - IRQ1 Mask 9 */
+	{ 0x00001849, 0xffff }, /* R6217 (0x1849) - IRQ1 Mask 10 */
+	{ 0x0000184a, 0xffff }, /* R6218 (0x184a) - IRQ1 Mask 11 */
+	{ 0x0000184b, 0xffff }, /* R6219 (0x184b) - IRQ1 Mask 12 */
+	{ 0x0000184c, 0xffff }, /* R6220 (0x184c) - IRQ1 Mask 13 */
+	{ 0x0000184d, 0xffff }, /* R6221 (0x184d) - IRQ1 Mask 14 */
+	{ 0x0000184e, 0xffff }, /* R6222 (0x184e) - IRQ1 Mask 15 */
+	{ 0x0000184f, 0xffff }, /* R6223 (0x184f) - IRQ1 Mask 16 */
+	{ 0x00001850, 0xffff }, /* R6224 (0x1850) - IRQ1 Mask 17 */
+	{ 0x00001851, 0xffff }, /* R6225 (0x1851) - IRQ1 Mask 18 */
+	{ 0x00001852, 0xffff }, /* R6226 (0x1852) - IRQ1 Mask 19 */
+	{ 0x00001853, 0xffff }, /* R6227 (0x1853) - IRQ1 Mask 20 */
+	{ 0x00001854, 0xffff }, /* R6228 (0x1854) - IRQ1 Mask 21 */
+	{ 0x00001855, 0xffff }, /* R6229 (0x1855) - IRQ1 Mask 22 */
+	{ 0x00001856, 0xffff }, /* R6230 (0x1856) - IRQ1 Mask 23 */
+	{ 0x00001857, 0xffff }, /* R6231 (0x1857) - IRQ1 Mask 24 */
+	{ 0x00001858, 0xffff }, /* R6232 (0x1858) - IRQ1 Mask 25 */
+	{ 0x00001859, 0xffff }, /* R6233 (0x1859) - IRQ1 Mask 26 */
+	{ 0x0000185a, 0xffff }, /* R6234 (0x185a) - IRQ1 Mask 27 */
+	{ 0x0000185b, 0xffff }, /* R6235 (0x185b) - IRQ1 Mask 28 */
+	{ 0x0000185c, 0xffff }, /* R6236 (0x185c) - IRQ1 Mask 29 */
+	{ 0x0000185d, 0xffff }, /* R6237 (0x185d) - IRQ1 Mask 30 */
+	{ 0x0000185e, 0xffff }, /* R6238 (0x185e) - IRQ1 Mask 31 */
+	{ 0x0000185f, 0xffff }, /* R6239 (0x185f) - IRQ1 Mask 32 */
+	{ 0x00001860, 0xffff }, /* R6240 (0x1860) - IRQ1 Mask 33 */
+	{ 0x00001a06, 0x0000 }, /* R6662 (0x1a06) - Interrupt Debounce 7 */
+	{ 0x00001a80, 0x4400 }, /* R6784 (0x1a80) - IRQ1 CTRL */
+};
+
+static bool cs47l90_is_adsp_memory(unsigned int reg)
+{
+	switch (reg) {
+	case 0x080000 ... 0x088ffe:
+	case 0x0a0000 ... 0x0a9ffe:
+	case 0x0c0000 ... 0x0c3ffe:
+	case 0x0e0000 ... 0x0e1ffe:
+	case 0x100000 ... 0x10effe:
+	case 0x120000 ... 0x12bffe:
+	case 0x136000 ... 0x137ffe:
+	case 0x140000 ... 0x14bffe:
+	case 0x160000 ... 0x161ffe:
+	case 0x180000 ... 0x18effe:
+	case 0x1a0000 ... 0x1b1ffe:
+	case 0x1b6000 ... 0x1b7ffe:
+	case 0x1c0000 ... 0x1cbffe:
+	case 0x1e0000 ... 0x1e1ffe:
+	case 0x200000 ... 0x208ffe:
+	case 0x220000 ... 0x229ffe:
+	case 0x240000 ... 0x243ffe:
+	case 0x260000 ... 0x261ffe:
+	case 0x280000 ... 0x288ffe:
+	case 0x2a0000 ... 0x2a9ffe:
+	case 0x2c0000 ... 0x2c3ffe:
+	case 0x2e0000 ... 0x2e1ffe:
+	case 0x300000 ... 0x308ffe:
+	case 0x320000 ... 0x333ffe:
+	case 0x340000 ... 0x353ffe:
+	case 0x360000 ... 0x361ffe:
+	case 0x380000 ... 0x388ffe:
+	case 0x3a0000 ... 0x3b3ffe:
+	case 0x3c0000 ... 0x3d3ffe:
+	case 0x3e0000 ... 0x3e1ffe:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool cs47l90_16bit_readable_register(struct device *dev,
+					    unsigned int reg)
+{
+	switch (reg) {
+	case MADERA_SOFTWARE_RESET:
+	case MADERA_HARDWARE_REVISION:
+	case MADERA_WRITE_SEQUENCER_CTRL_0:
+	case MADERA_WRITE_SEQUENCER_CTRL_1:
+	case MADERA_WRITE_SEQUENCER_CTRL_2:
+	case MADERA_TONE_GENERATOR_1:
+	case MADERA_TONE_GENERATOR_2:
+	case MADERA_TONE_GENERATOR_3:
+	case MADERA_TONE_GENERATOR_4:
+	case MADERA_TONE_GENERATOR_5:
+	case MADERA_PWM_DRIVE_1:
+	case MADERA_PWM_DRIVE_2:
+	case MADERA_PWM_DRIVE_3:
+	case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_1:
+	case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_2:
+	case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_3:
+	case MADERA_SAMPLE_RATE_SEQUENCE_SELECT_4:
+	case MADERA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_1:
+	case MADERA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_2:
+	case MADERA_HAPTICS_CONTROL_1:
+	case MADERA_HAPTICS_CONTROL_2:
+	case MADERA_HAPTICS_PHASE_1_INTENSITY:
+	case MADERA_HAPTICS_PHASE_1_DURATION:
+	case MADERA_HAPTICS_PHASE_2_INTENSITY:
+	case MADERA_HAPTICS_PHASE_2_DURATION:
+	case MADERA_HAPTICS_PHASE_3_INTENSITY:
+	case MADERA_HAPTICS_PHASE_3_DURATION:
+	case MADERA_HAPTICS_STATUS:
+	case MADERA_COMFORT_NOISE_GENERATOR:
+	case MADERA_CLOCK_32K_1:
+	case MADERA_SYSTEM_CLOCK_1:
+	case MADERA_SAMPLE_RATE_1:
+	case MADERA_SAMPLE_RATE_2:
+	case MADERA_SAMPLE_RATE_3:
+	case MADERA_SAMPLE_RATE_1_STATUS:
+	case MADERA_SAMPLE_RATE_2_STATUS:
+	case MADERA_SAMPLE_RATE_3_STATUS:
+	case MADERA_ASYNC_CLOCK_1:
+	case MADERA_ASYNC_SAMPLE_RATE_1:
+	case MADERA_ASYNC_SAMPLE_RATE_1_STATUS:
+	case MADERA_ASYNC_SAMPLE_RATE_2:
+	case MADERA_ASYNC_SAMPLE_RATE_2_STATUS:
+	case MADERA_DSP_CLOCK_1:
+	case MADERA_DSP_CLOCK_2:
+	case MADERA_OUTPUT_SYSTEM_CLOCK:
+	case MADERA_OUTPUT_ASYNC_CLOCK:
+	case MADERA_RATE_ESTIMATOR_1:
+	case MADERA_RATE_ESTIMATOR_2:
+	case MADERA_RATE_ESTIMATOR_3:
+	case MADERA_RATE_ESTIMATOR_4:
+	case MADERA_RATE_ESTIMATOR_5:
+	case MADERA_FLL1_CONTROL_1:
+	case MADERA_FLL1_CONTROL_2:
+	case MADERA_FLL1_CONTROL_3:
+	case MADERA_FLL1_CONTROL_4:
+	case MADERA_FLL1_CONTROL_5:
+	case MADERA_FLL1_CONTROL_6:
+	case MADERA_FLL1_CONTROL_7:
+	case MADERA_FLL1_EFS_2:
+	case MADERA_FLL1_LOOP_FILTER_TEST_1:
+	case MADERA_FLL1_SYNCHRONISER_1:
+	case MADERA_FLL1_SYNCHRONISER_2:
+	case MADERA_FLL1_SYNCHRONISER_3:
+	case MADERA_FLL1_SYNCHRONISER_4:
+	case MADERA_FLL1_SYNCHRONISER_5:
+	case MADERA_FLL1_SYNCHRONISER_6:
+	case MADERA_FLL1_SYNCHRONISER_7:
+	case MADERA_FLL1_SPREAD_SPECTRUM:
+	case MADERA_FLL1_GPIO_CLOCK:
+	case MADERA_FLL2_CONTROL_1:
+	case MADERA_FLL2_CONTROL_2:
+	case MADERA_FLL2_CONTROL_3:
+	case MADERA_FLL2_CONTROL_4:
+	case MADERA_FLL2_CONTROL_5:
+	case MADERA_FLL2_CONTROL_6:
+	case MADERA_FLL2_CONTROL_7:
+	case MADERA_FLL2_EFS_2:
+	case MADERA_FLL2_LOOP_FILTER_TEST_1:
+	case MADERA_FLL2_SYNCHRONISER_1:
+	case MADERA_FLL2_SYNCHRONISER_2:
+	case MADERA_FLL2_SYNCHRONISER_3:
+	case MADERA_FLL2_SYNCHRONISER_4:
+	case MADERA_FLL2_SYNCHRONISER_5:
+	case MADERA_FLL2_SYNCHRONISER_6:
+	case MADERA_FLL2_SYNCHRONISER_7:
+	case MADERA_FLL2_SPREAD_SPECTRUM:
+	case MADERA_FLL2_GPIO_CLOCK:
+	case MADERA_FLLAO_CONTROL_1:
+	case MADERA_FLLAO_CONTROL_2:
+	case MADERA_FLLAO_CONTROL_3:
+	case MADERA_FLLAO_CONTROL_4:
+	case MADERA_FLLAO_CONTROL_5:
+	case MADERA_FLLAO_CONTROL_6:
+	case MADERA_FLLAO_CONTROL_7:
+	case MADERA_FLLAO_CONTROL_8:
+	case MADERA_FLLAO_CONTROL_9:
+	case MADERA_FLLAO_CONTROL_10:
+	case MADERA_FLLAO_CONTROL_11:
+	case MADERA_MIC_CHARGE_PUMP_1:
+	case MADERA_LDO2_CONTROL_1:
+	case MADERA_MIC_BIAS_CTRL_1:
+	case MADERA_MIC_BIAS_CTRL_2:
+	case MADERA_MIC_BIAS_CTRL_5:
+	case MADERA_MIC_BIAS_CTRL_6:
+	case MADERA_HP_CTRL_1L:
+	case MADERA_HP_CTRL_1R:
+	case MADERA_HP_CTRL_2L:
+	case MADERA_HP_CTRL_2R:
+	case MADERA_HP_CTRL_3L:
+	case MADERA_HP_CTRL_3R:
+	case MADERA_EDRE_HP_STEREO_CONTROL:
+	case MADERA_ACCESSORY_DETECT_MODE_1:
+	case MADERA_HEADPHONE_DETECT_0:
+	case MADERA_HEADPHONE_DETECT_1:
+	case MADERA_HEADPHONE_DETECT_2:
+	case MADERA_HEADPHONE_DETECT_3:
+	case MADERA_HEADPHONE_DETECT_5:
+	case MADERA_MICD_CLAMP_CONTROL:
+	case MADERA_MIC_DETECT_1_CONTROL_0:
+	case MADERA_MIC_DETECT_1_CONTROL_1:
+	case MADERA_MIC_DETECT_1_CONTROL_2:
+	case MADERA_MIC_DETECT_1_CONTROL_3:
+	case MADERA_MIC_DETECT_1_LEVEL_1:
+	case MADERA_MIC_DETECT_1_LEVEL_2:
+	case MADERA_MIC_DETECT_1_LEVEL_3:
+	case MADERA_MIC_DETECT_1_LEVEL_4:
+	case MADERA_MIC_DETECT_1_CONTROL_4:
+	case MADERA_MIC_DETECT_2_CONTROL_0:
+	case MADERA_MIC_DETECT_2_CONTROL_1:
+	case MADERA_MIC_DETECT_2_CONTROL_2:
+	case MADERA_MIC_DETECT_2_CONTROL_3:
+	case MADERA_MIC_DETECT_2_LEVEL_1:
+	case MADERA_MIC_DETECT_2_LEVEL_2:
+	case MADERA_MIC_DETECT_2_LEVEL_3:
+	case MADERA_MIC_DETECT_2_LEVEL_4:
+	case MADERA_MIC_DETECT_2_CONTROL_4:
+	case MADERA_GP_SWITCH_1:
+	case MADERA_JACK_DETECT_ANALOGUE:
+	case MADERA_INPUT_ENABLES:
+	case MADERA_INPUT_ENABLES_STATUS:
+	case MADERA_INPUT_RATE:
+	case MADERA_INPUT_VOLUME_RAMP:
+	case MADERA_HPF_CONTROL:
+	case MADERA_IN1L_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_1L:
+	case MADERA_DMIC1L_CONTROL:
+	case MADERA_IN1L_RATE_CONTROL:
+	case MADERA_IN1R_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_1R:
+	case MADERA_DMIC1R_CONTROL:
+	case MADERA_IN1R_RATE_CONTROL:
+	case MADERA_IN2L_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_2L:
+	case MADERA_DMIC2L_CONTROL:
+	case MADERA_IN2L_RATE_CONTROL:
+	case MADERA_IN2R_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_2R:
+	case MADERA_DMIC2R_CONTROL:
+	case MADERA_IN2R_RATE_CONTROL:
+	case MADERA_IN3L_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_3L:
+	case MADERA_DMIC3L_CONTROL:
+	case MADERA_IN3L_RATE_CONTROL:
+	case MADERA_IN3R_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_3R:
+	case MADERA_DMIC3R_CONTROL:
+	case MADERA_IN3R_RATE_CONTROL:
+	case MADERA_IN4L_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_4L:
+	case MADERA_DMIC4L_CONTROL:
+	case MADERA_IN4L_RATE_CONTROL:
+	case MADERA_IN4R_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_4R:
+	case MADERA_DMIC4R_CONTROL:
+	case MADERA_IN4R_RATE_CONTROL:
+	case MADERA_IN5L_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_5L:
+	case MADERA_DMIC5L_CONTROL:
+	case MADERA_IN5L_RATE_CONTROL:
+	case MADERA_IN5R_CONTROL:
+	case MADERA_ADC_DIGITAL_VOLUME_5R:
+	case MADERA_DMIC5R_CONTROL:
+	case MADERA_IN5R_RATE_CONTROL:
+	case MADERA_OUTPUT_ENABLES_1:
+	case MADERA_OUTPUT_STATUS_1:
+	case MADERA_RAW_OUTPUT_STATUS_1:
+	case MADERA_OUTPUT_RATE_1:
+	case MADERA_OUTPUT_VOLUME_RAMP:
+	case MADERA_OUTPUT_PATH_CONFIG_1L:
+	case MADERA_DAC_DIGITAL_VOLUME_1L:
+	case MADERA_OUTPUT_PATH_CONFIG_1:
+	case MADERA_NOISE_GATE_SELECT_1L:
+	case MADERA_OUTPUT_PATH_CONFIG_1R:
+	case MADERA_DAC_DIGITAL_VOLUME_1R:
+	case MADERA_NOISE_GATE_SELECT_1R:
+	case MADERA_OUTPUT_PATH_CONFIG_2L:
+	case MADERA_DAC_DIGITAL_VOLUME_2L:
+	case MADERA_OUTPUT_PATH_CONFIG_2:
+	case MADERA_NOISE_GATE_SELECT_2L:
+	case MADERA_OUTPUT_PATH_CONFIG_2R:
+	case MADERA_DAC_DIGITAL_VOLUME_2R:
+	case MADERA_NOISE_GATE_SELECT_2R:
+	case MADERA_OUTPUT_PATH_CONFIG_3L:
+	case MADERA_DAC_DIGITAL_VOLUME_3L:
+	case MADERA_NOISE_GATE_SELECT_3L:
+	case MADERA_OUTPUT_PATH_CONFIG_3R:
+	case MADERA_DAC_DIGITAL_VOLUME_3R:
+	case MADERA_NOISE_GATE_SELECT_3R:
+	case MADERA_OUTPUT_PATH_CONFIG_5L:
+	case MADERA_DAC_DIGITAL_VOLUME_5L:
+	case MADERA_NOISE_GATE_SELECT_5L:
+	case MADERA_OUTPUT_PATH_CONFIG_5R:
+	case MADERA_DAC_DIGITAL_VOLUME_5R:
+	case MADERA_NOISE_GATE_SELECT_5R:
+	case MADERA_DRE_ENABLE:
+	case MADERA_EDRE_ENABLE:
+	case MADERA_DAC_AEC_CONTROL_1:
+	case MADERA_NOISE_GATE_CONTROL:
+	case MADERA_PDM_SPK1_CTRL_1:
+	case MADERA_PDM_SPK1_CTRL_2:
+	case MADERA_HP1_SHORT_CIRCUIT_CTRL:
+	case MADERA_HP2_SHORT_CIRCUIT_CTRL:
+	case MADERA_HP3_SHORT_CIRCUIT_CTRL:
+	case MADERA_AIF1_BCLK_CTRL:
+	case MADERA_AIF1_TX_PIN_CTRL:
+	case MADERA_AIF1_RX_PIN_CTRL:
+	case MADERA_AIF1_RATE_CTRL:
+	case MADERA_AIF1_FORMAT:
+	case MADERA_AIF1_RX_BCLK_RATE:
+	case MADERA_AIF1_FRAME_CTRL_1:
+	case MADERA_AIF1_FRAME_CTRL_2:
+	case MADERA_AIF1_FRAME_CTRL_3:
+	case MADERA_AIF1_FRAME_CTRL_4:
+	case MADERA_AIF1_FRAME_CTRL_5:
+	case MADERA_AIF1_FRAME_CTRL_6:
+	case MADERA_AIF1_FRAME_CTRL_7:
+	case MADERA_AIF1_FRAME_CTRL_8:
+	case MADERA_AIF1_FRAME_CTRL_9:
+	case MADERA_AIF1_FRAME_CTRL_10:
+	case MADERA_AIF1_FRAME_CTRL_11:
+	case MADERA_AIF1_FRAME_CTRL_12:
+	case MADERA_AIF1_FRAME_CTRL_13:
+	case MADERA_AIF1_FRAME_CTRL_14:
+	case MADERA_AIF1_FRAME_CTRL_15:
+	case MADERA_AIF1_FRAME_CTRL_16:
+	case MADERA_AIF1_FRAME_CTRL_17:
+	case MADERA_AIF1_FRAME_CTRL_18:
+	case MADERA_AIF1_TX_ENABLES:
+	case MADERA_AIF1_RX_ENABLES:
+	case MADERA_AIF2_BCLK_CTRL:
+	case MADERA_AIF2_TX_PIN_CTRL:
+	case MADERA_AIF2_RX_PIN_CTRL:
+	case MADERA_AIF2_RATE_CTRL:
+	case MADERA_AIF2_FORMAT:
+	case MADERA_AIF2_RX_BCLK_RATE:
+	case MADERA_AIF2_FRAME_CTRL_1:
+	case MADERA_AIF2_FRAME_CTRL_2:
+	case MADERA_AIF2_FRAME_CTRL_3:
+	case MADERA_AIF2_FRAME_CTRL_4:
+	case MADERA_AIF2_FRAME_CTRL_5:
+	case MADERA_AIF2_FRAME_CTRL_6:
+	case MADERA_AIF2_FRAME_CTRL_7:
+	case MADERA_AIF2_FRAME_CTRL_8:
+	case MADERA_AIF2_FRAME_CTRL_9:
+	case MADERA_AIF2_FRAME_CTRL_10:
+	case MADERA_AIF2_FRAME_CTRL_11:
+	case MADERA_AIF2_FRAME_CTRL_12:
+	case MADERA_AIF2_FRAME_CTRL_13:
+	case MADERA_AIF2_FRAME_CTRL_14:
+	case MADERA_AIF2_FRAME_CTRL_15:
+	case MADERA_AIF2_FRAME_CTRL_16:
+	case MADERA_AIF2_FRAME_CTRL_17:
+	case MADERA_AIF2_FRAME_CTRL_18:
+	case MADERA_AIF2_TX_ENABLES:
+	case MADERA_AIF2_RX_ENABLES:
+	case MADERA_AIF3_BCLK_CTRL:
+	case MADERA_AIF3_TX_PIN_CTRL:
+	case MADERA_AIF3_RX_PIN_CTRL:
+	case MADERA_AIF3_RATE_CTRL:
+	case MADERA_AIF3_FORMAT:
+	case MADERA_AIF3_RX_BCLK_RATE:
+	case MADERA_AIF3_FRAME_CTRL_1:
+	case MADERA_AIF3_FRAME_CTRL_2:
+	case MADERA_AIF3_FRAME_CTRL_3:
+	case MADERA_AIF3_FRAME_CTRL_4:
+	case MADERA_AIF3_FRAME_CTRL_11:
+	case MADERA_AIF3_FRAME_CTRL_12:
+	case MADERA_AIF3_TX_ENABLES:
+	case MADERA_AIF3_RX_ENABLES:
+	case MADERA_AIF4_BCLK_CTRL:
+	case MADERA_AIF4_TX_PIN_CTRL:
+	case MADERA_AIF4_RX_PIN_CTRL:
+	case MADERA_AIF4_RATE_CTRL:
+	case MADERA_AIF4_FORMAT:
+	case MADERA_AIF4_RX_BCLK_RATE:
+	case MADERA_AIF4_FRAME_CTRL_1:
+	case MADERA_AIF4_FRAME_CTRL_2:
+	case MADERA_AIF4_FRAME_CTRL_3:
+	case MADERA_AIF4_FRAME_CTRL_4:
+	case MADERA_AIF4_FRAME_CTRL_11:
+	case MADERA_AIF4_FRAME_CTRL_12:
+	case MADERA_AIF4_TX_ENABLES:
+	case MADERA_AIF4_RX_ENABLES:
+	case MADERA_SPD1_TX_CONTROL:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_1:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_2:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_3:
+	case MADERA_SLIMBUS_FRAMER_REF_GEAR:
+	case MADERA_SLIMBUS_RATES_1:
+	case MADERA_SLIMBUS_RATES_2:
+	case MADERA_SLIMBUS_RATES_3:
+	case MADERA_SLIMBUS_RATES_4:
+	case MADERA_SLIMBUS_RATES_5:
+	case MADERA_SLIMBUS_RATES_6:
+	case MADERA_SLIMBUS_RATES_7:
+	case MADERA_SLIMBUS_RATES_8:
+	case MADERA_SLIMBUS_RX_CHANNEL_ENABLE:
+	case MADERA_SLIMBUS_TX_CHANNEL_ENABLE:
+	case MADERA_SLIMBUS_RX_PORT_STATUS:
+	case MADERA_SLIMBUS_TX_PORT_STATUS:
+	case MADERA_PWM1MIX_INPUT_1_SOURCE:
+	case MADERA_PWM1MIX_INPUT_1_VOLUME:
+	case MADERA_PWM1MIX_INPUT_2_SOURCE:
+	case MADERA_PWM1MIX_INPUT_2_VOLUME:
+	case MADERA_PWM1MIX_INPUT_3_SOURCE:
+	case MADERA_PWM1MIX_INPUT_3_VOLUME:
+	case MADERA_PWM1MIX_INPUT_4_SOURCE:
+	case MADERA_PWM1MIX_INPUT_4_VOLUME:
+	case MADERA_PWM2MIX_INPUT_1_SOURCE:
+	case MADERA_PWM2MIX_INPUT_1_VOLUME:
+	case MADERA_PWM2MIX_INPUT_2_SOURCE:
+	case MADERA_PWM2MIX_INPUT_2_VOLUME:
+	case MADERA_PWM2MIX_INPUT_3_SOURCE:
+	case MADERA_PWM2MIX_INPUT_3_VOLUME:
+	case MADERA_PWM2MIX_INPUT_4_SOURCE:
+	case MADERA_PWM2MIX_INPUT_4_VOLUME:
+	case MADERA_OUT1LMIX_INPUT_1_SOURCE:
+	case MADERA_OUT1LMIX_INPUT_1_VOLUME:
+	case MADERA_OUT1LMIX_INPUT_2_SOURCE:
+	case MADERA_OUT1LMIX_INPUT_2_VOLUME:
+	case MADERA_OUT1LMIX_INPUT_3_SOURCE:
+	case MADERA_OUT1LMIX_INPUT_3_VOLUME:
+	case MADERA_OUT1LMIX_INPUT_4_SOURCE:
+	case MADERA_OUT1LMIX_INPUT_4_VOLUME:
+	case MADERA_OUT1RMIX_INPUT_1_SOURCE:
+	case MADERA_OUT1RMIX_INPUT_1_VOLUME:
+	case MADERA_OUT1RMIX_INPUT_2_SOURCE:
+	case MADERA_OUT1RMIX_INPUT_2_VOLUME:
+	case MADERA_OUT1RMIX_INPUT_3_SOURCE:
+	case MADERA_OUT1RMIX_INPUT_3_VOLUME:
+	case MADERA_OUT1RMIX_INPUT_4_SOURCE:
+	case MADERA_OUT1RMIX_INPUT_4_VOLUME:
+	case MADERA_OUT2LMIX_INPUT_1_SOURCE:
+	case MADERA_OUT2LMIX_INPUT_1_VOLUME:
+	case MADERA_OUT2LMIX_INPUT_2_SOURCE:
+	case MADERA_OUT2LMIX_INPUT_2_VOLUME:
+	case MADERA_OUT2LMIX_INPUT_3_SOURCE:
+	case MADERA_OUT2LMIX_INPUT_3_VOLUME:
+	case MADERA_OUT2LMIX_INPUT_4_SOURCE:
+	case MADERA_OUT2LMIX_INPUT_4_VOLUME:
+	case MADERA_OUT2RMIX_INPUT_1_SOURCE:
+	case MADERA_OUT2RMIX_INPUT_1_VOLUME:
+	case MADERA_OUT2RMIX_INPUT_2_SOURCE:
+	case MADERA_OUT2RMIX_INPUT_2_VOLUME:
+	case MADERA_OUT2RMIX_INPUT_3_SOURCE:
+	case MADERA_OUT2RMIX_INPUT_3_VOLUME:
+	case MADERA_OUT2RMIX_INPUT_4_SOURCE:
+	case MADERA_OUT2RMIX_INPUT_4_VOLUME:
+	case MADERA_OUT3LMIX_INPUT_1_SOURCE:
+	case MADERA_OUT3LMIX_INPUT_1_VOLUME:
+	case MADERA_OUT3LMIX_INPUT_2_SOURCE:
+	case MADERA_OUT3LMIX_INPUT_2_VOLUME:
+	case MADERA_OUT3LMIX_INPUT_3_SOURCE:
+	case MADERA_OUT3LMIX_INPUT_3_VOLUME:
+	case MADERA_OUT3LMIX_INPUT_4_SOURCE:
+	case MADERA_OUT3LMIX_INPUT_4_VOLUME:
+	case MADERA_OUT3RMIX_INPUT_1_SOURCE:
+	case MADERA_OUT3RMIX_INPUT_1_VOLUME:
+	case MADERA_OUT3RMIX_INPUT_2_SOURCE:
+	case MADERA_OUT3RMIX_INPUT_2_VOLUME:
+	case MADERA_OUT3RMIX_INPUT_3_SOURCE:
+	case MADERA_OUT3RMIX_INPUT_3_VOLUME:
+	case MADERA_OUT3RMIX_INPUT_4_SOURCE:
+	case MADERA_OUT3RMIX_INPUT_4_VOLUME:
+	case MADERA_OUT5LMIX_INPUT_1_SOURCE:
+	case MADERA_OUT5LMIX_INPUT_1_VOLUME:
+	case MADERA_OUT5LMIX_INPUT_2_SOURCE:
+	case MADERA_OUT5LMIX_INPUT_2_VOLUME:
+	case MADERA_OUT5LMIX_INPUT_3_SOURCE:
+	case MADERA_OUT5LMIX_INPUT_3_VOLUME:
+	case MADERA_OUT5LMIX_INPUT_4_SOURCE:
+	case MADERA_OUT5LMIX_INPUT_4_VOLUME:
+	case MADERA_OUT5RMIX_INPUT_1_SOURCE:
+	case MADERA_OUT5RMIX_INPUT_1_VOLUME:
+	case MADERA_OUT5RMIX_INPUT_2_SOURCE:
+	case MADERA_OUT5RMIX_INPUT_2_VOLUME:
+	case MADERA_OUT5RMIX_INPUT_3_SOURCE:
+	case MADERA_OUT5RMIX_INPUT_3_VOLUME:
+	case MADERA_OUT5RMIX_INPUT_4_SOURCE:
+	case MADERA_OUT5RMIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX1MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX1MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX1MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX1MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX1MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX1MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX1MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX1MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX2MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX2MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX2MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX2MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX2MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX2MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX2MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX2MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX3MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX3MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX3MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX3MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX3MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX3MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX3MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX3MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX4MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX4MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX4MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX4MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX4MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX4MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX4MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX4MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX5MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX5MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX5MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX5MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX5MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX5MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX5MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX5MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX6MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX6MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX6MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX6MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX6MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX6MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX6MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX6MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX7MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX7MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX7MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX7MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX7MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX7MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX7MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX7MIX_INPUT_4_VOLUME:
+	case MADERA_AIF1TX8MIX_INPUT_1_SOURCE:
+	case MADERA_AIF1TX8MIX_INPUT_1_VOLUME:
+	case MADERA_AIF1TX8MIX_INPUT_2_SOURCE:
+	case MADERA_AIF1TX8MIX_INPUT_2_VOLUME:
+	case MADERA_AIF1TX8MIX_INPUT_3_SOURCE:
+	case MADERA_AIF1TX8MIX_INPUT_3_VOLUME:
+	case MADERA_AIF1TX8MIX_INPUT_4_SOURCE:
+	case MADERA_AIF1TX8MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX1MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX1MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX1MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX1MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX1MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX1MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX1MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX1MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX2MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX2MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX2MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX2MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX2MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX2MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX2MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX2MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX3MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX3MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX3MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX3MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX3MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX3MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX3MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX3MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX4MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX4MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX4MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX4MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX4MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX4MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX4MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX4MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX5MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX5MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX5MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX5MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX5MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX5MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX5MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX5MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX6MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX6MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX6MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX6MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX6MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX6MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX6MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX6MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX7MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX7MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX7MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX7MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX7MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX7MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX7MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX7MIX_INPUT_4_VOLUME:
+	case MADERA_AIF2TX8MIX_INPUT_1_SOURCE:
+	case MADERA_AIF2TX8MIX_INPUT_1_VOLUME:
+	case MADERA_AIF2TX8MIX_INPUT_2_SOURCE:
+	case MADERA_AIF2TX8MIX_INPUT_2_VOLUME:
+	case MADERA_AIF2TX8MIX_INPUT_3_SOURCE:
+	case MADERA_AIF2TX8MIX_INPUT_3_VOLUME:
+	case MADERA_AIF2TX8MIX_INPUT_4_SOURCE:
+	case MADERA_AIF2TX8MIX_INPUT_4_VOLUME:
+	case MADERA_AIF3TX1MIX_INPUT_1_SOURCE:
+	case MADERA_AIF3TX1MIX_INPUT_1_VOLUME:
+	case MADERA_AIF3TX1MIX_INPUT_2_SOURCE:
+	case MADERA_AIF3TX1MIX_INPUT_2_VOLUME:
+	case MADERA_AIF3TX1MIX_INPUT_3_SOURCE:
+	case MADERA_AIF3TX1MIX_INPUT_3_VOLUME:
+	case MADERA_AIF3TX1MIX_INPUT_4_SOURCE:
+	case MADERA_AIF3TX1MIX_INPUT_4_VOLUME:
+	case MADERA_AIF3TX2MIX_INPUT_1_SOURCE:
+	case MADERA_AIF3TX2MIX_INPUT_1_VOLUME:
+	case MADERA_AIF3TX2MIX_INPUT_2_SOURCE:
+	case MADERA_AIF3TX2MIX_INPUT_2_VOLUME:
+	case MADERA_AIF3TX2MIX_INPUT_3_SOURCE:
+	case MADERA_AIF3TX2MIX_INPUT_3_VOLUME:
+	case MADERA_AIF3TX2MIX_INPUT_4_SOURCE:
+	case MADERA_AIF3TX2MIX_INPUT_4_VOLUME:
+	case MADERA_AIF4TX1MIX_INPUT_1_SOURCE:
+	case MADERA_AIF4TX1MIX_INPUT_1_VOLUME:
+	case MADERA_AIF4TX1MIX_INPUT_2_SOURCE:
+	case MADERA_AIF4TX1MIX_INPUT_2_VOLUME:
+	case MADERA_AIF4TX1MIX_INPUT_3_SOURCE:
+	case MADERA_AIF4TX1MIX_INPUT_3_VOLUME:
+	case MADERA_AIF4TX1MIX_INPUT_4_SOURCE:
+	case MADERA_AIF4TX1MIX_INPUT_4_VOLUME:
+	case MADERA_AIF4TX2MIX_INPUT_1_SOURCE:
+	case MADERA_AIF4TX2MIX_INPUT_1_VOLUME:
+	case MADERA_AIF4TX2MIX_INPUT_2_SOURCE:
+	case MADERA_AIF4TX2MIX_INPUT_2_VOLUME:
+	case MADERA_AIF4TX2MIX_INPUT_3_SOURCE:
+	case MADERA_AIF4TX2MIX_INPUT_3_VOLUME:
+	case MADERA_AIF4TX2MIX_INPUT_4_SOURCE:
+	case MADERA_AIF4TX2MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX1MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX1MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX1MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX1MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX1MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX1MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX1MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX1MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX2MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX2MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX2MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX2MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX2MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX2MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX2MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX2MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX3MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX3MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX3MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX3MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX3MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX3MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX3MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX3MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX4MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX4MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX4MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX4MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX4MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX4MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX4MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX4MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX5MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX5MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX5MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX5MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX5MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX5MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX5MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX5MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX6MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX6MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX6MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX6MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX6MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX6MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX6MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX6MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX7MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX7MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX7MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX7MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX7MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX7MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX7MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX7MIX_INPUT_4_VOLUME:
+	case MADERA_SLIMTX8MIX_INPUT_1_SOURCE:
+	case MADERA_SLIMTX8MIX_INPUT_1_VOLUME:
+	case MADERA_SLIMTX8MIX_INPUT_2_SOURCE:
+	case MADERA_SLIMTX8MIX_INPUT_2_VOLUME:
+	case MADERA_SLIMTX8MIX_INPUT_3_SOURCE:
+	case MADERA_SLIMTX8MIX_INPUT_3_VOLUME:
+	case MADERA_SLIMTX8MIX_INPUT_4_SOURCE:
+	case MADERA_SLIMTX8MIX_INPUT_4_VOLUME:
+	case MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE:
+	case MADERA_SPDIF1TX1MIX_INPUT_1_VOLUME:
+	case MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE:
+	case MADERA_SPDIF1TX2MIX_INPUT_1_VOLUME:
+	case MADERA_EQ1MIX_INPUT_1_SOURCE:
+	case MADERA_EQ1MIX_INPUT_1_VOLUME:
+	case MADERA_EQ1MIX_INPUT_2_SOURCE:
+	case MADERA_EQ1MIX_INPUT_2_VOLUME:
+	case MADERA_EQ1MIX_INPUT_3_SOURCE:
+	case MADERA_EQ1MIX_INPUT_3_VOLUME:
+	case MADERA_EQ1MIX_INPUT_4_SOURCE:
+	case MADERA_EQ1MIX_INPUT_4_VOLUME:
+	case MADERA_EQ2MIX_INPUT_1_SOURCE:
+	case MADERA_EQ2MIX_INPUT_1_VOLUME:
+	case MADERA_EQ2MIX_INPUT_2_SOURCE:
+	case MADERA_EQ2MIX_INPUT_2_VOLUME:
+	case MADERA_EQ2MIX_INPUT_3_SOURCE:
+	case MADERA_EQ2MIX_INPUT_3_VOLUME:
+	case MADERA_EQ2MIX_INPUT_4_SOURCE:
+	case MADERA_EQ2MIX_INPUT_4_VOLUME:
+	case MADERA_EQ3MIX_INPUT_1_SOURCE:
+	case MADERA_EQ3MIX_INPUT_1_VOLUME:
+	case MADERA_EQ3MIX_INPUT_2_SOURCE:
+	case MADERA_EQ3MIX_INPUT_2_VOLUME:
+	case MADERA_EQ3MIX_INPUT_3_SOURCE:
+	case MADERA_EQ3MIX_INPUT_3_VOLUME:
+	case MADERA_EQ3MIX_INPUT_4_SOURCE:
+	case MADERA_EQ3MIX_INPUT_4_VOLUME:
+	case MADERA_EQ4MIX_INPUT_1_SOURCE:
+	case MADERA_EQ4MIX_INPUT_1_VOLUME:
+	case MADERA_EQ4MIX_INPUT_2_SOURCE:
+	case MADERA_EQ4MIX_INPUT_2_VOLUME:
+	case MADERA_EQ4MIX_INPUT_3_SOURCE:
+	case MADERA_EQ4MIX_INPUT_3_VOLUME:
+	case MADERA_EQ4MIX_INPUT_4_SOURCE:
+	case MADERA_EQ4MIX_INPUT_4_VOLUME:
+	case MADERA_DRC1LMIX_INPUT_1_SOURCE:
+	case MADERA_DRC1LMIX_INPUT_1_VOLUME:
+	case MADERA_DRC1LMIX_INPUT_2_SOURCE:
+	case MADERA_DRC1LMIX_INPUT_2_VOLUME:
+	case MADERA_DRC1LMIX_INPUT_3_SOURCE:
+	case MADERA_DRC1LMIX_INPUT_3_VOLUME:
+	case MADERA_DRC1LMIX_INPUT_4_SOURCE:
+	case MADERA_DRC1LMIX_INPUT_4_VOLUME:
+	case MADERA_DRC1RMIX_INPUT_1_SOURCE:
+	case MADERA_DRC1RMIX_INPUT_1_VOLUME:
+	case MADERA_DRC1RMIX_INPUT_2_SOURCE:
+	case MADERA_DRC1RMIX_INPUT_2_VOLUME:
+	case MADERA_DRC1RMIX_INPUT_3_SOURCE:
+	case MADERA_DRC1RMIX_INPUT_3_VOLUME:
+	case MADERA_DRC1RMIX_INPUT_4_SOURCE:
+	case MADERA_DRC1RMIX_INPUT_4_VOLUME:
+	case MADERA_DRC2LMIX_INPUT_1_SOURCE:
+	case MADERA_DRC2LMIX_INPUT_1_VOLUME:
+	case MADERA_DRC2LMIX_INPUT_2_SOURCE:
+	case MADERA_DRC2LMIX_INPUT_2_VOLUME:
+	case MADERA_DRC2LMIX_INPUT_3_SOURCE:
+	case MADERA_DRC2LMIX_INPUT_3_VOLUME:
+	case MADERA_DRC2LMIX_INPUT_4_SOURCE:
+	case MADERA_DRC2LMIX_INPUT_4_VOLUME:
+	case MADERA_DRC2RMIX_INPUT_1_SOURCE:
+	case MADERA_DRC2RMIX_INPUT_1_VOLUME:
+	case MADERA_DRC2RMIX_INPUT_2_SOURCE:
+	case MADERA_DRC2RMIX_INPUT_2_VOLUME:
+	case MADERA_DRC2RMIX_INPUT_3_SOURCE:
+	case MADERA_DRC2RMIX_INPUT_3_VOLUME:
+	case MADERA_DRC2RMIX_INPUT_4_SOURCE:
+	case MADERA_DRC2RMIX_INPUT_4_VOLUME:
+	case MADERA_HPLP1MIX_INPUT_1_SOURCE:
+	case MADERA_HPLP1MIX_INPUT_1_VOLUME:
+	case MADERA_HPLP1MIX_INPUT_2_SOURCE:
+	case MADERA_HPLP1MIX_INPUT_2_VOLUME:
+	case MADERA_HPLP1MIX_INPUT_3_SOURCE:
+	case MADERA_HPLP1MIX_INPUT_3_VOLUME:
+	case MADERA_HPLP1MIX_INPUT_4_SOURCE:
+	case MADERA_HPLP1MIX_INPUT_4_VOLUME:
+	case MADERA_HPLP2MIX_INPUT_1_SOURCE:
+	case MADERA_HPLP2MIX_INPUT_1_VOLUME:
+	case MADERA_HPLP2MIX_INPUT_2_SOURCE:
+	case MADERA_HPLP2MIX_INPUT_2_VOLUME:
+	case MADERA_HPLP2MIX_INPUT_3_SOURCE:
+	case MADERA_HPLP2MIX_INPUT_3_VOLUME:
+	case MADERA_HPLP2MIX_INPUT_4_SOURCE:
+	case MADERA_HPLP2MIX_INPUT_4_VOLUME:
+	case MADERA_HPLP3MIX_INPUT_1_SOURCE:
+	case MADERA_HPLP3MIX_INPUT_1_VOLUME:
+	case MADERA_HPLP3MIX_INPUT_2_SOURCE:
+	case MADERA_HPLP3MIX_INPUT_2_VOLUME:
+	case MADERA_HPLP3MIX_INPUT_3_SOURCE:
+	case MADERA_HPLP3MIX_INPUT_3_VOLUME:
+	case MADERA_HPLP3MIX_INPUT_4_SOURCE:
+	case MADERA_HPLP3MIX_INPUT_4_VOLUME:
+	case MADERA_HPLP4MIX_INPUT_1_SOURCE:
+	case MADERA_HPLP4MIX_INPUT_1_VOLUME:
+	case MADERA_HPLP4MIX_INPUT_2_SOURCE:
+	case MADERA_HPLP4MIX_INPUT_2_VOLUME:
+	case MADERA_HPLP4MIX_INPUT_3_SOURCE:
+	case MADERA_HPLP4MIX_INPUT_3_VOLUME:
+	case MADERA_HPLP4MIX_INPUT_4_SOURCE:
+	case MADERA_HPLP4MIX_INPUT_4_VOLUME:
+	case MADERA_DSP1LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP1LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP1LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP1LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP1LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP1LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP1LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP1LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP1RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP1RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP1RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP1RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP1RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP1RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP1RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP1RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP1AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP1AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP1AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP1AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP1AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP1AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP2LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP2LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP2LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP2LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP2LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP2LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP2LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP2RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP2RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP2RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP2RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP2RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP2RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP2RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP2RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP2AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP2AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP3LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP3LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP3LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP3LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP3LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP3LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP3LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP3RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP3RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP3RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP3RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP3RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP3RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP3RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP3RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP3AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP3AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP4LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP4LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP4LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP4LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP4LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP4LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP4LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP4RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP4RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP4RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP4RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP4RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP4RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP4RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP4RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP4AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP4AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP5LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP5LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP5LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP5LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP5LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP5LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP5LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP5RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP5RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP5RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP5RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP5RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP5RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP5RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP5RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP5AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP5AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_ASRC1_1LMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC1_1RMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC1_2LMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC1_2RMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC2_1LMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC2_1RMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC2_2LMIX_INPUT_1_SOURCE:
+	case MADERA_ASRC2_2RMIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1DEC1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1DEC2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1DEC3MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1DEC4MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1INT1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1INT2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1INT3MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC1INT4MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2DEC1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2DEC2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2DEC3MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2DEC4MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2INT1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2INT2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2INT3MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC2INT4MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC3DEC1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC3DEC2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC3INT1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC3INT2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC4DEC1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC4DEC2MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC4INT1MIX_INPUT_1_SOURCE:
+	case MADERA_ISRC4INT2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP6LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP6LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP6LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP6LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP6LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP6LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP6LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP6RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP6RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP6RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP6RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP6RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP6RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP6RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP6RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP6AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP6AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7LMIX_INPUT_1_SOURCE:
+	case MADERA_DSP7LMIX_INPUT_1_VOLUME:
+	case MADERA_DSP7LMIX_INPUT_2_SOURCE:
+	case MADERA_DSP7LMIX_INPUT_2_VOLUME:
+	case MADERA_DSP7LMIX_INPUT_3_SOURCE:
+	case MADERA_DSP7LMIX_INPUT_3_VOLUME:
+	case MADERA_DSP7LMIX_INPUT_4_SOURCE:
+	case MADERA_DSP7LMIX_INPUT_4_VOLUME:
+	case MADERA_DSP7RMIX_INPUT_1_SOURCE:
+	case MADERA_DSP7RMIX_INPUT_1_VOLUME:
+	case MADERA_DSP7RMIX_INPUT_2_SOURCE:
+	case MADERA_DSP7RMIX_INPUT_2_VOLUME:
+	case MADERA_DSP7RMIX_INPUT_3_SOURCE:
+	case MADERA_DSP7RMIX_INPUT_3_VOLUME:
+	case MADERA_DSP7RMIX_INPUT_4_SOURCE:
+	case MADERA_DSP7RMIX_INPUT_4_VOLUME:
+	case MADERA_DSP7AUX1MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7AUX2MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7AUX3MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7AUX4MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7AUX5MIX_INPUT_1_SOURCE:
+	case MADERA_DSP7AUX6MIX_INPUT_1_SOURCE:
+	case MADERA_DFC1MIX_INPUT_1_SOURCE:
+	case MADERA_DFC2MIX_INPUT_1_SOURCE:
+	case MADERA_DFC3MIX_INPUT_1_SOURCE:
+	case MADERA_DFC4MIX_INPUT_1_SOURCE:
+	case MADERA_DFC5MIX_INPUT_1_SOURCE:
+	case MADERA_DFC6MIX_INPUT_1_SOURCE:
+	case MADERA_DFC7MIX_INPUT_1_SOURCE:
+	case MADERA_DFC8MIX_INPUT_1_SOURCE:
+	case MADERA_FX_CTRL1:
+	case MADERA_FX_CTRL2:
+	case MADERA_EQ1_1:
+	case MADERA_EQ1_2:
+	case MADERA_EQ1_3:
+	case MADERA_EQ1_4:
+	case MADERA_EQ1_5:
+	case MADERA_EQ1_6:
+	case MADERA_EQ1_7:
+	case MADERA_EQ1_8:
+	case MADERA_EQ1_9:
+	case MADERA_EQ1_10:
+	case MADERA_EQ1_11:
+	case MADERA_EQ1_12:
+	case MADERA_EQ1_13:
+	case MADERA_EQ1_14:
+	case MADERA_EQ1_15:
+	case MADERA_EQ1_16:
+	case MADERA_EQ1_17:
+	case MADERA_EQ1_18:
+	case MADERA_EQ1_19:
+	case MADERA_EQ1_20:
+	case MADERA_EQ1_21:
+	case MADERA_EQ2_1:
+	case MADERA_EQ2_2:
+	case MADERA_EQ2_3:
+	case MADERA_EQ2_4:
+	case MADERA_EQ2_5:
+	case MADERA_EQ2_6:
+	case MADERA_EQ2_7:
+	case MADERA_EQ2_8:
+	case MADERA_EQ2_9:
+	case MADERA_EQ2_10:
+	case MADERA_EQ2_11:
+	case MADERA_EQ2_12:
+	case MADERA_EQ2_13:
+	case MADERA_EQ2_14:
+	case MADERA_EQ2_15:
+	case MADERA_EQ2_16:
+	case MADERA_EQ2_17:
+	case MADERA_EQ2_18:
+	case MADERA_EQ2_19:
+	case MADERA_EQ2_20:
+	case MADERA_EQ2_21:
+	case MADERA_EQ3_1:
+	case MADERA_EQ3_2:
+	case MADERA_EQ3_3:
+	case MADERA_EQ3_4:
+	case MADERA_EQ3_5:
+	case MADERA_EQ3_6:
+	case MADERA_EQ3_7:
+	case MADERA_EQ3_8:
+	case MADERA_EQ3_9:
+	case MADERA_EQ3_10:
+	case MADERA_EQ3_11:
+	case MADERA_EQ3_12:
+	case MADERA_EQ3_13:
+	case MADERA_EQ3_14:
+	case MADERA_EQ3_15:
+	case MADERA_EQ3_16:
+	case MADERA_EQ3_17:
+	case MADERA_EQ3_18:
+	case MADERA_EQ3_19:
+	case MADERA_EQ3_20:
+	case MADERA_EQ3_21:
+	case MADERA_EQ4_1:
+	case MADERA_EQ4_2:
+	case MADERA_EQ4_3:
+	case MADERA_EQ4_4:
+	case MADERA_EQ4_5:
+	case MADERA_EQ4_6:
+	case MADERA_EQ4_7:
+	case MADERA_EQ4_8:
+	case MADERA_EQ4_9:
+	case MADERA_EQ4_10:
+	case MADERA_EQ4_11:
+	case MADERA_EQ4_12:
+	case MADERA_EQ4_13:
+	case MADERA_EQ4_14:
+	case MADERA_EQ4_15:
+	case MADERA_EQ4_16:
+	case MADERA_EQ4_17:
+	case MADERA_EQ4_18:
+	case MADERA_EQ4_19:
+	case MADERA_EQ4_20:
+	case MADERA_EQ4_21:
+	case MADERA_DRC1_CTRL1:
+	case MADERA_DRC1_CTRL2:
+	case MADERA_DRC1_CTRL3:
+	case MADERA_DRC1_CTRL4:
+	case MADERA_DRC1_CTRL5:
+	case MADERA_DRC2_CTRL1:
+	case MADERA_DRC2_CTRL2:
+	case MADERA_DRC2_CTRL3:
+	case MADERA_DRC2_CTRL4:
+	case MADERA_DRC2_CTRL5:
+	case MADERA_HPLPF1_1:
+	case MADERA_HPLPF1_2:
+	case MADERA_HPLPF2_1:
+	case MADERA_HPLPF2_2:
+	case MADERA_HPLPF3_1:
+	case MADERA_HPLPF3_2:
+	case MADERA_HPLPF4_1:
+	case MADERA_HPLPF4_2:
+	case MADERA_ASRC1_ENABLE:
+	case MADERA_ASRC1_STATUS:
+	case MADERA_ASRC1_RATE1:
+	case MADERA_ASRC1_RATE2:
+	case MADERA_ASRC2_ENABLE:
+	case MADERA_ASRC2_STATUS:
+	case MADERA_ASRC2_RATE1:
+	case MADERA_ASRC2_RATE2:
+	case MADERA_ISRC_1_CTRL_1:
+	case MADERA_ISRC_1_CTRL_2:
+	case MADERA_ISRC_1_CTRL_3:
+	case MADERA_ISRC_2_CTRL_1:
+	case MADERA_ISRC_2_CTRL_2:
+	case MADERA_ISRC_2_CTRL_3:
+	case MADERA_ISRC_3_CTRL_1:
+	case MADERA_ISRC_3_CTRL_2:
+	case MADERA_ISRC_3_CTRL_3:
+	case MADERA_ISRC_4_CTRL_1:
+	case MADERA_ISRC_4_CTRL_2:
+	case MADERA_ISRC_4_CTRL_3:
+	case MADERA_CLOCK_CONTROL:
+	case MADERA_ANC_SRC:
+	case MADERA_DSP_STATUS:
+	case MADERA_ANC_COEFF_START ... MADERA_ANC_COEFF_END:
+	case MADERA_FCL_FILTER_CONTROL:
+	case MADERA_FCL_ADC_REFORMATTER_CONTROL:
+	case MADERA_FCL_COEFF_START ... MADERA_FCL_COEFF_END:
+	case MADERA_FCR_FILTER_CONTROL:
+	case MADERA_FCR_ADC_REFORMATTER_CONTROL:
+	case MADERA_FCR_COEFF_START ... MADERA_FCR_COEFF_END:
+	case MADERA_DAC_COMP_1:
+	case MADERA_DAC_COMP_2:
+	case MADERA_FRF_COEFFICIENT_1L_1:
+	case MADERA_FRF_COEFFICIENT_1L_2:
+	case MADERA_FRF_COEFFICIENT_1L_3:
+	case MADERA_FRF_COEFFICIENT_1L_4:
+	case MADERA_FRF_COEFFICIENT_1R_1:
+	case MADERA_FRF_COEFFICIENT_1R_2:
+	case MADERA_FRF_COEFFICIENT_1R_3:
+	case MADERA_FRF_COEFFICIENT_1R_4:
+	case MADERA_FRF_COEFFICIENT_2L_1:
+	case MADERA_FRF_COEFFICIENT_2L_2:
+	case MADERA_FRF_COEFFICIENT_2L_3:
+	case MADERA_FRF_COEFFICIENT_2L_4:
+	case MADERA_FRF_COEFFICIENT_2R_1:
+	case MADERA_FRF_COEFFICIENT_2R_2:
+	case MADERA_FRF_COEFFICIENT_2R_3:
+	case MADERA_FRF_COEFFICIENT_2R_4:
+	case MADERA_FRF_COEFFICIENT_3L_1:
+	case MADERA_FRF_COEFFICIENT_3L_2:
+	case MADERA_FRF_COEFFICIENT_3L_3:
+	case MADERA_FRF_COEFFICIENT_3L_4:
+	case MADERA_FRF_COEFFICIENT_3R_1:
+	case MADERA_FRF_COEFFICIENT_3R_2:
+	case MADERA_FRF_COEFFICIENT_3R_3:
+	case MADERA_FRF_COEFFICIENT_3R_4:
+	case MADERA_FRF_COEFFICIENT_5L_1:
+	case MADERA_FRF_COEFFICIENT_5L_2:
+	case MADERA_FRF_COEFFICIENT_5L_3:
+	case MADERA_FRF_COEFFICIENT_5L_4:
+	case MADERA_FRF_COEFFICIENT_5R_1:
+	case MADERA_FRF_COEFFICIENT_5R_2:
+	case MADERA_FRF_COEFFICIENT_5R_3:
+	case MADERA_FRF_COEFFICIENT_5R_4:
+	case MADERA_DFC1_CTRL:
+	case MADERA_DFC1_RX:
+	case MADERA_DFC1_TX:
+	case MADERA_DFC2_CTRL:
+	case MADERA_DFC2_RX:
+	case MADERA_DFC2_TX:
+	case MADERA_DFC3_CTRL:
+	case MADERA_DFC3_RX:
+	case MADERA_DFC3_TX:
+	case MADERA_DFC4_CTRL:
+	case MADERA_DFC4_RX:
+	case MADERA_DFC4_TX:
+	case MADERA_DFC5_CTRL:
+	case MADERA_DFC5_RX:
+	case MADERA_DFC5_TX:
+	case MADERA_DFC6_CTRL:
+	case MADERA_DFC6_RX:
+	case MADERA_DFC6_TX:
+	case MADERA_DFC7_CTRL:
+	case MADERA_DFC7_RX:
+	case MADERA_DFC7_TX:
+	case MADERA_DFC8_CTRL:
+	case MADERA_DFC8_RX:
+	case MADERA_DFC8_TX:
+	case MADERA_DFC_STATUS:
+	case MADERA_GPIO1_CTRL_1:
+	case MADERA_GPIO1_CTRL_2:
+	case MADERA_GPIO2_CTRL_1:
+	case MADERA_GPIO2_CTRL_2:
+	case MADERA_GPIO3_CTRL_1:
+	case MADERA_GPIO3_CTRL_2:
+	case MADERA_GPIO4_CTRL_1:
+	case MADERA_GPIO4_CTRL_2:
+	case MADERA_GPIO5_CTRL_1:
+	case MADERA_GPIO5_CTRL_2:
+	case MADERA_GPIO6_CTRL_1:
+	case MADERA_GPIO6_CTRL_2:
+	case MADERA_GPIO7_CTRL_1:
+	case MADERA_GPIO7_CTRL_2:
+	case MADERA_GPIO8_CTRL_1:
+	case MADERA_GPIO8_CTRL_2:
+	case MADERA_GPIO9_CTRL_1:
+	case MADERA_GPIO9_CTRL_2:
+	case MADERA_GPIO10_CTRL_1:
+	case MADERA_GPIO10_CTRL_2:
+	case MADERA_GPIO11_CTRL_1:
+	case MADERA_GPIO11_CTRL_2:
+	case MADERA_GPIO12_CTRL_1:
+	case MADERA_GPIO12_CTRL_2:
+	case MADERA_GPIO13_CTRL_1:
+	case MADERA_GPIO13_CTRL_2:
+	case MADERA_GPIO14_CTRL_1:
+	case MADERA_GPIO14_CTRL_2:
+	case MADERA_GPIO15_CTRL_1:
+	case MADERA_GPIO15_CTRL_2:
+	case MADERA_GPIO16_CTRL_1:
+	case MADERA_GPIO16_CTRL_2:
+	case MADERA_GPIO17_CTRL_1:
+	case MADERA_GPIO17_CTRL_2:
+	case MADERA_GPIO18_CTRL_1:
+	case MADERA_GPIO18_CTRL_2:
+	case MADERA_GPIO19_CTRL_1:
+	case MADERA_GPIO19_CTRL_2:
+	case MADERA_GPIO20_CTRL_1:
+	case MADERA_GPIO20_CTRL_2:
+	case MADERA_GPIO21_CTRL_1:
+	case MADERA_GPIO21_CTRL_2:
+	case MADERA_GPIO22_CTRL_1:
+	case MADERA_GPIO22_CTRL_2:
+	case MADERA_GPIO23_CTRL_1:
+	case MADERA_GPIO23_CTRL_2:
+	case MADERA_GPIO24_CTRL_1:
+	case MADERA_GPIO24_CTRL_2:
+	case MADERA_GPIO25_CTRL_1:
+	case MADERA_GPIO25_CTRL_2:
+	case MADERA_GPIO26_CTRL_1:
+	case MADERA_GPIO26_CTRL_2:
+	case MADERA_GPIO27_CTRL_1:
+	case MADERA_GPIO27_CTRL_2:
+	case MADERA_GPIO28_CTRL_1:
+	case MADERA_GPIO28_CTRL_2:
+	case MADERA_GPIO29_CTRL_1:
+	case MADERA_GPIO29_CTRL_2:
+	case MADERA_GPIO30_CTRL_1:
+	case MADERA_GPIO30_CTRL_2:
+	case MADERA_GPIO31_CTRL_1:
+	case MADERA_GPIO31_CTRL_2:
+	case MADERA_GPIO32_CTRL_1:
+	case MADERA_GPIO32_CTRL_2:
+	case MADERA_GPIO33_CTRL_1:
+	case MADERA_GPIO33_CTRL_2:
+	case MADERA_GPIO34_CTRL_1:
+	case MADERA_GPIO34_CTRL_2:
+	case MADERA_GPIO35_CTRL_1:
+	case MADERA_GPIO35_CTRL_2:
+	case MADERA_GPIO36_CTRL_1:
+	case MADERA_GPIO36_CTRL_2:
+	case MADERA_GPIO37_CTRL_1:
+	case MADERA_GPIO37_CTRL_2:
+	case MADERA_GPIO38_CTRL_1:
+	case MADERA_GPIO38_CTRL_2:
+	case MADERA_IRQ1_STATUS_1 ... MADERA_IRQ1_STATUS_33:
+	case MADERA_IRQ1_MASK_1 ... MADERA_IRQ1_MASK_33:
+	case MADERA_IRQ1_RAW_STATUS_1 ... MADERA_IRQ1_RAW_STATUS_33:
+	case MADERA_INTERRUPT_DEBOUNCE_7:
+	case MADERA_IRQ1_CTRL:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool cs47l90_16bit_volatile_register(struct device *dev,
+					    unsigned int reg)
+{
+	switch (reg) {
+	case MADERA_SOFTWARE_RESET:
+	case MADERA_HARDWARE_REVISION:
+	case MADERA_WRITE_SEQUENCER_CTRL_0:
+	case MADERA_WRITE_SEQUENCER_CTRL_1:
+	case MADERA_WRITE_SEQUENCER_CTRL_2:
+	case MADERA_HAPTICS_STATUS:
+	case MADERA_SAMPLE_RATE_1_STATUS:
+	case MADERA_SAMPLE_RATE_2_STATUS:
+	case MADERA_SAMPLE_RATE_3_STATUS:
+	case MADERA_ASYNC_SAMPLE_RATE_1_STATUS:
+	case MADERA_ASYNC_SAMPLE_RATE_2_STATUS:
+	case MADERA_HP_CTRL_1L:
+	case MADERA_HP_CTRL_1R:
+	case MADERA_HP_CTRL_2L:
+	case MADERA_HP_CTRL_2R:
+	case MADERA_HP_CTRL_3L:
+	case MADERA_HP_CTRL_3R:
+	case MADERA_MIC_DETECT_1_CONTROL_3:
+	case MADERA_MIC_DETECT_1_CONTROL_4:
+	case MADERA_MIC_DETECT_2_CONTROL_3:
+	case MADERA_MIC_DETECT_2_CONTROL_4:
+	case MADERA_HEADPHONE_DETECT_2:
+	case MADERA_HEADPHONE_DETECT_3:
+	case MADERA_HEADPHONE_DETECT_5:
+	case MADERA_INPUT_ENABLES_STATUS:
+	case MADERA_OUTPUT_STATUS_1:
+	case MADERA_RAW_OUTPUT_STATUS_1:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_1:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_2:
+	case MADERA_SPD1_TX_CHANNEL_STATUS_3:
+	case MADERA_SLIMBUS_RX_PORT_STATUS:
+	case MADERA_SLIMBUS_TX_PORT_STATUS:
+	case MADERA_FX_CTRL2:
+	case MADERA_ASRC2_STATUS:
+	case MADERA_ASRC1_STATUS:
+	case MADERA_CLOCK_CONTROL:
+	case MADERA_DFC_STATUS:
+	case MADERA_IRQ1_STATUS_1 ... MADERA_IRQ1_STATUS_33:
+	case MADERA_IRQ1_RAW_STATUS_1 ... MADERA_IRQ1_RAW_STATUS_33:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool cs47l90_32bit_readable_register(struct device *dev,
+					    unsigned int reg)
+{
+	switch (reg) {
+	case MADERA_WSEQ_SEQUENCE_1 ... MADERA_WSEQ_SEQUENCE_508:
+	case MADERA_OTP_HPDET_CAL_1 ... MADERA_OTP_HPDET_CAL_2:
+	case MADERA_DSP1_CONFIG_1 ... MADERA_DSP1_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP2_CONFIG_1 ... MADERA_DSP2_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP3_CONFIG_1 ... MADERA_DSP3_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP4_CONFIG_1 ... MADERA_DSP4_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP5_CONFIG_1 ... MADERA_DSP5_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP6_CONFIG_1 ... MADERA_DSP6_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP7_CONFIG_1 ... MADERA_DSP7_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+		return true;
+	default:
+		return cs47l90_is_adsp_memory(reg);
+	}
+}
+
+static bool cs47l90_32bit_volatile_register(struct device *dev,
+					    unsigned int reg)
+{
+	switch (reg) {
+	case MADERA_WSEQ_SEQUENCE_1 ... MADERA_WSEQ_SEQUENCE_508:
+	case MADERA_OTP_HPDET_CAL_1 ... MADERA_OTP_HPDET_CAL_2:
+	case MADERA_DSP1_CONFIG_1 ... MADERA_DSP1_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP2_CONFIG_1 ... MADERA_DSP2_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP3_CONFIG_1 ... MADERA_DSP3_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP4_CONFIG_1 ... MADERA_DSP4_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP5_CONFIG_1 ... MADERA_DSP5_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP6_CONFIG_1 ... MADERA_DSP6_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+	case MADERA_DSP7_CONFIG_1 ... MADERA_DSP7_PMEM_ERR_ADDR___XMEM_ERR_ADDR:
+		return true;
+	default:
+		return cs47l90_is_adsp_memory(reg);
+	}
+}
+
+const struct regmap_config cs47l90_16bit_spi_regmap = {
+	.name = "cs47l90_16bit",
+	.reg_bits = 32,
+	.pad_bits = 16,
+	.val_bits = 16,
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+	.val_format_endian = REGMAP_ENDIAN_BIG,
+
+	.max_register = MADERA_INTERRUPT_RAW_STATUS_1,
+	.readable_reg = cs47l90_16bit_readable_register,
+	.volatile_reg = cs47l90_16bit_volatile_register,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = cs47l90_reg_default,
+	.num_reg_defaults = ARRAY_SIZE(cs47l90_reg_default),
+};
+EXPORT_SYMBOL_GPL(cs47l90_16bit_spi_regmap);
+
+const struct regmap_config cs47l90_16bit_i2c_regmap = {
+	.name = "cs47l90_16bit",
+	.reg_bits = 32,
+	.val_bits = 16,
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+	.val_format_endian = REGMAP_ENDIAN_BIG,
+
+	.max_register = MADERA_INTERRUPT_RAW_STATUS_1,
+	.readable_reg = cs47l90_16bit_readable_register,
+	.volatile_reg = cs47l90_16bit_volatile_register,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = cs47l90_reg_default,
+	.num_reg_defaults = ARRAY_SIZE(cs47l90_reg_default),
+};
+EXPORT_SYMBOL_GPL(cs47l90_16bit_i2c_regmap);
+
+const struct regmap_config cs47l90_32bit_spi_regmap = {
+	.name = "cs47l90_32bit",
+	.reg_bits = 32,
+	.reg_stride = 2,
+	.pad_bits = 16,
+	.val_bits = 32,
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+	.val_format_endian = REGMAP_ENDIAN_BIG,
+
+	.max_register = MADERA_DSP7_PMEM_ERR_ADDR___XMEM_ERR_ADDR,
+	.readable_reg = cs47l90_32bit_readable_register,
+	.volatile_reg = cs47l90_32bit_volatile_register,
+
+	.cache_type = REGCACHE_RBTREE,
+};
+EXPORT_SYMBOL_GPL(cs47l90_32bit_spi_regmap);
+
+const struct regmap_config cs47l90_32bit_i2c_regmap = {
+	.name = "cs47l90_32bit",
+	.reg_bits = 32,
+	.reg_stride = 2,
+	.val_bits = 32,
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+	.val_format_endian = REGMAP_ENDIAN_BIG,
+
+	.max_register = MADERA_DSP7_PMEM_ERR_ADDR___XMEM_ERR_ADDR,
+	.readable_reg = cs47l90_32bit_readable_register,
+	.volatile_reg = cs47l90_32bit_volatile_register,
+
+	.cache_type = REGCACHE_RBTREE,
+};
+EXPORT_SYMBOL_GPL(cs47l90_32bit_i2c_regmap);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 07/18] regulator: arizona-micsupp: Add support for Cirrus Logic Madera codecs
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones-QSEj5FYQhm4dnm+yROfE0A, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	gnurou-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493050124-5970-1-git-send-email-rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>

This adds a new driver identity "madera-micsupp" and probe function
so that this driver can be used to control the micsupp regulator on
Cirrus Logic Madera codecs.

Signed-off-by: Richard Fitzgerald <rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
---
Replaces the madera-specific driver from V1 patchset

 .../bindings/regulator/arizona-regulator.txt       |  3 +-
 drivers/regulator/Kconfig                          |  7 ++-
 drivers/regulator/arizona-micsupp.c                | 71 +++++++++++++++++++++-
 3 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/arizona-regulator.txt b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
index 443564d..91b00f9 100644
--- a/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
@@ -5,7 +5,8 @@ of analogue I/O.
 
 This document lists regulator specific bindings, see the primary binding
 document:
-  ../mfd/arizona.txt
+  For Wolfson Arizona codecs: ../mfd/arizona.txt
+  For Cirrus Logic Madera codecs: ../mfd/madera.txt
 
 Optional properties:
   - wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 8647538..05e6aae 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -134,11 +134,12 @@ config REGULATOR_ARIZONA_LDO1
 	  devices.
 
 config REGULATOR_ARIZONA_MICSUPP
-	tristate "Wolfson Arizona class devices MICSUPP"
-	depends on MFD_ARIZONA
+	tristate "Cirrus Madera and Wolfson Arizona class devices MICSUPP"
+	depends on MFD_ARIZONA || MFD_MADERA
 	depends on SND_SOC
 	help
-	  Support for the MICSUPP regulators found on Wolfson Arizona class
+	  Support for the MICSUPP regulators found on Cirrus Logic Madera codecs
+	  and Wolfson Arizona codecs
 	  devices.
 
 config REGULATOR_AS3711
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c
index 120de94..36bf73c 100644
--- a/drivers/regulator/arizona-micsupp.c
+++ b/drivers/regulator/arizona-micsupp.c
@@ -30,6 +30,10 @@
 #include <linux/mfd/arizona/pdata.h>
 #include <linux/mfd/arizona/registers.h>
 
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/pdata.h>
+#include <linux/mfd/madera/registers.h>
+
 #include <linux/regulator/arizona-micsupp.h>
 
 struct arizona_micsupp {
@@ -205,6 +209,28 @@ static int arizona_micsupp_set_bypass(struct regulator_dev *rdev, bool ena)
 	.num_consumer_supplies = 1,
 };
 
+static const struct regulator_desc madera_micsupp = {
+	.name = "MICVDD",
+	.supply_name = "CPVDD1",
+	.type = REGULATOR_VOLTAGE,
+	.n_voltages = 40,
+	.ops = &arizona_micsupp_ops,
+
+	.vsel_reg = MADERA_LDO2_CONTROL_1,
+	.vsel_mask = MADERA_LDO2_VSEL_MASK,
+	.enable_reg = MADERA_MIC_CHARGE_PUMP_1,
+	.enable_mask = MADERA_CPMIC_ENA,
+	.bypass_reg = MADERA_MIC_CHARGE_PUMP_1,
+	.bypass_mask = MADERA_CPMIC_BYPASS,
+
+	.linear_ranges = arizona_micsupp_ext_ranges,
+	.n_linear_ranges = ARRAY_SIZE(arizona_micsupp_ext_ranges),
+
+	.enable_time = 3000,
+
+	.owner = THIS_MODULE,
+};
+
 static int arizona_micsupp_of_get_pdata(struct arizona_micsupp_pdata *pdata,
 					struct regulator_config *config,
 					const struct regulator_desc *desc)
@@ -321,6 +347,24 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
 					   &arizona->pdata.micvdd);
 }
 
+static int madera_micsupp_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	struct arizona_micsupp *micsupp;
+
+	micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL);
+	if (!micsupp)
+		return -ENOMEM;
+
+	micsupp->regmap = madera->regmap;
+	micsupp->dapm = &madera->dapm;
+	micsupp->dev = madera->dev;
+	micsupp->init_data = arizona_micsupp_ext_default;
+
+	return arizona_micsupp_common_init(pdev, micsupp, &madera_micsupp,
+					   &madera->pdata.micvdd);
+}
+
 static struct platform_driver arizona_micsupp_driver = {
 	.probe = arizona_micsupp_probe,
 	.driver		= {
@@ -328,10 +372,35 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
 	},
 };
 
-module_platform_driver(arizona_micsupp_driver);
+static struct platform_driver madera_micsupp_driver = {
+	.probe = madera_micsupp_probe,
+	.driver		= {
+		.name	= "madera-micsupp",
+	},
+};
+
+static struct platform_driver * const arizona_micsupp_drivers[] = {
+	&arizona_micsupp_driver,
+	&madera_micsupp_driver,
+};
+
+static int __init arizona_micsupp_init(void)
+{
+	return platform_register_drivers(arizona_micsupp_drivers,
+					 ARRAY_SIZE(arizona_micsupp_drivers));
+}
+module_init(arizona_micsupp_init);
+
+static void __exit arizona_micsupp_exit(void)
+{
+	platform_unregister_drivers(arizona_micsupp_drivers,
+				    ARRAY_SIZE(arizona_micsupp_drivers));
+}
+module_exit(arizona_micsupp_exit);
 
 /* Module information */
 MODULE_AUTHOR("Mark Brown <broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>");
 MODULE_DESCRIPTION("Arizona microphone supply driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:arizona-micsupp");
+MODULE_ALIAS("platform:madera-micsupp");
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 08/18] regulator: arizona-ldo1: Add support for Cirrus Logic Madera codecs
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones, broonie, linus.walleij, gnurou, robh+dt, tglx, jason
  Cc: alsa-devel, patches, linux-gpio, devicetree, linux-kernel
In-Reply-To: <1493050124-5970-1-git-send-email-rf@opensource.wolfsonmicro.com>

This adds a new driver identity "madera-ldo1" and probe function
so that this driver can be used to control the LDO1 regulator on
some Cirrus Logic Madera codecs.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
Replaces the madera-specific driver from V1 patchset

 drivers/regulator/Kconfig        |  8 ++--
 drivers/regulator/arizona-ldo1.c | 82 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 85 insertions(+), 5 deletions(-)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 05e6aae..d12da22 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -126,12 +126,12 @@ config REGULATOR_AB8500
 	  signal AB8500 PMIC
 
 config REGULATOR_ARIZONA_LDO1
-	tristate "Wolfson Arizona class devices LDO1"
-	depends on MFD_ARIZONA
+	tristate "Cirrus Madera and Wolfson Arizona class devices LDO1"
+	depends on MFD_ARIZONA || MFD_MADERA
 	depends on SND_SOC
 	help
-	  Support for the LDO1 regulators found on Wolfson Arizona class
-	  devices.
+	  Support for the LDO1 regulators found on Cirrus Logic Madera codecs
+	  and Wolfson Arizona codecs.
 
 config REGULATOR_ARIZONA_MICSUPP
 	tristate "Cirrus Madera and Wolfson Arizona class devices MICSUPP"
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index 96fddff..c64625e 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -31,6 +31,10 @@
 #include <linux/mfd/arizona/pdata.h>
 #include <linux/mfd/arizona/registers.h>
 
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/pdata.h>
+#include <linux/mfd/madera/registers.h>
+
 struct arizona_ldo1 {
 	struct regulator_dev *regulator;
 	struct regmap *regmap;
@@ -188,6 +192,31 @@ static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev)
 	.num_consumer_supplies = 1,
 };
 
+static const struct regulator_desc madera_ldo1 = {
+	.name = "LDO1",
+	.supply_name = "LDOVDD",
+	.type = REGULATOR_VOLTAGE,
+	.ops = &arizona_ldo1_ops,
+
+	.vsel_reg = MADERA_LDO1_CONTROL_1,
+	.vsel_mask = MADERA_LDO1_VSEL_MASK,
+	.min_uV = 900000,
+	.uV_step = 25000,
+	.n_voltages = 13,
+	.enable_time = 3000,
+
+	.owner = THIS_MODULE,
+};
+
+static const struct regulator_init_data madera_ldo1_default = {
+	.constraints = {
+		.min_uV = 1200000,
+		.max_uV = 1200000,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = 1,
+};
+
 static int arizona_ldo1_of_get_pdata(struct arizona_ldo1_pdata *pdata,
 				     struct regulator_config *config,
 				     const struct regulator_desc *desc,
@@ -341,6 +370,32 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
 	return ret;
 }
 
+static int madera_ldo1_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	struct arizona_ldo1 *ldo1;
+	bool external_dcvdd;
+	int ret;
+
+	ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL);
+	if (!ldo1)
+		return -ENOMEM;
+
+	ldo1->regmap = madera->regmap;
+
+	ldo1->init_data = madera_ldo1_default;
+
+	ret = arizona_ldo1_common_init(pdev, ldo1, &arizona_ldo1,
+				       &madera->pdata.ldo1,
+				       &external_dcvdd);
+	if (ret)
+		return ret;
+
+	madera->internal_dcvdd = !external_dcvdd;
+
+	return 0;
+}
+
 static struct platform_driver arizona_ldo1_driver = {
 	.probe = arizona_ldo1_probe,
 	.driver		= {
@@ -348,10 +403,35 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
 	},
 };
 
-module_platform_driver(arizona_ldo1_driver);
+static struct platform_driver madera_ldo1_driver = {
+	.probe = madera_ldo1_probe,
+	.driver		= {
+		.name	= "madera-ldo1",
+	},
+};
+
+static struct platform_driver * const madera_ldo1_drivers[] = {
+	&arizona_ldo1_driver,
+	&madera_ldo1_driver,
+};
+
+static int __init arizona_ldo1_init(void)
+{
+	return platform_register_drivers(madera_ldo1_drivers,
+					 ARRAY_SIZE(madera_ldo1_drivers));
+}
+module_init(arizona_ldo1_init);
+
+static void __exit madera_ldo1_exit(void)
+{
+	platform_unregister_drivers(madera_ldo1_drivers,
+				    ARRAY_SIZE(madera_ldo1_drivers));
+}
+module_exit(madera_ldo1_exit);
 
 /* Module information */
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("Arizona LDO1 driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:arizona-ldo1");
+MODULE_ALIAS("platform:madera-ldo1");
-- 
1.9.1


^ permalink raw reply related

* [PATCH v2 09/18] irqchip: Add driver for Cirrus Logic Madera codecs
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones, broonie, linus.walleij, gnurou, robh+dt, tglx, jason
  Cc: alsa-devel, patches, linux-gpio, devicetree, linux-kernel
In-Reply-To: <1493050124-5970-1-git-send-email-rf@opensource.wolfsonmicro.com>

The Cirrus Logic Madera codecs (Cirrus Logic CS47L35/85/90/91 and WM1840)
are highly complex devices containing up to 7 programmable DSPs and many
other internal sources of interrupts plus a number of GPIOs that can be
used as interrupt inputs. The large number (>150) of internal interrupt
sources are managed by an on-board interrupt controller.

This driver provides the handling for the interrupt controller. As the
codec is accessed via regmap, we can make use of the generic IRQ
functionality from regmap to do most of the work. Only around half of
the possible interrupt source are currently of interest from the driver
so only this subset is defined. Others can be added in future if needed.

The KConfig options are not user-configurable because this driver is
mandatory so is automatically included when the parent MFD driver is
selected.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
Changes since V1:
- Removed dt bindings, squashed them into the parent MFD
- MFD now selects this driver so the "default y if" formula is removed from
  the Kconfig

 MAINTAINERS                              |   2 +
 drivers/irqchip/Kconfig                  |   3 +
 drivers/irqchip/Makefile                 |   1 +
 drivers/irqchip/irq-madera.c             | 349 +++++++++++++++++++++++++++++++
 include/linux/irqchip/irq-madera-pdata.h |  19 ++
 include/linux/irqchip/irq-madera.h       |  96 +++++++++
 6 files changed, 470 insertions(+)
 create mode 100644 drivers/irqchip/irq-madera.c
 create mode 100644 include/linux/irqchip/irq-madera-pdata.h
 create mode 100644 include/linux/irqchip/irq-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 4a01a2a..6e8eec6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3305,7 +3305,9 @@ T:	git https://github.com/CirrusLogic/linux-drivers.git
 W:	https://github.com/CirrusLogic/linux-drivers/wiki
 S:	Supported
 F:	Documentation/devicetree/bindings/mfd/madera.txt
+F:	include/linux/irqchip/irq-madera*
 F:	include/linux/mfd/madera/*
+F:	drivers/irqchip/irq-madera*
 F:	drivers/mfd/madera*
 F:	drivers/mfd/cs47l*
 
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 478f8ac..64350da 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -131,6 +131,9 @@ config IMGPDC_IRQ
 	select GENERIC_IRQ_CHIP
 	select IRQ_DOMAIN
 
+config MADERA_IRQ
+	bool
+
 config IRQ_MIPS_CPU
 	bool
 	select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b64c59b..a884ca8 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_ARCH_S3C24XX)		+= irq-s3c24xx.o
 obj-$(CONFIG_DW_APB_ICTL)		+= irq-dw-apb-ictl.o
 obj-$(CONFIG_METAG)			+= irq-metag-ext.o
 obj-$(CONFIG_METAG_PERFCOUNTER_IRQS)	+= irq-metag.o
+obj-$(CONFIG_MADERA_IRQ)		+= irq-madera.o
 obj-$(CONFIG_CLPS711X_IRQCHIP)		+= irq-clps711x.o
 obj-$(CONFIG_OR1K_PIC)			+= irq-or1k-pic.o
 obj-$(CONFIG_ORION_IRQCHIP)		+= irq-orion.o
diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
new file mode 100644
index 0000000..461cbb9
--- /dev/null
+++ b/drivers/irqchip/irq-madera.c
@@ -0,0 +1,349 @@
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+#include <linux/irqchip/irq-madera.h>
+#include <linux/irqchip/irq-madera-pdata.h>
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/pdata.h>
+#include <linux/mfd/madera/registers.h>
+
+struct madera_irq_priv {
+	struct device *dev;
+	int irq;
+	struct regmap_irq_chip_data *irq_data;
+	struct madera *madera;
+};
+
+static const struct regmap_irq madera_irqs[MADERA_NUM_IRQ] = {
+	[MADERA_IRQ_FLL1_LOCK] =  { .reg_offset = 0,
+				    .mask = MADERA_FLL1_LOCK_EINT1 },
+	[MADERA_IRQ_FLL2_LOCK] =  { .reg_offset = 0,
+				    .mask = MADERA_FLL2_LOCK_EINT1 },
+	[MADERA_IRQ_FLL3_LOCK] =  { .reg_offset = 0,
+				    .mask = MADERA_FLL3_LOCK_EINT1 },
+	[MADERA_IRQ_FLLAO_LOCK] = { .reg_offset = 0,
+				    .mask = MADERA_FLLAO_LOCK_EINT1 },
+
+	[MADERA_IRQ_MICDET1] = { .reg_offset = 4,
+				 .mask = MADERA_MICDET1_EINT1 },
+	[MADERA_IRQ_MICDET2] = { .reg_offset = 4,
+				 .mask = MADERA_MICDET2_EINT1 },
+	[MADERA_IRQ_HPDET] =   { .reg_offset = 4,
+				 .mask = MADERA_HPDET_EINT1 },
+
+	[MADERA_IRQ_MICD_CLAMP_RISE] = { .reg_offset = 5,
+					 .mask = MADERA_MICD_CLAMP_RISE_EINT1 },
+	[MADERA_IRQ_MICD_CLAMP_FALL] = { .reg_offset = 5,
+					 .mask = MADERA_MICD_CLAMP_FALL_EINT1 },
+	[MADERA_IRQ_JD1_FALL] =	       { .reg_offset = 5,
+					 .mask = MADERA_JD1_FALL_EINT1 },
+	[MADERA_IRQ_JD1_RISE] =	       { .reg_offset = 5,
+					 .mask = MADERA_JD1_RISE_EINT1 },
+
+	[MADERA_IRQ_ASRC2_IN1_LOCK] = { .reg_offset = 7,
+					.mask = MADERA_ASRC2_IN1_LOCK_EINT1 },
+	[MADERA_IRQ_ASRC2_IN2_LOCK] = { .reg_offset = 7,
+					.mask = MADERA_ASRC2_IN2_LOCK_EINT1 },
+	[MADERA_IRQ_ASRC1_IN1_LOCK] = { .reg_offset = 7,
+					.mask = MADERA_ASRC1_IN1_LOCK_EINT1 },
+	[MADERA_IRQ_ASRC1_IN2_LOCK] = { .reg_offset = 7,
+					.mask = MADERA_ASRC1_IN2_LOCK_EINT1 },
+
+	[MADERA_IRQ_DRC2_SIG_DET] = { .reg_offset = 7,
+				      .mask = MADERA_DRC2_SIG_DET_EINT1 },
+	[MADERA_IRQ_DRC1_SIG_DET] = { .reg_offset = 7,
+				      .mask = MADERA_DRC1_SIG_DET_EINT1 },
+
+	[MADERA_IRQ_DSP_IRQ1] = { .reg_offset = 9,
+				  .mask = MADERA_DSP_IRQ1_EINT1 },
+	[MADERA_IRQ_DSP_IRQ2] = { .reg_offset = 9,
+				  .mask = MADERA_DSP_IRQ2_EINT1 },
+	[MADERA_IRQ_DSP_IRQ3] = { .reg_offset = 9,
+				  .mask = MADERA_DSP_IRQ3_EINT1 },
+	[MADERA_IRQ_DSP_IRQ4] = { .reg_offset = 9,
+				  .mask = MADERA_DSP_IRQ4_EINT1 },
+	[MADERA_IRQ_DSP_IRQ5] = { .reg_offset = 9,
+				  .mask = MADERA_DSP_IRQ5_EINT1 },
+	[MADERA_IRQ_DSP_IRQ6] = { .reg_offset = 9,
+				  .mask = MADERA_DSP_IRQ6_EINT1 },
+	[MADERA_IRQ_DSP_IRQ7] = { .reg_offset = 9,
+				  .mask = MADERA_DSP_IRQ7_EINT1 },
+	[MADERA_IRQ_DSP_IRQ8] = { .reg_offset = 9,
+				  .mask = MADERA_DSP_IRQ8_EINT1 },
+	[MADERA_IRQ_DSP_IRQ9] = { .reg_offset = 9,
+				  .mask = MADERA_DSP_IRQ9_EINT1 },
+	[MADERA_IRQ_DSP_IRQ10] = { .reg_offset = 9,
+				   .mask = MADERA_DSP_IRQ10_EINT1 },
+	[MADERA_IRQ_DSP_IRQ11] = { .reg_offset = 9,
+				   .mask = MADERA_DSP_IRQ11_EINT1 },
+	[MADERA_IRQ_DSP_IRQ12] = { .reg_offset = 9,
+				   .mask = MADERA_DSP_IRQ12_EINT1 },
+	[MADERA_IRQ_DSP_IRQ13] = { .reg_offset = 9,
+				   .mask = MADERA_DSP_IRQ13_EINT1 },
+	[MADERA_IRQ_DSP_IRQ14] = { .reg_offset = 9,
+				   .mask = MADERA_DSP_IRQ14_EINT1 },
+	[MADERA_IRQ_DSP_IRQ15] = { .reg_offset = 9,
+				   .mask = MADERA_DSP_IRQ15_EINT1 },
+	[MADERA_IRQ_DSP_IRQ16] = { .reg_offset = 9,
+				   .mask = MADERA_DSP_IRQ16_EINT1 },
+
+	[MADERA_IRQ_HP3R_SC] = { .reg_offset = 10,
+				.mask = MADERA_HP3R_SC_EINT1 },
+	[MADERA_IRQ_HP3L_SC] = { .reg_offset = 10,
+				.mask = MADERA_HP3L_SC_EINT1 },
+	[MADERA_IRQ_HP2R_SC] = { .reg_offset = 10,
+				.mask = MADERA_HP2R_SC_EINT1 },
+	[MADERA_IRQ_HP2L_SC] = { .reg_offset = 10,
+				.mask = MADERA_HP2L_SC_EINT1 },
+	[MADERA_IRQ_HP1R_SC] = { .reg_offset = 10,
+				.mask = MADERA_HP1R_SC_EINT1 },
+	[MADERA_IRQ_HP1L_SC] = { .reg_offset = 10,
+				.mask = MADERA_HP1L_SC_EINT1 },
+
+	[MADERA_IRQ_SPK_OVERHEAT_WARN] = { .reg_offset = 13,
+				.mask = MADERA_SPK_OVERHEAT_WARN_EINT1 },
+	[MADERA_IRQ_SPK_OVERHEAT] = { .reg_offset = 13,
+				.mask = MADERA_SPK_SHUTDOWN_EINT1 },
+
+	[MADERA_IRQ_DSP1_BUS_ERROR] = { .reg_offset = 31,
+					.mask = MADERA_ADSP_ERROR_STATUS_DSP1 },
+	[MADERA_IRQ_DSP2_BUS_ERROR] = { .reg_offset = 31,
+					.mask = MADERA_ADSP_ERROR_STATUS_DSP2 },
+	[MADERA_IRQ_DSP3_BUS_ERROR] = { .reg_offset = 31,
+					.mask = MADERA_ADSP_ERROR_STATUS_DSP3 },
+	[MADERA_IRQ_DSP4_BUS_ERROR] = { .reg_offset = 31,
+					.mask = MADERA_ADSP_ERROR_STATUS_DSP4 },
+	[MADERA_IRQ_DSP5_BUS_ERROR] = { .reg_offset = 31,
+					.mask = MADERA_ADSP_ERROR_STATUS_DSP5 },
+	[MADERA_IRQ_DSP6_BUS_ERROR] = { .reg_offset = 31,
+					.mask = MADERA_ADSP_ERROR_STATUS_DSP6 },
+	[MADERA_IRQ_DSP7_BUS_ERROR] = { .reg_offset = 31,
+					.mask = MADERA_ADSP_ERROR_STATUS_DSP7 },
+};
+
+static const struct regmap_irq_chip madera_irq = {
+	.name = "madera IRQ",
+	.status_base = MADERA_IRQ1_STATUS_2,
+	.mask_base = MADERA_IRQ1_MASK_2,
+	.ack_base = MADERA_IRQ1_STATUS_2,
+	.runtime_pm = true, /* codec must be resumed to read IRQ status */
+	.num_regs = 32,
+	.irqs = madera_irqs,
+	.num_irqs = ARRAY_SIZE(madera_irqs),
+};
+
+static int madera_map_irq(struct madera *madera, int irq)
+{
+	struct madera_irq_priv *priv = dev_get_drvdata(madera->irq_dev);
+
+	if (irq < 0)
+		return irq;
+
+	if (!madera->irq_dev)
+		return -ENOENT;
+
+	return regmap_irq_get_virq(priv->irq_data, irq);
+}
+
+int madera_request_irq(struct madera *madera, int irq, const char *name,
+			irq_handler_t handler, void *data)
+{
+	irq = madera_map_irq(madera, irq);
+
+	if (irq < 0)
+		return irq;
+
+	return request_threaded_irq(irq, NULL, handler, IRQF_ONESHOT, name,
+				    data);
+
+}
+EXPORT_SYMBOL_GPL(madera_request_irq);
+
+void madera_free_irq(struct madera *madera, int irq, void *data)
+{
+	irq = madera_map_irq(madera, irq);
+
+	if (irq < 0)
+		return;
+
+	free_irq(irq, data);
+}
+EXPORT_SYMBOL_GPL(madera_free_irq);
+
+int madera_set_irq_wake(struct madera *madera, int irq, int on)
+{
+	irq = madera_map_irq(madera, irq);
+
+	if (irq < 0)
+		return irq;
+
+	return irq_set_irq_wake(irq, on);
+}
+EXPORT_SYMBOL_GPL(madera_set_irq_wake);
+
+#ifdef CONFIG_PM_SLEEP
+static int madera_suspend_noirq(struct device *dev)
+{
+	struct madera_irq_priv *priv = dev_get_drvdata(dev);
+
+	dev_dbg(priv->dev, "No IRQ suspend, reenabling IRQ\n");
+
+	enable_irq(priv->irq);
+
+	return 0;
+}
+
+static int madera_suspend(struct device *dev)
+{
+	struct madera_irq_priv *priv = dev_get_drvdata(dev);
+
+	dev_dbg(priv->dev, "Suspend, disabling IRQ\n");
+
+	disable_irq(priv->irq);
+
+	return 0;
+}
+
+static int madera_resume_noirq(struct device *dev)
+{
+	struct madera_irq_priv *priv = dev_get_drvdata(dev);
+
+	dev_dbg(priv->dev, "No IRQ resume, disabling IRQ\n");
+
+	disable_irq(priv->irq);
+
+	return 0;
+}
+
+static int madera_resume(struct device *dev)
+{
+	struct madera_irq_priv *priv = dev_get_drvdata(dev);
+
+	dev_dbg(priv->dev, "Resume, reenabling IRQ\n");
+
+	enable_irq(priv->irq);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops madera_irq_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(madera_suspend, madera_resume)
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(madera_suspend_noirq,
+				      madera_resume_noirq)
+};
+
+static int madera_irq_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	struct madera_irq_priv *priv;
+	struct irq_data *irq_data;
+	unsigned int irq_flags = madera->pdata.irqchip.irq_flags;
+	int ret;
+
+	dev_dbg(&pdev->dev, "probe\n");
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = &pdev->dev;
+	priv->madera = madera;
+	priv->irq = madera->irq;
+
+	/* Read the flags from the interrupt controller if not specified */
+	if (!irq_flags) {
+		irq_data = irq_get_irq_data(priv->irq);
+		if (!irq_data) {
+			dev_err(priv->dev, "Invalid IRQ: %d\n", priv->irq);
+			return -EINVAL;
+		}
+
+		irq_flags = irqd_get_trigger_type(irq_data);
+		if (irq_flags == IRQ_TYPE_NONE)
+			irq_flags = IRQF_TRIGGER_LOW; /* Device default */
+	}
+
+	if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+		dev_err(priv->dev,
+			"Host interrupt not level-triggered\n");
+		return -EINVAL;
+	}
+
+	if (irq_flags & IRQF_TRIGGER_HIGH) {
+		ret = regmap_update_bits(madera->regmap, MADERA_IRQ1_CTRL,
+					 MADERA_IRQ_POL_MASK, 0);
+		if (ret) {
+			dev_err(priv->dev,
+				"Failed to set IRQ polarity: %d\n", ret);
+			return ret;
+		}
+	}
+
+	/*
+	 * NOTE: regmap registers this against the OF node of the parent of
+	 * the regmap - that is, against the mfd driver
+	 */
+	ret = regmap_add_irq_chip(madera->regmap, priv->irq, IRQF_ONESHOT, 0,
+				  &madera_irq, &priv->irq_data);
+	if (ret) {
+		dev_err(priv->dev, "add_irq_chip failed: %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, priv);
+	madera->irq_dev = priv->dev;
+
+	return 0;
+}
+
+static int madera_irq_remove(struct platform_device *pdev)
+{
+	struct madera_irq_priv *priv = platform_get_drvdata(pdev);
+
+	/*
+	 * The IRQ is disabled by the parent MFD driver before
+	 * it starts cleaning up all child drivers
+	 */
+
+	priv->madera->irq_dev = NULL;
+
+	regmap_del_irq_chip(priv->irq, priv->irq_data);
+	free_irq(priv->irq, priv);
+
+	return 0;
+}
+
+static struct platform_driver madera_irq_driver = {
+	.probe = madera_irq_probe,
+	.remove = madera_irq_remove,
+	.driver = {
+		.name	= "madera-irq",
+		.pm = &madera_irq_pm_ops,
+	}
+};
+
+module_platform_driver(madera_irq_driver);
+
+MODULE_DESCRIPTION("Madera IRQ driver");
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/irqchip/irq-madera-pdata.h b/include/linux/irqchip/irq-madera-pdata.h
new file mode 100644
index 0000000..5928e81
--- /dev/null
+++ b/include/linux/irqchip/irq-madera-pdata.h
@@ -0,0 +1,19 @@
+/*
+ * Platform data for Cirrus Logic Madera codecs irqchip driver
+ *
+ * Copyright 2016 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef IRQCHIP_MADERA_PDATA_H
+#define IRQCHIP_MADERA_PDATA_H
+
+struct madera_irqchip_pdata {
+	/** Mode for primary IRQ (defaults to active low) */
+	unsigned int irq_flags;
+};
+
+#endif
diff --git a/include/linux/irqchip/irq-madera.h b/include/linux/irqchip/irq-madera.h
new file mode 100644
index 0000000..72dc5e6
--- /dev/null
+++ b/include/linux/irqchip/irq-madera.h
@@ -0,0 +1,96 @@
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef IRQCHIP_MADERA_H
+#define IRQCHIP_MADERA_H
+
+#define MADERA_IRQ_FLL1_LOCK		0
+#define MADERA_IRQ_FLL2_LOCK		1
+#define MADERA_IRQ_FLL3_LOCK		2
+#define MADERA_IRQ_FLLAO_LOCK		3
+#define MADERA_IRQ_CLK_SYS_ERR		4
+#define MADERA_IRQ_CLK_ASYNC_ERR	5
+#define MADERA_IRQ_CLK_DSP_ERR		6
+#define MADERA_IRQ_HPDET		7
+#define MADERA_IRQ_MICDET1		8
+#define MADERA_IRQ_MICDET2		9
+#define MADERA_IRQ_JD1_RISE		10
+#define MADERA_IRQ_JD1_FALL		11
+#define MADERA_IRQ_JD2_RISE		12
+#define MADERA_IRQ_JD2_FALL		13
+#define MADERA_IRQ_MICD_CLAMP_RISE	14
+#define MADERA_IRQ_MICD_CLAMP_FALL	15
+#define MADERA_IRQ_DRC2_SIG_DET		16
+#define MADERA_IRQ_DRC1_SIG_DET		17
+#define MADERA_IRQ_ASRC1_IN1_LOCK	18
+#define MADERA_IRQ_ASRC1_IN2_LOCK	19
+#define MADERA_IRQ_ASRC2_IN1_LOCK	20
+#define MADERA_IRQ_ASRC2_IN2_LOCK	21
+#define MADERA_IRQ_DSP_IRQ1		22
+#define MADERA_IRQ_DSP_IRQ2		23
+#define MADERA_IRQ_DSP_IRQ3		24
+#define MADERA_IRQ_DSP_IRQ4		25
+#define MADERA_IRQ_DSP_IRQ5		26
+#define MADERA_IRQ_DSP_IRQ6		27
+#define MADERA_IRQ_DSP_IRQ7		28
+#define MADERA_IRQ_DSP_IRQ8		29
+#define MADERA_IRQ_DSP_IRQ9		30
+#define MADERA_IRQ_DSP_IRQ10		31
+#define MADERA_IRQ_DSP_IRQ11		32
+#define MADERA_IRQ_DSP_IRQ12		33
+#define MADERA_IRQ_DSP_IRQ13		34
+#define MADERA_IRQ_DSP_IRQ14		35
+#define MADERA_IRQ_DSP_IRQ15		36
+#define MADERA_IRQ_DSP_IRQ16		37
+#define MADERA_IRQ_HP1L_SC		38
+#define MADERA_IRQ_HP1R_SC		39
+#define MADERA_IRQ_HP2L_SC		40
+#define MADERA_IRQ_HP2R_SC		41
+#define MADERA_IRQ_HP3L_SC		42
+#define MADERA_IRQ_HP3R_SC		43
+#define MADERA_IRQ_SPKOUTL_SC		44
+#define MADERA_IRQ_SPKOUTR_SC		45
+#define MADERA_IRQ_HP1L_ENABLE_DONE	46
+#define MADERA_IRQ_HP1R_ENABLE_DONE	47
+#define MADERA_IRQ_HP2L_ENABLE_DONE	48
+#define MADERA_IRQ_HP2R_ENABLE_DONE	49
+#define MADERA_IRQ_HP3L_ENABLE_DONE	50
+#define MADERA_IRQ_HP3R_ENABLE_DONE	51
+#define MADERA_IRQ_SPKOUTL_ENABLE_DONE	52
+#define MADERA_IRQ_SPKOUTR_ENABLE_DONE	53
+#define MADERA_IRQ_SPK_SHUTDOWN		54
+#define MADERA_IRQ_SPK_OVERHEAT		55
+#define MADERA_IRQ_SPK_OVERHEAT_WARN	56
+#define MADERA_IRQ_GPIO1		57
+#define MADERA_IRQ_GPIO2		58
+#define MADERA_IRQ_GPIO3		59
+#define MADERA_IRQ_GPIO4		60
+#define MADERA_IRQ_GPIO5		61
+#define MADERA_IRQ_GPIO6		62
+#define MADERA_IRQ_GPIO7		63
+#define MADERA_IRQ_GPIO8		64
+#define MADERA_IRQ_DSP1_BUS_ERROR	65
+#define MADERA_IRQ_DSP2_BUS_ERROR	66
+#define MADERA_IRQ_DSP3_BUS_ERROR	67
+#define MADERA_IRQ_DSP4_BUS_ERROR	68
+#define MADERA_IRQ_DSP5_BUS_ERROR	69
+#define MADERA_IRQ_DSP6_BUS_ERROR	70
+#define MADERA_IRQ_DSP7_BUS_ERROR	71
+
+#define MADERA_NUM_IRQ			72
+
+struct madera;
+
+int madera_request_irq(struct madera *madera, int irq, const char *name,
+		       irq_handler_t handler, void *data);
+void madera_free_irq(struct madera *madera, int irq, void *data);
+int madera_set_irq_wake(struct madera *madera, int irq, int on);
+
+#endif
-- 
1.9.1


^ permalink raw reply related

* [PATCH v2 10/18] pinctrl: madera: Add driver for Cirrus Logic Madera codecs
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones-QSEj5FYQhm4dnm+yROfE0A, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	gnurou-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493050124-5970-1-git-send-email-rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>

These codecs have a variable number of I/O lines each of which
is individually selectable to a wide range of possible functions.

The functionality is slightly different from the traditional muxed
GPIO since most of the functions can be mapped to any pin (and even
the same function to multiple pins). Most pins have a dedicated
"alternate" function that is only available on that pin. The
alternate functions are usually a group of signals, though it is
not always necessary to enable the full group, depending on the
alternate function and how it is to be used. The mapping between
alternate functions and GPIO pins varies between codecs depending
on the number of alternate functions and available pins.

Note on the Kconfig options:
The formula "default y if..." is used for PINCTRL_MADERA so that its
select options will be processed, allowing us to group selects for
pinctrl into the pinctrl Kconfig where they logically belong instead
of accumulating under the parent MFD Kconfig.

Signed-off-by: Richard Fitzgerald <rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
---
Changes since V1:
- dt binding moved to separate patch
- moved all source into a subdirectory drivers/pinctrl/cirrus
- split chip-specific tables into separate files
- codec-specific build options are now selected from MFD
- print useful information from madera_pin_dbg_show()
- added gpio_set_direciton / gpio_request_enable / gpio_disable_free functions
- added strict mode so GPIO and other functions are exclusive
- replace #ifdefs with if (IS_ENABLED(...)) in probe
- fixed bug reading registers in madera_pin_conf_get()

 MAINTAINERS                              |    2 +
 drivers/pinctrl/Kconfig                  |    1 +
 drivers/pinctrl/Makefile                 |    1 +
 drivers/pinctrl/cirrus/Kconfig           |   15 +
 drivers/pinctrl/cirrus/Makefile          |   11 +
 drivers/pinctrl/cirrus/pinctrl-cs47l35.c |   46 ++
 drivers/pinctrl/cirrus/pinctrl-cs47l85.c |   60 ++
 drivers/pinctrl/cirrus/pinctrl-cs47l90.c |   58 ++
 drivers/pinctrl/cirrus/pinctrl-madera.c  | 1106 ++++++++++++++++++++++++++++++
 drivers/pinctrl/cirrus/pinctrl-madera.h  |   40 ++
 10 files changed, 1340 insertions(+)
 create mode 100644 drivers/pinctrl/cirrus/Kconfig
 create mode 100644 drivers/pinctrl/cirrus/Makefile
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l35.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l85.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l90.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-madera.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6e8eec6..3e42a03 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3305,11 +3305,13 @@ T:	git https://github.com/CirrusLogic/linux-drivers.git
 W:	https://github.com/CirrusLogic/linux-drivers/wiki
 S:	Supported
 F:	Documentation/devicetree/bindings/mfd/madera.txt
+F:	Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
 F:	include/linux/irqchip/irq-madera*
 F:	include/linux/mfd/madera/*
 F:	drivers/irqchip/irq-madera*
 F:	drivers/mfd/madera*
 F:	drivers/mfd/cs47l*
+F:	drivers/pinctrl/cirrus/*
 
 CLEANCACHE API
 M:	Konrad Rzeszutek Wilk <konrad.wilk-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 37af5e3..59adb0a 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -315,6 +315,7 @@ source "drivers/pinctrl/ti/Kconfig"
 source "drivers/pinctrl/uniphier/Kconfig"
 source "drivers/pinctrl/vt8500/Kconfig"
 source "drivers/pinctrl/mediatek/Kconfig"
+source "drivers/pinctrl/cirrus/Kconfig"
 
 config PINCTRL_XWAY
 	bool
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 5fc3c1d..0129d72 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -58,3 +58,4 @@ obj-y				+= ti/
 obj-$(CONFIG_PINCTRL_UNIPHIER)	+= uniphier/
 obj-$(CONFIG_ARCH_VT8500)	+= vt8500/
 obj-$(CONFIG_PINCTRL_MTK)	+= mediatek/
+obj-y				+= cirrus/
diff --git a/drivers/pinctrl/cirrus/Kconfig b/drivers/pinctrl/cirrus/Kconfig
new file mode 100644
index 0000000..093527ea
--- /dev/null
+++ b/drivers/pinctrl/cirrus/Kconfig
@@ -0,0 +1,15 @@
+config PINCTRL_MADERA
+	bool
+	select PINMUX
+	select GENERIC_PINCONF
+	default y if MFD_MADERA=y
+
+config PINCTRL_CS47L35
+	bool
+
+config PINCTRL_CS47L85
+	bool
+
+config PINCTRL_CS47L90
+	bool
+
diff --git a/drivers/pinctrl/cirrus/Makefile b/drivers/pinctrl/cirrus/Makefile
new file mode 100644
index 0000000..b34473c
--- /dev/null
+++ b/drivers/pinctrl/cirrus/Makefile
@@ -0,0 +1,11 @@
+# Cirrus Logic pinctrl drivers
+obj-$(CONFIG_PINCTRL_MADERA)	+= pinctrl-madera.o
+ifeq ($(CONFIG_PINCTRL_CS47L35),y)
+obj-$(CONFIG_PINCTRL_MADERA)	+= pinctrl-cs47l35.o
+endif
+ifeq ($(CONFIG_PINCTRL_CS47L85),y)
+obj-$(CONFIG_PINCTRL_MADERA)	+= pinctrl-cs47l85.o
+endif
+ifeq ($(CONFIG_PINCTRL_CS47L90),y)
+obj-$(CONFIG_PINCTRL_MADERA)	+= pinctrl-cs47l90.o
+endif
diff --git a/drivers/pinctrl/cirrus/pinctrl-cs47l35.c b/drivers/pinctrl/cirrus/pinctrl-cs47l35.c
new file mode 100644
index 0000000..edf444a
--- /dev/null
+++ b/drivers/pinctrl/cirrus/pinctrl-cs47l35.c
@@ -0,0 +1,46 @@
+/*
+ * Pinctrl for Cirrus Logic CS47L35
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+
+#include <linux/mfd/madera/core.h>
+
+#include "pinctrl-madera.h"
+
+/*
+ * The alt func groups are the most commonly used functions we place these at
+ * the lower function indexes for convenience, and the less commonly used gpio
+ * functions at higher indexes.
+ *
+ * To stay consistent with the datasheet the function names are the same as
+ * the group names for that function's pins
+ *
+ * Note - all 1 less than in datasheet because these are zero-indexed
+ */
+static const unsigned int cs47l35_aif3_pins[] = { 0, 1, 2, 3 };
+static const unsigned int cs47l35_spk_pins[] = { 4, 5 };
+static const unsigned int cs47l35_aif1_pins[] = { 7, 8, 9, 10 };
+static const unsigned int cs47l35_aif2_pins[] = { 11, 12, 13, 14 };
+static const unsigned int cs47l35_mif1_pins[] = { 6, 15 };
+
+static const struct madera_pin_groups cs47l35_pin_groups[] = {
+	{ "aif1", cs47l35_aif1_pins, ARRAY_SIZE(cs47l35_aif1_pins) },
+	{ "aif2", cs47l35_aif2_pins, ARRAY_SIZE(cs47l35_aif2_pins) },
+	{ "aif3", cs47l35_aif3_pins, ARRAY_SIZE(cs47l35_aif3_pins) },
+	{ "mif1", cs47l35_mif1_pins, ARRAY_SIZE(cs47l35_mif1_pins) },
+	{ "pdmspk1", cs47l35_spk_pins, ARRAY_SIZE(cs47l35_spk_pins) },
+};
+
+const struct madera_pin_chip cs47l35_pin_chip = {
+	.n_pins = CS47L35_NUM_GPIOS,
+	.pin_groups = cs47l35_pin_groups,
+	.n_pin_groups = ARRAY_SIZE(cs47l35_pin_groups),
+};
diff --git a/drivers/pinctrl/cirrus/pinctrl-cs47l85.c b/drivers/pinctrl/cirrus/pinctrl-cs47l85.c
new file mode 100644
index 0000000..63e34f8
--- /dev/null
+++ b/drivers/pinctrl/cirrus/pinctrl-cs47l85.c
@@ -0,0 +1,60 @@
+/*
+ * Pinctrl for Cirrus Logic CS47L85
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+
+#include <linux/mfd/madera/core.h>
+
+#include "pinctrl-madera.h"
+
+/*
+ * The alt func groups are the most commonly used functions we place these at
+ * the lower function indexes for convenience, and the less commonly used gpio
+ * functions at higher indexes.
+ *
+ * To stay consistent with the datasheet the function names are the same as
+ * the group names for that function's pins
+ *
+ * Note - all 1 less than in datasheet because these are zero-indexed
+ */
+static const unsigned int cs47l85_mif1_pins[] = { 8, 9 };
+static const unsigned int cs47l85_mif2_pins[] = { 10, 11 };
+static const unsigned int cs47l85_mif3_pins[] = { 12, 13 };
+static const unsigned int cs47l85_aif1_pins[] = { 14, 15, 16, 17 };
+static const unsigned int cs47l85_aif2_pins[] = { 18, 19, 20, 21 };
+static const unsigned int cs47l85_aif3_pins[] = { 22, 23, 24, 25 };
+static const unsigned int cs47l85_aif4_pins[] = { 26, 27, 28, 29 };
+static const unsigned int cs47l85_dmic4_pins[] = { 30, 31 };
+static const unsigned int cs47l85_dmic5_pins[] = { 32, 33 };
+static const unsigned int cs47l85_dmic6_pins[] = { 34, 35 };
+static const unsigned int cs47l85_spk1_pins[] = { 36, 38 };
+static const unsigned int cs47l85_spk2_pins[] = { 37, 39 };
+
+static const struct madera_pin_groups cs47l85_pin_groups[] = {
+	{ "aif1", cs47l85_aif1_pins, ARRAY_SIZE(cs47l85_aif1_pins) },
+	{ "aif2", cs47l85_aif2_pins, ARRAY_SIZE(cs47l85_aif2_pins) },
+	{ "aif3", cs47l85_aif3_pins, ARRAY_SIZE(cs47l85_aif3_pins) },
+	{ "aif4", cs47l85_aif4_pins, ARRAY_SIZE(cs47l85_aif4_pins) },
+	{ "mif1", cs47l85_mif1_pins, ARRAY_SIZE(cs47l85_mif1_pins) },
+	{ "mif2", cs47l85_mif2_pins, ARRAY_SIZE(cs47l85_mif2_pins) },
+	{ "mif3", cs47l85_mif3_pins, ARRAY_SIZE(cs47l85_mif3_pins) },
+	{ "dmic4", cs47l85_dmic4_pins, ARRAY_SIZE(cs47l85_dmic4_pins) },
+	{ "dmic5", cs47l85_dmic5_pins, ARRAY_SIZE(cs47l85_dmic5_pins) },
+	{ "dmic6", cs47l85_dmic6_pins, ARRAY_SIZE(cs47l85_dmic6_pins) },
+	{ "pdmspk1", cs47l85_spk1_pins, ARRAY_SIZE(cs47l85_spk1_pins) },
+	{ "pdmspk2", cs47l85_spk2_pins, ARRAY_SIZE(cs47l85_spk2_pins) },
+};
+
+const struct madera_pin_chip cs47l85_pin_chip = {
+	.n_pins = CS47L85_NUM_GPIOS,
+	.pin_groups = cs47l85_pin_groups,
+	.n_pin_groups = ARRAY_SIZE(cs47l85_pin_groups),
+};
diff --git a/drivers/pinctrl/cirrus/pinctrl-cs47l90.c b/drivers/pinctrl/cirrus/pinctrl-cs47l90.c
new file mode 100644
index 0000000..a1099b3
--- /dev/null
+++ b/drivers/pinctrl/cirrus/pinctrl-cs47l90.c
@@ -0,0 +1,58 @@
+/*
+ * Pinctrl for Cirrus Logic CS47L90
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+
+#include <linux/mfd/madera/core.h>
+
+#include "pinctrl-madera.h"
+
+/*
+ * The alt func groups are the most commonly used functions we place these at
+ * the lower function indexes for convenience, and the less commonly used gpio
+ * functions at higher indexes.
+ *
+ * To stay consistent with the datasheet the function names are the same as
+ * the group names for that function's pins
+ *
+ * Note - all 1 less than in datasheet because these are zero-indexed
+ */
+static const unsigned int cs47l90_mif1_pins[] = { 8, 9 };
+static const unsigned int cs47l90_mif2_pins[] = { 10, 11 };
+static const unsigned int cs47l90_mif3_pins[] = { 12, 13 };
+static const unsigned int cs47l90_aif1_pins[] = { 14, 15, 16, 17 };
+static const unsigned int cs47l90_aif2_pins[] = { 18, 19, 20, 21 };
+static const unsigned int cs47l90_aif3_pins[] = { 22, 23, 24, 25 };
+static const unsigned int cs47l90_aif4_pins[] = { 26, 27, 28, 29 };
+static const unsigned int cs47l90_dmic4_pins[] = { 30, 31 };
+static const unsigned int cs47l90_dmic5_pins[] = { 32, 33 };
+static const unsigned int cs47l90_dmic3_pins[] = { 34, 35 };
+static const unsigned int cs47l90_spk1_pins[] = { 36, 37 };
+
+static const struct madera_pin_groups cs47l90_pin_groups[] = {
+	{ "aif1", cs47l90_aif1_pins, ARRAY_SIZE(cs47l90_aif1_pins) },
+	{ "aif2", cs47l90_aif2_pins, ARRAY_SIZE(cs47l90_aif2_pins) },
+	{ "aif3", cs47l90_aif3_pins, ARRAY_SIZE(cs47l90_aif3_pins) },
+	{ "aif4", cs47l90_aif4_pins, ARRAY_SIZE(cs47l90_aif4_pins) },
+	{ "mif1", cs47l90_mif1_pins, ARRAY_SIZE(cs47l90_mif1_pins) },
+	{ "mif2", cs47l90_mif2_pins, ARRAY_SIZE(cs47l90_mif2_pins) },
+	{ "mif3", cs47l90_mif3_pins, ARRAY_SIZE(cs47l90_mif3_pins) },
+	{ "dmic3", cs47l90_dmic3_pins, ARRAY_SIZE(cs47l90_dmic3_pins) },
+	{ "dmic4", cs47l90_dmic4_pins, ARRAY_SIZE(cs47l90_dmic4_pins) },
+	{ "dmic5", cs47l90_dmic5_pins, ARRAY_SIZE(cs47l90_dmic5_pins) },
+	{ "pdmspk1", cs47l90_spk1_pins, ARRAY_SIZE(cs47l90_spk1_pins) },
+};
+
+const struct madera_pin_chip cs47l90_pin_chip = {
+	.n_pins = CS47L90_NUM_GPIOS,
+	.pin_groups = cs47l90_pin_groups,
+	.n_pin_groups = ARRAY_SIZE(cs47l90_pin_groups),
+};
diff --git a/drivers/pinctrl/cirrus/pinctrl-madera.c b/drivers/pinctrl/cirrus/pinctrl-madera.c
new file mode 100644
index 0000000..6196f89
--- /dev/null
+++ b/drivers/pinctrl/cirrus/pinctrl-madera.c
@@ -0,0 +1,1106 @@
+/*
+ * Pinctrl for Cirrus Logic Madera codecs
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/registers.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-madera.h"
+
+/*
+ * Use pin GPIO names for consistency
+ * NOTE: IDs are zero-indexed for coding convenience
+ */
+static const struct pinctrl_pin_desc madera_pins[] = {
+	PINCTRL_PIN(0, "gpio1"),
+	PINCTRL_PIN(1, "gpio2"),
+	PINCTRL_PIN(2, "gpio3"),
+	PINCTRL_PIN(3, "gpio4"),
+	PINCTRL_PIN(4, "gpio5"),
+	PINCTRL_PIN(5, "gpio6"),
+	PINCTRL_PIN(6, "gpio7"),
+	PINCTRL_PIN(7, "gpio8"),
+	PINCTRL_PIN(8, "gpio9"),
+	PINCTRL_PIN(9, "gpio10"),
+	PINCTRL_PIN(10, "gpio11"),
+	PINCTRL_PIN(11, "gpio12"),
+	PINCTRL_PIN(12, "gpio13"),
+	PINCTRL_PIN(13, "gpio14"),
+	PINCTRL_PIN(14, "gpio15"),
+	PINCTRL_PIN(15, "gpio16"),
+	PINCTRL_PIN(16, "gpio17"),
+	PINCTRL_PIN(17, "gpio18"),
+	PINCTRL_PIN(18, "gpio19"),
+	PINCTRL_PIN(19, "gpio20"),
+	PINCTRL_PIN(20, "gpio21"),
+	PINCTRL_PIN(21, "gpio22"),
+	PINCTRL_PIN(22, "gpio23"),
+	PINCTRL_PIN(23, "gpio24"),
+	PINCTRL_PIN(24, "gpio25"),
+	PINCTRL_PIN(25, "gpio26"),
+	PINCTRL_PIN(26, "gpio27"),
+	PINCTRL_PIN(27, "gpio28"),
+	PINCTRL_PIN(28, "gpio29"),
+	PINCTRL_PIN(29, "gpio30"),
+	PINCTRL_PIN(30, "gpio31"),
+	PINCTRL_PIN(31, "gpio32"),
+	PINCTRL_PIN(32, "gpio33"),
+	PINCTRL_PIN(33, "gpio34"),
+	PINCTRL_PIN(34, "gpio35"),
+	PINCTRL_PIN(35, "gpio36"),
+	PINCTRL_PIN(36, "gpio37"),
+	PINCTRL_PIN(37, "gpio38"),
+	PINCTRL_PIN(38, "gpio39"),
+	PINCTRL_PIN(39, "gpio40"),
+};
+
+/*
+ * All single-pin functions can be mapped to any GPIO, however pinmux applies
+ * functions to pin groups and only those groups declared as supporting that
+ * function. To make this work we must put each pin in its own dummy group so
+ * that the functions can be described as applying to all pins.
+ * Since these do not correspond to anything in the actual hardware - they are
+ * merely an adaptation to pinctrl's view of the world - we use the same name
+ * as the pin to avoid confusion when comparing with datasheet instructions
+ */
+static const char * const madera_pin_single_group_names[] = {
+	"gpio1",  "gpio2",  "gpio3",  "gpio4",  "gpio5",  "gpio6",  "gpio7",
+	"gpio8",  "gpio9",  "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+	"gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+	"gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+	"gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+	"gpio36", "gpio37", "gpio38", "gpio39", "gpio40",
+};
+
+/* set of pin numbers for single-pin groups, zero-indexed */
+static const unsigned int madera_pin_single_group_pins[] = {
+	  0,  1,  2,  3,  4,  5,  6,
+	  7,  8,  9, 10, 11, 12, 13,
+	 14, 15, 16, 17, 18, 19, 20,
+	 21, 22, 23, 24, 25, 26, 27,
+	 28, 29, 30, 31, 32, 33, 34,
+	 35, 36, 37, 38, 39,
+};
+
+static const char * const madera_aif1_group_names[] = { "aif1" };
+static const char * const madera_aif2_group_names[] = { "aif2" };
+static const char * const madera_aif3_group_names[] = { "aif3" };
+static const char * const madera_aif4_group_names[] = { "aif4" };
+static const char * const madera_mif1_group_names[] = { "mif1" };
+static const char * const madera_mif2_group_names[] = { "mif2" };
+static const char * const madera_mif3_group_names[] = { "mif3" };
+static const char * const madera_dmic3_group_names[] = { "dmic3" };
+static const char * const madera_dmic4_group_names[] = { "dmic4" };
+static const char * const madera_dmic5_group_names[] = { "dmic5" };
+static const char * const madera_dmic6_group_names[] = { "dmic6" };
+static const char * const madera_spk1_group_names[] = { "pdmspk1" };
+static const char * const madera_spk2_group_names[] = { "pdmspk2" };
+
+/*
+ * alt-functions always apply to a single pin group, other functions always
+ * apply to all pins
+ */
+static const struct {
+	const char *name;
+	const char * const *group_names;
+	u32 func;
+} madera_mux_funcs[] = {
+	{
+		.name = "aif1",
+		.group_names = madera_aif1_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "aif2",
+		.group_names = madera_aif2_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "aif3",
+		.group_names = madera_aif3_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "aif4",
+		.group_names = madera_aif4_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "mif1",
+		.group_names = madera_mif1_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "mif2",
+		.group_names = madera_mif2_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "mif3",
+		.group_names = madera_mif3_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "dmic3",
+		.group_names = madera_dmic3_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "dmic4",
+		.group_names = madera_dmic4_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "dmic5",
+		.group_names = madera_dmic5_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "dmic6",
+		.group_names = madera_dmic6_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "pdmspk1",
+		.group_names = madera_spk1_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "pdmspk2",
+		.group_names = madera_spk2_group_names,
+		.func = 0x000
+	},
+	{
+		.name = "io",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x001
+	},
+	{
+		.name = "dsp-gpio",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x002
+	},
+	{
+		.name = "irq1",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x003
+	},
+	{
+		.name = "irq2",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x004
+	},
+	{
+		.name = "fll1-clk",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x010
+	},
+	{
+		.name = "fll2-clk",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x011
+	},
+	{
+		.name = "fll3-clk",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x012
+	},
+	{
+		.name = "fllao-clk",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x013
+	},
+	{
+		.name = "fll1-lock",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x018
+	},
+	{
+		.name = "fll2-lock",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x019
+	},
+	{
+		.name = "fll3-lock",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x01a
+	},
+	{
+		.name = "fllao-lock",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x01b
+	},
+	{
+		.name = "opclk",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x040
+	},
+	{
+		.name = "opclk-async",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x041
+	},
+	{
+		.name = "pwm1",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x048
+	},
+	{
+		.name = "pwm2",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x049
+	},
+	{
+		.name = "spdif",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x04c
+	},
+	{
+		.name = "asrc1-in1-lock",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x088
+	},
+	{
+		.name = "asrc1-in2-lock",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x089
+	},
+	{
+		.name = "asrc2-in1-lock",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x08a
+	},
+	{
+		.name = "asrc2-in2-lock",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x08b
+	},
+	{
+		.name = "spkl-short-circuit",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x0b6
+	},
+	{
+		.name = "spkr-short-circuit",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x0b7
+	},
+	{
+		.name = "spk-shutdown",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x0e0
+	},
+	{
+		.name = "spk-overheat-shutdown",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x0e1
+	},
+	{
+		.name = "spk-overheat-warn",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x0e2
+	},
+	{
+		.name = "timer1-sts",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x140
+	},
+	{
+		.name = "timer2-sts",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x141
+	},
+	{
+		.name = "timer3-sts",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x142
+	},
+	{
+		.name = "timer4-sts",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x143
+	},
+	{
+		.name = "timer5-sts",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x144
+	},
+	{
+		.name = "timer6-sts",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x145
+	},
+	{
+		.name = "timer7-sts",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x146
+	},
+	{
+		.name = "timer8-sts",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x147
+	},
+	{
+		.name = "log1-fifo-ne",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x150
+	},
+	{
+		.name = "log2-fifo-ne",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x151
+	},
+	{
+		.name = "log3-fifo-ne",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x152
+	},
+	{
+		.name = "log4-fifo-ne",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x153
+	},
+	{
+		.name = "log5-fifo-ne",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x154
+	},
+	{
+		.name = "log6-fifo-ne",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x155
+	},
+	{
+		.name = "log7-fifo-ne",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x156
+	},
+	{
+		.name = "log8-fifo-ne",
+		.group_names = madera_pin_single_group_names,
+		.func = 0x157
+	},
+};
+
+static u16 madera_pin_make_drv_str(struct madera_pin_private *priv,
+				      unsigned int milliamps)
+{
+	switch (priv->madera->type) {
+	case CS47L35:
+	case CS47L85:
+	case CS47L90:
+	case WM1840:
+		switch (milliamps) {
+		case 4:
+			return 0;
+		case 8:
+			return 2 << MADERA_GP1_DRV_STR_SHIFT;
+		default:
+			break;
+		}
+		break;
+
+	default:
+		switch (milliamps) {
+		case 4:
+			return 0;
+		case 8:
+			return 1 << MADERA_GP1_DRV_STR_SHIFT;
+		case 12:
+			return 2 << MADERA_GP1_DRV_STR_SHIFT;
+		case 16:
+			return 3 << MADERA_GP1_DRV_STR_SHIFT;
+		default:
+			break;
+		}
+		break;
+	}
+
+	dev_warn(priv->dev, "%u mA not a valid drive strength", milliamps);
+
+	return 0;
+}
+
+static unsigned int madera_pin_unmake_drv_str(struct madera_pin_private *priv,
+					      u16 regval)
+{
+	regval = (regval & MADERA_GP1_DRV_STR_MASK) >> MADERA_GP1_DRV_STR_SHIFT;
+
+	switch (priv->madera->type) {
+	case CS47L35:
+	case CS47L85:
+	case CS47L90:
+	case WM1840:
+		switch (regval) {
+		case 0:
+			return 4;
+		case 2:
+			return 8;
+		default:
+			return 0;
+		}
+
+	default:
+		switch (regval) {
+		case 0:
+			return 4;
+		case 1:
+			return 8;
+		case 2:
+			return 12;
+		case 3:
+			return 16;
+		default:
+			return 0;
+		}
+	}
+}
+
+static int madera_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+
+	/* Number of alt function groups plus number of single-pin groups */
+	return priv->chip->n_pin_groups + priv->chip->n_pins;
+}
+
+static const char *madera_get_group_name(struct pinctrl_dev *pctldev,
+					 unsigned int selector)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+
+	if (selector < priv->chip->n_pin_groups) {
+		return priv->chip->pin_groups[selector].name;
+	} else {
+		selector -= priv->chip->n_pin_groups;
+		return madera_pin_single_group_names[selector];
+	}
+}
+
+static int madera_get_group_pins(struct pinctrl_dev *pctldev,
+				 unsigned int selector,
+				 const unsigned int **pins,
+				 unsigned int *num_pins)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+
+	if (selector < priv->chip->n_pin_groups) {
+		*pins = priv->chip->pin_groups[selector].pins;
+		*num_pins = priv->chip->pin_groups[selector].n_pins;
+	} else {
+		/* return the dummy group for a single pin */
+		selector -= priv->chip->n_pin_groups;
+		*pins = &madera_pin_single_group_pins[selector];
+		*num_pins = 1;
+	}
+	return 0;
+}
+
+static void madera_pin_dbg_show_fn(struct madera_pin_private *priv,
+				   struct seq_file *s,
+				   unsigned int pin, unsigned int fn)
+{
+	const struct madera_pin_chip *chip = priv->chip;
+	int i, g_pin;
+
+	if (fn != 0) {
+		for (i = 0; i < ARRAY_SIZE(madera_mux_funcs); ++i) {
+			if (madera_mux_funcs[i].func == fn) {
+				seq_printf(s, " FN=%s",
+					   madera_mux_funcs[i].name);
+				return;
+			}
+		}
+		return;	/* ignore unknown function values */
+	}
+
+	/* alt function */
+	for (i = 0; i < chip->n_pin_groups; ++i) {
+		for (g_pin = 0; g_pin < chip->pin_groups[i].n_pins; ++g_pin) {
+			if (chip->pin_groups[i].pins[g_pin] == pin) {
+				seq_printf(s, " FN=%s",
+					   chip->pin_groups[i].name);
+				return;
+			}
+		}
+	}
+}
+
+static void madera_pin_dbg_show(struct pinctrl_dev *pctldev,
+				struct seq_file *s,
+				unsigned int pin)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+	unsigned int conf[2];
+	unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
+	unsigned int fn;
+	int ret;
+
+	ret = regmap_read(priv->madera->regmap, reg, &conf[0]);
+	if (ret)
+		return;
+
+	ret = regmap_read(priv->madera->regmap, reg + 1, &conf[1]);
+	if (ret)
+		return;
+
+	seq_printf(s, "%04x:%04x", conf[0], conf[1]);
+
+	fn = (conf[0] & MADERA_GP1_FN_MASK) >> MADERA_GP1_FN_SHIFT;
+	madera_pin_dbg_show_fn(priv, s, pin, fn);
+
+	/* State of direction bit is only relevant if function==1 */
+	if (fn == 1) {
+		if (conf[1] & MADERA_GP1_DIR_MASK)
+			seq_puts(s, " IN");
+		else
+			seq_puts(s, " OUT");
+	}
+
+	if (conf[1] & MADERA_GP1_PU_MASK)
+		seq_puts(s, " PU");
+
+	if (conf[1] & MADERA_GP1_PD_MASK)
+		seq_puts(s, " PD");
+
+	if (conf[0] & MADERA_GP1_DB_MASK)
+		seq_puts(s, " DB");
+
+	if (conf[0] & MADERA_GP1_OP_CFG_MASK)
+		seq_puts(s, " OD");
+	else
+		seq_puts(s, " CMOS");
+
+	seq_printf(s, " DRV=%umA", madera_pin_unmake_drv_str(priv, conf[1]));
+
+	if (conf[0] & MADERA_GP1_IP_CFG_MASK)
+		seq_puts(s, "SCHMITT");
+}
+
+
+static const struct pinctrl_ops madera_pin_group_ops = {
+	.get_groups_count = madera_get_groups_count,
+	.get_group_name = madera_get_group_name,
+	.get_group_pins = madera_get_group_pins,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+	.dt_free_map = pinctrl_utils_free_map,
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+	.pin_dbg_show = madera_pin_dbg_show,
+#endif
+};
+
+static int madera_mux_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(madera_mux_funcs);
+}
+
+static const char *madera_mux_get_func_name(struct pinctrl_dev *pctldev,
+					    unsigned int selector)
+{
+	return madera_mux_funcs[selector].name;
+}
+
+static int madera_mux_get_groups(struct pinctrl_dev *pctldev,
+				 unsigned int selector,
+				 const char * const **groups,
+				 unsigned int * const num_groups)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = madera_mux_funcs[selector].group_names;
+
+	if (madera_mux_funcs[selector].func == 0) {
+		/* alt func always maps to a single group */
+		*num_groups = 1;
+	} else {
+		/* other funcs map to all available gpio pins */
+		*num_groups = priv->chip->n_pins;
+	}
+
+	return 0;
+}
+
+static int madera_mux_set_mux(struct pinctrl_dev *pctldev,
+			      unsigned int selector,
+			      unsigned int group)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+	struct madera *madera = priv->madera;
+	const struct madera_pin_groups *pin_group = priv->chip->pin_groups;
+	unsigned int n_chip_groups = priv->chip->n_pin_groups;
+	const char *func_name = madera_mux_funcs[selector].name;
+	unsigned int reg;
+	int i, ret;
+
+	dev_dbg(priv->dev, "%s selecting %u (%s) for group %u (%s)\n",
+		__func__, selector, func_name, group,
+		madera_get_group_name(pctldev, group));
+
+	if (madera_mux_funcs[selector].func == 0) {
+		/* alt func pin assignments are codec-specific */
+		for (i = 0; i < n_chip_groups; ++i) {
+			if (strcmp(func_name, pin_group->name) == 0)
+				break;
+
+			++pin_group;
+		}
+
+		if (i == n_chip_groups)
+			return -EINVAL;
+
+		for (i = 0; i < pin_group->n_pins; ++i) {
+			reg = MADERA_GPIO1_CTRL_1 + (2 * pin_group->pins[i]);
+
+			dev_dbg(priv->dev, "%s setting 0x%x func bits to 0\n",
+				__func__, reg);
+
+			ret = regmap_update_bits(madera->regmap, reg, 0x1ff, 0);
+			if (ret)
+				break;
+
+		}
+	} else {
+		/*
+		 * for other funcs the group will be the gpio number and will
+		 * be offset by the number of chip-specific functions at the
+		 * start of the group list
+		 */
+		group -= n_chip_groups;
+		reg = MADERA_GPIO1_CTRL_1 + (2 * group);
+
+		dev_dbg(priv->dev, "%s setting 0x%x func bits to 0x%x\n",
+			__func__, reg, madera_mux_funcs[selector].func);
+
+		ret = regmap_update_bits(madera->regmap,
+					 reg,
+					 0x1ff,
+					 madera_mux_funcs[selector].func);
+	}
+
+	if (ret)
+		dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
+
+	return ret;
+}
+
+static int madera_gpio_set_direction(struct pinctrl_dev *pctldev,
+				     struct pinctrl_gpio_range *range,
+				     unsigned int offset,
+				     bool input)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+	struct madera *madera = priv->madera;
+	unsigned int reg = MADERA_GPIO1_CTRL_2 + (2 * offset);
+	unsigned int val;
+	int ret;
+
+	if (input)
+		val = MADERA_GP1_DIR;
+	else
+		val = 0;
+
+	ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_DIR_MASK, val);
+	if (ret)
+		dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
+
+	return ret;
+}
+
+static int madera_gpio_request_enable(struct pinctrl_dev *pctldev,
+				      struct pinctrl_gpio_range *range,
+				      unsigned int offset)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+	struct madera *madera = priv->madera;
+	unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * offset);
+	int ret;
+
+	/* put the pin into GPIO mode */
+	ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_FN_MASK, 1);
+	if (ret)
+		dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
+
+	return ret;
+}
+
+static void madera_gpio_disable_free(struct pinctrl_dev *pctldev,
+				     struct pinctrl_gpio_range *range,
+				     unsigned int offset)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+	struct madera *madera = priv->madera;
+	unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * offset);
+	int ret;
+
+	/* disable GPIO by setting to GPIO IN */
+	madera_gpio_set_direction(pctldev, range, offset, true);
+
+	ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_FN_MASK, 1);
+	if (ret)
+		dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
+}
+
+static const struct pinmux_ops madera_pin_mux_ops = {
+	.get_functions_count = madera_mux_get_funcs_count,
+	.get_function_name = madera_mux_get_func_name,
+	.get_function_groups = madera_mux_get_groups,
+	.set_mux = madera_mux_set_mux,
+	.gpio_request_enable = madera_gpio_request_enable,
+	.gpio_disable_free = madera_gpio_disable_free,
+	.gpio_set_direction = madera_gpio_set_direction,
+	.strict = true, /* GPIO and other functions are exclusive */
+};
+
+static int madera_pin_conf_get(struct pinctrl_dev *pctldev, unsigned int pin,
+			       unsigned long *config)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+	unsigned int param = pinconf_to_config_param(*config);
+	unsigned int result = 0;
+	unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
+	unsigned int conf[2];
+	int ret;
+
+	ret = regmap_read(priv->madera->regmap, reg, &conf[0]);
+	if (!ret)
+		ret = regmap_read(priv->madera->regmap, reg + 1, &conf[1]);
+
+	if (ret) {
+		dev_err(priv->dev, "Failed to read GP%d conf (%d)\n",
+			pin + 1, ret);
+		return ret;
+	}
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_BUS_HOLD:
+		conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
+		if (conf[1] == (MADERA_GP1_PU | MADERA_GP1_PD))
+			result = 1;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
+		if (!conf[1])
+			result = 1;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
+		if (conf[1] == MADERA_GP1_PD_MASK)
+			result = 1;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
+		if (conf[1] == MADERA_GP1_PU_MASK)
+			result = 1;
+		break;
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		if (conf[0] & MADERA_GP1_OP_CFG_MASK)
+			result = 1;
+		break;
+	case PIN_CONFIG_DRIVE_PUSH_PULL:
+		if (!(conf[0] & MADERA_GP1_OP_CFG_MASK))
+			result = 1;
+		break;
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		result = madera_pin_unmake_drv_str(priv, conf[1]);
+		break;
+	case PIN_CONFIG_INPUT_DEBOUNCE:
+		if (conf[0] & MADERA_GP1_DB_MASK)
+			result = 1;
+		break;
+	case PIN_CONFIG_INPUT_ENABLE:
+		if (conf[0] & MADERA_GP1_DIR_MASK)
+			result = 1;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT:
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		if (conf[0] & MADERA_GP1_IP_CFG_MASK)
+			result = 1;
+		break;
+	case PIN_CONFIG_OUTPUT:
+		if ((conf[1] & MADERA_GP1_DIR_MASK) &&
+		    (conf[0] & MADERA_GP1_LVL_MASK))
+			result = 1;
+		break;
+	default:
+		break;
+	}
+
+	*config = pinconf_to_config_packed(param, result);
+
+	return 0;
+}
+
+static int madera_pin_conf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+			       unsigned long *configs, unsigned int num_configs)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+	u16 conf[2] = {0, 0};
+	u16 mask[2] = {0, 0};
+	unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
+	unsigned int val;
+	int ret;
+
+	while (num_configs) {
+		dev_dbg(priv->dev, "%s config 0x%lx\n", __func__, *configs);
+
+		switch (pinconf_to_config_param(*configs)) {
+		case PIN_CONFIG_BIAS_BUS_HOLD:
+			mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
+			conf[1] |= MADERA_GP1_PU | MADERA_GP1_PD;
+			break;
+		case PIN_CONFIG_BIAS_DISABLE:
+			mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
+			conf[1] &= ~(MADERA_GP1_PU | MADERA_GP1_PD);
+			break;
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
+			conf[1] |= MADERA_GP1_PD;
+			conf[1] &= ~MADERA_GP1_PU;
+			break;
+		case PIN_CONFIG_BIAS_PULL_UP:
+			mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
+			conf[1] |= MADERA_GP1_PU;
+			conf[1] &= ~MADERA_GP1_PD;
+			break;
+		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+			mask[0] |= MADERA_GP1_OP_CFG_MASK;
+			conf[0] |= MADERA_GP1_OP_CFG;
+			break;
+		case PIN_CONFIG_DRIVE_PUSH_PULL:
+			mask[0] |= MADERA_GP1_OP_CFG_MASK;
+			conf[0] &= ~MADERA_GP1_OP_CFG;
+			break;
+		case PIN_CONFIG_DRIVE_STRENGTH:
+			val = pinconf_to_config_argument(*configs);
+			mask[1] |= MADERA_GP1_DRV_STR_MASK;
+			conf[1] &= ~MADERA_GP1_DRV_STR_MASK;
+			conf[1] |= madera_pin_make_drv_str(priv, val);
+			break;
+		case PIN_CONFIG_INPUT_DEBOUNCE:
+			mask[0] |= MADERA_GP1_DB_MASK;
+
+			/*
+			 * we can't configure debounce time per-pin so value
+			 * is just a flag
+			 */
+			val = pinconf_to_config_argument(*configs);
+			if (val)
+				conf[0] |= MADERA_GP1_DB;
+			else
+				conf[0] &= ~MADERA_GP1_DB;
+			break;
+		case PIN_CONFIG_INPUT_ENABLE:
+			val = pinconf_to_config_argument(*configs);
+			mask[1] |= MADERA_GP1_DIR_MASK;
+			if (val)
+				conf[1] |= MADERA_GP1_DIR;
+			else
+				conf[1] &= ~MADERA_GP1_DIR;
+			break;
+		case PIN_CONFIG_INPUT_SCHMITT:
+			val = pinconf_to_config_argument(*configs);
+			mask[0] |= MADERA_GP1_IP_CFG;
+			if (val)
+				conf[0] |= MADERA_GP1_IP_CFG;
+			else
+				conf[0] &= ~MADERA_GP1_IP_CFG;
+
+			mask[1] |= MADERA_GP1_DIR_MASK;
+			conf[1] |= MADERA_GP1_DIR;
+			break;
+		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+			mask[0] |= MADERA_GP1_IP_CFG;
+			conf[0] |= MADERA_GP1_IP_CFG;
+			mask[1] |= MADERA_GP1_DIR_MASK;
+			conf[1] |= MADERA_GP1_DIR;
+			break;
+		case PIN_CONFIG_OUTPUT:
+			val = pinconf_to_config_argument(*configs);
+			mask[0] |= MADERA_GP1_LVL_MASK;
+			if (val)
+				conf[0] |= MADERA_GP1_LVL;
+			else
+				conf[0] &= ~MADERA_GP1_LVL;
+
+			mask[1] |= MADERA_GP1_DIR_MASK;
+			conf[1] &= ~MADERA_GP1_DIR;
+			break;
+		default:
+			break;
+		}
+
+		++configs;
+		--num_configs;
+	}
+
+	dev_dbg(priv->dev,
+		"%s gpio%d 0x%x:0x%x 0x%x:0x%x\n",
+		__func__, pin + 1, reg, conf[0], reg + 1, conf[1]);
+
+	ret = regmap_update_bits(priv->madera->regmap, reg, mask[0], conf[0]);
+	if (ret)
+		goto err;
+
+	++reg;
+	ret = regmap_update_bits(priv->madera->regmap, reg, mask[1], conf[1]);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	dev_err(priv->dev,
+		"Failed to write GPIO%d conf (%d) reg 0x%x\n",
+		pin + 1, ret, reg);
+
+	return ret;
+}
+
+static int madera_pin_conf_group_set(struct pinctrl_dev *pctldev,
+				     unsigned int selector,
+				     unsigned long *configs,
+				     unsigned int num_configs)
+{
+	struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
+	const struct madera_pin_groups *pin_group;
+	unsigned int n_groups = priv->chip->n_pin_groups;
+	int i, ret;
+
+	dev_dbg(priv->dev, "%s setting group %s\n", __func__,
+		madera_get_group_name(pctldev, selector));
+
+	if (selector >= n_groups) {
+		/* group is a single pin, convert to pin number and set */
+		return madera_pin_conf_set(pctldev,
+					   selector - n_groups,
+					   configs,
+					   num_configs);
+	} else {
+		pin_group = &priv->chip->pin_groups[selector];
+
+		for (i = 0; i < pin_group->n_pins; ++i) {
+			ret = madera_pin_conf_set(pctldev,
+						  pin_group->pins[i],
+						  configs,
+						  num_configs);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct pinconf_ops madera_pin_conf_ops = {
+	.pin_config_get = madera_pin_conf_get,
+	.pin_config_set = madera_pin_conf_set,
+	.pin_config_group_set = madera_pin_conf_group_set,
+
+};
+
+static struct pinctrl_desc madera_pin_desc = {
+	.name = "madera-pinctrl",
+	.pins = madera_pins,
+	.pctlops = &madera_pin_group_ops,
+	.pmxops = &madera_pin_mux_ops,
+	.confops = &madera_pin_conf_ops,
+	.owner = THIS_MODULE,
+};
+
+static int madera_pin_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	const struct madera_pdata *pdata = dev_get_platdata(madera->dev);
+	struct madera_pin_private *priv;
+	int ret;
+
+	BUILD_BUG_ON(ARRAY_SIZE(madera_pin_single_group_names) !=
+		     ARRAY_SIZE(madera_pin_single_group_pins));
+
+	dev_dbg(&pdev->dev, "%s\n", __func__);
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = &pdev->dev;
+	priv->madera = madera;
+	pdev->dev.of_node = madera->dev->of_node;
+
+	switch (madera->type) {
+	case CS47L35:
+		if (IS_ENABLED(CONFIG_PINCTRL_CS47L35))
+			priv->chip = &cs47l35_pin_chip;
+		break;
+	case CS47L85:
+	case WM1840:
+		if (IS_ENABLED(CONFIG_PINCTRL_CS47L85))
+			priv->chip = &cs47l85_pin_chip;
+		break;
+	case CS47L90:
+	case CS47L91:
+		if (IS_ENABLED(CONFIG_PINCTRL_CS47L90))
+			priv->chip = &cs47l90_pin_chip;
+		break;
+	default:
+		break;
+	}
+
+	if (!priv->chip)
+		return -ENODEV;
+
+	madera_pin_desc.npins = priv->chip->n_pins;
+
+	priv->pctl = devm_pinctrl_register(&pdev->dev, &madera_pin_desc, priv);
+	if (IS_ERR(priv->pctl)) {
+		ret = PTR_ERR(priv->pctl);
+		dev_err(priv->dev, "Failed pinctrl register (%d)\n", ret);
+		return ret;
+	}
+
+	if (pdata) {
+		ret = pinctrl_register_mappings(pdata->gpio_configs,
+						pdata->n_gpio_configs);
+		if (ret) {
+			dev_err(priv->dev,
+				"Failed to register pdata mappings (%d)\n",
+				ret);
+			return ret;
+		}
+	}
+
+	dev_dbg(priv->dev, "pinctrl registered\n");
+
+	return 0;
+}
+
+static struct platform_driver madera_pin_driver = {
+	.probe = madera_pin_probe,
+	.driver = {
+		.name = "madera-pinctrl",
+	},
+};
+
+module_platform_driver(madera_pin_driver);
+
+MODULE_DESCRIPTION("Madera pinctrl driver");
+MODULE_AUTHOR("Richard Fitzgerald <rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/cirrus/pinctrl-madera.h b/drivers/pinctrl/cirrus/pinctrl-madera.h
new file mode 100644
index 0000000..7b55e22
--- /dev/null
+++ b/drivers/pinctrl/cirrus/pinctrl-madera.h
@@ -0,0 +1,40 @@
+/*
+ * Pinctrl for Cirrus Logic Madera codecs
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef PINCTRL_MADERA_H
+#define PINCTRL_MADERA_H
+
+struct madera_pin_groups {
+	const char *name;
+	const unsigned int *pins;
+	unsigned int n_pins;
+};
+
+struct madera_pin_chip {
+	unsigned int n_pins;
+
+	const struct madera_pin_groups *pin_groups;
+	unsigned int n_pin_groups;
+};
+
+struct madera_pin_private {
+	struct madera *madera;
+
+	const struct madera_pin_chip *chip; /* chip-specific groups */
+
+	struct device *dev;
+	struct pinctrl_dev *pctl;
+};
+
+extern const struct madera_pin_chip cs47l35_pin_chip;
+extern const struct madera_pin_chip cs47l85_pin_chip;
+extern const struct madera_pin_chip cs47l90_pin_chip;
+
+#endif
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 11/18] dt-bindings: pinctrl: Add bindings for Cirrus Logic Madera codecs
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones, broonie, linus.walleij, gnurou, robh+dt, tglx, jason
  Cc: linux-gpio, alsa-devel, patches, linux-kernel, devicetree
In-Reply-To: <1493050124-5970-1-git-send-email-rf@opensource.wolfsonmicro.com>

This is the binding description of the pinctrl driver for Cirru Logic
Madera codecs. The binding uses the generic pinctrl binding so  the main
purpose here is to describe the device-specific names for groups and
functions.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
Changes since V1:
- split out from main pinctrl patch into a separate patch
- fixed typo in pinctrl-names property description

 .../bindings/pinctrl/cirrus,madera-pinctrl.txt     | 102 +++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
new file mode 100644
index 0000000..0de91b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
@@ -0,0 +1,102 @@
+Cirrus Logic Madera class audio codecs pinctrl driver
+
+The Cirrus Logic Madera codecs provide a number of GPIO functions for
+interfacing to external hardware and to provide logic outputs to other devices.
+Certain groups of GPIO pins also have an alternate function, normally as an
+audio interface.
+
+The set of available GPIOs, functions and alternate function groups differs
+between codecs so refer to the datasheet for the codec for further information
+on what is supported on that device.
+
+The root node for this driver must be a subnode of the parent MFD driver node.
+It contains one subnode that is a container for an arbitrary number of subnodes
+to configure each pin or function group.
+
+See also
+  the core bindings for the parent MFD driver:
+    Documentation/devicetree/bindings/mfd/madera.txt
+
+  the generic pinmix bindings:
+    Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+
+Required properties of parent mfd node:
+  - pinctrl-names : must be "default"
+  - pinctrl-0 : a phandle to the node containing the configuration subnodes
+
+Required properties of pinctrl subnode:
+  - compatible : must be "cirrus,madera-pinctrl"
+
+Required properties of configuration subnodes:
+  - groups : name of one pin group to configure. One of:
+	aif1, aif2, aif3, aif4, mif1, mif2, mif3, pdmspk1, pdmspk2,
+	dmic4, dmic5, dmic6,
+	gpio1, gpio2, ..., gpio40
+    The gpioN groups select the single pin of this name for configuration
+
+Optional properties of configuration subnodes:
+  Any configuration option not explicitly listed in the dts will be left at
+  chip default setting.
+
+  - function : name of function to assign to this group. One of:
+	aif1, aif2, aif3, aif4, mif1, mif2, mif3, pdmspk1, pdmspk2,
+	dmic3, dmic4, dmic5, dmic6,
+	io, dsp-gpio, irq1, irq2,
+	fll1-clk, fll1-lock, fll2-clk, fll2-lock, fll3-clk, fll3-lock,
+	fllao-clk, fllao-lock,
+	opclk, opclk-async, pwm1, pwm2, spdif,
+	asrc1-in1-lock, asrc1-in2-lock, asrc2-in1-lock, asrc2-in2-lock,
+	spkl-short-circuit, spkr-short-circuit, spk-shutdown,
+	spk-overheat-shutdown, spk-overheat-warn,
+	timer1-sts, timer2-sts, timer3-sts, timer4-sts, timer5-sts, timer6-sts,
+	timer7-sts, timer8-sts,
+	log1-fifo-ne, log2-fifo-ne, log3-fifo-ne, log4-fifo-ne, log5-fifo-ne,
+	log6-fifo-ne, log7-fifo-ne, log8-fifo-ne,
+
+  - bias-disable : disable pull-up and pull-down
+  - bias-bus-hold : enable buskeeper
+  - bias-pull-up : output is pulled-up
+  - bias-pull-down : output is pulled-down
+  - drive-push-pull : CMOS output
+  - drive-open-drain : open-drain output
+  - drive-strength : drive strength in mA. Valid values are 4 or 8
+  - input-schmitt-enable : enable schmitt-trigger mode
+  - input-schmitt-disable : disable schmitt-trigger mode
+  - input-debounce : A value of 0 disables debounce, a value !=0 enables
+	debounce
+  - output-low : set the pin to output mode with low level
+  - output-high : set the pin to output mode with high level
+
+Example:
+
+cs47l85@0 {
+	compatible = "cirrus,cs47l85";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&cs47l85_gpio_defaults>;
+
+	pinctrl {
+		compatible = "cirrus,madera-pinctrl";
+
+		cs47l85_gpio_defaults: defaults {
+			aif1 {
+				groups = "aif1";
+				function = "aif1";
+				bias-bus-hold;
+			};
+
+			aif2 {
+				groups = "aif2";
+				function = "aif2";
+				bias-bus-hold;
+			};
+
+			opclk {
+				groups = "gpio1";
+				function = "opclk";
+				bias-pull-up;
+				drive-strength = <8>;
+			};
+		};
+	};
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones, broonie, linus.walleij, gnurou, robh+dt, tglx, jason
  Cc: alsa-devel, patches, linux-gpio, devicetree, linux-kernel
In-Reply-To: <1493050124-5970-1-git-send-email-rf@opensource.wolfsonmicro.com>

This adds support for the GPIOs on Cirrus Logic Madera class codecs.
Any pins not used for special functions (see the pinctrl driver) can be
used as general single-bit input or output lines. The number of available
GPIOs varies between codecs.

Signed-off-by: Nariman Poushin <nariman@opensource.wolfsonmicro.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
Changes from V1:
- dt bindings moved to a separate patch
- dependent on pinctrl driver instead of parent MFD
- added get_direction function
- added .request / .free / .set_config to work with pinctrl driver
- register range with pinctrl driver

 MAINTAINERS                |   2 +
 drivers/gpio/Kconfig       |   6 ++
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/gpio-madera.c | 196 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 205 insertions(+)
 create mode 100644 drivers/gpio/gpio-madera.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3e42a03..66c5263 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3304,10 +3304,12 @@ L:	patches@opensource.wolfsonmicro.com
 T:	git https://github.com/CirrusLogic/linux-drivers.git
 W:	https://github.com/CirrusLogic/linux-drivers/wiki
 S:	Supported
+F:	Documentation/devicetree/bindings/gpio/gpio-madera.txt
 F:	Documentation/devicetree/bindings/mfd/madera.txt
 F:	Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
 F:	include/linux/irqchip/irq-madera*
 F:	include/linux/mfd/madera/*
+F:	drivers/gpio/gpio-madera*
 F:	drivers/irqchip/irq-madera*
 F:	drivers/mfd/madera*
 F:	drivers/mfd/cs47l*
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 05e8fbf..9488abe 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -941,6 +941,12 @@ config GPIO_LP873X
 	  This driver can also be built as a module. If so, the module will be
           called gpio-lp873x.
 
+config GPIO_MADERA
+	bool "Cirrus Logic Madera class codecs"
+	depends on PINCTRL_MADERA
+	help
+	  Support for GPIOs on Cirrus Logic Madera class codecs.
+
 config GPIO_MAX77620
 	tristate "GPIO support for PMIC MAX77620 and MAX20024"
 	depends on MFD_MAX77620
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 095598e..d4b6c30 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_GPIO_LPC18XX)	+= gpio-lpc18xx.o
 obj-$(CONFIG_ARCH_LPC32XX)	+= gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_LP873X)	+= gpio-lp873x.o
 obj-$(CONFIG_GPIO_LYNXPOINT)	+= gpio-lynxpoint.o
+obj-$(CONFIG_GPIO_MADERA)	+= gpio-madera.o
 obj-$(CONFIG_GPIO_MAX730X)	+= gpio-max730x.o
 obj-$(CONFIG_GPIO_MAX7300)	+= gpio-max7300.o
 obj-$(CONFIG_GPIO_MAX7301)	+= gpio-max7301.o
diff --git a/drivers/gpio/gpio-madera.c b/drivers/gpio/gpio-madera.c
new file mode 100644
index 0000000..37ac706
--- /dev/null
+++ b/drivers/gpio/gpio-madera.c
@@ -0,0 +1,196 @@
+/*
+ * GPIO support for Cirrus Logic Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/pdata.h>
+#include <linux/mfd/madera/registers.h>
+
+struct madera_gpio {
+	struct madera *madera;
+	struct gpio_chip gpio_chip;
+};
+
+static int madera_gpio_get_direction(struct gpio_chip *chip,
+				     unsigned int offset)
+{
+	struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+	struct madera *madera = madera_gpio->madera;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(madera->regmap,
+			  MADERA_GPIO1_CTRL_2 + (2 * offset), &val);
+	if (ret < 0)
+		return ret;
+
+	return (val & MADERA_GP1_DIR_MASK) >> MADERA_GP1_DIR_SHIFT;
+}
+
+static int madera_gpio_direction_in(struct gpio_chip *chip, unsigned int offset)
+{
+	struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+	struct madera *madera = madera_gpio->madera;
+
+	return regmap_update_bits(madera->regmap,
+				  MADERA_GPIO1_CTRL_2 + (2 * offset),
+				  MADERA_GP1_DIR_MASK, MADERA_GP1_DIR);
+}
+
+static int madera_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+	struct madera *madera = madera_gpio->madera;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(madera->regmap,
+			  MADERA_GPIO1_CTRL_1 + (2 * offset), &val);
+	if (ret < 0)
+		return ret;
+
+	return !!(val & MADERA_GP1_LVL_MASK);
+}
+
+static int madera_gpio_direction_out(struct gpio_chip *chip,
+				     unsigned int offset, int value)
+{
+	struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+	struct madera *madera = madera_gpio->madera;
+	unsigned int regval;
+	int ret;
+
+	if (value)
+		regval = MADERA_GP1_LVL;
+	else
+		regval = 0;
+
+	ret = regmap_update_bits(madera->regmap,
+				 MADERA_GPIO1_CTRL_2 + (2 * offset),
+				 MADERA_GP1_DIR_MASK, 0);
+	if (ret < 0)
+		return ret;
+
+	return regmap_update_bits(madera->regmap,
+				  MADERA_GPIO1_CTRL_1 + (2 * offset),
+				  MADERA_GP1_LVL_MASK, regval);
+}
+
+static void madera_gpio_set(struct gpio_chip *chip, unsigned int offset,
+			    int value)
+{
+	struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+	struct madera *madera = madera_gpio->madera;
+	unsigned int regval;
+	int ret;
+
+	if (value)
+		regval = MADERA_GP1_LVL;
+	else
+		regval = 0;
+
+	ret = regmap_update_bits(madera->regmap,
+				 MADERA_GPIO1_CTRL_1 + (2 * offset),
+				 MADERA_GP1_LVL_MASK, regval);
+	if (ret)
+		dev_warn(madera->dev, "Failed to write to 0x%x (%d)\n",
+			 MADERA_GPIO1_CTRL_1 + (2 * offset), ret);
+}
+
+static struct gpio_chip template_chip = {
+	.label			= "madera",
+	.owner			= THIS_MODULE,
+	.request		= gpiochip_generic_request,
+	.free			= gpiochip_generic_free,
+	.get_direction		= madera_gpio_get_direction,
+	.direction_input	= madera_gpio_direction_in,
+	.get			= madera_gpio_get,
+	.direction_output	= madera_gpio_direction_out,
+	.set			= madera_gpio_set,
+	.set_config		= gpiochip_generic_config,
+	.can_sleep		= true,
+};
+
+static int madera_gpio_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	struct madera_pdata *pdata = dev_get_platdata(madera->dev);
+	struct madera_gpio *madera_gpio;
+	int ret;
+
+	madera_gpio = devm_kzalloc(&pdev->dev, sizeof(*madera_gpio),
+				   GFP_KERNEL);
+	if (!madera_gpio)
+		return -ENOMEM;
+
+	madera_gpio->madera = madera;
+	madera_gpio->gpio_chip = template_chip;
+	madera_gpio->gpio_chip.parent = &pdev->dev;
+
+	if (IS_ENABLED(CONFIG_OF_GPIO))
+		madera_gpio->gpio_chip.of_node = pdev->dev.of_node;
+
+	switch (madera->type) {
+	case CS47L35:
+		madera_gpio->gpio_chip.ngpio = CS47L35_NUM_GPIOS;
+		break;
+	case CS47L85:
+	case WM1840:
+		madera_gpio->gpio_chip.ngpio = CS47L85_NUM_GPIOS;
+		break;
+	case CS47L90:
+	case CS47L91:
+		madera_gpio->gpio_chip.ngpio = CS47L90_NUM_GPIOS;
+		break;
+	default:
+		dev_err(&pdev->dev, "Unknown chip variant %d\n", madera->type);
+		return -EINVAL;
+	}
+
+	if (pdata && pdata->gpio_base)
+		madera_gpio->gpio_chip.base = pdata->gpio_base;
+	else
+		madera_gpio->gpio_chip.base = -1;
+
+	ret = devm_gpiochip_add_data(&pdev->dev, &madera_gpio->gpio_chip,
+				     madera_gpio);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
+		return ret;
+	}
+
+	ret = gpiochip_add_pin_range(&madera_gpio->gpio_chip, "madera-pinctrl",
+				     0, 0, madera_gpio->gpio_chip.ngpio);
+	if (ret) {
+		dev_warn(&pdev->dev, "Failed to add pin range (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct platform_driver madera_gpio_driver = {
+	.driver.name	= "madera-gpio",
+	.driver.owner	= THIS_MODULE,
+	.probe		= madera_gpio_probe,
+};
+
+module_platform_driver(madera_gpio_driver);
+
+MODULE_DESCRIPTION("GPIO interface for Madera codecs");
+MODULE_AUTHOR("Nariman Poushin <nariman@opensource.wolfsonmicro.com>");
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:madera-gpio");
-- 
1.9.1


^ permalink raw reply related

* [PATCH v2 13/18] dt-bindings: gpio: Add bindings for GPIO on Cirrus Logic Madera codecs
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones, broonie, linus.walleij, gnurou, robh+dt, tglx, jason
  Cc: alsa-devel, patches, linux-gpio, devicetree, linux-kernel
In-Reply-To: <1493050124-5970-1-git-send-email-rf@opensource.wolfsonmicro.com>

The Cirrus Logic Madera codecs have a range of GPIO pins that can be
used as single-bit logic input or output. These are presented as a
standard GPIO binding.

The second cell in a GPIO binding is currently reserved for future use
as chip-specific flags.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
Changes from V1:
- moved out of main gpio patch into a separate patch
- added gpio-line-names as an optional property

 .../devicetree/bindings/gpio/gpio-madera.txt       | 27 ++++++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-madera.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-madera.txt b/Documentation/devicetree/bindings/gpio/gpio-madera.txt
new file mode 100644
index 0000000..6254f5b
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-madera.txt
@@ -0,0 +1,27 @@
+Cirrus Logic Madera class audio codecs gpio driver
+
+This is a subnode of the parent mfd node.
+
+See also the core bindings for the parent MFD driver:
+See Documentation/devicetree/bindings/mfd/madera.txt
+
+Required properties:
+  - compatible : must be "cirrus,madera-gpio"
+  - gpio-controller : Indicates this device is a GPIO controller.
+  - #gpio-cells : Must be 2. The first cell is the pin number. The second cell
+    is reserved for future use and must be zero
+
+Optional properties:
+  - gpio-line-names : as described in bindings/gpio/gpio.txt
+
+Example:
+
+cs47l85@0 {
+	compatible = "cirrus,cs47l85";
+
+	gpio {
+		compatible = "cirrus,madera-gpio";
+		gpio-controller;
+		#gpio-cells = <2>;
+	}
+};
-- 
1.9.1


^ permalink raw reply related

* [PATCH v2 14/18] ASoC: madera: Add common support for Cirrus Logic Madera codecs
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones-QSEj5FYQhm4dnm+yROfE0A, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	gnurou-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493050124-5970-1-git-send-email-rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>

The Cirrus Logic Madera codecs are a family of related codecs with
extensive digital and analogue I/O, digital mixing and routing,
signal processing and programmable DSPs.

This patch adds common support code shared by all Madera codecs.

Signed-off-by: Charles Keepax <ckeepax-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
Signed-off-by: Nariman Poushin <nariman-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
Signed-off-by: Nikesh Oswal <Nikesh.Oswal-UVNVL95qEvAciDkP5Hr2oA@public.gmane.org>
Signed-off-by: Piotr Stankiewicz <piotrs-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
Signed-off-by: Ajit Pandey <ajit.pandey-sjhevXS25z0S+FvcfC7Uqw@public.gmane.org>
Signed-off-by: Richard Fitzgerald <rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
---
Changes since V1:
- dt bindings moves to a separate patch
- fixed pdata comments to be kerneldoc format

 MAINTAINERS                        |    5 +
 include/dt-bindings/sound/madera.h |   18 +
 include/sound/madera-pdata.h       |   58 +
 sound/soc/codecs/Kconfig           |    5 +
 sound/soc/codecs/Makefile          |    2 +
 sound/soc/codecs/madera.c          | 4430 ++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/madera.h          |  470 ++++
 7 files changed, 4988 insertions(+)
 create mode 100644 include/dt-bindings/sound/madera.h
 create mode 100644 include/sound/madera-pdata.h
 create mode 100644 sound/soc/codecs/madera.c
 create mode 100644 sound/soc/codecs/madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 66c5263..13743da 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3307,13 +3307,18 @@ S:	Supported
 F:	Documentation/devicetree/bindings/gpio/gpio-madera.txt
 F:	Documentation/devicetree/bindings/mfd/madera.txt
 F:	Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F:	Documentation/devicetree/bindings/sound/madera.txt
+F:	include/dt-bindings/sound/madera*
 F:	include/linux/irqchip/irq-madera*
 F:	include/linux/mfd/madera/*
+F:	include/sound/madera*
 F:	drivers/gpio/gpio-madera*
 F:	drivers/irqchip/irq-madera*
 F:	drivers/mfd/madera*
 F:	drivers/mfd/cs47l*
 F:	drivers/pinctrl/cirrus/*
+F:	sound/soc/codecs/cs47l*
+F:	sound/soc/codecs/madera*
 
 CLEANCACHE API
 M:	Konrad Rzeszutek Wilk <konrad.wilk-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
diff --git a/include/dt-bindings/sound/madera.h b/include/dt-bindings/sound/madera.h
new file mode 100644
index 0000000..91896f8
--- /dev/null
+++ b/include/dt-bindings/sound/madera.h
@@ -0,0 +1,18 @@
+/*
+ * Device Tree defines for Madera codecs
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef DT_BINDINGS_SOUND_MADERA_H
+#define DT_BINDINGS_SOUND_MADERA_H
+
+#define MADERA_INMODE_DIFF	0
+#define MADERA_INMODE_SE	1
+#define MADERA_INMODE_DMIC	2
+
+#endif
diff --git a/include/sound/madera-pdata.h b/include/sound/madera-pdata.h
new file mode 100644
index 0000000..f38713d
--- /dev/null
+++ b/include/sound/madera-pdata.h
@@ -0,0 +1,58 @@
+/*
+ * Platform data for Madera codec driver
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MADERA_CODEC_PDATA_H
+#define MADERA_CODEC_PDATA_H
+
+#include <linux/kernel.h>
+
+#define MADERA_MAX_INPUT		6
+#define MADERA_MAX_MUXED_CHANNELS	4
+#define MADERA_MAX_OUTPUT		6
+#define MADERA_MAX_AIF			4
+#define MADERA_MAX_PDM_SPK		2
+#define MADERA_MAX_DSP			7
+
+/**
+ * struct madera_codec_pdata
+ *
+ * @max_channels_clocked: Maximum number of channels that I2S clocks will be
+ *			  generated for. Useful when clock master for systems
+ *			  where the I2S bus has multiple data lines
+ * @dmic_ref:		  DMIC bias reference for each input. A value of 0
+ *			  indicates MICVDD and is the default, other values
+ *			  depend on the codec - see the datasheet for the
+ *			  INn_DMIC_SUP field
+ * @inmode:		  Mode for the ADC inputs. One of the MADERA_INMODE_xxx
+ *			  values. Two-dimensional array
+ *			  [input_number][channel number], with four slots per
+ *			  input in the order
+ *			  [n][0]=INnAL [n][1]=INnAR [n][2]=INnBL [n][3]=INnBR
+ * @out_mono:		  For each output set the value to TRUE to indicate that
+ *			  the output is mono. [0]=OUT1, [1]=OUT2, ...
+ * @pdm_fmt:		  PDM speaker data format. See the PDM_SPKn_FMT field in
+ *			  the datasheet for a description of this value
+ * @pdm_mute:		  PDM mute format. See the PDM_SPKn_CTRL_1 register
+ *			  in the datasheet for a description of this value
+ */
+struct madera_codec_pdata {
+	u32 max_channels_clocked[MADERA_MAX_AIF];
+
+	u32 dmic_ref[MADERA_MAX_INPUT];
+
+	u32 inmode[MADERA_MAX_INPUT][MADERA_MAX_MUXED_CHANNELS];
+
+	bool out_mono[MADERA_MAX_OUTPUT];
+
+	u32 pdm_fmt[MADERA_MAX_PDM_SPK];
+	u32 pdm_mute[MADERA_MAX_PDM_SPK];
+};
+
+#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1957521..30985a1 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -247,10 +247,12 @@ config SND_SOC_WM_HUBS
 config SND_SOC_WM_ADSP
 	tristate
 	select SND_SOC_COMPRESS
+	default y if SND_SOC_MADERA=y
 	default y if SND_SOC_CS47L24=y
 	default y if SND_SOC_WM5102=y
 	default y if SND_SOC_WM5110=y
 	default y if SND_SOC_WM2200=y
+	default m if SND_SOC_MADERA=m
 	default m if SND_SOC_CS47L24=m
 	default m if SND_SOC_WM5102=m
 	default m if SND_SOC_WM5110=m
@@ -577,6 +579,9 @@ config SND_SOC_ISABELLE
 config SND_SOC_LM49453
 	tristate
 
+config SND_SOC_MADERA
+	tristate
+
 config SND_SOC_MAX98088
        tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 966eb2e..ae2eb27 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -77,6 +77,7 @@ snd-soc-jz4740-codec-objs := jz4740.o
 snd-soc-l3-objs := l3.o
 snd-soc-lm4857-objs := lm4857.o
 snd-soc-lm49453-objs := lm49453.o
+snd-soc-madera-objs := madera.o
 snd-soc-max9768-objs := max9768.o
 snd-soc-max98088-objs := max98088.o
 snd-soc-max98090-objs := max98090.o
@@ -311,6 +312,7 @@ obj-$(CONFIG_SND_SOC_JZ4740_CODEC)	+= snd-soc-jz4740-codec.o
 obj-$(CONFIG_SND_SOC_L3)	+= snd-soc-l3.o
 obj-$(CONFIG_SND_SOC_LM4857)	+= snd-soc-lm4857.o
 obj-$(CONFIG_SND_SOC_LM49453)   += snd-soc-lm49453.o
+obj-$(CONFIG_SND_SOC_MADERA)	+= snd-soc-madera.o
 obj-$(CONFIG_SND_SOC_MAX9768)	+= snd-soc-max9768.o
 obj-$(CONFIG_SND_SOC_MAX98088)	+= snd-soc-max98088.o
 obj-$(CONFIG_SND_SOC_MAX98090)	+= snd-soc-max98090.o
diff --git a/sound/soc/codecs/madera.c b/sound/soc/codecs/madera.c
new file mode 100644
index 0000000..6f205bf
--- /dev/null
+++ b/sound/soc/codecs/madera.c
@@ -0,0 +1,4430 @@
+/*
+ * madera.c - Cirrus Logic Madera class codecs common support
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/gcd.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/tlv.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/registers.h>
+#include <linux/mfd/madera/pdata.h>
+#include <sound/madera-pdata.h>
+
+#include <dt-bindings/sound/madera.h>
+
+#include "madera.h"
+
+#define MADERA_AIF_BCLK_CTRL			0x00
+#define MADERA_AIF_TX_PIN_CTRL			0x01
+#define MADERA_AIF_RX_PIN_CTRL			0x02
+#define MADERA_AIF_RATE_CTRL			0x03
+#define MADERA_AIF_FORMAT			0x04
+#define MADERA_AIF_RX_BCLK_RATE			0x06
+#define MADERA_AIF_FRAME_CTRL_1			0x07
+#define MADERA_AIF_FRAME_CTRL_2			0x08
+#define MADERA_AIF_FRAME_CTRL_3			0x09
+#define MADERA_AIF_FRAME_CTRL_4			0x0A
+#define MADERA_AIF_FRAME_CTRL_5			0x0B
+#define MADERA_AIF_FRAME_CTRL_6			0x0C
+#define MADERA_AIF_FRAME_CTRL_7			0x0D
+#define MADERA_AIF_FRAME_CTRL_8			0x0E
+#define MADERA_AIF_FRAME_CTRL_9			0x0F
+#define MADERA_AIF_FRAME_CTRL_10		0x10
+#define MADERA_AIF_FRAME_CTRL_11		0x11
+#define MADERA_AIF_FRAME_CTRL_12		0x12
+#define MADERA_AIF_FRAME_CTRL_13		0x13
+#define MADERA_AIF_FRAME_CTRL_14		0x14
+#define MADERA_AIF_FRAME_CTRL_15		0x15
+#define MADERA_AIF_FRAME_CTRL_16		0x16
+#define MADERA_AIF_FRAME_CTRL_17		0x17
+#define MADERA_AIF_FRAME_CTRL_18		0x18
+#define MADERA_AIF_TX_ENABLES			0x19
+#define MADERA_AIF_RX_ENABLES			0x1A
+#define MADERA_AIF_FORCE_WRITE			0x1B
+
+#define MADERA_DSP_CONFIG_1_OFFS		0x00
+#define MADERA_DSP_CONFIG_2_OFFS		0x02
+
+#define MADERA_DSP_CLK_SEL_MASK			0x70000
+#define MADERA_DSP_CLK_SEL_SHIFT		16
+
+#define MADERA_DSP_RATE_MASK			0x7800
+#define MADERA_DSP_RATE_SHIFT			11
+
+#define MADERA_SYSCLK_6MHZ			0
+#define MADERA_SYSCLK_12MHZ			1
+#define MADERA_SYSCLK_24MHZ			2
+#define MADERA_SYSCLK_49MHZ			3
+#define MADERA_SYSCLK_98MHZ			4
+
+#define MADERA_DSPCLK_9MHZ			0
+#define MADERA_DSPCLK_18MHZ			1
+#define MADERA_DSPCLK_36MHZ			2
+#define MADERA_DSPCLK_73MHZ			3
+#define MADERA_DSPCLK_147MHZ			4
+
+#define MADERA_FLL_VCO_CORNER			141900000
+#define MADERA_FLL_MAX_FREF			13500000
+#define MADERA_FLL_MAX_N			1023
+#define MADERA_FLL_MIN_FOUT			90000000
+#define MADERA_FLL_MAX_FOUT			100000000
+#define MADERA_FLL_MAX_FRATIO			16
+#define MADERA_FLL_MAX_REFDIV			8
+#define MADERA_FLL_OUTDIV			3
+#define MADERA_FLL_VCO_MULT			3
+#define MADERA_FLLAO_MAX_FREF			12288000
+#define MADERA_FLLAO_MIN_N			4
+#define MADERA_FLLAO_MAX_N			1023
+#define MADERA_FLLAO_MAX_FBDIV			254
+
+#define MADERA_FLL_SYNCHRONISER_OFFS		0x10
+#define CS47L35_FLL_SYNCHRONISER_OFFS		0xE
+#define MADERA_FLL_CONTROL_1_OFFS		0x1
+#define MADERA_FLL_CONTROL_2_OFFS		0x2
+#define MADERA_FLL_CONTROL_3_OFFS		0x3
+#define MADERA_FLL_CONTROL_4_OFFS		0x4
+#define MADERA_FLL_CONTROL_5_OFFS		0x5
+#define MADERA_FLL_CONTROL_6_OFFS		0x6
+#define MADERA_FLL_LOOP_FILTER_TEST_1_OFFS	0x7
+#define MADERA_FLL_NCO_TEST_0_OFFS		0x8
+#define MADERA_FLL_CONTROL_7_OFFS		0x9
+#define MADERA_FLL_EFS_2_OFFS			0xA
+#define MADERA_FLL_SYNCHRONISER_1_OFFS		0x1
+#define MADERA_FLL_SYNCHRONISER_2_OFFS		0x2
+#define MADERA_FLL_SYNCHRONISER_3_OFFS		0x3
+#define MADERA_FLL_SYNCHRONISER_4_OFFS		0x4
+#define MADERA_FLL_SYNCHRONISER_5_OFFS		0x5
+#define MADERA_FLL_SYNCHRONISER_6_OFFS		0x6
+#define MADERA_FLL_SYNCHRONISER_7_OFFS		0x7
+#define MADERA_FLL_SPREAD_SPECTRUM_OFFS		0x9
+#define MADERA_FLL_GPIO_CLOCK_OFFS		0xA
+
+#define MADERA_FLLAO_CONTROL_1_OFFS		0x1
+#define MADERA_FLLAO_CONTROL_2_OFFS		0x2
+#define MADERA_FLLAO_CONTROL_3_OFFS		0x3
+#define MADERA_FLLAO_CONTROL_4_OFFS		0x4
+#define MADERA_FLLAO_CONTROL_5_OFFS		0x5
+#define MADERA_FLLAO_CONTROL_6_OFFS		0x6
+#define MADERA_FLLAO_CONTROL_7_OFFS		0x8
+#define MADERA_FLLAO_CONTROL_8_OFFS		0xA
+#define MADERA_FLLAO_CONTROL_9_OFFS		0xB
+#define MADERA_FLLAO_CONTROL_10_OFFS		0xC
+#define MADERA_FLLAO_CONTROL_11_OFFS		0xD
+
+#define MADERA_FMT_DSP_MODE_A			0
+#define MADERA_FMT_DSP_MODE_B			1
+#define MADERA_FMT_I2S_MODE			2
+#define MADERA_FMT_LEFT_JUSTIFIED_MODE		3
+
+#define madera_fll_err(_fll, fmt, ...) \
+	dev_err(_fll->madera->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
+#define madera_fll_warn(_fll, fmt, ...) \
+	dev_warn(_fll->madera->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
+#define madera_fll_dbg(_fll, fmt, ...) \
+	dev_dbg(_fll->madera->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
+
+#define madera_aif_err(_dai, fmt, ...) \
+	dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
+#define madera_aif_warn(_dai, fmt, ...) \
+	dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
+#define madera_aif_dbg(_dai, fmt, ...) \
+	dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
+
+static const int madera_dsp_bus_error_irqs[MADERA_MAX_ADSP] = {
+	MADERA_IRQ_DSP1_BUS_ERROR,
+	MADERA_IRQ_DSP2_BUS_ERROR,
+	MADERA_IRQ_DSP3_BUS_ERROR,
+	MADERA_IRQ_DSP4_BUS_ERROR,
+	MADERA_IRQ_DSP5_BUS_ERROR,
+	MADERA_IRQ_DSP6_BUS_ERROR,
+	MADERA_IRQ_DSP7_BUS_ERROR,
+};
+
+void madera_spin_sysclk(struct madera_priv *priv)
+{
+	struct madera *madera = priv->madera;
+	unsigned int val;
+	int ret, i;
+
+	/* Skip this if the chip is down */
+	if (pm_runtime_suspended(madera->dev))
+		return;
+
+	/*
+	 * Just read a register a few times to ensure the internal
+	 * oscillator sends out a few clocks.
+	 */
+	for (i = 0; i < 4; i++) {
+		ret = regmap_read(madera->regmap, MADERA_SOFTWARE_RESET, &val);
+		if (ret)
+			dev_err(madera->dev,
+				"%s Failed to read register: %d (%d)\n",
+				__func__, ret, i);
+	}
+
+	udelay(300);
+}
+EXPORT_SYMBOL_GPL(madera_spin_sysclk);
+
+int madera_sysclk_ev(struct snd_soc_dapm_widget *w,
+		     struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+
+	madera_spin_sysclk(priv);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_sysclk_ev);
+
+static int madera_check_speaker_overheat(struct madera *madera,
+					 bool *warn, bool *shutdown)
+{
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_15, &val);
+	if (ret) {
+		dev_err(madera->dev, "Failed to read thermal status: %d\n",
+			ret);
+		return ret;
+	}
+
+	*warn = val & MADERA_SPK_OVERHEAT_WARN_STS1;
+	*shutdown = val & MADERA_SPK_OVERHEAT_STS1;
+
+	return 0;
+}
+
+int madera_spk_ev(struct snd_soc_dapm_widget *w,
+		  struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct madera *madera = dev_get_drvdata(codec->dev->parent);
+	bool warn, shutdown;
+	int ret;
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		ret = madera_check_speaker_overheat(madera, &warn, &shutdown);
+		if (ret)
+			return ret;
+
+		if (shutdown) {
+			dev_crit(madera->dev,
+				 "Speaker not enabled due to temperature\n");
+			return -EBUSY;
+		}
+
+		regmap_update_bits(madera->regmap,
+				   MADERA_OUTPUT_ENABLES_1,
+				   1 << w->shift, 1 << w->shift);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		regmap_update_bits(madera->regmap,
+				   MADERA_OUTPUT_ENABLES_1,
+				   1 << w->shift, 0);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_spk_ev);
+
+static irqreturn_t madera_thermal_warn(int irq, void *data)
+{
+	struct madera *madera = data;
+	bool warn, shutdown;
+	int ret;
+
+	ret = madera_check_speaker_overheat(madera, &warn, &shutdown);
+	if (ret)
+		shutdown = true; /* for safety attempt to shutdown on error */
+
+	if (shutdown) {
+		dev_crit(madera->dev, "Thermal shutdown\n");
+		ret = regmap_update_bits(madera->regmap,
+					 MADERA_OUTPUT_ENABLES_1,
+					 MADERA_OUT4L_ENA |
+					 MADERA_OUT4R_ENA, 0);
+		if (ret != 0)
+			dev_crit(madera->dev,
+				 "Failed to disable speaker outputs: %d\n",
+				 ret);
+	} else if (warn) {
+		dev_crit(madera->dev, "Thermal warning\n");
+	}
+
+	return IRQ_HANDLED;
+}
+
+int madera_init_overheat(struct madera_priv *priv)
+{
+	struct madera *madera = priv->madera;
+	int ret;
+
+	ret = madera_request_irq(madera, MADERA_IRQ_SPK_OVERHEAT_WARN,
+				 "Thermal warning", madera_thermal_warn,
+				 madera);
+	if (ret)
+		dev_warn(madera->dev,
+			"Failed to get thermal warning IRQ: %d\n", ret);
+
+	ret = madera_request_irq(madera, MADERA_IRQ_SPK_OVERHEAT,
+				 "Thermal shutdown", madera_thermal_warn,
+				 madera);
+	if (ret)
+		dev_warn(madera->dev,
+			"Failed to get thermal shutdown IRQ: %d\n", ret);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_init_overheat);
+
+int madera_free_overheat(struct madera_priv *priv)
+{
+	struct madera *madera = priv->madera;
+
+	madera_free_irq(madera, MADERA_IRQ_SPK_OVERHEAT_WARN, madera);
+	madera_free_irq(madera, MADERA_IRQ_SPK_OVERHEAT, madera);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_free_overheat);
+
+static int madera_get_variable_u32_array(struct madera_priv *priv,
+					 const char *propname,
+					 u32 *dest,
+					 int n_max,
+					 int multiple)
+{
+	int n, ret;
+
+	n = device_property_read_u32_array(priv->dev, propname, NULL, 0);
+	if (n == -EINVAL) {
+		return 0;	/* missing, ignore */
+	} else if (n < 0) {
+		dev_warn(priv->madera->dev, "%s malformed (%d)\n",
+			 propname, n);
+		return ret;
+	} else if ((n % multiple) != 0) {
+		dev_warn(priv->madera->dev, "%s not a multiple of %d entries\n",
+			 propname, multiple);
+		return -EINVAL;
+	}
+
+	if (n > n_max)
+		n = n_max;
+
+	ret = device_property_read_u32_array(priv->dev, propname, dest, n);
+
+	if (ret < 0)
+		return ret;
+	else
+		return n;
+}
+
+static void madera_prop_get_inmode(struct madera_priv *priv)
+{
+	struct madera *madera = priv->madera;
+	u32 tmp[MADERA_MAX_INPUT * MADERA_MAX_MUXED_CHANNELS];
+	int n, i, in_idx, ch_idx;
+
+	BUILD_BUG_ON(ARRAY_SIZE(madera->pdata.codec.inmode) != MADERA_MAX_INPUT);
+	BUILD_BUG_ON(ARRAY_SIZE(madera->pdata.codec.inmode[0]) !=
+		     MADERA_MAX_MUXED_CHANNELS);
+
+	n = madera_get_variable_u32_array(priv,
+					  "cirrus,inmode",
+					  tmp,
+					  ARRAY_SIZE(tmp),
+					  MADERA_MAX_MUXED_CHANNELS);
+	if (n < 0)
+		return;
+
+	in_idx = 0;
+	ch_idx = 0;
+	for (i = 0; i < n; ++i) {
+		madera->pdata.codec.inmode[in_idx][ch_idx] = tmp[i];
+
+		if (++ch_idx == MADERA_MAX_MUXED_CHANNELS) {
+			ch_idx = 0;
+			++in_idx;
+		}
+	}
+}
+
+static void madera_prop_get_pdata(struct madera_priv *priv)
+{
+	struct madera *madera = priv->madera;
+	struct madera_codec_pdata *pdata = &madera->pdata.codec;
+	u32 out_mono[ARRAY_SIZE(pdata->out_mono)];
+	int i, ret;
+
+	ret = madera_get_variable_u32_array(priv,
+					"cirrus,max-channels-clocked",
+					pdata->max_channels_clocked,
+					ARRAY_SIZE(pdata->max_channels_clocked),
+					1);
+	if (ret < 0)
+		return;
+
+	madera_prop_get_inmode(priv);
+
+	memset(&out_mono, 0, sizeof(out_mono));
+	ret = device_property_read_u32_array(priv->dev,
+					     "cirrus,out-mono",
+					     out_mono,
+					     ARRAY_SIZE(out_mono));
+	if (ret == 0)
+		for (i = 0; i < ARRAY_SIZE(out_mono); ++i)
+			pdata->out_mono[i] = !!out_mono[i];
+
+	madera_get_variable_u32_array(priv,
+				      "cirrus,pdm-fmt",
+				      pdata->pdm_fmt,
+				      ARRAY_SIZE(pdata->pdm_fmt),
+				      1);
+
+	madera_get_variable_u32_array(priv,
+				      "cirrus,pdm-mute",
+				      pdata->pdm_mute,
+				      ARRAY_SIZE(pdata->pdm_mute),
+				      1);
+
+	madera_get_variable_u32_array(priv,
+				      "cirrus,dmic-ref",
+				       pdata->dmic_ref,
+				       ARRAY_SIZE(pdata->dmic_ref),
+				       1);
+}
+
+int madera_core_init(struct madera_priv *priv)
+{
+	BUILD_BUG_ON(ARRAY_SIZE(madera_mixer_texts) != MADERA_NUM_MIXER_INPUTS);
+	BUILD_BUG_ON(ARRAY_SIZE(madera_mixer_values) != MADERA_NUM_MIXER_INPUTS);
+	BUILD_BUG_ON(madera_sample_rate_text[MADERA_SAMPLE_RATE_ENUM_SIZE - 1]
+		     == NULL);
+	BUILD_BUG_ON(madera_sample_rate_val[MADERA_SAMPLE_RATE_ENUM_SIZE - 1]
+		     == 0);
+
+	if (!dev_get_platdata(priv->madera->dev))
+		madera_prop_get_pdata(priv);
+
+	mutex_init(&priv->rate_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_core_init);
+
+int madera_core_destroy(struct madera_priv *priv)
+{
+	mutex_destroy(&priv->rate_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_core_destroy);
+
+static void madera_debug_dump_domain_groups(const struct madera_priv *priv)
+{
+	struct madera *madera = priv->madera;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(priv->domain_group_ref); ++i)
+		dev_dbg(madera->dev, "domain_grp_ref[%d]=%d\n", i,
+			priv->domain_group_ref[i]);
+}
+
+int madera_domain_clk_ev(struct snd_soc_dapm_widget *w,
+			 struct snd_kcontrol *kcontrol,
+			 int event)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	int dom_grp = w->shift;
+
+	if (dom_grp >= ARRAY_SIZE(priv->domain_group_ref)) {
+		WARN(true, "%s dom_grp exceeds array size\n", __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * We can't rely on the DAPM mutex for locking because we need a lock
+	 * that can safely be called in hw_params
+	 */
+	mutex_lock(&priv->rate_lock);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		dev_dbg(priv->madera->dev, "Inc ref on domain group %d\n",
+			dom_grp);
+		++priv->domain_group_ref[dom_grp];
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		dev_dbg(priv->madera->dev, "Dec ref on domain group %d\n",
+			dom_grp);
+		--priv->domain_group_ref[dom_grp];
+		break;
+	default:
+		break;
+	}
+
+	madera_debug_dump_domain_groups(priv);
+
+	mutex_unlock(&priv->rate_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_domain_clk_ev);
+
+int madera_out1_demux_put(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
+	struct snd_soc_dapm_context *dapm =
+		snd_soc_dapm_kcontrol_dapm(kcontrol);
+	struct madera *madera = dev_get_drvdata(codec->dev->parent);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int ep_sel, mux, change;
+	int ret, demux_change_ret;
+	bool out_mono, restore_out = true;
+
+	if (ucontrol->value.enumerated.item[0] > e->items - 1)
+		return -EINVAL;
+
+	mux = ucontrol->value.enumerated.item[0];
+	ep_sel = mux << MADERA_EP_SEL_SHIFT;
+
+	snd_soc_dapm_mutex_lock(dapm);
+
+	change = snd_soc_test_bits(codec, MADERA_OUTPUT_ENABLES_1,
+				   MADERA_EP_SEL_MASK, ep_sel);
+	if (!change)
+		goto end;
+
+	/* EP_SEL should not be modified while HP or EP driver is enabled */
+	ret = regmap_update_bits(madera->regmap,
+				 MADERA_OUTPUT_ENABLES_1,
+				 MADERA_OUT1L_ENA |
+				 MADERA_OUT1R_ENA, 0);
+	if (ret)
+		dev_warn(madera->dev, "Failed to disable outputs: %d\n", ret);
+
+	usleep_range(2000, 3000); /* wait for wseq to complete */
+
+	/*
+	 * if HP detection clamp is applied while switching to HPOUT
+	 * OUT1 should remain disabled and EDRE should be set to manual
+	 */
+	if (!ep_sel &&
+	    (madera->out_clamp[0] || madera->out_shorted[0]))
+		restore_out = false;
+
+	/* change demux setting */
+	demux_change_ret = regmap_update_bits(madera->regmap,
+					      MADERA_OUTPUT_ENABLES_1,
+					      MADERA_EP_SEL_MASK, ep_sel);
+	if (demux_change_ret) {
+		dev_err(madera->dev, "Failed to set OUT1 demux: %d\n",
+			demux_change_ret);
+	} else {
+		/* apply correct setting for mono mode */
+		if (!ep_sel && !madera->pdata.codec.out_mono[0])
+			out_mono = false; /* stereo HP */
+		else
+			out_mono = true; /* EP or mono HP */
+
+		ret = madera_set_output_mode(codec, 1, out_mono);
+		if (ret)
+			dev_warn(madera->dev,
+				 "Failed to set output mode: %d\n", ret);
+	}
+
+	/* restore output state if allowed */
+	if (restore_out) {
+		ret = regmap_update_bits(madera->regmap,
+					 MADERA_OUTPUT_ENABLES_1,
+					 MADERA_OUT1L_ENA |
+					 MADERA_OUT1R_ENA,
+					 madera->hp_ena);
+		if (ret)
+			dev_warn(madera->dev,
+				 "Failed to restore earpiece outputs: %d\n",
+				 ret);
+		else if (madera->hp_ena)
+			msleep(34); /* wait for enable wseq */
+		else
+			usleep_range(2000, 3000); /* wait for disable wseq */
+	}
+
+end:
+	snd_soc_dapm_mutex_unlock(dapm);
+
+	return snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL);
+}
+EXPORT_SYMBOL_GPL(madera_out1_demux_put);
+
+
+static int madera_inmux_put(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
+	struct snd_soc_dapm_context *dapm =
+		snd_soc_dapm_kcontrol_dapm(kcontrol);
+	struct madera *madera = dev_get_drvdata(codec->dev->parent);
+	struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
+	unsigned int mux, src_val, src_mask, gang_reg, dmode_reg, dmode_val;
+	unsigned int inmode_a, inmode_gang, inmode;
+	bool changed = false;
+	int ret;
+
+	mux = ucontrol->value.enumerated.item[0];
+	if (mux > 1)
+		return -EINVAL;
+
+	src_val = mux << e->shift_l;
+	src_mask = e->mask << e->shift_l;
+
+	switch (e->reg) {
+	case MADERA_ADC_DIGITAL_VOLUME_1L:
+		inmode_a = madera->pdata.codec.inmode[0][0];
+		inmode = madera->pdata.codec.inmode[0][2 * mux];
+		inmode_gang = madera->pdata.codec.inmode[0][1 + (2 * mux)];
+		gang_reg = MADERA_ADC_DIGITAL_VOLUME_1R;
+		dmode_reg = MADERA_IN1L_CONTROL;
+		break;
+	case MADERA_ADC_DIGITAL_VOLUME_1R:
+		inmode_a = madera->pdata.codec.inmode[0][0];
+		inmode = madera->pdata.codec.inmode[0][1 + (2 * mux)];
+		inmode_gang = madera->pdata.codec.inmode[0][2 * mux];
+		gang_reg = MADERA_ADC_DIGITAL_VOLUME_1L;
+		dmode_reg = MADERA_IN1L_CONTROL;
+		break;
+	case MADERA_ADC_DIGITAL_VOLUME_2L:
+		inmode_a = madera->pdata.codec.inmode[1][0];
+		inmode = madera->pdata.codec.inmode[1][2 * mux];
+		inmode_gang = madera->pdata.codec.inmode[1][1 + (2 * mux)];
+		gang_reg = MADERA_ADC_DIGITAL_VOLUME_2R;
+		dmode_reg = MADERA_IN2L_CONTROL;
+		break;
+	case MADERA_ADC_DIGITAL_VOLUME_2R:
+		inmode_a = madera->pdata.codec.inmode[1][0];
+		inmode = madera->pdata.codec.inmode[1][1 + (2 * mux)];
+		inmode_gang = madera->pdata.codec.inmode[1][2 * mux];
+		gang_reg = MADERA_ADC_DIGITAL_VOLUME_2L;
+		dmode_reg = MADERA_IN2L_CONTROL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* SE mask and shift is same for all channels */
+	src_mask |= MADERA_IN1L_SRC_SE_MASK;
+	if (inmode & MADERA_INMODE_SE)
+		src_val |= 1 << MADERA_IN1L_SRC_SE_SHIFT;
+
+	dev_dbg(madera->dev,
+		"mux=%u reg=0x%x inmode_a=0x%x inmode=0x%x mask=0x%x val=0x%x\n",
+		mux, e->reg, inmode_a, inmode, src_mask, src_val);
+
+	ret = snd_soc_component_update_bits(dapm->component,
+					    e->reg,
+					    src_mask,
+					    src_val);
+	if (ret < 0)
+		return ret;
+	else if (ret)
+		changed = true;
+
+	/* if the A input is digital we must switch both channels together */
+	if (inmode_a == MADERA_INMODE_DMIC) {
+		switch (madera->type) {
+		case CS47L85:
+		case WM1840:
+			if (e->reg == MADERA_ADC_DIGITAL_VOLUME_1L)
+				goto out;	/* not ganged */
+			break;
+		case CS47L90:
+		case CS47L91:
+			if (e->reg == MADERA_ADC_DIGITAL_VOLUME_2L)
+				goto out;	/* not ganged */
+			break;
+		default:
+			break;
+		}
+
+		/* ganged channels can have different analogue modes */
+		if (inmode_gang & MADERA_INMODE_SE)
+			src_val |= 1 << MADERA_IN1L_SRC_SE_SHIFT;
+		else
+			src_val &= ~(1 << MADERA_IN1L_SRC_SE_SHIFT);
+
+		if (mux)
+			dmode_val = 0; /* B always analogue */
+		else
+			dmode_val = 1 << MADERA_IN1_MODE_SHIFT; /* DMIC */
+
+		dev_dbg(madera->dev,
+			"gang_reg=0x%x inmode_gang=0x%x gang_val=0x%x dmode_val=0x%x\n",
+			gang_reg, inmode_gang, src_val, dmode_val);
+
+		ret = snd_soc_component_update_bits(dapm->component,
+						    gang_reg,
+						    src_mask,
+						    src_val);
+		if (ret < 0)
+			return ret;
+		else if (ret)
+			changed = true;
+
+		ret = snd_soc_component_update_bits(dapm->component,
+						    dmode_reg,
+						    MADERA_IN1_MODE_MASK,
+						    dmode_val);
+	}
+
+out:
+	if (changed)
+		return snd_soc_dapm_mux_update_power(dapm, kcontrol,
+						     mux, e, NULL);
+	else
+		return 0;
+}
+
+static const char * const madera_inmux_texts[] = {
+	"A",
+	"B",
+};
+
+static SOC_ENUM_SINGLE_DECL(madera_in1muxl_enum,
+			    MADERA_ADC_DIGITAL_VOLUME_1L,
+			    MADERA_IN1L_SRC_SHIFT,
+			    madera_inmux_texts);
+
+static SOC_ENUM_SINGLE_DECL(madera_in1muxr_enum,
+			    MADERA_ADC_DIGITAL_VOLUME_1R,
+			    MADERA_IN1R_SRC_SHIFT,
+			    madera_inmux_texts);
+
+static SOC_ENUM_SINGLE_DECL(madera_in2muxl_enum,
+			    MADERA_ADC_DIGITAL_VOLUME_2L,
+			    MADERA_IN2L_SRC_SHIFT,
+			    madera_inmux_texts);
+
+static SOC_ENUM_SINGLE_DECL(madera_in2muxr_enum,
+			    MADERA_ADC_DIGITAL_VOLUME_2R,
+			    MADERA_IN2R_SRC_SHIFT,
+			    madera_inmux_texts);
+
+const struct snd_kcontrol_new madera_inmux[] = {
+	SOC_DAPM_ENUM_EXT("IN1L Mux", madera_in1muxl_enum,
+			  snd_soc_dapm_get_enum_double, madera_inmux_put),
+	SOC_DAPM_ENUM_EXT("IN1R Mux", madera_in1muxr_enum,
+			  snd_soc_dapm_get_enum_double, madera_inmux_put),
+	SOC_DAPM_ENUM_EXT("IN2L Mux", madera_in2muxl_enum,
+			  snd_soc_dapm_get_enum_double, madera_inmux_put),
+	SOC_DAPM_ENUM_EXT("IN2R Mux", madera_in2muxr_enum,
+			  snd_soc_dapm_get_enum_double, madera_inmux_put),
+};
+EXPORT_SYMBOL_GPL(madera_inmux);
+
+static bool madera_can_change_grp_rate(const struct madera_priv *priv,
+				       unsigned int reg)
+{
+	int count;
+
+	switch (reg) {
+	case MADERA_FX_CTRL1:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_FX];
+		break;
+	case MADERA_ASRC1_RATE1:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ASRC1_RATE_1];
+		break;
+	case MADERA_ASRC1_RATE2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ASRC1_RATE_2];
+		break;
+	case MADERA_ASRC2_RATE1:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ASRC2_RATE_1];
+		break;
+	case MADERA_ASRC2_RATE2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ASRC2_RATE_2];
+		break;
+	case MADERA_ISRC_1_CTRL_1:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC1_INT];
+		break;
+	case MADERA_ISRC_1_CTRL_2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC1_DEC];
+		break;
+	case MADERA_ISRC_2_CTRL_1:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC2_INT];
+		break;
+	case MADERA_ISRC_2_CTRL_2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC2_DEC];
+		break;
+	case MADERA_ISRC_3_CTRL_1:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC3_INT];
+		break;
+	case MADERA_ISRC_3_CTRL_2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC3_DEC];
+		break;
+	case MADERA_ISRC_4_CTRL_1:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC4_INT];
+		break;
+	case MADERA_ISRC_4_CTRL_2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC4_DEC];
+		break;
+	case MADERA_OUTPUT_RATE_1:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_OUT];
+		break;
+	case MADERA_SPD1_TX_CONTROL:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_SPD];
+		break;
+	case MADERA_DSP1_CONFIG_1:
+	case MADERA_DSP1_CONFIG_2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_DSP1];
+		break;
+	case MADERA_DSP2_CONFIG_1:
+	case MADERA_DSP2_CONFIG_2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_DSP2];
+		break;
+	case MADERA_DSP3_CONFIG_1:
+	case MADERA_DSP3_CONFIG_2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_DSP3];
+		break;
+	case MADERA_DSP4_CONFIG_1:
+	case MADERA_DSP4_CONFIG_2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_DSP4];
+		break;
+	case MADERA_DSP5_CONFIG_1:
+	case MADERA_DSP5_CONFIG_2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_DSP5];
+		break;
+	case MADERA_DSP6_CONFIG_1:
+	case MADERA_DSP6_CONFIG_2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_DSP6];
+		break;
+	case MADERA_DSP7_CONFIG_1:
+	case MADERA_DSP7_CONFIG_2:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_DSP7];
+		break;
+	case MADERA_AIF1_RATE_CTRL:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_AIF1];
+		break;
+	case MADERA_AIF2_RATE_CTRL:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_AIF2];
+		break;
+	case MADERA_AIF3_RATE_CTRL:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_AIF3];
+		break;
+	case MADERA_AIF4_RATE_CTRL:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_AIF4];
+		break;
+	case MADERA_SLIMBUS_RATES_1:
+	case MADERA_SLIMBUS_RATES_2:
+	case MADERA_SLIMBUS_RATES_3:
+	case MADERA_SLIMBUS_RATES_4:
+	case MADERA_SLIMBUS_RATES_5:
+	case MADERA_SLIMBUS_RATES_6:
+	case MADERA_SLIMBUS_RATES_7:
+	case MADERA_SLIMBUS_RATES_8:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_SLIMBUS];
+		break;
+	case MADERA_PWM_DRIVE_1:
+		count = priv->domain_group_ref[MADERA_DOM_GRP_PWM];
+		break;
+	default:
+		return false;
+	}
+
+	dev_dbg(priv->madera->dev, "Rate reg 0x%x group ref %d\n", reg, count);
+
+	if (count)
+		return false;
+	else
+		return true;
+}
+
+int madera_adsp_rate_get(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int cached_rate;
+	const int adsp_num = e->shift_l;
+	int item;
+
+	mutex_lock(&priv->rate_lock);
+	cached_rate = priv->adsp_rate_cache[adsp_num];
+	mutex_unlock(&priv->rate_lock);
+
+	item = snd_soc_enum_val_to_item(e, cached_rate);
+	ucontrol->value.enumerated.item[0] = item;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_adsp_rate_get);
+
+int madera_adsp_rate_put(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	const int adsp_num = e->shift_l;
+	const unsigned int item = ucontrol->value.enumerated.item[0];
+	int ret;
+
+	if (item >= e->items)
+		return -EINVAL;
+
+	/*
+	 * We don't directly write the rate register here but we want to
+	 * maintain consistent behaviour that rate domains cannot be changed
+	 * while in use since this is a hardware requirement
+	 */
+	mutex_lock(&priv->rate_lock);
+
+	if (!madera_can_change_grp_rate(priv, priv->adsp[adsp_num].base)) {
+		dev_warn(priv->madera->dev,
+			 "Cannot change '%s' while in use by active audio paths\n",
+			 kcontrol->id.name);
+		ret = -EBUSY;
+	} else {
+		/* Volatile register so defer until the codec is powered up */
+		priv->adsp_rate_cache[adsp_num] = e->values[item];
+		ret = 0;
+	}
+
+	mutex_unlock(&priv->rate_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(madera_adsp_rate_put);
+
+static const struct soc_enum madera_adsp_rate_enum[] = {
+	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0, 0xf, MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 1, 0xf, MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 2, 0xf, MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 3, 0xf, MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 4, 0xf, MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 5, 0xf, MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 6, 0xf, MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+};
+
+const struct snd_kcontrol_new madera_adsp_rate_controls[] = {
+	SOC_ENUM_EXT("DSP1 Rate", madera_adsp_rate_enum[0],
+		     madera_adsp_rate_get, madera_adsp_rate_put),
+	SOC_ENUM_EXT("DSP2 Rate", madera_adsp_rate_enum[1],
+		     madera_adsp_rate_get, madera_adsp_rate_put),
+	SOC_ENUM_EXT("DSP3 Rate", madera_adsp_rate_enum[2],
+		     madera_adsp_rate_get, madera_adsp_rate_put),
+	SOC_ENUM_EXT("DSP4 Rate", madera_adsp_rate_enum[3],
+		     madera_adsp_rate_get, madera_adsp_rate_put),
+	SOC_ENUM_EXT("DSP5 Rate", madera_adsp_rate_enum[4],
+		     madera_adsp_rate_get, madera_adsp_rate_put),
+	SOC_ENUM_EXT("DSP6 Rate", madera_adsp_rate_enum[5],
+		     madera_adsp_rate_get, madera_adsp_rate_put),
+	SOC_ENUM_EXT("DSP7 Rate", madera_adsp_rate_enum[6],
+		     madera_adsp_rate_get, madera_adsp_rate_put),
+};
+EXPORT_SYMBOL_GPL(madera_adsp_rate_controls);
+
+static int madera_write_adsp_clk_setting(struct madera_priv *priv,
+					 struct wm_adsp *dsp,
+					 unsigned int freq)
+{
+	unsigned int val;
+	unsigned int mask = MADERA_DSP_RATE_MASK;
+	int ret;
+
+	/*
+	 * Take snapshot of rate. There will always be a race condition
+	 * between this code and setting the rate control. Wrapping the entire
+	 * function in the lock won't change that so don't bother
+	 */
+	mutex_lock(&priv->rate_lock);
+	val = priv->adsp_rate_cache[dsp->num - 1] << MADERA_DSP_RATE_SHIFT;
+	mutex_unlock(&priv->rate_lock);
+
+	switch (priv->madera->type) {
+	case CS47L35:
+	case CS47L85:
+	case WM1840:
+		/* use legacy frequency registers */
+		mask |= MADERA_DSP_CLK_SEL_MASK;
+		val |= (freq << MADERA_DSP_CLK_SEL_SHIFT);
+		break;
+	default:
+		/* Configure exact dsp frequency */
+		dev_dbg(priv->madera->dev, "Set DSP frequency to 0x%x\n", freq);
+
+		ret = regmap_write(dsp->regmap,
+				   dsp->base + MADERA_DSP_CONFIG_2_OFFS, freq);
+		if (ret)
+			goto err;
+		break;
+	}
+
+	ret = regmap_update_bits(dsp->regmap,
+				 dsp->base + MADERA_DSP_CONFIG_1_OFFS,
+				 mask, val);
+
+	dev_dbg(priv->madera->dev, "Set DSP clocking to 0x%x\n", val);
+
+	return 0;
+
+err:
+	dev_err(dsp->dev, "Failed to set DSP%d clock: %d\n", dsp->num, ret);
+
+	return ret;
+}
+
+int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num,
+			unsigned int freq)
+{
+	struct wm_adsp *dsp = &priv->adsp[dsp_num];
+	struct madera *madera = priv->madera;
+	unsigned int cur, new;
+	int ret;
+
+	/*
+	 * This is called at a higher DAPM priority than the mux widgets so
+	 * the muxes are still off at this point and it's safe to change
+	 * the rate domain control
+	 */
+
+	ret = regmap_read(dsp->regmap,  dsp->base, &cur);
+	if (ret) {
+		dev_err(madera->dev,
+			"Failed to read current DSP rate: %d\n", ret);
+		return ret;
+	}
+
+	cur &= MADERA_DSP_RATE_MASK;
+
+	mutex_lock(&priv->rate_lock);
+	new = priv->adsp_rate_cache[dsp->num - 1] << MADERA_DSP_RATE_SHIFT;
+	mutex_unlock(&priv->rate_lock);
+
+	if (new == cur) {
+		dev_dbg(madera->dev, "DSP rate not changed\n");
+		return madera_write_adsp_clk_setting(priv, dsp, freq);
+	} else {
+		dev_dbg(madera->dev, "DSP rate changed\n");
+
+		/* The write must be guarded by a number of SYSCLK cycles */
+		madera_spin_sysclk(priv);
+		ret = madera_write_adsp_clk_setting(priv, dsp, freq);
+		madera_spin_sysclk(priv);
+		return ret;
+	}
+}
+EXPORT_SYMBOL_GPL(madera_set_adsp_clk);
+
+int madera_rate_put(struct snd_kcontrol *kcontrol,
+		    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_dapm_context *dapm =
+		snd_soc_dapm_kcontrol_dapm(kcontrol);
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int item = ucontrol->value.enumerated.item[0];
+	unsigned int val;
+	int ret;
+
+	if (item >= e->items)
+		return -EINVAL;
+
+	/*
+	 * Prevent the domain powering up while we're checking whether it's
+	 * safe to change rate domain
+	 */
+	mutex_lock(&priv->rate_lock);
+
+	ret = snd_soc_component_read(dapm->component, e->reg, &val);
+	if (ret < 0) {
+		dev_warn(priv->madera->dev, "Failed to read 0x%x (%d)\n",
+			 e->reg, ret);
+		goto out;
+	}
+	val >>= e->shift_l;
+	val &= e->mask;
+	if (snd_soc_enum_item_to_val(e, item) == val) {
+		ret = 0;
+		goto out;
+	}
+
+	if (!madera_can_change_grp_rate(priv, e->reg)) {
+		dev_warn(priv->madera->dev,
+			 "Cannot change '%s' while in use by active audio paths\n",
+			 kcontrol->id.name);
+		ret = -EBUSY;
+	} else {
+		/* The write must be guarded by a number of SYSCLK cycles */
+		madera_spin_sysclk(priv);
+		ret = snd_soc_put_enum_double(kcontrol, ucontrol);
+		madera_spin_sysclk(priv);
+	}
+out:
+	mutex_unlock(&priv->rate_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(madera_rate_put);
+
+static void madera_configure_input_mode(struct madera *madera)
+{
+	unsigned int dig_mode, ana_mode_l, ana_mode_r;
+	int max_analogue_inputs, i;
+
+	switch (madera->type) {
+	case CS47L35:
+		max_analogue_inputs = 2;
+		break;
+	case CS47L85:
+	case WM1840:
+		max_analogue_inputs = 3;
+		break;
+	default:
+		max_analogue_inputs = 2;
+		break;
+	}
+
+	/*
+	 * Initialize input modes from the A settings. For muxed inputs the
+	 * B settings will be applied if the mux is changed
+	 */
+	for (i = 0; i < max_analogue_inputs; i++) {
+		dev_dbg(madera->dev, "IN%d mode %u:%u:%u:%u\n", i + 1,
+			madera->pdata.codec.inmode[i][0],
+			madera->pdata.codec.inmode[i][1],
+			madera->pdata.codec.inmode[i][2],
+			madera->pdata.codec.inmode[i][3]);
+
+		dig_mode = madera->pdata.codec.dmic_ref[i] <<
+			   MADERA_IN1_DMIC_SUP_SHIFT;
+
+		switch (madera->pdata.codec.inmode[i][0]) {
+		case MADERA_INMODE_DIFF:
+			ana_mode_l = 0;
+			break;
+		case MADERA_INMODE_SE:
+			ana_mode_l = 1 << MADERA_IN1L_SRC_SE_SHIFT;
+			break;
+		case MADERA_INMODE_DMIC:
+			ana_mode_l = 0;
+			dig_mode |= 1 << MADERA_IN1_MODE_SHIFT;
+			break;
+		default:
+			dev_warn(madera->dev,
+				 "IN%dAL Illegal inmode %u ignored\n",
+				 i + 1, madera->pdata.codec.inmode[i][0]);
+			continue;
+		}
+
+		switch (madera->pdata.codec.inmode[i][1]) {
+		case MADERA_INMODE_DIFF:
+		case MADERA_INMODE_DMIC:
+			ana_mode_r = 0;
+			break;
+		case MADERA_INMODE_SE:
+			ana_mode_r = 1 << MADERA_IN1R_SRC_SE_SHIFT;
+			break;
+		default:
+			dev_warn(madera->dev,
+				 "IN%dAR Illegal inmode %u ignored\n",
+				 i + 1, madera->pdata.codec.inmode[i][1]);
+			continue;
+		}
+
+		dev_dbg(madera->dev,
+			"IN%dA DMIC mode=0x%x Analogue mode=0x%x,0x%x\n",
+			i + 1, dig_mode, ana_mode_l, ana_mode_r);
+
+		regmap_update_bits(madera->regmap,
+				   MADERA_IN1L_CONTROL + (i * 8),
+				   MADERA_IN1_DMIC_SUP_MASK |
+				   MADERA_IN1_MODE_MASK,
+				   dig_mode);
+
+		regmap_update_bits(madera->regmap,
+				   MADERA_ADC_DIGITAL_VOLUME_1L + (i * 8),
+				   MADERA_IN1L_SRC_SE_MASK, ana_mode_l);
+
+		regmap_update_bits(madera->regmap,
+				   MADERA_ADC_DIGITAL_VOLUME_1R + (i * 8),
+				   MADERA_IN1R_SRC_SE_MASK, ana_mode_r);
+	}
+}
+
+int madera_init_inputs(struct snd_soc_codec *codec,
+		       const char * const *dmic_inputs, int n_dmic_inputs,
+		       const char * const *dmic_refs, int n_dmic_refs)
+{
+	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct madera *madera = priv->madera;
+	unsigned int ref;
+	int i, ret;
+	struct snd_soc_dapm_route routes[2];
+
+	memset(&routes, 0, sizeof(routes));
+
+	madera_configure_input_mode(madera);
+
+	for (i = 0; i < n_dmic_inputs / 2; ++i) {
+		ref = madera->pdata.codec.dmic_ref[i];
+		if (ref >= n_dmic_refs) {
+			dev_err(madera->dev,
+				"Illegal DMIC ref %u for IN%d\n", ref, i);
+			return -EINVAL;
+		}
+
+		routes[0].source = dmic_refs[ref];
+		routes[1].source = dmic_refs[ref];
+		routes[0].sink = dmic_inputs[i * 2];
+		routes[1].sink = dmic_inputs[(i * 2) + 1];
+
+		ret = snd_soc_dapm_add_routes(dapm, routes, 2);
+		if (ret)
+			dev_warn(madera->dev,
+				 "Failed to add routes for %s->(%s,%s) (%d)\n",
+				 routes[0].source,
+				 routes[0].sink,
+				 routes[1].sink,
+				 ret);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_init_inputs);
+
+static const struct snd_soc_dapm_route madera_mono_routes[] = {
+	{ "OUT1R", NULL, "OUT1L" },
+	{ "OUT2R", NULL, "OUT2L" },
+	{ "OUT3R", NULL, "OUT3L" },
+	{ "OUT4R", NULL, "OUT4L" },
+	{ "OUT5R", NULL, "OUT5L" },
+	{ "OUT6R", NULL, "OUT6L" },
+};
+
+int madera_init_outputs(struct snd_soc_codec *codec, int n_mono_routes)
+{
+	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct madera *madera = priv->madera;
+	const struct madera_codec_pdata *pdata = &madera->pdata.codec;
+	unsigned int val;
+	int i;
+
+	if (n_mono_routes > MADERA_MAX_OUTPUT) {
+		dev_warn(madera->dev,
+			 "Requested %d mono outputs, using maximum allowed %d\n",
+			 n_mono_routes, MADERA_MAX_OUTPUT);
+		n_mono_routes = MADERA_MAX_OUTPUT;
+	}
+
+	for (i = 0; i < n_mono_routes; i++) {
+		/* Default is 0 so noop with defaults */
+		if (pdata->out_mono[i]) {
+			val = MADERA_OUT1_MONO;
+			snd_soc_dapm_add_routes(dapm,
+						&madera_mono_routes[i], 1);
+		} else {
+			val = 0;
+		}
+
+		regmap_update_bits(madera->regmap,
+				   MADERA_OUTPUT_PATH_CONFIG_1L + (i * 8),
+				   MADERA_OUT1_MONO, val);
+
+		dev_dbg(madera->dev, "OUT%d mono=0x%x\n", i + 1, val);
+	}
+
+	for (i = 0; i < MADERA_MAX_PDM_SPK; i++) {
+		dev_dbg(madera->dev, "PDM%d fmt=0x%x mute=0x%x\n", i + 1,
+			pdata->pdm_fmt[i], pdata->pdm_mute[i]);
+
+		if (pdata->pdm_mute[i])
+			regmap_update_bits(madera->regmap,
+					   MADERA_PDM_SPK1_CTRL_1 + (i * 2),
+					   MADERA_SPK1_MUTE_ENDIAN_MASK |
+					   MADERA_SPK1_MUTE_SEQ1_MASK,
+					   pdata->pdm_mute[i]);
+
+		if (pdata->pdm_fmt[i])
+			regmap_update_bits(madera->regmap,
+					   MADERA_PDM_SPK1_CTRL_2 + (i * 2),
+					   MADERA_SPK1_FMT_MASK,
+					   pdata->pdm_fmt[i]);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_init_outputs);
+
+int madera_init_bus_error_irq(struct madera_priv *priv, int dsp_num,
+			      irq_handler_t handler)
+{
+	struct madera *madera = priv->madera;
+	int ret;
+
+	ret = madera_request_irq(madera,
+				 madera_dsp_bus_error_irqs[dsp_num],
+				 "ADSP2 bus error",
+				 handler,
+				 &priv->adsp[dsp_num]);
+	if (ret)
+		dev_err(madera->dev,
+			"Failed to request DSP Lock region IRQ: %d\n", ret);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(madera_init_bus_error_irq);
+
+void madera_destroy_bus_error_irq(struct madera_priv *priv, int dsp_num)
+{
+	struct madera *madera = priv->madera;
+
+	madera_free_irq(madera,
+			madera_dsp_bus_error_irqs[dsp_num],
+			&priv->adsp[dsp_num]);
+}
+EXPORT_SYMBOL_GPL(madera_destroy_bus_error_irq);
+
+const char * const madera_mixer_texts[] = {
+	"None",
+	"Tone Generator 1",
+	"Tone Generator 2",
+	"Haptics",
+	"AEC1",
+	"AEC2",
+	"Mic Mute Mixer",
+	"Noise Generator",
+	"IN1L",
+	"IN1R",
+	"IN2L",
+	"IN2R",
+	"IN3L",
+	"IN3R",
+	"IN4L",
+	"IN4R",
+	"IN5L",
+	"IN5R",
+	"IN6L",
+	"IN6R",
+	"AIF1RX1",
+	"AIF1RX2",
+	"AIF1RX3",
+	"AIF1RX4",
+	"AIF1RX5",
+	"AIF1RX6",
+	"AIF1RX7",
+	"AIF1RX8",
+	"AIF2RX1",
+	"AIF2RX2",
+	"AIF2RX3",
+	"AIF2RX4",
+	"AIF2RX5",
+	"AIF2RX6",
+	"AIF2RX7",
+	"AIF2RX8",
+	"AIF3RX1",
+	"AIF3RX2",
+	"AIF4RX1",
+	"AIF4RX2",
+	"SLIMRX1",
+	"SLIMRX2",
+	"SLIMRX3",
+	"SLIMRX4",
+	"SLIMRX5",
+	"SLIMRX6",
+	"SLIMRX7",
+	"SLIMRX8",
+	"EQ1",
+	"EQ2",
+	"EQ3",
+	"EQ4",
+	"DRC1L",
+	"DRC1R",
+	"DRC2L",
+	"DRC2R",
+	"LHPF1",
+	"LHPF2",
+	"LHPF3",
+	"LHPF4",
+	"DSP1.1",
+	"DSP1.2",
+	"DSP1.3",
+	"DSP1.4",
+	"DSP1.5",
+	"DSP1.6",
+	"DSP2.1",
+	"DSP2.2",
+	"DSP2.3",
+	"DSP2.4",
+	"DSP2.5",
+	"DSP2.6",
+	"DSP3.1",
+	"DSP3.2",
+	"DSP3.3",
+	"DSP3.4",
+	"DSP3.5",
+	"DSP3.6",
+	"DSP4.1",
+	"DSP4.2",
+	"DSP4.3",
+	"DSP4.4",
+	"DSP4.5",
+	"DSP4.6",
+	"DSP5.1",
+	"DSP5.2",
+	"DSP5.3",
+	"DSP5.4",
+	"DSP5.5",
+	"DSP5.6",
+	"DSP6.1",
+	"DSP6.2",
+	"DSP6.3",
+	"DSP6.4",
+	"DSP6.5",
+	"DSP6.6",
+	"DSP7.1",
+	"DSP7.2",
+	"DSP7.3",
+	"DSP7.4",
+	"DSP7.5",
+	"DSP7.6",
+	"ASRC1IN1L",
+	"ASRC1IN1R",
+	"ASRC1IN2L",
+	"ASRC1IN2R",
+	"ASRC2IN1L",
+	"ASRC2IN1R",
+	"ASRC2IN2L",
+	"ASRC2IN2R",
+	"ISRC1INT1",
+	"ISRC1INT2",
+	"ISRC1INT3",
+	"ISRC1INT4",
+	"ISRC1DEC1",
+	"ISRC1DEC2",
+	"ISRC1DEC3",
+	"ISRC1DEC4",
+	"ISRC2INT1",
+	"ISRC2INT2",
+	"ISRC2INT3",
+	"ISRC2INT4",
+	"ISRC2DEC1",
+	"ISRC2DEC2",
+	"ISRC2DEC3",
+	"ISRC2DEC4",
+	"ISRC3INT1",
+	"ISRC3INT2",
+	"ISRC3INT3",
+	"ISRC3INT4",
+	"ISRC3DEC1",
+	"ISRC3DEC2",
+	"ISRC3DEC3",
+	"ISRC3DEC4",
+	"ISRC4INT1",
+	"ISRC4INT2",
+	"ISRC4DEC1",
+	"ISRC4DEC2",
+	"DFC1",
+	"DFC2",
+	"DFC3",
+	"DFC4",
+	"DFC5",
+	"DFC6",
+	"DFC7",
+	"DFC8",
+};
+EXPORT_SYMBOL_GPL(madera_mixer_texts);
+
+unsigned int madera_mixer_values[] = {
+	0x00,	/* None */
+	0x04,	/* Tone Generator 1 */
+	0x05,	/* Tone Generator 2 */
+	0x06,	/* Haptics */
+	0x08,	/* AEC */
+	0x09,	/* AEC2 */
+	0x0c,	/* Noise mixer */
+	0x0d,	/* Comfort noise */
+	0x10,	/* IN1L */
+	0x11,
+	0x12,
+	0x13,
+	0x14,
+	0x15,
+	0x16,
+	0x17,
+	0x18,
+	0x19,
+	0x1A,
+	0x1B,
+	0x20,	/* AIF1RX1 */
+	0x21,
+	0x22,
+	0x23,
+	0x24,
+	0x25,
+	0x26,
+	0x27,
+	0x28,	/* AIF2RX1 */
+	0x29,
+	0x2a,
+	0x2b,
+	0x2c,
+	0x2d,
+	0x2e,
+	0x2f,
+	0x30,	/* AIF3RX1 */
+	0x31,
+	0x34,	/* AIF4RX1 */
+	0x35,
+	0x38,	/* SLIMRX1 */
+	0x39,
+	0x3a,
+	0x3b,
+	0x3c,
+	0x3d,
+	0x3e,
+	0x3f,
+	0x50,	/* EQ1 */
+	0x51,
+	0x52,
+	0x53,
+	0x58,	/* DRC1L */
+	0x59,
+	0x5a,
+	0x5b,
+	0x60,	/* LHPF1 */
+	0x61,
+	0x62,
+	0x63,
+	0x68,	/* DSP1.1 */
+	0x69,
+	0x6a,
+	0x6b,
+	0x6c,
+	0x6d,
+	0x70,	/* DSP2.1 */
+	0x71,
+	0x72,
+	0x73,
+	0x74,
+	0x75,
+	0x78,	/* DSP3.1 */
+	0x79,
+	0x7a,
+	0x7b,
+	0x7c,
+	0x7d,
+	0x80,	/* DSP4.1 */
+	0x81,
+	0x82,
+	0x83,
+	0x84,
+	0x85,
+	0x88,	/* DSP5.1 */
+	0x89,
+	0x8a,
+	0x8b,
+	0x8c,
+	0x8d,
+	0xc0,	/* DSP6.1 */
+	0xc1,
+	0xc2,
+	0xc3,
+	0xc4,
+	0xc5,
+	0xc8,	/* DSP7.1 */
+	0xc9,
+	0xca,
+	0xcb,
+	0xcc,
+	0xcd,
+	0x90,	/* ASRC1IN1L */
+	0x91,
+	0x92,
+	0x93,
+	0x94,	/* ASRC2IN1L */
+	0x95,
+	0x96,
+	0x97,
+	0xa0,	/* ISRC1INT1 */
+	0xa1,
+	0xa2,
+	0xa3,
+	0xa4,	/* ISRC1DEC1 */
+	0xa5,
+	0xa6,
+	0xa7,
+	0xa8,	/* ISRC2DEC1 */
+	0xa9,
+	0xaa,
+	0xab,
+	0xac,	/* ISRC2INT1 */
+	0xad,
+	0xae,
+	0xaf,
+	0xb0,	/* ISRC3DEC1 */
+	0xb1,
+	0xb2,
+	0xb3,
+	0xb4,	/* ISRC3INT1 */
+	0xb5,
+	0xb6,
+	0xb7,
+	0xb8,	/* ISRC4INT1 */
+	0xb9,
+	0xbc,	/* ISRC4DEC1 */
+	0xbd,
+	0xf8,	/* DFC1 */
+	0xf9,
+	0xfa,
+	0xfb,
+	0xfc,
+	0xfd,
+	0xfe,
+	0xff,	/* DFC8 */
+};
+EXPORT_SYMBOL_GPL(madera_mixer_values);
+
+const DECLARE_TLV_DB_SCALE(madera_ana_tlv, 0, 100, 0);
+EXPORT_SYMBOL_GPL(madera_ana_tlv);
+
+const DECLARE_TLV_DB_SCALE(madera_eq_tlv, -1200, 100, 0);
+EXPORT_SYMBOL_GPL(madera_eq_tlv);
+
+const DECLARE_TLV_DB_SCALE(madera_digital_tlv, -6400, 50, 0);
+EXPORT_SYMBOL_GPL(madera_digital_tlv);
+
+const DECLARE_TLV_DB_SCALE(madera_noise_tlv, -13200, 600, 0);
+EXPORT_SYMBOL_GPL(madera_noise_tlv);
+
+const DECLARE_TLV_DB_SCALE(madera_ng_tlv, -12000, 600, 0);
+EXPORT_SYMBOL_GPL(madera_ng_tlv);
+
+const DECLARE_TLV_DB_SCALE(madera_mixer_tlv, -3200, 100, 0);
+EXPORT_SYMBOL_GPL(madera_mixer_tlv);
+
+const char * const madera_sample_rate_text[MADERA_SAMPLE_RATE_ENUM_SIZE] = {
+	"12kHz", "24kHz", "48kHz", "96kHz", "192kHz", "384kHz",
+	"11.025kHz", "22.05kHz", "44.1kHz", "88.2kHz", "176.4kHz", "352.8kHz",
+	"4kHz", "8kHz", "16kHz", "32kHz",
+};
+EXPORT_SYMBOL_GPL(madera_sample_rate_text);
+
+const unsigned int madera_sample_rate_val[MADERA_SAMPLE_RATE_ENUM_SIZE] = {
+	0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+	0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+	0x10, 0x11, 0x12, 0x13,
+};
+EXPORT_SYMBOL_GPL(madera_sample_rate_val);
+
+const char *madera_sample_rate_val_to_name(unsigned int rate_val)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(madera_sample_rate_val); ++i) {
+		if (madera_sample_rate_val[i] == rate_val)
+			return madera_sample_rate_text[i];
+	}
+
+	return "Illegal";
+}
+EXPORT_SYMBOL_GPL(madera_sample_rate_val_to_name);
+
+const struct soc_enum madera_sample_rate[] = {
+	SOC_VALUE_ENUM_SINGLE(MADERA_SAMPLE_RATE_2,
+			      MADERA_SAMPLE_RATE_2_SHIFT, 0x1f,
+			      MADERA_SAMPLE_RATE_ENUM_SIZE,
+			      madera_sample_rate_text,
+			      madera_sample_rate_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_SAMPLE_RATE_3,
+			      MADERA_SAMPLE_RATE_3_SHIFT, 0x1f,
+			      MADERA_SAMPLE_RATE_ENUM_SIZE,
+			      madera_sample_rate_text,
+			      madera_sample_rate_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_ASYNC_SAMPLE_RATE_2,
+			      MADERA_ASYNC_SAMPLE_RATE_2_SHIFT, 0x1f,
+			      MADERA_SAMPLE_RATE_ENUM_SIZE,
+			      madera_sample_rate_text,
+			      madera_sample_rate_val),
+
+};
+EXPORT_SYMBOL_GPL(madera_sample_rate);
+
+const char * const madera_rate_text[MADERA_RATE_ENUM_SIZE] = {
+	"SYNCCLK rate 1", "SYNCCLK rate 2", "SYNCCLK rate 3",
+	"ASYNCCLK rate 1", "ASYNCCLK rate 2",
+};
+EXPORT_SYMBOL_GPL(madera_rate_text);
+
+const unsigned int madera_rate_val[MADERA_RATE_ENUM_SIZE] = {
+	0x0, 0x1, 0x2, 0x8, 0x9,
+};
+EXPORT_SYMBOL_GPL(madera_rate_val);
+
+const char * const madera_dfc_width_text[MADERA_DFC_WIDTH_ENUM_SIZE] = {
+	"8bit", "16bit", "20bit", "24bit", "32bit",
+};
+EXPORT_SYMBOL_GPL(madera_dfc_width_text);
+
+const unsigned int madera_dfc_width_val[MADERA_DFC_WIDTH_ENUM_SIZE] = {
+	7, 15, 19, 23, 31,
+};
+EXPORT_SYMBOL_GPL(madera_dfc_width_val);
+
+const char * const madera_dfc_type_text[MADERA_DFC_TYPE_ENUM_SIZE] = {
+	"Fixed", "Unsigned Fixed", "Single Precision Floating",
+	"Half Precision Floating", "Arm Alternative Floating",
+};
+EXPORT_SYMBOL_GPL(madera_dfc_type_text);
+
+const unsigned int madera_dfc_type_val[MADERA_DFC_TYPE_ENUM_SIZE] = {
+	0, 1, 2, 4, 5,
+};
+EXPORT_SYMBOL_GPL(madera_dfc_type_val);
+
+const struct soc_enum madera_dfc_width[] = {
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_RX,
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_RX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_TX,
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_TX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_RX,
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_RX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_TX,
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_TX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_RX,
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_RX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_TX,
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_TX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_RX,
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_RX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_TX,
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_TX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_RX,
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_RX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_TX,
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_TX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_RX,
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_RX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_TX,
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_TX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_RX,
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_RX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_TX,
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_TX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_RX,
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_RX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_TX,
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      MADERA_DFC1_TX_DATA_WIDTH_MASK >>
+			      MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
+			      ARRAY_SIZE(madera_dfc_width_text),
+			      madera_dfc_width_text,
+			      madera_dfc_width_val),
+};
+EXPORT_SYMBOL_GPL(madera_dfc_width);
+
+const struct soc_enum madera_dfc_type[] = {
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_RX,
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_RX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_TX,
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_TX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_RX,
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_RX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_TX,
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_TX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_RX,
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_RX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_TX,
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_TX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_RX,
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_RX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_TX,
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_TX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_RX,
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_RX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_TX,
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_TX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_RX,
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_RX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_TX,
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_TX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_RX,
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_RX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_TX,
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_TX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_RX,
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_RX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_RX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_TX,
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      MADERA_DFC1_TX_DATA_TYPE_MASK >>
+			      MADERA_DFC1_TX_DATA_TYPE_SHIFT,
+			      ARRAY_SIZE(madera_dfc_type_text),
+			      madera_dfc_type_text,
+			      madera_dfc_type_val),
+};
+EXPORT_SYMBOL_GPL(madera_dfc_type);
+
+const struct soc_enum madera_isrc_fsh[] = {
+	SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_1_CTRL_1,
+			      MADERA_ISRC1_FSH_SHIFT, 0xf,
+			      MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_2_CTRL_1,
+			      MADERA_ISRC2_FSH_SHIFT, 0xf,
+			      MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_3_CTRL_1,
+			      MADERA_ISRC3_FSH_SHIFT, 0xf,
+			      MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_4_CTRL_1,
+			      MADERA_ISRC4_FSH_SHIFT, 0xf,
+			      MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+
+};
+EXPORT_SYMBOL_GPL(madera_isrc_fsh);
+
+const struct soc_enum madera_isrc_fsl[] = {
+	SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_1_CTRL_2,
+			      MADERA_ISRC1_FSL_SHIFT, 0xf,
+			      MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_2_CTRL_2,
+			      MADERA_ISRC2_FSL_SHIFT, 0xf,
+			      MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_3_CTRL_2,
+			      MADERA_ISRC3_FSL_SHIFT, 0xf,
+			      MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_4_CTRL_2,
+			      MADERA_ISRC4_FSL_SHIFT, 0xf,
+			      MADERA_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+
+};
+EXPORT_SYMBOL_GPL(madera_isrc_fsl);
+
+const struct soc_enum madera_asrc1_rate[] = {
+	SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE1,
+			      MADERA_ASRC1_RATE1_SHIFT, 0xf,
+			      MADERA_SYNC_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE2,
+			      MADERA_ASRC1_RATE1_SHIFT, 0xf,
+			      MADERA_ASYNC_RATE_ENUM_SIZE,
+			      madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
+			      madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
+
+};
+EXPORT_SYMBOL_GPL(madera_asrc1_rate);
+
+const struct soc_enum madera_asrc2_rate[] = {
+	SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE1,
+			      MADERA_ASRC2_RATE1_SHIFT, 0xf,
+			      MADERA_SYNC_RATE_ENUM_SIZE,
+			      madera_rate_text, madera_rate_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE2,
+			      MADERA_ASRC2_RATE2_SHIFT, 0xf,
+			      MADERA_ASYNC_RATE_ENUM_SIZE,
+			      madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
+			      madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
+
+};
+EXPORT_SYMBOL_GPL(madera_asrc2_rate);
+
+static const char * const madera_vol_ramp_text[] = {
+	"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
+	"15ms/6dB", "30ms/6dB",
+};
+
+SOC_ENUM_SINGLE_DECL(madera_in_vd_ramp,
+		     MADERA_INPUT_VOLUME_RAMP,
+		     MADERA_IN_VD_RAMP_SHIFT,
+		     madera_vol_ramp_text);
+EXPORT_SYMBOL_GPL(madera_in_vd_ramp);
+
+SOC_ENUM_SINGLE_DECL(madera_in_vi_ramp,
+		     MADERA_INPUT_VOLUME_RAMP,
+		     MADERA_IN_VI_RAMP_SHIFT,
+		     madera_vol_ramp_text);
+EXPORT_SYMBOL_GPL(madera_in_vi_ramp);
+
+SOC_ENUM_SINGLE_DECL(madera_out_vd_ramp,
+		     MADERA_OUTPUT_VOLUME_RAMP,
+		     MADERA_OUT_VD_RAMP_SHIFT,
+		     madera_vol_ramp_text);
+EXPORT_SYMBOL_GPL(madera_out_vd_ramp);
+
+SOC_ENUM_SINGLE_DECL(madera_out_vi_ramp,
+		     MADERA_OUTPUT_VOLUME_RAMP,
+		     MADERA_OUT_VI_RAMP_SHIFT,
+		     madera_vol_ramp_text);
+EXPORT_SYMBOL_GPL(madera_out_vi_ramp);
+
+static const char * const madera_lhpf_mode_text[] = {
+	"Low-pass", "High-pass"
+};
+
+SOC_ENUM_SINGLE_DECL(madera_lhpf1_mode,
+		     MADERA_HPLPF1_1,
+		     MADERA_LHPF1_MODE_SHIFT,
+		     madera_lhpf_mode_text);
+EXPORT_SYMBOL_GPL(madera_lhpf1_mode);
+
+SOC_ENUM_SINGLE_DECL(madera_lhpf2_mode,
+		     MADERA_HPLPF2_1,
+		     MADERA_LHPF2_MODE_SHIFT,
+		     madera_lhpf_mode_text);
+EXPORT_SYMBOL_GPL(madera_lhpf2_mode);
+
+SOC_ENUM_SINGLE_DECL(madera_lhpf3_mode,
+		     MADERA_HPLPF3_1,
+		     MADERA_LHPF3_MODE_SHIFT,
+		     madera_lhpf_mode_text);
+EXPORT_SYMBOL_GPL(madera_lhpf3_mode);
+
+SOC_ENUM_SINGLE_DECL(madera_lhpf4_mode,
+		     MADERA_HPLPF4_1,
+		     MADERA_LHPF4_MODE_SHIFT,
+		     madera_lhpf_mode_text);
+EXPORT_SYMBOL_GPL(madera_lhpf4_mode);
+
+static const char * const madera_ng_hold_text[] = {
+	"30ms", "120ms", "250ms", "500ms",
+};
+
+SOC_ENUM_SINGLE_DECL(madera_ng_hold,
+		     MADERA_NOISE_GATE_CONTROL,
+		     MADERA_NGATE_HOLD_SHIFT,
+		     madera_ng_hold_text);
+EXPORT_SYMBOL_GPL(madera_ng_hold);
+
+static const char * const madera_in_hpf_cut_text[] = {
+	"2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
+};
+
+SOC_ENUM_SINGLE_DECL(madera_in_hpf_cut_enum,
+		     MADERA_HPF_CONTROL,
+		     MADERA_IN_HPF_CUT_SHIFT,
+		     madera_in_hpf_cut_text);
+EXPORT_SYMBOL_GPL(madera_in_hpf_cut_enum);
+
+static const char * const madera_in_dmic_osr_text[MADERA_OSR_ENUM_SIZE] = {
+	"384kHz", "768kHz", "1.536MHz", "3.072MHz", "6.144MHz",
+};
+
+static const unsigned int madera_in_dmic_osr_val[MADERA_OSR_ENUM_SIZE] = {
+	2, 3, 4, 5, 6,
+};
+
+const struct soc_enum madera_in_dmic_osr[] = {
+	SOC_VALUE_ENUM_SINGLE(MADERA_DMIC1L_CONTROL, MADERA_IN1_OSR_SHIFT,
+			      0x7, MADERA_OSR_ENUM_SIZE,
+			      madera_in_dmic_osr_text, madera_in_dmic_osr_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DMIC2L_CONTROL, MADERA_IN2_OSR_SHIFT,
+			      0x7, MADERA_OSR_ENUM_SIZE,
+			      madera_in_dmic_osr_text, madera_in_dmic_osr_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DMIC3L_CONTROL, MADERA_IN3_OSR_SHIFT,
+			      0x7, MADERA_OSR_ENUM_SIZE,
+			      madera_in_dmic_osr_text, madera_in_dmic_osr_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DMIC4L_CONTROL, MADERA_IN4_OSR_SHIFT,
+			      0x7, MADERA_OSR_ENUM_SIZE,
+			      madera_in_dmic_osr_text, madera_in_dmic_osr_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DMIC5L_CONTROL, MADERA_IN5_OSR_SHIFT,
+			      0x7, MADERA_OSR_ENUM_SIZE,
+			      madera_in_dmic_osr_text, madera_in_dmic_osr_val),
+	SOC_VALUE_ENUM_SINGLE(MADERA_DMIC6L_CONTROL, MADERA_IN6_OSR_SHIFT,
+			      0x7, MADERA_OSR_ENUM_SIZE,
+			      madera_in_dmic_osr_text, madera_in_dmic_osr_val),
+};
+EXPORT_SYMBOL_GPL(madera_in_dmic_osr);
+
+static const char * const madera_anc_input_src_text[] = {
+	"None", "IN1", "IN2", "IN3", "IN4", "IN5", "IN6",
+};
+
+static const char * const madera_anc_channel_src_text[] = {
+	"None", "Left", "Right", "Combine",
+};
+
+const struct soc_enum madera_anc_input_src[] = {
+	SOC_ENUM_SINGLE(MADERA_ANC_SRC,
+			MADERA_IN_RXANCL_SEL_SHIFT,
+			ARRAY_SIZE(madera_anc_input_src_text),
+			madera_anc_input_src_text),
+	SOC_ENUM_SINGLE(MADERA_FCL_ADC_REFORMATTER_CONTROL,
+			MADERA_FCL_MIC_MODE_SEL,
+			ARRAY_SIZE(madera_anc_channel_src_text),
+			madera_anc_channel_src_text),
+	SOC_ENUM_SINGLE(MADERA_ANC_SRC,
+			MADERA_IN_RXANCR_SEL_SHIFT,
+			ARRAY_SIZE(madera_anc_input_src_text),
+			madera_anc_input_src_text),
+	SOC_ENUM_SINGLE(MADERA_FCR_ADC_REFORMATTER_CONTROL,
+			MADERA_FCR_MIC_MODE_SEL,
+			ARRAY_SIZE(madera_anc_channel_src_text),
+			madera_anc_channel_src_text),
+};
+EXPORT_SYMBOL_GPL(madera_anc_input_src);
+
+static const char * const madera_anc_ng_texts[] = {
+	"None", "Internal", "External",
+};
+
+SOC_ENUM_SINGLE_DECL(madera_anc_ng_enum, SND_SOC_NOPM, 0, madera_anc_ng_texts);
+EXPORT_SYMBOL_GPL(madera_anc_ng_enum);
+
+static const char * const madera_out_anc_src_text[] = {
+	"None", "RXANCL", "RXANCR",
+};
+
+const struct soc_enum madera_output_anc_src[] = {
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_1L,
+			MADERA_OUT1L_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_1R,
+			MADERA_OUT1R_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_2L,
+			MADERA_OUT2L_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_2R,
+			MADERA_OUT2R_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_3L,
+			MADERA_OUT3L_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_3R,
+			MADERA_OUT3R_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_4L,
+			MADERA_OUT4L_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_4R,
+			MADERA_OUT4R_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_5L,
+			MADERA_OUT5L_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_5R,
+			MADERA_OUT5R_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_6L,
+			MADERA_OUT6L_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+	SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_6R,
+			MADERA_OUT6R_ANC_SRC_SHIFT,
+			ARRAY_SIZE(madera_out_anc_src_text),
+			madera_out_anc_src_text),
+};
+EXPORT_SYMBOL_GPL(madera_output_anc_src);
+
+int madera_dfc_put(struct snd_kcontrol *kcontrol,
+		   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int reg = e->reg;
+	unsigned int val;
+	int ret = 0;
+
+	reg = ((reg / 6) * 6) - 2;
+
+	snd_soc_dapm_mutex_lock(dapm);
+
+	val = snd_soc_read(codec, reg);
+	if (val & MADERA_DFC1_ENA) {
+		ret = -EBUSY;
+		dev_err(codec->dev, "Can't change mode on an active DFC\n");
+		goto exit;
+	}
+
+	ret = snd_soc_put_enum_double(kcontrol, ucontrol);
+exit:
+	snd_soc_dapm_mutex_unlock(dapm);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(madera_dfc_put);
+
+int madera_lp_mode_put(struct snd_kcontrol *kcontrol,
+		       struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	unsigned int reg, mask;
+	int ret;
+
+	snd_soc_dapm_mutex_lock(dapm);
+
+	/* Cannot change lp mode on an active input */
+	reg = snd_soc_read(codec, MADERA_INPUT_ENABLES);
+	mask = (mc->reg - MADERA_ADC_DIGITAL_VOLUME_1L) / 4;
+	mask ^= 0x1; /* Flip bottom bit for channel order */
+
+	if ((reg) & (1 << mask)) {
+		ret = -EBUSY;
+		dev_err(codec->dev,
+			"Can't change lp mode on an active input\n");
+		goto exit;
+	}
+
+	ret = snd_soc_put_volsw(kcontrol, ucontrol);
+
+exit:
+	snd_soc_dapm_mutex_unlock(dapm);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(madera_lp_mode_put);
+
+const struct snd_kcontrol_new madera_dsp_trigger_output_mux[] = {
+	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
+	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
+	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
+	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
+	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
+	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
+	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
+};
+EXPORT_SYMBOL_GPL(madera_dsp_trigger_output_mux);
+
+const struct snd_kcontrol_new madera_drc_activity_output_mux[] = {
+	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
+	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
+};
+EXPORT_SYMBOL_GPL(madera_drc_activity_output_mux);
+
+static void madera_in_set_vu(struct madera_priv *priv, bool enable)
+{
+	unsigned int val;
+	int i, ret;
+
+	if (enable)
+		val = MADERA_IN_VU;
+	else
+		val = 0;
+
+	for (i = 0; i < priv->num_inputs; i++) {
+		ret = regmap_update_bits(priv->madera->regmap,
+				    MADERA_ADC_DIGITAL_VOLUME_1L + (i * 4),
+				    MADERA_IN_VU, val);
+		if (ret)
+			dev_warn(priv->madera->dev,
+				 "Failed to modify VU bits: %d\n", ret);
+	}
+}
+
+int madera_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
+		 int event)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	unsigned int reg;
+
+	if (w->shift % 2)
+		reg = MADERA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
+	else
+		reg = MADERA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		priv->in_pending++;
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		priv->in_pending--;
+		snd_soc_update_bits(codec, reg, MADERA_IN1L_MUTE, 0);
+
+		/* If this is the last input pending then allow VU */
+		if (priv->in_pending == 0) {
+			usleep_range(1000, 3000);
+			madera_in_set_vu(priv, true);
+		}
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		snd_soc_update_bits(codec, reg,
+				    MADERA_IN1L_MUTE | MADERA_IN_VU,
+				    MADERA_IN1L_MUTE | MADERA_IN_VU);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* Disable volume updates if no inputs are enabled */
+		reg = snd_soc_read(codec, MADERA_INPUT_ENABLES);
+		if (reg == 0)
+			madera_in_set_vu(priv, false);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_in_ev);
+
+int madera_dre_put(struct snd_kcontrol *kcontrol,
+		   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	int ret;
+
+	snd_soc_dapm_mutex_lock(dapm);
+
+	ret = snd_soc_put_volsw(kcontrol, ucontrol);
+
+	snd_soc_dapm_mutex_unlock(dapm);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(madera_dre_put);
+
+int madera_out_ev(struct snd_soc_dapm_widget *w,
+		  struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct madera *madera = priv->madera;
+	int out_up_delay;
+
+	switch (madera->type) {
+	case CS47L90:
+	case CS47L91:
+		out_up_delay = 6;
+		break;
+	default:
+		out_up_delay = 17;
+		break;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		switch (w->shift) {
+		case MADERA_OUT1L_ENA_SHIFT:
+		case MADERA_OUT1R_ENA_SHIFT:
+		case MADERA_OUT2L_ENA_SHIFT:
+		case MADERA_OUT2R_ENA_SHIFT:
+		case MADERA_OUT3L_ENA_SHIFT:
+		case MADERA_OUT3R_ENA_SHIFT:
+			priv->out_up_pending++;
+			priv->out_up_delay += out_up_delay;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case SND_SOC_DAPM_POST_PMU:
+		switch (w->shift) {
+		case MADERA_OUT1L_ENA_SHIFT:
+		case MADERA_OUT1R_ENA_SHIFT:
+		case MADERA_OUT2L_ENA_SHIFT:
+		case MADERA_OUT2R_ENA_SHIFT:
+		case MADERA_OUT3L_ENA_SHIFT:
+		case MADERA_OUT3R_ENA_SHIFT:
+			priv->out_up_pending--;
+			if (!priv->out_up_pending) {
+				msleep(priv->out_up_delay);
+				priv->out_up_delay = 0;
+			}
+			break;
+
+		default:
+			break;
+		}
+		break;
+
+	case SND_SOC_DAPM_PRE_PMD:
+		switch (w->shift) {
+		case MADERA_OUT1L_ENA_SHIFT:
+		case MADERA_OUT1R_ENA_SHIFT:
+		case MADERA_OUT2L_ENA_SHIFT:
+		case MADERA_OUT2R_ENA_SHIFT:
+		case MADERA_OUT3L_ENA_SHIFT:
+		case MADERA_OUT3R_ENA_SHIFT:
+			priv->out_down_pending++;
+			priv->out_down_delay++;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case SND_SOC_DAPM_POST_PMD:
+		switch (w->shift) {
+		case MADERA_OUT1L_ENA_SHIFT:
+		case MADERA_OUT1R_ENA_SHIFT:
+		case MADERA_OUT2L_ENA_SHIFT:
+		case MADERA_OUT2R_ENA_SHIFT:
+		case MADERA_OUT3L_ENA_SHIFT:
+		case MADERA_OUT3R_ENA_SHIFT:
+			priv->out_down_pending--;
+			if (!priv->out_down_pending) {
+				msleep(priv->out_down_delay);
+				priv->out_down_delay = 0;
+			}
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_out_ev);
+
+int madera_hp_ev(struct snd_soc_dapm_widget *w,
+		 struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct madera *madera = priv->madera;
+	unsigned int mask = 1 << w->shift;
+	unsigned int out_num = w->shift / 2;
+	unsigned int val;
+	unsigned int ep_sel = 0;
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		val = mask;
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		val = 0;
+		break;
+	case SND_SOC_DAPM_PRE_PMU:
+	case SND_SOC_DAPM_POST_PMD:
+		return madera_out_ev(w, kcontrol, event);
+	default:
+		return 0;
+	}
+
+	/* Store the desired state for the HP outputs */
+	madera->hp_ena &= ~mask;
+	madera->hp_ena |= val;
+
+	/* if OUT1 is routed to EPOUT, ignore HP clamp and impedance */
+	regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
+	ep_sel &= MADERA_EP_SEL_MASK;
+
+	/* Force off if HPDET clamp is active for this output */
+	if (!ep_sel &&
+	    (madera->out_clamp[out_num] || madera->out_shorted[out_num]))
+		val = 0;
+
+	regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, mask, val);
+
+	return madera_out_ev(w, kcontrol, event);
+}
+EXPORT_SYMBOL_GPL(madera_hp_ev);
+
+int madera_anc_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
+		  int event)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	unsigned int val;
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		val = 1 << w->shift;
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		val = 1 << (w->shift + 1);
+		break;
+	default:
+		return 0;
+	}
+
+	snd_soc_write(codec, MADERA_CLOCK_CONTROL, val);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_anc_ev);
+
+static const unsigned int madera_opclk_ref_48k_rates[] = {
+	6144000,
+	12288000,
+	24576000,
+	49152000,
+};
+
+static const unsigned int madera_opclk_ref_44k1_rates[] = {
+	5644800,
+	11289600,
+	22579200,
+	45158400,
+};
+
+static int madera_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
+			    unsigned int freq)
+{
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	unsigned int reg;
+	const unsigned int *rates;
+	int ref, div, refclk;
+
+	BUILD_BUG_ON(ARRAY_SIZE(madera_opclk_ref_48k_rates) !=
+		     ARRAY_SIZE(madera_opclk_ref_44k1_rates));
+
+	switch (clk) {
+	case MADERA_CLK_OPCLK:
+		reg = MADERA_OUTPUT_SYSTEM_CLOCK;
+		refclk = priv->sysclk;
+		break;
+	case MADERA_CLK_ASYNC_OPCLK:
+		reg = MADERA_OUTPUT_ASYNC_CLOCK;
+		refclk = priv->asyncclk;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (refclk % 4000)
+		rates = madera_opclk_ref_44k1_rates;
+	else
+		rates = madera_opclk_ref_48k_rates;
+
+	for (ref = 0; ref < ARRAY_SIZE(madera_opclk_ref_48k_rates); ++ref) {
+		if (rates[ref] > refclk)
+			continue;
+
+		div = 2;
+		while ((rates[ref] / div >= freq) && (div <= 30)) {
+			if (rates[ref] / div == freq) {
+				dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
+					freq);
+				snd_soc_update_bits(codec, reg,
+						    MADERA_OPCLK_DIV_MASK |
+						    MADERA_OPCLK_SEL_MASK,
+						    (div <<
+						     MADERA_OPCLK_DIV_SHIFT) |
+						    ref);
+				return 0;
+			}
+			div += 2;
+		}
+	}
+
+	dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
+
+	return -EINVAL;
+}
+
+static int madera_get_sysclk_setting(unsigned int freq)
+{
+	switch (freq) {
+	case 0:
+	case 5644800:
+	case 6144000:
+		return 0;
+	case 11289600:
+	case 12288000:
+		return MADERA_SYSCLK_12MHZ << MADERA_SYSCLK_FREQ_SHIFT;
+	case 22579200:
+	case 24576000:
+		return MADERA_SYSCLK_24MHZ << MADERA_SYSCLK_FREQ_SHIFT;
+	case 45158400:
+	case 49152000:
+		return MADERA_SYSCLK_49MHZ << MADERA_SYSCLK_FREQ_SHIFT;
+	case 90316800:
+	case 98304000:
+		return MADERA_SYSCLK_98MHZ << MADERA_SYSCLK_FREQ_SHIFT;
+	default:
+		return -EINVAL;
+	}
+}
+
+int madera_get_legacy_dspclk_setting(struct madera *madera, unsigned int freq)
+{
+	switch (freq) {
+	case 0:
+		return 0;
+	case 45158400:
+	case 49152000:
+		switch (madera->type) {
+		case CS47L85:
+		case WM1840:
+			if (madera->rev < 3)
+				return -EINVAL;
+			else
+				return MADERA_SYSCLK_49MHZ <<
+				       MADERA_SYSCLK_FREQ_SHIFT;
+		default:
+			return -EINVAL;
+		}
+	case 135475200:
+	case 147456000:
+		return MADERA_DSPCLK_147MHZ << MADERA_DSP_CLK_FREQ_LEGACY_SHIFT;
+	default:
+		return -EINVAL;
+	}
+}
+EXPORT_SYMBOL_GPL(madera_get_legacy_dspclk_setting);
+
+static int madera_get_dspclk_setting(struct madera *madera,
+				     unsigned int freq,
+				     unsigned int *clock_2_val)
+{
+	switch (madera->type) {
+	case CS47L35:
+	case CS47L85:
+	case WM1840:
+		*clock_2_val = 0; /* don't use MADERA_DSP_CLOCK_2 */
+		return madera_get_legacy_dspclk_setting(madera, freq);
+	default:
+		if (freq > 150000000)
+			return -EINVAL;
+
+		/* Use new exact frequency control */
+		*clock_2_val = freq / 15625; /* freq * (2^6) / (10^6) */
+		return 0;
+	}
+}
+
+int madera_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+		      int source, unsigned int freq, int dir)
+{
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct madera *madera = priv->madera;
+	char *name;
+	unsigned int reg, clock_2_val = 0;
+	unsigned int mask = MADERA_SYSCLK_FREQ_MASK | MADERA_SYSCLK_SRC_MASK;
+	unsigned int val = source << MADERA_SYSCLK_SRC_SHIFT;
+	int clk_freq_sel, *clk;
+	int ret = 0;
+
+	switch (clk_id) {
+	case MADERA_CLK_SYSCLK_1:
+		name = "SYSCLK";
+		reg = MADERA_SYSTEM_CLOCK_1;
+		clk = &priv->sysclk;
+		clk_freq_sel = madera_get_sysclk_setting(freq);
+		mask |= MADERA_SYSCLK_FRAC;
+		break;
+	case MADERA_CLK_ASYNCCLK_1:
+		name = "ASYNCCLK";
+		reg = MADERA_ASYNC_CLOCK_1;
+		clk = &priv->asyncclk;
+		clk_freq_sel = madera_get_sysclk_setting(freq);
+		break;
+	case MADERA_CLK_OPCLK:
+	case MADERA_CLK_ASYNC_OPCLK:
+		return madera_set_opclk(codec, clk_id, freq);
+	case MADERA_CLK_DSPCLK:
+		name = "DSPCLK";
+		reg = MADERA_DSP_CLOCK_1;
+		clk = &priv->dspclk;
+		clk_freq_sel = madera_get_dspclk_setting(madera, freq,
+							 &clock_2_val);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (clk_freq_sel < 0) {
+		dev_err(madera->dev,
+			"Failed to get clk setting for %dHZ\n", freq);
+		return clk_freq_sel;
+	}
+
+	*clk = freq;
+
+	if (freq == 0) {
+		dev_dbg(madera->dev, "%s cleared\n", name);
+		return 0;
+	}
+
+	val |= clk_freq_sel;
+
+	if (clock_2_val) {
+		ret = regmap_write(madera->regmap, MADERA_DSP_CLOCK_2,
+				   clock_2_val);
+		if (ret) {
+			dev_err(madera->dev,
+				"Failed to write DSP_CONFIG2: %d\n", ret);
+			return ret;
+		}
+
+		/*
+		 * We're using the frequency setting in MADERA_DSP_CLOCK_2 so
+		 * don't change the frequency select bits in MADERA_DSP_CLOCK_1
+		 */
+		mask = MADERA_SYSCLK_SRC_MASK;
+	}
+
+	if (freq % 6144000)
+		val |= MADERA_SYSCLK_FRAC;
+
+	dev_dbg(madera->dev, "%s set to %uHz", name, freq);
+
+	return regmap_update_bits(madera->regmap, reg, mask, val);
+}
+EXPORT_SYMBOL_GPL(madera_set_sysclk);
+
+static int madera_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct madera *madera = priv->madera;
+	int lrclk, bclk, mode, base;
+
+	base = dai->driver->base;
+
+	lrclk = 0;
+	bclk = 0;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_DSP_A:
+		mode = MADERA_FMT_DSP_MODE_A;
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
+				!= SND_SOC_DAIFMT_CBM_CFM) {
+			madera_aif_err(dai, "DSP_B not valid in slave mode\n");
+			return -EINVAL;
+		}
+		mode = MADERA_FMT_DSP_MODE_B;
+		break;
+	case SND_SOC_DAIFMT_I2S:
+		mode = MADERA_FMT_I2S_MODE;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
+				!= SND_SOC_DAIFMT_CBM_CFM) {
+			madera_aif_err(dai, "LEFT_J not valid in slave mode\n");
+			return -EINVAL;
+		}
+		mode = MADERA_FMT_LEFT_JUSTIFIED_MODE;
+		break;
+	default:
+		madera_aif_err(dai, "Unsupported DAI format %d\n",
+			       fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS:
+		break;
+	case SND_SOC_DAIFMT_CBS_CFM:
+		lrclk |= MADERA_AIF1TX_LRCLK_MSTR;
+		break;
+	case SND_SOC_DAIFMT_CBM_CFS:
+		bclk |= MADERA_AIF1_BCLK_MSTR;
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM:
+		bclk |= MADERA_AIF1_BCLK_MSTR;
+		lrclk |= MADERA_AIF1TX_LRCLK_MSTR;
+		break;
+	default:
+		madera_aif_err(dai, "Unsupported master mode %d\n",
+			       fmt & SND_SOC_DAIFMT_MASTER_MASK);
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		bclk |= MADERA_AIF1_BCLK_INV;
+		lrclk |= MADERA_AIF1TX_LRCLK_INV;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		bclk |= MADERA_AIF1_BCLK_INV;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		lrclk |= MADERA_AIF1TX_LRCLK_INV;
+		break;
+	default:
+		madera_aif_err(dai, "Unsupported invert mode %d\n",
+			       fmt & SND_SOC_DAIFMT_INV_MASK);
+		return -EINVAL;
+	}
+
+	regmap_update_bits(madera->regmap, base + MADERA_AIF_BCLK_CTRL,
+			   MADERA_AIF1_BCLK_INV | MADERA_AIF1_BCLK_MSTR,
+			   bclk);
+	regmap_update_bits(madera->regmap, base + MADERA_AIF_TX_PIN_CTRL,
+			   MADERA_AIF1TX_LRCLK_INV | MADERA_AIF1TX_LRCLK_MSTR,
+			   lrclk);
+	regmap_update_bits(madera->regmap,
+			   base + MADERA_AIF_RX_PIN_CTRL,
+			   MADERA_AIF1RX_LRCLK_INV | MADERA_AIF1RX_LRCLK_MSTR,
+			   lrclk);
+	regmap_update_bits(madera->regmap, base + MADERA_AIF_FORMAT,
+			   MADERA_AIF1_FMT_MASK, mode);
+
+	return 0;
+}
+
+static const int madera_48k_bclk_rates[] = {
+	-1,
+	48000,
+	64000,
+	96000,
+	128000,
+	192000,
+	256000,
+	384000,
+	512000,
+	768000,
+	1024000,
+	1536000,
+	2048000,
+	3072000,
+	4096000,
+	6144000,
+	8192000,
+	12288000,
+	24576000,
+};
+
+static const int madera_44k1_bclk_rates[] = {
+	-1,
+	44100,
+	58800,
+	88200,
+	117600,
+	177640,
+	235200,
+	352800,
+	470400,
+	705600,
+	940800,
+	1411200,
+	1881600,
+	2822400,
+	3763200,
+	5644800,
+	7526400,
+	11289600,
+	22579200,
+};
+
+static const unsigned int madera_sr_vals[] = {
+	0,
+	12000,
+	24000,
+	48000,
+	96000,
+	192000,
+	384000,
+	768000,
+	0,
+	11025,
+	22050,
+	44100,
+	88200,
+	176400,
+	352800,
+	705600,
+	4000,
+	8000,
+	16000,
+	32000,
+	64000,
+	128000,
+	256000,
+	512000,
+};
+
+#define MADERA_48K_RATE_MASK	0x0F003E
+#define MADERA_44K1_RATE_MASK	0x003E00
+#define MADERA_RATE_MASK	(MADERA_48K_RATE_MASK | MADERA_44K1_RATE_MASK)
+
+static const struct snd_pcm_hw_constraint_list madera_constraint = {
+	.count	= ARRAY_SIZE(madera_sr_vals),
+	.list	= madera_sr_vals,
+};
+
+static int madera_startup(struct snd_pcm_substream *substream,
+			  struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
+	unsigned int base_rate;
+
+	if (!substream->runtime)
+		return 0;
+
+	switch (dai_priv->clk) {
+	case MADERA_CLK_SYSCLK_1:
+	case MADERA_CLK_SYSCLK_2:
+	case MADERA_CLK_SYSCLK_3:
+		base_rate = priv->sysclk;
+		break;
+	case MADERA_CLK_ASYNCCLK_1:
+	case MADERA_CLK_ASYNCCLK_2:
+		base_rate = priv->asyncclk;
+		break;
+	default:
+		return 0;
+	}
+
+	if (base_rate == 0)
+		dai_priv->constraint.mask = MADERA_RATE_MASK;
+	else if (base_rate % 4000)
+		dai_priv->constraint.mask = MADERA_44K1_RATE_MASK;
+	else
+		dai_priv->constraint.mask = MADERA_48K_RATE_MASK;
+
+	return snd_pcm_hw_constraint_list(substream->runtime, 0,
+					  SNDRV_PCM_HW_PARAM_RATE,
+					  &dai_priv->constraint);
+}
+
+static int madera_hw_params_rate(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params,
+				 struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
+	int base = dai->driver->base;
+	int ret = 0;
+	int i, sr_val;
+	unsigned int cur, tar;
+	bool change_rate_domain = false;
+
+	for (i = 0; i < ARRAY_SIZE(madera_sr_vals); i++)
+		if (madera_sr_vals[i] == params_rate(params))
+			break;
+
+	if (i == ARRAY_SIZE(madera_sr_vals)) {
+		madera_aif_err(dai, "Unsupported sample rate %dHz\n",
+				params_rate(params));
+		return -EINVAL;
+	}
+	sr_val = i;
+
+	if (base) {
+		switch (dai_priv->clk) {
+		case MADERA_CLK_SYSCLK_1:
+			tar = 0 << MADERA_AIF1_RATE_SHIFT;
+			break;
+		case MADERA_CLK_SYSCLK_2:
+			tar = 1 << MADERA_AIF1_RATE_SHIFT;
+			break;
+		case MADERA_CLK_SYSCLK_3:
+			tar = 2 << MADERA_AIF1_RATE_SHIFT;
+			break;
+		case MADERA_CLK_ASYNCCLK_1:
+			tar = 8 << MADERA_AIF1_RATE_SHIFT;
+			break;
+		case MADERA_CLK_ASYNCCLK_2:
+			tar = 9 << MADERA_AIF1_RATE_SHIFT;
+			break;
+		default:
+			madera_aif_err(dai, "Illegal clock id %d\n",
+				       dai_priv->clk);
+			return -EINVAL;
+		}
+
+		ret = regmap_read(priv->madera->regmap,
+				  base + MADERA_AIF_RATE_CTRL, &cur);
+		if (ret != 0) {
+			madera_aif_err(dai, "Failed to check rate: %d\n", ret);
+			return ret;
+		}
+
+		if ((cur & MADERA_AIF1_RATE_MASK) !=
+		    (tar & MADERA_AIF1_RATE_MASK)) {
+			change_rate_domain = true;
+
+			mutex_lock(&priv->rate_lock);
+
+			if (!madera_can_change_grp_rate(priv,
+						base + MADERA_AIF_RATE_CTRL)) {
+				madera_aif_warn(dai,
+						"Cannot change rate while active\n");
+				ret = -EBUSY;
+				goto out;
+			}
+
+			/* Guard the rate change with SYSCLK cycles */
+			madera_spin_sysclk(priv);
+		}
+	}
+
+	switch (dai_priv->clk) {
+	case MADERA_CLK_SYSCLK_1:
+		snd_soc_update_bits(codec, MADERA_SAMPLE_RATE_1,
+				    MADERA_SAMPLE_RATE_1_MASK, sr_val);
+		if (base)
+			snd_soc_update_bits(codec, base + MADERA_AIF_RATE_CTRL,
+					    MADERA_AIF1_RATE_MASK,
+					    0 << MADERA_AIF1_RATE_SHIFT);
+		break;
+	case MADERA_CLK_SYSCLK_2:
+		snd_soc_update_bits(codec, MADERA_SAMPLE_RATE_2,
+				    MADERA_SAMPLE_RATE_2_MASK, sr_val);
+		if (base)
+			snd_soc_update_bits(codec, base + MADERA_AIF_RATE_CTRL,
+					    MADERA_AIF1_RATE_MASK,
+					    1 << MADERA_AIF1_RATE_SHIFT);
+		break;
+	case MADERA_CLK_SYSCLK_3:
+		snd_soc_update_bits(codec, MADERA_SAMPLE_RATE_3,
+				    MADERA_SAMPLE_RATE_3_MASK, sr_val);
+		if (base)
+			snd_soc_update_bits(codec, base + MADERA_AIF_RATE_CTRL,
+					    MADERA_AIF1_RATE_MASK,
+					    2 << MADERA_AIF1_RATE_SHIFT);
+		break;
+	case MADERA_CLK_ASYNCCLK_1:
+		snd_soc_update_bits(codec, MADERA_ASYNC_SAMPLE_RATE_1,
+				    MADERA_ASYNC_SAMPLE_RATE_1_MASK, sr_val);
+		if (base)
+			snd_soc_update_bits(codec, base + MADERA_AIF_RATE_CTRL,
+					    MADERA_AIF1_RATE_MASK,
+					    8 << MADERA_AIF1_RATE_SHIFT);
+		break;
+	case MADERA_CLK_ASYNCCLK_2:
+		snd_soc_update_bits(codec, MADERA_ASYNC_SAMPLE_RATE_2,
+				    MADERA_ASYNC_SAMPLE_RATE_2_MASK, sr_val);
+		if (base)
+			snd_soc_update_bits(codec, base + MADERA_AIF_RATE_CTRL,
+					    MADERA_AIF1_RATE_MASK,
+					    9 << MADERA_AIF1_RATE_SHIFT);
+		break;
+	default:
+		madera_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
+		ret = -EINVAL;
+	}
+
+out:
+	if (change_rate_domain) {
+		madera_spin_sysclk(priv);
+		mutex_unlock(&priv->rate_lock);
+	}
+
+	return ret;
+}
+
+static bool madera_aif_cfg_changed(struct snd_soc_codec *codec,
+				   int base, int bclk, int lrclk, int frame)
+{
+	int val;
+
+	val = snd_soc_read(codec, base + MADERA_AIF_BCLK_CTRL);
+	if (bclk != (val & MADERA_AIF1_BCLK_FREQ_MASK))
+		return true;
+
+	val = snd_soc_read(codec, base + MADERA_AIF_RX_BCLK_RATE);
+	if (lrclk != (val & MADERA_AIF1RX_BCPF_MASK))
+		return true;
+
+	val = snd_soc_read(codec, base + MADERA_AIF_FRAME_CTRL_1);
+	if (frame != (val & (MADERA_AIF1TX_WL_MASK |
+			     MADERA_AIF1TX_SLOT_LEN_MASK)))
+		return true;
+
+	return false;
+}
+
+static int madera_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 madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct madera *madera = priv->madera;
+	int base = dai->driver->base;
+	const int *rates;
+	int i, ret, val;
+	unsigned int channels = params_channels(params);
+	unsigned int chan_limit =
+			madera->pdata.codec.max_channels_clocked[dai->id - 1];
+	int tdm_width = priv->tdm_width[dai->id - 1];
+	int tdm_slots = priv->tdm_slots[dai->id - 1];
+	int bclk, lrclk, wl, frame, bclk_target, num_rates;
+	bool reconfig;
+	unsigned int aif_tx_state = 0, aif_rx_state = 0;
+
+	if (params_rate(params) % 4000) {
+		rates = &madera_44k1_bclk_rates[0];
+		num_rates = ARRAY_SIZE(madera_44k1_bclk_rates);
+	} else {
+		rates = &madera_48k_bclk_rates[0];
+		num_rates = ARRAY_SIZE(madera_48k_bclk_rates);
+	}
+
+	wl = snd_pcm_format_width(params_format(params));
+
+	if (tdm_slots) {
+		madera_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
+				tdm_slots, tdm_width);
+		bclk_target = tdm_slots * tdm_width * params_rate(params);
+		channels = tdm_slots;
+	} else {
+		bclk_target = snd_soc_params_to_bclk(params);
+		tdm_width = wl;
+	}
+
+	if (chan_limit && chan_limit < channels) {
+		madera_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
+		bclk_target /= channels;
+		bclk_target *= chan_limit;
+	}
+
+	/* Force multiple of 2 channels for I2S mode */
+	val = snd_soc_read(codec, base + MADERA_AIF_FORMAT);
+	val &= MADERA_AIF1_FMT_MASK;
+	if ((channels & 1) && (val == MADERA_FMT_I2S_MODE)) {
+		madera_aif_dbg(dai, "Forcing stereo mode\n");
+		bclk_target /= channels;
+		bclk_target *= channels + 1;
+	}
+
+	for (i = 0; i < num_rates; i++) {
+		if (rates[i] >= bclk_target &&
+		    rates[i] % params_rate(params) == 0) {
+			bclk = i;
+			break;
+		}
+	}
+
+	if (i == num_rates) {
+		madera_aif_err(dai, "Unsupported sample rate %dHz\n",
+				params_rate(params));
+		return -EINVAL;
+	}
+
+	lrclk = rates[bclk] / params_rate(params);
+
+	madera_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
+			rates[bclk], rates[bclk] / lrclk);
+
+	frame = wl << MADERA_AIF1TX_WL_SHIFT | tdm_width;
+
+	reconfig = madera_aif_cfg_changed(codec, base, bclk, lrclk, frame);
+
+	if (reconfig) {
+		/* Save AIF TX/RX state */
+		aif_tx_state = snd_soc_read(codec,
+					    base + MADERA_AIF_TX_ENABLES);
+		aif_rx_state = snd_soc_read(codec,
+					    base + MADERA_AIF_RX_ENABLES);
+		/* Disable AIF TX/RX before reconfiguring it */
+		regmap_update_bits(madera->regmap,
+				   base + MADERA_AIF_TX_ENABLES, 0xff, 0x0);
+		regmap_update_bits(madera->regmap,
+				   base + MADERA_AIF_RX_ENABLES, 0xff, 0x0);
+	}
+
+	ret = madera_hw_params_rate(substream, params, dai);
+	if (ret != 0)
+		goto restore_aif;
+
+	if (reconfig) {
+		regmap_update_bits(madera->regmap,
+				   base + MADERA_AIF_BCLK_CTRL,
+				   MADERA_AIF1_BCLK_FREQ_MASK, bclk);
+		regmap_update_bits(madera->regmap,
+				   base + MADERA_AIF_RX_BCLK_RATE,
+				   MADERA_AIF1RX_BCPF_MASK, lrclk);
+		regmap_update_bits(madera->regmap,
+				   base + MADERA_AIF_FRAME_CTRL_1,
+				   MADERA_AIF1TX_WL_MASK |
+				   MADERA_AIF1TX_SLOT_LEN_MASK, frame);
+		regmap_update_bits(madera->regmap,
+				   base + MADERA_AIF_FRAME_CTRL_2,
+				   MADERA_AIF1RX_WL_MASK |
+				   MADERA_AIF1RX_SLOT_LEN_MASK, frame);
+	}
+
+restore_aif:
+	if (reconfig) {
+		/* Restore AIF TX/RX state */
+		regmap_update_bits(madera->regmap,
+				   base + MADERA_AIF_TX_ENABLES,
+				   0xff, aif_tx_state);
+		regmap_update_bits(madera->regmap,
+				   base + MADERA_AIF_RX_ENABLES,
+				   0xff, aif_rx_state);
+	}
+
+	return ret;
+}
+
+static int madera_is_syncclk(int clk_id)
+{
+	switch (clk_id) {
+	case MADERA_CLK_SYSCLK_1:
+	case MADERA_CLK_SYSCLK_2:
+	case MADERA_CLK_SYSCLK_3:
+		return 1;
+	case MADERA_CLK_ASYNCCLK_1:
+	case MADERA_CLK_ASYNCCLK_2:
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int madera_dai_set_sysclk(struct snd_soc_dai *dai,
+				 int clk_id, unsigned int freq, int dir)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
+	struct snd_soc_dapm_route routes[2];
+	int is_sync;
+
+	is_sync = madera_is_syncclk(clk_id);
+	if (is_sync < 0) {
+		dev_err(codec->dev, "Illegal DAI clock id %d\n", clk_id);
+		return is_sync;
+	}
+
+	if (is_sync == madera_is_syncclk(dai_priv->clk))
+		return 0;
+
+	if (dai->active) {
+		dev_err(codec->dev, "Can't change clock on active DAI %d\n",
+			dai->id);
+		return -EBUSY;
+	}
+
+	dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id,
+		is_sync ? "SYSCLK" : "ASYNCCLK");
+
+	/*
+	 * A connection to SYSCLK is always required, we only add and remove
+	 * a connection to ASYNCCLK
+	 */
+	memset(&routes, 0, sizeof(routes));
+	routes[0].sink = dai->driver->capture.stream_name;
+	routes[1].sink = dai->driver->playback.stream_name;
+	routes[0].source = "ASYNCCLK";
+	routes[1].source = "ASYNCCLK";
+
+	if (is_sync)
+		snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
+	else
+		snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
+
+	dai_priv->clk = clk_id;
+
+	return snd_soc_dapm_sync(dapm);
+}
+
+static int madera_set_tristate(struct snd_soc_dai *dai, int tristate)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	int base = dai->driver->base;
+	unsigned int reg;
+	int ret;
+
+	if (tristate)
+		reg = MADERA_AIF1_TRI;
+	else
+		reg = 0;
+
+	ret = snd_soc_update_bits(codec, base + MADERA_AIF_RATE_CTRL,
+				  MADERA_AIF1_TRI, reg);
+	if (ret < 0)
+		return ret;
+	else
+		return 0;
+}
+
+static void madera_set_channels_to_mask(struct snd_soc_dai *dai,
+					unsigned int base,
+					int channels, unsigned int mask)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct madera *madera = priv->madera;
+	int slot, i;
+
+	for (i = 0; i < channels; ++i) {
+		slot = ffs(mask) - 1;
+		if (slot < 0)
+			return;
+
+		regmap_write(madera->regmap, base + i, slot);
+
+		mask &= ~(1 << slot);
+	}
+
+	if (mask)
+		madera_aif_warn(dai, "Too many channels in TDM mask\n");
+}
+
+static int madera_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+			       unsigned int rx_mask, int slots, int slot_width)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct madera_priv *priv = snd_soc_codec_get_drvdata(codec);
+	int base = dai->driver->base;
+	int rx_max_chan = dai->driver->playback.channels_max;
+	int tx_max_chan = dai->driver->capture.channels_max;
+
+	/* Only support TDM for the physical AIFs */
+	if (dai->id > MADERA_MAX_AIF)
+		return -ENOTSUPP;
+
+	if (slots == 0) {
+		tx_mask = (1 << tx_max_chan) - 1;
+		rx_mask = (1 << rx_max_chan) - 1;
+	}
+
+	madera_set_channels_to_mask(dai, base + MADERA_AIF_FRAME_CTRL_3,
+				    tx_max_chan, tx_mask);
+	madera_set_channels_to_mask(dai, base + MADERA_AIF_FRAME_CTRL_11,
+				    rx_max_chan, rx_mask);
+
+	priv->tdm_width[dai->id - 1] = slot_width;
+	priv->tdm_slots[dai->id - 1] = slots;
+
+	return 0;
+}
+
+const struct snd_soc_dai_ops madera_dai_ops = {
+	.startup = madera_startup,
+	.set_fmt = madera_set_fmt,
+	.set_tdm_slot = madera_set_tdm_slot,
+	.hw_params = madera_hw_params,
+	.set_sysclk = madera_dai_set_sysclk,
+	.set_tristate = madera_set_tristate,
+};
+EXPORT_SYMBOL_GPL(madera_dai_ops);
+
+const struct snd_soc_dai_ops madera_simple_dai_ops = {
+	.startup = madera_startup,
+	.hw_params = madera_hw_params_rate,
+	.set_sysclk = madera_dai_set_sysclk,
+};
+EXPORT_SYMBOL_GPL(madera_simple_dai_ops);
+
+int madera_init_dai(struct madera_priv *priv, int id)
+{
+	struct madera_dai_priv *dai_priv = &priv->dai[id];
+
+	dai_priv->clk = MADERA_CLK_SYSCLK_1;
+	dai_priv->constraint = madera_constraint;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_init_dai);
+
+static const struct {
+	unsigned int min;
+	unsigned int max;
+	u16 fratio;
+	int ratio;
+} fll_sync_fratios[] = {
+	{       0,    64000, 4, 16 },
+	{   64000,   128000, 3,  8 },
+	{  128000,   256000, 2,  4 },
+	{  256000,  1000000, 1,  2 },
+	{ 1000000, 13500000, 0,  1 },
+};
+
+static const unsigned int pseudo_fref_max[MADERA_FLL_MAX_FRATIO] = {
+	13500000,
+	 6144000,
+	 6144000,
+	 3072000,
+	 3072000,
+	 2822400,
+	 2822400,
+	 1536000,
+	 1536000,
+	 1536000,
+	 1536000,
+	 1536000,
+	 1536000,
+	 1536000,
+	 1536000,
+	  768000,
+};
+
+struct madera_fll_gains {
+	unsigned int min;
+	unsigned int max;
+	int gain;		/* main gain */
+	int alt_gain;		/* alternate integer gain */
+};
+
+static const struct madera_fll_gains madera_fll_sync_gains[] = {
+	{       0,   256000, 0, -1 },
+	{  256000,  1000000, 2, -1 },
+	{ 1000000, 13500000, 4, -1 },
+};
+
+static const struct madera_fll_gains madera_fll_main_gains[] = {
+	{       0,   100000, 0, 2 },
+	{  100000,   375000, 2, 2 },
+	{  375000,   768000, 3, 2 },
+	{  768001,  1500000, 3, 3 },
+	{ 1500000,  6000000, 4, 3 },
+	{ 6000000, 13500000, 5, 3 },
+};
+
+static int madera_find_sync_fratio(unsigned int fref, int *fratio)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(fll_sync_fratios); i++) {
+		if (fll_sync_fratios[i].min <= fref &&
+		    fref <= fll_sync_fratios[i].max) {
+			if (fratio)
+				*fratio = fll_sync_fratios[i].fratio;
+
+			return fll_sync_fratios[i].ratio;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int madera_find_main_fratio(unsigned int fref, unsigned int fout,
+				   int *fratio)
+{
+	int ratio = 1;
+
+	while ((fout / (ratio * fref)) > MADERA_FLL_MAX_N)
+		ratio++;
+
+	if (fratio)
+		*fratio = ratio - 1;
+
+	return ratio;
+}
+
+static int madera_find_fratio(struct madera_fll *fll, unsigned int fref,
+			      bool sync, int *fratio)
+{
+	switch (fll->madera->type) {
+	case CS47L35:
+		switch (fll->madera->rev) {
+		case 0:
+			/* rev A0 uses sync calculation for both loops */
+			return madera_find_sync_fratio(fref, fratio);
+		default:
+			if (sync)
+				return madera_find_sync_fratio(fref, fratio);
+			else
+				return madera_find_main_fratio(fref,
+							       fll->fout,
+							       fratio);
+		}
+		break;
+	case CS47L85:
+	case WM1840:
+		/* these use the same calculation for main and sync loops */
+		return madera_find_sync_fratio(fref, fratio);
+	default:
+		if (sync)
+			return madera_find_sync_fratio(fref, fratio);
+		else
+			return madera_find_main_fratio(fref, fll->fout, fratio);
+	}
+}
+
+static int madera_calc_fratio(struct madera_fll *fll,
+			      struct madera_fll_cfg *cfg,
+			      unsigned int fref, bool sync)
+{
+	int init_ratio, ratio;
+	int refdiv, div;
+
+	/* fref must be <=13.5MHz, find initial refdiv */
+	div = 1;
+	cfg->refdiv = 0;
+	while (fref > MADERA_FLL_MAX_FREF) {
+		div *= 2;
+		fref /= 2;
+		cfg->refdiv++;
+
+		if (div > MADERA_FLL_MAX_REFDIV)
+			return -EINVAL;
+	}
+
+	/* Find an appropriate FLL_FRATIO */
+	init_ratio = madera_find_fratio(fll, fref, sync, &cfg->fratio);
+	if (init_ratio < 0) {
+		madera_fll_err(fll, "Unable to find FRATIO for fref=%uHz\n",
+				fref);
+		return init_ratio;
+	}
+
+	if (!sync)
+		cfg->fratio = init_ratio - 1;
+
+	switch (fll->madera->type) {
+	case CS47L35:
+		switch (fll->madera->rev) {
+		case 0:
+			if (sync)
+				return init_ratio;
+			break;
+		default:
+			return init_ratio;
+		}
+		break;
+	case CS47L85:
+	case WM1840:
+		if (sync)
+			return init_ratio;
+		break;
+	default:
+		return init_ratio;
+	}
+
+	/*
+	 * For CS47L35 rev A0, CS47L85 and WM1840 adjust FRATIO/refdiv to avoid
+	 * integer mode if possible
+	 */
+	refdiv = cfg->refdiv;
+
+	while (div <= MADERA_FLL_MAX_REFDIV) {
+		/*
+		 * start from init_ratio because this may already give a
+		 * fractional N.K
+		 */
+		for (ratio = init_ratio; ratio > 0; ratio--) {
+			if (fll->fout % (ratio * fref)) {
+				cfg->refdiv = refdiv;
+				cfg->fratio = ratio - 1;
+				return ratio;
+			}
+		}
+
+		for (ratio = init_ratio + 1; ratio <= MADERA_FLL_MAX_FRATIO;
+		     ratio++) {
+			if ((MADERA_FLL_VCO_CORNER / 2) /
+			    (MADERA_FLL_VCO_MULT * ratio) < fref)
+				break;
+
+			if (fref > pseudo_fref_max[ratio - 1])
+				break;
+
+			if (fll->fout % (ratio * fref)) {
+				cfg->refdiv = refdiv;
+				cfg->fratio = ratio - 1;
+				return ratio;
+			}
+		}
+
+		div *= 2;
+		fref /= 2;
+		refdiv++;
+		init_ratio = madera_find_fratio(fll, fref, sync, NULL);
+	}
+
+	madera_fll_warn(fll, "Falling back to integer mode operation\n");
+
+	return cfg->fratio + 1;
+}
+
+static int madera_find_fll_gain(struct madera_fll *fll,
+				struct madera_fll_cfg *cfg,
+				unsigned int fref,
+				const struct madera_fll_gains *gains,
+				int n_gains)
+{
+	int i;
+
+	for (i = 0; i < n_gains; i++) {
+		if (gains[i].min <= fref && fref <= gains[i].max) {
+			cfg->gain = gains[i].gain;
+			cfg->alt_gain = gains[i].alt_gain;
+			return 0;
+		}
+	}
+
+	madera_fll_err(fll, "Unable to find gain for fref=%uHz\n", fref);
+
+	return -EINVAL;
+}
+
+static int madera_calc_fll(struct madera_fll *fll,
+			   struct madera_fll_cfg *cfg,
+			   unsigned int fref, bool sync)
+{
+	unsigned int gcd_fll;
+	const struct madera_fll_gains *gains;
+	int n_gains;
+	int ratio, ret;
+
+	madera_fll_dbg(fll, "fref=%u Fout=%u fvco=%u\n",
+			fref, fll->fout, fll->fout * MADERA_FLL_VCO_MULT);
+
+	/* Find an appropriate FLL_FRATIO and refdiv */
+	ratio = madera_calc_fratio(fll, cfg, fref, sync);
+	if (ratio < 0)
+		return ratio;
+
+	/* Apply the division for our remaining calculations */
+	fref = fref / (1 << cfg->refdiv);
+
+	cfg->n = fll->fout / (ratio * fref);
+
+	if (fll->fout % (ratio * fref)) {
+		gcd_fll = gcd(fll->fout, ratio * fref);
+		madera_fll_dbg(fll, "GCD=%u\n", gcd_fll);
+
+		cfg->theta = (fll->fout - (cfg->n * ratio * fref))
+			/ gcd_fll;
+		cfg->lambda = (ratio * fref) / gcd_fll;
+	} else {
+		cfg->theta = 0;
+		cfg->lambda = 0;
+	}
+
+	/*
+	 * Round down to 16bit range with cost of accuracy lost.
+	 * Denominator must be bigger than numerator so we only
+	 * take care of it.
+	 */
+	while (cfg->lambda >= (1 << 16)) {
+		cfg->theta >>= 1;
+		cfg->lambda >>= 1;
+	}
+
+	switch (fll->madera->type) {
+	case CS47L35:
+		switch (fll->madera->rev) {
+		case 0:
+			/* Rev A0 uses the sync gains for both loops */
+			gains = madera_fll_sync_gains;
+			n_gains = ARRAY_SIZE(madera_fll_sync_gains);
+			break;
+		default:
+			if (sync) {
+				gains = madera_fll_sync_gains;
+				n_gains = ARRAY_SIZE(madera_fll_sync_gains);
+			} else {
+				gains = madera_fll_main_gains;
+				n_gains = ARRAY_SIZE(madera_fll_main_gains);
+			}
+			break;
+		}
+		break;
+	case CS47L85:
+	case WM1840:
+		/* These use the sync gains for both loops */
+		gains = madera_fll_sync_gains;
+		n_gains = ARRAY_SIZE(madera_fll_sync_gains);
+		break;
+	default:
+		if (sync) {
+			gains = madera_fll_sync_gains;
+			n_gains = ARRAY_SIZE(madera_fll_sync_gains);
+		} else {
+			gains = madera_fll_main_gains;
+			n_gains = ARRAY_SIZE(madera_fll_main_gains);
+		}
+		break;
+	}
+
+	ret = madera_find_fll_gain(fll, cfg, fref, gains, n_gains);
+	if (ret)
+		return ret;
+
+	madera_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
+			cfg->n, cfg->theta, cfg->lambda);
+	madera_fll_dbg(fll, "FRATIO=0x%x(%d) REFCLK_DIV=0x%x(%d)\n",
+			cfg->fratio, ratio, cfg->refdiv, 1 << cfg->refdiv);
+	madera_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
+
+	return 0;
+
+}
+
+static bool madera_write_fll(struct madera *madera, unsigned int base,
+			     struct madera_fll_cfg *cfg, int source,
+			     bool sync, int gain)
+{
+	bool change, fll_change;
+
+	fll_change = false;
+	regmap_update_bits_check(madera->regmap,
+				 base + MADERA_FLL_CONTROL_3_OFFS,
+				 MADERA_FLL1_THETA_MASK,
+				 cfg->theta, &change);
+	fll_change |= change;
+	regmap_update_bits_check(madera->regmap,
+				 base + MADERA_FLL_CONTROL_4_OFFS,
+				 MADERA_FLL1_LAMBDA_MASK,
+				 cfg->lambda, &change);
+	fll_change |= change;
+	regmap_update_bits_check(madera->regmap,
+				 base + MADERA_FLL_CONTROL_5_OFFS,
+				 MADERA_FLL1_FRATIO_MASK,
+				 cfg->fratio << MADERA_FLL1_FRATIO_SHIFT,
+				 &change);
+	fll_change |= change;
+	regmap_update_bits_check(madera->regmap,
+				 base + MADERA_FLL_CONTROL_6_OFFS,
+				 MADERA_FLL1_REFCLK_DIV_MASK |
+				 MADERA_FLL1_REFCLK_SRC_MASK,
+				 cfg->refdiv << MADERA_FLL1_REFCLK_DIV_SHIFT |
+				 source << MADERA_FLL1_REFCLK_SRC_SHIFT,
+				 &change);
+	fll_change |= change;
+
+	if (sync) {
+		regmap_update_bits_check(madera->regmap,
+					 base + MADERA_FLL_SYNCHRONISER_7_OFFS,
+					 MADERA_FLL1_GAIN_MASK,
+					 gain << MADERA_FLL1_GAIN_SHIFT,
+					 &change);
+		fll_change |= change;
+	} else {
+		regmap_update_bits_check(madera->regmap,
+					 base + MADERA_FLL_CONTROL_7_OFFS,
+					 MADERA_FLL1_GAIN_MASK,
+					 gain << MADERA_FLL1_GAIN_SHIFT,
+					 &change);
+		fll_change |= change;
+	}
+
+	regmap_update_bits_check(madera->regmap,
+				 base + MADERA_FLL_CONTROL_2_OFFS,
+				 MADERA_FLL1_CTRL_UPD | MADERA_FLL1_N_MASK,
+				 MADERA_FLL1_CTRL_UPD | cfg->n, &change);
+	fll_change |= change;
+
+	return fll_change;
+}
+
+static int madera_is_enabled_fll(struct madera_fll *fll, int base)
+{
+	struct madera *madera = fll->madera;
+	unsigned int reg;
+	int ret;
+
+	ret = regmap_read(madera->regmap,
+			  base + MADERA_FLL_CONTROL_1_OFFS, &reg);
+	if (ret != 0) {
+		madera_fll_err(fll, "Failed to read current state: %d\n", ret);
+		return ret;
+	}
+
+	return reg & MADERA_FLL1_ENA;
+}
+
+static int madera_wait_for_fll(struct madera_fll *fll, bool requested)
+{
+	struct madera *madera = fll->madera;
+	unsigned int val = 0;
+	bool status;
+	int i;
+
+	madera_fll_dbg(fll, "Waiting for FLL...\n");
+
+	for (i = 0; i < 30; i++) {
+		regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_2, &val);
+		status = val & (MADERA_FLL1_LOCK_STS1 << (fll->id - 1));
+		if (status == requested)
+			return 0;
+
+		switch (i) {
+		case 0 ... 5:
+			usleep_range(75, 125);
+			break;
+		case 11 ... 20:
+			usleep_range(750, 1250);
+			break;
+		default:
+			msleep(20);
+			break;
+		}
+	}
+
+	madera_fll_warn(fll, "Timed out waiting for lock\n");
+
+	return -ETIMEDOUT;
+}
+
+static bool madera_set_fll_phase_integrator(struct madera_fll *fll,
+					    struct madera_fll_cfg *ref_cfg,
+					    bool sync)
+{
+	unsigned int val;
+	bool reg_change;
+
+	if (!sync && (ref_cfg->theta == 0))
+		val = (1 << MADERA_FLL1_PHASE_ENA_SHIFT) |
+			(2 << MADERA_FLL1_PHASE_GAIN_SHIFT);
+	else
+		val = 2 << MADERA_FLL1_PHASE_GAIN_SHIFT;
+
+	regmap_update_bits_check(fll->madera->regmap,
+				 fll->base + MADERA_FLL_EFS_2_OFFS,
+				 MADERA_FLL1_PHASE_ENA_MASK |
+				 MADERA_FLL1_PHASE_GAIN_MASK,
+				 val,
+				 &reg_change);
+
+	return reg_change;
+}
+
+static void madera_disable_fll(struct madera_fll *fll)
+{
+	struct madera *madera = fll->madera;
+	unsigned int sync_reg_base;
+	bool change;
+
+	switch (madera->type) {
+	case CS47L35:
+		sync_reg_base = fll->base + CS47L35_FLL_SYNCHRONISER_OFFS;
+		break;
+	default:
+		sync_reg_base = fll->base + MADERA_FLL_SYNCHRONISER_OFFS;
+		break;
+	}
+
+	madera_fll_dbg(fll, "Disabling FLL\n");
+
+	regmap_update_bits(madera->regmap,
+			   fll->base + MADERA_FLL_CONTROL_1_OFFS,
+			   MADERA_FLL1_FREERUN, MADERA_FLL1_FREERUN);
+	regmap_update_bits_check(madera->regmap,
+				 fll->base + MADERA_FLL_CONTROL_1_OFFS,
+				 MADERA_FLL1_ENA, 0, &change);
+	regmap_update_bits(madera->regmap,
+			   sync_reg_base + MADERA_FLL_SYNCHRONISER_1_OFFS,
+			   MADERA_FLL1_SYNC_ENA, 0);
+	regmap_update_bits(madera->regmap,
+			   fll->base + MADERA_FLL_CONTROL_1_OFFS,
+			   MADERA_FLL1_FREERUN, 0);
+
+	madera_wait_for_fll(fll, false);
+
+	if (change)
+		pm_runtime_put_autosuspend(madera->dev);
+}
+
+static int madera_enable_fll(struct madera_fll *fll)
+{
+	struct madera *madera = fll->madera;
+	bool have_sync = false;
+	int already_enabled = madera_is_enabled_fll(fll, fll->base);
+	int sync_enabled;
+	struct madera_fll_cfg cfg;
+	unsigned int sync_reg_base;
+	int gain, ret;
+	bool fll_change = false;
+
+	if (already_enabled < 0)
+		return already_enabled;	/* error getting current state */
+
+	if ((fll->ref_src < 0) || (fll->ref_freq == 0)) {
+		madera_fll_err(fll, "No REFCLK\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	madera_fll_dbg(fll, "Enabling FLL, initially %s\n",
+			already_enabled ? "enabled" : "disabled");
+
+	if ((fll->fout < MADERA_FLL_MIN_FOUT) ||
+	    (fll->fout > MADERA_FLL_MAX_FOUT)) {
+		madera_fll_err(fll, "invalid fout %uHz\n", fll->fout);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	switch (madera->type) {
+	case CS47L35:
+		sync_reg_base = fll->base + CS47L35_FLL_SYNCHRONISER_OFFS;
+		break;
+	default:
+		sync_reg_base = fll->base + MADERA_FLL_SYNCHRONISER_OFFS;
+		break;
+	}
+
+	sync_enabled = madera_is_enabled_fll(fll, sync_reg_base);
+	if (sync_enabled < 0)
+		return sync_enabled;
+
+	if (already_enabled) {
+		/* Facilitate smooth refclk across the transition */
+		regmap_update_bits(fll->madera->regmap,
+				   fll->base + MADERA_FLL_CONTROL_1_OFFS,
+				   MADERA_FLL1_FREERUN,
+				   MADERA_FLL1_FREERUN);
+		udelay(32);
+		regmap_update_bits(fll->madera->regmap,
+				   fll->base + MADERA_FLL_CONTROL_7_OFFS,
+				   MADERA_FLL1_GAIN_MASK, 0);
+	}
+
+	/* Apply SYNCCLK setting */
+	if (fll->sync_src >= 0) {
+		ret = madera_calc_fll(fll, &cfg, fll->sync_freq, true);
+		if (ret < 0)
+			goto err;
+
+		fll_change |= madera_write_fll(madera, sync_reg_base,
+						&cfg, fll->sync_src,
+						true, cfg.gain);
+		have_sync = true;
+	}
+
+	if (already_enabled && !!sync_enabled != have_sync)
+		madera_fll_warn(fll, "Synchroniser changed on active FLL\n");
+
+	/* Apply REFCLK setting */
+	ret = madera_calc_fll(fll, &cfg, fll->ref_freq, false);
+	if (ret < 0)
+		goto err;
+
+	/* Ref path hardcodes lambda to 65536 when sync is on */
+	if (have_sync && cfg.lambda)
+		cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
+
+	switch (fll->madera->type) {
+	case CS47L35:
+		switch (fll->madera->rev) {
+		case 0:
+			break;
+		default:
+			fll_change |=
+				madera_set_fll_phase_integrator(fll, &cfg,
+								have_sync);
+			break;
+		}
+		gain = cfg.gain;
+		break;
+	case CS47L85:
+	case WM1840:
+		gain = cfg.gain;
+		break;
+	default:
+		fll_change |= madera_set_fll_phase_integrator(fll, &cfg,
+							      have_sync);
+		if (!have_sync && (cfg.theta == 0))
+			gain = cfg.alt_gain;
+		else
+			gain = cfg.gain;
+		break;
+	}
+
+	fll_change |= madera_write_fll(madera, fll->base,
+				      &cfg, fll->ref_src,
+				      false, gain);
+
+	/*
+	 * Increase the bandwidth if we're not using a low frequency
+	 * sync source.
+	 */
+	if (have_sync && fll->sync_freq > 100000)
+		regmap_update_bits(madera->regmap,
+				sync_reg_base + MADERA_FLL_SYNCHRONISER_7_OFFS,
+				MADERA_FLL1_SYNC_DFSAT_MASK, 0);
+	else
+		regmap_update_bits(madera->regmap,
+				sync_reg_base + MADERA_FLL_SYNCHRONISER_7_OFFS,
+				MADERA_FLL1_SYNC_DFSAT_MASK,
+				MADERA_FLL1_SYNC_DFSAT);
+
+	if (!already_enabled)
+		pm_runtime_get_sync(madera->dev);
+
+	if (have_sync)
+		regmap_update_bits(madera->regmap,
+				sync_reg_base + MADERA_FLL_SYNCHRONISER_1_OFFS,
+				MADERA_FLL1_SYNC_ENA,
+				MADERA_FLL1_SYNC_ENA);
+	regmap_update_bits(madera->regmap,
+			   fll->base + MADERA_FLL_CONTROL_1_OFFS,
+			   MADERA_FLL1_ENA, MADERA_FLL1_ENA);
+
+	if (already_enabled)
+		regmap_update_bits(madera->regmap,
+				   fll->base + MADERA_FLL_CONTROL_1_OFFS,
+				   MADERA_FLL1_FREERUN, 0);
+
+	if (fll_change || !already_enabled)
+		madera_wait_for_fll(fll, true);
+
+	return 0;
+
+err:
+	 /* In case of error don't leave the FLL running with an old config */
+	madera_disable_fll(fll);
+
+	return ret;
+}
+
+static int madera_apply_fll(struct madera_fll *fll)
+{
+	if (fll->fout) {
+		return madera_enable_fll(fll);
+	} else {
+		madera_disable_fll(fll);
+		return 0;
+	}
+}
+
+int madera_set_fll_syncclk(struct madera_fll *fll, int source,
+			   unsigned int fref, unsigned int fout)
+{
+	/*
+	 * fout is ignored, since the synchronizer is an optional extra
+	 * constraint on the Fout generated from REFCLK, so the Fout is
+	 * set when configuring REFCLK
+	 */
+
+	if (fll->sync_src == source && fll->sync_freq == fref)
+		return 0;
+
+	fll->sync_src = source;
+	fll->sync_freq = fref;
+
+	return madera_apply_fll(fll);
+}
+EXPORT_SYMBOL_GPL(madera_set_fll_syncclk);
+
+int madera_set_fll_refclk(struct madera_fll *fll, int source,
+			  unsigned int fref, unsigned int fout)
+{
+	int ret;
+
+	if (fll->ref_src == source &&
+	    fll->ref_freq == fref && fll->fout == fout)
+		return 0;
+
+	/*
+	 * Changes of fout on an enabled FLL aren't allowed except when
+	 * setting fout==0 to disable the FLL
+	 */
+	if (fout && (fout != fll->fout)) {
+		ret = madera_is_enabled_fll(fll, fll->base);
+		if (ret < 0)
+			return ret;
+
+		if (ret) {
+			madera_fll_err(fll, "Can't change Fout on active FLL\n");
+			return -EBUSY;
+		}
+	}
+
+	fll->ref_src = source;
+	fll->ref_freq = fref;
+	fll->fout = fout;
+
+	return madera_apply_fll(fll);
+}
+EXPORT_SYMBOL_GPL(madera_set_fll_refclk);
+
+int madera_init_fll(struct madera *madera, int id, int base,
+		    struct madera_fll *fll)
+{
+	fll->id = id;
+	fll->base = base;
+	fll->madera = madera;
+	fll->ref_src = MADERA_FLL_SRC_NONE;
+	fll->sync_src = MADERA_FLL_SRC_NONE;
+
+	regmap_update_bits(madera->regmap,
+			   fll->base + MADERA_FLL_CONTROL_1_OFFS,
+			   MADERA_FLL1_FREERUN, 0);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_init_fll);
+
+static const struct reg_sequence madera_fll_ao_32K_49M_patch[] = {
+	{ MADERA_FLLAO_CONTROL_2,  0x02EE },
+	{ MADERA_FLLAO_CONTROL_3,  0x0000 },
+	{ MADERA_FLLAO_CONTROL_4,  0x0001 },
+	{ MADERA_FLLAO_CONTROL_5,  0x0002 },
+	{ MADERA_FLLAO_CONTROL_6,  0x8001 },
+	{ MADERA_FLLAO_CONTROL_7,  0x0004 },
+	{ MADERA_FLLAO_CONTROL_8,  0x0077 },
+	{ MADERA_FLLAO_CONTROL_10, 0x06D8 },
+	{ MADERA_FLLAO_CONTROL_11, 0x0085 },
+	{ MADERA_FLLAO_CONTROL_2,  0x82EE },
+};
+
+static const struct reg_sequence madera_fll_ao_32K_45M_patch[] = {
+	{ MADERA_FLLAO_CONTROL_2,  0x02B1 },
+	{ MADERA_FLLAO_CONTROL_3,  0x0001 },
+	{ MADERA_FLLAO_CONTROL_4,  0x0010 },
+	{ MADERA_FLLAO_CONTROL_5,  0x0002 },
+	{ MADERA_FLLAO_CONTROL_6,  0x8001 },
+	{ MADERA_FLLAO_CONTROL_7,  0x0004 },
+	{ MADERA_FLLAO_CONTROL_8,  0x0077 },
+	{ MADERA_FLLAO_CONTROL_10, 0x06D8 },
+	{ MADERA_FLLAO_CONTROL_11, 0x0005 },
+	{ MADERA_FLLAO_CONTROL_2,  0x82B1 },
+};
+
+struct madera_fllao_patch {
+	unsigned int fin;
+	unsigned int fout;
+	const struct reg_sequence *patch;
+	unsigned int patch_size;
+};
+
+static const struct madera_fllao_patch madera_fllao_settings[] = {
+	{
+		.fin = 32768,
+		.fout = 49152000,
+		.patch = madera_fll_ao_32K_49M_patch,
+		.patch_size = ARRAY_SIZE(madera_fll_ao_32K_49M_patch),
+
+	},
+	{
+		.fin = 32768,
+		.fout = 45158400,
+		.patch = madera_fll_ao_32K_45M_patch,
+		.patch_size = ARRAY_SIZE(madera_fll_ao_32K_45M_patch),
+	},
+};
+
+static int madera_enable_fll_ao(struct madera_fll *fll,
+				const struct reg_sequence *patch,
+				unsigned int patch_size)
+{
+	struct madera *madera = fll->madera;
+	int already_enabled = madera_is_enabled_fll(fll, fll->base);
+	unsigned int val;
+	int i;
+
+	if (already_enabled < 0)
+		return already_enabled;
+
+	if (!already_enabled)
+		pm_runtime_get_sync(madera->dev);
+
+	madera_fll_dbg(fll, "Enabling FLL_AO, initially %s\n",
+			already_enabled ? "enabled" : "disabled");
+
+	/* FLL_AO_HOLD must be set before configuring any registers */
+	regmap_update_bits(fll->madera->regmap,
+			   fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
+			   MADERA_FLL_AO_HOLD, MADERA_FLL_AO_HOLD);
+
+	for (i = 0; i < patch_size; i++) {
+		val = patch[i].def;
+
+		/* modify the patch to apply fll->ref_src as input clock */
+		if (patch[i].reg == MADERA_FLLAO_CONTROL_6) {
+			val &= ~MADERA_FLL_AO_REFCLK_SRC_MASK;
+			val |= (fll->ref_src << MADERA_FLL_AO_REFCLK_SRC_SHIFT)
+				& MADERA_FLL_AO_REFCLK_SRC_MASK;
+		}
+
+		regmap_write(madera->regmap, patch[i].reg, val);
+	}
+
+	regmap_update_bits(madera->regmap,
+			   fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
+			   MADERA_FLL_AO_ENA, MADERA_FLL_AO_ENA);
+
+	/* Release the hold so that fll_ao locks to external frequency */
+	regmap_update_bits(madera->regmap,
+			   fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
+			   MADERA_FLL_AO_HOLD, 0);
+
+	if (!already_enabled)
+		madera_wait_for_fll(fll, true);
+
+	return 0;
+}
+
+static int madera_disable_fll_ao(struct madera_fll *fll)
+{
+	struct madera *madera = fll->madera;
+	bool change;
+
+	madera_fll_dbg(fll, "Disabling FLL_AO\n");
+
+	regmap_update_bits(madera->regmap,
+			   fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
+			   MADERA_FLL_AO_HOLD, MADERA_FLL_AO_HOLD);
+	regmap_update_bits_check(madera->regmap,
+				 fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
+				 MADERA_FLL_AO_ENA, 0, &change);
+
+	madera_wait_for_fll(fll, false);
+
+	/*
+	 * ctrl_up gates the writes to all fll_ao register, setting it to 0
+	 * here ensures that after a runtime suspend/resume cycle when one
+	 * enables the fllao then ctrl_up is the last bit that is configured
+	 * by the fllao enable code rather than the cache sync operation which
+	 * would have updated it much earlier before writing out all fllao
+	 * registers
+	 */
+	regmap_update_bits(madera->regmap,
+			   fll->base + MADERA_FLLAO_CONTROL_2_OFFS,
+			   MADERA_FLL_AO_CTRL_UPD_MASK, 0);
+
+	if (change)
+		pm_runtime_put_autosuspend(madera->dev);
+
+	return 0;
+}
+
+int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
+			     unsigned int fin, unsigned int fout)
+{
+	int ret = 0;
+	const struct reg_sequence *patch = NULL;
+	int patch_size = 0;
+	unsigned int i;
+
+	if (fll->ref_src == source &&
+	    fll->ref_freq == fin && fll->fout == fout)
+		return 0;
+
+	madera_fll_dbg(fll, "Change FLL_AO refclk to fin=%u fout=%u source=%d\n",
+			fin, fout, source);
+
+	if (fout && (fll->ref_freq != fin || fll->fout != fout)) {
+		for (i = 0; i < ARRAY_SIZE(madera_fllao_settings); i++) {
+			if (madera_fllao_settings[i].fin == fin &&
+			    madera_fllao_settings[i].fout == fout)
+				break;
+		}
+
+		if (i == ARRAY_SIZE(madera_fllao_settings)) {
+			madera_fll_err(fll,
+					"No matching configuration for FLL_AO\n");
+			return -EINVAL;
+		}
+
+		patch = madera_fllao_settings[i].patch;
+		patch_size = madera_fllao_settings[i].patch_size;
+	}
+
+	fll->ref_src = source;
+	fll->ref_freq = fin;
+	fll->fout = fout;
+
+	if (fout)
+		ret = madera_enable_fll_ao(fll, patch, patch_size);
+	else
+		madera_disable_fll_ao(fll);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(madera_set_fll_ao_refclk);
+
+/**
+ * madera_set_output_mode - Set the mode of the specified output
+ *
+ * @codec: Device to configure
+ * @output: Output number
+ * @diff: True to set the output to differential mode
+ *
+ * Some systems use external analogue switches to connect more
+ * analogue devices to the CODEC than are supported by the device.  In
+ * some systems this requires changing the switched output from single
+ * ended to differential mode dynamically at runtime, an operation
+ * supported using this function.
+ *
+ * Most systems have a single static configuration and should use
+ * platform data instead.
+ */
+int madera_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
+{
+	unsigned int reg, val;
+	int ret;
+
+	if (output < 1 || output > MADERA_MAX_OUTPUT)
+		return -EINVAL;
+
+	reg = MADERA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
+
+	if (diff)
+		val = MADERA_OUT1_MONO;
+	else
+		val = 0;
+
+	ret = snd_soc_update_bits(codec, reg, MADERA_OUT1_MONO, val);
+	if (ret < 0)
+		return ret;
+	else
+		return 0;
+}
+EXPORT_SYMBOL_GPL(madera_set_output_mode);
+
+static bool madera_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
+{
+	s16 a = be16_to_cpu(_a);
+	s16 b = be16_to_cpu(_b);
+
+	if (!mode) {
+		return abs(a) >= 4096;
+	} else {
+		if (abs(b) >= 4096)
+			return true;
+
+		return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
+	}
+}
+
+int madera_eq_coeff_put(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct madera *madera = dev_get_drvdata(codec->dev->parent);
+	struct soc_bytes *params = (void *)kcontrol->private_value;
+	unsigned int val;
+	__be16 *data;
+	int len;
+	int ret;
+
+	len = params->num_regs * regmap_get_val_bytes(madera->regmap);
+
+	data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
+	if (!data)
+		return -ENOMEM;
+
+	data[0] &= cpu_to_be16(MADERA_EQ1_B1_MODE);
+
+	if (madera_eq_filter_unstable(!!data[0], data[1], data[2]) ||
+	    madera_eq_filter_unstable(true, data[4], data[5]) ||
+	    madera_eq_filter_unstable(true, data[8], data[9]) ||
+	    madera_eq_filter_unstable(true, data[12], data[13]) ||
+	    madera_eq_filter_unstable(false, data[16], data[17])) {
+		dev_err(madera->dev, "Rejecting unstable EQ coefficients\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = regmap_read(madera->regmap, params->base, &val);
+	if (ret != 0)
+		goto out;
+
+	val &= ~MADERA_EQ1_B1_MODE;
+	data[0] |= cpu_to_be16(val);
+
+	ret = regmap_raw_write(madera->regmap, params->base, data, len);
+
+out:
+	kfree(data);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(madera_eq_coeff_put);
+
+int madera_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct madera *madera = dev_get_drvdata(codec->dev->parent);
+	__be16 *data = (__be16 *)ucontrol->value.bytes.data;
+	s16 val = be16_to_cpu(*data);
+
+	if (abs(val) >= 4096) {
+		dev_err(madera->dev, "Rejecting unstable LHPF coefficients\n");
+		return -EINVAL;
+	}
+
+	return snd_soc_bytes_put(kcontrol, ucontrol);
+}
+EXPORT_SYMBOL_GPL(madera_lhpf_coeff_put);
+
+MODULE_DESCRIPTION("ASoC Cirrus Logic Madera codec support");
+MODULE_AUTHOR("Charles Keepax <ckeepax-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>");
+MODULE_AUTHOR("Richard Fitzgerald <rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/madera.h b/sound/soc/codecs/madera.h
new file mode 100644
index 0000000..58f203b
--- /dev/null
+++ b/sound/soc/codecs/madera.h
@@ -0,0 +1,470 @@
+/*
+ * madera.h - Cirrus Logic Madera class codecs common support
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ASOC_MADERA_H
+#define ASOC_MADERA_H
+
+#include <linux/completion.h>
+
+#include <sound/soc.h>
+#include <sound/madera-pdata.h>
+
+#include "wm_adsp.h"
+
+#define MADERA_FLL1_REFCLK		1
+#define MADERA_FLL2_REFCLK		2
+#define MADERA_FLL3_REFCLK		3
+#define MADERA_FLLAO_REFCLK		4
+#define MADERA_FLL1_SYNCCLK		5
+#define MADERA_FLL2_SYNCCLK		6
+#define MADERA_FLL3_SYNCCLK		7
+#define MADERA_FLLAO_SYNCCLK		8
+
+#define MADERA_FLL_SRC_NONE		-1
+#define MADERA_FLL_SRC_MCLK1		0
+#define MADERA_FLL_SRC_MCLK2		1
+#define MADERA_FLL_SRC_SLIMCLK		3
+#define MADERA_FLL_SRC_FLL1		4
+#define MADERA_FLL_SRC_FLL2		5
+#define MADERA_FLL_SRC_AIF1BCLK		8
+#define MADERA_FLL_SRC_AIF2BCLK		9
+#define MADERA_FLL_SRC_AIF3BCLK		10
+#define MADERA_FLL_SRC_AIF4BCLK		11
+#define MADERA_FLL_SRC_AIF1LRCLK	12
+#define MADERA_FLL_SRC_AIF2LRCLK	13
+#define MADERA_FLL_SRC_AIF3LRCLK	14
+#define MADERA_FLL_SRC_AIF4LRCLK	15
+
+#define MADERA_CLK_SYSCLK_1		1
+#define MADERA_CLK_ASYNCCLK_1		2
+#define MADERA_CLK_OPCLK		3
+#define MADERA_CLK_ASYNC_OPCLK		4
+#define MADERA_CLK_SYSCLK_2		5
+#define MADERA_CLK_SYSCLK_3		6
+#define MADERA_CLK_ASYNCCLK_2		7
+#define MADERA_CLK_DSPCLK		8
+
+#define MADERA_CLK_SRC_MCLK1		0x0
+#define MADERA_CLK_SRC_MCLK2		0x1
+#define MADERA_CLK_SRC_FLL1		0x4
+#define MADERA_CLK_SRC_FLL2		0x5
+#define MADERA_CLK_SRC_FLL3		0x6
+#define MADERA_CLK_SRC_FLLAO_HI		0x7
+#define MADERA_CLK_SRC_FLL1_DIV6	0x7
+#define MADERA_CLK_SRC_AIF1BCLK		0x8
+#define MADERA_CLK_SRC_AIF2BCLK		0x9
+#define MADERA_CLK_SRC_AIF3BCLK		0xA
+#define MADERA_CLK_SRC_AIF4BCLK		0xB
+#define MADERA_CLK_SRC_FLLAO		0xF
+
+#define MADERA_MIXER_VOL_MASK		0x00FE
+#define MADERA_MIXER_VOL_SHIFT		1
+#define MADERA_MIXER_VOL_WIDTH		7
+
+#define MADERA_DOM_GRP_FX		0
+#define MADERA_DOM_GRP_ASRC1_RATE_1	1
+#define MADERA_DOM_GRP_ASRC1_RATE_2	2
+#define MADERA_DOM_GRP_ASRC2_RATE_1	3
+#define MADERA_DOM_GRP_ASRC2_RATE_2	4
+#define MADERA_DOM_GRP_ISRC1_DEC	5
+#define MADERA_DOM_GRP_ISRC1_INT	6
+#define MADERA_DOM_GRP_ISRC2_DEC	7
+#define MADERA_DOM_GRP_ISRC2_INT	8
+#define MADERA_DOM_GRP_ISRC3_DEC	9
+#define MADERA_DOM_GRP_ISRC3_INT	10
+#define MADERA_DOM_GRP_ISRC4_DEC	11
+#define MADERA_DOM_GRP_ISRC4_INT	12
+#define MADERA_DOM_GRP_OUT		13
+#define MADERA_DOM_GRP_SPD		14
+#define MADERA_DOM_GRP_DSP1		15
+#define MADERA_DOM_GRP_DSP2		16
+#define MADERA_DOM_GRP_DSP3		17
+#define MADERA_DOM_GRP_DSP4		18
+#define MADERA_DOM_GRP_DSP5		19
+#define MADERA_DOM_GRP_DSP6		20
+#define MADERA_DOM_GRP_DSP7		21
+#define MADERA_DOM_GRP_AIF1		22
+#define MADERA_DOM_GRP_AIF2		23
+#define MADERA_DOM_GRP_AIF3		24
+#define MADERA_DOM_GRP_AIF4		25
+#define MADERA_DOM_GRP_SLIMBUS		26
+#define MADERA_DOM_GRP_PWM		27
+#define MADERA_DOM_GRP_DFC		28
+#define MADERA_N_DOM_GRPS		29
+
+#define MADERA_MAX_DAI			11
+#define MADERA_MAX_ADSP			7
+
+#define MADERA_NUM_MIXER_INPUTS		146
+
+struct madera;
+struct wm_adsp;
+
+struct madera_voice_trigger_info {
+	/** Which core triggered, 1-based (1 = DSP1, ...) */
+	int core_num;
+};
+
+struct madera_dai_priv {
+	int clk;
+	struct snd_pcm_hw_constraint_list constraint;
+};
+
+struct madera_priv {
+	struct wm_adsp adsp[MADERA_MAX_ADSP];
+	struct madera *madera;
+	struct device *dev;
+	int sysclk;
+	int asyncclk;
+	int dspclk;
+	struct madera_dai_priv dai[MADERA_MAX_DAI];
+
+	int num_inputs;
+
+	unsigned int in_pending;
+
+	unsigned int out_up_pending;
+	unsigned int out_up_delay;
+	unsigned int out_down_pending;
+	unsigned int out_down_delay;
+
+	unsigned int adsp_rate_cache[MADERA_MAX_ADSP];
+
+	struct mutex rate_lock;
+
+	int tdm_width[MADERA_MAX_AIF];
+	int tdm_slots[MADERA_MAX_AIF];
+
+	int domain_group_ref[MADERA_N_DOM_GRPS];
+};
+
+struct madera_fll_cfg {
+	int n;
+	unsigned int theta;
+	unsigned int lambda;
+	int refdiv;
+	int fratio;
+	int gain;
+	int alt_gain;
+};
+
+struct madera_fll {
+	struct madera *madera;
+	int id;
+	unsigned int base;
+
+	unsigned int fout;
+
+	int sync_src;
+	unsigned int sync_freq;
+
+	int ref_src;
+	unsigned int ref_freq;
+	struct madera_fll_cfg ref_cfg;
+};
+
+struct madera_enum {
+	struct soc_enum mixer_enum;
+	int val;
+};
+
+extern const unsigned int madera_ana_tlv[];
+extern const unsigned int madera_eq_tlv[];
+extern const unsigned int madera_digital_tlv[];
+extern const unsigned int madera_noise_tlv[];
+extern const unsigned int madera_ng_tlv[];
+
+extern const unsigned int madera_mixer_tlv[];
+extern const char * const madera_mixer_texts[MADERA_NUM_MIXER_INPUTS];
+extern unsigned int madera_mixer_values[MADERA_NUM_MIXER_INPUTS];
+
+#define MADERA_GAINMUX_CONTROLS(name, base) \
+	SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1,		\
+			     MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0,	\
+			     madera_mixer_tlv)
+
+#define MADERA_MIXER_CONTROLS(name, base) \
+	SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1,		\
+			     MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0,	\
+			     madera_mixer_tlv),			\
+	SOC_SINGLE_RANGE_TLV(name " Input 2 Volume", base + 3,		\
+			     MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0,	\
+			     madera_mixer_tlv),			\
+	SOC_SINGLE_RANGE_TLV(name " Input 3 Volume", base + 5,		\
+			     MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0,	\
+			     madera_mixer_tlv),			\
+	SOC_SINGLE_RANGE_TLV(name " Input 4 Volume", base + 7,		\
+			     MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0,	\
+			     madera_mixer_tlv)
+
+#define MADERA_MUX_ENUM_DECL(name, reg) \
+	SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL( \
+		name, reg, 0, 0xff, madera_mixer_texts, madera_mixer_values)
+
+#define MADERA_MUX_CTL_DECL(name) \
+	const struct snd_kcontrol_new name##_mux =	\
+		SOC_DAPM_ENUM("Route", name##_enum)
+
+#define MADERA_MUX_ENUMS(name, base_reg) \
+	static MADERA_MUX_ENUM_DECL(name##_enum, base_reg);	\
+	static MADERA_MUX_CTL_DECL(name)
+
+#define MADERA_MIXER_ENUMS(name, base_reg) \
+	MADERA_MUX_ENUMS(name##_in1, base_reg);     \
+	MADERA_MUX_ENUMS(name##_in2, base_reg + 2); \
+	MADERA_MUX_ENUMS(name##_in3, base_reg + 4); \
+	MADERA_MUX_ENUMS(name##_in4, base_reg + 6)
+
+#define MADERA_DSP_AUX_ENUMS(name, base_reg) \
+	MADERA_MUX_ENUMS(name##_aux1, base_reg);	\
+	MADERA_MUX_ENUMS(name##_aux2, base_reg + 8);	\
+	MADERA_MUX_ENUMS(name##_aux3, base_reg + 16);	\
+	MADERA_MUX_ENUMS(name##_aux4, base_reg + 24);	\
+	MADERA_MUX_ENUMS(name##_aux5, base_reg + 32);	\
+	MADERA_MUX_ENUMS(name##_aux6, base_reg + 40)
+
+#define MADERA_MUX(name, ctrl) \
+	SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
+
+#define MADERA_MUX_WIDGETS(name, name_str) \
+	MADERA_MUX(name_str " Input 1", &name##_mux)
+
+#define MADERA_MIXER_WIDGETS(name, name_str)	\
+	MADERA_MUX(name_str " Input 1", &name##_in1_mux), \
+	MADERA_MUX(name_str " Input 2", &name##_in2_mux), \
+	MADERA_MUX(name_str " Input 3", &name##_in3_mux), \
+	MADERA_MUX(name_str " Input 4", &name##_in4_mux), \
+	SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
+
+#define MADERA_DSP_WIDGETS(name, name_str)			\
+	MADERA_MIXER_WIDGETS(name##L, name_str "L"),		\
+	MADERA_MIXER_WIDGETS(name##R, name_str "R"),		\
+	MADERA_MUX(name_str " Aux 1", &name##_aux1_mux),	\
+	MADERA_MUX(name_str " Aux 2", &name##_aux2_mux),	\
+	MADERA_MUX(name_str " Aux 3", &name##_aux3_mux),	\
+	MADERA_MUX(name_str " Aux 4", &name##_aux4_mux),	\
+	MADERA_MUX(name_str " Aux 5", &name##_aux5_mux),	\
+	MADERA_MUX(name_str " Aux 6", &name##_aux6_mux)
+
+#define MADERA_MUX_ROUTES(widget, name) \
+	{ widget, NULL, name " Input 1" }, \
+	MADERA_MIXER_INPUT_ROUTES(name " Input 1")
+
+#define MADERA_MIXER_ROUTES(widget, name)		\
+	{ widget, NULL, name " Mixer" },		\
+	{ name " Mixer", NULL, name " Input 1" },	\
+	{ name " Mixer", NULL, name " Input 2" },	\
+	{ name " Mixer", NULL, name " Input 3" },	\
+	{ name " Mixer", NULL, name " Input 4" },	\
+	MADERA_MIXER_INPUT_ROUTES(name " Input 1"),	\
+	MADERA_MIXER_INPUT_ROUTES(name " Input 2"),	\
+	MADERA_MIXER_INPUT_ROUTES(name " Input 3"),	\
+	MADERA_MIXER_INPUT_ROUTES(name " Input 4")
+
+#define MADERA_DSP_ROUTES(name)				\
+	{ name, NULL, name " Preloader"},		\
+	{ name " Preloader", NULL, "SYSCLK"},		\
+	{ name " Preloader", NULL, "DSPCLK"},		\
+	{ name, NULL, name " Aux 1" },			\
+	{ name, NULL, name " Aux 2" },			\
+	{ name, NULL, name " Aux 3" },			\
+	{ name, NULL, name " Aux 4" },			\
+	{ name, NULL, name " Aux 5" },			\
+	{ name, NULL, name " Aux 6" },			\
+	MADERA_MIXER_INPUT_ROUTES(name " Aux 1"),	\
+	MADERA_MIXER_INPUT_ROUTES(name " Aux 2"),	\
+	MADERA_MIXER_INPUT_ROUTES(name " Aux 3"),	\
+	MADERA_MIXER_INPUT_ROUTES(name " Aux 4"),	\
+	MADERA_MIXER_INPUT_ROUTES(name " Aux 5"),	\
+	MADERA_MIXER_INPUT_ROUTES(name " Aux 6"),	\
+	MADERA_MIXER_ROUTES(name, name "L"),		\
+	MADERA_MIXER_ROUTES(name, name "R")
+
+#define MADERA_SAMPLE_RATE_CONTROL(name, domain) \
+	SOC_ENUM(name, madera_sample_rate[(domain) - 2])
+
+#define MADERA_RATE_ENUM(xname, xenum) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
+	.info = snd_soc_info_enum_double, \
+	.get = snd_soc_get_enum_double, .put = madera_rate_put, \
+	.private_value = (unsigned long)&xenum }
+
+#define MADERA_EQ_CONTROL(xname, xbase)				\
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
+	.info = snd_soc_bytes_info, .get = snd_soc_bytes_get,	\
+	.put = madera_eq_coeff_put, .private_value =		\
+	((unsigned long)&(struct soc_bytes) { .base = xbase,	\
+	 .num_regs = 20, .mask = ~MADERA_EQ1_B1_MODE }) }
+
+#define MADERA_LHPF_CONTROL(xname, xbase)			\
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
+	.info = snd_soc_bytes_info, .get = snd_soc_bytes_get,	\
+	.put = madera_lhpf_coeff_put, .private_value =		\
+	((unsigned long)&(struct soc_bytes) { .base = xbase,	\
+	 .num_regs = 1 }) }
+
+#define MADERA_RATES SNDRV_PCM_RATE_KNOT
+
+#define MADERA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+#define MADERA_OSR_ENUM_SIZE		5
+#define MADERA_SYNC_RATE_ENUM_SIZE	3
+#define MADERA_ASYNC_RATE_ENUM_SIZE	2
+#define MADERA_RATE_ENUM_SIZE \
+		(MADERA_SYNC_RATE_ENUM_SIZE + MADERA_ASYNC_RATE_ENUM_SIZE)
+#define MADERA_SAMPLE_RATE_ENUM_SIZE	16
+#define MADERA_DFC_TYPE_ENUM_SIZE	5
+#define MADERA_DFC_WIDTH_ENUM_SIZE	5
+
+extern const struct snd_soc_dai_ops madera_dai_ops;
+extern const struct snd_soc_dai_ops madera_simple_dai_ops;
+
+extern const struct snd_kcontrol_new madera_inmux[];
+
+extern const char * const madera_rate_text[MADERA_RATE_ENUM_SIZE];
+extern const unsigned int madera_rate_val[MADERA_RATE_ENUM_SIZE];
+extern const char * const madera_sample_rate_text[MADERA_SAMPLE_RATE_ENUM_SIZE];
+extern const unsigned int madera_sample_rate_val[MADERA_SAMPLE_RATE_ENUM_SIZE];
+extern const char * const madera_dfc_width_text[MADERA_DFC_WIDTH_ENUM_SIZE];
+extern const unsigned int madera_dfc_width_val[MADERA_DFC_WIDTH_ENUM_SIZE];
+extern const char * const madera_dfc_type_text[MADERA_DFC_TYPE_ENUM_SIZE];
+extern const unsigned int madera_dfc_type_val[MADERA_DFC_TYPE_ENUM_SIZE];
+
+extern const struct soc_enum madera_sample_rate[];
+extern const struct soc_enum madera_isrc_fsl[];
+extern const struct soc_enum madera_isrc_fsh[];
+extern const struct soc_enum madera_asrc1_rate[];
+extern const struct soc_enum madera_asrc2_rate[];
+extern const struct soc_enum madera_dfc_width[];
+extern const struct soc_enum madera_dfc_type[];
+extern const struct soc_enum madera_spdif_rate;
+
+extern const struct soc_enum madera_in_vi_ramp;
+extern const struct soc_enum madera_in_vd_ramp;
+
+extern const struct soc_enum madera_out_vi_ramp;
+extern const struct soc_enum madera_out_vd_ramp;
+
+extern const struct soc_enum madera_lhpf1_mode;
+extern const struct soc_enum madera_lhpf2_mode;
+extern const struct soc_enum madera_lhpf3_mode;
+extern const struct soc_enum madera_lhpf4_mode;
+
+extern const struct soc_enum madera_ng_hold;
+extern const struct soc_enum madera_in_hpf_cut_enum;
+extern const struct soc_enum madera_in_dmic_osr[];
+
+extern const struct soc_enum madera_output_anc_src[];
+extern const struct soc_enum madera_anc_input_src[];
+extern const struct soc_enum madera_anc_ng_enum;
+
+extern const struct snd_kcontrol_new madera_dsp_trigger_output_mux[];
+extern const struct snd_kcontrol_new madera_drc_activity_output_mux[];
+
+extern const struct snd_kcontrol_new madera_adsp_rate_controls[];
+
+const char *madera_sample_rate_val_to_name(unsigned int rate_val);
+
+int madera_dfc_put(struct snd_kcontrol *kcontrol,
+		   struct snd_ctl_elem_value *ucontrol);
+
+int madera_lp_mode_put(struct snd_kcontrol *kcontrol,
+		       struct snd_ctl_elem_value *ucontrol);
+
+int madera_out1_demux_put(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol);
+
+int madera_dre_put(struct snd_kcontrol *kcontrol,
+		   struct snd_ctl_elem_value *ucontrol);
+
+int madera_rate_put(struct snd_kcontrol *kcontrol,
+		    struct snd_ctl_elem_value *ucontrol);
+
+int madera_eq_coeff_put(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol);
+int madera_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol);
+
+int madera_sysclk_ev(struct snd_soc_dapm_widget *w,
+		     struct snd_kcontrol *kcontrol, int event);
+int madera_spk_ev(struct snd_soc_dapm_widget *w,
+		  struct snd_kcontrol *kcontrol, int event);
+int madera_in_ev(struct snd_soc_dapm_widget *w,
+		 struct snd_kcontrol *kcontrol, int event);
+int madera_out_ev(struct snd_soc_dapm_widget *w,
+		  struct snd_kcontrol *kcontrol, int event);
+int madera_hp_ev(struct snd_soc_dapm_widget *w,
+		 struct snd_kcontrol *kcontrol, int event);
+int madera_anc_ev(struct snd_soc_dapm_widget *w,
+		  struct snd_kcontrol *kcontrol, int event);
+int madera_domain_clk_ev(struct snd_soc_dapm_widget *w,
+			 struct snd_kcontrol *kcontrol,
+			 int event);
+
+int madera_adsp_rate_info(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_info *uinfo);
+int madera_adsp_rate_get(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol);
+int madera_adsp_rate_put(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol);
+int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num,
+			unsigned int freq);
+
+int madera_set_sysclk(struct snd_soc_codec *codec, int clk_id, int source,
+		      unsigned int freq, int dir);
+int madera_get_legacy_dspclk_setting(struct madera *madera, unsigned int freq);
+void madera_spin_sysclk(struct madera_priv *priv);
+
+int madera_init_fll(struct madera *madera, int id, int base,
+		    struct madera_fll *fll);
+int madera_set_fll_refclk(struct madera_fll *fll, int source,
+			  unsigned int Fref, unsigned int Fout);
+int madera_set_fll_syncclk(struct madera_fll *fll, int source,
+			   unsigned int Fref, unsigned int Fout);
+int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
+			     unsigned int fin, unsigned int fout);
+
+int madera_core_init(struct madera_priv *priv);
+int madera_core_destroy(struct madera_priv *priv);
+int madera_init_overheat(struct madera_priv *priv);
+int madera_free_overheat(struct madera_priv *priv);
+int madera_init_inputs(struct snd_soc_codec *codec,
+		       const char * const *dmic_inputs,
+		       int n_dmic_inputs,
+		       const char * const *dmic_refs,
+		       int n_dmic_refs);
+int madera_init_outputs(struct snd_soc_codec *codec, int n_mono_routes);
+int madera_init_bus_error_irq(struct madera_priv *priv, int dsp_num,
+			      irq_handler_t handler);
+void madera_destroy_bus_error_irq(struct madera_priv *priv, int dsp_num);
+
+int madera_init_dai(struct madera_priv *priv, int dai);
+
+int madera_set_output_mode(struct snd_soc_codec *codec, int output, bool diff);
+
+/* Following functions are for use by machine drivers */
+static inline int madera_register_notifier(struct snd_soc_codec *codec,
+					   struct notifier_block *nb)
+{
+	struct madera *madera = dev_get_drvdata(codec->dev->parent);
+
+	return blocking_notifier_chain_register(&madera->notifier, nb);
+}
+
+static inline int madera_unregister_notifier(struct snd_soc_codec *codec,
+					     struct notifier_block *nb)
+{
+	struct madera *madera = dev_get_drvdata(codec->dev->parent);
+
+	return blocking_notifier_chain_unregister(&madera->notifier, nb);
+}
+
+#endif
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 15/18] dt-bindings: sound: Add bindings for Cirrus Logic Madera codecs
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones-QSEj5FYQhm4dnm+yROfE0A, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	gnurou-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA
  Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493050124-5970-1-git-send-email-rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>

The Cirrus Logic Madera codecs are a family of related codecs with
extensive digital and analogue I/O, digital mixing and routing,
signal processing and programmable DSPs.

Signed-off-by: Richard Fitzgerald <rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
---
Changes since V1:
- these bindings split out from the main source patch
- some minor edits to the property descriptions to match the pdata
  descriptions

 Documentation/devicetree/bindings/sound/madera.txt | 66 ++++++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/madera.txt

diff --git a/Documentation/devicetree/bindings/sound/madera.txt b/Documentation/devicetree/bindings/sound/madera.txt
new file mode 100644
index 0000000..b114f7b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/madera.txt
@@ -0,0 +1,66 @@
+Cirrus Logic Madera class audio codecs
+
+This is a subnode of the parent mfd node.
+
+See also the core bindings for the parent MFD driver:
+See Documentation/devicetree/bindings/mfd/madera.txt
+
+Required properties:
+  - compatible : One of the following chip-specific strings:
+        "cirrus,cs47l35-codec"
+        "cirrus,cs47l85-codec"
+        "cirrus,cs47l90-codec"
+
+Optional properties:
+  - cirrus,dmic-ref : DMIC bias reference for each input, one cell per input
+    <IN1 IN2 IN3 ...>
+    A value of 0 indicates MICVDD and is the default, other values depend on the
+    codec - see the datasheet for the INn_DMIC_SUP field
+
+  - cirrus,inmode : A list of input mode settings for each input. A maximum of
+    16 cells, with four cells per input in the order INnAL, INnAR INnBL INnBR.
+    For non-muxed inputs the first two cells for that input set the mode for
+    the left and right channel and the second two cells must be 0.
+    For muxed inputs the first two cells for that input set the mode of the
+    left and right A inputs and the second two cells set the mode of the left
+    and right B inputs.
+    Valid mode values are one of the MADERA_INMODE_xxx (see
+    include/dt-bindings/sound/madera.h). If the array is shorter than the number
+    of inputs the unspecified inputs default to MADERA_INMODE_DIFF.
+
+  - cirrus,out-mono : Mono bit for each output, must contain six cells if
+    specified. A non-zero value indicates the corresponding output is mono.
+
+  - cirrus,max-channels-clocked : Maximum number of channels that I2S clocks
+    will be generated for. Useful when clock master for systems where the I2S
+    bus has multiple data lines.
+    One cell for each AIF, use a value of zero for AIFs that should be handled
+    normally.
+
+  - cirrus,pdm-fmt : PDM speaker data format, must contain 2 cells
+    (OUT5 and OUT6). See the PDM_SPKn_FMT field in the datasheet for a
+    description of this value.
+    The second cell is ignored for codecs that do not have OUT6.
+
+  - cirrus,pdm-mute : PDM mute format, must contain 2 cells
+    (OUT5 and OUT6). See the PDM_SPKn_CTRL_1 register in the datasheet for a
+    description of this value.
+    The second cell is ignored for codecs that do not have OUT6.
+
+Example:
+
+codec: cs47l35@0 {
+	compatible = "cirrus,cs47l35";
+
+	codec {
+		compatible = "cirrus,cs47l35-codec";
+		cirrus,dmic-ref = <0 0 1 0>;
+		cirrus,dmic-clksrc = <0 0 0 0>;
+		cirrus,inmode = <
+			2 2 1 1 /* IN1A digital, IN1B single-ended */
+			0 0 0 0	/* IN2 differential */
+		>;
+		cirrus,out-mono = <0 0 0 0 0 0>;
+		cirrus,max-channels-clocked = <2 0 0>;
+	};
+};
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 16/18] ASoC: cs47l35: Add codec driver for Cirrus Logic CS47L35
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones, broonie, linus.walleij, gnurou, robh+dt, tglx, jason
  Cc: alsa-devel, patches, linux-gpio, devicetree, linux-kernel
In-Reply-To: <1493050124-5970-1-git-send-email-rf@opensource.wolfsonmicro.com>

Adds the codec driver for the CS47L35 SmartCodec. This is a
multi-functional codec based on the Cirrus Logic Madera platform.

Signed-off-by: Piotr Stankiewicz <piotrs@opensource.wolfsonmicro.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
No changes since V1

 sound/soc/codecs/Kconfig   |    6 +
 sound/soc/codecs/Makefile  |    2 +
 sound/soc/codecs/cs47l35.c | 1747 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1755 insertions(+)
 create mode 100644 sound/soc/codecs/cs47l35.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 30985a1..f502fec 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -62,6 +62,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_CS42XX8_I2C if I2C
 	select SND_SOC_CS4349 if I2C
 	select SND_SOC_CS47L24 if MFD_CS47L24
+	select SND_SOC_CS47L35 if MFD_CS47L35
 	select SND_SOC_CS53L30 if I2C
 	select SND_SOC_CX20442 if TTY
 	select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
@@ -494,6 +495,9 @@ config SND_SOC_CS4349
 config SND_SOC_CS47L24
 	tristate
 
+config SND_SOC_CS47L35
+	tristate
+
 # Cirrus Logic Quad-Channel ADC
 config SND_SOC_CS53L30
 	tristate "Cirrus Logic CS53L30 CODEC"
@@ -581,6 +585,8 @@ config SND_SOC_LM49453
 
 config SND_SOC_MADERA
 	tristate
+	default y if SND_SOC_CS47L35=y
+	default m if SND_SOC_CS47L35=m
 
 config SND_SOC_MAX98088
        tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index ae2eb27..9c578e1 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -55,6 +55,7 @@ snd-soc-cs42xx8-objs := cs42xx8.o
 snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
 snd-soc-cs4349-objs := cs4349.o
 snd-soc-cs47l24-objs := cs47l24.o
+snd-soc-cs47l35-objs := cs47l35.o
 snd-soc-cs53l30-objs := cs53l30.o
 snd-soc-cx20442-objs := cx20442.o
 snd-soc-da7210-objs := da7210.o
@@ -290,6 +291,7 @@ obj-$(CONFIG_SND_SOC_CS42XX8)	+= snd-soc-cs42xx8.o
 obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o
 obj-$(CONFIG_SND_SOC_CS4349)	+= snd-soc-cs4349.o
 obj-$(CONFIG_SND_SOC_CS47L24)	+= snd-soc-cs47l24.o
+obj-$(CONFIG_SND_SOC_CS47L35)	+= snd-soc-cs47l35.o
 obj-$(CONFIG_SND_SOC_CS53L30)	+= snd-soc-cs53l30.o
 obj-$(CONFIG_SND_SOC_CX20442)	+= snd-soc-cx20442.o
 obj-$(CONFIG_SND_SOC_DA7210)	+= snd-soc-da7210.o
diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c
new file mode 100644
index 0000000..50ecc44
--- /dev/null
+++ b/sound/soc/codecs/cs47l35.c
@@ -0,0 +1,1747 @@
+/*
+ * cs47l35.c  --  ALSA SoC Audio driver for CS47L35 codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+#include <sound/tlv.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/registers.h>
+
+#include "madera.h"
+#include "wm_adsp.h"
+
+#define CS47L35_NUM_ADSP	3
+#define CS47L35_MONO_OUTPUTS	1
+
+struct cs47l35 {
+	struct madera_priv core;
+	struct madera_fll fll;
+};
+
+static const struct wm_adsp_region cs47l35_dsp1_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x080000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x0e0000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x0a0000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x0c0000 },
+};
+
+static const struct wm_adsp_region cs47l35_dsp2_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x100000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x160000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x120000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x140000 },
+};
+
+static const struct wm_adsp_region cs47l35_dsp3_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x180000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x1e0000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x1a0000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x1c0000 },
+};
+
+static const struct wm_adsp_region *cs47l35_dsp_regions[] = {
+	cs47l35_dsp1_regions,
+	cs47l35_dsp2_regions,
+	cs47l35_dsp3_regions,
+};
+
+static const int wm_adsp2_control_bases[] = {
+	MADERA_DSP1_CONFIG_1,
+	MADERA_DSP2_CONFIG_1,
+	MADERA_DSP3_CONFIG_1,
+};
+
+static const char * const cs47l35_outdemux_texts[] = {
+	"HPOUT",
+	"EPOUT",
+};
+
+static SOC_ENUM_SINGLE_DECL(cs47l35_outdemux_enum, SND_SOC_NOPM, 0,
+			    cs47l35_outdemux_texts);
+
+static const struct snd_kcontrol_new cs47l35_outdemux =
+	SOC_DAPM_ENUM_EXT("HPOUT1 Demux", cs47l35_outdemux_enum,
+			  snd_soc_dapm_get_enum_double, madera_out1_demux_put);
+
+static int cs47l35_adsp_power_ev(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kcontrol,
+				 int event)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct cs47l35 *cs47l35 = snd_soc_codec_get_drvdata(codec);
+	struct madera_priv *priv = &cs47l35->core;
+	struct madera *madera = priv->madera;
+	unsigned int freq;
+	int ret;
+
+	ret = regmap_read(madera->regmap, MADERA_DSP_CLOCK_1, &freq);
+	if (ret != 0) {
+		dev_err(madera->dev,
+			"Failed to read MADERA_DSP_CLOCK_1: %d\n", ret);
+		return ret;
+	}
+
+	freq &= MADERA_DSP_CLK_FREQ_LEGACY_MASK;
+	freq >>= MADERA_DSP_CLK_FREQ_LEGACY_SHIFT;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		ret = madera_set_adsp_clk(&cs47l35->core, w->shift, freq);
+		if (ret)
+			return ret;
+		break;
+	default:
+		break;
+	}
+
+	return wm_adsp2_early_event(w, kcontrol, event, freq);
+}
+
+#define CS47L35_NG_SRC(name, base) \
+	SOC_SINGLE(name " NG HPOUT1L Switch",  base,  0, 1, 0), \
+	SOC_SINGLE(name " NG HPOUT1R Switch",  base,  1, 1, 0), \
+	SOC_SINGLE(name " NG SPKOUT Switch",  base,  6, 1, 0), \
+	SOC_SINGLE(name " NG SPKDAT1L Switch", base,  8, 1, 0), \
+	SOC_SINGLE(name " NG SPKDAT1R Switch", base,  9, 1, 0)
+
+static void cs47l35_hp_post_enable(struct snd_soc_dapm_widget *w)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	unsigned int val;
+
+	switch (w->shift) {
+	case MADERA_OUT1L_ENA_SHIFT:
+	case MADERA_OUT1R_ENA_SHIFT:
+		val = snd_soc_read(codec, MADERA_OUTPUT_ENABLES_1);
+		val &= (MADERA_OUT1L_ENA | MADERA_OUT1R_ENA);
+
+		if (val == (MADERA_OUT1L_ENA | MADERA_OUT1R_ENA))
+			snd_soc_update_bits(codec,
+				    MADERA_EDRE_HP_STEREO_CONTROL,
+				    MADERA_HP1_EDRE_STEREO_MASK,
+				    MADERA_HP1_EDRE_STEREO);
+		break;
+
+	default:
+		break;
+	}
+}
+
+static void cs47l35_hp_post_disable(struct snd_soc_dapm_widget *w)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+	switch (w->shift) {
+	case MADERA_OUT1L_ENA_SHIFT:
+		snd_soc_write(codec, MADERA_DCS_HP1L_CONTROL, 0x2006);
+		break;
+	case MADERA_OUT1R_ENA_SHIFT:
+		snd_soc_write(codec, MADERA_DCS_HP1R_CONTROL, 0x2006);
+		break;
+	default:
+		return;
+	}
+
+	/* Only get to here for OUT1L and OUT1R */
+	snd_soc_update_bits(codec,
+			    MADERA_EDRE_HP_STEREO_CONTROL,
+			    MADERA_HP1_EDRE_STEREO_MASK,
+			    0);
+}
+
+static int cs47l35_hp_ev(struct snd_soc_dapm_widget *w,
+			 struct snd_kcontrol *kcontrol, int event)
+{
+	int ret;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+	case SND_SOC_DAPM_PRE_PMD:
+		return madera_hp_ev(w, kcontrol, event);
+	case SND_SOC_DAPM_POST_PMU:
+		ret = madera_hp_ev(w, kcontrol, event);
+		if (ret < 0)
+			return ret;
+
+		cs47l35_hp_post_enable(w);
+		return 0;
+	case SND_SOC_DAPM_POST_PMD:
+		ret = madera_hp_ev(w, kcontrol, event);
+		cs47l35_hp_post_disable(w);
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct snd_kcontrol_new cs47l35_snd_controls[] = {
+SOC_ENUM("IN1 OSR", madera_in_dmic_osr[0]),
+SOC_ENUM("IN2 OSR", madera_in_dmic_osr[1]),
+
+SOC_SINGLE_RANGE_TLV("IN1L Volume", MADERA_IN1L_CONTROL,
+		     MADERA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+SOC_SINGLE_RANGE_TLV("IN1R Volume", MADERA_IN1R_CONTROL,
+		     MADERA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+SOC_SINGLE_RANGE_TLV("IN2L Volume", MADERA_IN2L_CONTROL,
+		     MADERA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+SOC_SINGLE_RANGE_TLV("IN2R Volume", MADERA_IN2R_CONTROL,
+		     MADERA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+
+SOC_ENUM("IN HPF Cutoff Frequency", madera_in_hpf_cut_enum),
+
+SOC_SINGLE("IN1L HPF Switch", MADERA_IN1L_CONTROL,
+	   MADERA_IN1L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN1R HPF Switch", MADERA_IN1R_CONTROL,
+	   MADERA_IN1R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN2L HPF Switch", MADERA_IN2L_CONTROL,
+	   MADERA_IN2L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN2R HPF Switch", MADERA_IN2R_CONTROL,
+	   MADERA_IN2R_HPF_SHIFT, 1, 0),
+
+SOC_SINGLE_TLV("IN1L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1L,
+	       MADERA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN1R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1R,
+	       MADERA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN2L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2L,
+	       MADERA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN2R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2R,
+	       MADERA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+
+SOC_ENUM("Input Ramp Up", madera_in_vi_ramp),
+SOC_ENUM("Input Ramp Down", madera_in_vd_ramp),
+
+MADERA_MIXER_CONTROLS("EQ1", MADERA_EQ1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("EQ2", MADERA_EQ2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("EQ3", MADERA_EQ3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("EQ4", MADERA_EQ4MIX_INPUT_1_SOURCE),
+
+MADERA_EQ_CONTROL("EQ1 Coefficients", MADERA_EQ1_2),
+SOC_SINGLE_TLV("EQ1 B1 Volume", MADERA_EQ1_1, MADERA_EQ1_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B2 Volume", MADERA_EQ1_1, MADERA_EQ1_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B3 Volume", MADERA_EQ1_1, MADERA_EQ1_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B4 Volume", MADERA_EQ1_2, MADERA_EQ1_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B5 Volume", MADERA_EQ1_2, MADERA_EQ1_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_EQ_CONTROL("EQ2 Coefficients", MADERA_EQ2_2),
+SOC_SINGLE_TLV("EQ2 B1 Volume", MADERA_EQ2_1, MADERA_EQ2_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B2 Volume", MADERA_EQ2_1, MADERA_EQ2_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B3 Volume", MADERA_EQ2_1, MADERA_EQ2_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B4 Volume", MADERA_EQ2_2, MADERA_EQ2_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B5 Volume", MADERA_EQ2_2, MADERA_EQ2_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_EQ_CONTROL("EQ3 Coefficients", MADERA_EQ3_2),
+SOC_SINGLE_TLV("EQ3 B1 Volume", MADERA_EQ3_1, MADERA_EQ3_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B2 Volume", MADERA_EQ3_1, MADERA_EQ3_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B3 Volume", MADERA_EQ3_1, MADERA_EQ3_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B4 Volume", MADERA_EQ3_2, MADERA_EQ3_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B5 Volume", MADERA_EQ3_2, MADERA_EQ3_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_EQ_CONTROL("EQ4 Coefficients", MADERA_EQ4_2),
+SOC_SINGLE_TLV("EQ4 B1 Volume", MADERA_EQ4_1, MADERA_EQ4_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B2 Volume", MADERA_EQ4_1, MADERA_EQ4_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B3 Volume", MADERA_EQ4_1, MADERA_EQ4_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B4 Volume", MADERA_EQ4_2, MADERA_EQ4_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B5 Volume", MADERA_EQ4_2, MADERA_EQ4_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_MIXER_CONTROLS("DRC1L", MADERA_DRC1LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DRC1R", MADERA_DRC1RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DRC2L", MADERA_DRC2LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DRC2R", MADERA_DRC2RMIX_INPUT_1_SOURCE),
+
+SND_SOC_BYTES_MASK("DRC1", MADERA_DRC1_CTRL1, 5,
+		   MADERA_DRC1R_ENA | MADERA_DRC1L_ENA),
+SND_SOC_BYTES_MASK("DRC2", MADERA_DRC2_CTRL1, 5,
+		   MADERA_DRC2R_ENA | MADERA_DRC2L_ENA),
+
+MADERA_MIXER_CONTROLS("LHPF1", MADERA_HPLP1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("LHPF2", MADERA_HPLP2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("LHPF3", MADERA_HPLP3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("LHPF4", MADERA_HPLP4MIX_INPUT_1_SOURCE),
+
+MADERA_LHPF_CONTROL("LHPF1 Coefficients", MADERA_HPLPF1_2),
+MADERA_LHPF_CONTROL("LHPF2 Coefficients", MADERA_HPLPF2_2),
+MADERA_LHPF_CONTROL("LHPF3 Coefficients", MADERA_HPLPF3_2),
+MADERA_LHPF_CONTROL("LHPF4 Coefficients", MADERA_HPLPF4_2),
+
+SOC_ENUM("LHPF1 Mode", madera_lhpf1_mode),
+SOC_ENUM("LHPF2 Mode", madera_lhpf2_mode),
+SOC_ENUM("LHPF3 Mode", madera_lhpf3_mode),
+SOC_ENUM("LHPF4 Mode", madera_lhpf4_mode),
+
+SOC_ENUM("Sample Rate 2", madera_sample_rate[0]),
+SOC_ENUM("Sample Rate 3", madera_sample_rate[1]),
+
+MADERA_RATE_ENUM("ISRC1 FSL", madera_isrc_fsl[0]),
+MADERA_RATE_ENUM("ISRC2 FSL", madera_isrc_fsl[1]),
+MADERA_RATE_ENUM("ISRC1 FSH", madera_isrc_fsh[0]),
+MADERA_RATE_ENUM("ISRC2 FSH", madera_isrc_fsh[1]),
+
+MADERA_MIXER_CONTROLS("DSP1L", MADERA_DSP1LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP1R", MADERA_DSP1RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP2L", MADERA_DSP2LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP2R", MADERA_DSP2RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP3L", MADERA_DSP3LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP3R", MADERA_DSP3RMIX_INPUT_1_SOURCE),
+
+SOC_SINGLE_TLV("Noise Generator Volume", MADERA_COMFORT_NOISE_GENERATOR,
+	       MADERA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, madera_noise_tlv),
+
+MADERA_MIXER_CONTROLS("HPOUT1L", MADERA_OUT1LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("HPOUT1R", MADERA_OUT1RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SPKOUT", MADERA_OUT4LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SPKDAT1L", MADERA_OUT5LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SPKDAT1R", MADERA_OUT5RMIX_INPUT_1_SOURCE),
+
+SOC_SINGLE("HPOUT1 SC Protect Switch", MADERA_HP1_SHORT_CIRCUIT_CTRL,
+	   MADERA_HP1_SC_ENA_SHIFT, 1, 0),
+
+SOC_SINGLE("HPOUT1L ONEFLT Switch", MADERA_HP_TEST_CTRL_5,
+				    MADERA_HP1L_ONEFLT_SHIFT, 1, 0),
+SOC_SINGLE("HPOUT1R ONEFLT Switch", MADERA_HP_TEST_CTRL_6,
+				    MADERA_HP1R_ONEFLT_SHIFT, 1, 0),
+
+SOC_SINGLE("SPKDAT1 High Performance Switch", MADERA_OUTPUT_PATH_CONFIG_5L,
+	   MADERA_OUT5_OSR_SHIFT, 1, 0),
+
+SOC_DOUBLE_R("HPOUT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_1L,
+	     MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_MUTE_SHIFT, 1, 1),
+SOC_SINGLE("Speaker Digital Switch", MADERA_DAC_DIGITAL_VOLUME_4L,
+	   MADERA_OUT4L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("SPKDAT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_5L,
+	     MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_MUTE_SHIFT, 1, 1),
+
+SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_1L,
+		 MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("Speaker Digital Volume", MADERA_DAC_DIGITAL_VOLUME_4L,
+	       MADERA_OUT4L_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_5L,
+		 MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+
+SOC_DOUBLE("SPKDAT1 Switch", MADERA_PDM_SPK1_CTRL_1, MADERA_SPK1L_MUTE_SHIFT,
+	   MADERA_SPK1R_MUTE_SHIFT, 1, 1),
+
+SOC_DOUBLE("HPOUT1 EDRE Switch", MADERA_EDRE_ENABLE,
+	   MADERA_EDRE_OUT1L_THR1_ENA_SHIFT,
+	   MADERA_EDRE_OUT1R_THR1_ENA_SHIFT, 1, 0),
+
+SOC_SINGLE("Speaker THR1 EDRE Switch", MADERA_EDRE_ENABLE,
+	   MADERA_EDRE_OUT4L_THR1_ENA_SHIFT, 1, 0),
+
+SOC_ENUM("Output Ramp Up", madera_out_vi_ramp),
+SOC_ENUM("Output Ramp Down", madera_out_vd_ramp),
+
+SOC_SINGLE("Noise Gate Switch", MADERA_NOISE_GATE_CONTROL,
+	   MADERA_NGATE_ENA_SHIFT, 1, 0),
+SOC_SINGLE_TLV("Noise Gate Threshold Volume", MADERA_NOISE_GATE_CONTROL,
+	       MADERA_NGATE_THR_SHIFT, 7, 1, madera_ng_tlv),
+SOC_ENUM("Noise Gate Hold", madera_ng_hold),
+
+CS47L35_NG_SRC("HPOUT1L", MADERA_NOISE_GATE_SELECT_1L),
+CS47L35_NG_SRC("HPOUT1R", MADERA_NOISE_GATE_SELECT_1R),
+CS47L35_NG_SRC("SPKOUT", MADERA_NOISE_GATE_SELECT_4L),
+CS47L35_NG_SRC("SPKDAT1L", MADERA_NOISE_GATE_SELECT_5L),
+CS47L35_NG_SRC("SPKDAT1R", MADERA_NOISE_GATE_SELECT_5R),
+
+MADERA_MIXER_CONTROLS("AIF1TX1", MADERA_AIF1TX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX2", MADERA_AIF1TX2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX3", MADERA_AIF1TX3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX4", MADERA_AIF1TX4MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX5", MADERA_AIF1TX5MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX6", MADERA_AIF1TX6MIX_INPUT_1_SOURCE),
+
+MADERA_MIXER_CONTROLS("AIF2TX1", MADERA_AIF2TX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX2", MADERA_AIF2TX2MIX_INPUT_1_SOURCE),
+
+MADERA_MIXER_CONTROLS("AIF3TX1", MADERA_AIF3TX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF3TX2", MADERA_AIF3TX2MIX_INPUT_1_SOURCE),
+
+MADERA_MIXER_CONTROLS("SLIMTX1", MADERA_SLIMTX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX2", MADERA_SLIMTX2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX3", MADERA_SLIMTX3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX4", MADERA_SLIMTX4MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX5", MADERA_SLIMTX5MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX6", MADERA_SLIMTX6MIX_INPUT_1_SOURCE),
+
+MADERA_GAINMUX_CONTROLS("SPDIF1TX1", MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE),
+MADERA_GAINMUX_CONTROLS("SPDIF1TX2", MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE),
+};
+
+MADERA_MIXER_ENUMS(EQ1, MADERA_EQ1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(EQ2, MADERA_EQ2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(EQ3, MADERA_EQ3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(EQ4, MADERA_EQ4MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DRC1L, MADERA_DRC1LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DRC1R, MADERA_DRC1RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DRC2L, MADERA_DRC2LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DRC2R, MADERA_DRC2RMIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(LHPF1, MADERA_HPLP1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(LHPF2, MADERA_HPLP2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(LHPF3, MADERA_HPLP3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(LHPF4, MADERA_HPLP4MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP1L, MADERA_DSP1LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP1R, MADERA_DSP1RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP1, MADERA_DSP1AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP2L, MADERA_DSP2LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP2R, MADERA_DSP2RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP2, MADERA_DSP2AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP3L, MADERA_DSP3LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP3R, MADERA_DSP3RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP3, MADERA_DSP3AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(PWM1, MADERA_PWM1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(PWM2, MADERA_PWM2MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(OUT1L, MADERA_OUT1LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(OUT1R, MADERA_OUT1RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SPKOUT, MADERA_OUT4LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SPKDAT1L, MADERA_OUT5LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SPKDAT1R, MADERA_OUT5RMIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(AIF1TX1, MADERA_AIF1TX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX2, MADERA_AIF1TX2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX3, MADERA_AIF1TX3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX4, MADERA_AIF1TX4MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX5, MADERA_AIF1TX5MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX6, MADERA_AIF1TX6MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(AIF2TX1, MADERA_AIF2TX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX2, MADERA_AIF2TX2MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(AIF3TX1, MADERA_AIF3TX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF3TX2, MADERA_AIF3TX2MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(SLIMTX1, MADERA_SLIMTX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX2, MADERA_SLIMTX2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX3, MADERA_SLIMTX3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX4, MADERA_SLIMTX4MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX5, MADERA_SLIMTX5MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX6, MADERA_SLIMTX6MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(SPD1TX1, MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(SPD1TX2, MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC1INT1, MADERA_ISRC1INT1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1INT2, MADERA_ISRC1INT2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1INT3, MADERA_ISRC1INT3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1INT4, MADERA_ISRC1INT4MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC1DEC1, MADERA_ISRC1DEC1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1DEC2, MADERA_ISRC1DEC2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1DEC3, MADERA_ISRC1DEC3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1DEC4, MADERA_ISRC1DEC4MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC2INT1, MADERA_ISRC2INT1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2INT2, MADERA_ISRC2INT2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2INT3, MADERA_ISRC2INT3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2INT4, MADERA_ISRC2INT4MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC2DEC1, MADERA_ISRC2DEC1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2DEC2, MADERA_ISRC2DEC2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2DEC3, MADERA_ISRC2DEC3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2DEC4, MADERA_ISRC2DEC4MIX_INPUT_1_SOURCE);
+
+static const char * const cs47l35_aec_loopback_texts[] = {
+	"HPOUT1L", "HPOUT1R", "SPKOUT", "SPKDAT1L", "SPKDAT1R",
+};
+
+static const unsigned int cs47l35_aec_loopback_values[] = {
+	0, 1, 6, 8, 9,
+};
+
+static const struct soc_enum cs47l35_aec_loopback =
+	SOC_VALUE_ENUM_SINGLE(MADERA_DAC_AEC_CONTROL_1,
+			      MADERA_AEC1_LOOPBACK_SRC_SHIFT, 0xf,
+			      ARRAY_SIZE(cs47l35_aec_loopback_texts),
+			      cs47l35_aec_loopback_texts,
+			      cs47l35_aec_loopback_values);
+
+static const struct snd_kcontrol_new cs47l35_aec_loopback_mux =
+	SOC_DAPM_ENUM("AEC1 Loopback", cs47l35_aec_loopback);
+
+static const struct snd_soc_dapm_widget cs47l35_dapm_widgets[] = {
+SND_SOC_DAPM_SUPPLY("SYSCLK", MADERA_SYSTEM_CLOCK_1, MADERA_SYSCLK_ENA_SHIFT,
+		    0, madera_sysclk_ev,
+		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK,
+		    MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1, 6,
+		    0, NULL, 0),
+
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD1", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD2", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
+SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDD", 0, 0),
+
+SND_SOC_DAPM_SUPPLY("MICBIAS1", MADERA_MIC_BIAS_CTRL_1,
+		    MADERA_MICB1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2", MADERA_MIC_BIAS_CTRL_2,
+		    MADERA_MICB1_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_SUPPLY("MICBIAS1A", MADERA_MIC_BIAS_CTRL_5,
+		MADERA_MICB1A_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS1B", MADERA_MIC_BIAS_CTRL_5,
+		MADERA_MICB1B_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2A", MADERA_MIC_BIAS_CTRL_6,
+		MADERA_MICB2A_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2B", MADERA_MIC_BIAS_CTRL_6,
+		MADERA_MICB2B_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_SUPPLY("FXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_FX, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC1DECCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC1_DEC, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC1INTCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC1_INT, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC2DECCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC2_DEC, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC2INTCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC2_INT, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("OUTCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_OUT, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("SPDCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_SPD, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP1, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP2, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP3CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP3, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("AIF1TXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_AIF1, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("AIF2TXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_AIF2, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("AIF3TXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_AIF3, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("SLIMBUSCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_SLIMBUS, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("PWMCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_PWM, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+SND_SOC_DAPM_SIGGEN("TONE"),
+SND_SOC_DAPM_SIGGEN("NOISE"),
+
+SND_SOC_DAPM_INPUT("IN1AL"),
+SND_SOC_DAPM_INPUT("IN1AR"),
+SND_SOC_DAPM_INPUT("IN1BL"),
+SND_SOC_DAPM_INPUT("IN1BR"),
+SND_SOC_DAPM_INPUT("IN2L"),
+SND_SOC_DAPM_INPUT("IN2R"),
+
+SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
+SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
+
+SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),
+
+SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[0]),
+SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[1]),
+
+SND_SOC_DAPM_DEMUX("HPOUT1 Demux", SND_SOC_NOPM, 0, 0, &cs47l35_outdemux),
+
+SND_SOC_DAPM_PGA("PWM1 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM1_ENA_SHIFT,
+		 0, NULL, 0),
+SND_SOC_DAPM_PGA("PWM2 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM2_ENA_SHIFT,
+		 0, NULL, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX6_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
+		     MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
+		     MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX6_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
+		   MADERA_OUT1L_ENA_SHIFT, 0, NULL, 0, cs47l35_hp_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
+		   MADERA_OUT1R_ENA_SHIFT, 0, NULL, 0, cs47l35_hp_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
+		   MADERA_OUT4L_ENA_SHIFT, 0, NULL, 0, madera_spk_ev,
+		   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_PGA_E("OUT5L", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT5L_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT5R", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT5R_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+
+SND_SOC_DAPM_PGA("SPD1TX1", MADERA_SPD1_TX_CONTROL,
+		   MADERA_SPD1_VAL1_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("SPD1TX2", MADERA_SPD1_TX_CONTROL,
+		   MADERA_SPD1_VAL2_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_OUT_DRV("SPD1", MADERA_SPD1_TX_CONTROL,
+		     MADERA_SPD1_ENA_SHIFT, 0, NULL, 0),
+
+/*
+ * Input mux widgets arranged in order of sources in MADERA_MIXER_INPUT_ROUTES
+ * to take advantage of cache lookup in DAPM
+ */
+SND_SOC_DAPM_PGA("Noise Generator", MADERA_COMFORT_NOISE_GENERATOR,
+		 MADERA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("Tone Generator 1", MADERA_TONE_GENERATOR_1,
+		 MADERA_TONE1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Tone Generator 2", MADERA_TONE_GENERATOR_1,
+		 MADERA_TONE2_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_SIGGEN("HAPTICS"),
+
+SND_SOC_DAPM_MUX("AEC1 Loopback", MADERA_DAC_AEC_CONTROL_1,
+		       MADERA_AEC1_LOOPBACK_ENA_SHIFT, 0,
+		       &cs47l35_aec_loopback_mux),
+
+SND_SOC_DAPM_PGA_E("IN1L PGA", MADERA_INPUT_ENABLES, MADERA_IN1L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN1R PGA", MADERA_INPUT_ENABLES, MADERA_IN1R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN2L PGA", MADERA_INPUT_ENABLES, MADERA_IN2L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN2R PGA", MADERA_INPUT_ENABLES, MADERA_IN2R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+
+SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX6_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
+		    MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
+		    MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
+		    MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
+		    MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX5", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX6", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX6_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_PGA("EQ1", MADERA_EQ1_1, MADERA_EQ1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("EQ2", MADERA_EQ2_1, MADERA_EQ2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("EQ3", MADERA_EQ3_1, MADERA_EQ3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("EQ4", MADERA_EQ4_1, MADERA_EQ4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("DRC1L", MADERA_DRC1_CTRL1, MADERA_DRC1L_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("DRC1R", MADERA_DRC1_CTRL1, MADERA_DRC1R_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("DRC2L", MADERA_DRC2_CTRL1, MADERA_DRC2L_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("DRC2R", MADERA_DRC2_CTRL1, MADERA_DRC2R_ENA_SHIFT, 0,
+		 NULL, 0),
+
+SND_SOC_DAPM_PGA("LHPF1", MADERA_HPLPF1_1, MADERA_LHPF1_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("LHPF2", MADERA_HPLPF2_1, MADERA_LHPF2_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("LHPF3", MADERA_HPLPF3_1, MADERA_LHPF3_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("LHPF4", MADERA_HPLPF4_1, MADERA_LHPF4_ENA_SHIFT, 0,
+		 NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC1DEC1", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC2", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC3", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC4", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC1INT1", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT2", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT3", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT4", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC2DEC1", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC2", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC3", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC4", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC2INT1", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT2", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT3", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT4", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT4_ENA_SHIFT, 0, NULL, 0),
+
+WM_ADSP2("DSP1", 0, cs47l35_adsp_power_ev),
+WM_ADSP2("DSP2", 1, cs47l35_adsp_power_ev),
+WM_ADSP2("DSP3", 2, cs47l35_adsp_power_ev),
+
+/* End of ordered input mux widgets */
+
+MADERA_MIXER_WIDGETS(EQ1, "EQ1"),
+MADERA_MIXER_WIDGETS(EQ2, "EQ2"),
+MADERA_MIXER_WIDGETS(EQ3, "EQ3"),
+MADERA_MIXER_WIDGETS(EQ4, "EQ4"),
+
+MADERA_MIXER_WIDGETS(DRC1L, "DRC1L"),
+MADERA_MIXER_WIDGETS(DRC1R, "DRC1R"),
+MADERA_MIXER_WIDGETS(DRC2L, "DRC2L"),
+MADERA_MIXER_WIDGETS(DRC2R, "DRC2R"),
+
+SND_SOC_DAPM_SWITCH("DRC1 Activity Output", SND_SOC_NOPM, 0, 0,
+		    &madera_drc_activity_output_mux[0]),
+SND_SOC_DAPM_SWITCH("DRC2 Activity Output", SND_SOC_NOPM, 0, 0,
+		    &madera_drc_activity_output_mux[1]),
+
+MADERA_MIXER_WIDGETS(LHPF1, "LHPF1"),
+MADERA_MIXER_WIDGETS(LHPF2, "LHPF2"),
+MADERA_MIXER_WIDGETS(LHPF3, "LHPF3"),
+MADERA_MIXER_WIDGETS(LHPF4, "LHPF4"),
+
+MADERA_MIXER_WIDGETS(PWM1, "PWM1"),
+MADERA_MIXER_WIDGETS(PWM2, "PWM2"),
+
+MADERA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
+MADERA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
+MADERA_MIXER_WIDGETS(SPKOUT, "SPKOUT"),
+MADERA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
+MADERA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
+
+MADERA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
+MADERA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
+MADERA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
+MADERA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
+MADERA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
+MADERA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
+
+MADERA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
+MADERA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
+
+MADERA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
+MADERA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
+
+MADERA_MIXER_WIDGETS(SLIMTX1, "SLIMTX1"),
+MADERA_MIXER_WIDGETS(SLIMTX2, "SLIMTX2"),
+MADERA_MIXER_WIDGETS(SLIMTX3, "SLIMTX3"),
+MADERA_MIXER_WIDGETS(SLIMTX4, "SLIMTX4"),
+MADERA_MIXER_WIDGETS(SLIMTX5, "SLIMTX5"),
+MADERA_MIXER_WIDGETS(SLIMTX6, "SLIMTX6"),
+
+MADERA_MUX_WIDGETS(SPD1TX1, "SPDIF1TX1"),
+MADERA_MUX_WIDGETS(SPD1TX2, "SPDIF1TX2"),
+
+MADERA_DSP_WIDGETS(DSP1, "DSP1"),
+MADERA_DSP_WIDGETS(DSP2, "DSP2"),
+MADERA_DSP_WIDGETS(DSP3, "DSP3"),
+
+SND_SOC_DAPM_SWITCH("DSP1 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[0]),
+SND_SOC_DAPM_SWITCH("DSP2 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[1]),
+SND_SOC_DAPM_SWITCH("DSP3 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[2]),
+
+MADERA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
+MADERA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
+MADERA_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
+MADERA_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
+
+MADERA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
+MADERA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
+MADERA_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
+MADERA_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
+
+MADERA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
+MADERA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
+MADERA_MUX_WIDGETS(ISRC2DEC3, "ISRC2DEC3"),
+MADERA_MUX_WIDGETS(ISRC2DEC4, "ISRC2DEC4"),
+
+MADERA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
+MADERA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
+MADERA_MUX_WIDGETS(ISRC2INT3, "ISRC2INT3"),
+MADERA_MUX_WIDGETS(ISRC2INT4, "ISRC2INT4"),
+
+SND_SOC_DAPM_OUTPUT("HPOUTL"),
+SND_SOC_DAPM_OUTPUT("HPOUTR"),
+SND_SOC_DAPM_OUTPUT("EPOUTP"),
+SND_SOC_DAPM_OUTPUT("EPOUTN"),
+SND_SOC_DAPM_OUTPUT("SPKOUTN"),
+SND_SOC_DAPM_OUTPUT("SPKOUTP"),
+SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
+SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
+SND_SOC_DAPM_OUTPUT("SPDIF1"),
+
+SND_SOC_DAPM_OUTPUT("MICSUPP"),
+};
+
+#define MADERA_MIXER_INPUT_ROUTES(name)	\
+	{ name, "Noise Generator", "Noise Generator" }, \
+	{ name, "Tone Generator 1", "Tone Generator 1" }, \
+	{ name, "Tone Generator 2", "Tone Generator 2" }, \
+	{ name, "Haptics", "HAPTICS" }, \
+	{ name, "AEC1", "AEC1 Loopback" }, \
+	{ name, "IN1L", "IN1L PGA" }, \
+	{ name, "IN1R", "IN1R PGA" }, \
+	{ name, "IN2L", "IN2L PGA" }, \
+	{ name, "IN2R", "IN2R PGA" }, \
+	{ name, "AIF1RX1", "AIF1RX1" }, \
+	{ name, "AIF1RX2", "AIF1RX2" }, \
+	{ name, "AIF1RX3", "AIF1RX3" }, \
+	{ name, "AIF1RX4", "AIF1RX4" }, \
+	{ name, "AIF1RX5", "AIF1RX5" }, \
+	{ name, "AIF1RX6", "AIF1RX6" }, \
+	{ name, "AIF2RX1", "AIF2RX1" }, \
+	{ name, "AIF2RX2", "AIF2RX2" }, \
+	{ name, "AIF3RX1", "AIF3RX1" }, \
+	{ name, "AIF3RX2", "AIF3RX2" }, \
+	{ name, "SLIMRX1", "SLIMRX1" }, \
+	{ name, "SLIMRX2", "SLIMRX2" }, \
+	{ name, "SLIMRX3", "SLIMRX3" }, \
+	{ name, "SLIMRX4", "SLIMRX4" }, \
+	{ name, "SLIMRX5", "SLIMRX5" }, \
+	{ name, "SLIMRX6", "SLIMRX6" }, \
+	{ name, "EQ1", "EQ1" }, \
+	{ name, "EQ2", "EQ2" }, \
+	{ name, "EQ3", "EQ3" }, \
+	{ name, "EQ4", "EQ4" }, \
+	{ name, "DRC1L", "DRC1L" }, \
+	{ name, "DRC1R", "DRC1R" }, \
+	{ name, "DRC2L", "DRC2L" }, \
+	{ name, "DRC2R", "DRC2R" }, \
+	{ name, "LHPF1", "LHPF1" }, \
+	{ name, "LHPF2", "LHPF2" }, \
+	{ name, "LHPF3", "LHPF3" }, \
+	{ name, "LHPF4", "LHPF4" }, \
+	{ name, "ISRC1DEC1", "ISRC1DEC1" }, \
+	{ name, "ISRC1DEC2", "ISRC1DEC2" }, \
+	{ name, "ISRC1DEC3", "ISRC1DEC3" }, \
+	{ name, "ISRC1DEC4", "ISRC1DEC4" }, \
+	{ name, "ISRC1INT1", "ISRC1INT1" }, \
+	{ name, "ISRC1INT2", "ISRC1INT2" }, \
+	{ name, "ISRC1INT3", "ISRC1INT3" }, \
+	{ name, "ISRC1INT4", "ISRC1INT4" }, \
+	{ name, "ISRC2DEC1", "ISRC2DEC1" }, \
+	{ name, "ISRC2DEC2", "ISRC2DEC2" }, \
+	{ name, "ISRC2DEC3", "ISRC2DEC3" }, \
+	{ name, "ISRC2DEC4", "ISRC2DEC4" }, \
+	{ name, "ISRC2INT1", "ISRC2INT1" }, \
+	{ name, "ISRC2INT2", "ISRC2INT2" }, \
+	{ name, "ISRC2INT3", "ISRC2INT3" }, \
+	{ name, "ISRC2INT4", "ISRC2INT4" }, \
+	{ name, "DSP1.1", "DSP1" }, \
+	{ name, "DSP1.2", "DSP1" }, \
+	{ name, "DSP1.3", "DSP1" }, \
+	{ name, "DSP1.4", "DSP1" }, \
+	{ name, "DSP1.5", "DSP1" }, \
+	{ name, "DSP1.6", "DSP1" }, \
+	{ name, "DSP2.1", "DSP2" }, \
+	{ name, "DSP2.2", "DSP2" }, \
+	{ name, "DSP2.3", "DSP2" }, \
+	{ name, "DSP2.4", "DSP2" }, \
+	{ name, "DSP2.5", "DSP2" }, \
+	{ name, "DSP2.6", "DSP2" }, \
+	{ name, "DSP3.1", "DSP3" }, \
+	{ name, "DSP3.2", "DSP3" }, \
+	{ name, "DSP3.3", "DSP3" }, \
+	{ name, "DSP3.4", "DSP3" }, \
+	{ name, "DSP3.5", "DSP3" }, \
+	{ name, "DSP3.6", "DSP3" }
+
+static const struct snd_soc_dapm_route cs47l35_dapm_routes[] = {
+	/* Internal clock domains */
+	{ "EQ1", NULL, "FXCLK" },
+	{ "EQ2", NULL, "FXCLK" },
+	{ "EQ3", NULL, "FXCLK" },
+	{ "EQ4", NULL, "FXCLK" },
+	{ "DRC1L", NULL, "FXCLK" },
+	{ "DRC1R", NULL, "FXCLK" },
+	{ "DRC2L", NULL, "FXCLK" },
+	{ "DRC2R", NULL, "FXCLK" },
+	{ "LHPF1", NULL, "FXCLK" },
+	{ "LHPF2", NULL, "FXCLK" },
+	{ "LHPF3", NULL, "FXCLK" },
+	{ "LHPF4", NULL, "FXCLK" },
+	{ "PWM1 Mixer", NULL, "PWMCLK" },
+	{ "PWM2 Mixer", NULL, "PWMCLK" },
+	{ "OUT1L", NULL, "OUTCLK" },
+	{ "OUT1R", NULL, "OUTCLK" },
+	{ "OUT4L", NULL, "OUTCLK" },
+	{ "OUT5L", NULL, "OUTCLK" },
+	{ "OUT5R", NULL, "OUTCLK" },
+	{ "AIF1TX1", NULL, "AIF1TXCLK" },
+	{ "AIF1TX2", NULL, "AIF1TXCLK" },
+	{ "AIF1TX3", NULL, "AIF1TXCLK" },
+	{ "AIF1TX4", NULL, "AIF1TXCLK" },
+	{ "AIF1TX5", NULL, "AIF1TXCLK" },
+	{ "AIF1TX6", NULL, "AIF1TXCLK" },
+	{ "AIF2TX1", NULL, "AIF2TXCLK" },
+	{ "AIF2TX2", NULL, "AIF2TXCLK" },
+	{ "AIF3TX1", NULL, "AIF3TXCLK" },
+	{ "AIF3TX2", NULL, "AIF3TXCLK" },
+	{ "SLIMTX1", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX2", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX3", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX4", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX5", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX6", NULL, "SLIMBUSCLK" },
+	{ "SPD1TX1", NULL, "SPDCLK" },
+	{ "SPD1TX2", NULL, "SPDCLK" },
+	{ "DSP1", NULL, "DSP1CLK" },
+	{ "DSP2", NULL, "DSP2CLK" },
+	{ "DSP3", NULL, "DSP3CLK" },
+	{ "ISRC1DEC1", NULL, "ISRC1DECCLK" },
+	{ "ISRC1DEC2", NULL, "ISRC1DECCLK" },
+	{ "ISRC1DEC3", NULL, "ISRC1DECCLK" },
+	{ "ISRC1DEC4", NULL, "ISRC1DECCLK" },
+	{ "ISRC1INT1", NULL, "ISRC1INTCLK" },
+	{ "ISRC1INT2", NULL, "ISRC1INTCLK" },
+	{ "ISRC1INT3", NULL, "ISRC1INTCLK" },
+	{ "ISRC1INT4", NULL, "ISRC1INTCLK" },
+	{ "ISRC2DEC1", NULL, "ISRC2DECCLK" },
+	{ "ISRC2DEC2", NULL, "ISRC2DECCLK" },
+	{ "ISRC2DEC3", NULL, "ISRC2DECCLK" },
+	{ "ISRC2DEC4", NULL, "ISRC2DECCLK" },
+	{ "ISRC2INT1", NULL, "ISRC2INTCLK" },
+	{ "ISRC2INT2", NULL, "ISRC2INTCLK" },
+	{ "ISRC2INT3", NULL, "ISRC2INTCLK" },
+	{ "ISRC2INT4", NULL, "ISRC2INTCLK" },
+
+	{ "AIF2 Capture", NULL, "DBVDD2" },
+	{ "AIF2 Playback", NULL, "DBVDD2" },
+
+	{ "AIF3 Capture", NULL, "DBVDD2" },
+	{ "AIF3 Playback", NULL, "DBVDD2" },
+
+	{ "OUT1L", NULL, "CPVDD1" },
+	{ "OUT1R", NULL, "CPVDD1" },
+	{ "OUT1L", NULL, "CPVDD2" },
+	{ "OUT1R", NULL, "CPVDD2" },
+
+	{ "OUT4L", NULL, "SPKVDD" },
+
+	{ "OUT1L", NULL, "SYSCLK" },
+	{ "OUT1R", NULL, "SYSCLK" },
+	{ "OUT4L", NULL, "SYSCLK" },
+	{ "OUT5L", NULL, "SYSCLK" },
+	{ "OUT5R", NULL, "SYSCLK" },
+
+	{ "SPD1", NULL, "SYSCLK" },
+	{ "SPD1", NULL, "SPD1TX1" },
+	{ "SPD1", NULL, "SPD1TX2" },
+
+	{ "IN1AL", NULL, "SYSCLK" },
+	{ "IN1AR", NULL, "SYSCLK" },
+	{ "IN1BL", NULL, "SYSCLK" },
+	{ "IN1BR", NULL, "SYSCLK" },
+	{ "IN2L", NULL, "SYSCLK" },
+	{ "IN2R", NULL, "SYSCLK" },
+
+	{ "MICBIAS1", NULL, "MICVDD" },
+	{ "MICBIAS2", NULL, "MICVDD" },
+
+	{ "MICBIAS1A", NULL, "MICBIAS1" },
+	{ "MICBIAS1B", NULL, "MICBIAS1" },
+	{ "MICBIAS2A", NULL, "MICBIAS2" },
+	{ "MICBIAS2B", NULL, "MICBIAS2" },
+
+	{ "Noise Generator", NULL, "SYSCLK" },
+	{ "Tone Generator 1", NULL, "SYSCLK" },
+	{ "Tone Generator 2", NULL, "SYSCLK" },
+
+	{ "Noise Generator", NULL, "NOISE" },
+	{ "Tone Generator 1", NULL, "TONE" },
+	{ "Tone Generator 2", NULL, "TONE" },
+
+	{ "AIF1 Capture", NULL, "AIF1TX1" },
+	{ "AIF1 Capture", NULL, "AIF1TX2" },
+	{ "AIF1 Capture", NULL, "AIF1TX3" },
+	{ "AIF1 Capture", NULL, "AIF1TX4" },
+	{ "AIF1 Capture", NULL, "AIF1TX5" },
+	{ "AIF1 Capture", NULL, "AIF1TX6" },
+
+	{ "AIF1RX1", NULL, "AIF1 Playback" },
+	{ "AIF1RX2", NULL, "AIF1 Playback" },
+	{ "AIF1RX3", NULL, "AIF1 Playback" },
+	{ "AIF1RX4", NULL, "AIF1 Playback" },
+	{ "AIF1RX5", NULL, "AIF1 Playback" },
+	{ "AIF1RX6", NULL, "AIF1 Playback" },
+
+	{ "AIF2 Capture", NULL, "AIF2TX1" },
+	{ "AIF2 Capture", NULL, "AIF2TX2" },
+
+	{ "AIF2RX1", NULL, "AIF2 Playback" },
+	{ "AIF2RX2", NULL, "AIF2 Playback" },
+
+	{ "AIF3 Capture", NULL, "AIF3TX1" },
+	{ "AIF3 Capture", NULL, "AIF3TX2" },
+
+	{ "AIF3RX1", NULL, "AIF3 Playback" },
+	{ "AIF3RX2", NULL, "AIF3 Playback" },
+
+	{ "Slim1 Capture", NULL, "SLIMTX1" },
+	{ "Slim1 Capture", NULL, "SLIMTX2" },
+	{ "Slim1 Capture", NULL, "SLIMTX3" },
+	{ "Slim1 Capture", NULL, "SLIMTX4" },
+
+	{ "SLIMRX1", NULL, "Slim1 Playback" },
+	{ "SLIMRX2", NULL, "Slim1 Playback" },
+	{ "SLIMRX3", NULL, "Slim1 Playback" },
+	{ "SLIMRX4", NULL, "Slim1 Playback" },
+
+	{ "Slim2 Capture", NULL, "SLIMTX5" },
+	{ "Slim2 Capture", NULL, "SLIMTX6" },
+
+	{ "SLIMRX5", NULL, "Slim2 Playback" },
+	{ "SLIMRX6", NULL, "Slim2 Playback" },
+
+	{ "AIF1 Playback", NULL, "SYSCLK" },
+	{ "AIF2 Playback", NULL, "SYSCLK" },
+	{ "AIF3 Playback", NULL, "SYSCLK" },
+	{ "Slim1 Playback", NULL, "SYSCLK" },
+	{ "Slim2 Playback", NULL, "SYSCLK" },
+
+	{ "AIF1 Capture", NULL, "SYSCLK" },
+	{ "AIF2 Capture", NULL, "SYSCLK" },
+	{ "AIF3 Capture", NULL, "SYSCLK" },
+	{ "Slim1 Capture", NULL, "SYSCLK" },
+	{ "Slim2 Capture", NULL, "SYSCLK" },
+
+	{ "Voice Control DSP", NULL, "DSP3" },
+
+	{ "Audio Trace DSP", NULL, "DSP1" },
+
+	{ "IN1L Mux", "A", "IN1AL" },
+	{ "IN1L Mux", "B", "IN1BL" },
+	{ "IN1R Mux", "A", "IN1AR" },
+	{ "IN1R Mux", "B", "IN1BR" },
+
+	{ "IN1L PGA", NULL, "IN1L Mux" },
+	{ "IN1R PGA", NULL, "IN1R Mux" },
+
+	{ "IN2L PGA", NULL, "IN2L" },
+	{ "IN2R PGA", NULL, "IN2R" },
+
+	MADERA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
+	MADERA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
+
+	MADERA_MIXER_ROUTES("OUT4L", "SPKOUT"),
+
+	MADERA_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
+	MADERA_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
+
+	MADERA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
+	MADERA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
+
+	MADERA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
+	MADERA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
+	MADERA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
+	MADERA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
+	MADERA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
+	MADERA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
+
+	MADERA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
+	MADERA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
+
+	MADERA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
+	MADERA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
+
+	MADERA_MIXER_ROUTES("SLIMTX1", "SLIMTX1"),
+	MADERA_MIXER_ROUTES("SLIMTX2", "SLIMTX2"),
+	MADERA_MIXER_ROUTES("SLIMTX3", "SLIMTX3"),
+	MADERA_MIXER_ROUTES("SLIMTX4", "SLIMTX4"),
+	MADERA_MIXER_ROUTES("SLIMTX5", "SLIMTX5"),
+	MADERA_MIXER_ROUTES("SLIMTX6", "SLIMTX6"),
+
+	MADERA_MUX_ROUTES("SPD1TX1", "SPDIF1TX1"),
+	MADERA_MUX_ROUTES("SPD1TX2", "SPDIF1TX2"),
+
+	MADERA_MIXER_ROUTES("EQ1", "EQ1"),
+	MADERA_MIXER_ROUTES("EQ2", "EQ2"),
+	MADERA_MIXER_ROUTES("EQ3", "EQ3"),
+	MADERA_MIXER_ROUTES("EQ4", "EQ4"),
+
+	MADERA_MIXER_ROUTES("DRC1L", "DRC1L"),
+	MADERA_MIXER_ROUTES("DRC1R", "DRC1R"),
+	MADERA_MIXER_ROUTES("DRC2L", "DRC2L"),
+	MADERA_MIXER_ROUTES("DRC2R", "DRC2R"),
+
+	MADERA_MIXER_ROUTES("LHPF1", "LHPF1"),
+	MADERA_MIXER_ROUTES("LHPF2", "LHPF2"),
+	MADERA_MIXER_ROUTES("LHPF3", "LHPF3"),
+	MADERA_MIXER_ROUTES("LHPF4", "LHPF4"),
+
+	MADERA_DSP_ROUTES("DSP1"),
+	MADERA_DSP_ROUTES("DSP2"),
+	MADERA_DSP_ROUTES("DSP3"),
+
+	{ "DSP Trigger Out", NULL, "DSP1 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP2 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP3 Trigger Output" },
+
+	{ "DSP1 Trigger Output", "Switch", "DSP1" },
+	{ "DSP2 Trigger Output", "Switch", "DSP2" },
+	{ "DSP3 Trigger Output", "Switch", "DSP3" },
+
+	MADERA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
+	MADERA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
+	MADERA_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
+	MADERA_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
+
+	MADERA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
+	MADERA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
+	MADERA_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
+	MADERA_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
+
+	MADERA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
+	MADERA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
+	MADERA_MUX_ROUTES("ISRC2INT3", "ISRC2INT3"),
+	MADERA_MUX_ROUTES("ISRC2INT4", "ISRC2INT4"),
+
+	MADERA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
+	MADERA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
+	MADERA_MUX_ROUTES("ISRC2DEC3", "ISRC2DEC3"),
+	MADERA_MUX_ROUTES("ISRC2DEC4", "ISRC2DEC4"),
+
+	{ "AEC1 Loopback", "HPOUT1L", "OUT1L" },
+	{ "AEC1 Loopback", "HPOUT1R", "OUT1R" },
+	{ "HPOUT1 Demux", NULL, "OUT1L" },
+	{ "HPOUT1 Demux", NULL, "OUT1R" },
+
+	{ "AEC1 Loopback", "SPKOUT", "OUT4L" },
+	{ "SPKOUTN", NULL, "OUT4L" },
+	{ "SPKOUTP", NULL, "OUT4L" },
+
+	{ "HPOUTL", "HPOUT", "HPOUT1 Demux" },
+	{ "HPOUTR", "HPOUT", "HPOUT1 Demux" },
+	{ "EPOUTP", "EPOUT", "HPOUT1 Demux" },
+	{ "EPOUTN", "EPOUT", "HPOUT1 Demux" },
+
+	{ "AEC1 Loopback", "SPKDAT1L", "OUT5L" },
+	{ "AEC1 Loopback", "SPKDAT1R", "OUT5R" },
+	{ "SPKDAT1L", NULL, "OUT5L" },
+	{ "SPKDAT1R", NULL, "OUT5R" },
+
+	{ "SPDIF1", NULL, "SPD1" },
+
+	{ "MICSUPP", NULL, "SYSCLK" },
+
+	{ "DRC1 Signal Activity", NULL, "DRC1 Activity Output" },
+	{ "DRC2 Signal Activity", NULL, "DRC2 Activity Output" },
+	{ "DRC1 Activity Output", "Switch", "DRC1L" },
+	{ "DRC1 Activity Output", "Switch", "DRC1R" },
+	{ "DRC2 Activity Output", "Switch", "DRC2L" },
+	{ "DRC2 Activity Output", "Switch", "DRC2R" },
+};
+
+static int cs47l35_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+			  unsigned int fref, unsigned int fout)
+{
+	struct cs47l35 *cs47l35 = snd_soc_codec_get_drvdata(codec);
+
+	switch (fll_id) {
+	case MADERA_FLL1_REFCLK:
+		return madera_set_fll_refclk(&cs47l35->fll, source, fref,
+					     fout);
+	case MADERA_FLL1_SYNCCLK:
+		return madera_set_fll_syncclk(&cs47l35->fll, source, fref,
+					      fout);
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct snd_soc_dai_driver cs47l35_dai[] = {
+	{
+		.name = "cs47l35-aif1",
+		.id = 1,
+		.base = MADERA_AIF1_BCLK_CTRL,
+		.playback = {
+			.stream_name = "AIF1 Playback",
+			.channels_min = 1,
+			.channels_max = 6,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AIF1 Capture",
+			.channels_min = 1,
+			.channels_max = 6,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_dai_ops,
+		.symmetric_rates = 1,
+		.symmetric_samplebits = 1,
+	},
+	{
+		.name = "cs47l35-aif2",
+		.id = 2,
+		.base = MADERA_AIF2_BCLK_CTRL,
+		.playback = {
+			.stream_name = "AIF2 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AIF2 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_dai_ops,
+		.symmetric_rates = 1,
+		.symmetric_samplebits = 1,
+	},
+	{
+		.name = "cs47l35-aif3",
+		.id = 3,
+		.base = MADERA_AIF3_BCLK_CTRL,
+		.playback = {
+			.stream_name = "AIF3 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AIF3 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_dai_ops,
+		.symmetric_rates = 1,
+		.symmetric_samplebits = 1,
+	},
+	{
+		.name = "cs47l35-slim1",
+		.id = 4,
+		.playback = {
+			.stream_name = "Slim1 Playback",
+			.channels_min = 1,
+			.channels_max = 4,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "Slim1 Capture",
+			.channels_min = 1,
+			.channels_max = 4,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_simple_dai_ops,
+	},
+	{
+		.name = "cs47l35-slim2",
+		.id = 5,
+		.playback = {
+			.stream_name = "Slim2 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "Slim2 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_simple_dai_ops,
+	},
+	{
+		.name = "cs47l35-cpu-voicectrl",
+		.capture = {
+			.stream_name = "Voice Control CPU",
+			.channels_min = 1,
+			.channels_max = 1,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.compress_new = snd_soc_new_compress,
+	},
+	{
+		.name = "cs47l35-dsp-voicectrl",
+		.capture = {
+			.stream_name = "Voice Control DSP",
+			.channels_min = 1,
+			.channels_max = 1,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+	},
+	{
+		.name = "cs47l35-cpu-trace",
+		.capture = {
+			.stream_name = "Audio Trace CPU",
+			.channels_min = 1,
+			.channels_max = 6,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.compress_new = snd_soc_new_compress,
+	},
+	{
+		.name = "cs47l35-dsp-trace",
+		.capture = {
+			.stream_name = "Audio Trace DSP",
+			.channels_min = 1,
+			.channels_max = 6,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+	},
+};
+
+static int cs47l35_open(struct snd_compr_stream *stream)
+{
+	struct snd_soc_pcm_runtime *rtd = stream->private_data;
+	struct cs47l35 *cs47l35 = snd_soc_platform_get_drvdata(rtd->platform);
+	struct madera_priv *priv = &cs47l35->core;
+	struct madera *madera = priv->madera;
+	int n_adsp;
+
+	if (strcmp(rtd->codec_dai->name, "cs47l35-dsp-voicectrl") == 0) {
+		n_adsp = 2;
+	} else if (strcmp(rtd->codec_dai->name, "cs47l35-dsp-trace") == 0) {
+		n_adsp = 0;
+	} else {
+		dev_err(madera->dev,
+			"No suitable compressed stream for DAI '%s'\n",
+			rtd->codec_dai->name);
+		return -EINVAL;
+	}
+
+	return wm_adsp_compr_open(&priv->adsp[n_adsp], stream);
+}
+
+static irqreturn_t cs47l35_adsp2_irq(int irq, void *data)
+{
+	struct cs47l35 *cs47l35 = data;
+	struct madera_priv *priv = &cs47l35->core;
+	struct madera *madera = priv->madera;
+	struct madera_voice_trigger_info trig_info;
+	int serviced = 0;
+	int i, ret;
+
+	for (i = 0; i < CS47L35_NUM_ADSP; ++i) {
+		ret = wm_adsp_compr_handle_irq(&priv->adsp[i]);
+		if (ret != -ENODEV)
+			serviced++;
+		if (ret == WM_ADSP_COMPR_VOICE_TRIGGER) {
+			trig_info.core_num = i + 1;
+			madera_call_notifiers(madera,
+					      MADERA_NOTIFY_VOICE_TRIGGER,
+					      &trig_info);
+		}
+	}
+
+	if (!serviced) {
+		dev_err(madera->dev, "Spurious compressed data IRQ\n");
+		return IRQ_NONE;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static const char * const cs47l35_dmic_refs[] = {
+	"MICVDD",
+	"MICBIAS1B",
+	"MICBIAS2A",
+	"MICBIAS2B",
+};
+
+static const char * const cs47l35_dmic_inputs[] = {
+	"IN1L Mux",
+	"IN1R Mux",
+	"IN2L",
+	"IN2R",
+};
+
+static int cs47l35_codec_probe(struct snd_soc_codec *codec)
+{
+	struct cs47l35 *cs47l35 = snd_soc_codec_get_drvdata(codec);
+	struct madera *madera = cs47l35->core.madera;
+	int i, ret;
+
+	madera->dapm = snd_soc_codec_get_dapm(codec);
+
+	ret = madera_init_inputs(codec,
+				 cs47l35_dmic_inputs,
+				 ARRAY_SIZE(cs47l35_dmic_inputs),
+				 cs47l35_dmic_refs,
+				 ARRAY_SIZE(cs47l35_dmic_refs));
+	if (ret)
+		return ret;
+
+	ret = madera_init_outputs(codec, CS47L35_MONO_OUTPUTS);
+	if (ret)
+		return ret;
+
+	snd_soc_component_disable_pin(snd_soc_dapm_to_component(madera->dapm),
+				      "HAPTICS");
+
+	ret = snd_soc_add_codec_controls(codec, madera_adsp_rate_controls,
+					 CS47L35_NUM_ADSP);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < CS47L35_NUM_ADSP; i++)
+		wm_adsp2_codec_probe(&cs47l35->core.adsp[i], codec);
+
+	return 0;
+}
+
+static int cs47l35_codec_remove(struct snd_soc_codec *codec)
+{
+	struct cs47l35 *cs47l35 = snd_soc_codec_get_drvdata(codec);
+	int i;
+
+	for (i = 0; i < CS47L35_NUM_ADSP; i++)
+		wm_adsp2_codec_remove(&cs47l35->core.adsp[i], codec);
+
+	cs47l35->core.madera->dapm = NULL;
+
+	return 0;
+}
+
+#define CS47L35_DIG_VU 0x0200
+
+static unsigned int cs47l35_digital_vu[] = {
+	MADERA_DAC_DIGITAL_VOLUME_1L,
+	MADERA_DAC_DIGITAL_VOLUME_1R,
+	MADERA_DAC_DIGITAL_VOLUME_4L,
+	MADERA_DAC_DIGITAL_VOLUME_5L,
+	MADERA_DAC_DIGITAL_VOLUME_5R,
+};
+
+static struct regmap *cs47l35_get_regmap(struct device *dev)
+{
+	struct cs47l35 *priv = dev_get_drvdata(dev);
+
+	return priv->core.madera->regmap;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_cs47l35 = {
+	.probe = cs47l35_codec_probe,
+	.remove = cs47l35_codec_remove,
+	.get_regmap = cs47l35_get_regmap,
+
+	.idle_bias_off = true,
+
+	.set_sysclk = madera_set_sysclk,
+	.set_pll = cs47l35_set_fll,
+
+	.component_driver = {
+		.controls = cs47l35_snd_controls,
+		.num_controls = ARRAY_SIZE(cs47l35_snd_controls),
+		.dapm_widgets = cs47l35_dapm_widgets,
+		.num_dapm_widgets = ARRAY_SIZE(cs47l35_dapm_widgets),
+		.dapm_routes = cs47l35_dapm_routes,
+		.num_dapm_routes = ARRAY_SIZE(cs47l35_dapm_routes),
+	},
+};
+
+static struct snd_compr_ops cs47l35_compr_ops = {
+	.open = cs47l35_open,
+	.free = wm_adsp_compr_free,
+	.set_params = wm_adsp_compr_set_params,
+	.get_caps = wm_adsp_compr_get_caps,
+	.trigger = wm_adsp_compr_trigger,
+	.pointer = wm_adsp_compr_pointer,
+	.copy = wm_adsp_compr_copy,
+};
+
+static struct snd_soc_platform_driver cs47l35_compr_platform = {
+	.compr_ops = &cs47l35_compr_ops,
+};
+
+static int cs47l35_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	struct cs47l35 *cs47l35;
+	int i, ret;
+
+	BUILD_BUG_ON(ARRAY_SIZE(cs47l35_dai) > MADERA_MAX_DAI);
+
+	/* quick exit if Madera irqchip driver hasn't completed probe */
+	if (!madera->irq_dev) {
+		dev_dbg(&pdev->dev, "irqchip driver not ready\n");
+		return -EPROBE_DEFER;
+	}
+
+	cs47l35 = devm_kzalloc(&pdev->dev, sizeof(struct cs47l35), GFP_KERNEL);
+	if (!cs47l35)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, cs47l35);
+
+	cs47l35->core.madera = madera;
+	cs47l35->core.dev = &pdev->dev;
+	cs47l35->core.num_inputs = 4;
+
+	ret = madera_core_init(&cs47l35->core);
+	if (ret)
+		return ret;
+
+	ret = madera_init_overheat(&cs47l35->core);
+	if (ret)
+		return ret;
+
+	ret = madera_request_irq(madera, MADERA_IRQ_DSP_IRQ1,
+				 "ADSP2 Compressed IRQ", cs47l35_adsp2_irq,
+				 cs47l35);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request DSP IRQ: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < CS47L35_NUM_ADSP; i++) {
+		cs47l35->core.adsp[i].part = "cs47l35";
+		cs47l35->core.adsp[i].num = i + 1;
+		cs47l35->core.adsp[i].type = WMFW_ADSP2;
+		cs47l35->core.adsp[i].rev = 1;
+		cs47l35->core.adsp[i].dev = madera->dev;
+		cs47l35->core.adsp[i].regmap = madera->regmap_32bit;
+
+		cs47l35->core.adsp[i].base = wm_adsp2_control_bases[i];
+		cs47l35->core.adsp[i].mem = cs47l35_dsp_regions[i];
+		cs47l35->core.adsp[i].num_mems
+			= ARRAY_SIZE(cs47l35_dsp1_regions);
+
+		ret = wm_adsp2_init(&cs47l35->core.adsp[i]);
+		if (ret != 0) {
+			for (--i; i >= 0; --i)
+				wm_adsp2_remove(&cs47l35->core.adsp[i]);
+			goto error_core;
+		}
+	}
+
+	madera_init_fll(madera, 1, MADERA_FLL1_CONTROL_1 - 1, &cs47l35->fll);
+
+	for (i = 0; i < ARRAY_SIZE(cs47l35_dai); i++)
+		madera_init_dai(&cs47l35->core, i);
+
+	/* Latch volume update bits */
+	for (i = 0; i < ARRAY_SIZE(cs47l35_digital_vu); i++)
+		regmap_update_bits(madera->regmap, cs47l35_digital_vu[i],
+				   CS47L35_DIG_VU, CS47L35_DIG_VU);
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_idle(&pdev->dev);
+
+	ret = snd_soc_register_platform(&pdev->dev, &cs47l35_compr_platform);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
+		goto error;
+	}
+
+	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l35,
+				      cs47l35_dai, ARRAY_SIZE(cs47l35_dai));
+	if (ret < 0) {
+		dev_err(&pdev->dev,
+			"Failed to register codec: %d\n",
+			ret);
+		snd_soc_unregister_platform(&pdev->dev);
+		goto error;
+	}
+
+	return ret;
+
+error:
+	for (i = 0; i < CS47L35_NUM_ADSP; i++)
+		wm_adsp2_remove(&cs47l35->core.adsp[i]);
+error_core:
+	madera_core_destroy(&cs47l35->core);
+
+	return ret;
+}
+
+static int cs47l35_remove(struct platform_device *pdev)
+{
+	struct cs47l35 *cs47l35 = platform_get_drvdata(pdev);
+	int i;
+
+	snd_soc_unregister_platform(&pdev->dev);
+	snd_soc_unregister_codec(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
+	for (i = 0; i < CS47L35_NUM_ADSP; i++)
+		wm_adsp2_remove(&cs47l35->core.adsp[i]);
+
+	madera_free_irq(cs47l35->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l35);
+	madera_free_overheat(&cs47l35->core);
+	madera_core_destroy(&cs47l35->core);
+
+	return 0;
+}
+
+static struct platform_driver cs47l35_codec_driver = {
+	.driver = {
+		.name = "cs47l35-codec",
+	},
+	.probe = cs47l35_probe,
+	.remove = cs47l35_remove,
+};
+
+module_platform_driver(cs47l35_codec_driver);
+
+MODULE_DESCRIPTION("ASoC CS47L35 driver");
+MODULE_AUTHOR("Piotr Stankiewicz <piotrs@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:cs47l35-codec");
-- 
1.9.1


^ permalink raw reply related

* [PATCH v2 17/18] ASoC: cs47l85: Add codec driver for Cirrus Logic CS47L85
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones, broonie, linus.walleij, gnurou, robh+dt, tglx, jason
  Cc: alsa-devel, patches, linux-gpio, devicetree, linux-kernel
In-Reply-To: <1493050124-5970-1-git-send-email-rf@opensource.wolfsonmicro.com>

Adds the codec driver for the CS47L85 SmartCodec. This is a
multi-functional codec based on the Cirrus Logic Madera platform.

Signed-off-by: Nariman Poushin <npoushin@opensource.wolfsonmicro.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
No changes since V1

 sound/soc/codecs/Kconfig   |    6 +
 sound/soc/codecs/Makefile  |    2 +
 sound/soc/codecs/cs47l85.c | 2706 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 2714 insertions(+)
 create mode 100644 sound/soc/codecs/cs47l85.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index f502fec..8b8e06c 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -63,6 +63,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_CS4349 if I2C
 	select SND_SOC_CS47L24 if MFD_CS47L24
 	select SND_SOC_CS47L35 if MFD_CS47L35
+	select SND_SOC_CS47L85 if MFD_CS47L85
 	select SND_SOC_CS53L30 if I2C
 	select SND_SOC_CX20442 if TTY
 	select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
@@ -498,6 +499,9 @@ config SND_SOC_CS47L24
 config SND_SOC_CS47L35
 	tristate
 
+config SND_SOC_CS47L85
+	tristate
+
 # Cirrus Logic Quad-Channel ADC
 config SND_SOC_CS53L30
 	tristate "Cirrus Logic CS53L30 CODEC"
@@ -586,7 +590,9 @@ config SND_SOC_LM49453
 config SND_SOC_MADERA
 	tristate
 	default y if SND_SOC_CS47L35=y
+	default y if SND_SOC_CS47L85=y
 	default m if SND_SOC_CS47L35=m
+	default m if SND_SOC_CS47L85=m
 
 config SND_SOC_MAX98088
        tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 9c578e1..1991b79 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -56,6 +56,7 @@ snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
 snd-soc-cs4349-objs := cs4349.o
 snd-soc-cs47l24-objs := cs47l24.o
 snd-soc-cs47l35-objs := cs47l35.o
+snd-soc-cs47l85-objs := cs47l85.o
 snd-soc-cs53l30-objs := cs53l30.o
 snd-soc-cx20442-objs := cx20442.o
 snd-soc-da7210-objs := da7210.o
@@ -292,6 +293,7 @@ obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o
 obj-$(CONFIG_SND_SOC_CS4349)	+= snd-soc-cs4349.o
 obj-$(CONFIG_SND_SOC_CS47L24)	+= snd-soc-cs47l24.o
 obj-$(CONFIG_SND_SOC_CS47L35)	+= snd-soc-cs47l35.o
+obj-$(CONFIG_SND_SOC_CS47L85)	+= snd-soc-cs47l85.o
 obj-$(CONFIG_SND_SOC_CS53L30)	+= snd-soc-cs53l30.o
 obj-$(CONFIG_SND_SOC_CX20442)	+= snd-soc-cx20442.o
 obj-$(CONFIG_SND_SOC_DA7210)	+= snd-soc-da7210.o
diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c
new file mode 100644
index 0000000..9fe76ec
--- /dev/null
+++ b/sound/soc/codecs/cs47l85.c
@@ -0,0 +1,2706 @@
+/*
+ * cs47l85.c  --  ALSA SoC Audio driver for CS47L85 codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/registers.h>
+
+#include "madera.h"
+#include "wm_adsp.h"
+
+#define CS47L85_NUM_ADSP	7
+#define CS47L85_MONO_OUTPUTS	4
+
+struct cs47l85 {
+	struct madera_priv core;
+	struct madera_fll fll[3];
+};
+
+static const struct wm_adsp_region cs47l85_dsp1_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x080000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x0e0000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x0a0000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x0c0000 },
+};
+
+static const struct wm_adsp_region cs47l85_dsp2_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x100000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x160000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x120000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x140000 },
+};
+
+static const struct wm_adsp_region cs47l85_dsp3_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x180000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x1e0000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x1a0000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x1c0000 },
+};
+
+static const struct wm_adsp_region cs47l85_dsp4_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x200000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x260000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x220000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x240000 },
+};
+
+static const struct wm_adsp_region cs47l85_dsp5_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x280000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x2e0000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x2a0000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x2c0000 },
+};
+
+static const struct wm_adsp_region cs47l85_dsp6_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x300000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x360000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x320000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x340000 },
+};
+
+static const struct wm_adsp_region cs47l85_dsp7_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x380000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x3e0000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x3a0000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x3c0000 },
+};
+
+static const struct wm_adsp_region *cs47l85_dsp_regions[] = {
+	cs47l85_dsp1_regions,
+	cs47l85_dsp2_regions,
+	cs47l85_dsp3_regions,
+	cs47l85_dsp4_regions,
+	cs47l85_dsp5_regions,
+	cs47l85_dsp6_regions,
+	cs47l85_dsp7_regions,
+};
+
+static const unsigned int wm_adsp2_control_bases[] = {
+	MADERA_DSP1_CONFIG_1,
+	MADERA_DSP2_CONFIG_1,
+	MADERA_DSP3_CONFIG_1,
+	MADERA_DSP4_CONFIG_1,
+	MADERA_DSP5_CONFIG_1,
+	MADERA_DSP6_CONFIG_1,
+	MADERA_DSP7_CONFIG_1,
+};
+
+static int cs47l85_adsp_power_ev(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kcontrol,
+				 int event)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct cs47l85 *cs47l85 = snd_soc_codec_get_drvdata(codec);
+	struct madera_priv *priv = &cs47l85->core;
+	struct madera *madera = priv->madera;
+	unsigned int freq;
+	int ret;
+
+	ret = regmap_read(madera->regmap, MADERA_DSP_CLOCK_1, &freq);
+	if (ret != 0) {
+		dev_err(madera->dev,
+			"Failed to read MADERA_DSP_CLOCK_1: %d\n", ret);
+		return ret;
+	}
+
+	freq &= MADERA_DSP_CLK_FREQ_LEGACY_MASK;
+	freq >>= MADERA_DSP_CLK_FREQ_LEGACY_SHIFT;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		ret = madera_set_adsp_clk(&cs47l85->core, w->shift, freq);
+		if (ret)
+			return ret;
+		break;
+	default:
+		break;
+	}
+
+	return wm_adsp2_early_event(w, kcontrol, event, freq);
+}
+
+#define CS47L85_NG_SRC(name, base) \
+	SOC_SINGLE(name " NG HPOUT1L Switch",  base,  0, 1, 0), \
+	SOC_SINGLE(name " NG HPOUT1R Switch",  base,  1, 1, 0), \
+	SOC_SINGLE(name " NG HPOUT2L Switch",  base,  2, 1, 0), \
+	SOC_SINGLE(name " NG HPOUT2R Switch",  base,  3, 1, 0), \
+	SOC_SINGLE(name " NG HPOUT3L Switch",  base,  4, 1, 0), \
+	SOC_SINGLE(name " NG HPOUT3R Switch",  base,  5, 1, 0), \
+	SOC_SINGLE(name " NG SPKOUTL Switch",  base,  6, 1, 0), \
+	SOC_SINGLE(name " NG SPKOUTR Switch",  base,  7, 1, 0), \
+	SOC_SINGLE(name " NG SPKDAT1L Switch", base,  8, 1, 0), \
+	SOC_SINGLE(name " NG SPKDAT1R Switch", base,  9, 1, 0), \
+	SOC_SINGLE(name " NG SPKDAT2L Switch", base, 10, 1, 0), \
+	SOC_SINGLE(name " NG SPKDAT2R Switch", base, 11, 1, 0)
+
+#define CS47L85_RXANC_INPUT_ROUTES(widget, name) \
+	{ widget, NULL, name " NG Mux" }, \
+	{ name " NG Internal", NULL, "RXANC NG Clock" }, \
+	{ name " NG Internal", NULL, name " Channel" }, \
+	{ name " NG External", NULL, "RXANC NG External Clock" }, \
+	{ name " NG External", NULL, name " Channel" }, \
+	{ name " NG Mux", "None", name " Channel" }, \
+	{ name " NG Mux", "Internal", name " NG Internal" }, \
+	{ name " NG Mux", "External", name " NG External" }, \
+	{ name " Channel", "Left", name " Left Input" }, \
+	{ name " Channel", "Combine", name " Left Input" }, \
+	{ name " Channel", "Right", name " Right Input" }, \
+	{ name " Channel", "Combine", name " Right Input" }, \
+	{ name " Left Input", "IN1", "IN1L PGA" }, \
+	{ name " Right Input", "IN1", "IN1R PGA" }, \
+	{ name " Left Input", "IN2", "IN2L PGA" }, \
+	{ name " Right Input", "IN2", "IN2R PGA" }, \
+	{ name " Left Input", "IN3", "IN3L PGA" }, \
+	{ name " Right Input", "IN3", "IN3R PGA" }, \
+	{ name " Left Input", "IN4", "IN4L PGA" }, \
+	{ name " Right Input", "IN4", "IN4R PGA" }, \
+	{ name " Left Input", "IN5", "IN5L PGA" }, \
+	{ name " Right Input", "IN5", "IN5R PGA" }, \
+	{ name " Left Input", "IN6", "IN6L PGA" }, \
+	{ name " Right Input", "IN6", "IN6R PGA" }
+
+#define CS47L85_RXANC_OUTPUT_ROUTES(widget, name) \
+	{ widget, NULL, name " ANC Source" }, \
+	{ name " ANC Source", "RXANCL", "RXANCL" }, \
+	{ name " ANC Source", "RXANCR", "RXANCR" }
+
+static void cs47l85_hp_post_enable(struct snd_soc_dapm_widget *w)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	unsigned int val;
+
+	switch (w->shift) {
+	case MADERA_OUT1L_ENA_SHIFT:
+	case MADERA_OUT1R_ENA_SHIFT:
+		val = snd_soc_read(codec, MADERA_OUTPUT_ENABLES_1);
+		val &= (MADERA_OUT1L_ENA | MADERA_OUT1R_ENA);
+
+		if (val == (MADERA_OUT1L_ENA | MADERA_OUT1R_ENA))
+			snd_soc_update_bits(codec,
+				    MADERA_EDRE_HP_STEREO_CONTROL,
+				    MADERA_HP1_EDRE_STEREO_MASK,
+				    MADERA_HP1_EDRE_STEREO);
+		break;
+
+	default:
+		break;
+	}
+}
+
+static void cs47l85_hp_post_disable(struct snd_soc_dapm_widget *w)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+	switch (w->shift) {
+	case MADERA_OUT1L_ENA_SHIFT:
+		snd_soc_write(codec, MADERA_DCS_HP1L_CONTROL, 0x2006);
+		break;
+	case MADERA_OUT1R_ENA_SHIFT:
+		snd_soc_write(codec, MADERA_DCS_HP1R_CONTROL, 0x2006);
+		break;
+	default:
+		return;
+	}
+
+	/* Only get to here for OUT1L and OUT1R */
+	snd_soc_update_bits(codec,
+			    MADERA_EDRE_HP_STEREO_CONTROL,
+			    MADERA_HP1_EDRE_STEREO_MASK,
+			    0);
+}
+
+static int cs47l85_hp_ev(struct snd_soc_dapm_widget *w,
+			 struct snd_kcontrol *kcontrol, int event)
+{
+	int ret;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+	case SND_SOC_DAPM_PRE_PMD:
+		return madera_hp_ev(w, kcontrol, event);
+	case SND_SOC_DAPM_POST_PMU:
+		ret = madera_hp_ev(w, kcontrol, event);
+		if (ret < 0)
+			return ret;
+
+		cs47l85_hp_post_enable(w);
+		return 0;
+	case SND_SOC_DAPM_POST_PMD:
+		ret = madera_hp_ev(w, kcontrol, event);
+		cs47l85_hp_post_disable(w);
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct snd_kcontrol_new cs47l85_snd_controls[] = {
+SOC_ENUM("IN1 OSR", madera_in_dmic_osr[0]),
+SOC_ENUM("IN2 OSR", madera_in_dmic_osr[1]),
+SOC_ENUM("IN3 OSR", madera_in_dmic_osr[2]),
+SOC_ENUM("IN4 OSR", madera_in_dmic_osr[3]),
+SOC_ENUM("IN5 OSR", madera_in_dmic_osr[4]),
+SOC_ENUM("IN6 OSR", madera_in_dmic_osr[5]),
+
+SOC_SINGLE_RANGE_TLV("IN1L Volume", MADERA_IN1L_CONTROL,
+		     MADERA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+SOC_SINGLE_RANGE_TLV("IN1R Volume", MADERA_IN1R_CONTROL,
+		     MADERA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+SOC_SINGLE_RANGE_TLV("IN2L Volume", MADERA_IN2L_CONTROL,
+		     MADERA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+SOC_SINGLE_RANGE_TLV("IN2R Volume", MADERA_IN2R_CONTROL,
+		     MADERA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+SOC_SINGLE_RANGE_TLV("IN3L Volume", MADERA_IN3L_CONTROL,
+		     MADERA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+SOC_SINGLE_RANGE_TLV("IN3R Volume", MADERA_IN3R_CONTROL,
+		     MADERA_IN3R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+
+SOC_ENUM("IN HPF Cutoff Frequency", madera_in_hpf_cut_enum),
+
+SOC_SINGLE("IN1L HPF Switch", MADERA_IN1L_CONTROL,
+	   MADERA_IN1L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN1R HPF Switch", MADERA_IN1R_CONTROL,
+	   MADERA_IN1R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN2L HPF Switch", MADERA_IN2L_CONTROL,
+	   MADERA_IN2L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN2R HPF Switch", MADERA_IN2R_CONTROL,
+	   MADERA_IN2R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN3L HPF Switch", MADERA_IN3L_CONTROL,
+	   MADERA_IN3L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN3R HPF Switch", MADERA_IN3R_CONTROL,
+	   MADERA_IN3R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN4L HPF Switch", MADERA_IN4L_CONTROL,
+	   MADERA_IN4L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN4R HPF Switch", MADERA_IN4R_CONTROL,
+	   MADERA_IN4R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN5L HPF Switch", MADERA_IN5L_CONTROL,
+	   MADERA_IN5L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN5R HPF Switch", MADERA_IN5R_CONTROL,
+	   MADERA_IN5R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN6L HPF Switch", MADERA_IN6L_CONTROL,
+	   MADERA_IN6L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN6R HPF Switch", MADERA_IN6R_CONTROL,
+	   MADERA_IN6R_HPF_SHIFT, 1, 0),
+
+SOC_SINGLE_TLV("IN1L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1L,
+	       MADERA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN1R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1R,
+	       MADERA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN2L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2L,
+	       MADERA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN2R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2R,
+	       MADERA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN3L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_3L,
+	       MADERA_IN3L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN3R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_3R,
+	       MADERA_IN3R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN4L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_4L,
+	       MADERA_IN4L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN4R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_4R,
+	       MADERA_IN4R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN5L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_5L,
+	       MADERA_IN5L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN5R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_5R,
+	       MADERA_IN5R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN6L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_6L,
+	       MADERA_IN6L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN6R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_6R,
+	       MADERA_IN6R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+
+SOC_ENUM("Input Ramp Up", madera_in_vi_ramp),
+SOC_ENUM("Input Ramp Down", madera_in_vd_ramp),
+
+SND_SOC_BYTES("RXANC Coefficients", MADERA_ANC_COEFF_START,
+	      MADERA_ANC_COEFF_END - MADERA_ANC_COEFF_START + 1),
+SND_SOC_BYTES("RXANCL Config", MADERA_FCL_FILTER_CONTROL, 1),
+SND_SOC_BYTES("RXANCL Coefficients", MADERA_FCL_COEFF_START,
+	      MADERA_FCL_COEFF_END - MADERA_FCL_COEFF_START + 1),
+SND_SOC_BYTES("RXANCR Config", MADERA_FCR_FILTER_CONTROL, 1),
+SND_SOC_BYTES("RXANCR Coefficients", MADERA_FCR_COEFF_START,
+	      MADERA_FCR_COEFF_END - MADERA_FCR_COEFF_START + 1),
+
+MADERA_MIXER_CONTROLS("EQ1", MADERA_EQ1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("EQ2", MADERA_EQ2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("EQ3", MADERA_EQ3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("EQ4", MADERA_EQ4MIX_INPUT_1_SOURCE),
+
+MADERA_EQ_CONTROL("EQ1 Coefficients", MADERA_EQ1_2),
+SOC_SINGLE_TLV("EQ1 B1 Volume", MADERA_EQ1_1, MADERA_EQ1_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B2 Volume", MADERA_EQ1_1, MADERA_EQ1_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B3 Volume", MADERA_EQ1_1, MADERA_EQ1_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B4 Volume", MADERA_EQ1_2, MADERA_EQ1_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B5 Volume", MADERA_EQ1_2, MADERA_EQ1_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_EQ_CONTROL("EQ2 Coefficients", MADERA_EQ2_2),
+SOC_SINGLE_TLV("EQ2 B1 Volume", MADERA_EQ2_1, MADERA_EQ2_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B2 Volume", MADERA_EQ2_1, MADERA_EQ2_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B3 Volume", MADERA_EQ2_1, MADERA_EQ2_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B4 Volume", MADERA_EQ2_2, MADERA_EQ2_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B5 Volume", MADERA_EQ2_2, MADERA_EQ2_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_EQ_CONTROL("EQ3 Coefficients", MADERA_EQ3_2),
+SOC_SINGLE_TLV("EQ3 B1 Volume", MADERA_EQ3_1, MADERA_EQ3_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B2 Volume", MADERA_EQ3_1, MADERA_EQ3_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B3 Volume", MADERA_EQ3_1, MADERA_EQ3_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B4 Volume", MADERA_EQ3_2, MADERA_EQ3_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B5 Volume", MADERA_EQ3_2, MADERA_EQ3_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_EQ_CONTROL("EQ4 Coefficients", MADERA_EQ4_2),
+SOC_SINGLE_TLV("EQ4 B1 Volume", MADERA_EQ4_1, MADERA_EQ4_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B2 Volume", MADERA_EQ4_1, MADERA_EQ4_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B3 Volume", MADERA_EQ4_1, MADERA_EQ4_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B4 Volume", MADERA_EQ4_2, MADERA_EQ4_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B5 Volume", MADERA_EQ4_2, MADERA_EQ4_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_MIXER_CONTROLS("DRC1L", MADERA_DRC1LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DRC1R", MADERA_DRC1RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DRC2L", MADERA_DRC2LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DRC2R", MADERA_DRC2RMIX_INPUT_1_SOURCE),
+
+SND_SOC_BYTES_MASK("DRC1", MADERA_DRC1_CTRL1, 5,
+		   MADERA_DRC1R_ENA | MADERA_DRC1L_ENA),
+SND_SOC_BYTES_MASK("DRC2", MADERA_DRC2_CTRL1, 5,
+		   MADERA_DRC2R_ENA | MADERA_DRC2L_ENA),
+
+MADERA_MIXER_CONTROLS("LHPF1", MADERA_HPLP1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("LHPF2", MADERA_HPLP2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("LHPF3", MADERA_HPLP3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("LHPF4", MADERA_HPLP4MIX_INPUT_1_SOURCE),
+
+MADERA_LHPF_CONTROL("LHPF1 Coefficients", MADERA_HPLPF1_2),
+MADERA_LHPF_CONTROL("LHPF2 Coefficients", MADERA_HPLPF2_2),
+MADERA_LHPF_CONTROL("LHPF3 Coefficients", MADERA_HPLPF3_2),
+MADERA_LHPF_CONTROL("LHPF4 Coefficients", MADERA_HPLPF4_2),
+
+SOC_ENUM("LHPF1 Mode", madera_lhpf1_mode),
+SOC_ENUM("LHPF2 Mode", madera_lhpf2_mode),
+SOC_ENUM("LHPF3 Mode", madera_lhpf3_mode),
+SOC_ENUM("LHPF4 Mode", madera_lhpf4_mode),
+
+SOC_ENUM("Sample Rate 2", madera_sample_rate[0]),
+SOC_ENUM("Sample Rate 3", madera_sample_rate[1]),
+SOC_ENUM("ASYNC Sample Rate 2", madera_sample_rate[2]),
+
+MADERA_RATE_ENUM("ISRC1 FSL", madera_isrc_fsl[0]),
+MADERA_RATE_ENUM("ISRC2 FSL", madera_isrc_fsl[1]),
+MADERA_RATE_ENUM("ISRC3 FSL", madera_isrc_fsl[2]),
+MADERA_RATE_ENUM("ISRC4 FSL", madera_isrc_fsl[3]),
+MADERA_RATE_ENUM("ISRC1 FSH", madera_isrc_fsh[0]),
+MADERA_RATE_ENUM("ISRC2 FSH", madera_isrc_fsh[1]),
+MADERA_RATE_ENUM("ISRC3 FSH", madera_isrc_fsh[2]),
+MADERA_RATE_ENUM("ISRC4 FSH", madera_isrc_fsh[3]),
+MADERA_RATE_ENUM("ASRC1 Rate 1", madera_asrc1_rate[0]),
+MADERA_RATE_ENUM("ASRC1 Rate 2", madera_asrc1_rate[1]),
+MADERA_RATE_ENUM("ASRC2 Rate 1", madera_asrc2_rate[0]),
+MADERA_RATE_ENUM("ASRC2 Rate 2", madera_asrc2_rate[1]),
+
+MADERA_MIXER_CONTROLS("DSP1L", MADERA_DSP1LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP1R", MADERA_DSP1RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP2L", MADERA_DSP2LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP2R", MADERA_DSP2RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP3L", MADERA_DSP3LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP3R", MADERA_DSP3RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP4L", MADERA_DSP4LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP4R", MADERA_DSP4RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP5L", MADERA_DSP5LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP5R", MADERA_DSP5RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP6L", MADERA_DSP6LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP6R", MADERA_DSP6RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP7L", MADERA_DSP7LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP7R", MADERA_DSP7RMIX_INPUT_1_SOURCE),
+
+SOC_SINGLE_TLV("Noise Generator Volume", MADERA_COMFORT_NOISE_GENERATOR,
+	       MADERA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, madera_noise_tlv),
+
+MADERA_MIXER_CONTROLS("HPOUT1L", MADERA_OUT1LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("HPOUT1R", MADERA_OUT1RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("HPOUT2L", MADERA_OUT2LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("HPOUT2R", MADERA_OUT2RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("HPOUT3L", MADERA_OUT3LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("HPOUT3R", MADERA_OUT3RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SPKOUTL", MADERA_OUT4LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SPKOUTR", MADERA_OUT4RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SPKDAT1L", MADERA_OUT5LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SPKDAT1R", MADERA_OUT5RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SPKDAT2L", MADERA_OUT6LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SPKDAT2R", MADERA_OUT6RMIX_INPUT_1_SOURCE),
+
+SOC_SINGLE("HPOUT1 SC Protect Switch", MADERA_HP1_SHORT_CIRCUIT_CTRL,
+	   MADERA_HP1_SC_ENA_SHIFT, 1, 0),
+SOC_SINGLE("HPOUT2 SC Protect Switch", MADERA_HP2_SHORT_CIRCUIT_CTRL,
+	   MADERA_HP2_SC_ENA_SHIFT, 1, 0),
+SOC_SINGLE("HPOUT3 SC Protect Switch", MADERA_HP3_SHORT_CIRCUIT_CTRL,
+	   MADERA_HP3_SC_ENA_SHIFT, 1, 0),
+
+SOC_SINGLE("HPOUT1L ONEFLT Switch", MADERA_HP_TEST_CTRL_5,
+				    MADERA_HP1L_ONEFLT_SHIFT, 1, 0),
+SOC_SINGLE("HPOUT1R ONEFLT Switch", MADERA_HP_TEST_CTRL_6,
+				    MADERA_HP1R_ONEFLT_SHIFT, 1, 0),
+
+SOC_SINGLE("SPKDAT1 High Performance Switch", MADERA_OUTPUT_PATH_CONFIG_5L,
+	   MADERA_OUT5_OSR_SHIFT, 1, 0),
+SOC_SINGLE("SPKDAT2 High Performance Switch", MADERA_OUTPUT_PATH_CONFIG_6L,
+	   MADERA_OUT6_OSR_SHIFT, 1, 0),
+
+SOC_DOUBLE_R("HPOUT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_1L,
+	     MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("HPOUT2 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_2L,
+	     MADERA_DAC_DIGITAL_VOLUME_2R, MADERA_OUT2L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("HPOUT3 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_3L,
+	     MADERA_DAC_DIGITAL_VOLUME_3R, MADERA_OUT3L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("Speaker Digital Switch", MADERA_DAC_DIGITAL_VOLUME_4L,
+	     MADERA_DAC_DIGITAL_VOLUME_4R, MADERA_OUT4L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("SPKDAT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_5L,
+	     MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("SPKDAT2 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_6L,
+	     MADERA_DAC_DIGITAL_VOLUME_6R, MADERA_OUT6L_MUTE_SHIFT, 1, 1),
+
+SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_1L,
+		 MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_2L,
+		 MADERA_DAC_DIGITAL_VOLUME_2R, MADERA_OUT2L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_3L,
+		 MADERA_DAC_DIGITAL_VOLUME_3R, MADERA_OUT3L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+SOC_DOUBLE_R_TLV("Speaker Digital Volume", MADERA_DAC_DIGITAL_VOLUME_4L,
+		 MADERA_DAC_DIGITAL_VOLUME_4R, MADERA_OUT4L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_5L,
+		 MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_6L,
+		 MADERA_DAC_DIGITAL_VOLUME_6R, MADERA_OUT6L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+
+SOC_DOUBLE("SPKDAT1 Switch", MADERA_PDM_SPK1_CTRL_1, MADERA_SPK1L_MUTE_SHIFT,
+	   MADERA_SPK1R_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE("SPKDAT2 Switch", MADERA_PDM_SPK2_CTRL_1, MADERA_SPK2L_MUTE_SHIFT,
+	   MADERA_SPK2R_MUTE_SHIFT, 1, 1),
+
+SOC_DOUBLE("HPOUT1 EDRE Switch", MADERA_EDRE_ENABLE,
+	   MADERA_EDRE_OUT1L_THR1_ENA_SHIFT,
+	   MADERA_EDRE_OUT1R_THR1_ENA_SHIFT, 1, 0),
+SOC_DOUBLE("HPOUT2 EDRE Switch", MADERA_EDRE_ENABLE,
+	   MADERA_EDRE_OUT2L_THR1_ENA_SHIFT,
+	   MADERA_EDRE_OUT2R_THR1_ENA_SHIFT, 1, 0),
+SOC_DOUBLE("HPOUT3 EDRE Switch", MADERA_EDRE_ENABLE,
+	   MADERA_EDRE_OUT3L_THR1_ENA_SHIFT,
+	   MADERA_EDRE_OUT3R_THR1_ENA_SHIFT, 1, 0),
+
+SOC_ENUM("Output Ramp Up", madera_out_vi_ramp),
+SOC_ENUM("Output Ramp Down", madera_out_vd_ramp),
+
+SOC_SINGLE("Noise Gate Switch", MADERA_NOISE_GATE_CONTROL,
+	   MADERA_NGATE_ENA_SHIFT, 1, 0),
+SOC_SINGLE_TLV("Noise Gate Threshold Volume", MADERA_NOISE_GATE_CONTROL,
+	       MADERA_NGATE_THR_SHIFT, 7, 1, madera_ng_tlv),
+SOC_ENUM("Noise Gate Hold", madera_ng_hold),
+
+CS47L85_NG_SRC("HPOUT1L", MADERA_NOISE_GATE_SELECT_1L),
+CS47L85_NG_SRC("HPOUT1R", MADERA_NOISE_GATE_SELECT_1R),
+CS47L85_NG_SRC("HPOUT2L", MADERA_NOISE_GATE_SELECT_2L),
+CS47L85_NG_SRC("HPOUT2R", MADERA_NOISE_GATE_SELECT_2R),
+CS47L85_NG_SRC("HPOUT3L", MADERA_NOISE_GATE_SELECT_3L),
+CS47L85_NG_SRC("HPOUT3R", MADERA_NOISE_GATE_SELECT_3R),
+CS47L85_NG_SRC("SPKOUTL", MADERA_NOISE_GATE_SELECT_4L),
+CS47L85_NG_SRC("SPKOUTR", MADERA_NOISE_GATE_SELECT_4R),
+CS47L85_NG_SRC("SPKDAT1L", MADERA_NOISE_GATE_SELECT_5L),
+CS47L85_NG_SRC("SPKDAT1R", MADERA_NOISE_GATE_SELECT_5R),
+CS47L85_NG_SRC("SPKDAT2L", MADERA_NOISE_GATE_SELECT_6L),
+CS47L85_NG_SRC("SPKDAT2R", MADERA_NOISE_GATE_SELECT_6R),
+
+MADERA_MIXER_CONTROLS("AIF1TX1", MADERA_AIF1TX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX2", MADERA_AIF1TX2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX3", MADERA_AIF1TX3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX4", MADERA_AIF1TX4MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX5", MADERA_AIF1TX5MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX6", MADERA_AIF1TX6MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX7", MADERA_AIF1TX7MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX8", MADERA_AIF1TX8MIX_INPUT_1_SOURCE),
+
+MADERA_MIXER_CONTROLS("AIF2TX1", MADERA_AIF2TX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX2", MADERA_AIF2TX2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX3", MADERA_AIF2TX3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX4", MADERA_AIF2TX4MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX5", MADERA_AIF2TX5MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX6", MADERA_AIF2TX6MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX7", MADERA_AIF2TX7MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX8", MADERA_AIF2TX8MIX_INPUT_1_SOURCE),
+
+MADERA_MIXER_CONTROLS("AIF3TX1", MADERA_AIF3TX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF3TX2", MADERA_AIF3TX2MIX_INPUT_1_SOURCE),
+
+MADERA_MIXER_CONTROLS("AIF4TX1", MADERA_AIF4TX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF4TX2", MADERA_AIF4TX2MIX_INPUT_1_SOURCE),
+
+MADERA_MIXER_CONTROLS("SLIMTX1", MADERA_SLIMTX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX2", MADERA_SLIMTX2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX3", MADERA_SLIMTX3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX4", MADERA_SLIMTX4MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX5", MADERA_SLIMTX5MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX6", MADERA_SLIMTX6MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX7", MADERA_SLIMTX7MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX8", MADERA_SLIMTX8MIX_INPUT_1_SOURCE),
+
+MADERA_GAINMUX_CONTROLS("SPDIF1TX1", MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE),
+MADERA_GAINMUX_CONTROLS("SPDIF1TX2", MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE),
+};
+
+MADERA_MIXER_ENUMS(EQ1, MADERA_EQ1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(EQ2, MADERA_EQ2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(EQ3, MADERA_EQ3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(EQ4, MADERA_EQ4MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DRC1L, MADERA_DRC1LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DRC1R, MADERA_DRC1RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DRC2L, MADERA_DRC2LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DRC2R, MADERA_DRC2RMIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(LHPF1, MADERA_HPLP1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(LHPF2, MADERA_HPLP2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(LHPF3, MADERA_HPLP3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(LHPF4, MADERA_HPLP4MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP1L, MADERA_DSP1LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP1R, MADERA_DSP1RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP1, MADERA_DSP1AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP2L, MADERA_DSP2LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP2R, MADERA_DSP2RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP2, MADERA_DSP2AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP3L, MADERA_DSP3LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP3R, MADERA_DSP3RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP3, MADERA_DSP3AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP4L, MADERA_DSP4LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP4R, MADERA_DSP4RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP4, MADERA_DSP4AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP5L, MADERA_DSP5LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP5R, MADERA_DSP5RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP5, MADERA_DSP5AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP6L, MADERA_DSP6LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP6R, MADERA_DSP6RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP6, MADERA_DSP6AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP7L, MADERA_DSP7LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP7R, MADERA_DSP7RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP7, MADERA_DSP7AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(PWM1, MADERA_PWM1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(PWM2, MADERA_PWM2MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(OUT1L, MADERA_OUT1LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(OUT1R, MADERA_OUT1RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(OUT2L, MADERA_OUT2LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(OUT2R, MADERA_OUT2RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(OUT3L, MADERA_OUT3LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(OUT3R, MADERA_OUT3RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SPKOUTL, MADERA_OUT4LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SPKOUTR, MADERA_OUT4RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SPKDAT1L, MADERA_OUT5LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SPKDAT1R, MADERA_OUT5RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SPKDAT2L, MADERA_OUT6LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SPKDAT2R, MADERA_OUT6RMIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(AIF1TX1, MADERA_AIF1TX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX2, MADERA_AIF1TX2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX3, MADERA_AIF1TX3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX4, MADERA_AIF1TX4MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX5, MADERA_AIF1TX5MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX6, MADERA_AIF1TX6MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX7, MADERA_AIF1TX7MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX8, MADERA_AIF1TX8MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(AIF2TX1, MADERA_AIF2TX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX2, MADERA_AIF2TX2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX3, MADERA_AIF2TX3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX4, MADERA_AIF2TX4MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX5, MADERA_AIF2TX5MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX6, MADERA_AIF2TX6MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX7, MADERA_AIF2TX7MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX8, MADERA_AIF2TX8MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(AIF3TX1, MADERA_AIF3TX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF3TX2, MADERA_AIF3TX2MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(AIF4TX1, MADERA_AIF4TX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF4TX2, MADERA_AIF4TX2MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(SLIMTX1, MADERA_SLIMTX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX2, MADERA_SLIMTX2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX3, MADERA_SLIMTX3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX4, MADERA_SLIMTX4MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX5, MADERA_SLIMTX5MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX6, MADERA_SLIMTX6MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX7, MADERA_SLIMTX7MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX8, MADERA_SLIMTX8MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(SPD1TX1, MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(SPD1TX2, MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ASRC1IN1L, MADERA_ASRC1_1LMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC1IN1R, MADERA_ASRC1_1RMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC1IN2L, MADERA_ASRC1_2LMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC1IN2R, MADERA_ASRC1_2RMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC2IN1L, MADERA_ASRC2_1LMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC2IN1R, MADERA_ASRC2_1RMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC2IN2L, MADERA_ASRC2_2LMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC2IN2R, MADERA_ASRC2_2RMIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC1INT1, MADERA_ISRC1INT1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1INT2, MADERA_ISRC1INT2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1INT3, MADERA_ISRC1INT3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1INT4, MADERA_ISRC1INT4MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC1DEC1, MADERA_ISRC1DEC1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1DEC2, MADERA_ISRC1DEC2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1DEC3, MADERA_ISRC1DEC3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1DEC4, MADERA_ISRC1DEC4MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC2INT1, MADERA_ISRC2INT1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2INT2, MADERA_ISRC2INT2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2INT3, MADERA_ISRC2INT3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2INT4, MADERA_ISRC2INT4MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC2DEC1, MADERA_ISRC2DEC1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2DEC2, MADERA_ISRC2DEC2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2DEC3, MADERA_ISRC2DEC3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2DEC4, MADERA_ISRC2DEC4MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC3INT1, MADERA_ISRC3INT1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC3INT2, MADERA_ISRC3INT2MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC3DEC1, MADERA_ISRC3DEC1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC3DEC2, MADERA_ISRC3DEC2MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC4INT1, MADERA_ISRC4INT1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC4INT2, MADERA_ISRC4INT2MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC4DEC1, MADERA_ISRC4DEC1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC4DEC2, MADERA_ISRC4DEC2MIX_INPUT_1_SOURCE);
+
+static const char * const cs47l85_aec_loopback_texts[] = {
+	"HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R",
+	"SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R", "SPKDAT2L", "SPKDAT2R",
+};
+
+static const unsigned int cs47l85_aec_loopback_values[] = {
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+};
+
+static const struct soc_enum cs47l85_aec1_loopback =
+	SOC_VALUE_ENUM_SINGLE(MADERA_DAC_AEC_CONTROL_1,
+			      MADERA_AEC1_LOOPBACK_SRC_SHIFT, 0xf,
+			      ARRAY_SIZE(cs47l85_aec_loopback_texts),
+			      cs47l85_aec_loopback_texts,
+			      cs47l85_aec_loopback_values);
+
+static const struct soc_enum cs47l85_aec2_loopback =
+	SOC_VALUE_ENUM_SINGLE(MADERA_DAC_AEC_CONTROL_2,
+			      MADERA_AEC2_LOOPBACK_SRC_SHIFT, 0xf,
+			      ARRAY_SIZE(cs47l85_aec_loopback_texts),
+			      cs47l85_aec_loopback_texts,
+			      cs47l85_aec_loopback_values);
+
+static const struct snd_kcontrol_new cs47l85_aec_loopback_mux[] = {
+	SOC_DAPM_ENUM("AEC1 Loopback", cs47l85_aec1_loopback),
+	SOC_DAPM_ENUM("AEC2 Loopback", cs47l85_aec2_loopback),
+};
+
+static const struct snd_kcontrol_new cs47l85_anc_input_mux[] = {
+	SOC_DAPM_ENUM("RXANCL Input", madera_anc_input_src[0]),
+	SOC_DAPM_ENUM("RXANCL Channel", madera_anc_input_src[1]),
+	SOC_DAPM_ENUM("RXANCR Input", madera_anc_input_src[2]),
+	SOC_DAPM_ENUM("RXANCR Channel", madera_anc_input_src[3]),
+};
+
+static const struct snd_kcontrol_new cs47l85_anc_ng_mux =
+	SOC_DAPM_ENUM("RXANC NG Source", madera_anc_ng_enum);
+
+static const struct snd_kcontrol_new cs47l85_output_anc_src[] = {
+	SOC_DAPM_ENUM("HPOUT1L ANC Source", madera_output_anc_src[0]),
+	SOC_DAPM_ENUM("HPOUT1R ANC Source", madera_output_anc_src[1]),
+	SOC_DAPM_ENUM("HPOUT2L ANC Source", madera_output_anc_src[2]),
+	SOC_DAPM_ENUM("HPOUT2R ANC Source", madera_output_anc_src[3]),
+	SOC_DAPM_ENUM("HPOUT3L ANC Source", madera_output_anc_src[4]),
+	SOC_DAPM_ENUM("HPOUT3R ANC Source", madera_output_anc_src[5]),
+	SOC_DAPM_ENUM("SPKOUTL ANC Source", madera_output_anc_src[6]),
+	SOC_DAPM_ENUM("SPKOUTR ANC Source", madera_output_anc_src[7]),
+	SOC_DAPM_ENUM("SPKDAT1L ANC Source", madera_output_anc_src[8]),
+	SOC_DAPM_ENUM("SPKDAT1R ANC Source", madera_output_anc_src[9]),
+	SOC_DAPM_ENUM("SPKDAT2L ANC Source", madera_output_anc_src[10]),
+	SOC_DAPM_ENUM("SPKDAT2R ANC Source", madera_output_anc_src[11]),
+};
+
+static const struct snd_soc_dapm_widget cs47l85_dapm_widgets[] = {
+SND_SOC_DAPM_SUPPLY("SYSCLK", MADERA_SYSTEM_CLOCK_1, MADERA_SYSCLK_ENA_SHIFT,
+		    0, madera_sysclk_ev,
+		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_SUPPLY("ASYNCCLK", MADERA_ASYNC_CLOCK_1,
+		    MADERA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK,
+		    MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", MADERA_OUTPUT_ASYNC_CLOCK,
+		    MADERA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1,
+		    MADERA_DSP_CLK_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD4", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD1", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD2", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
+SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
+
+SND_SOC_DAPM_SUPPLY("MICBIAS1", MADERA_MIC_BIAS_CTRL_1,
+		    MADERA_MICB1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2", MADERA_MIC_BIAS_CTRL_2,
+		    MADERA_MICB1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS3", MADERA_MIC_BIAS_CTRL_3,
+		    MADERA_MICB1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS4", MADERA_MIC_BIAS_CTRL_4,
+		    MADERA_MICB1_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_SUPPLY("FXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_FX, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ASRC1R1CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ASRC1_RATE_1, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ASRC1R2CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ASRC1_RATE_2, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ASRC2R1CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ASRC2_RATE_1, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ASRC2R2CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ASRC2_RATE_2, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC1DECCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC1_DEC, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC1INTCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC1_INT, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC2DECCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC2_DEC, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC2INTCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC2_INT, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("OUTCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_OUT, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("SPDCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_SPD, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP1, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP2, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP3CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP3, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP4CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP4, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP5CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP5, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP6CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP6, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP7CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP7, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("AIF1TXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_AIF1, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("AIF2TXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_AIF2, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("AIF3TXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_AIF3, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("AIF4TXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_AIF4, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("SLIMBUSCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_SLIMBUS, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("PWMCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_PWM, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+SND_SOC_DAPM_SUPPLY("RXANC NG External Clock", SND_SOC_NOPM,
+		    MADERA_EXT_NG_SEL_SET_SHIFT, 0, madera_anc_ev,
+		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+SND_SOC_DAPM_SUPPLY("RXANC NG Clock", SND_SOC_NOPM,
+		    MADERA_CLK_NG_ENA_SET_SHIFT, 0, madera_anc_ev,
+		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+SND_SOC_DAPM_SIGGEN("TONE"),
+SND_SOC_DAPM_SIGGEN("NOISE"),
+
+SND_SOC_DAPM_INPUT("IN1AL"),
+SND_SOC_DAPM_INPUT("IN1B"),
+SND_SOC_DAPM_INPUT("IN1R"),
+SND_SOC_DAPM_INPUT("IN2AL"),
+SND_SOC_DAPM_INPUT("IN2AR"),
+SND_SOC_DAPM_INPUT("IN2BL"),
+SND_SOC_DAPM_INPUT("IN2BR"),
+SND_SOC_DAPM_INPUT("IN3L"),
+SND_SOC_DAPM_INPUT("IN3R"),
+SND_SOC_DAPM_INPUT("IN4L"),
+SND_SOC_DAPM_INPUT("IN4R"),
+SND_SOC_DAPM_INPUT("IN5L"),
+SND_SOC_DAPM_INPUT("IN5R"),
+SND_SOC_DAPM_INPUT("IN6L"),
+SND_SOC_DAPM_INPUT("IN6R"),
+
+SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
+SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
+
+SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),
+
+SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[0]),
+SND_SOC_DAPM_MUX("IN2L Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[2]),
+SND_SOC_DAPM_MUX("IN2R Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[3]),
+
+SND_SOC_DAPM_PGA("PWM1 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM1_ENA_SHIFT,
+		 0, NULL, 0),
+SND_SOC_DAPM_PGA("PWM2 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM2_ENA_SHIFT,
+		 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("RXANCL NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_PGA("RXANCR NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("RXANCL NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_PGA("RXANCR NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+SND_SOC_DAPM_MUX("RXANCL Left Input", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_anc_input_mux[0]),
+SND_SOC_DAPM_MUX("RXANCL Right Input", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_anc_input_mux[0]),
+SND_SOC_DAPM_MUX("RXANCL Channel", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_anc_input_mux[1]),
+SND_SOC_DAPM_MUX("RXANCL NG Mux", SND_SOC_NOPM, 0, 0, &cs47l85_anc_ng_mux),
+SND_SOC_DAPM_MUX("RXANCR Left Input", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_anc_input_mux[2]),
+SND_SOC_DAPM_MUX("RXANCR Right Input", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_anc_input_mux[2]),
+SND_SOC_DAPM_MUX("RXANCR Channel", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_anc_input_mux[3]),
+SND_SOC_DAPM_MUX("RXANCR NG Mux", SND_SOC_NOPM, 0, 0, &cs47l85_anc_ng_mux),
+
+SND_SOC_DAPM_PGA_E("RXANCL", SND_SOC_NOPM, MADERA_CLK_L_ENA_SET_SHIFT,
+		   0, NULL, 0, madera_anc_ev,
+		   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_PGA_E("RXANCR", SND_SOC_NOPM, MADERA_CLK_R_ENA_SET_SHIFT,
+		   0, NULL, 0, madera_anc_ev,
+		   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+SND_SOC_DAPM_MUX("HPOUT1L ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[0]),
+SND_SOC_DAPM_MUX("HPOUT1R ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[1]),
+SND_SOC_DAPM_MUX("HPOUT2L ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[2]),
+SND_SOC_DAPM_MUX("HPOUT2R ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[3]),
+SND_SOC_DAPM_MUX("HPOUT3L ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[4]),
+SND_SOC_DAPM_MUX("HPOUT3R ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[5]),
+SND_SOC_DAPM_MUX("SPKOUTL ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[6]),
+SND_SOC_DAPM_MUX("SPKOUTR ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[7]),
+SND_SOC_DAPM_MUX("SPKDAT1L ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[8]),
+SND_SOC_DAPM_MUX("SPKDAT1R ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[9]),
+SND_SOC_DAPM_MUX("SPKDAT2L ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[10]),
+SND_SOC_DAPM_MUX("SPKDAT2R ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l85_output_anc_src[11]),
+
+SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX7", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX8", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX7", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX8", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
+		     MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
+		     MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF4TX1", NULL, 0,
+		     MADERA_AIF4_TX_ENABLES, MADERA_AIF4TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF4TX2", NULL, 0,
+		     MADERA_AIF4_TX_ENABLES, MADERA_AIF4TX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
+		   MADERA_OUT1L_ENA_SHIFT, 0, NULL, 0, cs47l85_hp_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
+		   MADERA_OUT1R_ENA_SHIFT, 0, NULL, 0, cs47l85_hp_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT2L", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT2L_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT2R", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT2R_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT3L", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT3L_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT3R", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT3R_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
+		   MADERA_OUT4L_ENA_SHIFT, 0, NULL, 0, madera_spk_ev,
+		   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
+		   MADERA_OUT4R_ENA_SHIFT, 0, NULL, 0, madera_spk_ev,
+		   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_PGA_E("OUT5L", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT5L_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT5R", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT5R_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT6L", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT6L_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT6R", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT6R_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+
+SND_SOC_DAPM_PGA("SPD1TX1", MADERA_SPD1_TX_CONTROL,
+		   MADERA_SPD1_VAL1_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("SPD1TX2", MADERA_SPD1_TX_CONTROL,
+		   MADERA_SPD1_VAL2_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_OUT_DRV("SPD1", MADERA_SPD1_TX_CONTROL,
+		     MADERA_SPD1_ENA_SHIFT, 0, NULL, 0),
+
+/*
+ * Input mux widgets arranged in order of sources in MADERA_MIXER_INPUT_ROUTES
+ * to take advantage of cache lookup in DAPM
+ */
+SND_SOC_DAPM_PGA("Noise Generator", MADERA_COMFORT_NOISE_GENERATOR,
+		 MADERA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("Tone Generator 1", MADERA_TONE_GENERATOR_1,
+		 MADERA_TONE1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Tone Generator 2", MADERA_TONE_GENERATOR_1,
+		 MADERA_TONE2_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_SIGGEN("HAPTICS"),
+
+SND_SOC_DAPM_MUX("AEC1 Loopback", MADERA_DAC_AEC_CONTROL_1,
+			MADERA_AEC1_LOOPBACK_ENA_SHIFT, 0,
+			&cs47l85_aec_loopback_mux[0]),
+SND_SOC_DAPM_MUX("AEC2 Loopback", MADERA_DAC_AEC_CONTROL_2,
+			MADERA_AEC2_LOOPBACK_ENA_SHIFT, 0,
+			&cs47l85_aec_loopback_mux[1]),
+
+SND_SOC_DAPM_PGA_E("IN1L PGA", MADERA_INPUT_ENABLES, MADERA_IN1L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN1R PGA", MADERA_INPUT_ENABLES, MADERA_IN1R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN2L PGA", MADERA_INPUT_ENABLES, MADERA_IN2L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN2R PGA", MADERA_INPUT_ENABLES, MADERA_IN2R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN3L PGA", MADERA_INPUT_ENABLES, MADERA_IN3L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN3R PGA", MADERA_INPUT_ENABLES, MADERA_IN3R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN4L PGA", MADERA_INPUT_ENABLES, MADERA_IN4L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN4R PGA", MADERA_INPUT_ENABLES, MADERA_IN4R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN5L PGA", MADERA_INPUT_ENABLES, MADERA_IN5L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN5R PGA", MADERA_INPUT_ENABLES, MADERA_IN5R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN6L PGA", MADERA_INPUT_ENABLES, MADERA_IN6L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN6R PGA", MADERA_INPUT_ENABLES, MADERA_IN6R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+
+SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
+		    MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
+		    MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
+		    MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0,
+		    MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0,
+		    MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 0,
+		    MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 0,
+		    MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX7", NULL, 0,
+		    MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX8", NULL, 0,
+		    MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
+		    MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
+		    MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("AIF4RX1", NULL, 0,
+		    MADERA_AIF4_RX_ENABLES, MADERA_AIF4RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF4RX2", NULL, 0,
+		    MADERA_AIF4_RX_ENABLES, MADERA_AIF4RX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX5", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX6", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX7", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0,
+		    MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+		    MADERA_SLIMRX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_PGA("EQ1", MADERA_EQ1_1, MADERA_EQ1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("EQ2", MADERA_EQ2_1, MADERA_EQ2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("EQ3", MADERA_EQ3_1, MADERA_EQ3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("EQ4", MADERA_EQ4_1, MADERA_EQ4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("DRC1L", MADERA_DRC1_CTRL1, MADERA_DRC1L_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("DRC1R", MADERA_DRC1_CTRL1, MADERA_DRC1R_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("DRC2L", MADERA_DRC2_CTRL1, MADERA_DRC2L_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("DRC2R", MADERA_DRC2_CTRL1, MADERA_DRC2R_ENA_SHIFT, 0,
+		 NULL, 0),
+
+SND_SOC_DAPM_PGA("LHPF1", MADERA_HPLPF1_1, MADERA_LHPF1_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("LHPF2", MADERA_HPLPF2_1, MADERA_LHPF2_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("LHPF3", MADERA_HPLPF3_1, MADERA_LHPF3_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("LHPF4", MADERA_HPLPF4_1, MADERA_LHPF4_ENA_SHIFT, 0,
+		 NULL, 0),
+
+SND_SOC_DAPM_PGA("ASRC1IN1L", MADERA_ASRC1_ENABLE, MADERA_ASRC1_IN1L_ENA_SHIFT,
+		 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC1IN1R", MADERA_ASRC1_ENABLE, MADERA_ASRC1_IN1R_ENA_SHIFT,
+		 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC1IN2L", MADERA_ASRC1_ENABLE, MADERA_ASRC1_IN2L_ENA_SHIFT,
+		 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC1IN2R", MADERA_ASRC1_ENABLE, MADERA_ASRC1_IN2R_ENA_SHIFT,
+		 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ASRC2IN1L", MADERA_ASRC2_ENABLE, MADERA_ASRC2_IN1L_ENA_SHIFT,
+		 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC2IN1R", MADERA_ASRC2_ENABLE, MADERA_ASRC2_IN1R_ENA_SHIFT,
+		 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC2IN2L", MADERA_ASRC2_ENABLE, MADERA_ASRC2_IN2L_ENA_SHIFT,
+		 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC2IN2R", MADERA_ASRC2_ENABLE, MADERA_ASRC2_IN2R_ENA_SHIFT,
+		 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC1DEC1", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC2", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC3", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC4", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC1INT1", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT2", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT3", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT4", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC2DEC1", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC2", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC3", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC4", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC2INT1", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT2", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT3", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT4", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC3DEC1", MADERA_ISRC_3_CTRL_3,
+		 MADERA_ISRC3_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC3DEC2", MADERA_ISRC_3_CTRL_3,
+		 MADERA_ISRC3_DEC2_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC3INT1", MADERA_ISRC_3_CTRL_3,
+		 MADERA_ISRC3_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC3INT2", MADERA_ISRC_3_CTRL_3,
+		 MADERA_ISRC3_INT2_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC4DEC1", MADERA_ISRC_4_CTRL_3,
+		 MADERA_ISRC4_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC4DEC2", MADERA_ISRC_4_CTRL_3,
+		 MADERA_ISRC4_DEC2_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC4INT1", MADERA_ISRC_4_CTRL_3,
+		 MADERA_ISRC4_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC4INT2", MADERA_ISRC_4_CTRL_3,
+		 MADERA_ISRC4_INT2_ENA_SHIFT, 0, NULL, 0),
+
+WM_ADSP2("DSP1", 0, cs47l85_adsp_power_ev),
+WM_ADSP2("DSP2", 1, cs47l85_adsp_power_ev),
+WM_ADSP2("DSP3", 2, cs47l85_adsp_power_ev),
+WM_ADSP2("DSP4", 3, cs47l85_adsp_power_ev),
+WM_ADSP2("DSP5", 4, cs47l85_adsp_power_ev),
+WM_ADSP2("DSP6", 5, cs47l85_adsp_power_ev),
+WM_ADSP2("DSP7", 6, cs47l85_adsp_power_ev),
+
+/* End of ordered input mux widgets */
+
+MADERA_MIXER_WIDGETS(EQ1, "EQ1"),
+MADERA_MIXER_WIDGETS(EQ2, "EQ2"),
+MADERA_MIXER_WIDGETS(EQ3, "EQ3"),
+MADERA_MIXER_WIDGETS(EQ4, "EQ4"),
+
+MADERA_MIXER_WIDGETS(DRC1L, "DRC1L"),
+MADERA_MIXER_WIDGETS(DRC1R, "DRC1R"),
+MADERA_MIXER_WIDGETS(DRC2L, "DRC2L"),
+MADERA_MIXER_WIDGETS(DRC2R, "DRC2R"),
+
+SND_SOC_DAPM_SWITCH("DRC1 Activity Output", SND_SOC_NOPM, 0, 0,
+		    &madera_drc_activity_output_mux[0]),
+SND_SOC_DAPM_SWITCH("DRC2 Activity Output", SND_SOC_NOPM, 0, 0,
+		    &madera_drc_activity_output_mux[1]),
+
+MADERA_MIXER_WIDGETS(LHPF1, "LHPF1"),
+MADERA_MIXER_WIDGETS(LHPF2, "LHPF2"),
+MADERA_MIXER_WIDGETS(LHPF3, "LHPF3"),
+MADERA_MIXER_WIDGETS(LHPF4, "LHPF4"),
+
+MADERA_MIXER_WIDGETS(PWM1, "PWM1"),
+MADERA_MIXER_WIDGETS(PWM2, "PWM2"),
+
+MADERA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
+MADERA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
+MADERA_MIXER_WIDGETS(OUT2L, "HPOUT2L"),
+MADERA_MIXER_WIDGETS(OUT2R, "HPOUT2R"),
+MADERA_MIXER_WIDGETS(OUT3L, "HPOUT3L"),
+MADERA_MIXER_WIDGETS(OUT3R, "HPOUT3R"),
+MADERA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
+MADERA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
+MADERA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
+MADERA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
+MADERA_MIXER_WIDGETS(SPKDAT2L, "SPKDAT2L"),
+MADERA_MIXER_WIDGETS(SPKDAT2R, "SPKDAT2R"),
+
+MADERA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
+MADERA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
+MADERA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
+MADERA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
+MADERA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
+MADERA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
+MADERA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
+MADERA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
+
+MADERA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
+MADERA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
+MADERA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"),
+MADERA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"),
+MADERA_MIXER_WIDGETS(AIF2TX5, "AIF2TX5"),
+MADERA_MIXER_WIDGETS(AIF2TX6, "AIF2TX6"),
+MADERA_MIXER_WIDGETS(AIF2TX7, "AIF2TX7"),
+MADERA_MIXER_WIDGETS(AIF2TX8, "AIF2TX8"),
+
+MADERA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
+MADERA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
+
+MADERA_MIXER_WIDGETS(AIF4TX1, "AIF4TX1"),
+MADERA_MIXER_WIDGETS(AIF4TX2, "AIF4TX2"),
+
+MADERA_MIXER_WIDGETS(SLIMTX1, "SLIMTX1"),
+MADERA_MIXER_WIDGETS(SLIMTX2, "SLIMTX2"),
+MADERA_MIXER_WIDGETS(SLIMTX3, "SLIMTX3"),
+MADERA_MIXER_WIDGETS(SLIMTX4, "SLIMTX4"),
+MADERA_MIXER_WIDGETS(SLIMTX5, "SLIMTX5"),
+MADERA_MIXER_WIDGETS(SLIMTX6, "SLIMTX6"),
+MADERA_MIXER_WIDGETS(SLIMTX7, "SLIMTX7"),
+MADERA_MIXER_WIDGETS(SLIMTX8, "SLIMTX8"),
+
+MADERA_MUX_WIDGETS(SPD1TX1, "SPDIF1TX1"),
+MADERA_MUX_WIDGETS(SPD1TX2, "SPDIF1TX2"),
+
+MADERA_MUX_WIDGETS(ASRC1IN1L, "ASRC1IN1L"),
+MADERA_MUX_WIDGETS(ASRC1IN1R, "ASRC1IN1R"),
+MADERA_MUX_WIDGETS(ASRC1IN2L, "ASRC1IN2L"),
+MADERA_MUX_WIDGETS(ASRC1IN2R, "ASRC1IN2R"),
+MADERA_MUX_WIDGETS(ASRC2IN1L, "ASRC2IN1L"),
+MADERA_MUX_WIDGETS(ASRC2IN1R, "ASRC2IN1R"),
+MADERA_MUX_WIDGETS(ASRC2IN2L, "ASRC2IN2L"),
+MADERA_MUX_WIDGETS(ASRC2IN2R, "ASRC2IN2R"),
+
+MADERA_DSP_WIDGETS(DSP1, "DSP1"),
+MADERA_DSP_WIDGETS(DSP2, "DSP2"),
+MADERA_DSP_WIDGETS(DSP3, "DSP3"),
+MADERA_DSP_WIDGETS(DSP4, "DSP4"),
+MADERA_DSP_WIDGETS(DSP5, "DSP5"),
+MADERA_DSP_WIDGETS(DSP6, "DSP6"),
+MADERA_DSP_WIDGETS(DSP7, "DSP7"),
+
+SND_SOC_DAPM_SWITCH("DSP1 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[0]),
+SND_SOC_DAPM_SWITCH("DSP2 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[1]),
+SND_SOC_DAPM_SWITCH("DSP3 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[2]),
+SND_SOC_DAPM_SWITCH("DSP4 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[3]),
+SND_SOC_DAPM_SWITCH("DSP5 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[4]),
+SND_SOC_DAPM_SWITCH("DSP6 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[5]),
+SND_SOC_DAPM_SWITCH("DSP7 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[6]),
+
+MADERA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
+MADERA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
+MADERA_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
+MADERA_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
+
+MADERA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
+MADERA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
+MADERA_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
+MADERA_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
+
+MADERA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
+MADERA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
+MADERA_MUX_WIDGETS(ISRC2DEC3, "ISRC2DEC3"),
+MADERA_MUX_WIDGETS(ISRC2DEC4, "ISRC2DEC4"),
+
+MADERA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
+MADERA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
+MADERA_MUX_WIDGETS(ISRC2INT3, "ISRC2INT3"),
+MADERA_MUX_WIDGETS(ISRC2INT4, "ISRC2INT4"),
+
+MADERA_MUX_WIDGETS(ISRC3DEC1, "ISRC3DEC1"),
+MADERA_MUX_WIDGETS(ISRC3DEC2, "ISRC3DEC2"),
+
+MADERA_MUX_WIDGETS(ISRC3INT1, "ISRC3INT1"),
+MADERA_MUX_WIDGETS(ISRC3INT2, "ISRC3INT2"),
+
+MADERA_MUX_WIDGETS(ISRC4DEC1, "ISRC4DEC1"),
+MADERA_MUX_WIDGETS(ISRC4DEC2, "ISRC4DEC2"),
+
+MADERA_MUX_WIDGETS(ISRC4INT1, "ISRC4INT1"),
+MADERA_MUX_WIDGETS(ISRC4INT2, "ISRC4INT2"),
+
+SND_SOC_DAPM_OUTPUT("HPOUT1L"),
+SND_SOC_DAPM_OUTPUT("HPOUT1R"),
+SND_SOC_DAPM_OUTPUT("HPOUT2L"),
+SND_SOC_DAPM_OUTPUT("HPOUT2R"),
+SND_SOC_DAPM_OUTPUT("HPOUT3L"),
+SND_SOC_DAPM_OUTPUT("HPOUT3R"),
+SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
+SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
+SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
+SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
+SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
+SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
+SND_SOC_DAPM_OUTPUT("SPKDAT2L"),
+SND_SOC_DAPM_OUTPUT("SPKDAT2R"),
+SND_SOC_DAPM_OUTPUT("SPDIF1"),
+
+SND_SOC_DAPM_OUTPUT("MICSUPP"),
+};
+
+#define MADERA_MIXER_INPUT_ROUTES(name)	\
+	{ name, "Noise Generator", "Noise Generator" }, \
+	{ name, "Tone Generator 1", "Tone Generator 1" }, \
+	{ name, "Tone Generator 2", "Tone Generator 2" }, \
+	{ name, "Haptics", "HAPTICS" }, \
+	{ name, "AEC1", "AEC1 Loopback" }, \
+	{ name, "AEC2", "AEC2 Loopback" }, \
+	{ name, "IN1L", "IN1L PGA" }, \
+	{ name, "IN1R", "IN1R PGA" }, \
+	{ name, "IN2L", "IN2L PGA" }, \
+	{ name, "IN2R", "IN2R PGA" }, \
+	{ name, "IN3L", "IN3L PGA" }, \
+	{ name, "IN3R", "IN3R PGA" }, \
+	{ name, "IN4L", "IN4L PGA" }, \
+	{ name, "IN4R", "IN4R PGA" }, \
+	{ name, "IN5L", "IN5L PGA" }, \
+	{ name, "IN5R", "IN5R PGA" }, \
+	{ name, "IN6L", "IN6L PGA" }, \
+	{ name, "IN6R", "IN6R PGA" }, \
+	{ name, "AIF1RX1", "AIF1RX1" }, \
+	{ name, "AIF1RX2", "AIF1RX2" }, \
+	{ name, "AIF1RX3", "AIF1RX3" }, \
+	{ name, "AIF1RX4", "AIF1RX4" }, \
+	{ name, "AIF1RX5", "AIF1RX5" }, \
+	{ name, "AIF1RX6", "AIF1RX6" }, \
+	{ name, "AIF1RX7", "AIF1RX7" }, \
+	{ name, "AIF1RX8", "AIF1RX8" }, \
+	{ name, "AIF2RX1", "AIF2RX1" }, \
+	{ name, "AIF2RX2", "AIF2RX2" }, \
+	{ name, "AIF2RX3", "AIF2RX3" }, \
+	{ name, "AIF2RX4", "AIF2RX4" }, \
+	{ name, "AIF2RX5", "AIF2RX5" }, \
+	{ name, "AIF2RX6", "AIF2RX6" }, \
+	{ name, "AIF2RX7", "AIF2RX7" }, \
+	{ name, "AIF2RX8", "AIF2RX8" }, \
+	{ name, "AIF3RX1", "AIF3RX1" }, \
+	{ name, "AIF3RX2", "AIF3RX2" }, \
+	{ name, "AIF4RX1", "AIF4RX1" }, \
+	{ name, "AIF4RX2", "AIF4RX2" }, \
+	{ name, "SLIMRX1", "SLIMRX1" }, \
+	{ name, "SLIMRX2", "SLIMRX2" }, \
+	{ name, "SLIMRX3", "SLIMRX3" }, \
+	{ name, "SLIMRX4", "SLIMRX4" }, \
+	{ name, "SLIMRX5", "SLIMRX5" }, \
+	{ name, "SLIMRX6", "SLIMRX6" }, \
+	{ name, "SLIMRX7", "SLIMRX7" }, \
+	{ name, "SLIMRX8", "SLIMRX8" }, \
+	{ name, "EQ1", "EQ1" }, \
+	{ name, "EQ2", "EQ2" }, \
+	{ name, "EQ3", "EQ3" }, \
+	{ name, "EQ4", "EQ4" }, \
+	{ name, "DRC1L", "DRC1L" }, \
+	{ name, "DRC1R", "DRC1R" }, \
+	{ name, "DRC2L", "DRC2L" }, \
+	{ name, "DRC2R", "DRC2R" }, \
+	{ name, "LHPF1", "LHPF1" }, \
+	{ name, "LHPF2", "LHPF2" }, \
+	{ name, "LHPF3", "LHPF3" }, \
+	{ name, "LHPF4", "LHPF4" }, \
+	{ name, "ASRC1IN1L", "ASRC1IN1L" }, \
+	{ name, "ASRC1IN1R", "ASRC1IN1R" }, \
+	{ name, "ASRC1IN2L", "ASRC1IN2L" }, \
+	{ name, "ASRC1IN2R", "ASRC1IN2R" }, \
+	{ name, "ASRC2IN1L", "ASRC2IN1L" }, \
+	{ name, "ASRC2IN1R", "ASRC2IN1R" }, \
+	{ name, "ASRC2IN2L", "ASRC2IN2L" }, \
+	{ name, "ASRC2IN2R", "ASRC2IN2R" }, \
+	{ name, "ISRC1DEC1", "ISRC1DEC1" }, \
+	{ name, "ISRC1DEC2", "ISRC1DEC2" }, \
+	{ name, "ISRC1DEC3", "ISRC1DEC3" }, \
+	{ name, "ISRC1DEC4", "ISRC1DEC4" }, \
+	{ name, "ISRC1INT1", "ISRC1INT1" }, \
+	{ name, "ISRC1INT2", "ISRC1INT2" }, \
+	{ name, "ISRC1INT3", "ISRC1INT3" }, \
+	{ name, "ISRC1INT4", "ISRC1INT4" }, \
+	{ name, "ISRC2DEC1", "ISRC2DEC1" }, \
+	{ name, "ISRC2DEC2", "ISRC2DEC2" }, \
+	{ name, "ISRC2DEC3", "ISRC2DEC3" }, \
+	{ name, "ISRC2DEC4", "ISRC2DEC4" }, \
+	{ name, "ISRC2INT1", "ISRC2INT1" }, \
+	{ name, "ISRC2INT2", "ISRC2INT2" }, \
+	{ name, "ISRC2INT3", "ISRC2INT3" }, \
+	{ name, "ISRC2INT4", "ISRC2INT4" }, \
+	{ name, "ISRC3DEC1", "ISRC3DEC1" }, \
+	{ name, "ISRC3DEC2", "ISRC3DEC2" }, \
+	{ name, "ISRC3INT1", "ISRC3INT1" }, \
+	{ name, "ISRC3INT2", "ISRC3INT2" }, \
+	{ name, "ISRC4DEC1", "ISRC4DEC1" }, \
+	{ name, "ISRC4DEC2", "ISRC4DEC2" }, \
+	{ name, "ISRC4INT1", "ISRC4INT1" }, \
+	{ name, "ISRC4INT2", "ISRC4INT2" }, \
+	{ name, "DSP1.1", "DSP1" }, \
+	{ name, "DSP1.2", "DSP1" }, \
+	{ name, "DSP1.3", "DSP1" }, \
+	{ name, "DSP1.4", "DSP1" }, \
+	{ name, "DSP1.5", "DSP1" }, \
+	{ name, "DSP1.6", "DSP1" }, \
+	{ name, "DSP2.1", "DSP2" }, \
+	{ name, "DSP2.2", "DSP2" }, \
+	{ name, "DSP2.3", "DSP2" }, \
+	{ name, "DSP2.4", "DSP2" }, \
+	{ name, "DSP2.5", "DSP2" }, \
+	{ name, "DSP2.6", "DSP2" }, \
+	{ name, "DSP3.1", "DSP3" }, \
+	{ name, "DSP3.2", "DSP3" }, \
+	{ name, "DSP3.3", "DSP3" }, \
+	{ name, "DSP3.4", "DSP3" }, \
+	{ name, "DSP3.5", "DSP3" }, \
+	{ name, "DSP3.6", "DSP3" }, \
+	{ name, "DSP4.1", "DSP4" }, \
+	{ name, "DSP4.2", "DSP4" }, \
+	{ name, "DSP4.3", "DSP4" }, \
+	{ name, "DSP4.4", "DSP4" }, \
+	{ name, "DSP4.5", "DSP4" }, \
+	{ name, "DSP4.6", "DSP4" }, \
+	{ name, "DSP5.1", "DSP5" }, \
+	{ name, "DSP5.2", "DSP5" }, \
+	{ name, "DSP5.3", "DSP5" }, \
+	{ name, "DSP5.4", "DSP5" }, \
+	{ name, "DSP5.5", "DSP5" }, \
+	{ name, "DSP5.6", "DSP5" }, \
+	{ name, "DSP6.1", "DSP6" }, \
+	{ name, "DSP6.2", "DSP6" }, \
+	{ name, "DSP6.3", "DSP6" }, \
+	{ name, "DSP6.4", "DSP6" }, \
+	{ name, "DSP6.5", "DSP6" }, \
+	{ name, "DSP6.6", "DSP6" }, \
+	{ name, "DSP7.1", "DSP7" }, \
+	{ name, "DSP7.2", "DSP7" }, \
+	{ name, "DSP7.3", "DSP7" }, \
+	{ name, "DSP7.4", "DSP7" }, \
+	{ name, "DSP7.5", "DSP7" }, \
+	{ name, "DSP7.6", "DSP7" }
+
+static const struct snd_soc_dapm_route cs47l85_dapm_routes[] = {
+	/* Internal clock domains */
+	{ "EQ1", NULL, "FXCLK" },
+	{ "EQ2", NULL, "FXCLK" },
+	{ "EQ3", NULL, "FXCLK" },
+	{ "EQ4", NULL, "FXCLK" },
+	{ "DRC1L", NULL, "FXCLK" },
+	{ "DRC1R", NULL, "FXCLK" },
+	{ "DRC2L", NULL, "FXCLK" },
+	{ "DRC2R", NULL, "FXCLK" },
+	{ "LHPF1", NULL, "FXCLK" },
+	{ "LHPF2", NULL, "FXCLK" },
+	{ "LHPF3", NULL, "FXCLK" },
+	{ "LHPF4", NULL, "FXCLK" },
+	{ "PWM1 Mixer", NULL, "PWMCLK" },
+	{ "PWM2 Mixer", NULL, "PWMCLK" },
+	{ "OUT1L", NULL, "OUTCLK" },
+	{ "OUT1R", NULL, "OUTCLK" },
+	{ "OUT2L", NULL, "OUTCLK" },
+	{ "OUT2R", NULL, "OUTCLK" },
+	{ "OUT3L", NULL, "OUTCLK" },
+	{ "OUT3R", NULL, "OUTCLK" },
+	{ "OUT4L", NULL, "OUTCLK" },
+	{ "OUT4R", NULL, "OUTCLK" },
+	{ "OUT5L", NULL, "OUTCLK" },
+	{ "OUT5R", NULL, "OUTCLK" },
+	{ "OUT6L", NULL, "OUTCLK" },
+	{ "OUT6R", NULL, "OUTCLK" },
+	{ "AIF1TX1", NULL, "AIF1TXCLK" },
+	{ "AIF1TX2", NULL, "AIF1TXCLK" },
+	{ "AIF1TX3", NULL, "AIF1TXCLK" },
+	{ "AIF1TX4", NULL, "AIF1TXCLK" },
+	{ "AIF1TX5", NULL, "AIF1TXCLK" },
+	{ "AIF1TX6", NULL, "AIF1TXCLK" },
+	{ "AIF1TX7", NULL, "AIF1TXCLK" },
+	{ "AIF1TX8", NULL, "AIF1TXCLK" },
+	{ "AIF2TX1", NULL, "AIF2TXCLK" },
+	{ "AIF2TX2", NULL, "AIF2TXCLK" },
+	{ "AIF2TX3", NULL, "AIF2TXCLK" },
+	{ "AIF2TX4", NULL, "AIF2TXCLK" },
+	{ "AIF2TX5", NULL, "AIF2TXCLK" },
+	{ "AIF2TX6", NULL, "AIF2TXCLK" },
+	{ "AIF2TX7", NULL, "AIF2TXCLK" },
+	{ "AIF2TX8", NULL, "AIF2TXCLK" },
+	{ "AIF3TX1", NULL, "AIF3TXCLK" },
+	{ "AIF3TX2", NULL, "AIF3TXCLK" },
+	{ "AIF4TX1", NULL, "AIF3TXCLK" },
+	{ "AIF4TX2", NULL, "AIF3TXCLK" },
+	{ "SLIMTX1", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX2", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX3", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX4", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX5", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX6", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX7", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX8", NULL, "SLIMBUSCLK" },
+	{ "SPD1TX1", NULL, "SPDCLK" },
+	{ "SPD1TX2", NULL, "SPDCLK" },
+	{ "DSP1", NULL, "DSP1CLK" },
+	{ "DSP2", NULL, "DSP2CLK" },
+	{ "DSP3", NULL, "DSP3CLK" },
+	{ "DSP4", NULL, "DSP4CLK" },
+	{ "DSP5", NULL, "DSP5CLK" },
+	{ "DSP6", NULL, "DSP6CLK" },
+	{ "DSP7", NULL, "DSP7CLK" },
+	{ "ISRC1DEC1", NULL, "ISRC1DECCLK" },
+	{ "ISRC1DEC2", NULL, "ISRC1DECCLK" },
+	{ "ISRC1DEC3", NULL, "ISRC1DECCLK" },
+	{ "ISRC1DEC4", NULL, "ISRC1DECCLK" },
+	{ "ISRC1INT1", NULL, "ISRC1INTCLK" },
+	{ "ISRC1INT2", NULL, "ISRC1INTCLK" },
+	{ "ISRC1INT3", NULL, "ISRC1INTCLK" },
+	{ "ISRC1INT4", NULL, "ISRC1INTCLK" },
+	{ "ISRC2DEC1", NULL, "ISRC2DECCLK" },
+	{ "ISRC2DEC2", NULL, "ISRC2DECCLK" },
+	{ "ISRC2DEC3", NULL, "ISRC2DECCLK" },
+	{ "ISRC2DEC4", NULL, "ISRC2DECCLK" },
+	{ "ISRC2INT1", NULL, "ISRC2INTCLK" },
+	{ "ISRC2INT2", NULL, "ISRC2INTCLK" },
+	{ "ISRC2INT3", NULL, "ISRC2INTCLK" },
+	{ "ISRC2INT4", NULL, "ISRC2INTCLK" },
+	{ "ISRC3DEC1", NULL, "ISRC1DECCLK" },
+	{ "ISRC3DEC2", NULL, "ISRC1DECCLK" },
+	{ "ISRC3INT1", NULL, "ISRC1INTCLK" },
+	{ "ISRC3INT2", NULL, "ISRC1INTCLK" },
+	{ "ISRC4DEC1", NULL, "ISRC1DECCLK" },
+	{ "ISRC4DEC2", NULL, "ISRC1DECCLK" },
+	{ "ISRC4INT1", NULL, "ISRC1INTCLK" },
+	{ "ISRC4INT2", NULL, "ISRC1INTCLK" },
+	{ "ASRC1IN1L", NULL, "ASRC1R1CLK" },
+	{ "ASRC1IN1R", NULL, "ASRC1R1CLK" },
+	{ "ASRC1IN2L", NULL, "ASRC1R2CLK" },
+	{ "ASRC1IN2L", NULL, "ASRC1R2CLK" },
+	{ "ASRC2IN1L", NULL, "ASRC2R1CLK" },
+	{ "ASRC2IN1R", NULL, "ASRC2R1CLK" },
+	{ "ASRC2IN2L", NULL, "ASRC2R2CLK" },
+	{ "ASRC2IN2L", NULL, "ASRC2R2CLK" },
+
+	{ "AIF2 Capture", NULL, "DBVDD2" },
+	{ "AIF2 Playback", NULL, "DBVDD2" },
+
+	{ "AIF3 Capture", NULL, "DBVDD3" },
+	{ "AIF3 Playback", NULL, "DBVDD3" },
+
+	{ "AIF4 Capture", NULL, "DBVDD3" },
+	{ "AIF4 Playback", NULL, "DBVDD3" },
+
+	{ "OUT1L", NULL, "CPVDD1" },
+	{ "OUT1L", NULL, "CPVDD2" },
+	{ "OUT1R", NULL, "CPVDD1" },
+	{ "OUT1R", NULL, "CPVDD2" },
+	{ "OUT2L", NULL, "CPVDD1" },
+	{ "OUT2L", NULL, "CPVDD2" },
+	{ "OUT2R", NULL, "CPVDD1" },
+	{ "OUT2R", NULL, "CPVDD2" },
+	{ "OUT3L", NULL, "CPVDD1" },
+	{ "OUT3L", NULL, "CPVDD2" },
+	{ "OUT3R", NULL, "CPVDD1" },
+	{ "OUT3R", NULL, "CPVDD2" },
+
+	{ "OUT4L", NULL, "SPKVDDL" },
+	{ "OUT4R", NULL, "SPKVDDR" },
+
+	{ "OUT1L", NULL, "SYSCLK" },
+	{ "OUT1R", NULL, "SYSCLK" },
+	{ "OUT2L", NULL, "SYSCLK" },
+	{ "OUT2R", NULL, "SYSCLK" },
+	{ "OUT3L", NULL, "SYSCLK" },
+	{ "OUT3R", NULL, "SYSCLK" },
+	{ "OUT4L", NULL, "SYSCLK" },
+	{ "OUT4R", NULL, "SYSCLK" },
+	{ "OUT5L", NULL, "SYSCLK" },
+	{ "OUT5R", NULL, "SYSCLK" },
+	{ "OUT6L", NULL, "SYSCLK" },
+	{ "OUT6R", NULL, "SYSCLK" },
+
+	{ "SPD1", NULL, "SYSCLK" },
+	{ "SPD1", NULL, "SPD1TX1" },
+	{ "SPD1", NULL, "SPD1TX2" },
+
+	{ "IN1AL", NULL, "SYSCLK" },
+	{ "IN1B", NULL, "SYSCLK" },
+	{ "IN1R", NULL, "SYSCLK" },
+	{ "IN2AL", NULL, "SYSCLK" },
+	{ "IN2AR", NULL, "SYSCLK" },
+	{ "IN2BL", NULL, "SYSCLK" },
+	{ "IN2BR", NULL, "SYSCLK" },
+	{ "IN3L", NULL, "SYSCLK" },
+	{ "IN3R", NULL, "SYSCLK" },
+	{ "IN4L", NULL, "SYSCLK" },
+	{ "IN4R", NULL, "SYSCLK" },
+	{ "IN5L", NULL, "SYSCLK" },
+	{ "IN5R", NULL, "SYSCLK" },
+	{ "IN6L", NULL, "SYSCLK" },
+	{ "IN6R", NULL, "SYSCLK" },
+
+	{ "IN4L", NULL, "DBVDD4" },
+	{ "IN4R", NULL, "DBVDD4" },
+	{ "IN5L", NULL, "DBVDD4" },
+	{ "IN5R", NULL, "DBVDD4" },
+	{ "IN6L", NULL, "DBVDD4" },
+	{ "IN6R", NULL, "DBVDD4" },
+
+	{ "ASRC1IN1L", NULL, "SYSCLK" },
+	{ "ASRC1IN1R", NULL, "SYSCLK" },
+	{ "ASRC1IN2L", NULL, "SYSCLK" },
+	{ "ASRC1IN2R", NULL, "SYSCLK" },
+	{ "ASRC2IN1L", NULL, "SYSCLK" },
+	{ "ASRC2IN1R", NULL, "SYSCLK" },
+	{ "ASRC2IN2L", NULL, "SYSCLK" },
+	{ "ASRC2IN2R", NULL, "SYSCLK" },
+
+	{ "ASRC1IN1L", NULL, "ASYNCCLK" },
+	{ "ASRC1IN1R", NULL, "ASYNCCLK" },
+	{ "ASRC1IN2L", NULL, "ASYNCCLK" },
+	{ "ASRC1IN2R", NULL, "ASYNCCLK" },
+	{ "ASRC2IN1L", NULL, "ASYNCCLK" },
+	{ "ASRC2IN1R", NULL, "ASYNCCLK" },
+	{ "ASRC2IN2L", NULL, "ASYNCCLK" },
+	{ "ASRC2IN2R", NULL, "ASYNCCLK" },
+
+	{ "MICBIAS1", NULL, "MICVDD" },
+	{ "MICBIAS2", NULL, "MICVDD" },
+	{ "MICBIAS3", NULL, "MICVDD" },
+	{ "MICBIAS4", NULL, "MICVDD" },
+
+	{ "Noise Generator", NULL, "SYSCLK" },
+	{ "Tone Generator 1", NULL, "SYSCLK" },
+	{ "Tone Generator 2", NULL, "SYSCLK" },
+
+	{ "Noise Generator", NULL, "NOISE" },
+	{ "Tone Generator 1", NULL, "TONE" },
+	{ "Tone Generator 2", NULL, "TONE" },
+
+	{ "AIF1 Capture", NULL, "AIF1TX1" },
+	{ "AIF1 Capture", NULL, "AIF1TX2" },
+	{ "AIF1 Capture", NULL, "AIF1TX3" },
+	{ "AIF1 Capture", NULL, "AIF1TX4" },
+	{ "AIF1 Capture", NULL, "AIF1TX5" },
+	{ "AIF1 Capture", NULL, "AIF1TX6" },
+	{ "AIF1 Capture", NULL, "AIF1TX7" },
+	{ "AIF1 Capture", NULL, "AIF1TX8" },
+
+	{ "AIF1RX1", NULL, "AIF1 Playback" },
+	{ "AIF1RX2", NULL, "AIF1 Playback" },
+	{ "AIF1RX3", NULL, "AIF1 Playback" },
+	{ "AIF1RX4", NULL, "AIF1 Playback" },
+	{ "AIF1RX5", NULL, "AIF1 Playback" },
+	{ "AIF1RX6", NULL, "AIF1 Playback" },
+	{ "AIF1RX7", NULL, "AIF1 Playback" },
+	{ "AIF1RX8", NULL, "AIF1 Playback" },
+
+	{ "AIF2 Capture", NULL, "AIF2TX1" },
+	{ "AIF2 Capture", NULL, "AIF2TX2" },
+	{ "AIF2 Capture", NULL, "AIF2TX3" },
+	{ "AIF2 Capture", NULL, "AIF2TX4" },
+	{ "AIF2 Capture", NULL, "AIF2TX5" },
+	{ "AIF2 Capture", NULL, "AIF2TX6" },
+	{ "AIF2 Capture", NULL, "AIF2TX7" },
+	{ "AIF2 Capture", NULL, "AIF2TX8" },
+
+	{ "AIF2RX1", NULL, "AIF2 Playback" },
+	{ "AIF2RX2", NULL, "AIF2 Playback" },
+	{ "AIF2RX3", NULL, "AIF2 Playback" },
+	{ "AIF2RX4", NULL, "AIF2 Playback" },
+	{ "AIF2RX5", NULL, "AIF2 Playback" },
+	{ "AIF2RX6", NULL, "AIF2 Playback" },
+	{ "AIF2RX7", NULL, "AIF2 Playback" },
+	{ "AIF2RX8", NULL, "AIF2 Playback" },
+
+	{ "AIF3 Capture", NULL, "AIF3TX1" },
+	{ "AIF3 Capture", NULL, "AIF3TX2" },
+
+	{ "AIF3RX1", NULL, "AIF3 Playback" },
+	{ "AIF3RX2", NULL, "AIF3 Playback" },
+
+	{ "AIF4 Capture", NULL, "AIF4TX1" },
+	{ "AIF4 Capture", NULL, "AIF4TX2" },
+
+	{ "AIF4RX1", NULL, "AIF4 Playback" },
+	{ "AIF4RX2", NULL, "AIF4 Playback" },
+
+	{ "Slim1 Capture", NULL, "SLIMTX1" },
+	{ "Slim1 Capture", NULL, "SLIMTX2" },
+	{ "Slim1 Capture", NULL, "SLIMTX3" },
+	{ "Slim1 Capture", NULL, "SLIMTX4" },
+
+	{ "SLIMRX1", NULL, "Slim1 Playback" },
+	{ "SLIMRX2", NULL, "Slim1 Playback" },
+	{ "SLIMRX3", NULL, "Slim1 Playback" },
+	{ "SLIMRX4", NULL, "Slim1 Playback" },
+
+	{ "Slim2 Capture", NULL, "SLIMTX5" },
+	{ "Slim2 Capture", NULL, "SLIMTX6" },
+
+	{ "SLIMRX5", NULL, "Slim2 Playback" },
+	{ "SLIMRX6", NULL, "Slim2 Playback" },
+
+	{ "Slim3 Capture", NULL, "SLIMTX7" },
+	{ "Slim3 Capture", NULL, "SLIMTX8" },
+
+	{ "SLIMRX7", NULL, "Slim3 Playback" },
+	{ "SLIMRX8", NULL, "Slim3 Playback" },
+
+	{ "AIF1 Playback", NULL, "SYSCLK" },
+	{ "AIF2 Playback", NULL, "SYSCLK" },
+	{ "AIF3 Playback", NULL, "SYSCLK" },
+	{ "AIF4 Playback", NULL, "SYSCLK" },
+	{ "Slim1 Playback", NULL, "SYSCLK" },
+	{ "Slim2 Playback", NULL, "SYSCLK" },
+	{ "Slim3 Playback", NULL, "SYSCLK" },
+
+	{ "AIF1 Capture", NULL, "SYSCLK" },
+	{ "AIF2 Capture", NULL, "SYSCLK" },
+	{ "AIF3 Capture", NULL, "SYSCLK" },
+	{ "AIF4 Capture", NULL, "SYSCLK" },
+	{ "Slim1 Capture", NULL, "SYSCLK" },
+	{ "Slim2 Capture", NULL, "SYSCLK" },
+	{ "Slim3 Capture", NULL, "SYSCLK" },
+
+	{ "Voice Control DSP", NULL, "DSP6" },
+
+	{ "Audio Trace DSP", NULL, "DSP1" },
+
+	{ "IN1L Mux", "A", "IN1AL" },
+	{ "IN1L Mux", "B", "IN1B" },
+
+	{ "IN2L Mux", "A", "IN2AL" },
+	{ "IN2L Mux", "B", "IN2BL" },
+	{ "IN2R Mux", "A", "IN2AR" },
+	{ "IN2R Mux", "B", "IN2BR" },
+
+	{ "IN1L PGA", NULL, "IN1L Mux" },
+	{ "IN1R PGA", NULL, "IN1R" },
+
+	{ "IN2L PGA", NULL, "IN2L Mux" },
+	{ "IN2R PGA", NULL, "IN2R Mux" },
+
+	{ "IN3L PGA", NULL, "IN3L" },
+	{ "IN3R PGA", NULL, "IN3R" },
+
+	{ "IN4L PGA", NULL, "IN4L" },
+	{ "IN4R PGA", NULL, "IN4R" },
+
+	{ "IN5L PGA", NULL, "IN5L" },
+	{ "IN5R PGA", NULL, "IN5R" },
+
+	{ "IN6L PGA", NULL, "IN6L" },
+	{ "IN6R PGA", NULL, "IN6R" },
+
+	MADERA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
+	MADERA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
+	MADERA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
+	MADERA_MIXER_ROUTES("OUT2R", "HPOUT2R"),
+	MADERA_MIXER_ROUTES("OUT3L", "HPOUT3L"),
+	MADERA_MIXER_ROUTES("OUT3R", "HPOUT3R"),
+
+	MADERA_MIXER_ROUTES("OUT4L", "SPKOUTL"),
+	MADERA_MIXER_ROUTES("OUT4R", "SPKOUTR"),
+	MADERA_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
+	MADERA_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
+	MADERA_MIXER_ROUTES("OUT6L", "SPKDAT2L"),
+	MADERA_MIXER_ROUTES("OUT6R", "SPKDAT2R"),
+
+	MADERA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
+	MADERA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
+
+	MADERA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
+	MADERA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
+	MADERA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
+	MADERA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
+	MADERA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
+	MADERA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
+	MADERA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
+	MADERA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
+
+	MADERA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
+	MADERA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
+	MADERA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"),
+	MADERA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"),
+	MADERA_MIXER_ROUTES("AIF2TX5", "AIF2TX5"),
+	MADERA_MIXER_ROUTES("AIF2TX6", "AIF2TX6"),
+	MADERA_MIXER_ROUTES("AIF2TX7", "AIF2TX7"),
+	MADERA_MIXER_ROUTES("AIF2TX8", "AIF2TX8"),
+
+	MADERA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
+	MADERA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
+
+	MADERA_MIXER_ROUTES("AIF4TX1", "AIF4TX1"),
+	MADERA_MIXER_ROUTES("AIF4TX2", "AIF4TX2"),
+
+	MADERA_MIXER_ROUTES("SLIMTX1", "SLIMTX1"),
+	MADERA_MIXER_ROUTES("SLIMTX2", "SLIMTX2"),
+	MADERA_MIXER_ROUTES("SLIMTX3", "SLIMTX3"),
+	MADERA_MIXER_ROUTES("SLIMTX4", "SLIMTX4"),
+	MADERA_MIXER_ROUTES("SLIMTX5", "SLIMTX5"),
+	MADERA_MIXER_ROUTES("SLIMTX6", "SLIMTX6"),
+	MADERA_MIXER_ROUTES("SLIMTX7", "SLIMTX7"),
+	MADERA_MIXER_ROUTES("SLIMTX8", "SLIMTX8"),
+
+	MADERA_MUX_ROUTES("SPD1TX1", "SPDIF1TX1"),
+	MADERA_MUX_ROUTES("SPD1TX2", "SPDIF1TX2"),
+
+	MADERA_MIXER_ROUTES("EQ1", "EQ1"),
+	MADERA_MIXER_ROUTES("EQ2", "EQ2"),
+	MADERA_MIXER_ROUTES("EQ3", "EQ3"),
+	MADERA_MIXER_ROUTES("EQ4", "EQ4"),
+
+	MADERA_MIXER_ROUTES("DRC1L", "DRC1L"),
+	MADERA_MIXER_ROUTES("DRC1R", "DRC1R"),
+	MADERA_MIXER_ROUTES("DRC2L", "DRC2L"),
+	MADERA_MIXER_ROUTES("DRC2R", "DRC2R"),
+
+	MADERA_MIXER_ROUTES("LHPF1", "LHPF1"),
+	MADERA_MIXER_ROUTES("LHPF2", "LHPF2"),
+	MADERA_MIXER_ROUTES("LHPF3", "LHPF3"),
+	MADERA_MIXER_ROUTES("LHPF4", "LHPF4"),
+
+	MADERA_MUX_ROUTES("ASRC1IN1L", "ASRC1IN1L"),
+	MADERA_MUX_ROUTES("ASRC1IN1R", "ASRC1IN1R"),
+	MADERA_MUX_ROUTES("ASRC1IN2L", "ASRC1IN2L"),
+	MADERA_MUX_ROUTES("ASRC1IN2R", "ASRC1IN2R"),
+	MADERA_MUX_ROUTES("ASRC2IN1L", "ASRC2IN1L"),
+	MADERA_MUX_ROUTES("ASRC2IN1R", "ASRC2IN1R"),
+	MADERA_MUX_ROUTES("ASRC2IN2L", "ASRC2IN2L"),
+	MADERA_MUX_ROUTES("ASRC2IN2R", "ASRC2IN2R"),
+
+	MADERA_DSP_ROUTES("DSP1"),
+	MADERA_DSP_ROUTES("DSP2"),
+	MADERA_DSP_ROUTES("DSP3"),
+	MADERA_DSP_ROUTES("DSP4"),
+	MADERA_DSP_ROUTES("DSP5"),
+	MADERA_DSP_ROUTES("DSP6"),
+	MADERA_DSP_ROUTES("DSP7"),
+
+	{ "DSP Trigger Out", NULL, "DSP1 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP2 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP3 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP4 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP5 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP6 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP7 Trigger Output" },
+
+	{ "DSP1 Trigger Output", "Switch", "DSP1" },
+	{ "DSP2 Trigger Output", "Switch", "DSP2" },
+	{ "DSP3 Trigger Output", "Switch", "DSP3" },
+	{ "DSP4 Trigger Output", "Switch", "DSP4" },
+	{ "DSP5 Trigger Output", "Switch", "DSP5" },
+	{ "DSP6 Trigger Output", "Switch", "DSP6" },
+	{ "DSP7 Trigger Output", "Switch", "DSP7" },
+
+	MADERA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
+	MADERA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
+	MADERA_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
+	MADERA_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
+
+	MADERA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
+	MADERA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
+	MADERA_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
+	MADERA_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
+
+	MADERA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
+	MADERA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
+	MADERA_MUX_ROUTES("ISRC2INT3", "ISRC2INT3"),
+	MADERA_MUX_ROUTES("ISRC2INT4", "ISRC2INT4"),
+
+	MADERA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
+	MADERA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
+	MADERA_MUX_ROUTES("ISRC2DEC3", "ISRC2DEC3"),
+	MADERA_MUX_ROUTES("ISRC2DEC4", "ISRC2DEC4"),
+
+	MADERA_MUX_ROUTES("ISRC3INT1", "ISRC3INT1"),
+	MADERA_MUX_ROUTES("ISRC3INT2", "ISRC3INT2"),
+
+	MADERA_MUX_ROUTES("ISRC3DEC1", "ISRC3DEC1"),
+	MADERA_MUX_ROUTES("ISRC3DEC2", "ISRC3DEC2"),
+
+	MADERA_MUX_ROUTES("ISRC4INT1", "ISRC4INT1"),
+	MADERA_MUX_ROUTES("ISRC4INT2", "ISRC4INT2"),
+
+	MADERA_MUX_ROUTES("ISRC4DEC1", "ISRC4DEC1"),
+	MADERA_MUX_ROUTES("ISRC4DEC2", "ISRC4DEC2"),
+
+	{ "AEC1 Loopback", "HPOUT1L", "OUT1L" },
+	{ "AEC1 Loopback", "HPOUT1R", "OUT1R" },
+	{ "AEC2 Loopback", "HPOUT1L", "OUT1L" },
+	{ "AEC2 Loopback", "HPOUT1R", "OUT1R" },
+	{ "HPOUT1L", NULL, "OUT1L" },
+	{ "HPOUT1R", NULL, "OUT1R" },
+
+	{ "AEC1 Loopback", "HPOUT2L", "OUT2L" },
+	{ "AEC1 Loopback", "HPOUT2R", "OUT2R" },
+	{ "AEC2 Loopback", "HPOUT2L", "OUT2L" },
+	{ "AEC2 Loopback", "HPOUT2R", "OUT2R" },
+	{ "HPOUT2L", NULL, "OUT2L" },
+	{ "HPOUT2R", NULL, "OUT2R" },
+
+	{ "AEC1 Loopback", "HPOUT3L", "OUT3L" },
+	{ "AEC1 Loopback", "HPOUT3R", "OUT3R" },
+	{ "AEC2 Loopback", "HPOUT3L", "OUT3L" },
+	{ "AEC2 Loopback", "HPOUT3R", "OUT3R" },
+	{ "HPOUT3L", NULL, "OUT3L" },
+	{ "HPOUT3R", NULL, "OUT3R" },
+
+	{ "AEC1 Loopback", "SPKOUTL", "OUT4L" },
+	{ "AEC2 Loopback", "SPKOUTL", "OUT4L" },
+	{ "SPKOUTLN", NULL, "OUT4L" },
+	{ "SPKOUTLP", NULL, "OUT4L" },
+
+	{ "AEC1 Loopback", "SPKOUTR", "OUT4R" },
+	{ "AEC2 Loopback", "SPKOUTR", "OUT4R" },
+	{ "SPKOUTRN", NULL, "OUT4R" },
+	{ "SPKOUTRP", NULL, "OUT4R" },
+
+	{ "AEC1 Loopback", "SPKDAT1L", "OUT5L" },
+	{ "AEC1 Loopback", "SPKDAT1R", "OUT5R" },
+	{ "AEC2 Loopback", "SPKDAT1L", "OUT5L" },
+	{ "AEC2 Loopback", "SPKDAT1R", "OUT5R" },
+	{ "SPKDAT1L", NULL, "OUT5L" },
+	{ "SPKDAT1R", NULL, "OUT5R" },
+
+	{ "AEC1 Loopback", "SPKDAT2L", "OUT6L" },
+	{ "AEC1 Loopback", "SPKDAT2R", "OUT6R" },
+	{ "AEC2 Loopback", "SPKDAT2L", "OUT6L" },
+	{ "AEC2 Loopback", "SPKDAT2R", "OUT6R" },
+	{ "SPKDAT2L", NULL, "OUT6L" },
+	{ "SPKDAT2R", NULL, "OUT6R" },
+
+	CS47L85_RXANC_INPUT_ROUTES("RXANCL", "RXANCL"),
+	CS47L85_RXANC_INPUT_ROUTES("RXANCR", "RXANCR"),
+
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT1L", "HPOUT1L"),
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT1R", "HPOUT1R"),
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT2L", "HPOUT2L"),
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT2R", "HPOUT2R"),
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT3L", "HPOUT3L"),
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT3R", "HPOUT3R"),
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT4L", "SPKOUTL"),
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT4R", "SPKOUTR"),
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT5L", "SPKDAT1L"),
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT5R", "SPKDAT1R"),
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT6L", "SPKDAT2L"),
+	CS47L85_RXANC_OUTPUT_ROUTES("OUT6R", "SPKDAT2R"),
+
+	{ "SPDIF1", NULL, "SPD1" },
+
+	{ "MICSUPP", NULL, "SYSCLK" },
+
+	{ "DRC1 Signal Activity", NULL, "DRC1 Activity Output" },
+	{ "DRC2 Signal Activity", NULL, "DRC2 Activity Output" },
+	{ "DRC1 Activity Output", "Switch", "DRC1L" },
+	{ "DRC1 Activity Output", "Switch", "DRC1R" },
+	{ "DRC2 Activity Output", "Switch", "DRC2L" },
+	{ "DRC2 Activity Output", "Switch", "DRC2R" },
+};
+
+static int cs47l85_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+			  unsigned int Fref, unsigned int Fout)
+{
+	struct cs47l85 *cs47l85 = snd_soc_codec_get_drvdata(codec);
+
+	switch (fll_id) {
+	case MADERA_FLL1_REFCLK:
+		return madera_set_fll_refclk(&cs47l85->fll[0], source, Fref,
+					     Fout);
+	case MADERA_FLL2_REFCLK:
+		return madera_set_fll_refclk(&cs47l85->fll[1], source, Fref,
+					     Fout);
+	case MADERA_FLL3_REFCLK:
+		return madera_set_fll_refclk(&cs47l85->fll[2], source, Fref,
+					     Fout);
+	case MADERA_FLL1_SYNCCLK:
+		return madera_set_fll_syncclk(&cs47l85->fll[0], source, Fref,
+					      Fout);
+	case MADERA_FLL2_SYNCCLK:
+		return madera_set_fll_syncclk(&cs47l85->fll[1], source, Fref,
+					      Fout);
+	case MADERA_FLL3_SYNCCLK:
+		return madera_set_fll_syncclk(&cs47l85->fll[2], source, Fref,
+					      Fout);
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct snd_soc_dai_driver cs47l85_dai[] = {
+	{
+		.name = "cs47l85-aif1",
+		.id = 1,
+		.base = MADERA_AIF1_BCLK_CTRL,
+		.playback = {
+			.stream_name = "AIF1 Playback",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AIF1 Capture",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_dai_ops,
+		.symmetric_rates = 1,
+		.symmetric_samplebits = 1,
+	},
+	{
+		.name = "cs47l85-aif2",
+		.id = 2,
+		.base = MADERA_AIF2_BCLK_CTRL,
+		.playback = {
+			.stream_name = "AIF2 Playback",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AIF2 Capture",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_dai_ops,
+		.symmetric_rates = 1,
+		.symmetric_samplebits = 1,
+	},
+	{
+		.name = "cs47l85-aif3",
+		.id = 3,
+		.base = MADERA_AIF3_BCLK_CTRL,
+		.playback = {
+			.stream_name = "AIF3 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AIF3 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_dai_ops,
+		.symmetric_rates = 1,
+		.symmetric_samplebits = 1,
+	},
+	{
+		.name = "cs47l85-aif4",
+		.id = 4,
+		.base = MADERA_AIF4_BCLK_CTRL,
+		.playback = {
+			.stream_name = "AIF4 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AIF4 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_dai_ops,
+		.symmetric_rates = 1,
+		.symmetric_samplebits = 1,
+	},
+	{
+		.name = "cs47l85-slim1",
+		.id = 5,
+		.playback = {
+			.stream_name = "Slim1 Playback",
+			.channels_min = 1,
+			.channels_max = 4,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "Slim1 Capture",
+			.channels_min = 1,
+			.channels_max = 4,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_simple_dai_ops,
+	},
+	{
+		.name = "cs47l85-slim2",
+		.id = 6,
+		.playback = {
+			.stream_name = "Slim2 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "Slim2 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_simple_dai_ops,
+	},
+	{
+		.name = "cs47l85-slim3",
+		.id = 7,
+		.playback = {
+			.stream_name = "Slim3 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "Slim3 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_simple_dai_ops,
+	},
+	{
+		.name = "cs47l85-cpu-voicectrl",
+		.capture = {
+			.stream_name = "Voice Control CPU",
+			.channels_min = 1,
+			.channels_max = 1,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.compress_new = snd_soc_new_compress,
+	},
+	{
+		.name = "cs47l85-dsp-voicectrl",
+		.capture = {
+			.stream_name = "Voice Control DSP",
+			.channels_min = 1,
+			.channels_max = 1,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+	},
+	{
+		.name = "cs47l85-cpu-trace",
+		.capture = {
+			.stream_name = "Audio Trace CPU",
+			.channels_min = 1,
+			.channels_max = 6,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.compress_new = snd_soc_new_compress,
+	},
+	{
+		.name = "cs47l85-dsp-trace",
+		.capture = {
+			.stream_name = "Audio Trace DSP",
+			.channels_min = 1,
+			.channels_max = 6,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+	},
+};
+
+static int cs47l85_open(struct snd_compr_stream *stream)
+{
+	struct snd_soc_pcm_runtime *rtd = stream->private_data;
+	struct cs47l85 *cs47l85 = snd_soc_platform_get_drvdata(rtd->platform);
+	struct madera_priv *priv = &cs47l85->core;
+	struct madera *madera = priv->madera;
+	int n_adsp;
+
+	if (strcmp(rtd->codec_dai->name, "cs47l85-dsp-voicectrl") == 0) {
+		n_adsp = 5;
+	} else if (strcmp(rtd->codec_dai->name, "cs47l85-dsp-trace") == 0) {
+		n_adsp = 0;
+	} else {
+		dev_err(madera->dev,
+			"No suitable compressed stream for DAI '%s'\n",
+			rtd->codec_dai->name);
+		return -EINVAL;
+	}
+
+	return wm_adsp_compr_open(&priv->adsp[n_adsp], stream);
+}
+
+static irqreturn_t cs47l85_adsp2_irq(int irq, void *data)
+{
+	struct cs47l85 *cs47l85 = data;
+	struct madera_priv *priv = &cs47l85->core;
+	struct madera *madera = priv->madera;
+	struct madera_voice_trigger_info trig_info;
+	int serviced = 0;
+	int i, ret;
+
+	for (i = 0; i < CS47L85_NUM_ADSP; ++i) {
+		ret = wm_adsp_compr_handle_irq(&priv->adsp[i]);
+		if (ret != -ENODEV)
+			serviced++;
+		if (ret == WM_ADSP_COMPR_VOICE_TRIGGER) {
+			trig_info.core_num = i + 1;
+			madera_call_notifiers(madera,
+					      MADERA_NOTIFY_VOICE_TRIGGER,
+					      &trig_info);
+		}
+	}
+
+	if (!serviced) {
+		dev_err(madera->dev, "Spurious compressed data IRQ\n");
+		return IRQ_NONE;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static const char * const cs47l85_dmic_refs[] = {
+	"MICVDD",
+	"MICBIAS1",
+	"MICBIAS2",
+	"MICBIAS3",
+};
+
+static const char * const cs47l85_dmic_inputs[] = {
+	"IN1L Mux",
+	"IN1R",
+	"IN2L Mux",
+	"IN2R Mux",
+	"IN3L",
+	"IN3R",
+	"IN4L",
+	"IN4R",
+	"IN5L",
+	"IN5R",
+	"IN6L",
+	"IN6R",
+};
+
+static int cs47l85_codec_probe(struct snd_soc_codec *codec)
+{
+	struct cs47l85 *cs47l85 = snd_soc_codec_get_drvdata(codec);
+	struct madera *madera = cs47l85->core.madera;
+	int i, ret;
+
+	madera->dapm = snd_soc_codec_get_dapm(codec);
+
+	ret = madera_init_inputs(codec,
+				 cs47l85_dmic_inputs,
+				 ARRAY_SIZE(cs47l85_dmic_inputs),
+				 cs47l85_dmic_refs,
+				 ARRAY_SIZE(cs47l85_dmic_refs));
+	if (ret)
+		return ret;
+
+	ret = madera_init_outputs(codec, CS47L85_MONO_OUTPUTS);
+	if (ret)
+		return ret;
+
+	snd_soc_component_disable_pin(snd_soc_dapm_to_component(madera->dapm),
+				      "HAPTICS");
+
+	ret = snd_soc_add_codec_controls(codec, madera_adsp_rate_controls,
+					 CS47L85_NUM_ADSP);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < CS47L85_NUM_ADSP; i++)
+		wm_adsp2_codec_probe(&cs47l85->core.adsp[i], codec);
+
+	return 0;
+}
+
+static int cs47l85_codec_remove(struct snd_soc_codec *codec)
+{
+	struct cs47l85 *cs47l85 = snd_soc_codec_get_drvdata(codec);
+	int i;
+
+	for (i = 0; i < CS47L85_NUM_ADSP; i++)
+		wm_adsp2_codec_remove(&cs47l85->core.adsp[i], codec);
+
+	cs47l85->core.madera->dapm = NULL;
+
+	return 0;
+}
+
+#define MADERA_DIG_VU 0x0200
+
+static const unsigned int cs47l85_digital_vu[] = {
+	MADERA_DAC_DIGITAL_VOLUME_1L,
+	MADERA_DAC_DIGITAL_VOLUME_1R,
+	MADERA_DAC_DIGITAL_VOLUME_2L,
+	MADERA_DAC_DIGITAL_VOLUME_2R,
+	MADERA_DAC_DIGITAL_VOLUME_3L,
+	MADERA_DAC_DIGITAL_VOLUME_3R,
+	MADERA_DAC_DIGITAL_VOLUME_4L,
+	MADERA_DAC_DIGITAL_VOLUME_4R,
+	MADERA_DAC_DIGITAL_VOLUME_5L,
+	MADERA_DAC_DIGITAL_VOLUME_5R,
+	MADERA_DAC_DIGITAL_VOLUME_6L,
+	MADERA_DAC_DIGITAL_VOLUME_6R,
+};
+
+static struct regmap *cs47l85_get_regmap(struct device *dev)
+{
+	struct cs47l85 *cs47l85 = dev_get_drvdata(dev);
+
+	return cs47l85->core.madera->regmap;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_cs47l85 = {
+	.probe = cs47l85_codec_probe,
+	.remove = cs47l85_codec_remove,
+	.get_regmap = cs47l85_get_regmap,
+
+	.idle_bias_off = true,
+
+	.set_sysclk = madera_set_sysclk,
+	.set_pll = cs47l85_set_fll,
+
+	.component_driver = {
+		.controls = cs47l85_snd_controls,
+		.num_controls = ARRAY_SIZE(cs47l85_snd_controls),
+		.dapm_widgets = cs47l85_dapm_widgets,
+		.num_dapm_widgets = ARRAY_SIZE(cs47l85_dapm_widgets),
+		.dapm_routes = cs47l85_dapm_routes,
+		.num_dapm_routes = ARRAY_SIZE(cs47l85_dapm_routes),
+	},
+};
+
+static struct snd_compr_ops cs47l85_compr_ops = {
+	.open = cs47l85_open,
+	.free = wm_adsp_compr_free,
+	.set_params = wm_adsp_compr_set_params,
+	.get_caps = wm_adsp_compr_get_caps,
+	.trigger = wm_adsp_compr_trigger,
+	.pointer = wm_adsp_compr_pointer,
+	.copy = wm_adsp_compr_copy,
+};
+
+static struct snd_soc_platform_driver cs47l85_compr_platform = {
+	.compr_ops = &cs47l85_compr_ops,
+};
+
+static int cs47l85_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	struct cs47l85 *cs47l85;
+	int i, ret;
+
+	BUILD_BUG_ON(ARRAY_SIZE(cs47l85_dai) > MADERA_MAX_DAI);
+
+	/* quick exit if Madera irqchip driver hasn't completed probe */
+	if (!madera->irq_dev) {
+		dev_dbg(&pdev->dev, "irqchip driver not ready\n");
+		return -EPROBE_DEFER;
+	}
+
+	cs47l85 = devm_kzalloc(&pdev->dev, sizeof(struct cs47l85),
+			       GFP_KERNEL);
+	if (!cs47l85)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, cs47l85);
+
+	cs47l85->core.madera = madera;
+	cs47l85->core.dev = &pdev->dev;
+	cs47l85->core.num_inputs = 12;
+
+	ret = madera_core_init(&cs47l85->core);
+	if (ret)
+		return ret;
+
+	ret = madera_init_overheat(&cs47l85->core);
+	if (ret)
+		return ret;
+
+	ret = madera_request_irq(madera, MADERA_IRQ_DSP_IRQ1,
+				 "ADSP2 Compressed IRQ", cs47l85_adsp2_irq,
+				 cs47l85);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request DSP IRQ: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < CS47L85_NUM_ADSP; i++) {
+		cs47l85->core.adsp[i].part = "cs47l85";
+		cs47l85->core.adsp[i].num = i + 1;
+		cs47l85->core.adsp[i].type = WMFW_ADSP2;
+		cs47l85->core.adsp[i].rev = 1;
+		cs47l85->core.adsp[i].dev = madera->dev;
+		cs47l85->core.adsp[i].regmap = madera->regmap_32bit;
+
+		cs47l85->core.adsp[i].base = wm_adsp2_control_bases[i];
+		cs47l85->core.adsp[i].mem = cs47l85_dsp_regions[i];
+		cs47l85->core.adsp[i].num_mems
+			= ARRAY_SIZE(cs47l85_dsp1_regions);
+
+		ret = wm_adsp2_init(&cs47l85->core.adsp[i]);
+		if (ret) {
+			for (--i; i >= 0; --i)
+				wm_adsp2_remove(&cs47l85->core.adsp[i]);
+			goto error_core;
+		}
+	}
+
+	madera_init_fll(madera, 1, MADERA_FLL1_CONTROL_1 - 1,
+			&cs47l85->fll[0]);
+	madera_init_fll(madera, 2, MADERA_FLL2_CONTROL_1 - 1,
+			&cs47l85->fll[1]);
+	madera_init_fll(madera, 3, MADERA_FLL3_CONTROL_1 - 1,
+			&cs47l85->fll[2]);
+
+	for (i = 0; i < ARRAY_SIZE(cs47l85_dai); i++)
+		madera_init_dai(&cs47l85->core, i);
+
+	/* Latch volume update bits */
+	for (i = 0; i < ARRAY_SIZE(cs47l85_digital_vu); i++)
+		regmap_update_bits(madera->regmap, cs47l85_digital_vu[i],
+				   MADERA_DIG_VU, MADERA_DIG_VU);
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_idle(&pdev->dev);
+
+	ret = snd_soc_register_platform(&pdev->dev, &cs47l85_compr_platform);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
+		goto error;
+	}
+
+	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l85,
+				     cs47l85_dai, ARRAY_SIZE(cs47l85_dai));
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
+		snd_soc_unregister_platform(&pdev->dev);
+		goto error;
+	}
+
+	return ret;
+
+error:
+	for (i = 0; i < CS47L85_NUM_ADSP; i++)
+		wm_adsp2_remove(&cs47l85->core.adsp[i]);
+error_core:
+	madera_core_destroy(&cs47l85->core);
+
+	return ret;
+}
+
+static int cs47l85_remove(struct platform_device *pdev)
+{
+	struct cs47l85 *cs47l85 = platform_get_drvdata(pdev);
+	int i;
+
+	snd_soc_unregister_platform(&pdev->dev);
+	snd_soc_unregister_codec(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
+	for (i = 0; i < CS47L85_NUM_ADSP; i++)
+		wm_adsp2_remove(&cs47l85->core.adsp[i]);
+
+	madera_free_irq(cs47l85->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l85);
+	madera_free_overheat(&cs47l85->core);
+	madera_core_destroy(&cs47l85->core);
+
+	return 0;
+}
+
+static struct platform_driver cs47l85_codec_driver = {
+	.driver = {
+		.name = "cs47l85-codec",
+	},
+	.probe = cs47l85_probe,
+	.remove = cs47l85_remove,
+};
+
+module_platform_driver(cs47l85_codec_driver);
+
+MODULE_DESCRIPTION("ASoC CS47L85 driver");
+MODULE_AUTHOR("Nariman Poushin <nariman@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:cs47l85-codec");
-- 
1.9.1


^ permalink raw reply related

* [PATCH v2 18/18] ASoC: cs47l90: Add codec driver for Cirrus Logic CS47L90
From: Richard Fitzgerald @ 2017-04-24 16:08 UTC (permalink / raw)
  To: lee.jones, broonie, linus.walleij, gnurou, robh+dt, tglx, jason
  Cc: alsa-devel, patches, linux-gpio, devicetree, linux-kernel
In-Reply-To: <1493050124-5970-1-git-send-email-rf@opensource.wolfsonmicro.com>

Adds the codec driver for the CS47L90 SmartCodec. This is a
multi-functional codec based on the Cirrus Logic Madera platform.

Signed-off-by: Nikesh Oswal <nikesh@opensource.wolfsonmicro.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
No changes since V1

 sound/soc/codecs/Kconfig   |    6 +
 sound/soc/codecs/Makefile  |    2 +
 sound/soc/codecs/cs47l90.c | 2645 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 2653 insertions(+)
 create mode 100644 sound/soc/codecs/cs47l90.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 8b8e06c..8b067c2 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -64,6 +64,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_CS47L24 if MFD_CS47L24
 	select SND_SOC_CS47L35 if MFD_CS47L35
 	select SND_SOC_CS47L85 if MFD_CS47L85
+	select SND_SOC_CS47L90 if MFD_CS47L90
 	select SND_SOC_CS53L30 if I2C
 	select SND_SOC_CX20442 if TTY
 	select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
@@ -502,6 +503,9 @@ config SND_SOC_CS47L35
 config SND_SOC_CS47L85
 	tristate
 
+config SND_SOC_CS47L90
+	tristate
+
 # Cirrus Logic Quad-Channel ADC
 config SND_SOC_CS53L30
 	tristate "Cirrus Logic CS53L30 CODEC"
@@ -591,8 +595,10 @@ config SND_SOC_MADERA
 	tristate
 	default y if SND_SOC_CS47L35=y
 	default y if SND_SOC_CS47L85=y
+	default y if SND_SOC_CS47L90=y
 	default m if SND_SOC_CS47L35=m
 	default m if SND_SOC_CS47L85=m
+	default m if SND_SOC_CS47L90=m
 
 config SND_SOC_MAX98088
        tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 1991b79..14c6b88 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -57,6 +57,7 @@ snd-soc-cs4349-objs := cs4349.o
 snd-soc-cs47l24-objs := cs47l24.o
 snd-soc-cs47l35-objs := cs47l35.o
 snd-soc-cs47l85-objs := cs47l85.o
+snd-soc-cs47l90-objs := cs47l90.o
 snd-soc-cs53l30-objs := cs53l30.o
 snd-soc-cx20442-objs := cx20442.o
 snd-soc-da7210-objs := da7210.o
@@ -294,6 +295,7 @@ obj-$(CONFIG_SND_SOC_CS4349)	+= snd-soc-cs4349.o
 obj-$(CONFIG_SND_SOC_CS47L24)	+= snd-soc-cs47l24.o
 obj-$(CONFIG_SND_SOC_CS47L35)	+= snd-soc-cs47l35.o
 obj-$(CONFIG_SND_SOC_CS47L85)	+= snd-soc-cs47l85.o
+obj-$(CONFIG_SND_SOC_CS47L90)	+= snd-soc-cs47l90.o
 obj-$(CONFIG_SND_SOC_CS53L30)	+= snd-soc-cs53l30.o
 obj-$(CONFIG_SND_SOC_CX20442)	+= snd-soc-cx20442.o
 obj-$(CONFIG_SND_SOC_DA7210)	+= snd-soc-da7210.o
diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c
new file mode 100644
index 0000000..e772274
--- /dev/null
+++ b/sound/soc/codecs/cs47l90.c
@@ -0,0 +1,2645 @@
+/*
+ * cs47l90.c  --  ALSA SoC Audio driver for CS47L90 codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * Author: Nikesh Oswal <nikesh@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/registers.h>
+
+#include "madera.h"
+#include "wm_adsp.h"
+
+#define CS47L90_NUM_ADSP	7
+#define CS47L90_MONO_OUTPUTS	3
+
+struct cs47l90 {
+	struct madera_priv core;
+	struct madera_fll fll[3];
+};
+
+static const struct wm_adsp_region cs47l90_dsp1_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x080000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x0e0000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x0a0000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x0c0000 },
+};
+
+static const struct wm_adsp_region cs47l90_dsp2_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x100000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x160000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x120000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x140000 },
+};
+
+static const struct wm_adsp_region cs47l90_dsp3_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x180000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x1e0000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x1a0000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x1c0000 },
+};
+
+static const struct wm_adsp_region cs47l90_dsp4_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x200000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x260000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x220000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x240000 },
+};
+
+static const struct wm_adsp_region cs47l90_dsp5_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x280000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x2e0000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x2a0000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x2c0000 },
+};
+
+static const struct wm_adsp_region cs47l90_dsp6_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x300000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x360000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x320000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x340000 },
+};
+
+static const struct wm_adsp_region cs47l90_dsp7_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x380000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x3e0000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x3a0000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x3c0000 },
+};
+
+static const struct wm_adsp_region *cs47l90_dsp_regions[] = {
+	cs47l90_dsp1_regions,
+	cs47l90_dsp2_regions,
+	cs47l90_dsp3_regions,
+	cs47l90_dsp4_regions,
+	cs47l90_dsp5_regions,
+	cs47l90_dsp6_regions,
+	cs47l90_dsp7_regions,
+};
+
+static const int cs47l90_dsp_control_bases[] = {
+	MADERA_DSP1_CONFIG_1,
+	MADERA_DSP2_CONFIG_1,
+	MADERA_DSP3_CONFIG_1,
+	MADERA_DSP4_CONFIG_1,
+	MADERA_DSP5_CONFIG_1,
+	MADERA_DSP6_CONFIG_1,
+	MADERA_DSP7_CONFIG_1,
+};
+
+static int cs47l90_adsp_power_ev(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kcontrol,
+				 int event)
+{
+	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct cs47l90 *cs47l90 = snd_soc_codec_get_drvdata(codec);
+	struct madera_priv *priv = &cs47l90->core;
+	struct madera *madera = priv->madera;
+	unsigned int freq;
+	int ret;
+
+	ret = regmap_read(madera->regmap, MADERA_DSP_CLOCK_2, &freq);
+	if (ret != 0) {
+		dev_err(madera->dev,
+			"Failed to read MADERA_DSP_CLOCK_2: %d\n", ret);
+		return ret;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		ret = madera_set_adsp_clk(&cs47l90->core, w->shift, freq);
+		if (ret)
+			return ret;
+		break;
+	default:
+		break;
+	}
+
+	return wm_adsp2_early_event(w, kcontrol, event, freq);
+}
+
+#define CS47L90_NG_SRC(name, base) \
+	SOC_SINGLE(name " NG HPOUT1L Switch",  base,  0, 1, 0), \
+	SOC_SINGLE(name " NG HPOUT1R Switch",  base,  1, 1, 0), \
+	SOC_SINGLE(name " NG HPOUT2L Switch",  base,  2, 1, 0), \
+	SOC_SINGLE(name " NG HPOUT2R Switch",  base,  3, 1, 0), \
+	SOC_SINGLE(name " NG HPOUT3L Switch",  base,  4, 1, 0), \
+	SOC_SINGLE(name " NG HPOUT3R Switch",  base,  5, 1, 0), \
+	SOC_SINGLE(name " NG SPKDAT1L Switch", base,  8, 1, 0), \
+	SOC_SINGLE(name " NG SPKDAT1R Switch", base,  9, 1, 0)
+
+#define CS47L90_RXANC_INPUT_ROUTES(widget, name) \
+	{ widget, NULL, name " NG Mux" }, \
+	{ name " NG Internal", NULL, "RXANC NG Clock" }, \
+	{ name " NG Internal", NULL, name " Channel" }, \
+	{ name " NG External", NULL, "RXANC NG External Clock" }, \
+	{ name " NG External", NULL, name " Channel" }, \
+	{ name " NG Mux", "None", name " Channel" }, \
+	{ name " NG Mux", "Internal", name " NG Internal" }, \
+	{ name " NG Mux", "External", name " NG External" }, \
+	{ name " Channel", "Left", name " Left Input" }, \
+	{ name " Channel", "Combine", name " Left Input" }, \
+	{ name " Channel", "Right", name " Right Input" }, \
+	{ name " Channel", "Combine", name " Right Input" }, \
+	{ name " Left Input", "IN1", "IN1L PGA" }, \
+	{ name " Right Input", "IN1", "IN1R PGA" }, \
+	{ name " Left Input", "IN2", "IN2L PGA" }, \
+	{ name " Right Input", "IN2", "IN2R PGA" }, \
+	{ name " Left Input", "IN3", "IN3L PGA" }, \
+	{ name " Right Input", "IN3", "IN3R PGA" }, \
+	{ name " Left Input", "IN4", "IN4L PGA" }, \
+	{ name " Right Input", "IN4", "IN4R PGA" }, \
+	{ name " Left Input", "IN5", "IN5L PGA" }, \
+	{ name " Right Input", "IN5", "IN5R PGA" }
+
+#define CS47L90_RXANC_OUTPUT_ROUTES(widget, name) \
+	{ widget, NULL, name " ANC Source" }, \
+	{ name " ANC Source", "RXANCL", "RXANCL" }, \
+	{ name " ANC Source", "RXANCR", "RXANCR" }
+
+static const struct snd_kcontrol_new cs47l90_snd_controls[] = {
+SOC_ENUM("IN1 OSR", madera_in_dmic_osr[0]),
+SOC_ENUM("IN2 OSR", madera_in_dmic_osr[1]),
+SOC_ENUM("IN3 OSR", madera_in_dmic_osr[2]),
+SOC_ENUM("IN4 OSR", madera_in_dmic_osr[3]),
+SOC_ENUM("IN5 OSR", madera_in_dmic_osr[4]),
+
+SOC_SINGLE_RANGE_TLV("IN1L Volume", MADERA_IN1L_CONTROL,
+		     MADERA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+SOC_SINGLE_RANGE_TLV("IN1R Volume", MADERA_IN1R_CONTROL,
+		     MADERA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+SOC_SINGLE_RANGE_TLV("IN2L Volume", MADERA_IN2L_CONTROL,
+		     MADERA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+SOC_SINGLE_RANGE_TLV("IN2R Volume", MADERA_IN2R_CONTROL,
+		     MADERA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
+
+SOC_ENUM("IN HPF Cutoff Frequency", madera_in_hpf_cut_enum),
+
+SOC_SINGLE_EXT("IN1L LP Switch", MADERA_ADC_DIGITAL_VOLUME_1L,
+		MADERA_IN1L_LP_MODE_SHIFT, 1, 0,
+		snd_soc_get_volsw, madera_lp_mode_put),
+SOC_SINGLE_EXT("IN1R LP Switch", MADERA_ADC_DIGITAL_VOLUME_1R,
+		MADERA_IN1R_LP_MODE_SHIFT, 1, 0,
+		snd_soc_get_volsw, madera_lp_mode_put),
+SOC_SINGLE_EXT("IN2L LP Switch", MADERA_ADC_DIGITAL_VOLUME_2L,
+		MADERA_IN2L_LP_MODE_SHIFT, 1, 0,
+		snd_soc_get_volsw, madera_lp_mode_put),
+SOC_SINGLE_EXT("IN2R LP Switch", MADERA_ADC_DIGITAL_VOLUME_2R,
+		MADERA_IN2R_LP_MODE_SHIFT, 1, 0,
+		snd_soc_get_volsw, madera_lp_mode_put),
+
+SOC_SINGLE("IN1L HPF Switch", MADERA_IN1L_CONTROL,
+	   MADERA_IN1L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN1R HPF Switch", MADERA_IN1R_CONTROL,
+	   MADERA_IN1R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN2L HPF Switch", MADERA_IN2L_CONTROL,
+	   MADERA_IN2L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN2R HPF Switch", MADERA_IN2R_CONTROL,
+	   MADERA_IN2R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN3L HPF Switch", MADERA_IN3L_CONTROL,
+	   MADERA_IN3L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN3R HPF Switch", MADERA_IN3R_CONTROL,
+	   MADERA_IN3R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN4L HPF Switch", MADERA_IN4L_CONTROL,
+	   MADERA_IN4L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN4R HPF Switch", MADERA_IN4R_CONTROL,
+	   MADERA_IN4R_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN5L HPF Switch", MADERA_IN5L_CONTROL,
+	   MADERA_IN5L_HPF_SHIFT, 1, 0),
+SOC_SINGLE("IN5R HPF Switch", MADERA_IN5R_CONTROL,
+	   MADERA_IN5R_HPF_SHIFT, 1, 0),
+
+SOC_SINGLE_TLV("IN1L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1L,
+	       MADERA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN1R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1R,
+	       MADERA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN2L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2L,
+	       MADERA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN2R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2R,
+	       MADERA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN3L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_3L,
+	       MADERA_IN3L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN3R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_3R,
+	       MADERA_IN3R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN4L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_4L,
+	       MADERA_IN4L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN4R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_4R,
+	       MADERA_IN4R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN5L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_5L,
+	       MADERA_IN5L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+SOC_SINGLE_TLV("IN5R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_5R,
+	       MADERA_IN5R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
+
+SOC_ENUM("Input Ramp Up", madera_in_vi_ramp),
+SOC_ENUM("Input Ramp Down", madera_in_vd_ramp),
+
+SND_SOC_BYTES("RXANC Coefficients", MADERA_ANC_COEFF_START,
+	      MADERA_ANC_COEFF_END - MADERA_ANC_COEFF_START + 1),
+SND_SOC_BYTES("RXANCL Config", MADERA_FCL_FILTER_CONTROL, 1),
+SND_SOC_BYTES("RXANCL Coefficients", MADERA_FCL_COEFF_START,
+	      MADERA_FCL_COEFF_END - MADERA_FCL_COEFF_START + 1),
+SND_SOC_BYTES("RXANCR Config", MADERA_FCR_FILTER_CONTROL, 1),
+SND_SOC_BYTES("RXANCR Coefficients", MADERA_FCR_COEFF_START,
+	      MADERA_FCR_COEFF_END - MADERA_FCR_COEFF_START + 1),
+
+MADERA_MIXER_CONTROLS("EQ1", MADERA_EQ1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("EQ2", MADERA_EQ2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("EQ3", MADERA_EQ3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("EQ4", MADERA_EQ4MIX_INPUT_1_SOURCE),
+
+MADERA_EQ_CONTROL("EQ1 Coefficients", MADERA_EQ1_2),
+SOC_SINGLE_TLV("EQ1 B1 Volume", MADERA_EQ1_1, MADERA_EQ1_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B2 Volume", MADERA_EQ1_1, MADERA_EQ1_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B3 Volume", MADERA_EQ1_1, MADERA_EQ1_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B4 Volume", MADERA_EQ1_2, MADERA_EQ1_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ1 B5 Volume", MADERA_EQ1_2, MADERA_EQ1_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_EQ_CONTROL("EQ2 Coefficients", MADERA_EQ2_2),
+SOC_SINGLE_TLV("EQ2 B1 Volume", MADERA_EQ2_1, MADERA_EQ2_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B2 Volume", MADERA_EQ2_1, MADERA_EQ2_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B3 Volume", MADERA_EQ2_1, MADERA_EQ2_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B4 Volume", MADERA_EQ2_2, MADERA_EQ2_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ2 B5 Volume", MADERA_EQ2_2, MADERA_EQ2_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_EQ_CONTROL("EQ3 Coefficients", MADERA_EQ3_2),
+SOC_SINGLE_TLV("EQ3 B1 Volume", MADERA_EQ3_1, MADERA_EQ3_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B2 Volume", MADERA_EQ3_1, MADERA_EQ3_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B3 Volume", MADERA_EQ3_1, MADERA_EQ3_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B4 Volume", MADERA_EQ3_2, MADERA_EQ3_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ3 B5 Volume", MADERA_EQ3_2, MADERA_EQ3_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_EQ_CONTROL("EQ4 Coefficients", MADERA_EQ4_2),
+SOC_SINGLE_TLV("EQ4 B1 Volume", MADERA_EQ4_1, MADERA_EQ4_B1_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B2 Volume", MADERA_EQ4_1, MADERA_EQ4_B2_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B3 Volume", MADERA_EQ4_1, MADERA_EQ4_B3_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B4 Volume", MADERA_EQ4_2, MADERA_EQ4_B4_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+SOC_SINGLE_TLV("EQ4 B5 Volume", MADERA_EQ4_2, MADERA_EQ4_B5_GAIN_SHIFT,
+	       24, 0, madera_eq_tlv),
+
+MADERA_MIXER_CONTROLS("DRC1L", MADERA_DRC1LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DRC1R", MADERA_DRC1RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DRC2L", MADERA_DRC2LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DRC2R", MADERA_DRC2RMIX_INPUT_1_SOURCE),
+
+SND_SOC_BYTES_MASK("DRC1", MADERA_DRC1_CTRL1, 5,
+		   MADERA_DRC1R_ENA | MADERA_DRC1L_ENA),
+SND_SOC_BYTES_MASK("DRC2", MADERA_DRC2_CTRL1, 5,
+		   MADERA_DRC2R_ENA | MADERA_DRC2L_ENA),
+
+MADERA_MIXER_CONTROLS("LHPF1", MADERA_HPLP1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("LHPF2", MADERA_HPLP2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("LHPF3", MADERA_HPLP3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("LHPF4", MADERA_HPLP4MIX_INPUT_1_SOURCE),
+
+MADERA_LHPF_CONTROL("LHPF1 Coefficients", MADERA_HPLPF1_2),
+MADERA_LHPF_CONTROL("LHPF2 Coefficients", MADERA_HPLPF2_2),
+MADERA_LHPF_CONTROL("LHPF3 Coefficients", MADERA_HPLPF3_2),
+MADERA_LHPF_CONTROL("LHPF4 Coefficients", MADERA_HPLPF4_2),
+
+SOC_ENUM("LHPF1 Mode", madera_lhpf1_mode),
+SOC_ENUM("LHPF2 Mode", madera_lhpf2_mode),
+SOC_ENUM("LHPF3 Mode", madera_lhpf3_mode),
+SOC_ENUM("LHPF4 Mode", madera_lhpf4_mode),
+
+SOC_ENUM("Sample Rate 2", madera_sample_rate[0]),
+SOC_ENUM("Sample Rate 3", madera_sample_rate[1]),
+SOC_ENUM("ASYNC Sample Rate 2", madera_sample_rate[2]),
+
+MADERA_RATE_ENUM("ISRC1 FSL", madera_isrc_fsl[0]),
+MADERA_RATE_ENUM("ISRC2 FSL", madera_isrc_fsl[1]),
+MADERA_RATE_ENUM("ISRC3 FSL", madera_isrc_fsl[2]),
+MADERA_RATE_ENUM("ISRC4 FSL", madera_isrc_fsl[3]),
+MADERA_RATE_ENUM("ISRC1 FSH", madera_isrc_fsh[0]),
+MADERA_RATE_ENUM("ISRC2 FSH", madera_isrc_fsh[1]),
+MADERA_RATE_ENUM("ISRC3 FSH", madera_isrc_fsh[2]),
+MADERA_RATE_ENUM("ISRC4 FSH", madera_isrc_fsh[3]),
+MADERA_RATE_ENUM("ASRC1 Rate 1", madera_asrc1_rate[0]),
+MADERA_RATE_ENUM("ASRC1 Rate 2", madera_asrc1_rate[1]),
+MADERA_RATE_ENUM("ASRC2 Rate 1", madera_asrc2_rate[0]),
+MADERA_RATE_ENUM("ASRC2 Rate 2", madera_asrc2_rate[1]),
+
+MADERA_MIXER_CONTROLS("DSP1L", MADERA_DSP1LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP1R", MADERA_DSP1RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP2L", MADERA_DSP2LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP2R", MADERA_DSP2RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP3L", MADERA_DSP3LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP3R", MADERA_DSP3RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP4L", MADERA_DSP4LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP4R", MADERA_DSP4RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP5L", MADERA_DSP5LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP5R", MADERA_DSP5RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP6L", MADERA_DSP6LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP6R", MADERA_DSP6RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP7L", MADERA_DSP7LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("DSP7R", MADERA_DSP7RMIX_INPUT_1_SOURCE),
+
+SOC_SINGLE_TLV("Noise Generator Volume", MADERA_COMFORT_NOISE_GENERATOR,
+	       MADERA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, madera_noise_tlv),
+
+MADERA_MIXER_CONTROLS("HPOUT1L", MADERA_OUT1LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("HPOUT1R", MADERA_OUT1RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("HPOUT2L", MADERA_OUT2LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("HPOUT2R", MADERA_OUT2RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("HPOUT3L", MADERA_OUT3LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("HPOUT3R", MADERA_OUT3RMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SPKDAT1L", MADERA_OUT5LMIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SPKDAT1R", MADERA_OUT5RMIX_INPUT_1_SOURCE),
+
+SOC_SINGLE("HPOUT1 SC Protect Switch", MADERA_HP1_SHORT_CIRCUIT_CTRL,
+	   MADERA_HP1_SC_ENA_SHIFT, 1, 0),
+SOC_SINGLE("HPOUT2 SC Protect Switch", MADERA_HP2_SHORT_CIRCUIT_CTRL,
+	   MADERA_HP2_SC_ENA_SHIFT, 1, 0),
+SOC_SINGLE("HPOUT3 SC Protect Switch", MADERA_HP3_SHORT_CIRCUIT_CTRL,
+	   MADERA_HP3_SC_ENA_SHIFT, 1, 0),
+
+SOC_SINGLE("SPKDAT1 High Performance Switch", MADERA_OUTPUT_PATH_CONFIG_5L,
+	   MADERA_OUT5_OSR_SHIFT, 1, 0),
+
+SOC_DOUBLE_R("HPOUT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_1L,
+	     MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("HPOUT2 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_2L,
+	     MADERA_DAC_DIGITAL_VOLUME_2R, MADERA_OUT2L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("HPOUT3 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_3L,
+	     MADERA_DAC_DIGITAL_VOLUME_3R, MADERA_OUT3L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("SPKDAT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_5L,
+	     MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_MUTE_SHIFT, 1, 1),
+
+SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_1L,
+		 MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_2L,
+		 MADERA_DAC_DIGITAL_VOLUME_2R, MADERA_OUT2L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_3L,
+		 MADERA_DAC_DIGITAL_VOLUME_3R, MADERA_OUT3L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_5L,
+		 MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_VOL_SHIFT,
+		 0xbf, 0, madera_digital_tlv),
+
+SOC_DOUBLE("SPKDAT1 Switch", MADERA_PDM_SPK1_CTRL_1, MADERA_SPK1L_MUTE_SHIFT,
+	   MADERA_SPK1R_MUTE_SHIFT, 1, 1),
+
+SOC_DOUBLE("HPOUT1 EDRE Switch", MADERA_EDRE_ENABLE,
+	   MADERA_EDRE_OUT1L_THR1_ENA_SHIFT,
+	   MADERA_EDRE_OUT1R_THR1_ENA_SHIFT, 1, 0),
+SOC_DOUBLE("HPOUT2 EDRE Switch", MADERA_EDRE_ENABLE,
+	   MADERA_EDRE_OUT2L_THR1_ENA_SHIFT,
+	   MADERA_EDRE_OUT2R_THR1_ENA_SHIFT, 1, 0),
+SOC_DOUBLE("HPOUT3 EDRE Switch", MADERA_EDRE_ENABLE,
+	   MADERA_EDRE_OUT3L_THR1_ENA_SHIFT,
+	   MADERA_EDRE_OUT3R_THR1_ENA_SHIFT, 1, 0),
+
+SOC_ENUM("Output Ramp Up", madera_out_vi_ramp),
+SOC_ENUM("Output Ramp Down", madera_out_vd_ramp),
+
+SOC_SINGLE("Noise Gate Switch", MADERA_NOISE_GATE_CONTROL,
+	   MADERA_NGATE_ENA_SHIFT, 1, 0),
+SOC_SINGLE_TLV("Noise Gate Threshold Volume", MADERA_NOISE_GATE_CONTROL,
+	       MADERA_NGATE_THR_SHIFT, 7, 1, madera_ng_tlv),
+SOC_ENUM("Noise Gate Hold", madera_ng_hold),
+
+SOC_ENUM_EXT("DFC1RX Width", madera_dfc_width[0],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC1RX Type", madera_dfc_type[0],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC1TX Width", madera_dfc_width[1],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC1TX Type", madera_dfc_type[1],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC2RX Width", madera_dfc_width[2],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC2RX Type", madera_dfc_type[2],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC2TX Width", madera_dfc_width[3],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC2TX Type", madera_dfc_type[3],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC3RX Width", madera_dfc_width[4],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC3RX Type", madera_dfc_type[4],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC3TX Width", madera_dfc_width[5],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC3TX Type", madera_dfc_type[5],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC4RX Width", madera_dfc_width[6],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC4RX Type", madera_dfc_type[6],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC4TX Width", madera_dfc_width[7],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC4TX Type", madera_dfc_type[7],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC5RX Width", madera_dfc_width[8],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC5RX Type", madera_dfc_type[8],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC5TX Width", madera_dfc_width[9],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC5TX Type", madera_dfc_type[9],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC6RX Width", madera_dfc_width[10],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC6RX Type", madera_dfc_type[10],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC6TX Width", madera_dfc_width[11],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC6TX Type", madera_dfc_type[11],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC7RX Width", madera_dfc_width[12],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC7RX Type", madera_dfc_type[12],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC7TX Width", madera_dfc_width[13],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC7TX Type", madera_dfc_type[13],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC8RX Width", madera_dfc_width[14],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC8RX Type", madera_dfc_type[14],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC8TX Width", madera_dfc_width[15],
+	     snd_soc_get_enum_double, madera_dfc_put),
+SOC_ENUM_EXT("DFC8TX Type", madera_dfc_type[15],
+	     snd_soc_get_enum_double, madera_dfc_put),
+
+CS47L90_NG_SRC("HPOUT1L", MADERA_NOISE_GATE_SELECT_1L),
+CS47L90_NG_SRC("HPOUT1R", MADERA_NOISE_GATE_SELECT_1R),
+CS47L90_NG_SRC("HPOUT2L", MADERA_NOISE_GATE_SELECT_2L),
+CS47L90_NG_SRC("HPOUT2R", MADERA_NOISE_GATE_SELECT_2R),
+CS47L90_NG_SRC("HPOUT3L", MADERA_NOISE_GATE_SELECT_3L),
+CS47L90_NG_SRC("HPOUT3R", MADERA_NOISE_GATE_SELECT_3R),
+CS47L90_NG_SRC("SPKDAT1L", MADERA_NOISE_GATE_SELECT_5L),
+CS47L90_NG_SRC("SPKDAT1R", MADERA_NOISE_GATE_SELECT_5R),
+
+MADERA_MIXER_CONTROLS("AIF1TX1", MADERA_AIF1TX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX2", MADERA_AIF1TX2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX3", MADERA_AIF1TX3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX4", MADERA_AIF1TX4MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX5", MADERA_AIF1TX5MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX6", MADERA_AIF1TX6MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX7", MADERA_AIF1TX7MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF1TX8", MADERA_AIF1TX8MIX_INPUT_1_SOURCE),
+
+MADERA_MIXER_CONTROLS("AIF2TX1", MADERA_AIF2TX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX2", MADERA_AIF2TX2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX3", MADERA_AIF2TX3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX4", MADERA_AIF2TX4MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX5", MADERA_AIF2TX5MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX6", MADERA_AIF2TX6MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX7", MADERA_AIF2TX7MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF2TX8", MADERA_AIF2TX8MIX_INPUT_1_SOURCE),
+
+MADERA_MIXER_CONTROLS("AIF3TX1", MADERA_AIF3TX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF3TX2", MADERA_AIF3TX2MIX_INPUT_1_SOURCE),
+
+MADERA_MIXER_CONTROLS("AIF4TX1", MADERA_AIF4TX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("AIF4TX2", MADERA_AIF4TX2MIX_INPUT_1_SOURCE),
+
+MADERA_MIXER_CONTROLS("SLIMTX1", MADERA_SLIMTX1MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX2", MADERA_SLIMTX2MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX3", MADERA_SLIMTX3MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX4", MADERA_SLIMTX4MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX5", MADERA_SLIMTX5MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX6", MADERA_SLIMTX6MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX7", MADERA_SLIMTX7MIX_INPUT_1_SOURCE),
+MADERA_MIXER_CONTROLS("SLIMTX8", MADERA_SLIMTX8MIX_INPUT_1_SOURCE),
+
+MADERA_GAINMUX_CONTROLS("SPDIF1TX1", MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE),
+MADERA_GAINMUX_CONTROLS("SPDIF1TX2", MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE),
+};
+
+MADERA_MIXER_ENUMS(EQ1, MADERA_EQ1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(EQ2, MADERA_EQ2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(EQ3, MADERA_EQ3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(EQ4, MADERA_EQ4MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DRC1L, MADERA_DRC1LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DRC1R, MADERA_DRC1RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DRC2L, MADERA_DRC2LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DRC2R, MADERA_DRC2RMIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(LHPF1, MADERA_HPLP1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(LHPF2, MADERA_HPLP2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(LHPF3, MADERA_HPLP3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(LHPF4, MADERA_HPLP4MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP1L, MADERA_DSP1LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP1R, MADERA_DSP1RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP1, MADERA_DSP1AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP2L, MADERA_DSP2LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP2R, MADERA_DSP2RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP2, MADERA_DSP2AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP3L, MADERA_DSP3LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP3R, MADERA_DSP3RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP3, MADERA_DSP3AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP4L, MADERA_DSP4LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP4R, MADERA_DSP4RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP4, MADERA_DSP4AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP5L, MADERA_DSP5LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP5R, MADERA_DSP5RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP5, MADERA_DSP5AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP6L, MADERA_DSP6LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP6R, MADERA_DSP6RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP6, MADERA_DSP6AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(DSP7L, MADERA_DSP7LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(DSP7R, MADERA_DSP7RMIX_INPUT_1_SOURCE);
+MADERA_DSP_AUX_ENUMS(DSP7, MADERA_DSP7AUX1MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(PWM1, MADERA_PWM1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(PWM2, MADERA_PWM2MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(OUT1L, MADERA_OUT1LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(OUT1R, MADERA_OUT1RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(OUT2L, MADERA_OUT2LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(OUT2R, MADERA_OUT2RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(OUT3L, MADERA_OUT3LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(OUT3R, MADERA_OUT3RMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SPKDAT1L, MADERA_OUT5LMIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SPKDAT1R, MADERA_OUT5RMIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(AIF1TX1, MADERA_AIF1TX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX2, MADERA_AIF1TX2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX3, MADERA_AIF1TX3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX4, MADERA_AIF1TX4MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX5, MADERA_AIF1TX5MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX6, MADERA_AIF1TX6MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX7, MADERA_AIF1TX7MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF1TX8, MADERA_AIF1TX8MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(AIF2TX1, MADERA_AIF2TX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX2, MADERA_AIF2TX2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX3, MADERA_AIF2TX3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX4, MADERA_AIF2TX4MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX5, MADERA_AIF2TX5MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX6, MADERA_AIF2TX6MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX7, MADERA_AIF2TX7MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF2TX8, MADERA_AIF2TX8MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(AIF3TX1, MADERA_AIF3TX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF3TX2, MADERA_AIF3TX2MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(AIF4TX1, MADERA_AIF4TX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(AIF4TX2, MADERA_AIF4TX2MIX_INPUT_1_SOURCE);
+
+MADERA_MIXER_ENUMS(SLIMTX1, MADERA_SLIMTX1MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX2, MADERA_SLIMTX2MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX3, MADERA_SLIMTX3MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX4, MADERA_SLIMTX4MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX5, MADERA_SLIMTX5MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX6, MADERA_SLIMTX6MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX7, MADERA_SLIMTX7MIX_INPUT_1_SOURCE);
+MADERA_MIXER_ENUMS(SLIMTX8, MADERA_SLIMTX8MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(SPD1TX1, MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(SPD1TX2, MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ASRC1IN1L, MADERA_ASRC1_1LMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC1IN1R, MADERA_ASRC1_1RMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC1IN2L, MADERA_ASRC1_2LMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC1IN2R, MADERA_ASRC1_2RMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC2IN1L, MADERA_ASRC2_1LMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC2IN1R, MADERA_ASRC2_1RMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC2IN2L, MADERA_ASRC2_2LMIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ASRC2IN2R, MADERA_ASRC2_2RMIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC1INT1, MADERA_ISRC1INT1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1INT2, MADERA_ISRC1INT2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1INT3, MADERA_ISRC1INT3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1INT4, MADERA_ISRC1INT4MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC1DEC1, MADERA_ISRC1DEC1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1DEC2, MADERA_ISRC1DEC2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1DEC3, MADERA_ISRC1DEC3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC1DEC4, MADERA_ISRC1DEC4MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC2INT1, MADERA_ISRC2INT1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2INT2, MADERA_ISRC2INT2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2INT3, MADERA_ISRC2INT3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2INT4, MADERA_ISRC2INT4MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC2DEC1, MADERA_ISRC2DEC1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2DEC2, MADERA_ISRC2DEC2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2DEC3, MADERA_ISRC2DEC3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC2DEC4, MADERA_ISRC2DEC4MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC3INT1, MADERA_ISRC3INT1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC3INT2, MADERA_ISRC3INT2MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC3DEC1, MADERA_ISRC3DEC1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC3DEC2, MADERA_ISRC3DEC2MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC4INT1, MADERA_ISRC4INT1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC4INT2, MADERA_ISRC4INT2MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(ISRC4DEC1, MADERA_ISRC4DEC1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(ISRC4DEC2, MADERA_ISRC4DEC2MIX_INPUT_1_SOURCE);
+
+MADERA_MUX_ENUMS(DFC1, MADERA_DFC1MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(DFC2, MADERA_DFC2MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(DFC3, MADERA_DFC3MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(DFC4, MADERA_DFC4MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(DFC5, MADERA_DFC5MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(DFC6, MADERA_DFC6MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(DFC7, MADERA_DFC7MIX_INPUT_1_SOURCE);
+MADERA_MUX_ENUMS(DFC8, MADERA_DFC8MIX_INPUT_1_SOURCE);
+
+static const char * const cs47l90_aec_loopback_texts[] = {
+	"HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R",
+	"SPKDAT1L", "SPKDAT1R",
+};
+
+static const unsigned int cs47l90_aec_loopback_values[] = {
+	0, 1, 2, 3, 4, 5, 8, 9,
+};
+
+static const struct soc_enum cs47l90_aec_loopback =
+	SOC_VALUE_ENUM_SINGLE(MADERA_DAC_AEC_CONTROL_1,
+			      MADERA_AEC1_LOOPBACK_SRC_SHIFT, 0xf,
+			      ARRAY_SIZE(cs47l90_aec_loopback_texts),
+			      cs47l90_aec_loopback_texts,
+			      cs47l90_aec_loopback_values);
+
+static const struct snd_kcontrol_new cs47l90_aec_loopback_mux =
+	SOC_DAPM_ENUM("AEC1 Loopback", cs47l90_aec_loopback);
+
+static const struct snd_kcontrol_new cs47l90_anc_input_mux[] = {
+	SOC_DAPM_ENUM("RXANCL Input", madera_anc_input_src[0]),
+	SOC_DAPM_ENUM("RXANCL Channel", madera_anc_input_src[1]),
+	SOC_DAPM_ENUM("RXANCR Input", madera_anc_input_src[2]),
+	SOC_DAPM_ENUM("RXANCR Channel", madera_anc_input_src[3]),
+};
+
+static const struct snd_kcontrol_new cs47l90_anc_ng_mux =
+	SOC_DAPM_ENUM("RXANC NG Source", madera_anc_ng_enum);
+
+static const struct snd_kcontrol_new cs47l90_output_anc_src[] = {
+	SOC_DAPM_ENUM("HPOUT1L ANC Source", madera_output_anc_src[0]),
+	SOC_DAPM_ENUM("HPOUT1R ANC Source", madera_output_anc_src[1]),
+	SOC_DAPM_ENUM("HPOUT2L ANC Source", madera_output_anc_src[2]),
+	SOC_DAPM_ENUM("HPOUT2R ANC Source", madera_output_anc_src[3]),
+	SOC_DAPM_ENUM("HPOUT3L ANC Source", madera_output_anc_src[4]),
+	SOC_DAPM_ENUM("HPOUT3R ANC Source", madera_output_anc_src[0]),
+	SOC_DAPM_ENUM("SPKDAT1L ANC Source", madera_output_anc_src[8]),
+	SOC_DAPM_ENUM("SPKDAT1R ANC Source", madera_output_anc_src[9]),
+};
+
+static const struct snd_soc_dapm_widget cs47l90_dapm_widgets[] = {
+SND_SOC_DAPM_SUPPLY("SYSCLK", MADERA_SYSTEM_CLOCK_1, MADERA_SYSCLK_ENA_SHIFT,
+		    0, madera_sysclk_ev,
+		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_SUPPLY("ASYNCCLK", MADERA_ASYNC_CLOCK_1,
+		    MADERA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK,
+		    MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", MADERA_OUTPUT_ASYNC_CLOCK,
+		    MADERA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1,
+		    MADERA_DSP_CLK_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD4", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD1", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD2", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
+
+SND_SOC_DAPM_SUPPLY("MICBIAS1", MADERA_MIC_BIAS_CTRL_1,
+		    MADERA_MICB1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2", MADERA_MIC_BIAS_CTRL_2,
+		    MADERA_MICB1_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_SUPPLY("MICBIAS1A", MADERA_MIC_BIAS_CTRL_5,
+			MADERA_MICB1A_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS1B", MADERA_MIC_BIAS_CTRL_5,
+			MADERA_MICB1B_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS1C", MADERA_MIC_BIAS_CTRL_5,
+			MADERA_MICB1C_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS1D", MADERA_MIC_BIAS_CTRL_5,
+			MADERA_MICB1D_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_SUPPLY("MICBIAS2A", MADERA_MIC_BIAS_CTRL_6,
+			MADERA_MICB2A_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2B", MADERA_MIC_BIAS_CTRL_6,
+			MADERA_MICB2B_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2C", MADERA_MIC_BIAS_CTRL_6,
+			MADERA_MICB2C_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2D", MADERA_MIC_BIAS_CTRL_6,
+			MADERA_MICB2D_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_SUPPLY("FXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_FX, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ASRC1R1CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ASRC1_RATE_1, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ASRC1R2CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ASRC1_RATE_2, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ASRC2R1CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ASRC2_RATE_1, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ASRC2R2CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ASRC2_RATE_2, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC1DECCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC1_DEC, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC1INTCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC1_INT, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC2DECCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC2_DEC, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("ISRC2INTCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_ISRC2_INT, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("OUTCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_OUT, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("SPDCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_SPD, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP1, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP2, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP3CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP3, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP4CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP4, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP5CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP5, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP6CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP6, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DSP7CLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DSP7, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("AIF1TXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_AIF1, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("AIF2TXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_AIF2, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("AIF3TXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_AIF3, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("AIF4TXCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_AIF4, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("SLIMBUSCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_SLIMBUS, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("PWMCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_PWM, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("DFCCLK", SND_SOC_NOPM,
+		    MADERA_DOM_GRP_DFC, 0,
+		    madera_domain_clk_ev,
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+SND_SOC_DAPM_SIGGEN("TONE"),
+SND_SOC_DAPM_SIGGEN("NOISE"),
+
+SND_SOC_DAPM_INPUT("IN1AL"),
+SND_SOC_DAPM_INPUT("IN1BL"),
+SND_SOC_DAPM_INPUT("IN1AR"),
+SND_SOC_DAPM_INPUT("IN1BR"),
+SND_SOC_DAPM_INPUT("IN2AL"),
+SND_SOC_DAPM_INPUT("IN2BL"),
+SND_SOC_DAPM_INPUT("IN2R"),
+SND_SOC_DAPM_INPUT("IN3L"),
+SND_SOC_DAPM_INPUT("IN3R"),
+SND_SOC_DAPM_INPUT("IN4L"),
+SND_SOC_DAPM_INPUT("IN4R"),
+SND_SOC_DAPM_INPUT("IN5L"),
+SND_SOC_DAPM_INPUT("IN5R"),
+
+SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
+SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
+
+SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),
+
+SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[0]),
+SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[1]),
+SND_SOC_DAPM_MUX("IN2L Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[2]),
+
+SND_SOC_DAPM_PGA("PWM1 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM1_ENA_SHIFT,
+		 0, NULL, 0),
+SND_SOC_DAPM_PGA("PWM2 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM2_ENA_SHIFT,
+		 0, NULL, 0),
+
+SND_SOC_DAPM_SUPPLY("RXANC NG External Clock", SND_SOC_NOPM,
+		    MADERA_EXT_NG_SEL_SET_SHIFT, 0, madera_anc_ev,
+		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_PGA("RXANCL NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_PGA("RXANCR NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+SND_SOC_DAPM_SUPPLY("RXANC NG Clock", SND_SOC_NOPM,
+		    MADERA_CLK_NG_ENA_SET_SHIFT, 0, madera_anc_ev,
+		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_PGA("RXANCL NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_PGA("RXANCR NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+SND_SOC_DAPM_MUX("RXANCL Left Input", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_anc_input_mux[0]),
+SND_SOC_DAPM_MUX("RXANCL Right Input", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_anc_input_mux[0]),
+SND_SOC_DAPM_MUX("RXANCL Channel", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_anc_input_mux[1]),
+SND_SOC_DAPM_MUX("RXANCL NG Mux", SND_SOC_NOPM, 0, 0, &cs47l90_anc_ng_mux),
+SND_SOC_DAPM_MUX("RXANCR Left Input", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_anc_input_mux[2]),
+SND_SOC_DAPM_MUX("RXANCR Right Input", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_anc_input_mux[2]),
+SND_SOC_DAPM_MUX("RXANCR Channel", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_anc_input_mux[3]),
+SND_SOC_DAPM_MUX("RXANCR NG Mux", SND_SOC_NOPM, 0, 0, &cs47l90_anc_ng_mux),
+
+SND_SOC_DAPM_PGA_E("RXANCL", SND_SOC_NOPM, MADERA_CLK_L_ENA_SET_SHIFT,
+		   0, NULL, 0, madera_anc_ev,
+		   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_PGA_E("RXANCR", SND_SOC_NOPM, MADERA_CLK_R_ENA_SET_SHIFT,
+		   0, NULL, 0, madera_anc_ev,
+		   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+SND_SOC_DAPM_MUX("HPOUT1L ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_output_anc_src[0]),
+SND_SOC_DAPM_MUX("HPOUT1R ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_output_anc_src[1]),
+SND_SOC_DAPM_MUX("HPOUT2L ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_output_anc_src[2]),
+SND_SOC_DAPM_MUX("HPOUT2R ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_output_anc_src[3]),
+SND_SOC_DAPM_MUX("HPOUT3L ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_output_anc_src[4]),
+SND_SOC_DAPM_MUX("HPOUT3R ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_output_anc_src[5]),
+SND_SOC_DAPM_MUX("SPKDAT1L ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_output_anc_src[6]),
+SND_SOC_DAPM_MUX("SPKDAT1R ANC Source", SND_SOC_NOPM, 0, 0,
+		 &cs47l90_output_anc_src[7]),
+
+SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
+		     MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX7", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2TX8", NULL, 0,
+		     MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX7", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX8", NULL, 0,
+		     MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
+		     MADERA_SLIMTX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
+		     MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
+		     MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF4TX1", NULL, 0,
+		     MADERA_AIF4_TX_ENABLES, MADERA_AIF4TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF4TX2", NULL, 0,
+		     MADERA_AIF4_TX_ENABLES, MADERA_AIF4TX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
+		   MADERA_OUT1L_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
+		   MADERA_OUT1R_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT2L", SND_SOC_NOPM,
+		   MADERA_OUT2L_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT2R", SND_SOC_NOPM,
+		   MADERA_OUT2R_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT3L", SND_SOC_NOPM,
+		   MADERA_OUT3L_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT3R", SND_SOC_NOPM,
+		   MADERA_OUT3R_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT5L", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT5L_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT5R", MADERA_OUTPUT_ENABLES_1,
+		   MADERA_OUT5R_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+
+SND_SOC_DAPM_PGA("SPD1TX1", MADERA_SPD1_TX_CONTROL,
+		   MADERA_SPD1_VAL1_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("SPD1TX2", MADERA_SPD1_TX_CONTROL,
+		   MADERA_SPD1_VAL2_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_OUT_DRV("SPD1", MADERA_SPD1_TX_CONTROL,
+		     MADERA_SPD1_ENA_SHIFT, 0, NULL, 0),
+
+/*
+ * mux_in widgets : arranged in the order of sources
+ * specified in MADERA_MIXER_INPUT_ROUTES
+ */
+
+SND_SOC_DAPM_PGA("Noise Generator", MADERA_COMFORT_NOISE_GENERATOR,
+		 MADERA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("Tone Generator 1", MADERA_TONE_GENERATOR_1,
+		 MADERA_TONE1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Tone Generator 2", MADERA_TONE_GENERATOR_1,
+		 MADERA_TONE2_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_SIGGEN("HAPTICS"),
+
+SND_SOC_DAPM_MUX("AEC1 Loopback", MADERA_DAC_AEC_CONTROL_1,
+		       MADERA_AEC1_LOOPBACK_ENA_SHIFT, 0,
+		       &cs47l90_aec_loopback_mux),
+
+SND_SOC_DAPM_PGA_E("IN1L PGA", MADERA_INPUT_ENABLES, MADERA_IN1L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN1R PGA", MADERA_INPUT_ENABLES, MADERA_IN1R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN2L PGA", MADERA_INPUT_ENABLES, MADERA_IN2L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN2R PGA", MADERA_INPUT_ENABLES, MADERA_IN2R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN3L PGA", MADERA_INPUT_ENABLES, MADERA_IN3L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN3R PGA", MADERA_INPUT_ENABLES, MADERA_IN3R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN4L PGA", MADERA_INPUT_ENABLES, MADERA_IN4L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN4R PGA", MADERA_INPUT_ENABLES, MADERA_IN4R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN5L PGA", MADERA_INPUT_ENABLES, MADERA_IN5L_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("IN5R PGA", MADERA_INPUT_ENABLES, MADERA_IN5R_ENA_SHIFT,
+		   0, NULL, 0, madera_in_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+		   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+
+SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
+			MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
+			MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
+			MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
+			MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
+			MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
+			MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
+			MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
+			MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
+			MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
+			MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0,
+			MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0,
+			MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 0,
+			MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 0,
+			MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX7", NULL, 0,
+			MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX8", NULL, 0,
+			MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
+			MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
+			MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("AIF4RX1", NULL, 0,
+			MADERA_AIF4_RX_ENABLES, MADERA_AIF4RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF4RX2", NULL, 0,
+			MADERA_AIF4_RX_ENABLES, MADERA_AIF4RX2_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0,
+			MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+			MADERA_SLIMRX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0,
+			MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+			MADERA_SLIMRX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0,
+			MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+			MADERA_SLIMRX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0,
+			MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+			MADERA_SLIMRX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX5", NULL, 0,
+			MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+			MADERA_SLIMRX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX6", NULL, 0,
+			MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+			MADERA_SLIMRX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX7", NULL, 0,
+			MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+			MADERA_SLIMRX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0,
+			MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
+			MADERA_SLIMRX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_PGA("EQ1", MADERA_EQ1_1, MADERA_EQ1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("EQ2", MADERA_EQ2_1, MADERA_EQ2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("EQ3", MADERA_EQ3_1, MADERA_EQ3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("EQ4", MADERA_EQ4_1, MADERA_EQ4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("DRC1L", MADERA_DRC1_CTRL1, MADERA_DRC1L_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("DRC1R", MADERA_DRC1_CTRL1, MADERA_DRC1R_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("DRC2L", MADERA_DRC2_CTRL1, MADERA_DRC2L_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("DRC2R", MADERA_DRC2_CTRL1, MADERA_DRC2R_ENA_SHIFT, 0,
+		 NULL, 0),
+
+SND_SOC_DAPM_PGA("LHPF1", MADERA_HPLPF1_1, MADERA_LHPF1_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("LHPF2", MADERA_HPLPF2_1, MADERA_LHPF2_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("LHPF3", MADERA_HPLPF3_1, MADERA_LHPF3_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("LHPF4", MADERA_HPLPF4_1, MADERA_LHPF4_ENA_SHIFT, 0,
+		 NULL, 0),
+
+SND_SOC_DAPM_PGA("ASRC1IN1L", MADERA_ASRC1_ENABLE,
+		MADERA_ASRC1_IN1L_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC1IN1R", MADERA_ASRC1_ENABLE,
+		MADERA_ASRC1_IN1R_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC1IN2L", MADERA_ASRC1_ENABLE,
+		MADERA_ASRC1_IN2L_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC1IN2R", MADERA_ASRC1_ENABLE,
+		MADERA_ASRC1_IN2R_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ASRC2IN1L", MADERA_ASRC2_ENABLE,
+		MADERA_ASRC2_IN1L_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC2IN1R", MADERA_ASRC2_ENABLE,
+		MADERA_ASRC2_IN1R_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC2IN2L", MADERA_ASRC2_ENABLE,
+		MADERA_ASRC2_IN2L_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ASRC2IN2R", MADERA_ASRC2_ENABLE,
+		MADERA_ASRC2_IN2R_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC1DEC1", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC2", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC3", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1DEC4", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_DEC4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC1INT1", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT2", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT3", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC1INT4", MADERA_ISRC_1_CTRL_3,
+		 MADERA_ISRC1_INT4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC2DEC1", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC2", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC3", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2DEC4", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_DEC4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC2INT1", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT2", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT2_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT3", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT3_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC2INT4", MADERA_ISRC_2_CTRL_3,
+		 MADERA_ISRC2_INT4_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC3DEC1", MADERA_ISRC_3_CTRL_3,
+		 MADERA_ISRC3_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC3DEC2", MADERA_ISRC_3_CTRL_3,
+		 MADERA_ISRC3_DEC2_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC3INT1", MADERA_ISRC_3_CTRL_3,
+		 MADERA_ISRC3_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC3INT2", MADERA_ISRC_3_CTRL_3,
+		 MADERA_ISRC3_INT2_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC4DEC1", MADERA_ISRC_4_CTRL_3,
+		 MADERA_ISRC4_DEC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC4DEC2", MADERA_ISRC_4_CTRL_3,
+		 MADERA_ISRC4_DEC2_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("ISRC4INT1", MADERA_ISRC_4_CTRL_3,
+		 MADERA_ISRC4_INT1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ISRC4INT2", MADERA_ISRC_4_CTRL_3,
+		 MADERA_ISRC4_INT2_ENA_SHIFT, 0, NULL, 0),
+
+WM_ADSP2("DSP1", 0, cs47l90_adsp_power_ev),
+WM_ADSP2("DSP2", 1, cs47l90_adsp_power_ev),
+WM_ADSP2("DSP3", 2, cs47l90_adsp_power_ev),
+WM_ADSP2("DSP4", 3, cs47l90_adsp_power_ev),
+WM_ADSP2("DSP5", 4, cs47l90_adsp_power_ev),
+WM_ADSP2("DSP6", 5, cs47l90_adsp_power_ev),
+WM_ADSP2("DSP7", 6, cs47l90_adsp_power_ev),
+
+/* end of ordered widget list */
+
+SND_SOC_DAPM_PGA("DFC1", MADERA_DFC1_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("DFC2", MADERA_DFC2_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("DFC3", MADERA_DFC3_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("DFC4", MADERA_DFC4_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("DFC5", MADERA_DFC5_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("DFC6", MADERA_DFC6_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("DFC7", MADERA_DFC7_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("DFC8", MADERA_DFC8_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
+
+MADERA_MIXER_WIDGETS(EQ1, "EQ1"),
+MADERA_MIXER_WIDGETS(EQ2, "EQ2"),
+MADERA_MIXER_WIDGETS(EQ3, "EQ3"),
+MADERA_MIXER_WIDGETS(EQ4, "EQ4"),
+
+MADERA_MIXER_WIDGETS(DRC1L, "DRC1L"),
+MADERA_MIXER_WIDGETS(DRC1R, "DRC1R"),
+MADERA_MIXER_WIDGETS(DRC2L, "DRC2L"),
+MADERA_MIXER_WIDGETS(DRC2R, "DRC2R"),
+
+SND_SOC_DAPM_SWITCH("DRC1 Activity Output", SND_SOC_NOPM, 0, 0,
+		    &madera_drc_activity_output_mux[0]),
+SND_SOC_DAPM_SWITCH("DRC2 Activity Output", SND_SOC_NOPM, 0, 0,
+		    &madera_drc_activity_output_mux[1]),
+
+MADERA_MIXER_WIDGETS(LHPF1, "LHPF1"),
+MADERA_MIXER_WIDGETS(LHPF2, "LHPF2"),
+MADERA_MIXER_WIDGETS(LHPF3, "LHPF3"),
+MADERA_MIXER_WIDGETS(LHPF4, "LHPF4"),
+
+MADERA_MIXER_WIDGETS(PWM1, "PWM1"),
+MADERA_MIXER_WIDGETS(PWM2, "PWM2"),
+
+MADERA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
+MADERA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
+MADERA_MIXER_WIDGETS(OUT2L, "HPOUT2L"),
+MADERA_MIXER_WIDGETS(OUT2R, "HPOUT2R"),
+MADERA_MIXER_WIDGETS(OUT3L, "HPOUT3L"),
+MADERA_MIXER_WIDGETS(OUT3R, "HPOUT3R"),
+MADERA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
+MADERA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
+
+MADERA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
+MADERA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
+MADERA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
+MADERA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
+MADERA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
+MADERA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
+MADERA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
+MADERA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
+
+MADERA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
+MADERA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
+MADERA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"),
+MADERA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"),
+MADERA_MIXER_WIDGETS(AIF2TX5, "AIF2TX5"),
+MADERA_MIXER_WIDGETS(AIF2TX6, "AIF2TX6"),
+MADERA_MIXER_WIDGETS(AIF2TX7, "AIF2TX7"),
+MADERA_MIXER_WIDGETS(AIF2TX8, "AIF2TX8"),
+
+MADERA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
+MADERA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
+
+MADERA_MIXER_WIDGETS(AIF4TX1, "AIF4TX1"),
+MADERA_MIXER_WIDGETS(AIF4TX2, "AIF4TX2"),
+
+MADERA_MIXER_WIDGETS(SLIMTX1, "SLIMTX1"),
+MADERA_MIXER_WIDGETS(SLIMTX2, "SLIMTX2"),
+MADERA_MIXER_WIDGETS(SLIMTX3, "SLIMTX3"),
+MADERA_MIXER_WIDGETS(SLIMTX4, "SLIMTX4"),
+MADERA_MIXER_WIDGETS(SLIMTX5, "SLIMTX5"),
+MADERA_MIXER_WIDGETS(SLIMTX6, "SLIMTX6"),
+MADERA_MIXER_WIDGETS(SLIMTX7, "SLIMTX7"),
+MADERA_MIXER_WIDGETS(SLIMTX8, "SLIMTX8"),
+
+MADERA_MUX_WIDGETS(SPD1TX1, "SPDIF1TX1"),
+MADERA_MUX_WIDGETS(SPD1TX2, "SPDIF1TX2"),
+
+MADERA_MUX_WIDGETS(ASRC1IN1L, "ASRC1IN1L"),
+MADERA_MUX_WIDGETS(ASRC1IN1R, "ASRC1IN1R"),
+MADERA_MUX_WIDGETS(ASRC1IN2L, "ASRC1IN2L"),
+MADERA_MUX_WIDGETS(ASRC1IN2R, "ASRC1IN2R"),
+MADERA_MUX_WIDGETS(ASRC2IN1L, "ASRC2IN1L"),
+MADERA_MUX_WIDGETS(ASRC2IN1R, "ASRC2IN1R"),
+MADERA_MUX_WIDGETS(ASRC2IN2L, "ASRC2IN2L"),
+MADERA_MUX_WIDGETS(ASRC2IN2R, "ASRC2IN2R"),
+
+MADERA_DSP_WIDGETS(DSP1, "DSP1"),
+MADERA_DSP_WIDGETS(DSP2, "DSP2"),
+MADERA_DSP_WIDGETS(DSP3, "DSP3"),
+MADERA_DSP_WIDGETS(DSP4, "DSP4"),
+MADERA_DSP_WIDGETS(DSP5, "DSP5"),
+MADERA_DSP_WIDGETS(DSP6, "DSP6"),
+MADERA_DSP_WIDGETS(DSP7, "DSP7"),
+
+SND_SOC_DAPM_SWITCH("DSP1 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[0]),
+SND_SOC_DAPM_SWITCH("DSP2 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[1]),
+SND_SOC_DAPM_SWITCH("DSP3 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[2]),
+SND_SOC_DAPM_SWITCH("DSP4 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[3]),
+SND_SOC_DAPM_SWITCH("DSP5 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[4]),
+SND_SOC_DAPM_SWITCH("DSP6 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[5]),
+SND_SOC_DAPM_SWITCH("DSP7 Trigger Output", SND_SOC_NOPM, 0, 0,
+		    &madera_dsp_trigger_output_mux[6]),
+
+MADERA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
+MADERA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
+MADERA_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
+MADERA_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
+
+MADERA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
+MADERA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
+MADERA_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
+MADERA_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
+
+MADERA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
+MADERA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
+MADERA_MUX_WIDGETS(ISRC2DEC3, "ISRC2DEC3"),
+MADERA_MUX_WIDGETS(ISRC2DEC4, "ISRC2DEC4"),
+
+MADERA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
+MADERA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
+MADERA_MUX_WIDGETS(ISRC2INT3, "ISRC2INT3"),
+MADERA_MUX_WIDGETS(ISRC2INT4, "ISRC2INT4"),
+
+MADERA_MUX_WIDGETS(ISRC3DEC1, "ISRC3DEC1"),
+MADERA_MUX_WIDGETS(ISRC3DEC2, "ISRC3DEC2"),
+
+MADERA_MUX_WIDGETS(ISRC3INT1, "ISRC3INT1"),
+MADERA_MUX_WIDGETS(ISRC3INT2, "ISRC3INT2"),
+
+MADERA_MUX_WIDGETS(ISRC4DEC1, "ISRC4DEC1"),
+MADERA_MUX_WIDGETS(ISRC4DEC2, "ISRC4DEC2"),
+
+MADERA_MUX_WIDGETS(ISRC4INT1, "ISRC4INT1"),
+MADERA_MUX_WIDGETS(ISRC4INT2, "ISRC4INT2"),
+
+MADERA_MUX_WIDGETS(DFC1, "DFC1"),
+MADERA_MUX_WIDGETS(DFC2, "DFC2"),
+MADERA_MUX_WIDGETS(DFC3, "DFC3"),
+MADERA_MUX_WIDGETS(DFC4, "DFC4"),
+MADERA_MUX_WIDGETS(DFC5, "DFC5"),
+MADERA_MUX_WIDGETS(DFC6, "DFC6"),
+MADERA_MUX_WIDGETS(DFC7, "DFC7"),
+MADERA_MUX_WIDGETS(DFC8, "DFC8"),
+
+SND_SOC_DAPM_OUTPUT("HPOUT1L"),
+SND_SOC_DAPM_OUTPUT("HPOUT1R"),
+SND_SOC_DAPM_OUTPUT("HPOUT2L"),
+SND_SOC_DAPM_OUTPUT("HPOUT2R"),
+SND_SOC_DAPM_OUTPUT("HPOUT3L"),
+SND_SOC_DAPM_OUTPUT("HPOUT3R"),
+SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
+SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
+SND_SOC_DAPM_OUTPUT("SPDIF1"),
+
+SND_SOC_DAPM_OUTPUT("MICSUPP"),
+};
+
+#define MADERA_MIXER_INPUT_ROUTES(name)	\
+	{ name, "Noise Generator", "Noise Generator" }, \
+	{ name, "Tone Generator 1", "Tone Generator 1" }, \
+	{ name, "Tone Generator 2", "Tone Generator 2" }, \
+	{ name, "Haptics", "HAPTICS" }, \
+	{ name, "AEC1", "AEC1 Loopback" }, \
+	{ name, "IN1L", "IN1L PGA" }, \
+	{ name, "IN1R", "IN1R PGA" }, \
+	{ name, "IN2L", "IN2L PGA" }, \
+	{ name, "IN2R", "IN2R PGA" }, \
+	{ name, "IN3L", "IN3L PGA" }, \
+	{ name, "IN3R", "IN3R PGA" }, \
+	{ name, "IN4L", "IN4L PGA" }, \
+	{ name, "IN4R", "IN4R PGA" }, \
+	{ name, "IN5L", "IN5L PGA" }, \
+	{ name, "IN5R", "IN5R PGA" }, \
+	{ name, "AIF1RX1", "AIF1RX1" }, \
+	{ name, "AIF1RX2", "AIF1RX2" }, \
+	{ name, "AIF1RX3", "AIF1RX3" }, \
+	{ name, "AIF1RX4", "AIF1RX4" }, \
+	{ name, "AIF1RX5", "AIF1RX5" }, \
+	{ name, "AIF1RX6", "AIF1RX6" }, \
+	{ name, "AIF1RX7", "AIF1RX7" }, \
+	{ name, "AIF1RX8", "AIF1RX8" }, \
+	{ name, "AIF2RX1", "AIF2RX1" }, \
+	{ name, "AIF2RX2", "AIF2RX2" }, \
+	{ name, "AIF2RX3", "AIF2RX3" }, \
+	{ name, "AIF2RX4", "AIF2RX4" }, \
+	{ name, "AIF2RX5", "AIF2RX5" }, \
+	{ name, "AIF2RX6", "AIF2RX6" }, \
+	{ name, "AIF2RX7", "AIF2RX7" }, \
+	{ name, "AIF2RX8", "AIF2RX8" }, \
+	{ name, "AIF3RX1", "AIF3RX1" }, \
+	{ name, "AIF3RX2", "AIF3RX2" }, \
+	{ name, "AIF4RX1", "AIF4RX1" }, \
+	{ name, "AIF4RX2", "AIF4RX2" }, \
+	{ name, "SLIMRX1", "SLIMRX1" }, \
+	{ name, "SLIMRX2", "SLIMRX2" }, \
+	{ name, "SLIMRX3", "SLIMRX3" }, \
+	{ name, "SLIMRX4", "SLIMRX4" }, \
+	{ name, "SLIMRX5", "SLIMRX5" }, \
+	{ name, "SLIMRX6", "SLIMRX6" }, \
+	{ name, "SLIMRX7", "SLIMRX7" }, \
+	{ name, "SLIMRX8", "SLIMRX8" }, \
+	{ name, "EQ1", "EQ1" }, \
+	{ name, "EQ2", "EQ2" }, \
+	{ name, "EQ3", "EQ3" }, \
+	{ name, "EQ4", "EQ4" }, \
+	{ name, "DRC1L", "DRC1L" }, \
+	{ name, "DRC1R", "DRC1R" }, \
+	{ name, "DRC2L", "DRC2L" }, \
+	{ name, "DRC2R", "DRC2R" }, \
+	{ name, "LHPF1", "LHPF1" }, \
+	{ name, "LHPF2", "LHPF2" }, \
+	{ name, "LHPF3", "LHPF3" }, \
+	{ name, "LHPF4", "LHPF4" }, \
+	{ name, "ASRC1IN1L", "ASRC1IN1L" }, \
+	{ name, "ASRC1IN1R", "ASRC1IN1R" }, \
+	{ name, "ASRC1IN2L", "ASRC1IN2L" }, \
+	{ name, "ASRC1IN2R", "ASRC1IN2R" }, \
+	{ name, "ASRC2IN1L", "ASRC2IN1L" }, \
+	{ name, "ASRC2IN1R", "ASRC2IN1R" }, \
+	{ name, "ASRC2IN2L", "ASRC2IN2L" }, \
+	{ name, "ASRC2IN2R", "ASRC2IN2R" }, \
+	{ name, "ISRC1DEC1", "ISRC1DEC1" }, \
+	{ name, "ISRC1DEC2", "ISRC1DEC2" }, \
+	{ name, "ISRC1DEC3", "ISRC1DEC3" }, \
+	{ name, "ISRC1DEC4", "ISRC1DEC4" }, \
+	{ name, "ISRC1INT1", "ISRC1INT1" }, \
+	{ name, "ISRC1INT2", "ISRC1INT2" }, \
+	{ name, "ISRC1INT3", "ISRC1INT3" }, \
+	{ name, "ISRC1INT4", "ISRC1INT4" }, \
+	{ name, "ISRC2DEC1", "ISRC2DEC1" }, \
+	{ name, "ISRC2DEC2", "ISRC2DEC2" }, \
+	{ name, "ISRC2DEC3", "ISRC2DEC3" }, \
+	{ name, "ISRC2DEC4", "ISRC2DEC4" }, \
+	{ name, "ISRC2INT1", "ISRC2INT1" }, \
+	{ name, "ISRC2INT2", "ISRC2INT2" }, \
+	{ name, "ISRC2INT3", "ISRC2INT3" }, \
+	{ name, "ISRC2INT4", "ISRC2INT4" }, \
+	{ name, "ISRC3DEC1", "ISRC3DEC1" }, \
+	{ name, "ISRC3DEC2", "ISRC3DEC2" }, \
+	{ name, "ISRC3INT1", "ISRC3INT1" }, \
+	{ name, "ISRC3INT2", "ISRC3INT2" }, \
+	{ name, "ISRC4DEC1", "ISRC4DEC1" }, \
+	{ name, "ISRC4DEC2", "ISRC4DEC2" }, \
+	{ name, "ISRC4INT1", "ISRC4INT1" }, \
+	{ name, "ISRC4INT2", "ISRC4INT2" }, \
+	{ name, "DSP1.1", "DSP1" }, \
+	{ name, "DSP1.2", "DSP1" }, \
+	{ name, "DSP1.3", "DSP1" }, \
+	{ name, "DSP1.4", "DSP1" }, \
+	{ name, "DSP1.5", "DSP1" }, \
+	{ name, "DSP1.6", "DSP1" }, \
+	{ name, "DSP2.1", "DSP2" }, \
+	{ name, "DSP2.2", "DSP2" }, \
+	{ name, "DSP2.3", "DSP2" }, \
+	{ name, "DSP2.4", "DSP2" }, \
+	{ name, "DSP2.5", "DSP2" }, \
+	{ name, "DSP2.6", "DSP2" }, \
+	{ name, "DSP3.1", "DSP3" }, \
+	{ name, "DSP3.2", "DSP3" }, \
+	{ name, "DSP3.3", "DSP3" }, \
+	{ name, "DSP3.4", "DSP3" }, \
+	{ name, "DSP3.5", "DSP3" }, \
+	{ name, "DSP3.6", "DSP3" }, \
+	{ name, "DSP4.1", "DSP4" }, \
+	{ name, "DSP4.2", "DSP4" }, \
+	{ name, "DSP4.3", "DSP4" }, \
+	{ name, "DSP4.4", "DSP4" }, \
+	{ name, "DSP4.5", "DSP4" }, \
+	{ name, "DSP4.6", "DSP4" }, \
+	{ name, "DSP5.1", "DSP5" }, \
+	{ name, "DSP5.2", "DSP5" }, \
+	{ name, "DSP5.3", "DSP5" }, \
+	{ name, "DSP5.4", "DSP5" }, \
+	{ name, "DSP5.5", "DSP5" }, \
+	{ name, "DSP5.6", "DSP5" }, \
+	{ name, "DSP6.1", "DSP6" }, \
+	{ name, "DSP6.2", "DSP6" }, \
+	{ name, "DSP6.3", "DSP6" }, \
+	{ name, "DSP6.4", "DSP6" }, \
+	{ name, "DSP6.5", "DSP6" }, \
+	{ name, "DSP6.6", "DSP6" }, \
+	{ name, "DSP7.1", "DSP7" }, \
+	{ name, "DSP7.2", "DSP7" }, \
+	{ name, "DSP7.3", "DSP7" }, \
+	{ name, "DSP7.4", "DSP7" }, \
+	{ name, "DSP7.5", "DSP7" }, \
+	{ name, "DSP7.6", "DSP7" }, \
+	{ name, "DFC1", "DFC1" }, \
+	{ name, "DFC2", "DFC2" }, \
+	{ name, "DFC3", "DFC3" }, \
+	{ name, "DFC4", "DFC4" }, \
+	{ name, "DFC5", "DFC5" }, \
+	{ name, "DFC6", "DFC6" }, \
+	{ name, "DFC7", "DFC7" }, \
+	{ name, "DFC8", "DFC8" }
+
+static const struct snd_soc_dapm_route cs47l90_dapm_routes[] = {
+	/* Internal clock domains */
+	{ "EQ1", NULL, "FXCLK" },
+	{ "EQ2", NULL, "FXCLK" },
+	{ "EQ3", NULL, "FXCLK" },
+	{ "EQ4", NULL, "FXCLK" },
+	{ "DRC1L", NULL, "FXCLK" },
+	{ "DRC1R", NULL, "FXCLK" },
+	{ "DRC2L", NULL, "FXCLK" },
+	{ "DRC2R", NULL, "FXCLK" },
+	{ "LHPF1", NULL, "FXCLK" },
+	{ "LHPF2", NULL, "FXCLK" },
+	{ "LHPF3", NULL, "FXCLK" },
+	{ "LHPF4", NULL, "FXCLK" },
+	{ "PWM1 Mixer", NULL, "PWMCLK" },
+	{ "PWM2 Mixer", NULL, "PWMCLK" },
+	{ "OUT1L", NULL, "OUTCLK" },
+	{ "OUT1R", NULL, "OUTCLK" },
+	{ "OUT2L", NULL, "OUTCLK" },
+	{ "OUT2R", NULL, "OUTCLK" },
+	{ "OUT3L", NULL, "OUTCLK" },
+	{ "OUT3R", NULL, "OUTCLK" },
+	{ "OUT5L", NULL, "OUTCLK" },
+	{ "OUT5R", NULL, "OUTCLK" },
+	{ "AIF1TX1", NULL, "AIF1TXCLK" },
+	{ "AIF1TX2", NULL, "AIF1TXCLK" },
+	{ "AIF1TX3", NULL, "AIF1TXCLK" },
+	{ "AIF1TX4", NULL, "AIF1TXCLK" },
+	{ "AIF1TX5", NULL, "AIF1TXCLK" },
+	{ "AIF1TX6", NULL, "AIF1TXCLK" },
+	{ "AIF1TX7", NULL, "AIF1TXCLK" },
+	{ "AIF1TX8", NULL, "AIF1TXCLK" },
+	{ "AIF2TX1", NULL, "AIF2TXCLK" },
+	{ "AIF2TX2", NULL, "AIF2TXCLK" },
+	{ "AIF2TX3", NULL, "AIF2TXCLK" },
+	{ "AIF2TX4", NULL, "AIF2TXCLK" },
+	{ "AIF2TX5", NULL, "AIF2TXCLK" },
+	{ "AIF2TX6", NULL, "AIF2TXCLK" },
+	{ "AIF2TX7", NULL, "AIF2TXCLK" },
+	{ "AIF2TX8", NULL, "AIF2TXCLK" },
+	{ "AIF3TX1", NULL, "AIF3TXCLK" },
+	{ "AIF3TX2", NULL, "AIF3TXCLK" },
+	{ "AIF4TX1", NULL, "AIF4TXCLK" },
+	{ "AIF4TX2", NULL, "AIF4TXCLK" },
+	{ "SLIMTX1", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX2", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX3", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX4", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX5", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX6", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX7", NULL, "SLIMBUSCLK" },
+	{ "SLIMTX8", NULL, "SLIMBUSCLK" },
+	{ "SPD1TX1", NULL, "SPDCLK" },
+	{ "SPD1TX2", NULL, "SPDCLK" },
+	{ "DSP1", NULL, "DSP1CLK" },
+	{ "DSP2", NULL, "DSP2CLK" },
+	{ "DSP3", NULL, "DSP3CLK" },
+	{ "DSP4", NULL, "DSP4CLK" },
+	{ "DSP5", NULL, "DSP5CLK" },
+	{ "DSP6", NULL, "DSP6CLK" },
+	{ "DSP7", NULL, "DSP7CLK" },
+	{ "ISRC1DEC1", NULL, "ISRC1DECCLK" },
+	{ "ISRC1DEC2", NULL, "ISRC1DECCLK" },
+	{ "ISRC1DEC3", NULL, "ISRC1DECCLK" },
+	{ "ISRC1DEC4", NULL, "ISRC1DECCLK" },
+	{ "ISRC1INT1", NULL, "ISRC1INTCLK" },
+	{ "ISRC1INT2", NULL, "ISRC1INTCLK" },
+	{ "ISRC1INT3", NULL, "ISRC1INTCLK" },
+	{ "ISRC1INT4", NULL, "ISRC1INTCLK" },
+	{ "ISRC2DEC1", NULL, "ISRC2DECCLK" },
+	{ "ISRC2DEC2", NULL, "ISRC2DECCLK" },
+	{ "ISRC2DEC3", NULL, "ISRC2DECCLK" },
+	{ "ISRC2DEC4", NULL, "ISRC2DECCLK" },
+	{ "ISRC2INT1", NULL, "ISRC2INTCLK" },
+	{ "ISRC2INT2", NULL, "ISRC2INTCLK" },
+	{ "ISRC2INT3", NULL, "ISRC2INTCLK" },
+	{ "ISRC2INT4", NULL, "ISRC2INTCLK" },
+	{ "ISRC3DEC1", NULL, "ISRC1DECCLK" },
+	{ "ISRC3DEC2", NULL, "ISRC1DECCLK" },
+	{ "ISRC3INT1", NULL, "ISRC1INTCLK" },
+	{ "ISRC3INT2", NULL, "ISRC1INTCLK" },
+	{ "ISRC4DEC1", NULL, "ISRC1DECCLK" },
+	{ "ISRC4DEC2", NULL, "ISRC1DECCLK" },
+	{ "ISRC4INT1", NULL, "ISRC1INTCLK" },
+	{ "ISRC4INT2", NULL, "ISRC1INTCLK" },
+	{ "ASRC1IN1L", NULL, "ASRC1R1CLK" },
+	{ "ASRC1IN1R", NULL, "ASRC1R1CLK" },
+	{ "ASRC1IN2L", NULL, "ASRC1R2CLK" },
+	{ "ASRC1IN2L", NULL, "ASRC1R2CLK" },
+	{ "ASRC2IN1L", NULL, "ASRC2R1CLK" },
+	{ "ASRC2IN1R", NULL, "ASRC2R1CLK" },
+	{ "ASRC2IN2L", NULL, "ASRC2R2CLK" },
+	{ "ASRC2IN2L", NULL, "ASRC2R2CLK" },
+	{ "DFC1", NULL, "DFCCLK" },
+	{ "DFC2", NULL, "DFCCLK" },
+	{ "DFC3", NULL, "DFCCLK" },
+	{ "DFC4", NULL, "DFCCLK" },
+	{ "DFC5", NULL, "DFCCLK" },
+	{ "DFC6", NULL, "DFCCLK" },
+	{ "DFC7", NULL, "DFCCLK" },
+	{ "DFC8", NULL, "DFCCLK" },
+
+	{ "AIF2 Capture", NULL, "DBVDD2" },
+	{ "AIF2 Playback", NULL, "DBVDD2" },
+
+	{ "AIF3 Capture", NULL, "DBVDD3" },
+	{ "AIF3 Playback", NULL, "DBVDD3" },
+
+	{ "AIF4 Capture", NULL, "DBVDD3" },
+	{ "AIF4 Playback", NULL, "DBVDD3" },
+
+	{ "OUT1L", NULL, "CPVDD1" },
+	{ "OUT1L", NULL, "CPVDD2" },
+	{ "OUT1R", NULL, "CPVDD1" },
+	{ "OUT1R", NULL, "CPVDD2" },
+	{ "OUT2L", NULL, "CPVDD1" },
+	{ "OUT2L", NULL, "CPVDD2" },
+	{ "OUT2R", NULL, "CPVDD1" },
+	{ "OUT2R", NULL, "CPVDD2" },
+	{ "OUT3L", NULL, "CPVDD1" },
+	{ "OUT3L", NULL, "CPVDD2" },
+	{ "OUT3R", NULL, "CPVDD1" },
+	{ "OUT3R", NULL, "CPVDD2" },
+
+	{ "OUT1L", NULL, "SYSCLK" },
+	{ "OUT1R", NULL, "SYSCLK" },
+	{ "OUT2L", NULL, "SYSCLK" },
+	{ "OUT2R", NULL, "SYSCLK" },
+	{ "OUT3L", NULL, "SYSCLK" },
+	{ "OUT3R", NULL, "SYSCLK" },
+	{ "OUT5L", NULL, "SYSCLK" },
+	{ "OUT5R", NULL, "SYSCLK" },
+
+	{ "SPD1", NULL, "SYSCLK" },
+	{ "SPD1", NULL, "SPD1TX1" },
+	{ "SPD1", NULL, "SPD1TX2" },
+
+	{ "IN1AL", NULL, "SYSCLK" },
+	{ "IN1BL", NULL, "SYSCLK" },
+	{ "IN1AR", NULL, "SYSCLK" },
+	{ "IN1BR", NULL, "SYSCLK" },
+	{ "IN2AL", NULL, "SYSCLK" },
+	{ "IN2BL", NULL, "SYSCLK" },
+	{ "IN2R", NULL, "SYSCLK" },
+	{ "IN3L", NULL, "SYSCLK" },
+	{ "IN3R", NULL, "SYSCLK" },
+	{ "IN4L", NULL, "SYSCLK" },
+	{ "IN4R", NULL, "SYSCLK" },
+	{ "IN5L", NULL, "SYSCLK" },
+	{ "IN5R", NULL, "SYSCLK" },
+
+	{ "IN3L", NULL, "DBVDD4" },
+	{ "IN3R", NULL, "DBVDD4" },
+	{ "IN4L", NULL, "DBVDD4" },
+	{ "IN4R", NULL, "DBVDD4" },
+	{ "IN5L", NULL, "DBVDD4" },
+	{ "IN5R", NULL, "DBVDD4" },
+
+	{ "ASRC1IN1L", NULL, "SYSCLK" },
+	{ "ASRC1IN1R", NULL, "SYSCLK" },
+	{ "ASRC1IN2L", NULL, "SYSCLK" },
+	{ "ASRC1IN2R", NULL, "SYSCLK" },
+	{ "ASRC2IN1L", NULL, "SYSCLK" },
+	{ "ASRC2IN1R", NULL, "SYSCLK" },
+	{ "ASRC2IN2L", NULL, "SYSCLK" },
+	{ "ASRC2IN2R", NULL, "SYSCLK" },
+
+	{ "ASRC1IN1L", NULL, "ASYNCCLK" },
+	{ "ASRC1IN1R", NULL, "ASYNCCLK" },
+	{ "ASRC1IN2L", NULL, "ASYNCCLK" },
+	{ "ASRC1IN2R", NULL, "ASYNCCLK" },
+	{ "ASRC2IN1L", NULL, "ASYNCCLK" },
+	{ "ASRC2IN1R", NULL, "ASYNCCLK" },
+	{ "ASRC2IN2L", NULL, "ASYNCCLK" },
+	{ "ASRC2IN2R", NULL, "ASYNCCLK" },
+
+	{ "MICBIAS1", NULL, "MICVDD" },
+	{ "MICBIAS2", NULL, "MICVDD" },
+
+	{ "MICBIAS1A", NULL, "MICBIAS1" },
+	{ "MICBIAS1B", NULL, "MICBIAS1" },
+	{ "MICBIAS1C", NULL, "MICBIAS1" },
+	{ "MICBIAS1D", NULL, "MICBIAS1" },
+
+	{ "MICBIAS2A", NULL, "MICBIAS2" },
+	{ "MICBIAS2B", NULL, "MICBIAS2" },
+	{ "MICBIAS2C", NULL, "MICBIAS2" },
+	{ "MICBIAS2D", NULL, "MICBIAS2" },
+
+	{ "Noise Generator", NULL, "SYSCLK" },
+	{ "Tone Generator 1", NULL, "SYSCLK" },
+	{ "Tone Generator 2", NULL, "SYSCLK" },
+
+	{ "Noise Generator", NULL, "NOISE" },
+	{ "Tone Generator 1", NULL, "TONE" },
+	{ "Tone Generator 2", NULL, "TONE" },
+
+	{ "AIF1 Capture", NULL, "AIF1TX1" },
+	{ "AIF1 Capture", NULL, "AIF1TX2" },
+	{ "AIF1 Capture", NULL, "AIF1TX3" },
+	{ "AIF1 Capture", NULL, "AIF1TX4" },
+	{ "AIF1 Capture", NULL, "AIF1TX5" },
+	{ "AIF1 Capture", NULL, "AIF1TX6" },
+	{ "AIF1 Capture", NULL, "AIF1TX7" },
+	{ "AIF1 Capture", NULL, "AIF1TX8" },
+
+	{ "AIF1RX1", NULL, "AIF1 Playback" },
+	{ "AIF1RX2", NULL, "AIF1 Playback" },
+	{ "AIF1RX3", NULL, "AIF1 Playback" },
+	{ "AIF1RX4", NULL, "AIF1 Playback" },
+	{ "AIF1RX5", NULL, "AIF1 Playback" },
+	{ "AIF1RX6", NULL, "AIF1 Playback" },
+	{ "AIF1RX7", NULL, "AIF1 Playback" },
+	{ "AIF1RX8", NULL, "AIF1 Playback" },
+
+	{ "AIF2 Capture", NULL, "AIF2TX1" },
+	{ "AIF2 Capture", NULL, "AIF2TX2" },
+	{ "AIF2 Capture", NULL, "AIF2TX3" },
+	{ "AIF2 Capture", NULL, "AIF2TX4" },
+	{ "AIF2 Capture", NULL, "AIF2TX5" },
+	{ "AIF2 Capture", NULL, "AIF2TX6" },
+	{ "AIF2 Capture", NULL, "AIF2TX7" },
+	{ "AIF2 Capture", NULL, "AIF2TX8" },
+
+	{ "AIF2RX1", NULL, "AIF2 Playback" },
+	{ "AIF2RX2", NULL, "AIF2 Playback" },
+	{ "AIF2RX3", NULL, "AIF2 Playback" },
+	{ "AIF2RX4", NULL, "AIF2 Playback" },
+	{ "AIF2RX5", NULL, "AIF2 Playback" },
+	{ "AIF2RX6", NULL, "AIF2 Playback" },
+	{ "AIF2RX7", NULL, "AIF2 Playback" },
+	{ "AIF2RX8", NULL, "AIF2 Playback" },
+
+	{ "AIF3 Capture", NULL, "AIF3TX1" },
+	{ "AIF3 Capture", NULL, "AIF3TX2" },
+
+	{ "AIF3RX1", NULL, "AIF3 Playback" },
+	{ "AIF3RX2", NULL, "AIF3 Playback" },
+
+	{ "AIF4 Capture", NULL, "AIF4TX1" },
+	{ "AIF4 Capture", NULL, "AIF4TX2" },
+
+	{ "AIF4RX1", NULL, "AIF4 Playback" },
+	{ "AIF4RX2", NULL, "AIF4 Playback" },
+
+	{ "Slim1 Capture", NULL, "SLIMTX1" },
+	{ "Slim1 Capture", NULL, "SLIMTX2" },
+	{ "Slim1 Capture", NULL, "SLIMTX3" },
+	{ "Slim1 Capture", NULL, "SLIMTX4" },
+
+	{ "SLIMRX1", NULL, "Slim1 Playback" },
+	{ "SLIMRX2", NULL, "Slim1 Playback" },
+	{ "SLIMRX3", NULL, "Slim1 Playback" },
+	{ "SLIMRX4", NULL, "Slim1 Playback" },
+
+	{ "Slim2 Capture", NULL, "SLIMTX5" },
+	{ "Slim2 Capture", NULL, "SLIMTX6" },
+
+	{ "SLIMRX5", NULL, "Slim2 Playback" },
+	{ "SLIMRX6", NULL, "Slim2 Playback" },
+
+	{ "Slim3 Capture", NULL, "SLIMTX7" },
+	{ "Slim3 Capture", NULL, "SLIMTX8" },
+
+	{ "SLIMRX7", NULL, "Slim3 Playback" },
+	{ "SLIMRX8", NULL, "Slim3 Playback" },
+
+	{ "AIF1 Playback", NULL, "SYSCLK" },
+	{ "AIF2 Playback", NULL, "SYSCLK" },
+	{ "AIF3 Playback", NULL, "SYSCLK" },
+	{ "AIF4 Playback", NULL, "SYSCLK" },
+	{ "Slim1 Playback", NULL, "SYSCLK" },
+	{ "Slim2 Playback", NULL, "SYSCLK" },
+	{ "Slim3 Playback", NULL, "SYSCLK" },
+
+	{ "AIF1 Capture", NULL, "SYSCLK" },
+	{ "AIF2 Capture", NULL, "SYSCLK" },
+	{ "AIF3 Capture", NULL, "SYSCLK" },
+	{ "AIF4 Capture", NULL, "SYSCLK" },
+	{ "Slim1 Capture", NULL, "SYSCLK" },
+	{ "Slim2 Capture", NULL, "SYSCLK" },
+	{ "Slim3 Capture", NULL, "SYSCLK" },
+
+	{ "Voice Control DSP", NULL, "DSP6" },
+
+	{ "Audio Trace DSP", NULL, "DSP1" },
+
+	{ "IN1L Mux", "A", "IN1AL" },
+	{ "IN1L Mux", "B", "IN1BL" },
+	{ "IN1R Mux", "A", "IN1AR" },
+	{ "IN1R Mux", "B", "IN1BR" },
+
+	{ "IN2L Mux", "A", "IN2AL" },
+	{ "IN2L Mux", "B", "IN2BL" },
+
+	{ "IN1L PGA", NULL, "IN1L Mux" },
+	{ "IN1R PGA", NULL, "IN1R Mux" },
+
+	{ "IN2L PGA", NULL, "IN2L Mux" },
+	{ "IN2R PGA", NULL, "IN2R" },
+
+	{ "IN3L PGA", NULL, "IN3L" },
+	{ "IN3R PGA", NULL, "IN3R" },
+
+	{ "IN4L PGA", NULL, "IN4L" },
+	{ "IN4R PGA", NULL, "IN4R" },
+
+	{ "IN5L PGA", NULL, "IN5L" },
+	{ "IN5R PGA", NULL, "IN5R" },
+
+	MADERA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
+	MADERA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
+	MADERA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
+	MADERA_MIXER_ROUTES("OUT2R", "HPOUT2R"),
+	MADERA_MIXER_ROUTES("OUT3L", "HPOUT3L"),
+	MADERA_MIXER_ROUTES("OUT3R", "HPOUT3R"),
+
+	MADERA_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
+	MADERA_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
+
+	MADERA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
+	MADERA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
+
+	MADERA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
+	MADERA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
+	MADERA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
+	MADERA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
+	MADERA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
+	MADERA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
+	MADERA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
+	MADERA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
+
+	MADERA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
+	MADERA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
+	MADERA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"),
+	MADERA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"),
+	MADERA_MIXER_ROUTES("AIF2TX5", "AIF2TX5"),
+	MADERA_MIXER_ROUTES("AIF2TX6", "AIF2TX6"),
+	MADERA_MIXER_ROUTES("AIF2TX7", "AIF2TX7"),
+	MADERA_MIXER_ROUTES("AIF2TX8", "AIF2TX8"),
+
+	MADERA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
+	MADERA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
+
+	MADERA_MIXER_ROUTES("AIF4TX1", "AIF4TX1"),
+	MADERA_MIXER_ROUTES("AIF4TX2", "AIF4TX2"),
+
+	MADERA_MIXER_ROUTES("SLIMTX1", "SLIMTX1"),
+	MADERA_MIXER_ROUTES("SLIMTX2", "SLIMTX2"),
+	MADERA_MIXER_ROUTES("SLIMTX3", "SLIMTX3"),
+	MADERA_MIXER_ROUTES("SLIMTX4", "SLIMTX4"),
+	MADERA_MIXER_ROUTES("SLIMTX5", "SLIMTX5"),
+	MADERA_MIXER_ROUTES("SLIMTX6", "SLIMTX6"),
+	MADERA_MIXER_ROUTES("SLIMTX7", "SLIMTX7"),
+	MADERA_MIXER_ROUTES("SLIMTX8", "SLIMTX8"),
+
+	MADERA_MUX_ROUTES("SPD1TX1", "SPDIF1TX1"),
+	MADERA_MUX_ROUTES("SPD1TX2", "SPDIF1TX2"),
+
+	MADERA_MIXER_ROUTES("EQ1", "EQ1"),
+	MADERA_MIXER_ROUTES("EQ2", "EQ2"),
+	MADERA_MIXER_ROUTES("EQ3", "EQ3"),
+	MADERA_MIXER_ROUTES("EQ4", "EQ4"),
+
+	MADERA_MIXER_ROUTES("DRC1L", "DRC1L"),
+	MADERA_MIXER_ROUTES("DRC1R", "DRC1R"),
+	MADERA_MIXER_ROUTES("DRC2L", "DRC2L"),
+	MADERA_MIXER_ROUTES("DRC2R", "DRC2R"),
+
+	MADERA_MIXER_ROUTES("LHPF1", "LHPF1"),
+	MADERA_MIXER_ROUTES("LHPF2", "LHPF2"),
+	MADERA_MIXER_ROUTES("LHPF3", "LHPF3"),
+	MADERA_MIXER_ROUTES("LHPF4", "LHPF4"),
+
+	MADERA_MUX_ROUTES("ASRC1IN1L", "ASRC1IN1L"),
+	MADERA_MUX_ROUTES("ASRC1IN1R", "ASRC1IN1R"),
+	MADERA_MUX_ROUTES("ASRC1IN2L", "ASRC1IN2L"),
+	MADERA_MUX_ROUTES("ASRC1IN2R", "ASRC1IN2R"),
+	MADERA_MUX_ROUTES("ASRC2IN1L", "ASRC2IN1L"),
+	MADERA_MUX_ROUTES("ASRC2IN1R", "ASRC2IN1R"),
+	MADERA_MUX_ROUTES("ASRC2IN2L", "ASRC2IN2L"),
+	MADERA_MUX_ROUTES("ASRC2IN2R", "ASRC2IN2R"),
+
+	MADERA_DSP_ROUTES("DSP1"),
+	MADERA_DSP_ROUTES("DSP2"),
+	MADERA_DSP_ROUTES("DSP3"),
+	MADERA_DSP_ROUTES("DSP4"),
+	MADERA_DSP_ROUTES("DSP5"),
+	MADERA_DSP_ROUTES("DSP6"),
+	MADERA_DSP_ROUTES("DSP7"),
+
+	{ "DSP Trigger Out", NULL, "DSP1 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP2 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP3 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP4 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP5 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP6 Trigger Output" },
+	{ "DSP Trigger Out", NULL, "DSP7 Trigger Output" },
+
+	{ "DSP1 Trigger Output", "Switch", "DSP1" },
+	{ "DSP2 Trigger Output", "Switch", "DSP2" },
+	{ "DSP3 Trigger Output", "Switch", "DSP3" },
+	{ "DSP4 Trigger Output", "Switch", "DSP4" },
+	{ "DSP5 Trigger Output", "Switch", "DSP5" },
+	{ "DSP6 Trigger Output", "Switch", "DSP6" },
+	{ "DSP7 Trigger Output", "Switch", "DSP7" },
+
+	MADERA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
+	MADERA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
+	MADERA_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
+	MADERA_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
+
+	MADERA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
+	MADERA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
+	MADERA_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
+	MADERA_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
+
+	MADERA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
+	MADERA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
+	MADERA_MUX_ROUTES("ISRC2INT3", "ISRC2INT3"),
+	MADERA_MUX_ROUTES("ISRC2INT4", "ISRC2INT4"),
+
+	MADERA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
+	MADERA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
+	MADERA_MUX_ROUTES("ISRC2DEC3", "ISRC2DEC3"),
+	MADERA_MUX_ROUTES("ISRC2DEC4", "ISRC2DEC4"),
+
+	MADERA_MUX_ROUTES("ISRC3INT1", "ISRC3INT1"),
+	MADERA_MUX_ROUTES("ISRC3INT2", "ISRC3INT2"),
+
+	MADERA_MUX_ROUTES("ISRC3DEC1", "ISRC3DEC1"),
+	MADERA_MUX_ROUTES("ISRC3DEC2", "ISRC3DEC2"),
+
+	MADERA_MUX_ROUTES("ISRC4INT1", "ISRC4INT1"),
+	MADERA_MUX_ROUTES("ISRC4INT2", "ISRC4INT2"),
+
+	MADERA_MUX_ROUTES("ISRC4DEC1", "ISRC4DEC1"),
+	MADERA_MUX_ROUTES("ISRC4DEC2", "ISRC4DEC2"),
+
+	{ "AEC1 Loopback", "HPOUT1L", "OUT1L" },
+	{ "AEC1 Loopback", "HPOUT1R", "OUT1R" },
+	{ "HPOUT1L", NULL, "OUT1L" },
+	{ "HPOUT1R", NULL, "OUT1R" },
+
+	{ "AEC1 Loopback", "HPOUT2L", "OUT2L" },
+	{ "AEC1 Loopback", "HPOUT2R", "OUT2R" },
+	{ "HPOUT2L", NULL, "OUT2L" },
+	{ "HPOUT2R", NULL, "OUT2R" },
+
+	{ "AEC1 Loopback", "HPOUT3L", "OUT3L" },
+	{ "AEC1 Loopback", "HPOUT3R", "OUT3R" },
+	{ "HPOUT3L", NULL, "OUT3L" },
+	{ "HPOUT3R", NULL, "OUT3R" },
+
+	{ "AEC1 Loopback", "SPKDAT1L", "OUT5L" },
+	{ "AEC1 Loopback", "SPKDAT1R", "OUT5R" },
+	{ "SPKDAT1L", NULL, "OUT5L" },
+	{ "SPKDAT1R", NULL, "OUT5R" },
+
+	CS47L90_RXANC_INPUT_ROUTES("RXANCL", "RXANCL"),
+	CS47L90_RXANC_INPUT_ROUTES("RXANCR", "RXANCR"),
+
+	CS47L90_RXANC_OUTPUT_ROUTES("OUT1L", "HPOUT1L"),
+	CS47L90_RXANC_OUTPUT_ROUTES("OUT1R", "HPOUT1R"),
+	CS47L90_RXANC_OUTPUT_ROUTES("OUT2L", "HPOUT2L"),
+	CS47L90_RXANC_OUTPUT_ROUTES("OUT2R", "HPOUT2R"),
+	CS47L90_RXANC_OUTPUT_ROUTES("OUT3L", "HPOUT3L"),
+	CS47L90_RXANC_OUTPUT_ROUTES("OUT3R", "HPOUT3R"),
+	CS47L90_RXANC_OUTPUT_ROUTES("OUT5L", "SPKDAT1L"),
+	CS47L90_RXANC_OUTPUT_ROUTES("OUT5R", "SPKDAT1R"),
+
+	{ "SPDIF1", NULL, "SPD1" },
+
+	{ "MICSUPP", NULL, "SYSCLK" },
+
+	{ "DRC1 Signal Activity", NULL, "DRC1 Activity Output" },
+	{ "DRC2 Signal Activity", NULL, "DRC2 Activity Output" },
+	{ "DRC1 Activity Output", "Switch", "DRC1L" },
+	{ "DRC1 Activity Output", "Switch", "DRC1R" },
+	{ "DRC2 Activity Output", "Switch", "DRC2L" },
+	{ "DRC2 Activity Output", "Switch", "DRC2R" },
+
+	MADERA_MUX_ROUTES("DFC1", "DFC1"),
+	MADERA_MUX_ROUTES("DFC2", "DFC2"),
+	MADERA_MUX_ROUTES("DFC3", "DFC3"),
+	MADERA_MUX_ROUTES("DFC4", "DFC4"),
+	MADERA_MUX_ROUTES("DFC5", "DFC5"),
+	MADERA_MUX_ROUTES("DFC6", "DFC6"),
+	MADERA_MUX_ROUTES("DFC7", "DFC7"),
+	MADERA_MUX_ROUTES("DFC8", "DFC8"),
+};
+
+static int cs47l90_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+			   unsigned int Fref, unsigned int Fout)
+{
+	struct cs47l90 *cs47l90 = snd_soc_codec_get_drvdata(codec);
+
+	switch (fll_id) {
+	case MADERA_FLL1_REFCLK:
+		return madera_set_fll_refclk(&cs47l90->fll[0], source, Fref,
+					     Fout);
+	case MADERA_FLL2_REFCLK:
+		return madera_set_fll_refclk(&cs47l90->fll[1], source, Fref,
+					     Fout);
+	case MADERA_FLLAO_REFCLK:
+		return madera_set_fll_ao_refclk(&cs47l90->fll[2], source, Fref,
+						Fout);
+	case MADERA_FLL1_SYNCCLK:
+		return madera_set_fll_syncclk(&cs47l90->fll[0], source, Fref,
+					      Fout);
+	case MADERA_FLL2_SYNCCLK:
+		return madera_set_fll_syncclk(&cs47l90->fll[1], source, Fref,
+					      Fout);
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct snd_soc_dai_driver cs47l90_dai[] = {
+	{
+		.name = "cs47l90-aif1",
+		.id = 1,
+		.base = MADERA_AIF1_BCLK_CTRL,
+		.playback = {
+			.stream_name = "AIF1 Playback",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AIF1 Capture",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_dai_ops,
+		.symmetric_rates = 1,
+		.symmetric_samplebits = 1,
+	},
+	{
+		.name = "cs47l90-aif2",
+		.id = 2,
+		.base = MADERA_AIF2_BCLK_CTRL,
+		.playback = {
+			.stream_name = "AIF2 Playback",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AIF2 Capture",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_dai_ops,
+		.symmetric_rates = 1,
+		.symmetric_samplebits = 1,
+	},
+	{
+		.name = "cs47l90-aif3",
+		.id = 3,
+		.base = MADERA_AIF3_BCLK_CTRL,
+		.playback = {
+			.stream_name = "AIF3 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AIF3 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_dai_ops,
+		.symmetric_rates = 1,
+		.symmetric_samplebits = 1,
+	},
+	{
+		.name = "cs47l90-aif4",
+		.id = 4,
+		.base = MADERA_AIF4_BCLK_CTRL,
+		.playback = {
+			.stream_name = "AIF4 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AIF4 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_dai_ops,
+		.symmetric_rates = 1,
+		.symmetric_samplebits = 1,
+	},
+	{
+		.name = "cs47l90-slim1",
+		.id = 5,
+		.playback = {
+			.stream_name = "Slim1 Playback",
+			.channels_min = 1,
+			.channels_max = 4,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "Slim1 Capture",
+			.channels_min = 1,
+			.channels_max = 4,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_simple_dai_ops,
+	},
+	{
+		.name = "cs47l90-slim2",
+		.id = 6,
+		.playback = {
+			.stream_name = "Slim2 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "Slim2 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_simple_dai_ops,
+	},
+	{
+		.name = "cs47l90-slim3",
+		.id = 7,
+		.playback = {
+			.stream_name = "Slim3 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.capture = {
+			.stream_name = "Slim3 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		 },
+		.ops = &madera_simple_dai_ops,
+	},
+	{
+		.name = "cs47l90-cpu-voicectrl",
+		.capture = {
+			.stream_name = "Voice Control CPU",
+			.channels_min = 1,
+			.channels_max = 1,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.compress_new = snd_soc_new_compress,
+	},
+	{
+		.name = "cs47l90-dsp-voicectrl",
+		.capture = {
+			.stream_name = "Voice Control DSP",
+			.channels_min = 1,
+			.channels_max = 1,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+	},
+	{
+		.name = "cs47l90-cpu-trace",
+		.capture = {
+			.stream_name = "Audio Trace CPU",
+			.channels_min = 1,
+			.channels_max = 6,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+		.compress_new = snd_soc_new_compress,
+	},
+	{
+		.name = "cs47l90-dsp-trace",
+		.capture = {
+			.stream_name = "Audio Trace DSP",
+			.channels_min = 1,
+			.channels_max = 6,
+			.rates = MADERA_RATES,
+			.formats = MADERA_FORMATS,
+		},
+	},
+};
+
+static int cs47l90_open(struct snd_compr_stream *stream)
+{
+	struct snd_soc_pcm_runtime *rtd = stream->private_data;
+	struct cs47l90 *cs47l90 = snd_soc_platform_get_drvdata(rtd->platform);
+	struct madera_priv *priv = &cs47l90->core;
+	struct madera *madera = priv->madera;
+	int n_adsp;
+
+	if (strcmp(rtd->codec_dai->name, "cs47l90-dsp-voicectrl") == 0) {
+		n_adsp = 5;
+	} else if (strcmp(rtd->codec_dai->name, "cs47l90-dsp-trace") == 0) {
+		n_adsp = 0;
+	} else {
+		dev_err(madera->dev,
+			"No suitable compressed stream for DAI '%s'\n",
+			rtd->codec_dai->name);
+		return -EINVAL;
+	}
+
+	return wm_adsp_compr_open(&priv->adsp[n_adsp], stream);
+}
+
+static irqreturn_t cs47l90_adsp2_irq(int irq, void *data)
+{
+	struct cs47l90 *cs47l90 = data;
+	struct madera_priv *priv = &cs47l90->core;
+	struct madera *madera = priv->madera;
+	struct madera_voice_trigger_info trig_info;
+	int serviced = 0;
+	int i, ret;
+
+	for (i = 0; i < CS47L90_NUM_ADSP; ++i) {
+		ret = wm_adsp_compr_handle_irq(&priv->adsp[i]);
+		if (ret != -ENODEV)
+			serviced++;
+		if (ret == WM_ADSP_COMPR_VOICE_TRIGGER) {
+			trig_info.core_num = i + 1;
+			madera_call_notifiers(madera,
+					      MADERA_NOTIFY_VOICE_TRIGGER,
+					      &trig_info);
+		}
+	}
+
+	if (!serviced) {
+		dev_err(madera->dev, "Spurious compressed data IRQ\n");
+		return IRQ_NONE;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t cs47l90_dsp_bus_error(int irq, void *data)
+{
+	struct wm_adsp *dsp = (struct wm_adsp *)data;
+
+	return wm_adsp2_bus_error(dsp);
+}
+
+static const char * const cs47l90_dmic_refs[] = {
+	"MICVDD",
+	"MICBIAS1",
+	"MICBIAS2",
+	"MICBIAS3",
+};
+
+static const char * const cs47l90_dmic_inputs[] = {
+	"IN1L Mux",
+	"IN1R Mux",
+	"IN2L Mux",
+	"IN2R",
+	"IN3L",
+	"IN3R",
+	"IN4L",
+	"IN4R",
+	"IN5L",
+	"IN5R",
+};
+
+static int cs47l90_codec_probe(struct snd_soc_codec *codec)
+{
+	struct cs47l90 *cs47l90 = snd_soc_codec_get_drvdata(codec);
+	struct madera *madera = cs47l90->core.madera;
+	int ret, i;
+
+	madera->dapm = snd_soc_codec_get_dapm(codec);
+
+	ret = madera_init_inputs(codec,
+				 cs47l90_dmic_inputs,
+				 ARRAY_SIZE(cs47l90_dmic_inputs),
+				 cs47l90_dmic_refs,
+				 ARRAY_SIZE(cs47l90_dmic_refs));
+	if (ret)
+		return ret;
+
+	ret = madera_init_outputs(codec, CS47L90_MONO_OUTPUTS);
+	if (ret)
+		return ret;
+
+	snd_soc_component_disable_pin(snd_soc_dapm_to_component(madera->dapm),
+				      "HAPTICS");
+
+	ret = snd_soc_add_codec_controls(codec, madera_adsp_rate_controls,
+					 CS47L90_NUM_ADSP);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < CS47L90_NUM_ADSP; i++)
+		wm_adsp2_codec_probe(&cs47l90->core.adsp[i], codec);
+
+	return 0;
+}
+
+static int cs47l90_codec_remove(struct snd_soc_codec *codec)
+{
+	int i;
+	struct cs47l90 *cs47l90 = snd_soc_codec_get_drvdata(codec);
+
+	for (i = 0; i < CS47L90_NUM_ADSP; i++) {
+		wm_adsp2_codec_remove(&cs47l90->core.adsp[i], codec);
+		madera_destroy_bus_error_irq(&cs47l90->core, i);
+	}
+
+	cs47l90->core.madera->dapm = NULL;
+
+	return 0;
+}
+
+#define CS47L90_DIG_VU 0x0200
+
+static unsigned int cs47l90_digital_vu[] = {
+	MADERA_DAC_DIGITAL_VOLUME_1L,
+	MADERA_DAC_DIGITAL_VOLUME_1R,
+	MADERA_DAC_DIGITAL_VOLUME_2L,
+	MADERA_DAC_DIGITAL_VOLUME_2R,
+	MADERA_DAC_DIGITAL_VOLUME_3L,
+	MADERA_DAC_DIGITAL_VOLUME_3R,
+	MADERA_DAC_DIGITAL_VOLUME_5L,
+	MADERA_DAC_DIGITAL_VOLUME_5R,
+};
+
+static struct regmap *cs47l90_get_regmap(struct device *dev)
+{
+	struct cs47l90 *cs47l90 = dev_get_drvdata(dev);
+
+	return cs47l90->core.madera->regmap;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_cs47l90 = {
+	.probe = cs47l90_codec_probe,
+	.remove = cs47l90_codec_remove,
+	.get_regmap = cs47l90_get_regmap,
+
+	.idle_bias_off = true,
+
+	.set_sysclk = madera_set_sysclk,
+	.set_pll = cs47l90_set_fll,
+
+	.component_driver = {
+		.controls = cs47l90_snd_controls,
+		.num_controls = ARRAY_SIZE(cs47l90_snd_controls),
+		.dapm_widgets = cs47l90_dapm_widgets,
+		.num_dapm_widgets = ARRAY_SIZE(cs47l90_dapm_widgets),
+		.dapm_routes = cs47l90_dapm_routes,
+		.num_dapm_routes = ARRAY_SIZE(cs47l90_dapm_routes),
+	},
+};
+
+static struct snd_compr_ops cs47l90_compr_ops = {
+	.open = cs47l90_open,
+	.free = wm_adsp_compr_free,
+	.set_params = wm_adsp_compr_set_params,
+	.get_caps = wm_adsp_compr_get_caps,
+	.trigger = wm_adsp_compr_trigger,
+	.pointer = wm_adsp_compr_pointer,
+	.copy = wm_adsp_compr_copy,
+};
+
+static struct snd_soc_platform_driver cs47l90_compr_platform = {
+	.compr_ops = &cs47l90_compr_ops,
+};
+
+static int cs47l90_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	struct cs47l90 *cs47l90;
+	int i, ret;
+
+	BUILD_BUG_ON(ARRAY_SIZE(cs47l90_dai) > MADERA_MAX_DAI);
+
+	/* quick exit if Madera irqchip driver hasn't completed probe */
+	if (!madera->irq_dev) {
+		dev_dbg(&pdev->dev, "irqchip driver not ready\n");
+		return -EPROBE_DEFER;
+	}
+
+	cs47l90 = devm_kzalloc(&pdev->dev, sizeof(struct cs47l90),
+			      GFP_KERNEL);
+	if (!cs47l90)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, cs47l90);
+
+	cs47l90->core.madera = madera;
+	cs47l90->core.dev = &pdev->dev;
+	cs47l90->core.num_inputs = 10;
+
+	ret = madera_core_init(&cs47l90->core);
+	if (ret)
+		return ret;
+
+	ret = madera_request_irq(madera, MADERA_IRQ_DSP_IRQ1,
+				 "ADSP2 Compressed IRQ", cs47l90_adsp2_irq,
+				 cs47l90);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request DSP IRQ: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < CS47L90_NUM_ADSP; i++) {
+		cs47l90->core.adsp[i].part = "cs47l90";
+		cs47l90->core.adsp[i].num = i + 1;
+		cs47l90->core.adsp[i].type = WMFW_ADSP2;
+		cs47l90->core.adsp[i].rev = 2;
+		cs47l90->core.adsp[i].dev = madera->dev;
+		cs47l90->core.adsp[i].regmap = madera->regmap_32bit;
+
+		cs47l90->core.adsp[i].base = cs47l90_dsp_control_bases[i];
+		cs47l90->core.adsp[i].mem = cs47l90_dsp_regions[i];
+		cs47l90->core.adsp[i].num_mems
+			= ARRAY_SIZE(cs47l90_dsp1_regions);
+
+		cs47l90->core.adsp[i].lock_regions = WM_ADSP2_REGION_1_9;
+
+		ret = wm_adsp2_init(&cs47l90->core.adsp[i]);
+
+		if (ret == 0) {
+			ret = madera_init_bus_error_irq(&cs47l90->core,
+							i,
+							cs47l90_dsp_bus_error);
+			if (ret != 0)
+				wm_adsp2_remove(&cs47l90->core.adsp[i]);
+		}
+
+		if (ret != 0) {
+			for (--i; i >= 0; --i) {
+				madera_destroy_bus_error_irq(&cs47l90->core, i);
+				wm_adsp2_remove(&cs47l90->core.adsp[i]);
+			}
+			goto error_core;
+		}
+	}
+
+	madera_init_fll(madera, 1, MADERA_FLL1_CONTROL_1 - 1,
+			&cs47l90->fll[0]);
+	madera_init_fll(madera, 2, MADERA_FLL2_CONTROL_1 - 1,
+			&cs47l90->fll[1]);
+	madera_init_fll(madera, 4, MADERA_FLLAO_CONTROL_1 - 1,
+			&cs47l90->fll[2]);
+
+	for (i = 0; i < ARRAY_SIZE(cs47l90_dai); i++)
+		madera_init_dai(&cs47l90->core, i);
+
+	/* Latch volume update bits */
+	for (i = 0; i < ARRAY_SIZE(cs47l90_digital_vu); i++)
+		regmap_update_bits(madera->regmap, cs47l90_digital_vu[i],
+				   CS47L90_DIG_VU, CS47L90_DIG_VU);
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_idle(&pdev->dev);
+
+	ret = snd_soc_register_platform(&pdev->dev, &cs47l90_compr_platform);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
+		goto error;
+	}
+
+	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l90,
+				     cs47l90_dai, ARRAY_SIZE(cs47l90_dai));
+	if (ret < 0) {
+		dev_err(&pdev->dev,
+			"Failed to register codec: %d\n", ret);
+		snd_soc_unregister_platform(&pdev->dev);
+		goto error;
+	}
+
+	return ret;
+
+error:
+	for (i = 0; i < CS47L90_NUM_ADSP; i++) {
+		madera_destroy_bus_error_irq(&cs47l90->core, i);
+		wm_adsp2_remove(&cs47l90->core.adsp[i]);
+	}
+
+error_core:
+	madera_free_irq(madera, MADERA_IRQ_DSP_IRQ1, cs47l90);
+	madera_core_destroy(&cs47l90->core);
+
+	return ret;
+}
+
+static int cs47l90_remove(struct platform_device *pdev)
+{
+	struct cs47l90 *cs47l90 = platform_get_drvdata(pdev);
+	int i;
+
+	snd_soc_unregister_platform(&pdev->dev);
+	snd_soc_unregister_codec(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
+	for (i = 0; i < CS47L90_NUM_ADSP; i++) {
+		madera_destroy_bus_error_irq(&cs47l90->core, i);
+		wm_adsp2_remove(&cs47l90->core.adsp[i]);
+	}
+
+	madera_free_irq(cs47l90->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l90);
+	madera_core_destroy(&cs47l90->core);
+
+	return 0;
+}
+
+static struct platform_driver cs47l90_codec_driver = {
+	.driver = {
+		.name = "cs47l90-codec",
+	},
+	.probe = cs47l90_probe,
+	.remove = cs47l90_remove,
+};
+
+module_platform_driver(cs47l90_codec_driver);
+
+MODULE_DESCRIPTION("ASoC CS47L90 driver");
+MODULE_AUTHOR("Nikesh Oswal <nikesh@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:cs47l90-codec");
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH v4 03/10] irqchip/sunxi-nmi: add support for the NMI in A64 R_INTC
From: icenowy-h8G6r0blFSE @ 2017-04-24 16:11 UTC (permalink / raw)
  To: Thomas Gleixner, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
	Lee Jones, Liam Girdwood
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20170424160103.9447-4-icenowy-h8G6r0blFSE@public.gmane.org>

在 2017-04-25 00:00,Icenowy Zheng 写道:
> Add support for the newly imported compatible for the A64 R_INTC in
> irq-sunxi-nmi driver
> 
> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> ---
> New patch in v4, which is part of NMI refactor.
> 
>  drivers/irqchip/irq-sunxi-nmi.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-sunxi-nmi.c 
> b/drivers/irqchip/irq-sunxi-nmi.c
> index 668730c5cb66..5f7408b1cd4d 100644
> --- a/drivers/irqchip/irq-sunxi-nmi.c
> +++ b/drivers/irqchip/irq-sunxi-nmi.c
> @@ -56,6 +56,12 @@ static struct sunxi_sc_nmi_reg_offs sun9i_reg_offs = 
> {
>  	.enable	= 0x04,
>  };
> 
> +static struct sunxi_sc_nmi_reg_offs sun50i_reg_offs = {
> +	.ctrl	= 0x0c,
> +	.pend	= 0x10,
> +	.enable	= 0x40,
> +};
> +
>  static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 
> off,
>  				      u32 val)
>  {
> @@ -220,3 +226,10 @@ static int __init sun9i_nmi_irq_init(struct
> device_node *node,
>  	return sunxi_sc_nmi_irq_init(node, &sun9i_reg_offs);
>  }
>  IRQCHIP_DECLARE(sun9i_nmi, "allwinner,sun9i-a80-nmi", 
> sun9i_nmi_irq_init);
> +
> +static int __init sun50i_nmi_irq_init(struct device_node *node,
> +				     struct device_node *parent)
> +{
> +	return sunxi_sc_nmi_irq_init(node, &sun50i_reg_offs);
> +}
> +IRQCHIP_DECLARE(sun50i_nmi, "allwinner,sun50i-a80-nmi", 
> sun50i_nmi_irq_init);

Should be:
+IRQCHIP_DECLARE(sun50i_nmi, "allwinner,sun50i-a64-r-intc", 
sun50i_nmi_irq_init);

Sorry!

Thanks,
Icenowy

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* [RFC v2 1/2] dt-bindings: add mmio-based syscon mux controller DT bindings
From: Philipp Zabel @ 2017-04-24 16:12 UTC (permalink / raw)
  To: Peter Rosin
  Cc: Rob Herring, Mark Rutland, Sakari Ailus, Steve Longerbeam,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Philipp Zabel

This adds device tree binding documentation for mmio-based syscon
multiplexers controlled by a single bitfield in a syscon register
range.

Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
Changes since v1:
 - Replaced reg, bit-mask, and bit-shift properties with mux-reg-masks array
   to allow defining multiple mux bit-fields per mmio-mux instance.
 - Changed mux-control-cells value to <1>, the cell value is an index into
   the mux-reg-masks array.
 - Replaced idle-state with idle-states array.
---
 Documentation/devicetree/bindings/mux/mmio-mux.txt | 60 ++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mux/mmio-mux.txt

diff --git a/Documentation/devicetree/bindings/mux/mmio-mux.txt b/Documentation/devicetree/bindings/mux/mmio-mux.txt
new file mode 100644
index 0000000000000..99282fa761c55
--- /dev/null
+++ b/Documentation/devicetree/bindings/mux/mmio-mux.txt
@@ -0,0 +1,60 @@
+MMIO register bitfield-based multiplexer controller bindings
+
+Define register bitfields to be used to control multiplexers. The parent
+device tree node must be a syscon node to provide register access.
+
+Required properties:
+- compatible : "mmio-mux"
+- #mux-control-cells : <1>
+- mux-reg-masks : an array of register offset and pre-shifted bitfield mask
+                  pairs, each describing a single mux control.
+* Standard mux-controller bindings as decribed in mux-controller.txt
+
+Optional properties:
+- idle-states : if present, the state the muxes will have when idle. The
+		special state MUX_IDLE_AS_IS is the default.
+
+The multiplexer state is defined as the value of the bitfield described
+by the reg, bit-mask, and bit-shift properties, accessed through the parent
+syscon.
+
+Example:
+
+	syscon {
+		compatible = "syscon";
+
+		mux: mux-controller@3 {
+			compatible = "mmio-mux";
+			#mux-control-cells = <1>;
+
+			mux-reg-masks = <0x3 0x30>, /* 0: reg 0x3, bits 5:4 */
+					<0x3 0x40>, /* 1: reg 0x3, bit 6 */
+			idle-states = <MUX_IDLE_AS_IS>, <0>;
+		};
+	};
+
+	video-mux {
+		compatible = "video-mux";
+		mux-controls = <&mux 0>;
+
+		ports {
+			/* inputs 0..3 */
+			port@0 {
+				reg = <0>;
+			};
+			port@1 {
+				reg = <1>;
+			};
+			port@2 {
+				reg = <2>;
+			};
+			port@3 {
+				reg = <3>;
+			};
+
+			/* output */
+			port@4 {
+				reg = <4>;
+			};
+		};
+	};
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [RFC v2 2/2] mux: mmio-based syscon mux controller
From: Philipp Zabel @ 2017-04-24 16:12 UTC (permalink / raw)
  To: Peter Rosin
  Cc: Rob Herring, Mark Rutland, Sakari Ailus, Steve Longerbeam,
	devicetree, linux-kernel, kernel, Philipp Zabel
In-Reply-To: <1493050349-25533-1-git-send-email-p.zabel@pengutronix.de>

This adds a driver for mmio-based syscon multiplexers controlled by a
single bitfield in a syscon register range.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
Changes since v1:
 - Renamed MUX_SYSCON to MUX_MMIO. Instead of obtaining the regmap via syscon,
   this could just as well map its own MMIO register range if a reg property
   was added.
 - Replaced reg, bit-mask, and bit-shift properties with mux-reg-masks array
   to allow defining multiple mux bit-fields per mmio-mux instance.
 - Changed mux-control-cells value to <1>, the cell value is an index into
   the mux-reg-masks array.
 - Replaced idle-state with idle-states array.
 - Stopped clobbering mux->cached_state, that is internal to the mux core.
---
 drivers/mux/Kconfig    |  13 ++++
 drivers/mux/Makefile   |   1 +
 drivers/mux/mux-mmio.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 176 insertions(+)
 create mode 100644 drivers/mux/mux-mmio.c

diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
index 34b8284d6d29e..e2bee25a1586e 100644
--- a/drivers/mux/Kconfig
+++ b/drivers/mux/Kconfig
@@ -43,4 +43,17 @@ config MUX_GPIO
 	  To compile the driver as a module, choose M here: the module will
 	  be called mux-gpio.
 
+config MUX_MMIO
+	tristate "MMIO register bitfield-controlled Multiplexer"
+	depends on OF && MFD_SYSCON
+	help
+	  MMIO register bitfield-controlled Multiplexer controller.
+
+	  The driver builds a single multiplexer controller using a bitfield
+	  in a syscon register. For N bit wide bitfields, there will be 2^N
+	  possible multiplexer states.
+
+	  To compile the driver as a module, choose M here: the module will
+	  be called mux-mmio.
+
 endif
diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile
index b00a7d37d2fbe..6bac5b0fea137 100644
--- a/drivers/mux/Makefile
+++ b/drivers/mux/Makefile
@@ -5,3 +5,4 @@
 obj-$(CONFIG_MULTIPLEXER)	+= mux-core.o
 obj-$(CONFIG_MUX_ADG792A)	+= mux-adg792a.o
 obj-$(CONFIG_MUX_GPIO)		+= mux-gpio.o
+obj-$(CONFIG_MUX_MMIO)		+= mux-mmio.o
diff --git a/drivers/mux/mux-mmio.c b/drivers/mux/mux-mmio.c
new file mode 100644
index 0000000000000..0b011fb59f99b
--- /dev/null
+++ b/drivers/mux/mux-mmio.c
@@ -0,0 +1,162 @@
+/*
+ * MMIO register bitfield-controlled multiplexer driver
+ *
+ * Copyright (C) 2017 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/mux/driver.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+static int mux_mmio_set(struct mux_control *mux, int state)
+{
+	struct regmap_field **fields = mux_chip_priv(mux->chip);
+	int index = mux - mux->chip->mux;
+
+	return regmap_field_write(fields[index], state);
+}
+
+static const struct mux_control_ops mux_mmio_ops = {
+	.set = mux_mmio_set,
+};
+
+static const struct of_device_id mux_mmio_dt_ids[] = {
+	{ .compatible = "mmio-mux", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mux_mmio_dt_ids);
+
+static int mux_mmio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct regmap_field **fields;
+	struct mux_chip *mux_chip;
+	struct regmap *regmap;
+	s32 *idle_states;
+	u32 *reg_masks;
+	int num_fields;
+	int ret;
+	int i;
+
+	regmap = syscon_node_to_regmap(np->parent);
+	if (IS_ERR(regmap)) {
+		ret = PTR_ERR(regmap);
+		dev_err(dev, "failed to get syscon regmap: %d\n", ret);
+		return ret;
+	}
+
+	ret = of_property_count_u32_elems(np, "mux-reg-masks");
+	if (ret == 0 || ret % 2)
+		ret = -EINVAL;
+	if (ret > 0) {
+		num_fields = ret / 2;
+
+		reg_masks = devm_kmalloc(dev, ret * sizeof(u32), GFP_KERNEL);
+		if (!reg_masks)
+			return -ENOMEM;
+
+		ret = of_property_read_u32_array(np, "mux-reg-masks",
+						 reg_masks, ret);
+	}
+	if (ret < 0) {
+		dev_err(dev, "mux-reg-masks property missing or invalid: %d\n",
+			ret);
+		return ret;
+	}
+
+	mux_chip = devm_mux_chip_alloc(dev, num_fields, num_fields *
+				       sizeof(*fields));
+	if (IS_ERR(mux_chip))
+		return PTR_ERR(mux_chip);
+
+	fields = mux_chip_priv(mux_chip);
+
+	for (i = 0; i < num_fields; i++) {
+		struct mux_control *mux = &mux_chip->mux[i];
+		struct reg_field field;
+		u32 *reg_mask = reg_masks + 2 * i;
+		int bits;
+
+		field.reg = reg_mask[0];
+		field.msb = fls(reg_mask[1]) - 1;
+		field.lsb = ffs(reg_mask[1]) - 1;
+		bits = 1 + field.msb - field.lsb;
+
+		fields[i] = devm_regmap_field_alloc(&pdev->dev, regmap, field);
+		if (IS_ERR(fields[i])) {
+			ret = PTR_ERR(fields[i]);
+			dev_err(&pdev->dev, "failed to get bit-field %d: %d\n",
+				i, ret);
+			return ret;
+		}
+
+		mux->states = 1 << bits;
+	}
+
+	devm_kfree(dev, reg_masks);
+
+	if (of_find_property(np, "idle-states", NULL)) {
+		ret = of_property_count_u32_elems(np, "idle-states");
+		if (ret == num_fields) {
+			idle_states = devm_kmalloc(dev, ret * sizeof(s32),
+						   GFP_KERNEL);
+			if (!idle_states)
+				return -ENOMEM;
+
+			ret = of_property_read_u32_array(np, "idle-states",
+							 idle_states, ret);
+		} else {
+			idle_states = NULL;
+			if (ret >= 0)
+				ret = -EINVAL;
+		}
+		if (ret < 0) {
+			dev_err(dev, "idle-states property invalid: %d\n", ret);
+			return ret;
+		}
+
+		for (i = 0; i < num_fields; i++) {
+			struct mux_control *mux = &mux_chip->mux[i];
+
+			if (idle_states[i] != MUX_IDLE_AS_IS) {
+				if (idle_states[i] < 0 ||
+				    idle_states[i] >= mux->states) {
+					dev_err(dev, "invalid idle-state %u\n",
+						idle_states[i]);
+					return -EINVAL;
+				}
+
+				mux->idle_state = idle_states[i];
+			}
+		}
+
+		devm_kfree(dev, idle_states);
+	}
+
+	mux_chip->ops = &mux_mmio_ops;
+
+	return devm_mux_chip_register(dev, mux_chip);
+}
+
+static struct platform_driver mux_mmio_driver = {
+	.driver = {
+		.name = "mmio-mux",
+		.of_match_table	= of_match_ptr(mux_mmio_dt_ids),
+	},
+	.probe = mux_mmio_probe,
+};
+module_platform_driver(mux_mmio_driver);
+
+MODULE_DESCRIPTION("MMIO register bitfield-controlled multiplexer driver");
+MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
-- 
2.11.0

^ permalink raw reply related

* Re: [PATCH 2/2] mmc: dw_mmc-rockchip: parse rockchip,default-num-phases from DT
From: Doug Anderson @ 2017-04-24 16:18 UTC (permalink / raw)
  To: Shawn Lin
  Cc: Jaehoon Chung, Ulf Hansson, Rob Herring,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Ziyuan Xu,
	open list:ARM/Rockchip SoC...,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <58609a89-3413-3383-4bd5-271868500f7d-TNX95d0MmH7DzftRWevZcw@public.gmane.org>

Hi,

On Wed, Apr 19, 2017 at 6:21 PM, Shawn Lin <shawn.lin-TNX95d0MmH7DzftRWevZcw@public.gmane.org> wrote:
> Hi Doug,
>
> 在 2017/4/20 4:19, Doug Anderson 写道:
>>
>> Hi,
>>
>> On Wed, Apr 19, 2017 at 2:00 AM, Shawn Lin <shawn.lin-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
>> wrote:
>>>
>>> Currently we unconditionally do tuning for each degree, which
>>> costs 900ms for each boot and resume.
>>>
>>> May someone argue that this is a question of accuracy VS time. But I
>>> would say it's a trick of how we need to do decision for our boards.
>>> If we don't care the time we spend at all, we could definitely do tuning
>>> for each degree. But when we need to improve the user experience, for
>>> instance, speed up resuming from S3, we should also have the right to
>>> do that. This patch add parsing "rockchip,default-num-phases", for folks
>>> to specify the number of doing tuning. If not specified, 360 will be used
>>> as before.
>>>
>>> Signed-off-by: Shawn Lin <shawn.lin-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
>>>
>>> ---
>>>
>>>  drivers/mmc/host/dw_mmc-rockchip.c | 48
>>> ++++++++++++++++++++++++--------------
>>>  1 file changed, 30 insertions(+), 18 deletions(-)
>>
>>
>> No huge objection here, but I do remember we ended up at the 360
>> phases due to some of the craziness with dw_mmc delay elements on
>> rk3288.  IIRC one of the big problems was that the delay elements
>> changed _a lot_ with the "LOGIC" voltage and we tweaked the voltage at
>> runtime for DDR DVFS.  That imposed an extra need to be very accurate
>> on that SoC, at least on any board that was designed to support DDR
>> DVFS.
>>
>
> Not just with the vdd_logic but also with the process of Soc.
> To better guaratee the accuracy, firstly we use delay element to do
> tuning and then convert it to be combination of degree + delay element.
> But as the dalay elements aren't accuracy themself, so all the math we
> do here is trick.

Yup.  I brought up the vdd logic specifically because it's something
that can make the phases change quite dramatically on the same machine
between the time you tuned and the time you used it.


>> I also remember there being some weirdness on the Rockchip
>> implementation where there was a certain set of phases that the MMC
>> controller was essentially "blind".  This blind spot was in the middle
>> of an otherwise good range of points.  Unfortunately this blind spot
>> was somewhat hard to detect properly because it was not very big.
>> ...the variability of the delay elements meant that there could be big
>> ranges where we weren't getting any good test coverage, but also the
>> fact that they changed with the LOGIC voltage might mean that we
>> weren't in the "blind" spot and then suddenly we were.
>
>
> I undertand all of these as I was suffering from it when bringing up
> RK3288.
>
>>
>> One other note is that i remember that the vast majority of time spent
>> tuning was dealing with "bad" phases, not dealing with "good" phases.
>> If you're looking to speed things up, maybe finding a way to make
>> "bad" phases fail faster would be wise?  I think one of the reasons
>> bad phases failed so slowly is because the dw_mmc timeouts are all so
>> long.
>
>
> Good point. I haven't thought of speeding up the handle of bad phases,
> but I will take a look at this.
>
>>
>> Oh, and I guess one last note is that I have no idea if folks will
>> like the device bindings here.  Part of me thinks it should be
>> something more "symbolic" like "rockchip,need-accurate-tuning" or
>> something like that.  I guess I'd let the DT experts chime in.
>>
>>
>> So I guess to summarize:
>> * On rk3288 boards w/ DDR DVFS (or any other similar boards), 360
>> seems to provide real benefit.
>> * On other boards, probably you can get by with fewer phases.
>>
>
> I would try to say it's a question of "900ms for a single time" VS.
> "some of discrete tuning cost for more chance to do retune".
>
> (1)We could try to do a more accurate tuning process and spends 900ms.
> Then we have less chance to do retune later.
>
> (2)We do a rough tuning and have more chance to do retune later.

Ah, interesting point.  I haven't used newer versions of Linux much,
but I seem to remember that they will automatically retune sometimes
if they see errors.  That makes your strategy a bit more valid.


> I also would say that this is a game , and we can't say which
> one is better. Obvious now the "900ms" alwyas happens in the spot
> routine, for instance, booting and resuming from S3.

Is it really 900 ms?  I don't quite remember it being that long, but I
could be remembering incorrectly.

-Doug
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 1/2] gpio: move tca9554 from pcf857x to pca953x
From: Linus Walleij @ 2017-04-24 16:28 UTC (permalink / raw)
  To: Anders Darander
  Cc: Alexandre Courbot, Rob Herring,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Mark Rutland
In-Reply-To: <20170421124631.19269-1-anders-7UjN0b3lYz2SbKU13Z4Etw@public.gmane.org>

On Fri, Apr 21, 2017 at 2:46 PM, Anders Darander <anders-7UjN0b3lYz2SbKU13Z4Etw@public.gmane.org> wrote:

> The TCA9554 doesn't work with the pcf857x driver, trying to change the direction
> gives a NAK bailout error.
>
> TCA9554 is similar to the PCA9554, thus change the driver.
>
> Signed-off-by: Anders Darander <anders-7UjN0b3lYz2SbKU13Z4Etw@public.gmane.org>

Patch applied.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 2/2] gpio: DT bindings, move tca9554 from pcf857x to pca953x
From: Linus Walleij @ 2017-04-24 16:31 UTC (permalink / raw)
  To: Anders Darander
  Cc: Alexandre Courbot, Rob Herring, linux-gpio@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	Mark Rutland
In-Reply-To: <20170421124631.19269-2-anders@chargestorm.se>

On Fri, Apr 21, 2017 at 2:46 PM, Anders Darander <anders@chargestorm.se> wrote:

> The TCA9554 is similar to the PCA9554. Update the DT binding docs.
>
> Signed-off-by: Anders Darander <anders@chargestorm.se>

Patch applied. Seems like this component was misqualified at some point,
let's repair it.

yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH] ARM: at91/at91-pinctrl documentation: fix spelling mistake: "contoller" -> "controller"
From: Linus Walleij @ 2017-04-24 16:33 UTC (permalink / raw)
  To: Colin King
  Cc: Rob Herring, Mark Rutland, linux-gpio@vger.kernel.org,
	devicetree@vger.kernel.org, kernel-janitors,
	linux-kernel@vger.kernel.org
In-Reply-To: <20170421120713.4939-1-colin.king@canonical.com>

On Fri, Apr 21, 2017 at 2:07 PM, Colin King <colin.king@canonical.com> wrote:

> From: Colin Ian King <colin.king@canonical.com>
>
> trivial fix to spelling mistake in documentation
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Patch applied with Nico's ACK.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH 1/4] pinctrl: stm32: set pin to gpio input when used as interrupt
From: Alexandre Torgue @ 2017-04-24 16:40 UTC (permalink / raw)
  To: Linus Walleij
  Cc: devicetree@vger.kernel.org, linux-gpio@vger.kernel.org,
	Patrice Chotard, linux-kernel@vger.kernel.org, Paul Gortmaker,
	Rob Herring, Maxime Coquelin,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <CACRpkdYZixkJroS-gQxYL6xW47-J9UiNv4hOO9F-1b2eYLr8XQ@mail.gmail.com>

Hi Linus,

On 04/24/2017 02:36 PM, Linus Walleij wrote:
> On Fri, Apr 7, 2017 at 5:10 PM, Alexandre TORGUE
> <alexandre.torgue@st.com> wrote:
>
>> This patch ensures that pin is correctly set as gpio input when it is used
>> as an interrupt.
>>
>> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
> (...)
>
>> +static int stm32_gpio_irq_request_resources(struct irq_data *irq_data)
>> +{
>> +       struct stm32_gpio_bank *bank = irq_data->domain->host_data;
>> +       u32 ret;
>> +
>> +       if (!gpiochip_is_requested(&bank->gpio_chip, irq_data->hwirq)) {
>> +               ret = stm32_gpio_request(&bank->gpio_chip, irq_data->hwirq);
>> +               if (ret)
>> +                       return ret;
>> +       }
>
> This is wrong. You should only use gpiochip_lock_as_irq(), because of the
> following in Documentation/gpio/driver.txt:
>
> ---------------
> It is legal for any IRQ consumer to request an IRQ from any irqchip no matter
> if that is a combined GPIO+IRQ driver. The basic premise is that gpio_chip and
> irq_chip are orthogonal, and offering their services independent of each
> other.
> (...)
> So always prepare the hardware and make it ready for action in respective
> callbacks from the GPIO and irqchip APIs. Do not rely on gpiod_to_irq() having
> been called first.

Ok, so actually the action to set pin in input mode is necessary in 
stm32_gpio_irq_request_resources.

I'll fix it in V2.


>
> This orthogonality leads to ambiguities that we need to solve: if there is
> competition inside the subsystem which side is using the resource (a certain
> GPIO line and register for example) it needs to deny certain operations and
> keep track of usage inside of the gpiolib subsystem. This is why the API
> below exists.
>
> Locking IRQ usage
> -----------------
> Input GPIOs can be used as IRQ signals. When this happens, a driver is requested
> to mark the GPIO as being used as an IRQ:
>
>         int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
>
> This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
> is released:
>
>         void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset)
>
> When implementing an irqchip inside a GPIO driver, these two functions should
> typically be called in the .startup() and .shutdown() callbacks from the
> irqchip.
>
> When using the gpiolib irqchip helpers, these callback are automatically
> assigned.
> --------------
>
> It is because of easy to make errors like this that I prefer that people try
> to use GPIOLIB_IRQCHIP helpers insteaf of rolling their own irqchip code.

I understand. It was difficult in our case due to design.

Thanks for review.
Alex

>
> Yours,
> Linus Walleij
>

^ permalink raw reply

* Re: [PATCH 1/5 v3] usb: host: add DT bindings for faraday fotg2
From: Hans Ulli Kroll @ 2017-04-24 16:53 UTC (permalink / raw)
  To: Linus Walleij
  Cc: openwrt-devel, devicetree, Paulius Zaleckas, Greg Kroah-Hartman,
	linux-usb, Janos Laube, linux-arm-kernel
In-Reply-To: <20170421204058.6206-1-linus.walleij@linaro.org>

Hi Linus

On Fri, 21 Apr 2017, Linus Walleij wrote:

> From: Hans Ulli Kroll <ulli.kroll@googlemail.com>
> 
> This adds device tree bindings for the Faraday FOTG2
> dual-mode host controller.
> 
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Hans Ulli Kroll <ulli.kroll@googlemail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v1->v3:
> - Change compatible to "faraday,fotg210" as the name of the
>   hardware block.
> - Add an elaborate SoC-specific compatible string for the
>   Cortina Systems Gemini so that SoC-specific features can
>   be enabled.
> - Add cortina,gemini-mini-b to indicate a Gemini PHY with
>   a Mini-B adapter connected.
> - Indicated that the Gemini version can handle "wakeup-source".
> - Add optional IP block clock.
> ---
>  .../devicetree/bindings/usb/faraday,fotg210.txt    | 35 ++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/faraday,fotg210.txt
> 

Got NAK'ed from Rob on some ealier round due missing "device mode" on this 
IP. I've blatantly overrided this to a host only driver.

These are the needed changes in DT to support both modes
Note the -dr at the end of fotg210, to reflect this in an dual role device

diff --git a/Documentation/devicetree/bindings/usb/faraday,fotg210.txt 
b/Documentation/devicetree/bindings/usb/faraday,fotg210.txt
index cf06808303e2..862cda19e9d3 100644
--- a/Documentation/devicetree/bindings/usb/faraday,fotg210.txt
+++ b/Documentation/devicetree/bindings/usb/faraday,fotg210.txt
@@ -13,6 +13,9 @@ Required properties:
 Optional properties:
 - clocks: should contain the IP block clock
 - clock-names: should be "PCLK" for the IP block clock
+- dr_mode : indicates the working mode for "fotg210-dr" compatible
+   controllers.  Can be "host", "peripheral". Default to
+   "host" if not defined for backward compatibility.
 
 Required properties for "cortina,gemini-usb" compatible:
 - syscon: a phandle to the system controller to access PHY registers
@@ -25,7 +28,7 @@ Optional properties for "cortina,gemini-usb" compatible:
 Example for Gemini:
 
 usb@68000000 {
-       compatible = "cortina,gemini-usb", "faraday,fotg210";
+       compatible = "cortina,gemini-usb", "faraday,fotg210-dr";
        reg = <0x68000000 0x1000>;
        interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&cc 12>;
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

^ permalink raw reply related

* Re: [PATCH 1/3] of: overlay_adjust_phandles() - do not modify const field
From: Rob Herring @ 2017-04-24 16:56 UTC (permalink / raw)
  To: Frank Rowand
  Cc: Stephen Boyd, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1493011204-27635-2-git-send-email-frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Mon, Apr 24, 2017 at 12:20 AM,  <frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
>
> When adjusting overlay phandles to apply to the live device tree, can
> not modify the property value because it is type const.
>
> This is to resolve the issue found by Stephen Boyd [1] when he changed
> the type of struct property.value from void * to const void *.  As
> a result of the type change, the overlay code had compile errors
> where the resolver updates phandle values.

Conceptually, I prefer your first version. phandles are special and
there's little reason to expose them except to generate a dts or dtb
from /proc/device-tree. We could still generate the phandle file in
that case, but I don't know if special casing phandle is worth it.

>
>   [1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html
>
> Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
> ---
>  drivers/of/base.c       |  4 ++--
>  drivers/of/dynamic.c    | 28 +++++++++++++++++++++------
>  drivers/of/of_private.h |  3 +++
>  drivers/of/resolver.c   | 51 ++++++++++++++++++++++++++++++-------------------
>  4 files changed, 58 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index d7c4629a3a2d..b41650fd0fcf 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -220,8 +220,8 @@ void __init of_core_init(void)
>                 proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
>  }
>
> -static struct property *__of_find_property(const struct device_node *np,
> -                                          const char *name, int *lenp)
> +struct property *__of_find_property(const struct device_node *np,
> +                                   const char *name, int *lenp)
>  {
>         struct property *pp;
>
> diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
> index 888fdbc09992..44963b4e7235 100644
> --- a/drivers/of/dynamic.c
> +++ b/drivers/of/dynamic.c
> @@ -354,17 +354,17 @@ void of_node_release(struct kobject *kobj)
>  }
>
>  /**
> - * __of_prop_dup - Copy a property dynamically.
> + * __of_prop_alloc - Create a property dynamically.
>   * @prop:      Property to copy
>   * @allocflags:        Allocation flags (typically pass GFP_KERNEL)
>   *
> - * Copy a property by dynamically allocating the memory of both the
> + * Create a property by dynamically allocating the memory of both the
>   * property structure and the property name & contents. The property's
>   * flags have the OF_DYNAMIC bit set so that we can differentiate between
>   * dynamically allocated properties and not.
>   * Returns the newly allocated property or NULL on out of memory error.
>   */
> -struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
> +struct property *__of_prop_alloc(char *name, void *value, int len, gfp_t allocflags)
>  {
>         struct property *new;
>
> @@ -378,9 +378,9 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
>          * of zero bytes. We do this to work around the use
>          * of of_get_property() calls on boolean values.
>          */
> -       new->name = kstrdup(prop->name, allocflags);
> -       new->value = kmemdup(prop->value, prop->length, allocflags);
> -       new->length = prop->length;
> +       new->name = kstrdup(name, allocflags);
> +       new->value = kmemdup(value, len, allocflags);
> +       new->length = len;
>         if (!new->name || !new->value)
>                 goto err_free;
>
> @@ -397,6 +397,22 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
>  }
>
>  /**
> + * __of_prop_dup - Copy a property dynamically.
> + * @prop:      Property to copy
> + * @allocflags:        Allocation flags (typically pass GFP_KERNEL)
> + *
> + * Copy a property by dynamically allocating the memory of both the
> + * property structure and the property name & contents. The property's
> + * flags have the OF_DYNAMIC bit set so that we can differentiate between
> + * dynamically allocated properties and not.
> + * Returns the newly allocated property or NULL on out of memory error.
> + */
> +struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
> +{
> +       return __of_prop_alloc(prop->name, prop->value, prop->length, allocflags);
> +}
> +
> +/**
>   * __of_node_dup() - Duplicate or create an empty device node dynamically.
>   * @fmt: Format string (plus vargs) for new full name of the device node
>   *
> diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
> index 18bbb4517e25..554394c96569 100644
> --- a/drivers/of/of_private.h
> +++ b/drivers/of/of_private.h
> @@ -62,6 +62,7 @@ static inline int of_property_notify(int action, struct device_node *np,
>   * without taking node references, so you either have to
>   * own the devtree lock or work on detached trees only.
>   */
> +struct property *__of_prop_alloc(char *name, void *value, int len, gfp_t allocflags);
>  struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags);
>  __printf(2, 3) struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...);
>
> @@ -70,6 +71,8 @@ extern const void *__of_get_property(const struct device_node *np,
>  extern int __of_add_property(struct device_node *np, struct property *prop);
>  extern int __of_add_property_sysfs(struct device_node *np,
>                 struct property *prop);
> +extern struct property *__of_find_property(const struct device_node *np,
> +                                          const char *name, int *lenp);
>  extern int __of_remove_property(struct device_node *np, struct property *prop);
>  extern void __of_remove_property_sysfs(struct device_node *np,
>                 struct property *prop);
> diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
> index 7ae9863cb0a4..a2d5b8f0b7bf 100644
> --- a/drivers/of/resolver.c
> +++ b/drivers/of/resolver.c
> @@ -20,6 +20,8 @@
>  #include <linux/errno.h>
>  #include <linux/slab.h>
>
> +#include "of_private.h"
> +
>  /* illegal phandle value (set when unresolved) */
>  #define OF_PHANDLE_ILLEGAL     0xdeadbeef
>
> @@ -67,36 +69,43 @@ static phandle live_tree_max_phandle(void)
>         return phandle;
>  }
>
> -static void adjust_overlay_phandles(struct device_node *overlay,
> +static int adjust_overlay_phandles(struct device_node *overlay,
>                 int phandle_delta)
>  {
>         struct device_node *child;
> +       struct property *newprop;
>         struct property *prop;
>         phandle phandle;

Some of these can move into the if statement. That will save some
stack space on recursion (or maybe the compiler is smart enough).

> +       int ret;
>
> -       /* adjust node's phandle in node */
> -       if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
> -               overlay->phandle += phandle_delta;
> -
> -       /* copy adjusted phandle into *phandle properties */
> -       for_each_property_of_node(overlay, prop) {
> +       if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL) {
>
> -               if (of_prop_cmp(prop->name, "phandle") &&
> -                   of_prop_cmp(prop->name, "linux,phandle"))
> -                       continue;
> -
> -               if (prop->length < 4)
> -                       continue;
> +               overlay->phandle += phandle_delta;
>
> -               phandle = be32_to_cpup(prop->value);
> -               if (phandle == OF_PHANDLE_ILLEGAL)
> -                       continue;
> +               phandle = cpu_to_be32(overlay->phandle);
> +
> +               prop = __of_find_property(overlay, "phandle", NULL);
> +               newprop = __of_prop_alloc(prop->name, &phandle, sizeof(phandle),
> +                                         GFP_KERNEL);
> +               if (!newprop)
> +                       return -ENOMEM;
> +               __of_update_property(overlay, newprop, &prop);
> +
> +               prop = __of_find_property(overlay, "linux,phandle", NULL);
> +               newprop = __of_prop_alloc(prop->name, &phandle, sizeof(phandle),
> +                                         GFP_KERNEL);

There is no reason to support "linux,phandle" for overlays. That is
legacy (pre ePAPR) which predates any overlays by a long time.

Also, dtc still defaults to generating both phandle and linux,phandle
properties which maybe we should switch off now. If anything, we're
wasting a bit of memory storing both. I think we should only store
"phandle" and convert any cases of only a "linux,phandle" property to
"phandle".

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 2/2] dmaengine: Add DW AXI DMAC driver
From: Andy Shevchenko @ 2017-04-24 16:56 UTC (permalink / raw)
  To: Eugeniy Paltsev
  Cc: vinod.koul@intel.com, linux-kernel@vger.kernel.org,
	robh+dt@kernel.org, Alexey.Brodkin@synopsys.com,
	devicetree@vger.kernel.org, linux-snps-arc@lists.infradead.org,
	dan.j.williams@intel.com, dmaengine@vger.kernel.org
In-Reply-To: <1493049305.25985.4.camel@synopsys.com>

On Mon, 2017-04-24 at 15:55 +0000, Eugeniy Paltsev wrote:
> Hi,
> On Fri, 2017-04-21 at 18:13 +0300, Andy Shevchenko wrote:
> > On Fri, 2017-04-21 at 14:29 +0000, Eugeniy Paltsev wrote:
> > > On Tue, 2017-04-18 at 15:31 +0300, Andy Shevchenko wrote:
> > > > On Fri, 2017-04-07 at 17:04 +0300, Eugeniy Paltsev wrote:
> > > > > This patch adds support for the DW AXI DMAC controller.
> > > > > +#define AXI_DMA_BUSWIDTHS		  \
> > > > > +	(DMA_SLAVE_BUSWIDTH_1_BYTE	| \
> > > > > +	DMA_SLAVE_BUSWIDTH_2_BYTES	| \
> > > > > +	DMA_SLAVE_BUSWIDTH_4_BYTES	| \
> > > > > +	DMA_SLAVE_BUSWIDTH_8_BYTES	| \
> > > > > +	DMA_SLAVE_BUSWIDTH_16_BYTES	| \
> > > > > +	DMA_SLAVE_BUSWIDTH_32_BYTES	| \
> > > > > +	DMA_SLAVE_BUSWIDTH_64_BYTES)
> > > > > +/* TODO: check: do we need to use BIT() macro here? */
> > > > 
> > > > Still TODO? I remember I answered to this on the first round.
> > > 
> > > Yes, I remember it.
> > > I left this TODO as a reminder because src_addr_widths and
> > > dst_addr_widths are
> > > not used anywhere and they are set differently in different
> > > drivers
> > > (with or without BIT macro).
> > 
> > Strange. AFAIK they are representing bits (which is not the best
> > idea) in the resulting u64 field. So, anything bigger than 63
> > doesn't
> >  make sense.
> 
> They are u32 fields!

Even "better"!

> From dmaengine.h :
> struct dma_device {
> ...
>     u32 src_addr_widths;
>     u32 dst_addr_widths;
> };
> 
> > In drivers where they are not bits quite likely a bug is hidden.
> 
> For example (from pxa_dma.c):
> const enum dma_slave_buswidth widths = DMA_SLAVE_BUSWIDTH_1_BYTE |
> DMA_SLAVE_BUSWIDTH_2_BYTES | DMA_SLAVE_BUSWIDTH_4_BYTES;
> 
> And there are a lot of drivers, which don't use BIT for this fields.
> sh/shdmac.c
> sh/rcar-dmac.c
> qcom/bam_dma.c
> mmp_pdma.c
> ste_dma40.c
> And many others...

Definitely the concept of that interface never thought enough and broken
by design.

> > > > > +static inline void
> > > > > +axi_dma_iowrite32(struct axi_dma_chip *chip, u32 reg, u32
> > > > > val)
> > > > > +{
> > > > > +	iowrite32(val, chip->regs + reg);
> > > > 
> > > > Are you going to use IO ports for this IP? I don't think so.
> > > > Wouldn't be better to call readl()/writel() instead?
> > > 
> > > As I understand, it's better to use ioread/iowrite as more
> > > universal
> > > IO
> > > access way. Am I wrong?
> > 
> > As I said above the ioreadX/iowriteX makes only sense when your IP
> > would be accessed via IO region or MMIO. I'm pretty sure IO is not
> > the case at all for this IP.
> 
> MMIO? This IP works exactly via memory-mapped I/O.

Yes, and why do you need to check this on each IO read/write?
Please, switch to plain readX()/writeX() instead.

> > > > > +		val = axi_chan_ioread32(chan,
> > > > > CH_INTSTATUS_ENA);
> > > > > +		val &= ~irq_mask;
> > > > > +		axi_chan_iowrite32(chan, CH_INTSTATUS_ENA,
> > > > > val);
> > > > > +	}
> > > > > +
> > > > > +	return min_t(size_t, __ffs(sdl), max_width);
> > > > > +}
> > > > > +static void axi_desc_put(struct axi_dma_desc *desc)
> > > > > +{
> > > > > +	struct axi_dma_chan *chan = desc->chan;
> > > > > +	struct dw_axi_dma *dw = chan->chip->dw;
> > > > > +	struct axi_dma_desc *child, *_next;
> > > > > +	unsigned int descs_put = 0;
> > > > > +	list_for_each_entry_safe(child, _next, &desc-
> > > > > > xfer_list,
> > > > > 
> > > > > xfer_list) {
> > > > 
> > > > xfer_list looks redundant.
> > > > Can you elaborate why virtual channel management is not working
> > > > for
> > > > you?
> > > 
> > > Each virtual descriptor encapsulates several hardware descriptors,
> > > which belong to same transfer.
> > > This list (xfer_list) is used only for allocating/freeing these
> > > descriptors and it doesn't affect on virtual dma work logic.
> > > I can see this approach in several drivers with VirtDMA (but they
> > > mostly use array instead of list)
> > 
> > You described how most of the DMA drivers are implemented, though
> > they
> > are using just sg_list directly. I would recommend to do the same
> > and
> > get rid of this list.
> 
> This IP can be (ans is) configured with small block size.
> (note, that I am not saying about runtime HW configuration)
> 
> And there is opportunity what we can't use sg_list directly and need
> to
> split sg_list to a smaller chunks.

That's what I have referred quite ago. The driver should provide an
interface to tell potential caller what maximum block (number of items
with given bus width) it supports.

We have struct dma_parms in struct device, but what we actually need is
to support similar on per channel basis in DMAengine framework.

So, instead of working around this I recommend either to implement it
properly or rely on the fact that in the future someone eventually does
that for you.

Each driver which has this re-splitting mechanism should be cleaned up
and refactored.

> > > > Btw, are you planning to use priority at all? For now on I
> > > > didn't
> > > > see
> > > > a single driver (from the set I have checked, like 4-5 of them)
> > > > that
> > > > uses priority anyhow. It makes driver more complex for nothing.
> > > 
> > > Only for dma slave operations.
> > 
> > So, in other words you *have* an actual two or more users that
> > *need*
> > prioritization?
> 
> As I remember there was an idea to give higher priority to audio dma
> chanels.

I don't see cyclic transfers support in the driver. So, I would suggest
just drop entire prioritization for now. When it would be actual user
one may start thinking of it.

Just a rule of common sense: do not implement something which will have
no user or solve non-existing problem.

> > > > As I said earlier dw_dmac is *bad* example of the (virtual
> > > > channel
> > > > based) DMA driver.
> > > > 
> > > > I guess you may just fail the descriptor and don't pretend it
> > > > has
> > > > been processed successfully.
> > > 
> > > What do you mean by saying "fail the descriptor"?
> > > After I get error I cancel current transfer and free all
> > > descriptors
> > > from it (by calling vchan_cookie_complete).
> > > I can't store error status in descriptor structure because it will
> > > be
> > > freed by vchan_cookie_complete.
> > > I can't store error status in channel structure because it will be
> > > overwritten by next transfer.
> > 
> > Better not to pretend that it has been processed successfully. Don't
> > call callback on it and set its status to DMA_ERROR (that's why
> > descriptors in many drivers have dma_status field). When user asks
> > for
> > status (using cookie) the saved value would be returned until
> > descriptor
> > is active.
> > 
> > Do you have some other workflow in mind?
> 
> Hmm...
> Do you mean I should left error descriptors in desc_issued list
> or I should create another list (like desc_error) in my driver and
> move
> error descriptors to desc_error list?
> 
> And when exactly should I free error descriptors?

See below.

> I checked hsu/hsu.c dma driver implementation:
>   vdma descriptor is deleted from desc_issued list when transfer
>   starts. When descriptor marked as error descriptor
>   vchan_cookie_complete isn't called for this descriptor. And this
>   descriptor isn't placed in any list. So error descriptors *never*
>   will be freed.
>   I don't actually like this approach.

Descriptor is active until terminate_all() is called or new descriptor
is supplied. So, the caller has a quite time to check on it.

So, what's wrong on it by your opinion?

Of course, if you want to keep by some reason (should be stated what the
reason in comment) erred descriptors, you can do that.

> > > > > +static const struct dev_pm_ops dw_axi_dma_pm_ops = {
> > > > > +	SET_RUNTIME_PM_OPS(axi_dma_runtime_suspend,
> > > > > axi_dma_runtime_resume, NULL)
> > > > > +};
> > > > 
> > > > Have you tried to build with CONFIG_PM disabled?
> > > 
> > > Yes.
> > > 
> > > > I'm pretty sure you need __maybe_unused applied to your PM ops.
> > > 
> > > I call axi_dma_runtime_suspend / axi_dma_runtime_resume even I
> > > dont't
> > > use PM.
> > > (I call them in probe / remove function.)
> > 
> > Hmm... I didn't check your ->probe() and ->remove(). Do you mean you
> > call them explicitly by those names?
> > 
> > If so, please don't do that. Use pm_runtime_*() instead. And...
> > 
> > > So I don't need to declare them with __maybe_unused.
> > 
> > ...in that case it's possible you have them defined but not used.
> > 
> 
> From my ->probe() function:
> 
> pm_runtime_get_noresume(chip->dev);
> ret = axi_dma_runtime_resume(chip->dev);
> 
> Firstly I only incrememt counter.
> Secondly explicitly call my resume function.
> 
> I call them explicitly because I need driver to work also without
> Runtime PM. So I can't just call pm_runtime_get here instead of
> pm_runtime_get_noresume + axi_dma_runtime_resume.
> 
> Of course I can copy *all* code from axi_dma_runtime_resume
> to ->probe() function, but I don't really like this idea.

It looks like you need more time to investigate how runtime PM works
from driver point of view, but you shouldn't call your PM callbacks
directly without a really good reason (weird silicon bugs, architectural
impediments). I don't think that is the case here.

> > > > > +
> > > > > +	/* these other elements are all protected by vc.lock
> > > > > */
> > > > > +	bool				is_paused;
> > > > 
> > > > I still didn't get (already forgot) why you can't use dma_status
> > > > instead for the active descriptor?
> > > 
> > > As I said before, I checked several driver, which have status
> > > variable
> > > in their channel structure - it is used *only* for determinating
> > > is
> > > channel paused or not. So there is no much sense in replacing
> > > "is_paused" to "status" and I left "is_paused" variable untouched.
> > 
> > Not only (see above), the errored descriptor keeps that status.
> > 
> > > (I described above why we can't use status in channel structure
> > > for
> > > error handling)
> > 
> > Ah, I'm talking about descriptor.
> 
> Again - PAUSED is per-channel flag. So, even if we have status field
> in
> each descriptor, it is simpler to use one per-channel flag instead of
> plenty per-descriptor flags.

> When we pausing/resuming dma channel it is simpler to set only one
> flag
> instead of writing DMA_PAUSED to *each* descriptor status field.

What do you mean by "each"? I don't recall the driver which can handle
more than one *active* descriptor per channel. Do you?

In that case status of active descriptor == status of channel. That
trick (I also already referred to earlier) is used in some drivers.

> > I mean, who are the users of them? If it's only one module, there is
> > no need to put them in header.
> 
> Yes, only one module.
> Should I move all this definitions to axi_dma_platform.c file and rid
> of both axi_dma_platform_reg.h and axi_dma_platform.h headers?

Depends on your design.

If it would be just one C module it might make sense to use driver.c and
driver.h or just driver.c.

I see several drivers in current linux-next that are using latter and
some that are using former, and number of plain driver.c variant is
bigger.

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox