Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: WM8983: Initial driver

The WM8983 is a low power, high quality stereo CODEC
designed for portable multimedia applications. Highly flexible
analogue mixing functions enable new application features,
combining hi-fi quality audio with voice communication.

Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Dimitris Papastamos and committed by
Mark Brown
6b3860b0 47d90a03

+2238
+4
sound/soc/codecs/Kconfig
··· 87 87 select SND_SOC_WM8971 if I2C 88 88 select SND_SOC_WM8974 if I2C 89 89 select SND_SOC_WM8978 if I2C 90 + select SND_SOC_WM8983 if SND_SOC_I2C_AND_SPI 90 91 select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI 91 92 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 92 93 select SND_SOC_WM8990 if I2C ··· 353 352 tristate 354 353 355 354 config SND_SOC_WM8978 355 + tristate 356 + 357 + config SND_SOC_WM8983 356 358 tristate 357 359 358 360 config SND_SOC_WM8985
+2
sound/soc/codecs/Makefile
··· 72 72 snd-soc-wm8971-objs := wm8971.o 73 73 snd-soc-wm8974-objs := wm8974.o 74 74 snd-soc-wm8978-objs := wm8978.o 75 + snd-soc-wm8983-objs := wm8983.o 75 76 snd-soc-wm8985-objs := wm8985.o 76 77 snd-soc-wm8988-objs := wm8988.o 77 78 snd-soc-wm8990-objs := wm8990.o ··· 169 168 obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 170 169 obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o 171 170 obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o 171 + obj-$(CONFIG_SND_SOC_WM8983) += snd-soc-wm8983.o 172 172 obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o 173 173 obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 174 174 obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
+1203
sound/soc/codecs/wm8983.c
··· 1 + /* 2 + * wm8983.c -- WM8983 ALSA SoC Audio driver 3 + * 4 + * Copyright 2011 Wolfson Microelectronics plc 5 + * 6 + * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/moduleparam.h> 15 + #include <linux/init.h> 16 + #include <linux/delay.h> 17 + #include <linux/pm.h> 18 + #include <linux/i2c.h> 19 + #include <linux/spi/spi.h> 20 + #include <linux/slab.h> 21 + #include <sound/core.h> 22 + #include <sound/pcm.h> 23 + #include <sound/pcm_params.h> 24 + #include <sound/soc.h> 25 + #include <sound/initval.h> 26 + #include <sound/tlv.h> 27 + 28 + #include "wm8983.h" 29 + 30 + static const u16 wm8983_reg_defs[WM8983_MAX_REGISTER + 1] = { 31 + [0x00] = 0x0000, /* R0 - Software Reset */ 32 + [0x01] = 0x0000, /* R1 - Power management 1 */ 33 + [0x02] = 0x0000, /* R2 - Power management 2 */ 34 + [0x03] = 0x0000, /* R3 - Power management 3 */ 35 + [0x04] = 0x0050, /* R4 - Audio Interface */ 36 + [0x05] = 0x0000, /* R5 - Companding control */ 37 + [0x06] = 0x0140, /* R6 - Clock Gen control */ 38 + [0x07] = 0x0000, /* R7 - Additional control */ 39 + [0x08] = 0x0000, /* R8 - GPIO Control */ 40 + [0x09] = 0x0000, /* R9 - Jack Detect Control 1 */ 41 + [0x0A] = 0x0000, /* R10 - DAC Control */ 42 + [0x0B] = 0x00FF, /* R11 - Left DAC digital Vol */ 43 + [0x0C] = 0x00FF, /* R12 - Right DAC digital vol */ 44 + [0x0D] = 0x0000, /* R13 - Jack Detect Control 2 */ 45 + [0x0E] = 0x0100, /* R14 - ADC Control */ 46 + [0x0F] = 0x00FF, /* R15 - Left ADC Digital Vol */ 47 + [0x10] = 0x00FF, /* R16 - Right ADC Digital Vol */ 48 + [0x12] = 0x012C, /* R18 - EQ1 - low shelf */ 49 + [0x13] = 0x002C, /* R19 - EQ2 - peak 1 */ 50 + [0x14] = 0x002C, /* R20 - EQ3 - peak 2 */ 51 + [0x15] = 0x002C, /* R21 - EQ4 - peak 3 */ 52 + [0x16] = 0x002C, /* R22 - EQ5 - high shelf */ 53 + [0x18] = 0x0032, /* R24 - DAC Limiter 1 */ 54 + [0x19] = 0x0000, /* R25 - DAC Limiter 2 */ 55 + [0x1B] = 0x0000, /* R27 - Notch Filter 1 */ 56 + [0x1C] = 0x0000, /* R28 - Notch Filter 2 */ 57 + [0x1D] = 0x0000, /* R29 - Notch Filter 3 */ 58 + [0x1E] = 0x0000, /* R30 - Notch Filter 4 */ 59 + [0x20] = 0x0038, /* R32 - ALC control 1 */ 60 + [0x21] = 0x000B, /* R33 - ALC control 2 */ 61 + [0x22] = 0x0032, /* R34 - ALC control 3 */ 62 + [0x23] = 0x0000, /* R35 - Noise Gate */ 63 + [0x24] = 0x0008, /* R36 - PLL N */ 64 + [0x25] = 0x000C, /* R37 - PLL K 1 */ 65 + [0x26] = 0x0093, /* R38 - PLL K 2 */ 66 + [0x27] = 0x00E9, /* R39 - PLL K 3 */ 67 + [0x29] = 0x0000, /* R41 - 3D control */ 68 + [0x2A] = 0x0000, /* R42 - OUT4 to ADC */ 69 + [0x2B] = 0x0000, /* R43 - Beep control */ 70 + [0x2C] = 0x0033, /* R44 - Input ctrl */ 71 + [0x2D] = 0x0010, /* R45 - Left INP PGA gain ctrl */ 72 + [0x2E] = 0x0010, /* R46 - Right INP PGA gain ctrl */ 73 + [0x2F] = 0x0100, /* R47 - Left ADC BOOST ctrl */ 74 + [0x30] = 0x0100, /* R48 - Right ADC BOOST ctrl */ 75 + [0x31] = 0x0002, /* R49 - Output ctrl */ 76 + [0x32] = 0x0001, /* R50 - Left mixer ctrl */ 77 + [0x33] = 0x0001, /* R51 - Right mixer ctrl */ 78 + [0x34] = 0x0039, /* R52 - LOUT1 (HP) volume ctrl */ 79 + [0x35] = 0x0039, /* R53 - ROUT1 (HP) volume ctrl */ 80 + [0x36] = 0x0039, /* R54 - LOUT2 (SPK) volume ctrl */ 81 + [0x37] = 0x0039, /* R55 - ROUT2 (SPK) volume ctrl */ 82 + [0x38] = 0x0001, /* R56 - OUT3 mixer ctrl */ 83 + [0x39] = 0x0001, /* R57 - OUT4 (MONO) mix ctrl */ 84 + [0x3D] = 0x0000 /* R61 - BIAS CTRL */ 85 + }; 86 + 87 + static const struct wm8983_reg_access { 88 + u16 read; /* Mask of readable bits */ 89 + u16 write; /* Mask of writable bits */ 90 + } wm8983_access_masks[WM8983_MAX_REGISTER + 1] = { 91 + [0x00] = { 0x0000, 0x01FF }, /* R0 - Software Reset */ 92 + [0x01] = { 0x0000, 0x01FF }, /* R1 - Power management 1 */ 93 + [0x02] = { 0x0000, 0x01FF }, /* R2 - Power management 2 */ 94 + [0x03] = { 0x0000, 0x01EF }, /* R3 - Power management 3 */ 95 + [0x04] = { 0x0000, 0x01FF }, /* R4 - Audio Interface */ 96 + [0x05] = { 0x0000, 0x003F }, /* R5 - Companding control */ 97 + [0x06] = { 0x0000, 0x01FD }, /* R6 - Clock Gen control */ 98 + [0x07] = { 0x0000, 0x000F }, /* R7 - Additional control */ 99 + [0x08] = { 0x0000, 0x003F }, /* R8 - GPIO Control */ 100 + [0x09] = { 0x0000, 0x0070 }, /* R9 - Jack Detect Control 1 */ 101 + [0x0A] = { 0x0000, 0x004F }, /* R10 - DAC Control */ 102 + [0x0B] = { 0x0000, 0x01FF }, /* R11 - Left DAC digital Vol */ 103 + [0x0C] = { 0x0000, 0x01FF }, /* R12 - Right DAC digital vol */ 104 + [0x0D] = { 0x0000, 0x00FF }, /* R13 - Jack Detect Control 2 */ 105 + [0x0E] = { 0x0000, 0x01FB }, /* R14 - ADC Control */ 106 + [0x0F] = { 0x0000, 0x01FF }, /* R15 - Left ADC Digital Vol */ 107 + [0x10] = { 0x0000, 0x01FF }, /* R16 - Right ADC Digital Vol */ 108 + [0x12] = { 0x0000, 0x017F }, /* R18 - EQ1 - low shelf */ 109 + [0x13] = { 0x0000, 0x017F }, /* R19 - EQ2 - peak 1 */ 110 + [0x14] = { 0x0000, 0x017F }, /* R20 - EQ3 - peak 2 */ 111 + [0x15] = { 0x0000, 0x017F }, /* R21 - EQ4 - peak 3 */ 112 + [0x16] = { 0x0000, 0x007F }, /* R22 - EQ5 - high shelf */ 113 + [0x18] = { 0x0000, 0x01FF }, /* R24 - DAC Limiter 1 */ 114 + [0x19] = { 0x0000, 0x007F }, /* R25 - DAC Limiter 2 */ 115 + [0x1B] = { 0x0000, 0x01FF }, /* R27 - Notch Filter 1 */ 116 + [0x1C] = { 0x0000, 0x017F }, /* R28 - Notch Filter 2 */ 117 + [0x1D] = { 0x0000, 0x017F }, /* R29 - Notch Filter 3 */ 118 + [0x1E] = { 0x0000, 0x017F }, /* R30 - Notch Filter 4 */ 119 + [0x20] = { 0x0000, 0x01BF }, /* R32 - ALC control 1 */ 120 + [0x21] = { 0x0000, 0x00FF }, /* R33 - ALC control 2 */ 121 + [0x22] = { 0x0000, 0x01FF }, /* R34 - ALC control 3 */ 122 + [0x23] = { 0x0000, 0x000F }, /* R35 - Noise Gate */ 123 + [0x24] = { 0x0000, 0x001F }, /* R36 - PLL N */ 124 + [0x25] = { 0x0000, 0x003F }, /* R37 - PLL K 1 */ 125 + [0x26] = { 0x0000, 0x01FF }, /* R38 - PLL K 2 */ 126 + [0x27] = { 0x0000, 0x01FF }, /* R39 - PLL K 3 */ 127 + [0x29] = { 0x0000, 0x000F }, /* R41 - 3D control */ 128 + [0x2A] = { 0x0000, 0x01E7 }, /* R42 - OUT4 to ADC */ 129 + [0x2B] = { 0x0000, 0x01BF }, /* R43 - Beep control */ 130 + [0x2C] = { 0x0000, 0x0177 }, /* R44 - Input ctrl */ 131 + [0x2D] = { 0x0000, 0x01FF }, /* R45 - Left INP PGA gain ctrl */ 132 + [0x2E] = { 0x0000, 0x01FF }, /* R46 - Right INP PGA gain ctrl */ 133 + [0x2F] = { 0x0000, 0x0177 }, /* R47 - Left ADC BOOST ctrl */ 134 + [0x30] = { 0x0000, 0x0177 }, /* R48 - Right ADC BOOST ctrl */ 135 + [0x31] = { 0x0000, 0x007F }, /* R49 - Output ctrl */ 136 + [0x32] = { 0x0000, 0x01FF }, /* R50 - Left mixer ctrl */ 137 + [0x33] = { 0x0000, 0x01FF }, /* R51 - Right mixer ctrl */ 138 + [0x34] = { 0x0000, 0x01FF }, /* R52 - LOUT1 (HP) volume ctrl */ 139 + [0x35] = { 0x0000, 0x01FF }, /* R53 - ROUT1 (HP) volume ctrl */ 140 + [0x36] = { 0x0000, 0x01FF }, /* R54 - LOUT2 (SPK) volume ctrl */ 141 + [0x37] = { 0x0000, 0x01FF }, /* R55 - ROUT2 (SPK) volume ctrl */ 142 + [0x38] = { 0x0000, 0x004F }, /* R56 - OUT3 mixer ctrl */ 143 + [0x39] = { 0x0000, 0x00FF }, /* R57 - OUT4 (MONO) mix ctrl */ 144 + [0x3D] = { 0x0000, 0x0100 } /* R61 - BIAS CTRL */ 145 + }; 146 + 147 + /* vol/gain update regs */ 148 + static const int vol_update_regs[] = { 149 + WM8983_LEFT_DAC_DIGITAL_VOL, 150 + WM8983_RIGHT_DAC_DIGITAL_VOL, 151 + WM8983_LEFT_ADC_DIGITAL_VOL, 152 + WM8983_RIGHT_ADC_DIGITAL_VOL, 153 + WM8983_LOUT1_HP_VOLUME_CTRL, 154 + WM8983_ROUT1_HP_VOLUME_CTRL, 155 + WM8983_LOUT2_SPK_VOLUME_CTRL, 156 + WM8983_ROUT2_SPK_VOLUME_CTRL, 157 + WM8983_LEFT_INP_PGA_GAIN_CTRL, 158 + WM8983_RIGHT_INP_PGA_GAIN_CTRL 159 + }; 160 + 161 + struct wm8983_priv { 162 + enum snd_soc_control_type control_type; 163 + u32 sysclk; 164 + u32 bclk; 165 + }; 166 + 167 + static const struct { 168 + int div; 169 + int ratio; 170 + } fs_ratios[] = { 171 + { 10, 128 }, 172 + { 15, 192 }, 173 + { 20, 256 }, 174 + { 30, 384 }, 175 + { 40, 512 }, 176 + { 60, 768 }, 177 + { 80, 1024 }, 178 + { 120, 1536 } 179 + }; 180 + 181 + static const int srates[] = { 48000, 32000, 24000, 16000, 12000, 8000 }; 182 + 183 + static const int bclk_divs[] = { 184 + 1, 2, 4, 8, 16, 32 185 + }; 186 + 187 + static int eqmode_get(struct snd_kcontrol *kcontrol, 188 + struct snd_ctl_elem_value *ucontrol); 189 + static int eqmode_put(struct snd_kcontrol *kcontrol, 190 + struct snd_ctl_elem_value *ucontrol); 191 + 192 + static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1); 193 + static const DECLARE_TLV_DB_SCALE(adc_tlv, -12700, 50, 1); 194 + static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); 195 + static const DECLARE_TLV_DB_SCALE(lim_thresh_tlv, -600, 100, 0); 196 + static const DECLARE_TLV_DB_SCALE(lim_boost_tlv, 0, 100, 0); 197 + static const DECLARE_TLV_DB_SCALE(alc_min_tlv, -1200, 600, 0); 198 + static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -675, 600, 0); 199 + static const DECLARE_TLV_DB_SCALE(alc_tar_tlv, -2250, 150, 0); 200 + static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1200, 75, 0); 201 + static const DECLARE_TLV_DB_SCALE(boost_tlv, -1200, 300, 1); 202 + static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 203 + static const DECLARE_TLV_DB_SCALE(aux_tlv, -1500, 300, 0); 204 + static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); 205 + static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); 206 + 207 + static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; 208 + static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8983_ALC_CONTROL_1, 7, 209 + alc_sel_text); 210 + 211 + static const char *alc_mode_text[] = { "ALC", "Limiter" }; 212 + static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8983_ALC_CONTROL_3, 8, 213 + alc_mode_text); 214 + 215 + static const char *filter_mode_text[] = { "Audio", "Application" }; 216 + static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8983_ADC_CONTROL, 7, 217 + filter_mode_text); 218 + 219 + static const char *eq_bw_text[] = { "Narrow", "Wide" }; 220 + static const char *eqmode_text[] = { "Capture", "Playback" }; 221 + static const SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text); 222 + 223 + static const char *eq1_cutoff_text[] = { 224 + "80Hz", "105Hz", "135Hz", "175Hz" 225 + }; 226 + static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8983_EQ1_LOW_SHELF, 5, 227 + eq1_cutoff_text); 228 + static const char *eq2_cutoff_text[] = { 229 + "230Hz", "300Hz", "385Hz", "500Hz" 230 + }; 231 + static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8983_EQ2_PEAK_1, 8, eq_bw_text); 232 + static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8983_EQ2_PEAK_1, 5, 233 + eq2_cutoff_text); 234 + static const char *eq3_cutoff_text[] = { 235 + "650Hz", "850Hz", "1.1kHz", "1.4kHz" 236 + }; 237 + static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8983_EQ3_PEAK_2, 8, eq_bw_text); 238 + static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8983_EQ3_PEAK_2, 5, 239 + eq3_cutoff_text); 240 + static const char *eq4_cutoff_text[] = { 241 + "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" 242 + }; 243 + static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8983_EQ4_PEAK_3, 8, eq_bw_text); 244 + static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8983_EQ4_PEAK_3, 5, 245 + eq4_cutoff_text); 246 + static const char *eq5_cutoff_text[] = { 247 + "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" 248 + }; 249 + static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5, 250 + eq5_cutoff_text); 251 + 252 + static const char *speaker_mode_text[] = { "Class A/B", "Class D" }; 253 + static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text); 254 + 255 + static const char *depth_3d_text[] = { 256 + "Off", 257 + "6.67%", 258 + "13.3%", 259 + "20%", 260 + "26.7%", 261 + "33.3%", 262 + "40%", 263 + "46.6%", 264 + "53.3%", 265 + "60%", 266 + "66.7%", 267 + "73.3%", 268 + "80%", 269 + "86.7%", 270 + "93.3%", 271 + "100%" 272 + }; 273 + static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8983_3D_CONTROL, 0, 274 + depth_3d_text); 275 + 276 + static const struct snd_kcontrol_new wm8983_snd_controls[] = { 277 + SOC_SINGLE("Digital Loopback Switch", WM8983_COMPANDING_CONTROL, 278 + 0, 1, 0), 279 + 280 + SOC_ENUM("ALC Capture Function", alc_sel), 281 + SOC_SINGLE_TLV("ALC Capture Max Volume", WM8983_ALC_CONTROL_1, 282 + 3, 7, 0, alc_max_tlv), 283 + SOC_SINGLE_TLV("ALC Capture Min Volume", WM8983_ALC_CONTROL_1, 284 + 0, 7, 0, alc_min_tlv), 285 + SOC_SINGLE_TLV("ALC Capture Target Volume", WM8983_ALC_CONTROL_2, 286 + 0, 15, 0, alc_tar_tlv), 287 + SOC_SINGLE("ALC Capture Attack", WM8983_ALC_CONTROL_3, 0, 10, 0), 288 + SOC_SINGLE("ALC Capture Hold", WM8983_ALC_CONTROL_2, 4, 10, 0), 289 + SOC_SINGLE("ALC Capture Decay", WM8983_ALC_CONTROL_3, 4, 10, 0), 290 + SOC_ENUM("ALC Mode", alc_mode), 291 + SOC_SINGLE("ALC Capture NG Switch", WM8983_NOISE_GATE, 292 + 3, 1, 0), 293 + SOC_SINGLE("ALC Capture NG Threshold", WM8983_NOISE_GATE, 294 + 0, 7, 1), 295 + 296 + SOC_DOUBLE_R_TLV("Capture Volume", WM8983_LEFT_ADC_DIGITAL_VOL, 297 + WM8983_RIGHT_ADC_DIGITAL_VOL, 0, 255, 0, adc_tlv), 298 + SOC_DOUBLE_R("Capture PGA ZC Switch", WM8983_LEFT_INP_PGA_GAIN_CTRL, 299 + WM8983_RIGHT_INP_PGA_GAIN_CTRL, 7, 1, 0), 300 + SOC_DOUBLE_R_TLV("Capture PGA Volume", WM8983_LEFT_INP_PGA_GAIN_CTRL, 301 + WM8983_RIGHT_INP_PGA_GAIN_CTRL, 0, 63, 0, pga_vol_tlv), 302 + 303 + SOC_DOUBLE_R_TLV("Capture PGA Boost Volume", 304 + WM8983_LEFT_ADC_BOOST_CTRL, WM8983_RIGHT_ADC_BOOST_CTRL, 305 + 8, 1, 0, pga_boost_tlv), 306 + 307 + SOC_DOUBLE("ADC Inversion Switch", WM8983_ADC_CONTROL, 0, 1, 1, 0), 308 + SOC_SINGLE("ADC 128x Oversampling Switch", WM8983_ADC_CONTROL, 8, 1, 0), 309 + 310 + SOC_DOUBLE_R_TLV("Playback Volume", WM8983_LEFT_DAC_DIGITAL_VOL, 311 + WM8983_RIGHT_DAC_DIGITAL_VOL, 0, 255, 0, dac_tlv), 312 + 313 + SOC_SINGLE("DAC Playback Limiter Switch", WM8983_DAC_LIMITER_1, 8, 1, 0), 314 + SOC_SINGLE("DAC Playback Limiter Decay", WM8983_DAC_LIMITER_1, 4, 10, 0), 315 + SOC_SINGLE("DAC Playback Limiter Attack", WM8983_DAC_LIMITER_1, 0, 11, 0), 316 + SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8983_DAC_LIMITER_2, 317 + 4, 7, 1, lim_thresh_tlv), 318 + SOC_SINGLE_TLV("DAC Playback Limiter Boost Volume", WM8983_DAC_LIMITER_2, 319 + 0, 12, 0, lim_boost_tlv), 320 + SOC_DOUBLE("DAC Inversion Switch", WM8983_DAC_CONTROL, 0, 1, 1, 0), 321 + SOC_SINGLE("DAC Auto Mute Switch", WM8983_DAC_CONTROL, 2, 1, 0), 322 + SOC_SINGLE("DAC 128x Oversampling Switch", WM8983_DAC_CONTROL, 3, 1, 0), 323 + 324 + SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8983_LOUT1_HP_VOLUME_CTRL, 325 + WM8983_ROUT1_HP_VOLUME_CTRL, 0, 63, 0, out_tlv), 326 + SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8983_LOUT1_HP_VOLUME_CTRL, 327 + WM8983_ROUT1_HP_VOLUME_CTRL, 7, 1, 0), 328 + SOC_DOUBLE_R("Headphone Switch", WM8983_LOUT1_HP_VOLUME_CTRL, 329 + WM8983_ROUT1_HP_VOLUME_CTRL, 6, 1, 1), 330 + 331 + SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8983_LOUT2_SPK_VOLUME_CTRL, 332 + WM8983_ROUT2_SPK_VOLUME_CTRL, 0, 63, 0, out_tlv), 333 + SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8983_LOUT2_SPK_VOLUME_CTRL, 334 + WM8983_ROUT2_SPK_VOLUME_CTRL, 7, 1, 0), 335 + SOC_DOUBLE_R("Speaker Switch", WM8983_LOUT2_SPK_VOLUME_CTRL, 336 + WM8983_ROUT2_SPK_VOLUME_CTRL, 6, 1, 1), 337 + 338 + SOC_SINGLE("OUT3 Switch", WM8983_OUT3_MIXER_CTRL, 339 + 6, 1, 1), 340 + 341 + SOC_SINGLE("OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL, 342 + 6, 1, 1), 343 + 344 + SOC_SINGLE("High Pass Filter Switch", WM8983_ADC_CONTROL, 8, 1, 0), 345 + SOC_ENUM("High Pass Filter Mode", filter_mode), 346 + SOC_SINGLE("High Pass Filter Cutoff", WM8983_ADC_CONTROL, 4, 7, 0), 347 + 348 + SOC_DOUBLE_R_TLV("Aux Bypass Volume", 349 + WM8983_LEFT_MIXER_CTRL, WM8983_RIGHT_MIXER_CTRL, 6, 7, 0, 350 + aux_tlv), 351 + 352 + SOC_DOUBLE_R_TLV("Input PGA Bypass Volume", 353 + WM8983_LEFT_MIXER_CTRL, WM8983_RIGHT_MIXER_CTRL, 2, 7, 0, 354 + bypass_tlv), 355 + 356 + SOC_ENUM_EXT("Equalizer Function", eqmode, eqmode_get, eqmode_put), 357 + SOC_ENUM("EQ1 Cutoff", eq1_cutoff), 358 + SOC_SINGLE_TLV("EQ1 Volume", WM8983_EQ1_LOW_SHELF, 0, 24, 1, eq_tlv), 359 + SOC_ENUM("EQ2 Bandwith", eq2_bw), 360 + SOC_ENUM("EQ2 Cutoff", eq2_cutoff), 361 + SOC_SINGLE_TLV("EQ2 Volume", WM8983_EQ2_PEAK_1, 0, 24, 1, eq_tlv), 362 + SOC_ENUM("EQ3 Bandwith", eq3_bw), 363 + SOC_ENUM("EQ3 Cutoff", eq3_cutoff), 364 + SOC_SINGLE_TLV("EQ3 Volume", WM8983_EQ3_PEAK_2, 0, 24, 1, eq_tlv), 365 + SOC_ENUM("EQ4 Bandwith", eq4_bw), 366 + SOC_ENUM("EQ4 Cutoff", eq4_cutoff), 367 + SOC_SINGLE_TLV("EQ4 Volume", WM8983_EQ4_PEAK_3, 0, 24, 1, eq_tlv), 368 + SOC_ENUM("EQ5 Cutoff", eq5_cutoff), 369 + SOC_SINGLE_TLV("EQ5 Volume", WM8983_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv), 370 + 371 + SOC_ENUM("3D Depth", depth_3d), 372 + 373 + SOC_ENUM("Speaker Mode", speaker_mode) 374 + }; 375 + 376 + static const struct snd_kcontrol_new left_out_mixer[] = { 377 + SOC_DAPM_SINGLE("Line Switch", WM8983_LEFT_MIXER_CTRL, 1, 1, 0), 378 + SOC_DAPM_SINGLE("Aux Switch", WM8983_LEFT_MIXER_CTRL, 5, 1, 0), 379 + SOC_DAPM_SINGLE("PCM Switch", WM8983_LEFT_MIXER_CTRL, 0, 1, 0), 380 + }; 381 + 382 + static const struct snd_kcontrol_new right_out_mixer[] = { 383 + SOC_DAPM_SINGLE("Line Switch", WM8983_RIGHT_MIXER_CTRL, 1, 1, 0), 384 + SOC_DAPM_SINGLE("Aux Switch", WM8983_RIGHT_MIXER_CTRL, 5, 1, 0), 385 + SOC_DAPM_SINGLE("PCM Switch", WM8983_RIGHT_MIXER_CTRL, 0, 1, 0), 386 + }; 387 + 388 + static const struct snd_kcontrol_new left_input_mixer[] = { 389 + SOC_DAPM_SINGLE("L2 Switch", WM8983_INPUT_CTRL, 2, 1, 0), 390 + SOC_DAPM_SINGLE("MicN Switch", WM8983_INPUT_CTRL, 1, 1, 0), 391 + SOC_DAPM_SINGLE("MicP Switch", WM8983_INPUT_CTRL, 0, 1, 0), 392 + }; 393 + 394 + static const struct snd_kcontrol_new right_input_mixer[] = { 395 + SOC_DAPM_SINGLE("R2 Switch", WM8983_INPUT_CTRL, 6, 1, 0), 396 + SOC_DAPM_SINGLE("MicN Switch", WM8983_INPUT_CTRL, 5, 1, 0), 397 + SOC_DAPM_SINGLE("MicP Switch", WM8983_INPUT_CTRL, 4, 1, 0), 398 + }; 399 + 400 + static const struct snd_kcontrol_new left_boost_mixer[] = { 401 + SOC_DAPM_SINGLE_TLV("L2 Volume", WM8983_LEFT_ADC_BOOST_CTRL, 402 + 4, 7, 0, boost_tlv), 403 + SOC_DAPM_SINGLE_TLV("AUXL Volume", WM8983_LEFT_ADC_BOOST_CTRL, 404 + 0, 7, 0, boost_tlv) 405 + }; 406 + 407 + static const struct snd_kcontrol_new out3_mixer[] = { 408 + SOC_DAPM_SINGLE("LMIX2OUT3 Switch", WM8983_OUT3_MIXER_CTRL, 409 + 1, 1, 0), 410 + SOC_DAPM_SINGLE("LDAC2OUT3 Switch", WM8983_OUT3_MIXER_CTRL, 411 + 0, 1, 0), 412 + }; 413 + 414 + static const struct snd_kcontrol_new out4_mixer[] = { 415 + SOC_DAPM_SINGLE("LMIX2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL, 416 + 4, 1, 0), 417 + SOC_DAPM_SINGLE("RMIX2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL, 418 + 1, 1, 0), 419 + SOC_DAPM_SINGLE("LDAC2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL, 420 + 3, 1, 0), 421 + SOC_DAPM_SINGLE("RDAC2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL, 422 + 0, 1, 0), 423 + }; 424 + 425 + static const struct snd_kcontrol_new right_boost_mixer[] = { 426 + SOC_DAPM_SINGLE_TLV("R2 Volume", WM8983_RIGHT_ADC_BOOST_CTRL, 427 + 4, 7, 0, boost_tlv), 428 + SOC_DAPM_SINGLE_TLV("AUXR Volume", WM8983_RIGHT_ADC_BOOST_CTRL, 429 + 0, 7, 0, boost_tlv) 430 + }; 431 + 432 + static const struct snd_soc_dapm_widget wm8983_dapm_widgets[] = { 433 + SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8983_POWER_MANAGEMENT_3, 434 + 0, 0), 435 + SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8983_POWER_MANAGEMENT_3, 436 + 1, 0), 437 + SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8983_POWER_MANAGEMENT_2, 438 + 0, 0), 439 + SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8983_POWER_MANAGEMENT_2, 440 + 1, 0), 441 + 442 + SND_SOC_DAPM_MIXER("Left Output Mixer", WM8983_POWER_MANAGEMENT_3, 443 + 2, 0, left_out_mixer, ARRAY_SIZE(left_out_mixer)), 444 + SND_SOC_DAPM_MIXER("Right Output Mixer", WM8983_POWER_MANAGEMENT_3, 445 + 3, 0, right_out_mixer, ARRAY_SIZE(right_out_mixer)), 446 + 447 + SND_SOC_DAPM_MIXER("Left Input Mixer", WM8983_POWER_MANAGEMENT_2, 448 + 2, 0, left_input_mixer, ARRAY_SIZE(left_input_mixer)), 449 + SND_SOC_DAPM_MIXER("Right Input Mixer", WM8983_POWER_MANAGEMENT_2, 450 + 3, 0, right_input_mixer, ARRAY_SIZE(right_input_mixer)), 451 + 452 + SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8983_POWER_MANAGEMENT_2, 453 + 4, 0, left_boost_mixer, ARRAY_SIZE(left_boost_mixer)), 454 + SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8983_POWER_MANAGEMENT_2, 455 + 5, 0, right_boost_mixer, ARRAY_SIZE(right_boost_mixer)), 456 + 457 + SND_SOC_DAPM_MIXER("OUT3 Mixer", WM8983_POWER_MANAGEMENT_1, 458 + 6, 0, out3_mixer, ARRAY_SIZE(out3_mixer)), 459 + 460 + SND_SOC_DAPM_MIXER("OUT4 Mixer", WM8983_POWER_MANAGEMENT_1, 461 + 7, 0, out4_mixer, ARRAY_SIZE(out4_mixer)), 462 + 463 + SND_SOC_DAPM_PGA("Left Capture PGA", WM8983_LEFT_INP_PGA_GAIN_CTRL, 464 + 6, 1, NULL, 0), 465 + SND_SOC_DAPM_PGA("Right Capture PGA", WM8983_RIGHT_INP_PGA_GAIN_CTRL, 466 + 6, 1, NULL, 0), 467 + 468 + SND_SOC_DAPM_PGA("Left Headphone Out", WM8983_POWER_MANAGEMENT_2, 469 + 7, 0, NULL, 0), 470 + SND_SOC_DAPM_PGA("Right Headphone Out", WM8983_POWER_MANAGEMENT_2, 471 + 8, 0, NULL, 0), 472 + 473 + SND_SOC_DAPM_PGA("Left Speaker Out", WM8983_POWER_MANAGEMENT_3, 474 + 5, 0, NULL, 0), 475 + SND_SOC_DAPM_PGA("Right Speaker Out", WM8983_POWER_MANAGEMENT_3, 476 + 6, 0, NULL, 0), 477 + 478 + SND_SOC_DAPM_PGA("OUT3 Out", WM8983_POWER_MANAGEMENT_3, 479 + 7, 0, NULL, 0), 480 + 481 + SND_SOC_DAPM_PGA("OUT4 Out", WM8983_POWER_MANAGEMENT_3, 482 + 8, 0, NULL, 0), 483 + 484 + SND_SOC_DAPM_MICBIAS("Mic Bias", WM8983_POWER_MANAGEMENT_1, 4, 0), 485 + 486 + SND_SOC_DAPM_INPUT("LIN"), 487 + SND_SOC_DAPM_INPUT("LIP"), 488 + SND_SOC_DAPM_INPUT("RIN"), 489 + SND_SOC_DAPM_INPUT("RIP"), 490 + SND_SOC_DAPM_INPUT("AUXL"), 491 + SND_SOC_DAPM_INPUT("AUXR"), 492 + SND_SOC_DAPM_INPUT("L2"), 493 + SND_SOC_DAPM_INPUT("R2"), 494 + SND_SOC_DAPM_OUTPUT("HPL"), 495 + SND_SOC_DAPM_OUTPUT("HPR"), 496 + SND_SOC_DAPM_OUTPUT("SPKL"), 497 + SND_SOC_DAPM_OUTPUT("SPKR"), 498 + SND_SOC_DAPM_OUTPUT("OUT3"), 499 + SND_SOC_DAPM_OUTPUT("OUT4") 500 + }; 501 + 502 + static const struct snd_soc_dapm_route wm8983_audio_map[] = { 503 + { "OUT3 Mixer", "LMIX2OUT3 Switch", "Left Output Mixer" }, 504 + { "OUT3 Mixer", "LDAC2OUT3 Switch", "Left DAC" }, 505 + 506 + { "OUT3 Out", NULL, "OUT3 Mixer" }, 507 + { "OUT3", NULL, "OUT3 Out" }, 508 + 509 + { "OUT4 Mixer", "LMIX2OUT4 Switch", "Left Output Mixer" }, 510 + { "OUT4 Mixer", "RMIX2OUT4 Switch", "Right Output Mixer" }, 511 + { "OUT4 Mixer", "LDAC2OUT4 Switch", "Left DAC" }, 512 + { "OUT4 Mixer", "RDAC2OUT4 Switch", "Right DAC" }, 513 + 514 + { "OUT4 Out", NULL, "OUT4 Mixer" }, 515 + { "OUT4", NULL, "OUT4 Out" }, 516 + 517 + { "Right Output Mixer", "PCM Switch", "Right DAC" }, 518 + { "Right Output Mixer", "Aux Switch", "AUXR" }, 519 + { "Right Output Mixer", "Line Switch", "Right Boost Mixer" }, 520 + 521 + { "Left Output Mixer", "PCM Switch", "Left DAC" }, 522 + { "Left Output Mixer", "Aux Switch", "AUXL" }, 523 + { "Left Output Mixer", "Line Switch", "Left Boost Mixer" }, 524 + 525 + { "Right Headphone Out", NULL, "Right Output Mixer" }, 526 + { "HPR", NULL, "Right Headphone Out" }, 527 + 528 + { "Left Headphone Out", NULL, "Left Output Mixer" }, 529 + { "HPL", NULL, "Left Headphone Out" }, 530 + 531 + { "Right Speaker Out", NULL, "Right Output Mixer" }, 532 + { "SPKR", NULL, "Right Speaker Out" }, 533 + 534 + { "Left Speaker Out", NULL, "Left Output Mixer" }, 535 + { "SPKL", NULL, "Left Speaker Out" }, 536 + 537 + { "Right ADC", NULL, "Right Boost Mixer" }, 538 + 539 + { "Right Boost Mixer", "AUXR Volume", "AUXR" }, 540 + { "Right Boost Mixer", NULL, "Right Capture PGA" }, 541 + { "Right Boost Mixer", "R2 Volume", "R2" }, 542 + 543 + { "Left ADC", NULL, "Left Boost Mixer" }, 544 + 545 + { "Left Boost Mixer", "AUXL Volume", "AUXL" }, 546 + { "Left Boost Mixer", NULL, "Left Capture PGA" }, 547 + { "Left Boost Mixer", "L2 Volume", "L2" }, 548 + 549 + { "Right Capture PGA", NULL, "Right Input Mixer" }, 550 + { "Left Capture PGA", NULL, "Left Input Mixer" }, 551 + 552 + { "Right Input Mixer", "R2 Switch", "R2" }, 553 + { "Right Input Mixer", "MicN Switch", "RIN" }, 554 + { "Right Input Mixer", "MicP Switch", "RIP" }, 555 + 556 + { "Left Input Mixer", "L2 Switch", "L2" }, 557 + { "Left Input Mixer", "MicN Switch", "LIN" }, 558 + { "Left Input Mixer", "MicP Switch", "LIP" }, 559 + }; 560 + 561 + static int eqmode_get(struct snd_kcontrol *kcontrol, 562 + struct snd_ctl_elem_value *ucontrol) 563 + { 564 + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 565 + unsigned int reg; 566 + 567 + reg = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF); 568 + if (reg & WM8983_EQ3DMODE) 569 + ucontrol->value.integer.value[0] = 1; 570 + else 571 + ucontrol->value.integer.value[0] = 0; 572 + 573 + return 0; 574 + } 575 + 576 + static int eqmode_put(struct snd_kcontrol *kcontrol, 577 + struct snd_ctl_elem_value *ucontrol) 578 + { 579 + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 580 + unsigned int regpwr2, regpwr3; 581 + unsigned int reg_eq; 582 + 583 + if (ucontrol->value.integer.value[0] != 0 584 + && ucontrol->value.integer.value[0] != 1) 585 + return -EINVAL; 586 + 587 + reg_eq = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF); 588 + switch ((reg_eq & WM8983_EQ3DMODE) >> WM8983_EQ3DMODE_SHIFT) { 589 + case 0: 590 + if (!ucontrol->value.integer.value[0]) 591 + return 0; 592 + break; 593 + case 1: 594 + if (ucontrol->value.integer.value[0]) 595 + return 0; 596 + break; 597 + } 598 + 599 + regpwr2 = snd_soc_read(codec, WM8983_POWER_MANAGEMENT_2); 600 + regpwr3 = snd_soc_read(codec, WM8983_POWER_MANAGEMENT_3); 601 + /* disable the DACs and ADCs */ 602 + snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_2, 603 + WM8983_ADCENR_MASK | WM8983_ADCENL_MASK, 0); 604 + snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_3, 605 + WM8983_DACENR_MASK | WM8983_DACENL_MASK, 0); 606 + /* set the desired eqmode */ 607 + snd_soc_update_bits(codec, WM8983_EQ1_LOW_SHELF, 608 + WM8983_EQ3DMODE_MASK, 609 + ucontrol->value.integer.value[0] 610 + << WM8983_EQ3DMODE_SHIFT); 611 + /* restore DAC/ADC configuration */ 612 + snd_soc_write(codec, WM8983_POWER_MANAGEMENT_2, regpwr2); 613 + snd_soc_write(codec, WM8983_POWER_MANAGEMENT_3, regpwr3); 614 + return 0; 615 + } 616 + 617 + static int wm8983_readable(struct snd_soc_codec *codec, unsigned int reg) 618 + { 619 + if (reg > WM8983_MAX_REGISTER) 620 + return 0; 621 + 622 + return wm8983_access_masks[reg].read != 0; 623 + } 624 + 625 + static int wm8983_dac_mute(struct snd_soc_dai *dai, int mute) 626 + { 627 + struct snd_soc_codec *codec = dai->codec; 628 + 629 + return snd_soc_update_bits(codec, WM8983_DAC_CONTROL, 630 + WM8983_SOFTMUTE_MASK, 631 + !!mute << WM8983_SOFTMUTE_SHIFT); 632 + } 633 + 634 + static int wm8983_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 635 + { 636 + struct snd_soc_codec *codec = dai->codec; 637 + u16 format, master, bcp, lrp; 638 + 639 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 640 + case SND_SOC_DAIFMT_I2S: 641 + format = 0x2; 642 + break; 643 + case SND_SOC_DAIFMT_RIGHT_J: 644 + format = 0x0; 645 + break; 646 + case SND_SOC_DAIFMT_LEFT_J: 647 + format = 0x1; 648 + break; 649 + case SND_SOC_DAIFMT_DSP_A: 650 + case SND_SOC_DAIFMT_DSP_B: 651 + format = 0x3; 652 + break; 653 + default: 654 + dev_err(dai->dev, "Unknown dai format\n"); 655 + return -EINVAL; 656 + } 657 + 658 + snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE, 659 + WM8983_FMT_MASK, format << WM8983_FMT_SHIFT); 660 + 661 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 662 + case SND_SOC_DAIFMT_CBM_CFM: 663 + master = 1; 664 + break; 665 + case SND_SOC_DAIFMT_CBS_CFS: 666 + master = 0; 667 + break; 668 + default: 669 + dev_err(dai->dev, "Unknown master/slave configuration\n"); 670 + return -EINVAL; 671 + } 672 + 673 + snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL, 674 + WM8983_MS_MASK, master << WM8983_MS_SHIFT); 675 + 676 + /* FIXME: We don't currently support DSP A/B modes */ 677 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 678 + case SND_SOC_DAIFMT_DSP_A: 679 + case SND_SOC_DAIFMT_DSP_B: 680 + dev_err(dai->dev, "DSP A/B modes are not supported\n"); 681 + return -EINVAL; 682 + default: 683 + break; 684 + } 685 + 686 + bcp = lrp = 0; 687 + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 688 + case SND_SOC_DAIFMT_NB_NF: 689 + break; 690 + case SND_SOC_DAIFMT_IB_IF: 691 + bcp = lrp = 1; 692 + break; 693 + case SND_SOC_DAIFMT_IB_NF: 694 + bcp = 1; 695 + break; 696 + case SND_SOC_DAIFMT_NB_IF: 697 + lrp = 1; 698 + break; 699 + default: 700 + dev_err(dai->dev, "Unknown polarity configuration\n"); 701 + return -EINVAL; 702 + } 703 + 704 + snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE, 705 + WM8983_LRCP_MASK, lrp << WM8983_LRCP_SHIFT); 706 + snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE, 707 + WM8983_BCP_MASK, bcp << WM8983_BCP_SHIFT); 708 + return 0; 709 + } 710 + 711 + static int wm8983_hw_params(struct snd_pcm_substream *substream, 712 + struct snd_pcm_hw_params *params, 713 + struct snd_soc_dai *dai) 714 + { 715 + int i; 716 + struct snd_soc_codec *codec = dai->codec; 717 + struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec); 718 + u16 blen, srate_idx; 719 + u32 tmp; 720 + int srate_best; 721 + int ret; 722 + 723 + ret = snd_soc_params_to_bclk(params); 724 + if (ret < 0) { 725 + dev_err(codec->dev, "Failed to convert params to bclk: %d\n", ret); 726 + return ret; 727 + } 728 + 729 + wm8983->bclk = ret; 730 + 731 + switch (params_format(params)) { 732 + case SNDRV_PCM_FORMAT_S16_LE: 733 + blen = 0x0; 734 + break; 735 + case SNDRV_PCM_FORMAT_S20_3LE: 736 + blen = 0x1; 737 + break; 738 + case SNDRV_PCM_FORMAT_S24_LE: 739 + blen = 0x2; 740 + break; 741 + case SNDRV_PCM_FORMAT_S32_LE: 742 + blen = 0x3; 743 + break; 744 + default: 745 + dev_err(dai->dev, "Unsupported word length %u\n", 746 + params_format(params)); 747 + return -EINVAL; 748 + } 749 + 750 + snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE, 751 + WM8983_WL_MASK, blen << WM8983_WL_SHIFT); 752 + 753 + /* 754 + * match to the nearest possible sample rate and rely 755 + * on the array index to configure the SR register 756 + */ 757 + srate_idx = 0; 758 + srate_best = abs(srates[0] - params_rate(params)); 759 + for (i = 1; i < ARRAY_SIZE(srates); ++i) { 760 + if (abs(srates[i] - params_rate(params)) >= srate_best) 761 + continue; 762 + srate_idx = i; 763 + srate_best = abs(srates[i] - params_rate(params)); 764 + } 765 + 766 + dev_dbg(dai->dev, "Selected SRATE = %d\n", srates[srate_idx]); 767 + snd_soc_update_bits(codec, WM8983_ADDITIONAL_CONTROL, 768 + WM8983_SR_MASK, srate_idx << WM8983_SR_SHIFT); 769 + 770 + dev_dbg(dai->dev, "Target BCLK = %uHz\n", wm8983->bclk); 771 + dev_dbg(dai->dev, "SYSCLK = %uHz\n", wm8983->sysclk); 772 + 773 + for (i = 0; i < ARRAY_SIZE(fs_ratios); ++i) { 774 + if (wm8983->sysclk / params_rate(params) 775 + == fs_ratios[i].ratio) 776 + break; 777 + } 778 + 779 + if (i == ARRAY_SIZE(fs_ratios)) { 780 + dev_err(dai->dev, "Unable to configure MCLK ratio %u/%u\n", 781 + wm8983->sysclk, params_rate(params)); 782 + return -EINVAL; 783 + } 784 + 785 + dev_dbg(dai->dev, "MCLK ratio = %dfs\n", fs_ratios[i].ratio); 786 + snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL, 787 + WM8983_MCLKDIV_MASK, i << WM8983_MCLKDIV_SHIFT); 788 + 789 + /* select the appropriate bclk divider */ 790 + tmp = (wm8983->sysclk / fs_ratios[i].div) * 10; 791 + for (i = 0; i < ARRAY_SIZE(bclk_divs); ++i) { 792 + if (wm8983->bclk == tmp / bclk_divs[i]) 793 + break; 794 + } 795 + 796 + if (i == ARRAY_SIZE(bclk_divs)) { 797 + dev_err(dai->dev, "No matching BCLK divider found\n"); 798 + return -EINVAL; 799 + } 800 + 801 + dev_dbg(dai->dev, "BCLK div = %d\n", i); 802 + snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL, 803 + WM8983_BCLKDIV_MASK, i << WM8983_BCLKDIV_SHIFT); 804 + 805 + return 0; 806 + } 807 + 808 + struct pll_div { 809 + u32 div2:1; 810 + u32 n:4; 811 + u32 k:24; 812 + }; 813 + 814 + #define FIXED_PLL_SIZE ((1ULL << 24) * 10) 815 + static int pll_factors(struct pll_div *pll_div, unsigned int target, 816 + unsigned int source) 817 + { 818 + u64 Kpart; 819 + unsigned long int K, Ndiv, Nmod; 820 + 821 + pll_div->div2 = 0; 822 + Ndiv = target / source; 823 + if (Ndiv < 6) { 824 + source >>= 1; 825 + pll_div->div2 = 1; 826 + Ndiv = target / source; 827 + } 828 + 829 + if (Ndiv < 6 || Ndiv > 12) { 830 + printk(KERN_ERR "%s: WM8983 N value is not within" 831 + " the recommended range: %lu\n", __func__, Ndiv); 832 + return -EINVAL; 833 + } 834 + pll_div->n = Ndiv; 835 + 836 + Nmod = target % source; 837 + Kpart = FIXED_PLL_SIZE * (u64)Nmod; 838 + 839 + do_div(Kpart, source); 840 + 841 + K = Kpart & 0xffffffff; 842 + if ((K % 10) >= 5) 843 + K += 5; 844 + K /= 10; 845 + pll_div->k = K; 846 + return 0; 847 + } 848 + 849 + static int wm8983_set_pll(struct snd_soc_dai *dai, int pll_id, 850 + int source, unsigned int freq_in, 851 + unsigned int freq_out) 852 + { 853 + int ret; 854 + struct snd_soc_codec *codec; 855 + struct pll_div pll_div; 856 + 857 + codec = dai->codec; 858 + if (freq_in && freq_out) { 859 + ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in); 860 + if (ret) 861 + return ret; 862 + } 863 + 864 + /* disable the PLL before re-programming it */ 865 + snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1, 866 + WM8983_PLLEN_MASK, 0); 867 + 868 + if (!freq_in || !freq_out) 869 + return 0; 870 + 871 + /* set PLLN and PRESCALE */ 872 + snd_soc_write(codec, WM8983_PLL_N, 873 + (pll_div.div2 << WM8983_PLL_PRESCALE_SHIFT) 874 + | pll_div.n); 875 + /* set PLLK */ 876 + snd_soc_write(codec, WM8983_PLL_K_3, pll_div.k & 0x1ff); 877 + snd_soc_write(codec, WM8983_PLL_K_2, (pll_div.k >> 9) & 0x1ff); 878 + snd_soc_write(codec, WM8983_PLL_K_1, (pll_div.k >> 18)); 879 + /* enable the PLL */ 880 + snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1, 881 + WM8983_PLLEN_MASK, WM8983_PLLEN); 882 + return 0; 883 + } 884 + 885 + static int wm8983_set_sysclk(struct snd_soc_dai *dai, 886 + int clk_id, unsigned int freq, int dir) 887 + { 888 + struct snd_soc_codec *codec = dai->codec; 889 + struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec); 890 + 891 + switch (clk_id) { 892 + case WM8983_CLKSRC_MCLK: 893 + snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL, 894 + WM8983_CLKSEL_MASK, 0); 895 + break; 896 + case WM8983_CLKSRC_PLL: 897 + snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL, 898 + WM8983_CLKSEL_MASK, WM8983_CLKSEL); 899 + break; 900 + default: 901 + dev_err(dai->dev, "Unknown clock source: %d\n", clk_id); 902 + return -EINVAL; 903 + } 904 + 905 + wm8983->sysclk = freq; 906 + return 0; 907 + } 908 + 909 + static int wm8983_set_bias_level(struct snd_soc_codec *codec, 910 + enum snd_soc_bias_level level) 911 + { 912 + int ret; 913 + 914 + switch (level) { 915 + case SND_SOC_BIAS_ON: 916 + case SND_SOC_BIAS_PREPARE: 917 + /* VMID at 100k */ 918 + snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1, 919 + WM8983_VMIDSEL_MASK, 920 + 1 << WM8983_VMIDSEL_SHIFT); 921 + break; 922 + case SND_SOC_BIAS_STANDBY: 923 + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 924 + ret = snd_soc_cache_sync(codec); 925 + if (ret < 0) { 926 + dev_err(codec->dev, "Failed to sync cache: %d\n", ret); 927 + return ret; 928 + } 929 + /* enable anti-pop features */ 930 + snd_soc_update_bits(codec, WM8983_OUT4_TO_ADC, 931 + WM8983_POBCTRL_MASK | WM8983_DELEN_MASK, 932 + WM8983_POBCTRL | WM8983_DELEN); 933 + /* enable thermal shutdown */ 934 + snd_soc_update_bits(codec, WM8983_OUTPUT_CTRL, 935 + WM8983_TSDEN_MASK, WM8983_TSDEN); 936 + /* enable BIASEN */ 937 + snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1, 938 + WM8983_BIASEN_MASK, WM8983_BIASEN); 939 + /* VMID at 100k */ 940 + snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1, 941 + WM8983_VMIDSEL_MASK, 942 + 1 << WM8983_VMIDSEL_SHIFT); 943 + msleep(250); 944 + /* disable anti-pop features */ 945 + snd_soc_update_bits(codec, WM8983_OUT4_TO_ADC, 946 + WM8983_POBCTRL_MASK | 947 + WM8983_DELEN_MASK, 0); 948 + } 949 + 950 + /* VMID at 500k */ 951 + snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1, 952 + WM8983_VMIDSEL_MASK, 953 + 2 << WM8983_VMIDSEL_SHIFT); 954 + break; 955 + case SND_SOC_BIAS_OFF: 956 + /* disable thermal shutdown */ 957 + snd_soc_update_bits(codec, WM8983_OUTPUT_CTRL, 958 + WM8983_TSDEN_MASK, 0); 959 + /* disable VMIDSEL and BIASEN */ 960 + snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1, 961 + WM8983_VMIDSEL_MASK | WM8983_BIASEN_MASK, 962 + 0); 963 + /* wait for VMID to discharge */ 964 + msleep(100); 965 + snd_soc_write(codec, WM8983_POWER_MANAGEMENT_1, 0); 966 + snd_soc_write(codec, WM8983_POWER_MANAGEMENT_2, 0); 967 + snd_soc_write(codec, WM8983_POWER_MANAGEMENT_3, 0); 968 + break; 969 + } 970 + 971 + codec->dapm.bias_level = level; 972 + return 0; 973 + } 974 + 975 + #ifdef CONFIG_PM 976 + static int wm8983_suspend(struct snd_soc_codec *codec, pm_message_t state) 977 + { 978 + wm8983_set_bias_level(codec, SND_SOC_BIAS_OFF); 979 + return 0; 980 + } 981 + 982 + static int wm8983_resume(struct snd_soc_codec *codec) 983 + { 984 + wm8983_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 985 + return 0; 986 + } 987 + #else 988 + #define wm8983_suspend NULL 989 + #define wm8983_resume NULL 990 + #endif 991 + 992 + static int wm8983_remove(struct snd_soc_codec *codec) 993 + { 994 + wm8983_set_bias_level(codec, SND_SOC_BIAS_OFF); 995 + return 0; 996 + } 997 + 998 + static int wm8983_probe(struct snd_soc_codec *codec) 999 + { 1000 + int ret; 1001 + struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec); 1002 + int i; 1003 + 1004 + ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8983->control_type); 1005 + if (ret < 0) { 1006 + dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); 1007 + return ret; 1008 + } 1009 + 1010 + ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0x8983); 1011 + if (ret < 0) { 1012 + dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 1013 + return ret; 1014 + } 1015 + 1016 + /* set the vol/gain update bits */ 1017 + for (i = 0; i < ARRAY_SIZE(vol_update_regs); ++i) 1018 + snd_soc_update_bits(codec, vol_update_regs[i], 1019 + 0x100, 0x100); 1020 + 1021 + /* mute all outputs and set PGAs to minimum gain */ 1022 + for (i = WM8983_LOUT1_HP_VOLUME_CTRL; 1023 + i <= WM8983_OUT4_MONO_MIX_CTRL; ++i) 1024 + snd_soc_update_bits(codec, i, 0x40, 0x40); 1025 + 1026 + /* enable soft mute */ 1027 + snd_soc_update_bits(codec, WM8983_DAC_CONTROL, 1028 + WM8983_SOFTMUTE_MASK, 1029 + WM8983_SOFTMUTE); 1030 + 1031 + /* enable BIASCUT */ 1032 + snd_soc_update_bits(codec, WM8983_BIAS_CTRL, 1033 + WM8983_BIASCUT, WM8983_BIASCUT); 1034 + return 0; 1035 + } 1036 + 1037 + static struct snd_soc_dai_ops wm8983_dai_ops = { 1038 + .digital_mute = wm8983_dac_mute, 1039 + .hw_params = wm8983_hw_params, 1040 + .set_fmt = wm8983_set_fmt, 1041 + .set_sysclk = wm8983_set_sysclk, 1042 + .set_pll = wm8983_set_pll 1043 + }; 1044 + 1045 + #define WM8983_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1046 + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 1047 + 1048 + static struct snd_soc_dai_driver wm8983_dai = { 1049 + .name = "wm8983-hifi", 1050 + .playback = { 1051 + .stream_name = "Playback", 1052 + .channels_min = 2, 1053 + .channels_max = 2, 1054 + .rates = SNDRV_PCM_RATE_8000_48000, 1055 + .formats = WM8983_FORMATS, 1056 + }, 1057 + .capture = { 1058 + .stream_name = "Capture", 1059 + .channels_min = 2, 1060 + .channels_max = 2, 1061 + .rates = SNDRV_PCM_RATE_8000_48000, 1062 + .formats = WM8983_FORMATS, 1063 + }, 1064 + .ops = &wm8983_dai_ops, 1065 + .symmetric_rates = 1 1066 + }; 1067 + 1068 + static struct snd_soc_codec_driver soc_codec_dev_wm8983 = { 1069 + .probe = wm8983_probe, 1070 + .remove = wm8983_remove, 1071 + .suspend = wm8983_suspend, 1072 + .resume = wm8983_resume, 1073 + .set_bias_level = wm8983_set_bias_level, 1074 + .reg_cache_size = ARRAY_SIZE(wm8983_reg_defs), 1075 + .reg_word_size = sizeof(u16), 1076 + .reg_cache_default = wm8983_reg_defs, 1077 + .controls = wm8983_snd_controls, 1078 + .num_controls = ARRAY_SIZE(wm8983_snd_controls), 1079 + .dapm_widgets = wm8983_dapm_widgets, 1080 + .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets), 1081 + .dapm_routes = wm8983_audio_map, 1082 + .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map), 1083 + .readable_register = wm8983_readable 1084 + }; 1085 + 1086 + #if defined(CONFIG_SPI_MASTER) 1087 + static int __devinit wm8983_spi_probe(struct spi_device *spi) 1088 + { 1089 + struct wm8983_priv *wm8983; 1090 + int ret; 1091 + 1092 + wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL); 1093 + if (!wm8983) 1094 + return -ENOMEM; 1095 + 1096 + wm8983->control_type = SND_SOC_SPI; 1097 + spi_set_drvdata(spi, wm8983); 1098 + 1099 + ret = snd_soc_register_codec(&spi->dev, 1100 + &soc_codec_dev_wm8983, &wm8983_dai, 1); 1101 + if (ret < 0) 1102 + kfree(wm8983); 1103 + return ret; 1104 + } 1105 + 1106 + static int __devexit wm8983_spi_remove(struct spi_device *spi) 1107 + { 1108 + snd_soc_unregister_codec(&spi->dev); 1109 + kfree(spi_get_drvdata(spi)); 1110 + return 0; 1111 + } 1112 + 1113 + static struct spi_driver wm8983_spi_driver = { 1114 + .driver = { 1115 + .name = "wm8983", 1116 + .owner = THIS_MODULE, 1117 + }, 1118 + .probe = wm8983_spi_probe, 1119 + .remove = __devexit_p(wm8983_spi_remove) 1120 + }; 1121 + #endif 1122 + 1123 + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1124 + static __devinit int wm8983_i2c_probe(struct i2c_client *i2c, 1125 + const struct i2c_device_id *id) 1126 + { 1127 + struct wm8983_priv *wm8983; 1128 + int ret; 1129 + 1130 + wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL); 1131 + if (!wm8983) 1132 + return -ENOMEM; 1133 + 1134 + wm8983->control_type = SND_SOC_I2C; 1135 + i2c_set_clientdata(i2c, wm8983); 1136 + 1137 + ret = snd_soc_register_codec(&i2c->dev, 1138 + &soc_codec_dev_wm8983, &wm8983_dai, 1); 1139 + if (ret < 0) 1140 + kfree(wm8983); 1141 + return ret; 1142 + } 1143 + 1144 + static __devexit int wm8983_i2c_remove(struct i2c_client *client) 1145 + { 1146 + snd_soc_unregister_codec(&client->dev); 1147 + kfree(i2c_get_clientdata(client)); 1148 + return 0; 1149 + } 1150 + 1151 + static const struct i2c_device_id wm8983_i2c_id[] = { 1152 + { "wm8983", 0 }, 1153 + { } 1154 + }; 1155 + MODULE_DEVICE_TABLE(i2c, wm8983_i2c_id); 1156 + 1157 + static struct i2c_driver wm8983_i2c_driver = { 1158 + .driver = { 1159 + .name = "wm8983", 1160 + .owner = THIS_MODULE, 1161 + }, 1162 + .probe = wm8983_i2c_probe, 1163 + .remove = __devexit_p(wm8983_i2c_remove), 1164 + .id_table = wm8983_i2c_id 1165 + }; 1166 + #endif 1167 + 1168 + static int __init wm8983_modinit(void) 1169 + { 1170 + int ret = 0; 1171 + 1172 + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1173 + ret = i2c_add_driver(&wm8983_i2c_driver); 1174 + if (ret) { 1175 + printk(KERN_ERR "Failed to register wm8983 I2C driver: %d\n", 1176 + ret); 1177 + } 1178 + #endif 1179 + #if defined(CONFIG_SPI_MASTER) 1180 + ret = spi_register_driver(&wm8983_spi_driver); 1181 + if (ret != 0) { 1182 + printk(KERN_ERR "Failed to register wm8983 SPI driver: %d\n", 1183 + ret); 1184 + } 1185 + #endif 1186 + return ret; 1187 + } 1188 + module_init(wm8983_modinit); 1189 + 1190 + static void __exit wm8983_exit(void) 1191 + { 1192 + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1193 + i2c_del_driver(&wm8983_i2c_driver); 1194 + #endif 1195 + #if defined(CONFIG_SPI_MASTER) 1196 + spi_unregister_driver(&wm8983_spi_driver); 1197 + #endif 1198 + } 1199 + module_exit(wm8983_exit); 1200 + 1201 + MODULE_DESCRIPTION("ASoC WM8983 driver"); 1202 + MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>"); 1203 + MODULE_LICENSE("GPL");
+1029
sound/soc/codecs/wm8983.h
··· 1 + /* 2 + * wm8983.h -- WM8983 ALSA SoC Audio driver 3 + * 4 + * Copyright 2011 Wolfson Microelectronics plc 5 + * 6 + * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #ifndef _WM8983_H 14 + #define _WM8983_H 15 + 16 + /* 17 + * Register values. 18 + */ 19 + #define WM8983_SOFTWARE_RESET 0x00 20 + #define WM8983_POWER_MANAGEMENT_1 0x01 21 + #define WM8983_POWER_MANAGEMENT_2 0x02 22 + #define WM8983_POWER_MANAGEMENT_3 0x03 23 + #define WM8983_AUDIO_INTERFACE 0x04 24 + #define WM8983_COMPANDING_CONTROL 0x05 25 + #define WM8983_CLOCK_GEN_CONTROL 0x06 26 + #define WM8983_ADDITIONAL_CONTROL 0x07 27 + #define WM8983_GPIO_CONTROL 0x08 28 + #define WM8983_JACK_DETECT_CONTROL_1 0x09 29 + #define WM8983_DAC_CONTROL 0x0A 30 + #define WM8983_LEFT_DAC_DIGITAL_VOL 0x0B 31 + #define WM8983_RIGHT_DAC_DIGITAL_VOL 0x0C 32 + #define WM8983_JACK_DETECT_CONTROL_2 0x0D 33 + #define WM8983_ADC_CONTROL 0x0E 34 + #define WM8983_LEFT_ADC_DIGITAL_VOL 0x0F 35 + #define WM8983_RIGHT_ADC_DIGITAL_VOL 0x10 36 + #define WM8983_EQ1_LOW_SHELF 0x12 37 + #define WM8983_EQ2_PEAK_1 0x13 38 + #define WM8983_EQ3_PEAK_2 0x14 39 + #define WM8983_EQ4_PEAK_3 0x15 40 + #define WM8983_EQ5_HIGH_SHELF 0x16 41 + #define WM8983_DAC_LIMITER_1 0x18 42 + #define WM8983_DAC_LIMITER_2 0x19 43 + #define WM8983_NOTCH_FILTER_1 0x1B 44 + #define WM8983_NOTCH_FILTER_2 0x1C 45 + #define WM8983_NOTCH_FILTER_3 0x1D 46 + #define WM8983_NOTCH_FILTER_4 0x1E 47 + #define WM8983_ALC_CONTROL_1 0x20 48 + #define WM8983_ALC_CONTROL_2 0x21 49 + #define WM8983_ALC_CONTROL_3 0x22 50 + #define WM8983_NOISE_GATE 0x23 51 + #define WM8983_PLL_N 0x24 52 + #define WM8983_PLL_K_1 0x25 53 + #define WM8983_PLL_K_2 0x26 54 + #define WM8983_PLL_K_3 0x27 55 + #define WM8983_3D_CONTROL 0x29 56 + #define WM8983_OUT4_TO_ADC 0x2A 57 + #define WM8983_BEEP_CONTROL 0x2B 58 + #define WM8983_INPUT_CTRL 0x2C 59 + #define WM8983_LEFT_INP_PGA_GAIN_CTRL 0x2D 60 + #define WM8983_RIGHT_INP_PGA_GAIN_CTRL 0x2E 61 + #define WM8983_LEFT_ADC_BOOST_CTRL 0x2F 62 + #define WM8983_RIGHT_ADC_BOOST_CTRL 0x30 63 + #define WM8983_OUTPUT_CTRL 0x31 64 + #define WM8983_LEFT_MIXER_CTRL 0x32 65 + #define WM8983_RIGHT_MIXER_CTRL 0x33 66 + #define WM8983_LOUT1_HP_VOLUME_CTRL 0x34 67 + #define WM8983_ROUT1_HP_VOLUME_CTRL 0x35 68 + #define WM8983_LOUT2_SPK_VOLUME_CTRL 0x36 69 + #define WM8983_ROUT2_SPK_VOLUME_CTRL 0x37 70 + #define WM8983_OUT3_MIXER_CTRL 0x38 71 + #define WM8983_OUT4_MONO_MIX_CTRL 0x39 72 + #define WM8983_BIAS_CTRL 0x3D 73 + 74 + #define WM8983_REGISTER_COUNT 59 75 + #define WM8983_MAX_REGISTER 0x3F 76 + 77 + /* 78 + * Field Definitions. 79 + */ 80 + 81 + /* 82 + * R0 (0x00) - Software Reset 83 + */ 84 + #define WM8983_SOFTWARE_RESET_MASK 0x01FF /* SOFTWARE_RESET - [8:0] */ 85 + #define WM8983_SOFTWARE_RESET_SHIFT 0 /* SOFTWARE_RESET - [8:0] */ 86 + #define WM8983_SOFTWARE_RESET_WIDTH 9 /* SOFTWARE_RESET - [8:0] */ 87 + 88 + /* 89 + * R1 (0x01) - Power management 1 90 + */ 91 + #define WM8983_BUFDCOPEN 0x0100 /* BUFDCOPEN */ 92 + #define WM8983_BUFDCOPEN_MASK 0x0100 /* BUFDCOPEN */ 93 + #define WM8983_BUFDCOPEN_SHIFT 8 /* BUFDCOPEN */ 94 + #define WM8983_BUFDCOPEN_WIDTH 1 /* BUFDCOPEN */ 95 + #define WM8983_OUT4MIXEN 0x0080 /* OUT4MIXEN */ 96 + #define WM8983_OUT4MIXEN_MASK 0x0080 /* OUT4MIXEN */ 97 + #define WM8983_OUT4MIXEN_SHIFT 7 /* OUT4MIXEN */ 98 + #define WM8983_OUT4MIXEN_WIDTH 1 /* OUT4MIXEN */ 99 + #define WM8983_OUT3MIXEN 0x0040 /* OUT3MIXEN */ 100 + #define WM8983_OUT3MIXEN_MASK 0x0040 /* OUT3MIXEN */ 101 + #define WM8983_OUT3MIXEN_SHIFT 6 /* OUT3MIXEN */ 102 + #define WM8983_OUT3MIXEN_WIDTH 1 /* OUT3MIXEN */ 103 + #define WM8983_PLLEN 0x0020 /* PLLEN */ 104 + #define WM8983_PLLEN_MASK 0x0020 /* PLLEN */ 105 + #define WM8983_PLLEN_SHIFT 5 /* PLLEN */ 106 + #define WM8983_PLLEN_WIDTH 1 /* PLLEN */ 107 + #define WM8983_MICBEN 0x0010 /* MICBEN */ 108 + #define WM8983_MICBEN_MASK 0x0010 /* MICBEN */ 109 + #define WM8983_MICBEN_SHIFT 4 /* MICBEN */ 110 + #define WM8983_MICBEN_WIDTH 1 /* MICBEN */ 111 + #define WM8983_BIASEN 0x0008 /* BIASEN */ 112 + #define WM8983_BIASEN_MASK 0x0008 /* BIASEN */ 113 + #define WM8983_BIASEN_SHIFT 3 /* BIASEN */ 114 + #define WM8983_BIASEN_WIDTH 1 /* BIASEN */ 115 + #define WM8983_BUFIOEN 0x0004 /* BUFIOEN */ 116 + #define WM8983_BUFIOEN_MASK 0x0004 /* BUFIOEN */ 117 + #define WM8983_BUFIOEN_SHIFT 2 /* BUFIOEN */ 118 + #define WM8983_BUFIOEN_WIDTH 1 /* BUFIOEN */ 119 + #define WM8983_VMIDSEL_MASK 0x0003 /* VMIDSEL - [1:0] */ 120 + #define WM8983_VMIDSEL_SHIFT 0 /* VMIDSEL - [1:0] */ 121 + #define WM8983_VMIDSEL_WIDTH 2 /* VMIDSEL - [1:0] */ 122 + 123 + /* 124 + * R2 (0x02) - Power management 2 125 + */ 126 + #define WM8983_ROUT1EN 0x0100 /* ROUT1EN */ 127 + #define WM8983_ROUT1EN_MASK 0x0100 /* ROUT1EN */ 128 + #define WM8983_ROUT1EN_SHIFT 8 /* ROUT1EN */ 129 + #define WM8983_ROUT1EN_WIDTH 1 /* ROUT1EN */ 130 + #define WM8983_LOUT1EN 0x0080 /* LOUT1EN */ 131 + #define WM8983_LOUT1EN_MASK 0x0080 /* LOUT1EN */ 132 + #define WM8983_LOUT1EN_SHIFT 7 /* LOUT1EN */ 133 + #define WM8983_LOUT1EN_WIDTH 1 /* LOUT1EN */ 134 + #define WM8983_SLEEP 0x0040 /* SLEEP */ 135 + #define WM8983_SLEEP_MASK 0x0040 /* SLEEP */ 136 + #define WM8983_SLEEP_SHIFT 6 /* SLEEP */ 137 + #define WM8983_SLEEP_WIDTH 1 /* SLEEP */ 138 + #define WM8983_BOOSTENR 0x0020 /* BOOSTENR */ 139 + #define WM8983_BOOSTENR_MASK 0x0020 /* BOOSTENR */ 140 + #define WM8983_BOOSTENR_SHIFT 5 /* BOOSTENR */ 141 + #define WM8983_BOOSTENR_WIDTH 1 /* BOOSTENR */ 142 + #define WM8983_BOOSTENL 0x0010 /* BOOSTENL */ 143 + #define WM8983_BOOSTENL_MASK 0x0010 /* BOOSTENL */ 144 + #define WM8983_BOOSTENL_SHIFT 4 /* BOOSTENL */ 145 + #define WM8983_BOOSTENL_WIDTH 1 /* BOOSTENL */ 146 + #define WM8983_INPGAENR 0x0008 /* INPGAENR */ 147 + #define WM8983_INPGAENR_MASK 0x0008 /* INPGAENR */ 148 + #define WM8983_INPGAENR_SHIFT 3 /* INPGAENR */ 149 + #define WM8983_INPGAENR_WIDTH 1 /* INPGAENR */ 150 + #define WM8983_INPPGAENL 0x0004 /* INPPGAENL */ 151 + #define WM8983_INPPGAENL_MASK 0x0004 /* INPPGAENL */ 152 + #define WM8983_INPPGAENL_SHIFT 2 /* INPPGAENL */ 153 + #define WM8983_INPPGAENL_WIDTH 1 /* INPPGAENL */ 154 + #define WM8983_ADCENR 0x0002 /* ADCENR */ 155 + #define WM8983_ADCENR_MASK 0x0002 /* ADCENR */ 156 + #define WM8983_ADCENR_SHIFT 1 /* ADCENR */ 157 + #define WM8983_ADCENR_WIDTH 1 /* ADCENR */ 158 + #define WM8983_ADCENL 0x0001 /* ADCENL */ 159 + #define WM8983_ADCENL_MASK 0x0001 /* ADCENL */ 160 + #define WM8983_ADCENL_SHIFT 0 /* ADCENL */ 161 + #define WM8983_ADCENL_WIDTH 1 /* ADCENL */ 162 + 163 + /* 164 + * R3 (0x03) - Power management 3 165 + */ 166 + #define WM8983_OUT4EN 0x0100 /* OUT4EN */ 167 + #define WM8983_OUT4EN_MASK 0x0100 /* OUT4EN */ 168 + #define WM8983_OUT4EN_SHIFT 8 /* OUT4EN */ 169 + #define WM8983_OUT4EN_WIDTH 1 /* OUT4EN */ 170 + #define WM8983_OUT3EN 0x0080 /* OUT3EN */ 171 + #define WM8983_OUT3EN_MASK 0x0080 /* OUT3EN */ 172 + #define WM8983_OUT3EN_SHIFT 7 /* OUT3EN */ 173 + #define WM8983_OUT3EN_WIDTH 1 /* OUT3EN */ 174 + #define WM8983_LOUT2EN 0x0040 /* LOUT2EN */ 175 + #define WM8983_LOUT2EN_MASK 0x0040 /* LOUT2EN */ 176 + #define WM8983_LOUT2EN_SHIFT 6 /* LOUT2EN */ 177 + #define WM8983_LOUT2EN_WIDTH 1 /* LOUT2EN */ 178 + #define WM8983_ROUT2EN 0x0020 /* ROUT2EN */ 179 + #define WM8983_ROUT2EN_MASK 0x0020 /* ROUT2EN */ 180 + #define WM8983_ROUT2EN_SHIFT 5 /* ROUT2EN */ 181 + #define WM8983_ROUT2EN_WIDTH 1 /* ROUT2EN */ 182 + #define WM8983_RMIXEN 0x0008 /* RMIXEN */ 183 + #define WM8983_RMIXEN_MASK 0x0008 /* RMIXEN */ 184 + #define WM8983_RMIXEN_SHIFT 3 /* RMIXEN */ 185 + #define WM8983_RMIXEN_WIDTH 1 /* RMIXEN */ 186 + #define WM8983_LMIXEN 0x0004 /* LMIXEN */ 187 + #define WM8983_LMIXEN_MASK 0x0004 /* LMIXEN */ 188 + #define WM8983_LMIXEN_SHIFT 2 /* LMIXEN */ 189 + #define WM8983_LMIXEN_WIDTH 1 /* LMIXEN */ 190 + #define WM8983_DACENR 0x0002 /* DACENR */ 191 + #define WM8983_DACENR_MASK 0x0002 /* DACENR */ 192 + #define WM8983_DACENR_SHIFT 1 /* DACENR */ 193 + #define WM8983_DACENR_WIDTH 1 /* DACENR */ 194 + #define WM8983_DACENL 0x0001 /* DACENL */ 195 + #define WM8983_DACENL_MASK 0x0001 /* DACENL */ 196 + #define WM8983_DACENL_SHIFT 0 /* DACENL */ 197 + #define WM8983_DACENL_WIDTH 1 /* DACENL */ 198 + 199 + /* 200 + * R4 (0x04) - Audio Interface 201 + */ 202 + #define WM8983_BCP 0x0100 /* BCP */ 203 + #define WM8983_BCP_MASK 0x0100 /* BCP */ 204 + #define WM8983_BCP_SHIFT 8 /* BCP */ 205 + #define WM8983_BCP_WIDTH 1 /* BCP */ 206 + #define WM8983_LRCP 0x0080 /* LRCP */ 207 + #define WM8983_LRCP_MASK 0x0080 /* LRCP */ 208 + #define WM8983_LRCP_SHIFT 7 /* LRCP */ 209 + #define WM8983_LRCP_WIDTH 1 /* LRCP */ 210 + #define WM8983_WL_MASK 0x0060 /* WL - [6:5] */ 211 + #define WM8983_WL_SHIFT 5 /* WL - [6:5] */ 212 + #define WM8983_WL_WIDTH 2 /* WL - [6:5] */ 213 + #define WM8983_FMT_MASK 0x0018 /* FMT - [4:3] */ 214 + #define WM8983_FMT_SHIFT 3 /* FMT - [4:3] */ 215 + #define WM8983_FMT_WIDTH 2 /* FMT - [4:3] */ 216 + #define WM8983_DLRSWAP 0x0004 /* DLRSWAP */ 217 + #define WM8983_DLRSWAP_MASK 0x0004 /* DLRSWAP */ 218 + #define WM8983_DLRSWAP_SHIFT 2 /* DLRSWAP */ 219 + #define WM8983_DLRSWAP_WIDTH 1 /* DLRSWAP */ 220 + #define WM8983_ALRSWAP 0x0002 /* ALRSWAP */ 221 + #define WM8983_ALRSWAP_MASK 0x0002 /* ALRSWAP */ 222 + #define WM8983_ALRSWAP_SHIFT 1 /* ALRSWAP */ 223 + #define WM8983_ALRSWAP_WIDTH 1 /* ALRSWAP */ 224 + #define WM8983_MONO 0x0001 /* MONO */ 225 + #define WM8983_MONO_MASK 0x0001 /* MONO */ 226 + #define WM8983_MONO_SHIFT 0 /* MONO */ 227 + #define WM8983_MONO_WIDTH 1 /* MONO */ 228 + 229 + /* 230 + * R5 (0x05) - Companding control 231 + */ 232 + #define WM8983_WL8 0x0020 /* WL8 */ 233 + #define WM8983_WL8_MASK 0x0020 /* WL8 */ 234 + #define WM8983_WL8_SHIFT 5 /* WL8 */ 235 + #define WM8983_WL8_WIDTH 1 /* WL8 */ 236 + #define WM8983_DAC_COMP_MASK 0x0018 /* DAC_COMP - [4:3] */ 237 + #define WM8983_DAC_COMP_SHIFT 3 /* DAC_COMP - [4:3] */ 238 + #define WM8983_DAC_COMP_WIDTH 2 /* DAC_COMP - [4:3] */ 239 + #define WM8983_ADC_COMP_MASK 0x0006 /* ADC_COMP - [2:1] */ 240 + #define WM8983_ADC_COMP_SHIFT 1 /* ADC_COMP - [2:1] */ 241 + #define WM8983_ADC_COMP_WIDTH 2 /* ADC_COMP - [2:1] */ 242 + #define WM8983_LOOPBACK 0x0001 /* LOOPBACK */ 243 + #define WM8983_LOOPBACK_MASK 0x0001 /* LOOPBACK */ 244 + #define WM8983_LOOPBACK_SHIFT 0 /* LOOPBACK */ 245 + #define WM8983_LOOPBACK_WIDTH 1 /* LOOPBACK */ 246 + 247 + /* 248 + * R6 (0x06) - Clock Gen control 249 + */ 250 + #define WM8983_CLKSEL 0x0100 /* CLKSEL */ 251 + #define WM8983_CLKSEL_MASK 0x0100 /* CLKSEL */ 252 + #define WM8983_CLKSEL_SHIFT 8 /* CLKSEL */ 253 + #define WM8983_CLKSEL_WIDTH 1 /* CLKSEL */ 254 + #define WM8983_MCLKDIV_MASK 0x00E0 /* MCLKDIV - [7:5] */ 255 + #define WM8983_MCLKDIV_SHIFT 5 /* MCLKDIV - [7:5] */ 256 + #define WM8983_MCLKDIV_WIDTH 3 /* MCLKDIV - [7:5] */ 257 + #define WM8983_BCLKDIV_MASK 0x001C /* BCLKDIV - [4:2] */ 258 + #define WM8983_BCLKDIV_SHIFT 2 /* BCLKDIV - [4:2] */ 259 + #define WM8983_BCLKDIV_WIDTH 3 /* BCLKDIV - [4:2] */ 260 + #define WM8983_MS 0x0001 /* MS */ 261 + #define WM8983_MS_MASK 0x0001 /* MS */ 262 + #define WM8983_MS_SHIFT 0 /* MS */ 263 + #define WM8983_MS_WIDTH 1 /* MS */ 264 + 265 + /* 266 + * R7 (0x07) - Additional control 267 + */ 268 + #define WM8983_SR_MASK 0x000E /* SR - [3:1] */ 269 + #define WM8983_SR_SHIFT 1 /* SR - [3:1] */ 270 + #define WM8983_SR_WIDTH 3 /* SR - [3:1] */ 271 + #define WM8983_SLOWCLKEN 0x0001 /* SLOWCLKEN */ 272 + #define WM8983_SLOWCLKEN_MASK 0x0001 /* SLOWCLKEN */ 273 + #define WM8983_SLOWCLKEN_SHIFT 0 /* SLOWCLKEN */ 274 + #define WM8983_SLOWCLKEN_WIDTH 1 /* SLOWCLKEN */ 275 + 276 + /* 277 + * R8 (0x08) - GPIO Control 278 + */ 279 + #define WM8983_OPCLKDIV_MASK 0x0030 /* OPCLKDIV - [5:4] */ 280 + #define WM8983_OPCLKDIV_SHIFT 4 /* OPCLKDIV - [5:4] */ 281 + #define WM8983_OPCLKDIV_WIDTH 2 /* OPCLKDIV - [5:4] */ 282 + #define WM8983_GPIO1POL 0x0008 /* GPIO1POL */ 283 + #define WM8983_GPIO1POL_MASK 0x0008 /* GPIO1POL */ 284 + #define WM8983_GPIO1POL_SHIFT 3 /* GPIO1POL */ 285 + #define WM8983_GPIO1POL_WIDTH 1 /* GPIO1POL */ 286 + #define WM8983_GPIO1SEL_MASK 0x0007 /* GPIO1SEL - [2:0] */ 287 + #define WM8983_GPIO1SEL_SHIFT 0 /* GPIO1SEL - [2:0] */ 288 + #define WM8983_GPIO1SEL_WIDTH 3 /* GPIO1SEL - [2:0] */ 289 + 290 + /* 291 + * R9 (0x09) - Jack Detect Control 1 292 + */ 293 + #define WM8983_JD_VMID1 0x0100 /* JD_VMID1 */ 294 + #define WM8983_JD_VMID1_MASK 0x0100 /* JD_VMID1 */ 295 + #define WM8983_JD_VMID1_SHIFT 8 /* JD_VMID1 */ 296 + #define WM8983_JD_VMID1_WIDTH 1 /* JD_VMID1 */ 297 + #define WM8983_JD_VMID0 0x0080 /* JD_VMID0 */ 298 + #define WM8983_JD_VMID0_MASK 0x0080 /* JD_VMID0 */ 299 + #define WM8983_JD_VMID0_SHIFT 7 /* JD_VMID0 */ 300 + #define WM8983_JD_VMID0_WIDTH 1 /* JD_VMID0 */ 301 + #define WM8983_JD_EN 0x0040 /* JD_EN */ 302 + #define WM8983_JD_EN_MASK 0x0040 /* JD_EN */ 303 + #define WM8983_JD_EN_SHIFT 6 /* JD_EN */ 304 + #define WM8983_JD_EN_WIDTH 1 /* JD_EN */ 305 + #define WM8983_JD_SEL_MASK 0x0030 /* JD_SEL - [5:4] */ 306 + #define WM8983_JD_SEL_SHIFT 4 /* JD_SEL - [5:4] */ 307 + #define WM8983_JD_SEL_WIDTH 2 /* JD_SEL - [5:4] */ 308 + 309 + /* 310 + * R10 (0x0A) - DAC Control 311 + */ 312 + #define WM8983_SOFTMUTE 0x0040 /* SOFTMUTE */ 313 + #define WM8983_SOFTMUTE_MASK 0x0040 /* SOFTMUTE */ 314 + #define WM8983_SOFTMUTE_SHIFT 6 /* SOFTMUTE */ 315 + #define WM8983_SOFTMUTE_WIDTH 1 /* SOFTMUTE */ 316 + #define WM8983_DACOSR128 0x0008 /* DACOSR128 */ 317 + #define WM8983_DACOSR128_MASK 0x0008 /* DACOSR128 */ 318 + #define WM8983_DACOSR128_SHIFT 3 /* DACOSR128 */ 319 + #define WM8983_DACOSR128_WIDTH 1 /* DACOSR128 */ 320 + #define WM8983_AMUTE 0x0004 /* AMUTE */ 321 + #define WM8983_AMUTE_MASK 0x0004 /* AMUTE */ 322 + #define WM8983_AMUTE_SHIFT 2 /* AMUTE */ 323 + #define WM8983_AMUTE_WIDTH 1 /* AMUTE */ 324 + #define WM8983_DACRPOL 0x0002 /* DACRPOL */ 325 + #define WM8983_DACRPOL_MASK 0x0002 /* DACRPOL */ 326 + #define WM8983_DACRPOL_SHIFT 1 /* DACRPOL */ 327 + #define WM8983_DACRPOL_WIDTH 1 /* DACRPOL */ 328 + #define WM8983_DACLPOL 0x0001 /* DACLPOL */ 329 + #define WM8983_DACLPOL_MASK 0x0001 /* DACLPOL */ 330 + #define WM8983_DACLPOL_SHIFT 0 /* DACLPOL */ 331 + #define WM8983_DACLPOL_WIDTH 1 /* DACLPOL */ 332 + 333 + /* 334 + * R11 (0x0B) - Left DAC digital Vol 335 + */ 336 + #define WM8983_DACVU 0x0100 /* DACVU */ 337 + #define WM8983_DACVU_MASK 0x0100 /* DACVU */ 338 + #define WM8983_DACVU_SHIFT 8 /* DACVU */ 339 + #define WM8983_DACVU_WIDTH 1 /* DACVU */ 340 + #define WM8983_DACLVOL_MASK 0x00FF /* DACLVOL - [7:0] */ 341 + #define WM8983_DACLVOL_SHIFT 0 /* DACLVOL - [7:0] */ 342 + #define WM8983_DACLVOL_WIDTH 8 /* DACLVOL - [7:0] */ 343 + 344 + /* 345 + * R12 (0x0C) - Right DAC digital vol 346 + */ 347 + #define WM8983_DACVU 0x0100 /* DACVU */ 348 + #define WM8983_DACVU_MASK 0x0100 /* DACVU */ 349 + #define WM8983_DACVU_SHIFT 8 /* DACVU */ 350 + #define WM8983_DACVU_WIDTH 1 /* DACVU */ 351 + #define WM8983_DACRVOL_MASK 0x00FF /* DACRVOL - [7:0] */ 352 + #define WM8983_DACRVOL_SHIFT 0 /* DACRVOL - [7:0] */ 353 + #define WM8983_DACRVOL_WIDTH 8 /* DACRVOL - [7:0] */ 354 + 355 + /* 356 + * R13 (0x0D) - Jack Detect Control 2 357 + */ 358 + #define WM8983_JD_EN1_MASK 0x00F0 /* JD_EN1 - [7:4] */ 359 + #define WM8983_JD_EN1_SHIFT 4 /* JD_EN1 - [7:4] */ 360 + #define WM8983_JD_EN1_WIDTH 4 /* JD_EN1 - [7:4] */ 361 + #define WM8983_JD_EN0_MASK 0x000F /* JD_EN0 - [3:0] */ 362 + #define WM8983_JD_EN0_SHIFT 0 /* JD_EN0 - [3:0] */ 363 + #define WM8983_JD_EN0_WIDTH 4 /* JD_EN0 - [3:0] */ 364 + 365 + /* 366 + * R14 (0x0E) - ADC Control 367 + */ 368 + #define WM8983_HPFEN 0x0100 /* HPFEN */ 369 + #define WM8983_HPFEN_MASK 0x0100 /* HPFEN */ 370 + #define WM8983_HPFEN_SHIFT 8 /* HPFEN */ 371 + #define WM8983_HPFEN_WIDTH 1 /* HPFEN */ 372 + #define WM8983_HPFAPP 0x0080 /* HPFAPP */ 373 + #define WM8983_HPFAPP_MASK 0x0080 /* HPFAPP */ 374 + #define WM8983_HPFAPP_SHIFT 7 /* HPFAPP */ 375 + #define WM8983_HPFAPP_WIDTH 1 /* HPFAPP */ 376 + #define WM8983_HPFCUT_MASK 0x0070 /* HPFCUT - [6:4] */ 377 + #define WM8983_HPFCUT_SHIFT 4 /* HPFCUT - [6:4] */ 378 + #define WM8983_HPFCUT_WIDTH 3 /* HPFCUT - [6:4] */ 379 + #define WM8983_ADCOSR128 0x0008 /* ADCOSR128 */ 380 + #define WM8983_ADCOSR128_MASK 0x0008 /* ADCOSR128 */ 381 + #define WM8983_ADCOSR128_SHIFT 3 /* ADCOSR128 */ 382 + #define WM8983_ADCOSR128_WIDTH 1 /* ADCOSR128 */ 383 + #define WM8983_ADCRPOL 0x0002 /* ADCRPOL */ 384 + #define WM8983_ADCRPOL_MASK 0x0002 /* ADCRPOL */ 385 + #define WM8983_ADCRPOL_SHIFT 1 /* ADCRPOL */ 386 + #define WM8983_ADCRPOL_WIDTH 1 /* ADCRPOL */ 387 + #define WM8983_ADCLPOL 0x0001 /* ADCLPOL */ 388 + #define WM8983_ADCLPOL_MASK 0x0001 /* ADCLPOL */ 389 + #define WM8983_ADCLPOL_SHIFT 0 /* ADCLPOL */ 390 + #define WM8983_ADCLPOL_WIDTH 1 /* ADCLPOL */ 391 + 392 + /* 393 + * R15 (0x0F) - Left ADC Digital Vol 394 + */ 395 + #define WM8983_ADCVU 0x0100 /* ADCVU */ 396 + #define WM8983_ADCVU_MASK 0x0100 /* ADCVU */ 397 + #define WM8983_ADCVU_SHIFT 8 /* ADCVU */ 398 + #define WM8983_ADCVU_WIDTH 1 /* ADCVU */ 399 + #define WM8983_ADCLVOL_MASK 0x00FF /* ADCLVOL - [7:0] */ 400 + #define WM8983_ADCLVOL_SHIFT 0 /* ADCLVOL - [7:0] */ 401 + #define WM8983_ADCLVOL_WIDTH 8 /* ADCLVOL - [7:0] */ 402 + 403 + /* 404 + * R16 (0x10) - Right ADC Digital Vol 405 + */ 406 + #define WM8983_ADCVU 0x0100 /* ADCVU */ 407 + #define WM8983_ADCVU_MASK 0x0100 /* ADCVU */ 408 + #define WM8983_ADCVU_SHIFT 8 /* ADCVU */ 409 + #define WM8983_ADCVU_WIDTH 1 /* ADCVU */ 410 + #define WM8983_ADCRVOL_MASK 0x00FF /* ADCRVOL - [7:0] */ 411 + #define WM8983_ADCRVOL_SHIFT 0 /* ADCRVOL - [7:0] */ 412 + #define WM8983_ADCRVOL_WIDTH 8 /* ADCRVOL - [7:0] */ 413 + 414 + /* 415 + * R18 (0x12) - EQ1 - low shelf 416 + */ 417 + #define WM8983_EQ3DMODE 0x0100 /* EQ3DMODE */ 418 + #define WM8983_EQ3DMODE_MASK 0x0100 /* EQ3DMODE */ 419 + #define WM8983_EQ3DMODE_SHIFT 8 /* EQ3DMODE */ 420 + #define WM8983_EQ3DMODE_WIDTH 1 /* EQ3DMODE */ 421 + #define WM8983_EQ1C_MASK 0x0060 /* EQ1C - [6:5] */ 422 + #define WM8983_EQ1C_SHIFT 5 /* EQ1C - [6:5] */ 423 + #define WM8983_EQ1C_WIDTH 2 /* EQ1C - [6:5] */ 424 + #define WM8983_EQ1G_MASK 0x001F /* EQ1G - [4:0] */ 425 + #define WM8983_EQ1G_SHIFT 0 /* EQ1G - [4:0] */ 426 + #define WM8983_EQ1G_WIDTH 5 /* EQ1G - [4:0] */ 427 + 428 + /* 429 + * R19 (0x13) - EQ2 - peak 1 430 + */ 431 + #define WM8983_EQ2BW 0x0100 /* EQ2BW */ 432 + #define WM8983_EQ2BW_MASK 0x0100 /* EQ2BW */ 433 + #define WM8983_EQ2BW_SHIFT 8 /* EQ2BW */ 434 + #define WM8983_EQ2BW_WIDTH 1 /* EQ2BW */ 435 + #define WM8983_EQ2C_MASK 0x0060 /* EQ2C - [6:5] */ 436 + #define WM8983_EQ2C_SHIFT 5 /* EQ2C - [6:5] */ 437 + #define WM8983_EQ2C_WIDTH 2 /* EQ2C - [6:5] */ 438 + #define WM8983_EQ2G_MASK 0x001F /* EQ2G - [4:0] */ 439 + #define WM8983_EQ2G_SHIFT 0 /* EQ2G - [4:0] */ 440 + #define WM8983_EQ2G_WIDTH 5 /* EQ2G - [4:0] */ 441 + 442 + /* 443 + * R20 (0x14) - EQ3 - peak 2 444 + */ 445 + #define WM8983_EQ3BW 0x0100 /* EQ3BW */ 446 + #define WM8983_EQ3BW_MASK 0x0100 /* EQ3BW */ 447 + #define WM8983_EQ3BW_SHIFT 8 /* EQ3BW */ 448 + #define WM8983_EQ3BW_WIDTH 1 /* EQ3BW */ 449 + #define WM8983_EQ3C_MASK 0x0060 /* EQ3C - [6:5] */ 450 + #define WM8983_EQ3C_SHIFT 5 /* EQ3C - [6:5] */ 451 + #define WM8983_EQ3C_WIDTH 2 /* EQ3C - [6:5] */ 452 + #define WM8983_EQ3G_MASK 0x001F /* EQ3G - [4:0] */ 453 + #define WM8983_EQ3G_SHIFT 0 /* EQ3G - [4:0] */ 454 + #define WM8983_EQ3G_WIDTH 5 /* EQ3G - [4:0] */ 455 + 456 + /* 457 + * R21 (0x15) - EQ4 - peak 3 458 + */ 459 + #define WM8983_EQ4BW 0x0100 /* EQ4BW */ 460 + #define WM8983_EQ4BW_MASK 0x0100 /* EQ4BW */ 461 + #define WM8983_EQ4BW_SHIFT 8 /* EQ4BW */ 462 + #define WM8983_EQ4BW_WIDTH 1 /* EQ4BW */ 463 + #define WM8983_EQ4C_MASK 0x0060 /* EQ4C - [6:5] */ 464 + #define WM8983_EQ4C_SHIFT 5 /* EQ4C - [6:5] */ 465 + #define WM8983_EQ4C_WIDTH 2 /* EQ4C - [6:5] */ 466 + #define WM8983_EQ4G_MASK 0x001F /* EQ4G - [4:0] */ 467 + #define WM8983_EQ4G_SHIFT 0 /* EQ4G - [4:0] */ 468 + #define WM8983_EQ4G_WIDTH 5 /* EQ4G - [4:0] */ 469 + 470 + /* 471 + * R22 (0x16) - EQ5 - high shelf 472 + */ 473 + #define WM8983_EQ5C_MASK 0x0060 /* EQ5C - [6:5] */ 474 + #define WM8983_EQ5C_SHIFT 5 /* EQ5C - [6:5] */ 475 + #define WM8983_EQ5C_WIDTH 2 /* EQ5C - [6:5] */ 476 + #define WM8983_EQ5G_MASK 0x001F /* EQ5G - [4:0] */ 477 + #define WM8983_EQ5G_SHIFT 0 /* EQ5G - [4:0] */ 478 + #define WM8983_EQ5G_WIDTH 5 /* EQ5G - [4:0] */ 479 + 480 + /* 481 + * R24 (0x18) - DAC Limiter 1 482 + */ 483 + #define WM8983_LIMEN 0x0100 /* LIMEN */ 484 + #define WM8983_LIMEN_MASK 0x0100 /* LIMEN */ 485 + #define WM8983_LIMEN_SHIFT 8 /* LIMEN */ 486 + #define WM8983_LIMEN_WIDTH 1 /* LIMEN */ 487 + #define WM8983_LIMDCY_MASK 0x00F0 /* LIMDCY - [7:4] */ 488 + #define WM8983_LIMDCY_SHIFT 4 /* LIMDCY - [7:4] */ 489 + #define WM8983_LIMDCY_WIDTH 4 /* LIMDCY - [7:4] */ 490 + #define WM8983_LIMATK_MASK 0x000F /* LIMATK - [3:0] */ 491 + #define WM8983_LIMATK_SHIFT 0 /* LIMATK - [3:0] */ 492 + #define WM8983_LIMATK_WIDTH 4 /* LIMATK - [3:0] */ 493 + 494 + /* 495 + * R25 (0x19) - DAC Limiter 2 496 + */ 497 + #define WM8983_LIMLVL_MASK 0x0070 /* LIMLVL - [6:4] */ 498 + #define WM8983_LIMLVL_SHIFT 4 /* LIMLVL - [6:4] */ 499 + #define WM8983_LIMLVL_WIDTH 3 /* LIMLVL - [6:4] */ 500 + #define WM8983_LIMBOOST_MASK 0x000F /* LIMBOOST - [3:0] */ 501 + #define WM8983_LIMBOOST_SHIFT 0 /* LIMBOOST - [3:0] */ 502 + #define WM8983_LIMBOOST_WIDTH 4 /* LIMBOOST - [3:0] */ 503 + 504 + /* 505 + * R27 (0x1B) - Notch Filter 1 506 + */ 507 + #define WM8983_NFU 0x0100 /* NFU */ 508 + #define WM8983_NFU_MASK 0x0100 /* NFU */ 509 + #define WM8983_NFU_SHIFT 8 /* NFU */ 510 + #define WM8983_NFU_WIDTH 1 /* NFU */ 511 + #define WM8983_NFEN 0x0080 /* NFEN */ 512 + #define WM8983_NFEN_MASK 0x0080 /* NFEN */ 513 + #define WM8983_NFEN_SHIFT 7 /* NFEN */ 514 + #define WM8983_NFEN_WIDTH 1 /* NFEN */ 515 + #define WM8983_NFA0_13_7_MASK 0x007F /* NFA0(13:7) - [6:0] */ 516 + #define WM8983_NFA0_13_7_SHIFT 0 /* NFA0(13:7) - [6:0] */ 517 + #define WM8983_NFA0_13_7_WIDTH 7 /* NFA0(13:7) - [6:0] */ 518 + 519 + /* 520 + * R28 (0x1C) - Notch Filter 2 521 + */ 522 + #define WM8983_NFU 0x0100 /* NFU */ 523 + #define WM8983_NFU_MASK 0x0100 /* NFU */ 524 + #define WM8983_NFU_SHIFT 8 /* NFU */ 525 + #define WM8983_NFU_WIDTH 1 /* NFU */ 526 + #define WM8983_NFA0_6_0_MASK 0x007F /* NFA0(6:0) - [6:0] */ 527 + #define WM8983_NFA0_6_0_SHIFT 0 /* NFA0(6:0) - [6:0] */ 528 + #define WM8983_NFA0_6_0_WIDTH 7 /* NFA0(6:0) - [6:0] */ 529 + 530 + /* 531 + * R29 (0x1D) - Notch Filter 3 532 + */ 533 + #define WM8983_NFU 0x0100 /* NFU */ 534 + #define WM8983_NFU_MASK 0x0100 /* NFU */ 535 + #define WM8983_NFU_SHIFT 8 /* NFU */ 536 + #define WM8983_NFU_WIDTH 1 /* NFU */ 537 + #define WM8983_NFA1_13_7_MASK 0x007F /* NFA1(13:7) - [6:0] */ 538 + #define WM8983_NFA1_13_7_SHIFT 0 /* NFA1(13:7) - [6:0] */ 539 + #define WM8983_NFA1_13_7_WIDTH 7 /* NFA1(13:7) - [6:0] */ 540 + 541 + /* 542 + * R30 (0x1E) - Notch Filter 4 543 + */ 544 + #define WM8983_NFU 0x0100 /* NFU */ 545 + #define WM8983_NFU_MASK 0x0100 /* NFU */ 546 + #define WM8983_NFU_SHIFT 8 /* NFU */ 547 + #define WM8983_NFU_WIDTH 1 /* NFU */ 548 + #define WM8983_NFA1_6_0_MASK 0x007F /* NFA1(6:0) - [6:0] */ 549 + #define WM8983_NFA1_6_0_SHIFT 0 /* NFA1(6:0) - [6:0] */ 550 + #define WM8983_NFA1_6_0_WIDTH 7 /* NFA1(6:0) - [6:0] */ 551 + 552 + /* 553 + * R32 (0x20) - ALC control 1 554 + */ 555 + #define WM8983_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */ 556 + #define WM8983_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */ 557 + #define WM8983_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */ 558 + #define WM8983_ALCMAX_MASK 0x0038 /* ALCMAX - [5:3] */ 559 + #define WM8983_ALCMAX_SHIFT 3 /* ALCMAX - [5:3] */ 560 + #define WM8983_ALCMAX_WIDTH 3 /* ALCMAX - [5:3] */ 561 + #define WM8983_ALCMIN_MASK 0x0007 /* ALCMIN - [2:0] */ 562 + #define WM8983_ALCMIN_SHIFT 0 /* ALCMIN - [2:0] */ 563 + #define WM8983_ALCMIN_WIDTH 3 /* ALCMIN - [2:0] */ 564 + 565 + /* 566 + * R33 (0x21) - ALC control 2 567 + */ 568 + #define WM8983_ALCHLD_MASK 0x00F0 /* ALCHLD - [7:4] */ 569 + #define WM8983_ALCHLD_SHIFT 4 /* ALCHLD - [7:4] */ 570 + #define WM8983_ALCHLD_WIDTH 4 /* ALCHLD - [7:4] */ 571 + #define WM8983_ALCLVL_MASK 0x000F /* ALCLVL - [3:0] */ 572 + #define WM8983_ALCLVL_SHIFT 0 /* ALCLVL - [3:0] */ 573 + #define WM8983_ALCLVL_WIDTH 4 /* ALCLVL - [3:0] */ 574 + 575 + /* 576 + * R34 (0x22) - ALC control 3 577 + */ 578 + #define WM8983_ALCMODE 0x0100 /* ALCMODE */ 579 + #define WM8983_ALCMODE_MASK 0x0100 /* ALCMODE */ 580 + #define WM8983_ALCMODE_SHIFT 8 /* ALCMODE */ 581 + #define WM8983_ALCMODE_WIDTH 1 /* ALCMODE */ 582 + #define WM8983_ALCDCY_MASK 0x00F0 /* ALCDCY - [7:4] */ 583 + #define WM8983_ALCDCY_SHIFT 4 /* ALCDCY - [7:4] */ 584 + #define WM8983_ALCDCY_WIDTH 4 /* ALCDCY - [7:4] */ 585 + #define WM8983_ALCATK_MASK 0x000F /* ALCATK - [3:0] */ 586 + #define WM8983_ALCATK_SHIFT 0 /* ALCATK - [3:0] */ 587 + #define WM8983_ALCATK_WIDTH 4 /* ALCATK - [3:0] */ 588 + 589 + /* 590 + * R35 (0x23) - Noise Gate 591 + */ 592 + #define WM8983_NGEN 0x0008 /* NGEN */ 593 + #define WM8983_NGEN_MASK 0x0008 /* NGEN */ 594 + #define WM8983_NGEN_SHIFT 3 /* NGEN */ 595 + #define WM8983_NGEN_WIDTH 1 /* NGEN */ 596 + #define WM8983_NGTH_MASK 0x0007 /* NGTH - [2:0] */ 597 + #define WM8983_NGTH_SHIFT 0 /* NGTH - [2:0] */ 598 + #define WM8983_NGTH_WIDTH 3 /* NGTH - [2:0] */ 599 + 600 + /* 601 + * R36 (0x24) - PLL N 602 + */ 603 + #define WM8983_PLL_PRESCALE 0x0010 /* PLL_PRESCALE */ 604 + #define WM8983_PLL_PRESCALE_MASK 0x0010 /* PLL_PRESCALE */ 605 + #define WM8983_PLL_PRESCALE_SHIFT 4 /* PLL_PRESCALE */ 606 + #define WM8983_PLL_PRESCALE_WIDTH 1 /* PLL_PRESCALE */ 607 + #define WM8983_PLLN_MASK 0x000F /* PLLN - [3:0] */ 608 + #define WM8983_PLLN_SHIFT 0 /* PLLN - [3:0] */ 609 + #define WM8983_PLLN_WIDTH 4 /* PLLN - [3:0] */ 610 + 611 + /* 612 + * R37 (0x25) - PLL K 1 613 + */ 614 + #define WM8983_PLLK_23_18_MASK 0x003F /* PLLK(23:18) - [5:0] */ 615 + #define WM8983_PLLK_23_18_SHIFT 0 /* PLLK(23:18) - [5:0] */ 616 + #define WM8983_PLLK_23_18_WIDTH 6 /* PLLK(23:18) - [5:0] */ 617 + 618 + /* 619 + * R38 (0x26) - PLL K 2 620 + */ 621 + #define WM8983_PLLK_17_9_MASK 0x01FF /* PLLK(17:9) - [8:0] */ 622 + #define WM8983_PLLK_17_9_SHIFT 0 /* PLLK(17:9) - [8:0] */ 623 + #define WM8983_PLLK_17_9_WIDTH 9 /* PLLK(17:9) - [8:0] */ 624 + 625 + /* 626 + * R39 (0x27) - PLL K 3 627 + */ 628 + #define WM8983_PLLK_8_0_MASK 0x01FF /* PLLK(8:0) - [8:0] */ 629 + #define WM8983_PLLK_8_0_SHIFT 0 /* PLLK(8:0) - [8:0] */ 630 + #define WM8983_PLLK_8_0_WIDTH 9 /* PLLK(8:0) - [8:0] */ 631 + 632 + /* 633 + * R41 (0x29) - 3D control 634 + */ 635 + #define WM8983_DEPTH3D_MASK 0x000F /* DEPTH3D - [3:0] */ 636 + #define WM8983_DEPTH3D_SHIFT 0 /* DEPTH3D - [3:0] */ 637 + #define WM8983_DEPTH3D_WIDTH 4 /* DEPTH3D - [3:0] */ 638 + 639 + /* 640 + * R42 (0x2A) - OUT4 to ADC 641 + */ 642 + #define WM8983_OUT4_2ADCVOL_MASK 0x01C0 /* OUT4_2ADCVOL - [8:6] */ 643 + #define WM8983_OUT4_2ADCVOL_SHIFT 6 /* OUT4_2ADCVOL - [8:6] */ 644 + #define WM8983_OUT4_2ADCVOL_WIDTH 3 /* OUT4_2ADCVOL - [8:6] */ 645 + #define WM8983_OUT4_2LNR 0x0020 /* OUT4_2LNR */ 646 + #define WM8983_OUT4_2LNR_MASK 0x0020 /* OUT4_2LNR */ 647 + #define WM8983_OUT4_2LNR_SHIFT 5 /* OUT4_2LNR */ 648 + #define WM8983_OUT4_2LNR_WIDTH 1 /* OUT4_2LNR */ 649 + #define WM8983_POBCTRL 0x0004 /* POBCTRL */ 650 + #define WM8983_POBCTRL_MASK 0x0004 /* POBCTRL */ 651 + #define WM8983_POBCTRL_SHIFT 2 /* POBCTRL */ 652 + #define WM8983_POBCTRL_WIDTH 1 /* POBCTRL */ 653 + #define WM8983_DELEN 0x0002 /* DELEN */ 654 + #define WM8983_DELEN_MASK 0x0002 /* DELEN */ 655 + #define WM8983_DELEN_SHIFT 1 /* DELEN */ 656 + #define WM8983_DELEN_WIDTH 1 /* DELEN */ 657 + #define WM8983_OUT1DEL 0x0001 /* OUT1DEL */ 658 + #define WM8983_OUT1DEL_MASK 0x0001 /* OUT1DEL */ 659 + #define WM8983_OUT1DEL_SHIFT 0 /* OUT1DEL */ 660 + #define WM8983_OUT1DEL_WIDTH 1 /* OUT1DEL */ 661 + 662 + /* 663 + * R43 (0x2B) - Beep control 664 + */ 665 + #define WM8983_BYPL2RMIX 0x0100 /* BYPL2RMIX */ 666 + #define WM8983_BYPL2RMIX_MASK 0x0100 /* BYPL2RMIX */ 667 + #define WM8983_BYPL2RMIX_SHIFT 8 /* BYPL2RMIX */ 668 + #define WM8983_BYPL2RMIX_WIDTH 1 /* BYPL2RMIX */ 669 + #define WM8983_BYPR2LMIX 0x0080 /* BYPR2LMIX */ 670 + #define WM8983_BYPR2LMIX_MASK 0x0080 /* BYPR2LMIX */ 671 + #define WM8983_BYPR2LMIX_SHIFT 7 /* BYPR2LMIX */ 672 + #define WM8983_BYPR2LMIX_WIDTH 1 /* BYPR2LMIX */ 673 + #define WM8983_MUTERPGA2INV 0x0020 /* MUTERPGA2INV */ 674 + #define WM8983_MUTERPGA2INV_MASK 0x0020 /* MUTERPGA2INV */ 675 + #define WM8983_MUTERPGA2INV_SHIFT 5 /* MUTERPGA2INV */ 676 + #define WM8983_MUTERPGA2INV_WIDTH 1 /* MUTERPGA2INV */ 677 + #define WM8983_INVROUT2 0x0010 /* INVROUT2 */ 678 + #define WM8983_INVROUT2_MASK 0x0010 /* INVROUT2 */ 679 + #define WM8983_INVROUT2_SHIFT 4 /* INVROUT2 */ 680 + #define WM8983_INVROUT2_WIDTH 1 /* INVROUT2 */ 681 + #define WM8983_BEEPVOL_MASK 0x000E /* BEEPVOL - [3:1] */ 682 + #define WM8983_BEEPVOL_SHIFT 1 /* BEEPVOL - [3:1] */ 683 + #define WM8983_BEEPVOL_WIDTH 3 /* BEEPVOL - [3:1] */ 684 + #define WM8983_BEEPEN 0x0001 /* BEEPEN */ 685 + #define WM8983_BEEPEN_MASK 0x0001 /* BEEPEN */ 686 + #define WM8983_BEEPEN_SHIFT 0 /* BEEPEN */ 687 + #define WM8983_BEEPEN_WIDTH 1 /* BEEPEN */ 688 + 689 + /* 690 + * R44 (0x2C) - Input ctrl 691 + */ 692 + #define WM8983_MBVSEL 0x0100 /* MBVSEL */ 693 + #define WM8983_MBVSEL_MASK 0x0100 /* MBVSEL */ 694 + #define WM8983_MBVSEL_SHIFT 8 /* MBVSEL */ 695 + #define WM8983_MBVSEL_WIDTH 1 /* MBVSEL */ 696 + #define WM8983_R2_2INPPGA 0x0040 /* R2_2INPPGA */ 697 + #define WM8983_R2_2INPPGA_MASK 0x0040 /* R2_2INPPGA */ 698 + #define WM8983_R2_2INPPGA_SHIFT 6 /* R2_2INPPGA */ 699 + #define WM8983_R2_2INPPGA_WIDTH 1 /* R2_2INPPGA */ 700 + #define WM8983_RIN2INPPGA 0x0020 /* RIN2INPPGA */ 701 + #define WM8983_RIN2INPPGA_MASK 0x0020 /* RIN2INPPGA */ 702 + #define WM8983_RIN2INPPGA_SHIFT 5 /* RIN2INPPGA */ 703 + #define WM8983_RIN2INPPGA_WIDTH 1 /* RIN2INPPGA */ 704 + #define WM8983_RIP2INPPGA 0x0010 /* RIP2INPPGA */ 705 + #define WM8983_RIP2INPPGA_MASK 0x0010 /* RIP2INPPGA */ 706 + #define WM8983_RIP2INPPGA_SHIFT 4 /* RIP2INPPGA */ 707 + #define WM8983_RIP2INPPGA_WIDTH 1 /* RIP2INPPGA */ 708 + #define WM8983_L2_2INPPGA 0x0004 /* L2_2INPPGA */ 709 + #define WM8983_L2_2INPPGA_MASK 0x0004 /* L2_2INPPGA */ 710 + #define WM8983_L2_2INPPGA_SHIFT 2 /* L2_2INPPGA */ 711 + #define WM8983_L2_2INPPGA_WIDTH 1 /* L2_2INPPGA */ 712 + #define WM8983_LIN2INPPGA 0x0002 /* LIN2INPPGA */ 713 + #define WM8983_LIN2INPPGA_MASK 0x0002 /* LIN2INPPGA */ 714 + #define WM8983_LIN2INPPGA_SHIFT 1 /* LIN2INPPGA */ 715 + #define WM8983_LIN2INPPGA_WIDTH 1 /* LIN2INPPGA */ 716 + #define WM8983_LIP2INPPGA 0x0001 /* LIP2INPPGA */ 717 + #define WM8983_LIP2INPPGA_MASK 0x0001 /* LIP2INPPGA */ 718 + #define WM8983_LIP2INPPGA_SHIFT 0 /* LIP2INPPGA */ 719 + #define WM8983_LIP2INPPGA_WIDTH 1 /* LIP2INPPGA */ 720 + 721 + /* 722 + * R45 (0x2D) - Left INP PGA gain ctrl 723 + */ 724 + #define WM8983_INPGAVU 0x0100 /* INPGAVU */ 725 + #define WM8983_INPGAVU_MASK 0x0100 /* INPGAVU */ 726 + #define WM8983_INPGAVU_SHIFT 8 /* INPGAVU */ 727 + #define WM8983_INPGAVU_WIDTH 1 /* INPGAVU */ 728 + #define WM8983_INPPGAZCL 0x0080 /* INPPGAZCL */ 729 + #define WM8983_INPPGAZCL_MASK 0x0080 /* INPPGAZCL */ 730 + #define WM8983_INPPGAZCL_SHIFT 7 /* INPPGAZCL */ 731 + #define WM8983_INPPGAZCL_WIDTH 1 /* INPPGAZCL */ 732 + #define WM8983_INPPGAMUTEL 0x0040 /* INPPGAMUTEL */ 733 + #define WM8983_INPPGAMUTEL_MASK 0x0040 /* INPPGAMUTEL */ 734 + #define WM8983_INPPGAMUTEL_SHIFT 6 /* INPPGAMUTEL */ 735 + #define WM8983_INPPGAMUTEL_WIDTH 1 /* INPPGAMUTEL */ 736 + #define WM8983_INPPGAVOLL_MASK 0x003F /* INPPGAVOLL - [5:0] */ 737 + #define WM8983_INPPGAVOLL_SHIFT 0 /* INPPGAVOLL - [5:0] */ 738 + #define WM8983_INPPGAVOLL_WIDTH 6 /* INPPGAVOLL - [5:0] */ 739 + 740 + /* 741 + * R46 (0x2E) - Right INP PGA gain ctrl 742 + */ 743 + #define WM8983_INPGAVU 0x0100 /* INPGAVU */ 744 + #define WM8983_INPGAVU_MASK 0x0100 /* INPGAVU */ 745 + #define WM8983_INPGAVU_SHIFT 8 /* INPGAVU */ 746 + #define WM8983_INPGAVU_WIDTH 1 /* INPGAVU */ 747 + #define WM8983_INPPGAZCR 0x0080 /* INPPGAZCR */ 748 + #define WM8983_INPPGAZCR_MASK 0x0080 /* INPPGAZCR */ 749 + #define WM8983_INPPGAZCR_SHIFT 7 /* INPPGAZCR */ 750 + #define WM8983_INPPGAZCR_WIDTH 1 /* INPPGAZCR */ 751 + #define WM8983_INPPGAMUTER 0x0040 /* INPPGAMUTER */ 752 + #define WM8983_INPPGAMUTER_MASK 0x0040 /* INPPGAMUTER */ 753 + #define WM8983_INPPGAMUTER_SHIFT 6 /* INPPGAMUTER */ 754 + #define WM8983_INPPGAMUTER_WIDTH 1 /* INPPGAMUTER */ 755 + #define WM8983_INPPGAVOLR_MASK 0x003F /* INPPGAVOLR - [5:0] */ 756 + #define WM8983_INPPGAVOLR_SHIFT 0 /* INPPGAVOLR - [5:0] */ 757 + #define WM8983_INPPGAVOLR_WIDTH 6 /* INPPGAVOLR - [5:0] */ 758 + 759 + /* 760 + * R47 (0x2F) - Left ADC BOOST ctrl 761 + */ 762 + #define WM8983_PGABOOSTL 0x0100 /* PGABOOSTL */ 763 + #define WM8983_PGABOOSTL_MASK 0x0100 /* PGABOOSTL */ 764 + #define WM8983_PGABOOSTL_SHIFT 8 /* PGABOOSTL */ 765 + #define WM8983_PGABOOSTL_WIDTH 1 /* PGABOOSTL */ 766 + #define WM8983_L2_2BOOSTVOL_MASK 0x0070 /* L2_2BOOSTVOL - [6:4] */ 767 + #define WM8983_L2_2BOOSTVOL_SHIFT 4 /* L2_2BOOSTVOL - [6:4] */ 768 + #define WM8983_L2_2BOOSTVOL_WIDTH 3 /* L2_2BOOSTVOL - [6:4] */ 769 + #define WM8983_AUXL2BOOSTVOL_MASK 0x0007 /* AUXL2BOOSTVOL - [2:0] */ 770 + #define WM8983_AUXL2BOOSTVOL_SHIFT 0 /* AUXL2BOOSTVOL - [2:0] */ 771 + #define WM8983_AUXL2BOOSTVOL_WIDTH 3 /* AUXL2BOOSTVOL - [2:0] */ 772 + 773 + /* 774 + * R48 (0x30) - Right ADC BOOST ctrl 775 + */ 776 + #define WM8983_PGABOOSTR 0x0100 /* PGABOOSTR */ 777 + #define WM8983_PGABOOSTR_MASK 0x0100 /* PGABOOSTR */ 778 + #define WM8983_PGABOOSTR_SHIFT 8 /* PGABOOSTR */ 779 + #define WM8983_PGABOOSTR_WIDTH 1 /* PGABOOSTR */ 780 + #define WM8983_R2_2BOOSTVOL_MASK 0x0070 /* R2_2BOOSTVOL - [6:4] */ 781 + #define WM8983_R2_2BOOSTVOL_SHIFT 4 /* R2_2BOOSTVOL - [6:4] */ 782 + #define WM8983_R2_2BOOSTVOL_WIDTH 3 /* R2_2BOOSTVOL - [6:4] */ 783 + #define WM8983_AUXR2BOOSTVOL_MASK 0x0007 /* AUXR2BOOSTVOL - [2:0] */ 784 + #define WM8983_AUXR2BOOSTVOL_SHIFT 0 /* AUXR2BOOSTVOL - [2:0] */ 785 + #define WM8983_AUXR2BOOSTVOL_WIDTH 3 /* AUXR2BOOSTVOL - [2:0] */ 786 + 787 + /* 788 + * R49 (0x31) - Output ctrl 789 + */ 790 + #define WM8983_DACL2RMIX 0x0040 /* DACL2RMIX */ 791 + #define WM8983_DACL2RMIX_MASK 0x0040 /* DACL2RMIX */ 792 + #define WM8983_DACL2RMIX_SHIFT 6 /* DACL2RMIX */ 793 + #define WM8983_DACL2RMIX_WIDTH 1 /* DACL2RMIX */ 794 + #define WM8983_DACR2LMIX 0x0020 /* DACR2LMIX */ 795 + #define WM8983_DACR2LMIX_MASK 0x0020 /* DACR2LMIX */ 796 + #define WM8983_DACR2LMIX_SHIFT 5 /* DACR2LMIX */ 797 + #define WM8983_DACR2LMIX_WIDTH 1 /* DACR2LMIX */ 798 + #define WM8983_OUT4BOOST 0x0010 /* OUT4BOOST */ 799 + #define WM8983_OUT4BOOST_MASK 0x0010 /* OUT4BOOST */ 800 + #define WM8983_OUT4BOOST_SHIFT 4 /* OUT4BOOST */ 801 + #define WM8983_OUT4BOOST_WIDTH 1 /* OUT4BOOST */ 802 + #define WM8983_OUT3BOOST 0x0008 /* OUT3BOOST */ 803 + #define WM8983_OUT3BOOST_MASK 0x0008 /* OUT3BOOST */ 804 + #define WM8983_OUT3BOOST_SHIFT 3 /* OUT3BOOST */ 805 + #define WM8983_OUT3BOOST_WIDTH 1 /* OUT3BOOST */ 806 + #define WM8983_SPKBOOST 0x0004 /* SPKBOOST */ 807 + #define WM8983_SPKBOOST_MASK 0x0004 /* SPKBOOST */ 808 + #define WM8983_SPKBOOST_SHIFT 2 /* SPKBOOST */ 809 + #define WM8983_SPKBOOST_WIDTH 1 /* SPKBOOST */ 810 + #define WM8983_TSDEN 0x0002 /* TSDEN */ 811 + #define WM8983_TSDEN_MASK 0x0002 /* TSDEN */ 812 + #define WM8983_TSDEN_SHIFT 1 /* TSDEN */ 813 + #define WM8983_TSDEN_WIDTH 1 /* TSDEN */ 814 + #define WM8983_VROI 0x0001 /* VROI */ 815 + #define WM8983_VROI_MASK 0x0001 /* VROI */ 816 + #define WM8983_VROI_SHIFT 0 /* VROI */ 817 + #define WM8983_VROI_WIDTH 1 /* VROI */ 818 + 819 + /* 820 + * R50 (0x32) - Left mixer ctrl 821 + */ 822 + #define WM8983_AUXLMIXVOL_MASK 0x01C0 /* AUXLMIXVOL - [8:6] */ 823 + #define WM8983_AUXLMIXVOL_SHIFT 6 /* AUXLMIXVOL - [8:6] */ 824 + #define WM8983_AUXLMIXVOL_WIDTH 3 /* AUXLMIXVOL - [8:6] */ 825 + #define WM8983_AUXL2LMIX 0x0020 /* AUXL2LMIX */ 826 + #define WM8983_AUXL2LMIX_MASK 0x0020 /* AUXL2LMIX */ 827 + #define WM8983_AUXL2LMIX_SHIFT 5 /* AUXL2LMIX */ 828 + #define WM8983_AUXL2LMIX_WIDTH 1 /* AUXL2LMIX */ 829 + #define WM8983_BYPLMIXVOL_MASK 0x001C /* BYPLMIXVOL - [4:2] */ 830 + #define WM8983_BYPLMIXVOL_SHIFT 2 /* BYPLMIXVOL - [4:2] */ 831 + #define WM8983_BYPLMIXVOL_WIDTH 3 /* BYPLMIXVOL - [4:2] */ 832 + #define WM8983_BYPL2LMIX 0x0002 /* BYPL2LMIX */ 833 + #define WM8983_BYPL2LMIX_MASK 0x0002 /* BYPL2LMIX */ 834 + #define WM8983_BYPL2LMIX_SHIFT 1 /* BYPL2LMIX */ 835 + #define WM8983_BYPL2LMIX_WIDTH 1 /* BYPL2LMIX */ 836 + #define WM8983_DACL2LMIX 0x0001 /* DACL2LMIX */ 837 + #define WM8983_DACL2LMIX_MASK 0x0001 /* DACL2LMIX */ 838 + #define WM8983_DACL2LMIX_SHIFT 0 /* DACL2LMIX */ 839 + #define WM8983_DACL2LMIX_WIDTH 1 /* DACL2LMIX */ 840 + 841 + /* 842 + * R51 (0x33) - Right mixer ctrl 843 + */ 844 + #define WM8983_AUXRMIXVOL_MASK 0x01C0 /* AUXRMIXVOL - [8:6] */ 845 + #define WM8983_AUXRMIXVOL_SHIFT 6 /* AUXRMIXVOL - [8:6] */ 846 + #define WM8983_AUXRMIXVOL_WIDTH 3 /* AUXRMIXVOL - [8:6] */ 847 + #define WM8983_AUXR2RMIX 0x0020 /* AUXR2RMIX */ 848 + #define WM8983_AUXR2RMIX_MASK 0x0020 /* AUXR2RMIX */ 849 + #define WM8983_AUXR2RMIX_SHIFT 5 /* AUXR2RMIX */ 850 + #define WM8983_AUXR2RMIX_WIDTH 1 /* AUXR2RMIX */ 851 + #define WM8983_BYPRMIXVOL_MASK 0x001C /* BYPRMIXVOL - [4:2] */ 852 + #define WM8983_BYPRMIXVOL_SHIFT 2 /* BYPRMIXVOL - [4:2] */ 853 + #define WM8983_BYPRMIXVOL_WIDTH 3 /* BYPRMIXVOL - [4:2] */ 854 + #define WM8983_BYPR2RMIX 0x0002 /* BYPR2RMIX */ 855 + #define WM8983_BYPR2RMIX_MASK 0x0002 /* BYPR2RMIX */ 856 + #define WM8983_BYPR2RMIX_SHIFT 1 /* BYPR2RMIX */ 857 + #define WM8983_BYPR2RMIX_WIDTH 1 /* BYPR2RMIX */ 858 + #define WM8983_DACR2RMIX 0x0001 /* DACR2RMIX */ 859 + #define WM8983_DACR2RMIX_MASK 0x0001 /* DACR2RMIX */ 860 + #define WM8983_DACR2RMIX_SHIFT 0 /* DACR2RMIX */ 861 + #define WM8983_DACR2RMIX_WIDTH 1 /* DACR2RMIX */ 862 + 863 + /* 864 + * R52 (0x34) - LOUT1 (HP) volume ctrl 865 + */ 866 + #define WM8983_OUT1VU 0x0100 /* OUT1VU */ 867 + #define WM8983_OUT1VU_MASK 0x0100 /* OUT1VU */ 868 + #define WM8983_OUT1VU_SHIFT 8 /* OUT1VU */ 869 + #define WM8983_OUT1VU_WIDTH 1 /* OUT1VU */ 870 + #define WM8983_LOUT1ZC 0x0080 /* LOUT1ZC */ 871 + #define WM8983_LOUT1ZC_MASK 0x0080 /* LOUT1ZC */ 872 + #define WM8983_LOUT1ZC_SHIFT 7 /* LOUT1ZC */ 873 + #define WM8983_LOUT1ZC_WIDTH 1 /* LOUT1ZC */ 874 + #define WM8983_LOUT1MUTE 0x0040 /* LOUT1MUTE */ 875 + #define WM8983_LOUT1MUTE_MASK 0x0040 /* LOUT1MUTE */ 876 + #define WM8983_LOUT1MUTE_SHIFT 6 /* LOUT1MUTE */ 877 + #define WM8983_LOUT1MUTE_WIDTH 1 /* LOUT1MUTE */ 878 + #define WM8983_LOUT1VOL_MASK 0x003F /* LOUT1VOL - [5:0] */ 879 + #define WM8983_LOUT1VOL_SHIFT 0 /* LOUT1VOL - [5:0] */ 880 + #define WM8983_LOUT1VOL_WIDTH 6 /* LOUT1VOL - [5:0] */ 881 + 882 + /* 883 + * R53 (0x35) - ROUT1 (HP) volume ctrl 884 + */ 885 + #define WM8983_OUT1VU 0x0100 /* OUT1VU */ 886 + #define WM8983_OUT1VU_MASK 0x0100 /* OUT1VU */ 887 + #define WM8983_OUT1VU_SHIFT 8 /* OUT1VU */ 888 + #define WM8983_OUT1VU_WIDTH 1 /* OUT1VU */ 889 + #define WM8983_ROUT1ZC 0x0080 /* ROUT1ZC */ 890 + #define WM8983_ROUT1ZC_MASK 0x0080 /* ROUT1ZC */ 891 + #define WM8983_ROUT1ZC_SHIFT 7 /* ROUT1ZC */ 892 + #define WM8983_ROUT1ZC_WIDTH 1 /* ROUT1ZC */ 893 + #define WM8983_ROUT1MUTE 0x0040 /* ROUT1MUTE */ 894 + #define WM8983_ROUT1MUTE_MASK 0x0040 /* ROUT1MUTE */ 895 + #define WM8983_ROUT1MUTE_SHIFT 6 /* ROUT1MUTE */ 896 + #define WM8983_ROUT1MUTE_WIDTH 1 /* ROUT1MUTE */ 897 + #define WM8983_ROUT1VOL_MASK 0x003F /* ROUT1VOL - [5:0] */ 898 + #define WM8983_ROUT1VOL_SHIFT 0 /* ROUT1VOL - [5:0] */ 899 + #define WM8983_ROUT1VOL_WIDTH 6 /* ROUT1VOL - [5:0] */ 900 + 901 + /* 902 + * R54 (0x36) - LOUT2 (SPK) volume ctrl 903 + */ 904 + #define WM8983_OUT2VU 0x0100 /* OUT2VU */ 905 + #define WM8983_OUT2VU_MASK 0x0100 /* OUT2VU */ 906 + #define WM8983_OUT2VU_SHIFT 8 /* OUT2VU */ 907 + #define WM8983_OUT2VU_WIDTH 1 /* OUT2VU */ 908 + #define WM8983_LOUT2ZC 0x0080 /* LOUT2ZC */ 909 + #define WM8983_LOUT2ZC_MASK 0x0080 /* LOUT2ZC */ 910 + #define WM8983_LOUT2ZC_SHIFT 7 /* LOUT2ZC */ 911 + #define WM8983_LOUT2ZC_WIDTH 1 /* LOUT2ZC */ 912 + #define WM8983_LOUT2MUTE 0x0040 /* LOUT2MUTE */ 913 + #define WM8983_LOUT2MUTE_MASK 0x0040 /* LOUT2MUTE */ 914 + #define WM8983_LOUT2MUTE_SHIFT 6 /* LOUT2MUTE */ 915 + #define WM8983_LOUT2MUTE_WIDTH 1 /* LOUT2MUTE */ 916 + #define WM8983_LOUT2VOL_MASK 0x003F /* LOUT2VOL - [5:0] */ 917 + #define WM8983_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [5:0] */ 918 + #define WM8983_LOUT2VOL_WIDTH 6 /* LOUT2VOL - [5:0] */ 919 + 920 + /* 921 + * R55 (0x37) - ROUT2 (SPK) volume ctrl 922 + */ 923 + #define WM8983_OUT2VU 0x0100 /* OUT2VU */ 924 + #define WM8983_OUT2VU_MASK 0x0100 /* OUT2VU */ 925 + #define WM8983_OUT2VU_SHIFT 8 /* OUT2VU */ 926 + #define WM8983_OUT2VU_WIDTH 1 /* OUT2VU */ 927 + #define WM8983_ROUT2ZC 0x0080 /* ROUT2ZC */ 928 + #define WM8983_ROUT2ZC_MASK 0x0080 /* ROUT2ZC */ 929 + #define WM8983_ROUT2ZC_SHIFT 7 /* ROUT2ZC */ 930 + #define WM8983_ROUT2ZC_WIDTH 1 /* ROUT2ZC */ 931 + #define WM8983_ROUT2MUTE 0x0040 /* ROUT2MUTE */ 932 + #define WM8983_ROUT2MUTE_MASK 0x0040 /* ROUT2MUTE */ 933 + #define WM8983_ROUT2MUTE_SHIFT 6 /* ROUT2MUTE */ 934 + #define WM8983_ROUT2MUTE_WIDTH 1 /* ROUT2MUTE */ 935 + #define WM8983_ROUT2VOL_MASK 0x003F /* ROUT2VOL - [5:0] */ 936 + #define WM8983_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [5:0] */ 937 + #define WM8983_ROUT2VOL_WIDTH 6 /* ROUT2VOL - [5:0] */ 938 + 939 + /* 940 + * R56 (0x38) - OUT3 mixer ctrl 941 + */ 942 + #define WM8983_OUT3MUTE 0x0040 /* OUT3MUTE */ 943 + #define WM8983_OUT3MUTE_MASK 0x0040 /* OUT3MUTE */ 944 + #define WM8983_OUT3MUTE_SHIFT 6 /* OUT3MUTE */ 945 + #define WM8983_OUT3MUTE_WIDTH 1 /* OUT3MUTE */ 946 + #define WM8983_OUT4_2OUT3 0x0008 /* OUT4_2OUT3 */ 947 + #define WM8983_OUT4_2OUT3_MASK 0x0008 /* OUT4_2OUT3 */ 948 + #define WM8983_OUT4_2OUT3_SHIFT 3 /* OUT4_2OUT3 */ 949 + #define WM8983_OUT4_2OUT3_WIDTH 1 /* OUT4_2OUT3 */ 950 + #define WM8983_BYPL2OUT3 0x0004 /* BYPL2OUT3 */ 951 + #define WM8983_BYPL2OUT3_MASK 0x0004 /* BYPL2OUT3 */ 952 + #define WM8983_BYPL2OUT3_SHIFT 2 /* BYPL2OUT3 */ 953 + #define WM8983_BYPL2OUT3_WIDTH 1 /* BYPL2OUT3 */ 954 + #define WM8983_LMIX2OUT3 0x0002 /* LMIX2OUT3 */ 955 + #define WM8983_LMIX2OUT3_MASK 0x0002 /* LMIX2OUT3 */ 956 + #define WM8983_LMIX2OUT3_SHIFT 1 /* LMIX2OUT3 */ 957 + #define WM8983_LMIX2OUT3_WIDTH 1 /* LMIX2OUT3 */ 958 + #define WM8983_LDAC2OUT3 0x0001 /* LDAC2OUT3 */ 959 + #define WM8983_LDAC2OUT3_MASK 0x0001 /* LDAC2OUT3 */ 960 + #define WM8983_LDAC2OUT3_SHIFT 0 /* LDAC2OUT3 */ 961 + #define WM8983_LDAC2OUT3_WIDTH 1 /* LDAC2OUT3 */ 962 + 963 + /* 964 + * R57 (0x39) - OUT4 (MONO) mix ctrl 965 + */ 966 + #define WM8983_OUT3_2OUT4 0x0080 /* OUT3_2OUT4 */ 967 + #define WM8983_OUT3_2OUT4_MASK 0x0080 /* OUT3_2OUT4 */ 968 + #define WM8983_OUT3_2OUT4_SHIFT 7 /* OUT3_2OUT4 */ 969 + #define WM8983_OUT3_2OUT4_WIDTH 1 /* OUT3_2OUT4 */ 970 + #define WM8983_OUT4MUTE 0x0040 /* OUT4MUTE */ 971 + #define WM8983_OUT4MUTE_MASK 0x0040 /* OUT4MUTE */ 972 + #define WM8983_OUT4MUTE_SHIFT 6 /* OUT4MUTE */ 973 + #define WM8983_OUT4MUTE_WIDTH 1 /* OUT4MUTE */ 974 + #define WM8983_OUT4ATTN 0x0020 /* OUT4ATTN */ 975 + #define WM8983_OUT4ATTN_MASK 0x0020 /* OUT4ATTN */ 976 + #define WM8983_OUT4ATTN_SHIFT 5 /* OUT4ATTN */ 977 + #define WM8983_OUT4ATTN_WIDTH 1 /* OUT4ATTN */ 978 + #define WM8983_LMIX2OUT4 0x0010 /* LMIX2OUT4 */ 979 + #define WM8983_LMIX2OUT4_MASK 0x0010 /* LMIX2OUT4 */ 980 + #define WM8983_LMIX2OUT4_SHIFT 4 /* LMIX2OUT4 */ 981 + #define WM8983_LMIX2OUT4_WIDTH 1 /* LMIX2OUT4 */ 982 + #define WM8983_LDAC2OUT4 0x0008 /* LDAC2OUT4 */ 983 + #define WM8983_LDAC2OUT4_MASK 0x0008 /* LDAC2OUT4 */ 984 + #define WM8983_LDAC2OUT4_SHIFT 3 /* LDAC2OUT4 */ 985 + #define WM8983_LDAC2OUT4_WIDTH 1 /* LDAC2OUT4 */ 986 + #define WM8983_BYPR2OUT4 0x0004 /* BYPR2OUT4 */ 987 + #define WM8983_BYPR2OUT4_MASK 0x0004 /* BYPR2OUT4 */ 988 + #define WM8983_BYPR2OUT4_SHIFT 2 /* BYPR2OUT4 */ 989 + #define WM8983_BYPR2OUT4_WIDTH 1 /* BYPR2OUT4 */ 990 + #define WM8983_RMIX2OUT4 0x0002 /* RMIX2OUT4 */ 991 + #define WM8983_RMIX2OUT4_MASK 0x0002 /* RMIX2OUT4 */ 992 + #define WM8983_RMIX2OUT4_SHIFT 1 /* RMIX2OUT4 */ 993 + #define WM8983_RMIX2OUT4_WIDTH 1 /* RMIX2OUT4 */ 994 + #define WM8983_RDAC2OUT4 0x0001 /* RDAC2OUT4 */ 995 + #define WM8983_RDAC2OUT4_MASK 0x0001 /* RDAC2OUT4 */ 996 + #define WM8983_RDAC2OUT4_SHIFT 0 /* RDAC2OUT4 */ 997 + #define WM8983_RDAC2OUT4_WIDTH 1 /* RDAC2OUT4 */ 998 + 999 + /* 1000 + * R61 (0x3D) - BIAS CTRL 1001 + */ 1002 + #define WM8983_BIASCUT 0x0100 /* BIASCUT */ 1003 + #define WM8983_BIASCUT_MASK 0x0100 /* BIASCUT */ 1004 + #define WM8983_BIASCUT_SHIFT 8 /* BIASCUT */ 1005 + #define WM8983_BIASCUT_WIDTH 1 /* BIASCUT */ 1006 + #define WM8983_HALFIPBIAS 0x0080 /* HALFIPBIAS */ 1007 + #define WM8983_HALFIPBIAS_MASK 0x0080 /* HALFIPBIAS */ 1008 + #define WM8983_HALFIPBIAS_SHIFT 7 /* HALFIPBIAS */ 1009 + #define WM8983_HALFIPBIAS_WIDTH 1 /* HALFIPBIAS */ 1010 + #define WM8983_VBBIASTST_MASK 0x0060 /* VBBIASTST - [6:5] */ 1011 + #define WM8983_VBBIASTST_SHIFT 5 /* VBBIASTST - [6:5] */ 1012 + #define WM8983_VBBIASTST_WIDTH 2 /* VBBIASTST - [6:5] */ 1013 + #define WM8983_BUFBIAS_MASK 0x0018 /* BUFBIAS - [4:3] */ 1014 + #define WM8983_BUFBIAS_SHIFT 3 /* BUFBIAS - [4:3] */ 1015 + #define WM8983_BUFBIAS_WIDTH 2 /* BUFBIAS - [4:3] */ 1016 + #define WM8983_ADCBIAS_MASK 0x0006 /* ADCBIAS - [2:1] */ 1017 + #define WM8983_ADCBIAS_SHIFT 1 /* ADCBIAS - [2:1] */ 1018 + #define WM8983_ADCBIAS_WIDTH 2 /* ADCBIAS - [2:1] */ 1019 + #define WM8983_HALFOPBIAS 0x0001 /* HALFOPBIAS */ 1020 + #define WM8983_HALFOPBIAS_MASK 0x0001 /* HALFOPBIAS */ 1021 + #define WM8983_HALFOPBIAS_SHIFT 0 /* HALFOPBIAS */ 1022 + #define WM8983_HALFOPBIAS_WIDTH 1 /* HALFOPBIAS */ 1023 + 1024 + enum clk_src { 1025 + WM8983_CLKSRC_MCLK, 1026 + WM8983_CLKSRC_PLL 1027 + }; 1028 + 1029 + #endif /* _WM8983_H */