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

ASoC: WM8985: Initial driver

The WM8985 is a low power, high quality, feature-rich stereo
CODEC designed for portable multimedia applications that
require low power consumption and high quality audio.

Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Dimitris Papastamos and committed by
Mark Brown
6d6f8b83 69737897

+2246
+4
sound/soc/codecs/Kconfig
··· 67 67 select SND_SOC_WM8971 if I2C 68 68 select SND_SOC_WM8974 if I2C 69 69 select SND_SOC_WM8978 if I2C 70 + select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI 70 71 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 71 72 select SND_SOC_WM8990 if I2C 72 73 select SND_SOC_WM8993 if I2C ··· 268 267 tristate 269 268 270 269 config SND_SOC_WM8978 270 + tristate 271 + 272 + config SND_SOC_WM8985 271 273 tristate 272 274 273 275 config SND_SOC_WM8988
+2
sound/soc/codecs/Makefile
··· 52 52 snd-soc-wm8971-objs := wm8971.o 53 53 snd-soc-wm8974-objs := wm8974.o 54 54 snd-soc-wm8978-objs := wm8978.o 55 + snd-soc-wm8985-objs := wm8985.o 55 56 snd-soc-wm8988-objs := wm8988.o 56 57 snd-soc-wm8990-objs := wm8990.o 57 58 snd-soc-wm8993-objs := wm8993.o ··· 125 124 obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 126 125 obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o 127 126 obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o 127 + obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o 128 128 obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 129 129 obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 130 130 obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
+1195
sound/soc/codecs/wm8985.c
··· 1 + /* 2 + * wm8985.c -- WM8985 ALSA SoC Audio driver 3 + * 4 + * Copyright 2010 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 + * TODO: 13 + * o Add OUT3/OUT4 mixer controls. 14 + */ 15 + 16 + #include <linux/module.h> 17 + #include <linux/moduleparam.h> 18 + #include <linux/init.h> 19 + #include <linux/delay.h> 20 + #include <linux/pm.h> 21 + #include <linux/i2c.h> 22 + #include <linux/regulator/consumer.h> 23 + #include <linux/spi/spi.h> 24 + #include <linux/slab.h> 25 + #include <sound/core.h> 26 + #include <sound/pcm.h> 27 + #include <sound/pcm_params.h> 28 + #include <sound/soc.h> 29 + #include <sound/soc-dapm.h> 30 + #include <sound/initval.h> 31 + #include <sound/tlv.h> 32 + 33 + #include "wm8985.h" 34 + 35 + #define WM8985_NUM_SUPPLIES 4 36 + static const char *wm8985_supply_names[WM8985_NUM_SUPPLIES] = { 37 + "DCVDD", 38 + "DBVDD", 39 + "AVDD1", 40 + "AVDD2" 41 + }; 42 + 43 + static const u16 wm8985_reg_defs[] = { 44 + 0x0000, /* R0 - Software Reset */ 45 + 0x0000, /* R1 - Power management 1 */ 46 + 0x0000, /* R2 - Power management 2 */ 47 + 0x0000, /* R3 - Power management 3 */ 48 + 0x0050, /* R4 - Audio Interface */ 49 + 0x0000, /* R5 - Companding control */ 50 + 0x0140, /* R6 - Clock Gen control */ 51 + 0x0000, /* R7 - Additional control */ 52 + 0x0000, /* R8 - GPIO Control */ 53 + 0x0000, /* R9 - Jack Detect Control 1 */ 54 + 0x0000, /* R10 - DAC Control */ 55 + 0x00FF, /* R11 - Left DAC digital Vol */ 56 + 0x00FF, /* R12 - Right DAC digital vol */ 57 + 0x0000, /* R13 - Jack Detect Control 2 */ 58 + 0x0100, /* R14 - ADC Control */ 59 + 0x00FF, /* R15 - Left ADC Digital Vol */ 60 + 0x00FF, /* R16 - Right ADC Digital Vol */ 61 + 0x0000, /* R17 */ 62 + 0x012C, /* R18 - EQ1 - low shelf */ 63 + 0x002C, /* R19 - EQ2 - peak 1 */ 64 + 0x002C, /* R20 - EQ3 - peak 2 */ 65 + 0x002C, /* R21 - EQ4 - peak 3 */ 66 + 0x002C, /* R22 - EQ5 - high shelf */ 67 + 0x0000, /* R23 */ 68 + 0x0032, /* R24 - DAC Limiter 1 */ 69 + 0x0000, /* R25 - DAC Limiter 2 */ 70 + 0x0000, /* R26 */ 71 + 0x0000, /* R27 - Notch Filter 1 */ 72 + 0x0000, /* R28 - Notch Filter 2 */ 73 + 0x0000, /* R29 - Notch Filter 3 */ 74 + 0x0000, /* R30 - Notch Filter 4 */ 75 + 0x0000, /* R31 */ 76 + 0x0038, /* R32 - ALC control 1 */ 77 + 0x000B, /* R33 - ALC control 2 */ 78 + 0x0032, /* R34 - ALC control 3 */ 79 + 0x0000, /* R35 - Noise Gate */ 80 + 0x0008, /* R36 - PLL N */ 81 + 0x000C, /* R37 - PLL K 1 */ 82 + 0x0093, /* R38 - PLL K 2 */ 83 + 0x00E9, /* R39 - PLL K 3 */ 84 + 0x0000, /* R40 */ 85 + 0x0000, /* R41 - 3D control */ 86 + 0x0000, /* R42 - OUT4 to ADC */ 87 + 0x0000, /* R43 - Beep control */ 88 + 0x0033, /* R44 - Input ctrl */ 89 + 0x0010, /* R45 - Left INP PGA gain ctrl */ 90 + 0x0010, /* R46 - Right INP PGA gain ctrl */ 91 + 0x0100, /* R47 - Left ADC BOOST ctrl */ 92 + 0x0100, /* R48 - Right ADC BOOST ctrl */ 93 + 0x0002, /* R49 - Output ctrl */ 94 + 0x0001, /* R50 - Left mixer ctrl */ 95 + 0x0001, /* R51 - Right mixer ctrl */ 96 + 0x0039, /* R52 - LOUT1 (HP) volume ctrl */ 97 + 0x0039, /* R53 - ROUT1 (HP) volume ctrl */ 98 + 0x0039, /* R54 - LOUT2 (SPK) volume ctrl */ 99 + 0x0039, /* R55 - ROUT2 (SPK) volume ctrl */ 100 + 0x0001, /* R56 - OUT3 mixer ctrl */ 101 + 0x0001, /* R57 - OUT4 (MONO) mix ctrl */ 102 + 0x0001, /* R58 */ 103 + 0x0000, /* R59 */ 104 + 0x0004, /* R60 - OUTPUT ctrl */ 105 + 0x0000, /* R61 - BIAS CTRL */ 106 + 0x0180, /* R62 */ 107 + 0x0000 /* R63 */ 108 + }; 109 + 110 + /* 111 + * latch bit 8 of these registers to ensure instant 112 + * volume updates 113 + */ 114 + static const int volume_update_regs[] = { 115 + WM8985_LEFT_DAC_DIGITAL_VOL, 116 + WM8985_RIGHT_DAC_DIGITAL_VOL, 117 + WM8985_LEFT_ADC_DIGITAL_VOL, 118 + WM8985_RIGHT_ADC_DIGITAL_VOL, 119 + WM8985_LOUT2_SPK_VOLUME_CTRL, 120 + WM8985_ROUT2_SPK_VOLUME_CTRL, 121 + WM8985_LOUT1_HP_VOLUME_CTRL, 122 + WM8985_ROUT1_HP_VOLUME_CTRL, 123 + WM8985_LEFT_INP_PGA_GAIN_CTRL, 124 + WM8985_RIGHT_INP_PGA_GAIN_CTRL 125 + }; 126 + 127 + struct wm8985_priv { 128 + enum snd_soc_control_type control_type; 129 + struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES]; 130 + unsigned int sysclk; 131 + unsigned int bclk; 132 + }; 133 + 134 + static const struct { 135 + int div; 136 + int ratio; 137 + } fs_ratios[] = { 138 + { 10, 128 }, 139 + { 15, 192 }, 140 + { 20, 256 }, 141 + { 30, 384 }, 142 + { 40, 512 }, 143 + { 60, 768 }, 144 + { 80, 1024 }, 145 + { 120, 1536 } 146 + }; 147 + 148 + static const int srates[] = { 48000, 32000, 24000, 16000, 12000, 8000 }; 149 + 150 + static const int bclk_divs[] = { 151 + 1, 2, 4, 8, 16, 32 152 + }; 153 + 154 + static int eqmode_get(struct snd_kcontrol *kcontrol, 155 + struct snd_ctl_elem_value *ucontrol); 156 + static int eqmode_put(struct snd_kcontrol *kcontrol, 157 + struct snd_ctl_elem_value *ucontrol); 158 + 159 + static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1); 160 + static const DECLARE_TLV_DB_SCALE(adc_tlv, -12700, 50, 1); 161 + static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); 162 + static const DECLARE_TLV_DB_SCALE(lim_thresh_tlv, -600, 100, 0); 163 + static const DECLARE_TLV_DB_SCALE(lim_boost_tlv, 0, 100, 0); 164 + static const DECLARE_TLV_DB_SCALE(alc_min_tlv, -1200, 600, 0); 165 + static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -675, 600, 0); 166 + static const DECLARE_TLV_DB_SCALE(alc_tar_tlv, -2250, 150, 0); 167 + static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1200, 75, 0); 168 + static const DECLARE_TLV_DB_SCALE(boost_tlv, -1200, 300, 1); 169 + static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 170 + static const DECLARE_TLV_DB_SCALE(aux_tlv, -1500, 300, 0); 171 + static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); 172 + static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0); 173 + 174 + static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" }; 175 + static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8985_ALC_CONTROL_1, 7, 176 + alc_sel_text); 177 + 178 + static const char *alc_mode_text[] = { "ALC", "Limiter" }; 179 + static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8985_ALC_CONTROL_3, 8, 180 + alc_mode_text); 181 + 182 + static const char *filter_mode_text[] = { "Audio", "Application" }; 183 + static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8985_ADC_CONTROL, 7, 184 + filter_mode_text); 185 + 186 + static const char *eq_bw_text[] = { "Narrow", "Wide" }; 187 + static const char *eqmode_text[] = { "Capture", "Playback" }; 188 + static const SOC_ENUM_SINGLE_DECL(eqmode, WM8985_EQ1_LOW_SHELF, 8, 189 + eqmode_text); 190 + static const char *eq1_cutoff_text[] = { 191 + "80Hz", "105Hz", "135Hz", "175Hz" 192 + }; 193 + static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8985_EQ1_LOW_SHELF, 5, 194 + eq1_cutoff_text); 195 + static const char *eq2_cutoff_text[] = { 196 + "230Hz", "300Hz", "385Hz", "500Hz" 197 + }; 198 + static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8985_EQ2_PEAK_1, 8, eq_bw_text); 199 + static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8985_EQ2_PEAK_1, 5, 200 + eq2_cutoff_text); 201 + static const char *eq3_cutoff_text[] = { 202 + "650Hz", "850Hz", "1.1kHz", "1.4kHz" 203 + }; 204 + static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8985_EQ3_PEAK_2, 8, eq_bw_text); 205 + static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8985_EQ3_PEAK_2, 5, 206 + eq3_cutoff_text); 207 + static const char *eq4_cutoff_text[] = { 208 + "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" 209 + }; 210 + static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8985_EQ4_PEAK_3, 8, eq_bw_text); 211 + static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8985_EQ4_PEAK_3, 5, 212 + eq4_cutoff_text); 213 + static const char *eq5_cutoff_text[] = { 214 + "5.3kHz", "6.9kHz", "9kHz", "11.7kHz" 215 + }; 216 + static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8985_EQ5_HIGH_SHELF, 5, 217 + eq5_cutoff_text); 218 + 219 + static const char *speaker_mode_text[] = { "Class A/B", "Class D" }; 220 + static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text); 221 + 222 + static const char *depth_3d_text[] = { 223 + "Off", 224 + "6.67%", 225 + "13.3%", 226 + "20%", 227 + "26.7%", 228 + "33.3%", 229 + "40%", 230 + "46.6%", 231 + "53.3%", 232 + "60%", 233 + "66.7%", 234 + "73.3%", 235 + "80%", 236 + "86.7%", 237 + "93.3%", 238 + "100%" 239 + }; 240 + static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0, 241 + depth_3d_text); 242 + 243 + static const struct snd_kcontrol_new wm8985_snd_controls[] = { 244 + SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL, 245 + 0, 1, 0), 246 + 247 + SOC_ENUM("ALC Capture Function", alc_sel), 248 + SOC_SINGLE_TLV("ALC Capture Max Volume", WM8985_ALC_CONTROL_1, 249 + 3, 7, 0, alc_max_tlv), 250 + SOC_SINGLE_TLV("ALC Capture Min Volume", WM8985_ALC_CONTROL_1, 251 + 0, 7, 0, alc_min_tlv), 252 + SOC_SINGLE_TLV("ALC Capture Target Volume", WM8985_ALC_CONTROL_2, 253 + 0, 15, 0, alc_tar_tlv), 254 + SOC_SINGLE("ALC Capture Attack", WM8985_ALC_CONTROL_3, 0, 10, 0), 255 + SOC_SINGLE("ALC Capture Hold", WM8985_ALC_CONTROL_2, 4, 10, 0), 256 + SOC_SINGLE("ALC Capture Decay", WM8985_ALC_CONTROL_3, 4, 10, 0), 257 + SOC_ENUM("ALC Mode", alc_mode), 258 + SOC_SINGLE("ALC Capture NG Switch", WM8985_NOISE_GATE, 259 + 3, 1, 0), 260 + SOC_SINGLE("ALC Capture NG Threshold", WM8985_NOISE_GATE, 261 + 0, 7, 1), 262 + 263 + SOC_DOUBLE_R_TLV("Capture Volume", WM8985_LEFT_ADC_DIGITAL_VOL, 264 + WM8985_RIGHT_ADC_DIGITAL_VOL, 0, 255, 0, adc_tlv), 265 + SOC_DOUBLE_R("Capture PGA ZC Switch", WM8985_LEFT_INP_PGA_GAIN_CTRL, 266 + WM8985_RIGHT_INP_PGA_GAIN_CTRL, 7, 1, 0), 267 + SOC_DOUBLE_R_TLV("Capture PGA Volume", WM8985_LEFT_INP_PGA_GAIN_CTRL, 268 + WM8985_RIGHT_INP_PGA_GAIN_CTRL, 0, 63, 0, pga_vol_tlv), 269 + 270 + SOC_DOUBLE_R_TLV("Capture PGA Boost Volume", 271 + WM8985_LEFT_ADC_BOOST_CTRL, WM8985_RIGHT_ADC_BOOST_CTRL, 272 + 8, 1, 0, pga_boost_tlv), 273 + 274 + SOC_DOUBLE("ADC Inversion Switch", WM8985_ADC_CONTROL, 0, 1, 1, 0), 275 + SOC_SINGLE("ADC 128x Oversampling Switch", WM8985_ADC_CONTROL, 8, 1, 0), 276 + 277 + SOC_DOUBLE_R_TLV("Playback Volume", WM8985_LEFT_DAC_DIGITAL_VOL, 278 + WM8985_RIGHT_DAC_DIGITAL_VOL, 0, 255, 0, dac_tlv), 279 + 280 + SOC_SINGLE("DAC Playback Limiter Switch", WM8985_DAC_LIMITER_1, 8, 1, 0), 281 + SOC_SINGLE("DAC Playback Limiter Decay", WM8985_DAC_LIMITER_1, 4, 10, 0), 282 + SOC_SINGLE("DAC Playback Limiter Attack", WM8985_DAC_LIMITER_1, 0, 11, 0), 283 + SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8985_DAC_LIMITER_2, 284 + 4, 7, 1, lim_thresh_tlv), 285 + SOC_SINGLE_TLV("DAC Playback Limiter Boost Volume", WM8985_DAC_LIMITER_2, 286 + 0, 12, 0, lim_boost_tlv), 287 + SOC_DOUBLE("DAC Inversion Switch", WM8985_DAC_CONTROL, 0, 1, 1, 0), 288 + SOC_SINGLE("DAC Auto Mute Switch", WM8985_DAC_CONTROL, 2, 1, 0), 289 + SOC_SINGLE("DAC 128x Oversampling Switch", WM8985_DAC_CONTROL, 3, 1, 0), 290 + 291 + SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8985_LOUT1_HP_VOLUME_CTRL, 292 + WM8985_ROUT1_HP_VOLUME_CTRL, 0, 63, 0, out_tlv), 293 + SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8985_LOUT1_HP_VOLUME_CTRL, 294 + WM8985_ROUT1_HP_VOLUME_CTRL, 7, 1, 0), 295 + SOC_DOUBLE_R("Headphone Switch", WM8985_LOUT1_HP_VOLUME_CTRL, 296 + WM8985_ROUT1_HP_VOLUME_CTRL, 6, 1, 1), 297 + 298 + SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8985_LOUT2_SPK_VOLUME_CTRL, 299 + WM8985_ROUT2_SPK_VOLUME_CTRL, 0, 63, 0, out_tlv), 300 + SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8985_LOUT2_SPK_VOLUME_CTRL, 301 + WM8985_ROUT2_SPK_VOLUME_CTRL, 7, 1, 0), 302 + SOC_DOUBLE_R("Speaker Switch", WM8985_LOUT2_SPK_VOLUME_CTRL, 303 + WM8985_ROUT2_SPK_VOLUME_CTRL, 6, 1, 1), 304 + 305 + SOC_SINGLE("High Pass Filter Switch", WM8985_ADC_CONTROL, 8, 1, 0), 306 + SOC_ENUM("High Pass Filter Mode", filter_mode), 307 + SOC_SINGLE("High Pass Filter Cutoff", WM8985_ADC_CONTROL, 4, 7, 0), 308 + 309 + SOC_DOUBLE_R_TLV("Aux Bypass Volume", 310 + WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 6, 7, 0, 311 + aux_tlv), 312 + 313 + SOC_DOUBLE_R_TLV("Input PGA Bypass Volume", 314 + WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 2, 7, 0, 315 + bypass_tlv), 316 + 317 + SOC_ENUM_EXT("Equalizer Function", eqmode, eqmode_get, eqmode_put), 318 + SOC_ENUM("EQ1 Cutoff", eq1_cutoff), 319 + SOC_SINGLE_TLV("EQ1 Volume", WM8985_EQ1_LOW_SHELF, 0, 24, 1, eq_tlv), 320 + SOC_ENUM("EQ2 Bandwith", eq2_bw), 321 + SOC_ENUM("EQ2 Cutoff", eq2_cutoff), 322 + SOC_SINGLE_TLV("EQ2 Volume", WM8985_EQ2_PEAK_1, 0, 24, 1, eq_tlv), 323 + SOC_ENUM("EQ3 Bandwith", eq3_bw), 324 + SOC_ENUM("EQ3 Cutoff", eq3_cutoff), 325 + SOC_SINGLE_TLV("EQ3 Volume", WM8985_EQ3_PEAK_2, 0, 24, 1, eq_tlv), 326 + SOC_ENUM("EQ4 Bandwith", eq4_bw), 327 + SOC_ENUM("EQ4 Cutoff", eq4_cutoff), 328 + SOC_SINGLE_TLV("EQ4 Volume", WM8985_EQ4_PEAK_3, 0, 24, 1, eq_tlv), 329 + SOC_ENUM("EQ5 Cutoff", eq5_cutoff), 330 + SOC_SINGLE_TLV("EQ5 Volume", WM8985_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv), 331 + 332 + SOC_ENUM("3D Depth", depth_3d), 333 + 334 + SOC_ENUM("Speaker Mode", speaker_mode) 335 + }; 336 + 337 + static const struct snd_kcontrol_new left_out_mixer[] = { 338 + SOC_DAPM_SINGLE("Line Switch", WM8985_LEFT_MIXER_CTRL, 1, 1, 0), 339 + SOC_DAPM_SINGLE("Aux Switch", WM8985_LEFT_MIXER_CTRL, 5, 1, 0), 340 + SOC_DAPM_SINGLE("PCM Switch", WM8985_LEFT_MIXER_CTRL, 0, 1, 0), 341 + }; 342 + 343 + static const struct snd_kcontrol_new right_out_mixer[] = { 344 + SOC_DAPM_SINGLE("Line Switch", WM8985_RIGHT_MIXER_CTRL, 1, 1, 0), 345 + SOC_DAPM_SINGLE("Aux Switch", WM8985_RIGHT_MIXER_CTRL, 5, 1, 0), 346 + SOC_DAPM_SINGLE("PCM Switch", WM8985_RIGHT_MIXER_CTRL, 0, 1, 0), 347 + }; 348 + 349 + static const struct snd_kcontrol_new left_input_mixer[] = { 350 + SOC_DAPM_SINGLE("L2 Switch", WM8985_INPUT_CTRL, 2, 1, 0), 351 + SOC_DAPM_SINGLE("MicN Switch", WM8985_INPUT_CTRL, 1, 1, 0), 352 + SOC_DAPM_SINGLE("MicP Switch", WM8985_INPUT_CTRL, 0, 1, 0), 353 + }; 354 + 355 + static const struct snd_kcontrol_new right_input_mixer[] = { 356 + SOC_DAPM_SINGLE("R2 Switch", WM8985_INPUT_CTRL, 6, 1, 0), 357 + SOC_DAPM_SINGLE("MicN Switch", WM8985_INPUT_CTRL, 5, 1, 0), 358 + SOC_DAPM_SINGLE("MicP Switch", WM8985_INPUT_CTRL, 4, 1, 0), 359 + }; 360 + 361 + static const struct snd_kcontrol_new left_boost_mixer[] = { 362 + SOC_DAPM_SINGLE_TLV("L2 Volume", WM8985_LEFT_ADC_BOOST_CTRL, 363 + 4, 7, 0, boost_tlv), 364 + SOC_DAPM_SINGLE_TLV("AUXL Volume", WM8985_LEFT_ADC_BOOST_CTRL, 365 + 0, 7, 0, boost_tlv) 366 + }; 367 + 368 + static const struct snd_kcontrol_new right_boost_mixer[] = { 369 + SOC_DAPM_SINGLE_TLV("R2 Volume", WM8985_RIGHT_ADC_BOOST_CTRL, 370 + 4, 7, 0, boost_tlv), 371 + SOC_DAPM_SINGLE_TLV("AUXR Volume", WM8985_RIGHT_ADC_BOOST_CTRL, 372 + 0, 7, 0, boost_tlv) 373 + }; 374 + 375 + static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = { 376 + SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8985_POWER_MANAGEMENT_3, 377 + 0, 0), 378 + SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8985_POWER_MANAGEMENT_3, 379 + 1, 0), 380 + SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8985_POWER_MANAGEMENT_2, 381 + 0, 0), 382 + SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8985_POWER_MANAGEMENT_2, 383 + 1, 0), 384 + 385 + SND_SOC_DAPM_MIXER("Left Output Mixer", WM8985_POWER_MANAGEMENT_3, 386 + 2, 0, left_out_mixer, ARRAY_SIZE(left_out_mixer)), 387 + SND_SOC_DAPM_MIXER("Right Output Mixer", WM8985_POWER_MANAGEMENT_3, 388 + 3, 0, right_out_mixer, ARRAY_SIZE(right_out_mixer)), 389 + 390 + SND_SOC_DAPM_MIXER("Left Input Mixer", WM8985_POWER_MANAGEMENT_2, 391 + 2, 0, left_input_mixer, ARRAY_SIZE(left_input_mixer)), 392 + SND_SOC_DAPM_MIXER("Right Input Mixer", WM8985_POWER_MANAGEMENT_2, 393 + 3, 0, right_input_mixer, ARRAY_SIZE(right_input_mixer)), 394 + 395 + SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8985_POWER_MANAGEMENT_2, 396 + 4, 0, left_boost_mixer, ARRAY_SIZE(left_boost_mixer)), 397 + SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8985_POWER_MANAGEMENT_2, 398 + 5, 0, right_boost_mixer, ARRAY_SIZE(right_boost_mixer)), 399 + 400 + SND_SOC_DAPM_PGA("Left Capture PGA", WM8985_LEFT_INP_PGA_GAIN_CTRL, 401 + 6, 1, NULL, 0), 402 + SND_SOC_DAPM_PGA("Right Capture PGA", WM8985_RIGHT_INP_PGA_GAIN_CTRL, 403 + 6, 1, NULL, 0), 404 + 405 + SND_SOC_DAPM_PGA("Left Headphone Out", WM8985_POWER_MANAGEMENT_2, 406 + 7, 0, NULL, 0), 407 + SND_SOC_DAPM_PGA("Right Headphone Out", WM8985_POWER_MANAGEMENT_2, 408 + 8, 0, NULL, 0), 409 + 410 + SND_SOC_DAPM_PGA("Left Speaker Out", WM8985_POWER_MANAGEMENT_3, 411 + 5, 0, NULL, 0), 412 + SND_SOC_DAPM_PGA("Right Speaker Out", WM8985_POWER_MANAGEMENT_3, 413 + 6, 0, NULL, 0), 414 + 415 + SND_SOC_DAPM_MICBIAS("Mic Bias", WM8985_POWER_MANAGEMENT_1, 4, 0), 416 + 417 + SND_SOC_DAPM_INPUT("LIN"), 418 + SND_SOC_DAPM_INPUT("LIP"), 419 + SND_SOC_DAPM_INPUT("RIN"), 420 + SND_SOC_DAPM_INPUT("RIP"), 421 + SND_SOC_DAPM_INPUT("AUXL"), 422 + SND_SOC_DAPM_INPUT("AUXR"), 423 + SND_SOC_DAPM_INPUT("L2"), 424 + SND_SOC_DAPM_INPUT("R2"), 425 + SND_SOC_DAPM_OUTPUT("HPL"), 426 + SND_SOC_DAPM_OUTPUT("HPR"), 427 + SND_SOC_DAPM_OUTPUT("SPKL"), 428 + SND_SOC_DAPM_OUTPUT("SPKR") 429 + }; 430 + 431 + static const struct snd_soc_dapm_route audio_map[] = { 432 + { "Right Output Mixer", "PCM Switch", "Right DAC" }, 433 + { "Right Output Mixer", "Aux Switch", "AUXR" }, 434 + { "Right Output Mixer", "Line Switch", "Right Boost Mixer" }, 435 + 436 + { "Left Output Mixer", "PCM Switch", "Left DAC" }, 437 + { "Left Output Mixer", "Aux Switch", "AUXL" }, 438 + { "Left Output Mixer", "Line Switch", "Left Boost Mixer" }, 439 + 440 + { "Right Headphone Out", NULL, "Right Output Mixer" }, 441 + { "HPR", NULL, "Right Headphone Out" }, 442 + 443 + { "Left Headphone Out", NULL, "Left Output Mixer" }, 444 + { "HPL", NULL, "Left Headphone Out" }, 445 + 446 + { "Right Speaker Out", NULL, "Right Output Mixer" }, 447 + { "SPKR", NULL, "Right Speaker Out" }, 448 + 449 + { "Left Speaker Out", NULL, "Left Output Mixer" }, 450 + { "SPKL", NULL, "Left Speaker Out" }, 451 + 452 + { "Right ADC", NULL, "Right Boost Mixer" }, 453 + 454 + { "Right Boost Mixer", "AUXR Volume", "AUXR" }, 455 + { "Right Boost Mixer", NULL, "Right Capture PGA" }, 456 + { "Right Boost Mixer", "R2 Volume", "R2" }, 457 + 458 + { "Left ADC", NULL, "Left Boost Mixer" }, 459 + 460 + { "Left Boost Mixer", "AUXL Volume", "AUXL" }, 461 + { "Left Boost Mixer", NULL, "Left Capture PGA" }, 462 + { "Left Boost Mixer", "L2 Volume", "L2" }, 463 + 464 + { "Right Capture PGA", NULL, "Right Input Mixer" }, 465 + { "Left Capture PGA", NULL, "Left Input Mixer" }, 466 + 467 + { "Right Input Mixer", "R2 Switch", "R2" }, 468 + { "Right Input Mixer", "MicN Switch", "RIN" }, 469 + { "Right Input Mixer", "MicP Switch", "RIP" }, 470 + 471 + { "Left Input Mixer", "L2 Switch", "L2" }, 472 + { "Left Input Mixer", "MicN Switch", "LIN" }, 473 + { "Left Input Mixer", "MicP Switch", "LIP" }, 474 + }; 475 + 476 + static int eqmode_get(struct snd_kcontrol *kcontrol, 477 + struct snd_ctl_elem_value *ucontrol) 478 + { 479 + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 480 + unsigned int reg; 481 + 482 + reg = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF); 483 + if (reg & WM8985_EQ3DMODE) 484 + ucontrol->value.integer.value[0] = 1; 485 + else 486 + ucontrol->value.integer.value[0] = 0; 487 + 488 + return 0; 489 + } 490 + 491 + static int eqmode_put(struct snd_kcontrol *kcontrol, 492 + struct snd_ctl_elem_value *ucontrol) 493 + { 494 + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 495 + unsigned int regpwr2, regpwr3; 496 + unsigned int reg_eq; 497 + 498 + if (ucontrol->value.integer.value[0] != 0 499 + && ucontrol->value.integer.value[0] != 1) 500 + return -EINVAL; 501 + 502 + reg_eq = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF); 503 + switch ((reg_eq & WM8985_EQ3DMODE) >> WM8985_EQ3DMODE_SHIFT) { 504 + case 0: 505 + if (!ucontrol->value.integer.value[0]) 506 + return 0; 507 + break; 508 + case 1: 509 + if (ucontrol->value.integer.value[0]) 510 + return 0; 511 + break; 512 + } 513 + 514 + regpwr2 = snd_soc_read(codec, WM8985_POWER_MANAGEMENT_2); 515 + regpwr3 = snd_soc_read(codec, WM8985_POWER_MANAGEMENT_3); 516 + /* disable the DACs and ADCs */ 517 + snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_2, 518 + WM8985_ADCENR_MASK | WM8985_ADCENL_MASK, 0); 519 + snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_3, 520 + WM8985_DACENR_MASK | WM8985_DACENL_MASK, 0); 521 + snd_soc_update_bits(codec, WM8985_ADDITIONAL_CONTROL, 522 + WM8985_M128ENB_MASK, WM8985_M128ENB); 523 + /* set the desired eqmode */ 524 + snd_soc_update_bits(codec, WM8985_EQ1_LOW_SHELF, 525 + WM8985_EQ3DMODE_MASK, 526 + ucontrol->value.integer.value[0] 527 + << WM8985_EQ3DMODE_SHIFT); 528 + /* restore DAC/ADC configuration */ 529 + snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, regpwr2); 530 + snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, regpwr3); 531 + return 0; 532 + } 533 + 534 + static int wm8985_add_widgets(struct snd_soc_codec *codec) 535 + { 536 + snd_soc_dapm_new_controls(codec, wm8985_dapm_widgets, 537 + ARRAY_SIZE(wm8985_dapm_widgets)); 538 + 539 + snd_soc_dapm_add_routes(codec, audio_map, 540 + ARRAY_SIZE(audio_map)); 541 + return 0; 542 + } 543 + 544 + static int wm8985_reset(struct snd_soc_codec *codec) 545 + { 546 + return snd_soc_write(codec, WM8985_SOFTWARE_RESET, 0x0); 547 + } 548 + 549 + static int wm8985_dac_mute(struct snd_soc_dai *dai, int mute) 550 + { 551 + struct snd_soc_codec *codec = dai->codec; 552 + 553 + return snd_soc_update_bits(codec, WM8985_DAC_CONTROL, 554 + WM8985_SOFTMUTE_MASK, 555 + !!mute << WM8985_SOFTMUTE_SHIFT); 556 + } 557 + 558 + static int wm8985_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 559 + { 560 + struct wm8985_priv *wm8985; 561 + struct snd_soc_codec *codec; 562 + u16 format, master, bcp, lrp; 563 + 564 + codec = dai->codec; 565 + wm8985 = snd_soc_codec_get_drvdata(codec); 566 + 567 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 568 + case SND_SOC_DAIFMT_I2S: 569 + format = 0x2; 570 + break; 571 + case SND_SOC_DAIFMT_RIGHT_J: 572 + format = 0x0; 573 + break; 574 + case SND_SOC_DAIFMT_LEFT_J: 575 + format = 0x1; 576 + break; 577 + case SND_SOC_DAIFMT_DSP_A: 578 + case SND_SOC_DAIFMT_DSP_B: 579 + format = 0x3; 580 + break; 581 + default: 582 + dev_err(dai->dev, "Unknown dai format\n"); 583 + return -EINVAL; 584 + } 585 + 586 + snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE, 587 + WM8985_FMT_MASK, format << WM8985_FMT_SHIFT); 588 + 589 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 590 + case SND_SOC_DAIFMT_CBM_CFM: 591 + master = 1; 592 + break; 593 + case SND_SOC_DAIFMT_CBS_CFS: 594 + master = 0; 595 + break; 596 + default: 597 + dev_err(dai->dev, "Unknown master/slave configuration\n"); 598 + return -EINVAL; 599 + } 600 + 601 + snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL, 602 + WM8985_MS_MASK, master << WM8985_MS_SHIFT); 603 + 604 + /* frame inversion is not valid for dsp modes */ 605 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 606 + case SND_SOC_DAIFMT_DSP_A: 607 + case SND_SOC_DAIFMT_DSP_B: 608 + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 609 + case SND_SOC_DAIFMT_IB_IF: 610 + case SND_SOC_DAIFMT_NB_IF: 611 + return -EINVAL; 612 + default: 613 + break; 614 + } 615 + break; 616 + default: 617 + break; 618 + } 619 + 620 + bcp = lrp = 0; 621 + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 622 + case SND_SOC_DAIFMT_NB_NF: 623 + break; 624 + case SND_SOC_DAIFMT_IB_IF: 625 + bcp = lrp = 1; 626 + break; 627 + case SND_SOC_DAIFMT_IB_NF: 628 + bcp = 1; 629 + break; 630 + case SND_SOC_DAIFMT_NB_IF: 631 + lrp = 1; 632 + break; 633 + default: 634 + dev_err(dai->dev, "Unknown polarity configuration\n"); 635 + return -EINVAL; 636 + } 637 + 638 + snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE, 639 + WM8985_LRP_MASK, lrp << WM8985_LRP_SHIFT); 640 + snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE, 641 + WM8985_BCP_MASK, bcp << WM8985_BCP_SHIFT); 642 + return 0; 643 + } 644 + 645 + static int wm8985_hw_params(struct snd_pcm_substream *substream, 646 + struct snd_pcm_hw_params *params, 647 + struct snd_soc_dai *dai) 648 + { 649 + size_t i; 650 + struct snd_soc_codec *codec; 651 + struct wm8985_priv *wm8985; 652 + u16 blen, srate_idx; 653 + unsigned int tmp; 654 + int srate_best; 655 + 656 + codec = dai->codec; 657 + wm8985 = snd_soc_codec_get_drvdata(codec); 658 + 659 + wm8985->bclk = snd_soc_params_to_bclk(params); 660 + if ((int)wm8985->bclk < 0) 661 + return wm8985->bclk; 662 + 663 + switch (params_format(params)) { 664 + case SNDRV_PCM_FORMAT_S16_LE: 665 + blen = 0x0; 666 + break; 667 + case SNDRV_PCM_FORMAT_S20_3LE: 668 + blen = 0x1; 669 + break; 670 + case SNDRV_PCM_FORMAT_S24_LE: 671 + blen = 0x2; 672 + break; 673 + case SNDRV_PCM_FORMAT_S32_LE: 674 + blen = 0x3; 675 + break; 676 + default: 677 + dev_err(dai->dev, "Unsupported word length %u\n", 678 + params_format(params)); 679 + return -EINVAL; 680 + } 681 + 682 + snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE, 683 + WM8985_WL_MASK, blen << WM8985_WL_SHIFT); 684 + 685 + /* 686 + * match to the nearest possible sample rate and rely 687 + * on the array index to configure the SR register 688 + */ 689 + srate_idx = 0; 690 + srate_best = abs(srates[0] - params_rate(params)); 691 + for (i = 1; i < ARRAY_SIZE(srates); ++i) { 692 + if (abs(srates[i] - params_rate(params)) >= srate_best) 693 + continue; 694 + srate_idx = i; 695 + srate_best = abs(srates[i] - params_rate(params)); 696 + } 697 + 698 + dev_dbg(dai->dev, "Selected SRATE = %d\n", srates[srate_idx]); 699 + snd_soc_update_bits(codec, WM8985_ADDITIONAL_CONTROL, 700 + WM8985_SR_MASK, srate_idx << WM8985_SR_SHIFT); 701 + 702 + dev_dbg(dai->dev, "Target BCLK = %uHz\n", wm8985->bclk); 703 + dev_dbg(dai->dev, "SYSCLK = %uHz\n", wm8985->sysclk); 704 + 705 + for (i = 0; i < ARRAY_SIZE(fs_ratios); ++i) { 706 + if (wm8985->sysclk / params_rate(params) 707 + == fs_ratios[i].ratio) 708 + break; 709 + } 710 + 711 + if (i == ARRAY_SIZE(fs_ratios)) { 712 + dev_err(dai->dev, "Unable to configure MCLK ratio %u/%u\n", 713 + wm8985->sysclk, params_rate(params)); 714 + return -EINVAL; 715 + } 716 + 717 + dev_dbg(dai->dev, "MCLK ratio = %dfs\n", fs_ratios[i].ratio); 718 + snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL, 719 + WM8985_MCLKDIV_MASK, i << WM8985_MCLKDIV_SHIFT); 720 + 721 + /* select the appropriate bclk divider */ 722 + tmp = (wm8985->sysclk / fs_ratios[i].div) * 10; 723 + for (i = 0; i < ARRAY_SIZE(bclk_divs); ++i) { 724 + if (wm8985->bclk == tmp / bclk_divs[i]) 725 + break; 726 + } 727 + 728 + if (i == ARRAY_SIZE(bclk_divs)) { 729 + dev_err(dai->dev, "No matching BCLK divider found\n"); 730 + return -EINVAL; 731 + } 732 + 733 + dev_dbg(dai->dev, "BCLK div = %d\n", i); 734 + snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL, 735 + WM8985_BCLKDIV_MASK, i << WM8985_BCLKDIV_SHIFT); 736 + return 0; 737 + } 738 + 739 + struct pll_div { 740 + u32 div2:1; 741 + u32 n:4; 742 + u32 k:24; 743 + }; 744 + 745 + #define FIXED_PLL_SIZE ((1ULL << 24) * 10) 746 + static int pll_factors(struct pll_div *pll_div, unsigned int target, 747 + unsigned int source) 748 + { 749 + u64 Kpart; 750 + unsigned long int K, Ndiv, Nmod; 751 + 752 + pll_div->div2 = 0; 753 + Ndiv = target / source; 754 + if (Ndiv < 6) { 755 + source >>= 1; 756 + pll_div->div2 = 1; 757 + Ndiv = target / source; 758 + } 759 + 760 + if (Ndiv < 6 || Ndiv > 12) { 761 + printk(KERN_ERR "%s: WM8985 N value is not within" 762 + " the recommended range: %lu\n", __func__, Ndiv); 763 + return -EINVAL; 764 + } 765 + pll_div->n = Ndiv; 766 + 767 + Nmod = target % source; 768 + Kpart = FIXED_PLL_SIZE * (u64)Nmod; 769 + 770 + do_div(Kpart, source); 771 + 772 + K = Kpart & 0xffffffff; 773 + if ((K % 10) >= 5) 774 + K += 5; 775 + K /= 10; 776 + pll_div->k = K; 777 + 778 + return 0; 779 + } 780 + 781 + static int wm8985_set_pll(struct snd_soc_dai *dai, int pll_id, 782 + int source, unsigned int freq_in, 783 + unsigned int freq_out) 784 + { 785 + int ret; 786 + struct snd_soc_codec *codec; 787 + struct pll_div pll_div; 788 + 789 + codec = dai->codec; 790 + if (freq_in && freq_out) { 791 + ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in); 792 + if (ret) 793 + return ret; 794 + } 795 + 796 + /* disable the PLL before reprogramming it */ 797 + snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1, 798 + WM8985_PLLEN_MASK, 0); 799 + 800 + if (!freq_in || !freq_out) 801 + return 0; 802 + 803 + /* set PLLN and PRESCALE */ 804 + snd_soc_write(codec, WM8985_PLL_N, 805 + (pll_div.div2 << WM8985_PLL_PRESCALE_SHIFT) 806 + | pll_div.n); 807 + /* set PLLK */ 808 + snd_soc_write(codec, WM8985_PLL_K_3, pll_div.k & 0x1ff); 809 + snd_soc_write(codec, WM8985_PLL_K_2, (pll_div.k >> 9) & 0x1ff); 810 + snd_soc_write(codec, WM8985_PLL_K_1, (pll_div.k >> 18)); 811 + /* set the source of the clock to be the PLL */ 812 + snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL, 813 + WM8985_CLKSEL_MASK, WM8985_CLKSEL); 814 + /* enable the PLL */ 815 + snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1, 816 + WM8985_PLLEN_MASK, WM8985_PLLEN); 817 + return 0; 818 + } 819 + 820 + static int wm8985_set_sysclk(struct snd_soc_dai *dai, 821 + int clk_id, unsigned int freq, int dir) 822 + { 823 + struct snd_soc_codec *codec; 824 + struct wm8985_priv *wm8985; 825 + 826 + codec = dai->codec; 827 + wm8985 = snd_soc_codec_get_drvdata(codec); 828 + 829 + switch (clk_id) { 830 + case WM8985_CLKSRC_MCLK: 831 + snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL, 832 + WM8985_CLKSEL_MASK, 0); 833 + snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1, 834 + WM8985_PLLEN_MASK, 0); 835 + break; 836 + case WM8985_CLKSRC_PLL: 837 + snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL, 838 + WM8985_CLKSEL_MASK, WM8985_CLKSEL); 839 + break; 840 + default: 841 + dev_err(dai->dev, "Unknown clock source %d\n", clk_id); 842 + return -EINVAL; 843 + } 844 + 845 + wm8985->sysclk = freq; 846 + return 0; 847 + } 848 + 849 + static void wm8985_sync_cache(struct snd_soc_codec *codec) 850 + { 851 + short i; 852 + u16 *cache; 853 + 854 + if (!codec->cache_sync) 855 + return; 856 + codec->cache_only = 0; 857 + /* restore cache */ 858 + cache = codec->reg_cache; 859 + for (i = 0; i < codec->driver->reg_cache_size; i++) { 860 + if (i == WM8985_SOFTWARE_RESET 861 + || cache[i] == wm8985_reg_defs[i]) 862 + continue; 863 + snd_soc_write(codec, i, cache[i]); 864 + } 865 + codec->cache_sync = 0; 866 + } 867 + 868 + static int wm8985_set_bias_level(struct snd_soc_codec *codec, 869 + enum snd_soc_bias_level level) 870 + { 871 + int ret; 872 + struct wm8985_priv *wm8985; 873 + 874 + wm8985 = snd_soc_codec_get_drvdata(codec); 875 + switch (level) { 876 + case SND_SOC_BIAS_ON: 877 + case SND_SOC_BIAS_PREPARE: 878 + /* VMID at 75k */ 879 + snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1, 880 + WM8985_VMIDSEL_MASK, 881 + 1 << WM8985_VMIDSEL_SHIFT); 882 + break; 883 + case SND_SOC_BIAS_STANDBY: 884 + if (codec->bias_level == SND_SOC_BIAS_OFF) { 885 + ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies), 886 + wm8985->supplies); 887 + if (ret) { 888 + dev_err(codec->dev, 889 + "Failed to enable supplies: %d\n", 890 + ret); 891 + return ret; 892 + } 893 + 894 + wm8985_sync_cache(codec); 895 + 896 + /* enable anti-pop features */ 897 + snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC, 898 + WM8985_POBCTRL_MASK, 899 + WM8985_POBCTRL); 900 + /* enable thermal shutdown */ 901 + snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0, 902 + WM8985_TSDEN_MASK, WM8985_TSDEN); 903 + snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0, 904 + WM8985_TSOPCTRL_MASK, 905 + WM8985_TSOPCTRL); 906 + /* enable BIASEN */ 907 + snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1, 908 + WM8985_BIASEN_MASK, WM8985_BIASEN); 909 + /* VMID at 75k */ 910 + snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1, 911 + WM8985_VMIDSEL_MASK, 912 + 1 << WM8985_VMIDSEL_SHIFT); 913 + msleep(500); 914 + /* disable anti-pop features */ 915 + snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC, 916 + WM8985_POBCTRL_MASK, 0); 917 + } 918 + /* VMID at 300k */ 919 + snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1, 920 + WM8985_VMIDSEL_MASK, 921 + 2 << WM8985_VMIDSEL_SHIFT); 922 + break; 923 + case SND_SOC_BIAS_OFF: 924 + /* disable thermal shutdown */ 925 + snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0, 926 + WM8985_TSOPCTRL_MASK, 0); 927 + snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0, 928 + WM8985_TSDEN_MASK, 0); 929 + /* disable VMIDSEL and BIASEN */ 930 + snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1, 931 + WM8985_VMIDSEL_MASK | WM8985_BIASEN_MASK, 932 + 0); 933 + snd_soc_write(codec, WM8985_POWER_MANAGEMENT_1, 0); 934 + snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0); 935 + snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0); 936 + 937 + codec->cache_sync = 1; 938 + 939 + regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), 940 + wm8985->supplies); 941 + break; 942 + } 943 + 944 + codec->bias_level = level; 945 + return 0; 946 + } 947 + 948 + #ifdef CONFIG_PM 949 + static int wm8985_suspend(struct snd_soc_codec *codec, pm_message_t state) 950 + { 951 + wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF); 952 + return 0; 953 + } 954 + 955 + static int wm8985_resume(struct snd_soc_codec *codec) 956 + { 957 + wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 958 + return 0; 959 + } 960 + #else 961 + #define wm8985_suspend NULL 962 + #define wm8985_resume NULL 963 + #endif 964 + 965 + static int wm8985_remove(struct snd_soc_codec *codec) 966 + { 967 + struct wm8985_priv *wm8985; 968 + 969 + wm8985 = snd_soc_codec_get_drvdata(codec); 970 + wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF); 971 + regulator_bulk_free(ARRAY_SIZE(wm8985->supplies), wm8985->supplies); 972 + return 0; 973 + } 974 + 975 + static int wm8985_probe(struct snd_soc_codec *codec) 976 + { 977 + size_t i; 978 + struct wm8985_priv *wm8985; 979 + int ret; 980 + u16 *cache; 981 + 982 + wm8985 = snd_soc_codec_get_drvdata(codec); 983 + 984 + ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8985->control_type); 985 + if (ret < 0) { 986 + dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); 987 + return ret; 988 + } 989 + 990 + for (i = 0; i < ARRAY_SIZE(wm8985->supplies); i++) 991 + wm8985->supplies[i].supply = wm8985_supply_names[i]; 992 + 993 + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8985->supplies), 994 + wm8985->supplies); 995 + if (ret) { 996 + dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 997 + return ret; 998 + } 999 + 1000 + ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies), 1001 + wm8985->supplies); 1002 + if (ret) { 1003 + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 1004 + goto err_reg_get; 1005 + } 1006 + 1007 + ret = wm8985_reset(codec); 1008 + if (ret < 0) { 1009 + dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 1010 + goto err_reg_enable; 1011 + } 1012 + 1013 + cache = codec->reg_cache; 1014 + /* latch volume update bits */ 1015 + for (i = 0; i < ARRAY_SIZE(volume_update_regs); ++i) 1016 + cache[volume_update_regs[i]] |= 0x100; 1017 + /* enable BIASCUT */ 1018 + cache[WM8985_BIAS_CTRL] |= WM8985_BIASCUT; 1019 + codec->cache_sync = 1; 1020 + 1021 + snd_soc_add_controls(codec, wm8985_snd_controls, 1022 + ARRAY_SIZE(wm8985_snd_controls)); 1023 + wm8985_add_widgets(codec); 1024 + 1025 + wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1026 + return 0; 1027 + 1028 + err_reg_enable: 1029 + regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), wm8985->supplies); 1030 + err_reg_get: 1031 + regulator_bulk_free(ARRAY_SIZE(wm8985->supplies), wm8985->supplies); 1032 + return ret; 1033 + } 1034 + 1035 + static struct snd_soc_dai_ops wm8985_dai_ops = { 1036 + .digital_mute = wm8985_dac_mute, 1037 + .hw_params = wm8985_hw_params, 1038 + .set_fmt = wm8985_set_fmt, 1039 + .set_sysclk = wm8985_set_sysclk, 1040 + .set_pll = wm8985_set_pll 1041 + }; 1042 + 1043 + #define WM8985_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1044 + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 1045 + 1046 + static struct snd_soc_dai_driver wm8985_dai = { 1047 + .name = "wm8985-hifi", 1048 + .playback = { 1049 + .stream_name = "Playback", 1050 + .channels_min = 2, 1051 + .channels_max = 2, 1052 + .rates = SNDRV_PCM_RATE_8000_48000, 1053 + .formats = WM8985_FORMATS, 1054 + }, 1055 + .capture = { 1056 + .stream_name = "Capture", 1057 + .channels_min = 2, 1058 + .channels_max = 2, 1059 + .rates = SNDRV_PCM_RATE_8000_48000, 1060 + .formats = WM8985_FORMATS, 1061 + }, 1062 + .ops = &wm8985_dai_ops, 1063 + .symmetric_rates = 1 1064 + }; 1065 + 1066 + static struct snd_soc_codec_driver soc_codec_dev_wm8985 = { 1067 + .probe = wm8985_probe, 1068 + .remove = wm8985_remove, 1069 + .suspend = wm8985_suspend, 1070 + .resume = wm8985_resume, 1071 + .set_bias_level = wm8985_set_bias_level, 1072 + .reg_cache_size = ARRAY_SIZE(wm8985_reg_defs), 1073 + .reg_word_size = sizeof(u16), 1074 + .reg_cache_default = wm8985_reg_defs 1075 + }; 1076 + 1077 + #if defined(CONFIG_SPI_MASTER) 1078 + static int __devinit wm8985_spi_probe(struct spi_device *spi) 1079 + { 1080 + struct wm8985_priv *wm8985; 1081 + int ret; 1082 + 1083 + wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL); 1084 + if (IS_ERR(wm8985)) 1085 + return PTR_ERR(wm8985); 1086 + 1087 + wm8985->control_type = SND_SOC_SPI; 1088 + spi_set_drvdata(spi, wm8985); 1089 + 1090 + ret = snd_soc_register_codec(&spi->dev, 1091 + &soc_codec_dev_wm8985, &wm8985_dai, 1); 1092 + if (ret < 0) 1093 + kfree(wm8985); 1094 + return ret; 1095 + } 1096 + 1097 + static int __devexit wm8985_spi_remove(struct spi_device *spi) 1098 + { 1099 + snd_soc_unregister_codec(&spi->dev); 1100 + kfree(spi_get_drvdata(spi)); 1101 + return 0; 1102 + } 1103 + 1104 + static struct spi_driver wm8985_spi_driver = { 1105 + .driver = { 1106 + .name = "wm8985", 1107 + .bus = &spi_bus_type, 1108 + .owner = THIS_MODULE, 1109 + }, 1110 + .probe = wm8985_spi_probe, 1111 + .remove = __devexit_p(wm8985_spi_remove) 1112 + }; 1113 + #endif 1114 + 1115 + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1116 + static __devinit int wm8985_i2c_probe(struct i2c_client *i2c, 1117 + const struct i2c_device_id *id) 1118 + { 1119 + struct wm8985_priv *wm8985; 1120 + int ret; 1121 + 1122 + wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL); 1123 + if (IS_ERR(wm8985)) 1124 + return PTR_ERR(wm8985); 1125 + 1126 + wm8985->control_type = SND_SOC_I2C; 1127 + i2c_set_clientdata(i2c, wm8985); 1128 + 1129 + ret = snd_soc_register_codec(&i2c->dev, 1130 + &soc_codec_dev_wm8985, &wm8985_dai, 1); 1131 + if (ret < 0) 1132 + kfree(wm8985); 1133 + return ret; 1134 + } 1135 + 1136 + static __devexit int wm8985_i2c_remove(struct i2c_client *client) 1137 + { 1138 + snd_soc_unregister_codec(&client->dev); 1139 + kfree(i2c_get_clientdata(client)); 1140 + return 0; 1141 + } 1142 + 1143 + static const struct i2c_device_id wm8985_i2c_id[] = { 1144 + { "wm8985", 0 }, 1145 + { } 1146 + }; 1147 + MODULE_DEVICE_TABLE(i2c, wm8985_i2c_id); 1148 + 1149 + static struct i2c_driver wm8985_i2c_driver = { 1150 + .driver = { 1151 + .name = "wm8985", 1152 + .owner = THIS_MODULE, 1153 + }, 1154 + .probe = wm8985_i2c_probe, 1155 + .remove = __devexit_p(wm8985_i2c_remove), 1156 + .id_table = wm8985_i2c_id 1157 + }; 1158 + #endif 1159 + 1160 + static int __init wm8985_modinit(void) 1161 + { 1162 + int ret = 0; 1163 + 1164 + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1165 + ret = i2c_add_driver(&wm8985_i2c_driver); 1166 + if (ret) { 1167 + printk(KERN_ERR "Failed to register wm8985 I2C driver: %d\n", 1168 + ret); 1169 + } 1170 + #endif 1171 + #if defined(CONFIG_SPI_MASTER) 1172 + ret = spi_register_driver(&wm8985_spi_driver); 1173 + if (ret != 0) { 1174 + printk(KERN_ERR "Failed to register wm8985 SPI driver: %d\n", 1175 + ret); 1176 + } 1177 + #endif 1178 + return ret; 1179 + } 1180 + module_init(wm8985_modinit); 1181 + 1182 + static void __exit wm8985_exit(void) 1183 + { 1184 + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1185 + i2c_del_driver(&wm8985_i2c_driver); 1186 + #endif 1187 + #if defined(CONFIG_SPI_MASTER) 1188 + spi_unregister_driver(&wm8985_spi_driver); 1189 + #endif 1190 + } 1191 + module_exit(wm8985_exit); 1192 + 1193 + MODULE_DESCRIPTION("ASoC WM8985 driver"); 1194 + MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>"); 1195 + MODULE_LICENSE("GPL");
+1045
sound/soc/codecs/wm8985.h
··· 1 + /* 2 + * wm8985.h -- WM8985 ASoC driver 3 + * 4 + * Copyright 2010 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 _WM8985_H 14 + #define _WM8985_H 15 + 16 + #define WM8985_SOFTWARE_RESET 0x00 17 + #define WM8985_POWER_MANAGEMENT_1 0x01 18 + #define WM8985_POWER_MANAGEMENT_2 0x02 19 + #define WM8985_POWER_MANAGEMENT_3 0x03 20 + #define WM8985_AUDIO_INTERFACE 0x04 21 + #define WM8985_COMPANDING_CONTROL 0x05 22 + #define WM8985_CLOCK_GEN_CONTROL 0x06 23 + #define WM8985_ADDITIONAL_CONTROL 0x07 24 + #define WM8985_GPIO_CONTROL 0x08 25 + #define WM8985_JACK_DETECT_CONTROL_1 0x09 26 + #define WM8985_DAC_CONTROL 0x0A 27 + #define WM8985_LEFT_DAC_DIGITAL_VOL 0x0B 28 + #define WM8985_RIGHT_DAC_DIGITAL_VOL 0x0C 29 + #define WM8985_JACK_DETECT_CONTROL_2 0x0D 30 + #define WM8985_ADC_CONTROL 0x0E 31 + #define WM8985_LEFT_ADC_DIGITAL_VOL 0x0F 32 + #define WM8985_RIGHT_ADC_DIGITAL_VOL 0x10 33 + #define WM8985_EQ1_LOW_SHELF 0x12 34 + #define WM8985_EQ2_PEAK_1 0x13 35 + #define WM8985_EQ3_PEAK_2 0x14 36 + #define WM8985_EQ4_PEAK_3 0x15 37 + #define WM8985_EQ5_HIGH_SHELF 0x16 38 + #define WM8985_DAC_LIMITER_1 0x18 39 + #define WM8985_DAC_LIMITER_2 0x19 40 + #define WM8985_NOTCH_FILTER_1 0x1B 41 + #define WM8985_NOTCH_FILTER_2 0x1C 42 + #define WM8985_NOTCH_FILTER_3 0x1D 43 + #define WM8985_NOTCH_FILTER_4 0x1E 44 + #define WM8985_ALC_CONTROL_1 0x20 45 + #define WM8985_ALC_CONTROL_2 0x21 46 + #define WM8985_ALC_CONTROL_3 0x22 47 + #define WM8985_NOISE_GATE 0x23 48 + #define WM8985_PLL_N 0x24 49 + #define WM8985_PLL_K_1 0x25 50 + #define WM8985_PLL_K_2 0x26 51 + #define WM8985_PLL_K_3 0x27 52 + #define WM8985_3D_CONTROL 0x29 53 + #define WM8985_OUT4_TO_ADC 0x2A 54 + #define WM8985_BEEP_CONTROL 0x2B 55 + #define WM8985_INPUT_CTRL 0x2C 56 + #define WM8985_LEFT_INP_PGA_GAIN_CTRL 0x2D 57 + #define WM8985_RIGHT_INP_PGA_GAIN_CTRL 0x2E 58 + #define WM8985_LEFT_ADC_BOOST_CTRL 0x2F 59 + #define WM8985_RIGHT_ADC_BOOST_CTRL 0x30 60 + #define WM8985_OUTPUT_CTRL0 0x31 61 + #define WM8985_LEFT_MIXER_CTRL 0x32 62 + #define WM8985_RIGHT_MIXER_CTRL 0x33 63 + #define WM8985_LOUT1_HP_VOLUME_CTRL 0x34 64 + #define WM8985_ROUT1_HP_VOLUME_CTRL 0x35 65 + #define WM8985_LOUT2_SPK_VOLUME_CTRL 0x36 66 + #define WM8985_ROUT2_SPK_VOLUME_CTRL 0x37 67 + #define WM8985_OUT3_MIXER_CTRL 0x38 68 + #define WM8985_OUT4_MONO_MIX_CTRL 0x39 69 + #define WM8985_OUTPUT_CTRL1 0x3C 70 + #define WM8985_BIAS_CTRL 0x3D 71 + 72 + #define WM8985_REGISTER_COUNT 59 73 + #define WM8985_MAX_REGISTER 0x3F 74 + 75 + /* 76 + * Field Definitions. 77 + */ 78 + 79 + /* 80 + * R0 (0x00) - Software Reset 81 + */ 82 + #define WM8985_SOFTWARE_RESET_MASK 0x01FF /* SOFTWARE_RESET - [8:0] */ 83 + #define WM8985_SOFTWARE_RESET_SHIFT 0 /* SOFTWARE_RESET - [8:0] */ 84 + #define WM8985_SOFTWARE_RESET_WIDTH 9 /* SOFTWARE_RESET - [8:0] */ 85 + 86 + /* 87 + * R1 (0x01) - Power management 1 88 + */ 89 + #define WM8985_OUT4MIXEN 0x0080 /* OUT4MIXEN */ 90 + #define WM8985_OUT4MIXEN_MASK 0x0080 /* OUT4MIXEN */ 91 + #define WM8985_OUT4MIXEN_SHIFT 7 /* OUT4MIXEN */ 92 + #define WM8985_OUT4MIXEN_WIDTH 1 /* OUT4MIXEN */ 93 + #define WM8985_OUT3MIXEN 0x0040 /* OUT3MIXEN */ 94 + #define WM8985_OUT3MIXEN_MASK 0x0040 /* OUT3MIXEN */ 95 + #define WM8985_OUT3MIXEN_SHIFT 6 /* OUT3MIXEN */ 96 + #define WM8985_OUT3MIXEN_WIDTH 1 /* OUT3MIXEN */ 97 + #define WM8985_PLLEN 0x0020 /* PLLEN */ 98 + #define WM8985_PLLEN_MASK 0x0020 /* PLLEN */ 99 + #define WM8985_PLLEN_SHIFT 5 /* PLLEN */ 100 + #define WM8985_PLLEN_WIDTH 1 /* PLLEN */ 101 + #define WM8985_MICBEN 0x0010 /* MICBEN */ 102 + #define WM8985_MICBEN_MASK 0x0010 /* MICBEN */ 103 + #define WM8985_MICBEN_SHIFT 4 /* MICBEN */ 104 + #define WM8985_MICBEN_WIDTH 1 /* MICBEN */ 105 + #define WM8985_BIASEN 0x0008 /* BIASEN */ 106 + #define WM8985_BIASEN_MASK 0x0008 /* BIASEN */ 107 + #define WM8985_BIASEN_SHIFT 3 /* BIASEN */ 108 + #define WM8985_BIASEN_WIDTH 1 /* BIASEN */ 109 + #define WM8985_BUFIOEN 0x0004 /* BUFIOEN */ 110 + #define WM8985_BUFIOEN_MASK 0x0004 /* BUFIOEN */ 111 + #define WM8985_BUFIOEN_SHIFT 2 /* BUFIOEN */ 112 + #define WM8985_BUFIOEN_WIDTH 1 /* BUFIOEN */ 113 + #define WM8985_VMIDSEL 0x0003 /* VMIDSEL */ 114 + #define WM8985_VMIDSEL_MASK 0x0003 /* VMIDSEL - [1:0] */ 115 + #define WM8985_VMIDSEL_SHIFT 0 /* VMIDSEL - [1:0] */ 116 + #define WM8985_VMIDSEL_WIDTH 2 /* VMIDSEL - [1:0] */ 117 + 118 + /* 119 + * R2 (0x02) - Power management 2 120 + */ 121 + #define WM8985_ROUT1EN 0x0100 /* ROUT1EN */ 122 + #define WM8985_ROUT1EN_MASK 0x0100 /* ROUT1EN */ 123 + #define WM8985_ROUT1EN_SHIFT 8 /* ROUT1EN */ 124 + #define WM8985_ROUT1EN_WIDTH 1 /* ROUT1EN */ 125 + #define WM8985_LOUT1EN 0x0080 /* LOUT1EN */ 126 + #define WM8985_LOUT1EN_MASK 0x0080 /* LOUT1EN */ 127 + #define WM8985_LOUT1EN_SHIFT 7 /* LOUT1EN */ 128 + #define WM8985_LOUT1EN_WIDTH 1 /* LOUT1EN */ 129 + #define WM8985_SLEEP 0x0040 /* SLEEP */ 130 + #define WM8985_SLEEP_MASK 0x0040 /* SLEEP */ 131 + #define WM8985_SLEEP_SHIFT 6 /* SLEEP */ 132 + #define WM8985_SLEEP_WIDTH 1 /* SLEEP */ 133 + #define WM8985_BOOSTENR 0x0020 /* BOOSTENR */ 134 + #define WM8985_BOOSTENR_MASK 0x0020 /* BOOSTENR */ 135 + #define WM8985_BOOSTENR_SHIFT 5 /* BOOSTENR */ 136 + #define WM8985_BOOSTENR_WIDTH 1 /* BOOSTENR */ 137 + #define WM8985_BOOSTENL 0x0010 /* BOOSTENL */ 138 + #define WM8985_BOOSTENL_MASK 0x0010 /* BOOSTENL */ 139 + #define WM8985_BOOSTENL_SHIFT 4 /* BOOSTENL */ 140 + #define WM8985_BOOSTENL_WIDTH 1 /* BOOSTENL */ 141 + #define WM8985_INPGAENR 0x0008 /* INPGAENR */ 142 + #define WM8985_INPGAENR_MASK 0x0008 /* INPGAENR */ 143 + #define WM8985_INPGAENR_SHIFT 3 /* INPGAENR */ 144 + #define WM8985_INPGAENR_WIDTH 1 /* INPGAENR */ 145 + #define WM8985_INPPGAENL 0x0004 /* INPPGAENL */ 146 + #define WM8985_INPPGAENL_MASK 0x0004 /* INPPGAENL */ 147 + #define WM8985_INPPGAENL_SHIFT 2 /* INPPGAENL */ 148 + #define WM8985_INPPGAENL_WIDTH 1 /* INPPGAENL */ 149 + #define WM8985_ADCENR 0x0002 /* ADCENR */ 150 + #define WM8985_ADCENR_MASK 0x0002 /* ADCENR */ 151 + #define WM8985_ADCENR_SHIFT 1 /* ADCENR */ 152 + #define WM8985_ADCENR_WIDTH 1 /* ADCENR */ 153 + #define WM8985_ADCENL 0x0001 /* ADCENL */ 154 + #define WM8985_ADCENL_MASK 0x0001 /* ADCENL */ 155 + #define WM8985_ADCENL_SHIFT 0 /* ADCENL */ 156 + #define WM8985_ADCENL_WIDTH 1 /* ADCENL */ 157 + 158 + /* 159 + * R3 (0x03) - Power management 3 160 + */ 161 + #define WM8985_OUT4EN 0x0100 /* OUT4EN */ 162 + #define WM8985_OUT4EN_MASK 0x0100 /* OUT4EN */ 163 + #define WM8985_OUT4EN_SHIFT 8 /* OUT4EN */ 164 + #define WM8985_OUT4EN_WIDTH 1 /* OUT4EN */ 165 + #define WM8985_OUT3EN 0x0080 /* OUT3EN */ 166 + #define WM8985_OUT3EN_MASK 0x0080 /* OUT3EN */ 167 + #define WM8985_OUT3EN_SHIFT 7 /* OUT3EN */ 168 + #define WM8985_OUT3EN_WIDTH 1 /* OUT3EN */ 169 + #define WM8985_ROUT2EN 0x0040 /* ROUT2EN */ 170 + #define WM8985_ROUT2EN_MASK 0x0040 /* ROUT2EN */ 171 + #define WM8985_ROUT2EN_SHIFT 6 /* ROUT2EN */ 172 + #define WM8985_ROUT2EN_WIDTH 1 /* ROUT2EN */ 173 + #define WM8985_LOUT2EN 0x0020 /* LOUT2EN */ 174 + #define WM8985_LOUT2EN_MASK 0x0020 /* LOUT2EN */ 175 + #define WM8985_LOUT2EN_SHIFT 5 /* LOUT2EN */ 176 + #define WM8985_LOUT2EN_WIDTH 1 /* LOUT2EN */ 177 + #define WM8985_RMIXEN 0x0008 /* RMIXEN */ 178 + #define WM8985_RMIXEN_MASK 0x0008 /* RMIXEN */ 179 + #define WM8985_RMIXEN_SHIFT 3 /* RMIXEN */ 180 + #define WM8985_RMIXEN_WIDTH 1 /* RMIXEN */ 181 + #define WM8985_LMIXEN 0x0004 /* LMIXEN */ 182 + #define WM8985_LMIXEN_MASK 0x0004 /* LMIXEN */ 183 + #define WM8985_LMIXEN_SHIFT 2 /* LMIXEN */ 184 + #define WM8985_LMIXEN_WIDTH 1 /* LMIXEN */ 185 + #define WM8985_DACENR 0x0002 /* DACENR */ 186 + #define WM8985_DACENR_MASK 0x0002 /* DACENR */ 187 + #define WM8985_DACENR_SHIFT 1 /* DACENR */ 188 + #define WM8985_DACENR_WIDTH 1 /* DACENR */ 189 + #define WM8985_DACENL 0x0001 /* DACENL */ 190 + #define WM8985_DACENL_MASK 0x0001 /* DACENL */ 191 + #define WM8985_DACENL_SHIFT 0 /* DACENL */ 192 + #define WM8985_DACENL_WIDTH 1 /* DACENL */ 193 + 194 + /* 195 + * R4 (0x04) - Audio Interface 196 + */ 197 + #define WM8985_BCP 0x0100 /* BCP */ 198 + #define WM8985_BCP_MASK 0x0100 /* BCP */ 199 + #define WM8985_BCP_SHIFT 8 /* BCP */ 200 + #define WM8985_BCP_WIDTH 1 /* BCP */ 201 + #define WM8985_LRP 0x0080 /* LRP */ 202 + #define WM8985_LRP_MASK 0x0080 /* LRP */ 203 + #define WM8985_LRP_SHIFT 7 /* LRP */ 204 + #define WM8985_LRP_WIDTH 1 /* LRP */ 205 + #define WM8985_WL_MASK 0x0060 /* WL - [6:5] */ 206 + #define WM8985_WL_SHIFT 5 /* WL - [6:5] */ 207 + #define WM8985_WL_WIDTH 2 /* WL - [6:5] */ 208 + #define WM8985_FMT_MASK 0x0018 /* FMT - [4:3] */ 209 + #define WM8985_FMT_SHIFT 3 /* FMT - [4:3] */ 210 + #define WM8985_FMT_WIDTH 2 /* FMT - [4:3] */ 211 + #define WM8985_DLRSWAP 0x0004 /* DLRSWAP */ 212 + #define WM8985_DLRSWAP_MASK 0x0004 /* DLRSWAP */ 213 + #define WM8985_DLRSWAP_SHIFT 2 /* DLRSWAP */ 214 + #define WM8985_DLRSWAP_WIDTH 1 /* DLRSWAP */ 215 + #define WM8985_ALRSWAP 0x0002 /* ALRSWAP */ 216 + #define WM8985_ALRSWAP_MASK 0x0002 /* ALRSWAP */ 217 + #define WM8985_ALRSWAP_SHIFT 1 /* ALRSWAP */ 218 + #define WM8985_ALRSWAP_WIDTH 1 /* ALRSWAP */ 219 + #define WM8985_MONO 0x0001 /* MONO */ 220 + #define WM8985_MONO_MASK 0x0001 /* MONO */ 221 + #define WM8985_MONO_SHIFT 0 /* MONO */ 222 + #define WM8985_MONO_WIDTH 1 /* MONO */ 223 + 224 + /* 225 + * R5 (0x05) - Companding control 226 + */ 227 + #define WM8985_WL8 0x0020 /* WL8 */ 228 + #define WM8985_WL8_MASK 0x0020 /* WL8 */ 229 + #define WM8985_WL8_SHIFT 5 /* WL8 */ 230 + #define WM8985_WL8_WIDTH 1 /* WL8 */ 231 + #define WM8985_DAC_COMP_MASK 0x0018 /* DAC_COMP - [4:3] */ 232 + #define WM8985_DAC_COMP_SHIFT 3 /* DAC_COMP - [4:3] */ 233 + #define WM8985_DAC_COMP_WIDTH 2 /* DAC_COMP - [4:3] */ 234 + #define WM8985_ADC_COMP_MASK 0x0006 /* ADC_COMP - [2:1] */ 235 + #define WM8985_ADC_COMP_SHIFT 1 /* ADC_COMP - [2:1] */ 236 + #define WM8985_ADC_COMP_WIDTH 2 /* ADC_COMP - [2:1] */ 237 + #define WM8985_LOOPBACK 0x0001 /* LOOPBACK */ 238 + #define WM8985_LOOPBACK_MASK 0x0001 /* LOOPBACK */ 239 + #define WM8985_LOOPBACK_SHIFT 0 /* LOOPBACK */ 240 + #define WM8985_LOOPBACK_WIDTH 1 /* LOOPBACK */ 241 + 242 + /* 243 + * R6 (0x06) - Clock Gen control 244 + */ 245 + #define WM8985_CLKSEL 0x0100 /* CLKSEL */ 246 + #define WM8985_CLKSEL_MASK 0x0100 /* CLKSEL */ 247 + #define WM8985_CLKSEL_SHIFT 8 /* CLKSEL */ 248 + #define WM8985_CLKSEL_WIDTH 1 /* CLKSEL */ 249 + #define WM8985_MCLKDIV_MASK 0x00E0 /* MCLKDIV - [7:5] */ 250 + #define WM8985_MCLKDIV_SHIFT 5 /* MCLKDIV - [7:5] */ 251 + #define WM8985_MCLKDIV_WIDTH 3 /* MCLKDIV - [7:5] */ 252 + #define WM8985_BCLKDIV_MASK 0x001C /* BCLKDIV - [4:2] */ 253 + #define WM8985_BCLKDIV_SHIFT 2 /* BCLKDIV - [4:2] */ 254 + #define WM8985_BCLKDIV_WIDTH 3 /* BCLKDIV - [4:2] */ 255 + #define WM8985_MS 0x0001 /* MS */ 256 + #define WM8985_MS_MASK 0x0001 /* MS */ 257 + #define WM8985_MS_SHIFT 0 /* MS */ 258 + #define WM8985_MS_WIDTH 1 /* MS */ 259 + 260 + /* 261 + * R7 (0x07) - Additional control 262 + */ 263 + #define WM8985_M128ENB 0x0100 /* M128ENB */ 264 + #define WM8985_M128ENB_MASK 0x0100 /* M128ENB */ 265 + #define WM8985_M128ENB_SHIFT 8 /* M128ENB */ 266 + #define WM8985_M128ENB_WIDTH 1 /* M128ENB */ 267 + #define WM8985_DCLKDIV_MASK 0x00F0 /* DCLKDIV - [7:4] */ 268 + #define WM8985_DCLKDIV_SHIFT 4 /* DCLKDIV - [7:4] */ 269 + #define WM8985_DCLKDIV_WIDTH 4 /* DCLKDIV - [7:4] */ 270 + #define WM8985_SR_MASK 0x000E /* SR - [3:1] */ 271 + #define WM8985_SR_SHIFT 1 /* SR - [3:1] */ 272 + #define WM8985_SR_WIDTH 3 /* SR - [3:1] */ 273 + #define WM8985_SLOWCLKEN 0x0001 /* SLOWCLKEN */ 274 + #define WM8985_SLOWCLKEN_MASK 0x0001 /* SLOWCLKEN */ 275 + #define WM8985_SLOWCLKEN_SHIFT 0 /* SLOWCLKEN */ 276 + #define WM8985_SLOWCLKEN_WIDTH 1 /* SLOWCLKEN */ 277 + 278 + /* 279 + * R8 (0x08) - GPIO Control 280 + */ 281 + #define WM8985_GPIO1GP 0x0100 /* GPIO1GP */ 282 + #define WM8985_GPIO1GP_MASK 0x0100 /* GPIO1GP */ 283 + #define WM8985_GPIO1GP_SHIFT 8 /* GPIO1GP */ 284 + #define WM8985_GPIO1GP_WIDTH 1 /* GPIO1GP */ 285 + #define WM8985_GPIO1GPU 0x0080 /* GPIO1GPU */ 286 + #define WM8985_GPIO1GPU_MASK 0x0080 /* GPIO1GPU */ 287 + #define WM8985_GPIO1GPU_SHIFT 7 /* GPIO1GPU */ 288 + #define WM8985_GPIO1GPU_WIDTH 1 /* GPIO1GPU */ 289 + #define WM8985_GPIO1GPD 0x0040 /* GPIO1GPD */ 290 + #define WM8985_GPIO1GPD_MASK 0x0040 /* GPIO1GPD */ 291 + #define WM8985_GPIO1GPD_SHIFT 6 /* GPIO1GPD */ 292 + #define WM8985_GPIO1GPD_WIDTH 1 /* GPIO1GPD */ 293 + #define WM8985_GPIO1POL 0x0008 /* GPIO1POL */ 294 + #define WM8985_GPIO1POL_MASK 0x0008 /* GPIO1POL */ 295 + #define WM8985_GPIO1POL_SHIFT 3 /* GPIO1POL */ 296 + #define WM8985_GPIO1POL_WIDTH 1 /* GPIO1POL */ 297 + #define WM8985_GPIO1SEL_MASK 0x0007 /* GPIO1SEL - [2:0] */ 298 + #define WM8985_GPIO1SEL_SHIFT 0 /* GPIO1SEL - [2:0] */ 299 + #define WM8985_GPIO1SEL_WIDTH 3 /* GPIO1SEL - [2:0] */ 300 + 301 + /* 302 + * R9 (0x09) - Jack Detect Control 1 303 + */ 304 + #define WM8985_JD_EN 0x0040 /* JD_EN */ 305 + #define WM8985_JD_EN_MASK 0x0040 /* JD_EN */ 306 + #define WM8985_JD_EN_SHIFT 6 /* JD_EN */ 307 + #define WM8985_JD_EN_WIDTH 1 /* JD_EN */ 308 + #define WM8985_JD_SEL_MASK 0x0030 /* JD_SEL - [5:4] */ 309 + #define WM8985_JD_SEL_SHIFT 4 /* JD_SEL - [5:4] */ 310 + #define WM8985_JD_SEL_WIDTH 2 /* JD_SEL - [5:4] */ 311 + 312 + /* 313 + * R10 (0x0A) - DAC Control 314 + */ 315 + #define WM8985_SOFTMUTE 0x0040 /* SOFTMUTE */ 316 + #define WM8985_SOFTMUTE_MASK 0x0040 /* SOFTMUTE */ 317 + #define WM8985_SOFTMUTE_SHIFT 6 /* SOFTMUTE */ 318 + #define WM8985_SOFTMUTE_WIDTH 1 /* SOFTMUTE */ 319 + #define WM8985_DACOSR128 0x0008 /* DACOSR128 */ 320 + #define WM8985_DACOSR128_MASK 0x0008 /* DACOSR128 */ 321 + #define WM8985_DACOSR128_SHIFT 3 /* DACOSR128 */ 322 + #define WM8985_DACOSR128_WIDTH 1 /* DACOSR128 */ 323 + #define WM8985_AMUTE 0x0004 /* AMUTE */ 324 + #define WM8985_AMUTE_MASK 0x0004 /* AMUTE */ 325 + #define WM8985_AMUTE_SHIFT 2 /* AMUTE */ 326 + #define WM8985_AMUTE_WIDTH 1 /* AMUTE */ 327 + #define WM8985_DACPOLR 0x0002 /* DACPOLR */ 328 + #define WM8985_DACPOLR_MASK 0x0002 /* DACPOLR */ 329 + #define WM8985_DACPOLR_SHIFT 1 /* DACPOLR */ 330 + #define WM8985_DACPOLR_WIDTH 1 /* DACPOLR */ 331 + #define WM8985_DACPOLL 0x0001 /* DACPOLL */ 332 + #define WM8985_DACPOLL_MASK 0x0001 /* DACPOLL */ 333 + #define WM8985_DACPOLL_SHIFT 0 /* DACPOLL */ 334 + #define WM8985_DACPOLL_WIDTH 1 /* DACPOLL */ 335 + 336 + /* 337 + * R11 (0x0B) - Left DAC digital Vol 338 + */ 339 + #define WM8985_DACVU 0x0100 /* DACVU */ 340 + #define WM8985_DACVU_MASK 0x0100 /* DACVU */ 341 + #define WM8985_DACVU_SHIFT 8 /* DACVU */ 342 + #define WM8985_DACVU_WIDTH 1 /* DACVU */ 343 + #define WM8985_DACVOLL_MASK 0x00FF /* DACVOLL - [7:0] */ 344 + #define WM8985_DACVOLL_SHIFT 0 /* DACVOLL - [7:0] */ 345 + #define WM8985_DACVOLL_WIDTH 8 /* DACVOLL - [7:0] */ 346 + 347 + /* 348 + * R12 (0x0C) - Right DAC digital vol 349 + */ 350 + #define WM8985_DACVU 0x0100 /* DACVU */ 351 + #define WM8985_DACVU_MASK 0x0100 /* DACVU */ 352 + #define WM8985_DACVU_SHIFT 8 /* DACVU */ 353 + #define WM8985_DACVU_WIDTH 1 /* DACVU */ 354 + #define WM8985_DACVOLR_MASK 0x00FF /* DACVOLR - [7:0] */ 355 + #define WM8985_DACVOLR_SHIFT 0 /* DACVOLR - [7:0] */ 356 + #define WM8985_DACVOLR_WIDTH 8 /* DACVOLR - [7:0] */ 357 + 358 + /* 359 + * R13 (0x0D) - Jack Detect Control 2 360 + */ 361 + #define WM8985_JD_EN1_MASK 0x00F0 /* JD_EN1 - [7:4] */ 362 + #define WM8985_JD_EN1_SHIFT 4 /* JD_EN1 - [7:4] */ 363 + #define WM8985_JD_EN1_WIDTH 4 /* JD_EN1 - [7:4] */ 364 + #define WM8985_JD_EN0_MASK 0x000F /* JD_EN0 - [3:0] */ 365 + #define WM8985_JD_EN0_SHIFT 0 /* JD_EN0 - [3:0] */ 366 + #define WM8985_JD_EN0_WIDTH 4 /* JD_EN0 - [3:0] */ 367 + 368 + /* 369 + * R14 (0x0E) - ADC Control 370 + */ 371 + #define WM8985_HPFEN 0x0100 /* HPFEN */ 372 + #define WM8985_HPFEN_MASK 0x0100 /* HPFEN */ 373 + #define WM8985_HPFEN_SHIFT 8 /* HPFEN */ 374 + #define WM8985_HPFEN_WIDTH 1 /* HPFEN */ 375 + #define WM8985_HPFAPP 0x0080 /* HPFAPP */ 376 + #define WM8985_HPFAPP_MASK 0x0080 /* HPFAPP */ 377 + #define WM8985_HPFAPP_SHIFT 7 /* HPFAPP */ 378 + #define WM8985_HPFAPP_WIDTH 1 /* HPFAPP */ 379 + #define WM8985_HPFCUT_MASK 0x0070 /* HPFCUT - [6:4] */ 380 + #define WM8985_HPFCUT_SHIFT 4 /* HPFCUT - [6:4] */ 381 + #define WM8985_HPFCUT_WIDTH 3 /* HPFCUT - [6:4] */ 382 + #define WM8985_ADCOSR128 0x0008 /* ADCOSR128 */ 383 + #define WM8985_ADCOSR128_MASK 0x0008 /* ADCOSR128 */ 384 + #define WM8985_ADCOSR128_SHIFT 3 /* ADCOSR128 */ 385 + #define WM8985_ADCOSR128_WIDTH 1 /* ADCOSR128 */ 386 + #define WM8985_ADCRPOL 0x0002 /* ADCRPOL */ 387 + #define WM8985_ADCRPOL_MASK 0x0002 /* ADCRPOL */ 388 + #define WM8985_ADCRPOL_SHIFT 1 /* ADCRPOL */ 389 + #define WM8985_ADCRPOL_WIDTH 1 /* ADCRPOL */ 390 + #define WM8985_ADCLPOL 0x0001 /* ADCLPOL */ 391 + #define WM8985_ADCLPOL_MASK 0x0001 /* ADCLPOL */ 392 + #define WM8985_ADCLPOL_SHIFT 0 /* ADCLPOL */ 393 + #define WM8985_ADCLPOL_WIDTH 1 /* ADCLPOL */ 394 + 395 + /* 396 + * R15 (0x0F) - Left ADC Digital Vol 397 + */ 398 + #define WM8985_ADCVU 0x0100 /* ADCVU */ 399 + #define WM8985_ADCVU_MASK 0x0100 /* ADCVU */ 400 + #define WM8985_ADCVU_SHIFT 8 /* ADCVU */ 401 + #define WM8985_ADCVU_WIDTH 1 /* ADCVU */ 402 + #define WM8985_ADCVOLL_MASK 0x00FF /* ADCVOLL - [7:0] */ 403 + #define WM8985_ADCVOLL_SHIFT 0 /* ADCVOLL - [7:0] */ 404 + #define WM8985_ADCVOLL_WIDTH 8 /* ADCVOLL - [7:0] */ 405 + 406 + /* 407 + * R16 (0x10) - Right ADC Digital Vol 408 + */ 409 + #define WM8985_ADCVU 0x0100 /* ADCVU */ 410 + #define WM8985_ADCVU_MASK 0x0100 /* ADCVU */ 411 + #define WM8985_ADCVU_SHIFT 8 /* ADCVU */ 412 + #define WM8985_ADCVU_WIDTH 1 /* ADCVU */ 413 + #define WM8985_ADCVOLR_MASK 0x00FF /* ADCVOLR - [7:0] */ 414 + #define WM8985_ADCVOLR_SHIFT 0 /* ADCVOLR - [7:0] */ 415 + #define WM8985_ADCVOLR_WIDTH 8 /* ADCVOLR - [7:0] */ 416 + 417 + /* 418 + * R18 (0x12) - EQ1 - low shelf 419 + */ 420 + #define WM8985_EQ3DMODE 0x0100 /* EQ3DMODE */ 421 + #define WM8985_EQ3DMODE_MASK 0x0100 /* EQ3DMODE */ 422 + #define WM8985_EQ3DMODE_SHIFT 8 /* EQ3DMODE */ 423 + #define WM8985_EQ3DMODE_WIDTH 1 /* EQ3DMODE */ 424 + #define WM8985_EQ1C_MASK 0x0060 /* EQ1C - [6:5] */ 425 + #define WM8985_EQ1C_SHIFT 5 /* EQ1C - [6:5] */ 426 + #define WM8985_EQ1C_WIDTH 2 /* EQ1C - [6:5] */ 427 + #define WM8985_EQ1G_MASK 0x001F /* EQ1G - [4:0] */ 428 + #define WM8985_EQ1G_SHIFT 0 /* EQ1G - [4:0] */ 429 + #define WM8985_EQ1G_WIDTH 5 /* EQ1G - [4:0] */ 430 + 431 + /* 432 + * R19 (0x13) - EQ2 - peak 1 433 + */ 434 + #define WM8985_EQ2BW 0x0100 /* EQ2BW */ 435 + #define WM8985_EQ2BW_MASK 0x0100 /* EQ2BW */ 436 + #define WM8985_EQ2BW_SHIFT 8 /* EQ2BW */ 437 + #define WM8985_EQ2BW_WIDTH 1 /* EQ2BW */ 438 + #define WM8985_EQ2C_MASK 0x0060 /* EQ2C - [6:5] */ 439 + #define WM8985_EQ2C_SHIFT 5 /* EQ2C - [6:5] */ 440 + #define WM8985_EQ2C_WIDTH 2 /* EQ2C - [6:5] */ 441 + #define WM8985_EQ2G_MASK 0x001F /* EQ2G - [4:0] */ 442 + #define WM8985_EQ2G_SHIFT 0 /* EQ2G - [4:0] */ 443 + #define WM8985_EQ2G_WIDTH 5 /* EQ2G - [4:0] */ 444 + 445 + /* 446 + * R20 (0x14) - EQ3 - peak 2 447 + */ 448 + #define WM8985_EQ3BW 0x0100 /* EQ3BW */ 449 + #define WM8985_EQ3BW_MASK 0x0100 /* EQ3BW */ 450 + #define WM8985_EQ3BW_SHIFT 8 /* EQ3BW */ 451 + #define WM8985_EQ3BW_WIDTH 1 /* EQ3BW */ 452 + #define WM8985_EQ3C_MASK 0x0060 /* EQ3C - [6:5] */ 453 + #define WM8985_EQ3C_SHIFT 5 /* EQ3C - [6:5] */ 454 + #define WM8985_EQ3C_WIDTH 2 /* EQ3C - [6:5] */ 455 + #define WM8985_EQ3G_MASK 0x001F /* EQ3G - [4:0] */ 456 + #define WM8985_EQ3G_SHIFT 0 /* EQ3G - [4:0] */ 457 + #define WM8985_EQ3G_WIDTH 5 /* EQ3G - [4:0] */ 458 + 459 + /* 460 + * R21 (0x15) - EQ4 - peak 3 461 + */ 462 + #define WM8985_EQ4BW 0x0100 /* EQ4BW */ 463 + #define WM8985_EQ4BW_MASK 0x0100 /* EQ4BW */ 464 + #define WM8985_EQ4BW_SHIFT 8 /* EQ4BW */ 465 + #define WM8985_EQ4BW_WIDTH 1 /* EQ4BW */ 466 + #define WM8985_EQ4C_MASK 0x0060 /* EQ4C - [6:5] */ 467 + #define WM8985_EQ4C_SHIFT 5 /* EQ4C - [6:5] */ 468 + #define WM8985_EQ4C_WIDTH 2 /* EQ4C - [6:5] */ 469 + #define WM8985_EQ4G_MASK 0x001F /* EQ4G - [4:0] */ 470 + #define WM8985_EQ4G_SHIFT 0 /* EQ4G - [4:0] */ 471 + #define WM8985_EQ4G_WIDTH 5 /* EQ4G - [4:0] */ 472 + 473 + /* 474 + * R22 (0x16) - EQ5 - high shelf 475 + */ 476 + #define WM8985_EQ5C_MASK 0x0060 /* EQ5C - [6:5] */ 477 + #define WM8985_EQ5C_SHIFT 5 /* EQ5C - [6:5] */ 478 + #define WM8985_EQ5C_WIDTH 2 /* EQ5C - [6:5] */ 479 + #define WM8985_EQ5G_MASK 0x001F /* EQ5G - [4:0] */ 480 + #define WM8985_EQ5G_SHIFT 0 /* EQ5G - [4:0] */ 481 + #define WM8985_EQ5G_WIDTH 5 /* EQ5G - [4:0] */ 482 + 483 + /* 484 + * R24 (0x18) - DAC Limiter 1 485 + */ 486 + #define WM8985_LIMEN 0x0100 /* LIMEN */ 487 + #define WM8985_LIMEN_MASK 0x0100 /* LIMEN */ 488 + #define WM8985_LIMEN_SHIFT 8 /* LIMEN */ 489 + #define WM8985_LIMEN_WIDTH 1 /* LIMEN */ 490 + #define WM8985_LIMDCY_MASK 0x00F0 /* LIMDCY - [7:4] */ 491 + #define WM8985_LIMDCY_SHIFT 4 /* LIMDCY - [7:4] */ 492 + #define WM8985_LIMDCY_WIDTH 4 /* LIMDCY - [7:4] */ 493 + #define WM8985_LIMATK_MASK 0x000F /* LIMATK - [3:0] */ 494 + #define WM8985_LIMATK_SHIFT 0 /* LIMATK - [3:0] */ 495 + #define WM8985_LIMATK_WIDTH 4 /* LIMATK - [3:0] */ 496 + 497 + /* 498 + * R25 (0x19) - DAC Limiter 2 499 + */ 500 + #define WM8985_LIMLVL_MASK 0x0070 /* LIMLVL - [6:4] */ 501 + #define WM8985_LIMLVL_SHIFT 4 /* LIMLVL - [6:4] */ 502 + #define WM8985_LIMLVL_WIDTH 3 /* LIMLVL - [6:4] */ 503 + #define WM8985_LIMBOOST_MASK 0x000F /* LIMBOOST - [3:0] */ 504 + #define WM8985_LIMBOOST_SHIFT 0 /* LIMBOOST - [3:0] */ 505 + #define WM8985_LIMBOOST_WIDTH 4 /* LIMBOOST - [3:0] */ 506 + 507 + /* 508 + * R27 (0x1B) - Notch Filter 1 509 + */ 510 + #define WM8985_NFU 0x0100 /* NFU */ 511 + #define WM8985_NFU_MASK 0x0100 /* NFU */ 512 + #define WM8985_NFU_SHIFT 8 /* NFU */ 513 + #define WM8985_NFU_WIDTH 1 /* NFU */ 514 + #define WM8985_NFEN 0x0080 /* NFEN */ 515 + #define WM8985_NFEN_MASK 0x0080 /* NFEN */ 516 + #define WM8985_NFEN_SHIFT 7 /* NFEN */ 517 + #define WM8985_NFEN_WIDTH 1 /* NFEN */ 518 + #define WM8985_NFA0_13_7_MASK 0x007F /* NFA0(13:7) - [6:0] */ 519 + #define WM8985_NFA0_13_7_SHIFT 0 /* NFA0(13:7) - [6:0] */ 520 + #define WM8985_NFA0_13_7_WIDTH 7 /* NFA0(13:7) - [6:0] */ 521 + 522 + /* 523 + * R28 (0x1C) - Notch Filter 2 524 + */ 525 + #define WM8985_NFU 0x0100 /* NFU */ 526 + #define WM8985_NFU_MASK 0x0100 /* NFU */ 527 + #define WM8985_NFU_SHIFT 8 /* NFU */ 528 + #define WM8985_NFU_WIDTH 1 /* NFU */ 529 + #define WM8985_NFA0_6_0_MASK 0x007F /* NFA0(6:0) - [6:0] */ 530 + #define WM8985_NFA0_6_0_SHIFT 0 /* NFA0(6:0) - [6:0] */ 531 + #define WM8985_NFA0_6_0_WIDTH 7 /* NFA0(6:0) - [6:0] */ 532 + 533 + /* 534 + * R29 (0x1D) - Notch Filter 3 535 + */ 536 + #define WM8985_NFU 0x0100 /* NFU */ 537 + #define WM8985_NFU_MASK 0x0100 /* NFU */ 538 + #define WM8985_NFU_SHIFT 8 /* NFU */ 539 + #define WM8985_NFU_WIDTH 1 /* NFU */ 540 + #define WM8985_NFA1_13_7_MASK 0x007F /* NFA1(13:7) - [6:0] */ 541 + #define WM8985_NFA1_13_7_SHIFT 0 /* NFA1(13:7) - [6:0] */ 542 + #define WM8985_NFA1_13_7_WIDTH 7 /* NFA1(13:7) - [6:0] */ 543 + 544 + /* 545 + * R30 (0x1E) - Notch Filter 4 546 + */ 547 + #define WM8985_NFU 0x0100 /* NFU */ 548 + #define WM8985_NFU_MASK 0x0100 /* NFU */ 549 + #define WM8985_NFU_SHIFT 8 /* NFU */ 550 + #define WM8985_NFU_WIDTH 1 /* NFU */ 551 + #define WM8985_NFA1_6_0_MASK 0x007F /* NFA1(6:0) - [6:0] */ 552 + #define WM8985_NFA1_6_0_SHIFT 0 /* NFA1(6:0) - [6:0] */ 553 + #define WM8985_NFA1_6_0_WIDTH 7 /* NFA1(6:0) - [6:0] */ 554 + 555 + /* 556 + * R32 (0x20) - ALC control 1 557 + */ 558 + #define WM8985_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */ 559 + #define WM8985_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */ 560 + #define WM8985_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */ 561 + #define WM8985_ALCMAX_MASK 0x0038 /* ALCMAX - [5:3] */ 562 + #define WM8985_ALCMAX_SHIFT 3 /* ALCMAX - [5:3] */ 563 + #define WM8985_ALCMAX_WIDTH 3 /* ALCMAX - [5:3] */ 564 + #define WM8985_ALCMIN_MASK 0x0007 /* ALCMIN - [2:0] */ 565 + #define WM8985_ALCMIN_SHIFT 0 /* ALCMIN - [2:0] */ 566 + #define WM8985_ALCMIN_WIDTH 3 /* ALCMIN - [2:0] */ 567 + 568 + /* 569 + * R33 (0x21) - ALC control 2 570 + */ 571 + #define WM8985_ALCHLD_MASK 0x00F0 /* ALCHLD - [7:4] */ 572 + #define WM8985_ALCHLD_SHIFT 4 /* ALCHLD - [7:4] */ 573 + #define WM8985_ALCHLD_WIDTH 4 /* ALCHLD - [7:4] */ 574 + #define WM8985_ALCLVL_MASK 0x000F /* ALCLVL - [3:0] */ 575 + #define WM8985_ALCLVL_SHIFT 0 /* ALCLVL - [3:0] */ 576 + #define WM8985_ALCLVL_WIDTH 4 /* ALCLVL - [3:0] */ 577 + 578 + /* 579 + * R34 (0x22) - ALC control 3 580 + */ 581 + #define WM8985_ALCMODE 0x0100 /* ALCMODE */ 582 + #define WM8985_ALCMODE_MASK 0x0100 /* ALCMODE */ 583 + #define WM8985_ALCMODE_SHIFT 8 /* ALCMODE */ 584 + #define WM8985_ALCMODE_WIDTH 1 /* ALCMODE */ 585 + #define WM8985_ALCDCY_MASK 0x00F0 /* ALCDCY - [7:4] */ 586 + #define WM8985_ALCDCY_SHIFT 4 /* ALCDCY - [7:4] */ 587 + #define WM8985_ALCDCY_WIDTH 4 /* ALCDCY - [7:4] */ 588 + #define WM8985_ALCATK_MASK 0x000F /* ALCATK - [3:0] */ 589 + #define WM8985_ALCATK_SHIFT 0 /* ALCATK - [3:0] */ 590 + #define WM8985_ALCATK_WIDTH 4 /* ALCATK - [3:0] */ 591 + 592 + /* 593 + * R35 (0x23) - Noise Gate 594 + */ 595 + #define WM8985_NGEN 0x0008 /* NGEN */ 596 + #define WM8985_NGEN_MASK 0x0008 /* NGEN */ 597 + #define WM8985_NGEN_SHIFT 3 /* NGEN */ 598 + #define WM8985_NGEN_WIDTH 1 /* NGEN */ 599 + #define WM8985_NGTH_MASK 0x0007 /* NGTH - [2:0] */ 600 + #define WM8985_NGTH_SHIFT 0 /* NGTH - [2:0] */ 601 + #define WM8985_NGTH_WIDTH 3 /* NGTH - [2:0] */ 602 + 603 + /* 604 + * R36 (0x24) - PLL N 605 + */ 606 + #define WM8985_PLL_PRESCALE 0x0010 /* PLL_PRESCALE */ 607 + #define WM8985_PLL_PRESCALE_MASK 0x0010 /* PLL_PRESCALE */ 608 + #define WM8985_PLL_PRESCALE_SHIFT 4 /* PLL_PRESCALE */ 609 + #define WM8985_PLL_PRESCALE_WIDTH 1 /* PLL_PRESCALE */ 610 + #define WM8985_PLLN_MASK 0x000F /* PLLN - [3:0] */ 611 + #define WM8985_PLLN_SHIFT 0 /* PLLN - [3:0] */ 612 + #define WM8985_PLLN_WIDTH 4 /* PLLN - [3:0] */ 613 + 614 + /* 615 + * R37 (0x25) - PLL K 1 616 + */ 617 + #define WM8985_PLLK_23_18_MASK 0x003F /* PLLK(23:18) - [5:0] */ 618 + #define WM8985_PLLK_23_18_SHIFT 0 /* PLLK(23:18) - [5:0] */ 619 + #define WM8985_PLLK_23_18_WIDTH 6 /* PLLK(23:18) - [5:0] */ 620 + 621 + /* 622 + * R38 (0x26) - PLL K 2 623 + */ 624 + #define WM8985_PLLK_17_9_MASK 0x01FF /* PLLK(17:9) - [8:0] */ 625 + #define WM8985_PLLK_17_9_SHIFT 0 /* PLLK(17:9) - [8:0] */ 626 + #define WM8985_PLLK_17_9_WIDTH 9 /* PLLK(17:9) - [8:0] */ 627 + 628 + /* 629 + * R39 (0x27) - PLL K 3 630 + */ 631 + #define WM8985_PLLK_8_0_MASK 0x01FF /* PLLK(8:0) - [8:0] */ 632 + #define WM8985_PLLK_8_0_SHIFT 0 /* PLLK(8:0) - [8:0] */ 633 + #define WM8985_PLLK_8_0_WIDTH 9 /* PLLK(8:0) - [8:0] */ 634 + 635 + /* 636 + * R41 (0x29) - 3D control 637 + */ 638 + #define WM8985_DEPTH3D_MASK 0x000F /* DEPTH3D - [3:0] */ 639 + #define WM8985_DEPTH3D_SHIFT 0 /* DEPTH3D - [3:0] */ 640 + #define WM8985_DEPTH3D_WIDTH 4 /* DEPTH3D - [3:0] */ 641 + 642 + /* 643 + * R42 (0x2A) - OUT4 to ADC 644 + */ 645 + #define WM8985_OUT4_2ADCVOL_MASK 0x01C0 /* OUT4_2ADCVOL - [8:6] */ 646 + #define WM8985_OUT4_2ADCVOL_SHIFT 6 /* OUT4_2ADCVOL - [8:6] */ 647 + #define WM8985_OUT4_2ADCVOL_WIDTH 3 /* OUT4_2ADCVOL - [8:6] */ 648 + #define WM8985_OUT4_2LNR 0x0020 /* OUT4_2LNR */ 649 + #define WM8985_OUT4_2LNR_MASK 0x0020 /* OUT4_2LNR */ 650 + #define WM8985_OUT4_2LNR_SHIFT 5 /* OUT4_2LNR */ 651 + #define WM8985_OUT4_2LNR_WIDTH 1 /* OUT4_2LNR */ 652 + #define WM8985_POBCTRL 0x0004 /* POBCTRL */ 653 + #define WM8985_POBCTRL_MASK 0x0004 /* POBCTRL */ 654 + #define WM8985_POBCTRL_SHIFT 2 /* POBCTRL */ 655 + #define WM8985_POBCTRL_WIDTH 1 /* POBCTRL */ 656 + #define WM8985_DELEN 0x0002 /* DELEN */ 657 + #define WM8985_DELEN_MASK 0x0002 /* DELEN */ 658 + #define WM8985_DELEN_SHIFT 1 /* DELEN */ 659 + #define WM8985_DELEN_WIDTH 1 /* DELEN */ 660 + #define WM8985_OUT1DEL 0x0001 /* OUT1DEL */ 661 + #define WM8985_OUT1DEL_MASK 0x0001 /* OUT1DEL */ 662 + #define WM8985_OUT1DEL_SHIFT 0 /* OUT1DEL */ 663 + #define WM8985_OUT1DEL_WIDTH 1 /* OUT1DEL */ 664 + 665 + /* 666 + * R43 (0x2B) - Beep control 667 + */ 668 + #define WM8985_BYPL2RMIX 0x0100 /* BYPL2RMIX */ 669 + #define WM8985_BYPL2RMIX_MASK 0x0100 /* BYPL2RMIX */ 670 + #define WM8985_BYPL2RMIX_SHIFT 8 /* BYPL2RMIX */ 671 + #define WM8985_BYPL2RMIX_WIDTH 1 /* BYPL2RMIX */ 672 + #define WM8985_BYPR2LMIX 0x0080 /* BYPR2LMIX */ 673 + #define WM8985_BYPR2LMIX_MASK 0x0080 /* BYPR2LMIX */ 674 + #define WM8985_BYPR2LMIX_SHIFT 7 /* BYPR2LMIX */ 675 + #define WM8985_BYPR2LMIX_WIDTH 1 /* BYPR2LMIX */ 676 + #define WM8985_MUTERPGA2INV 0x0020 /* MUTERPGA2INV */ 677 + #define WM8985_MUTERPGA2INV_MASK 0x0020 /* MUTERPGA2INV */ 678 + #define WM8985_MUTERPGA2INV_SHIFT 5 /* MUTERPGA2INV */ 679 + #define WM8985_MUTERPGA2INV_WIDTH 1 /* MUTERPGA2INV */ 680 + #define WM8985_INVROUT2 0x0010 /* INVROUT2 */ 681 + #define WM8985_INVROUT2_MASK 0x0010 /* INVROUT2 */ 682 + #define WM8985_INVROUT2_SHIFT 4 /* INVROUT2 */ 683 + #define WM8985_INVROUT2_WIDTH 1 /* INVROUT2 */ 684 + #define WM8985_BEEPVOL_MASK 0x000E /* BEEPVOL - [3:1] */ 685 + #define WM8985_BEEPVOL_SHIFT 1 /* BEEPVOL - [3:1] */ 686 + #define WM8985_BEEPVOL_WIDTH 3 /* BEEPVOL - [3:1] */ 687 + #define WM8985_BEEPEN 0x0001 /* BEEPEN */ 688 + #define WM8985_BEEPEN_MASK 0x0001 /* BEEPEN */ 689 + #define WM8985_BEEPEN_SHIFT 0 /* BEEPEN */ 690 + #define WM8985_BEEPEN_WIDTH 1 /* BEEPEN */ 691 + 692 + /* 693 + * R44 (0x2C) - Input ctrl 694 + */ 695 + #define WM8985_MBVSEL 0x0100 /* MBVSEL */ 696 + #define WM8985_MBVSEL_MASK 0x0100 /* MBVSEL */ 697 + #define WM8985_MBVSEL_SHIFT 8 /* MBVSEL */ 698 + #define WM8985_MBVSEL_WIDTH 1 /* MBVSEL */ 699 + #define WM8985_R2_2INPPGA 0x0040 /* R2_2INPPGA */ 700 + #define WM8985_R2_2INPPGA_MASK 0x0040 /* R2_2INPPGA */ 701 + #define WM8985_R2_2INPPGA_SHIFT 6 /* R2_2INPPGA */ 702 + #define WM8985_R2_2INPPGA_WIDTH 1 /* R2_2INPPGA */ 703 + #define WM8985_RIN2INPPGA 0x0020 /* RIN2INPPGA */ 704 + #define WM8985_RIN2INPPGA_MASK 0x0020 /* RIN2INPPGA */ 705 + #define WM8985_RIN2INPPGA_SHIFT 5 /* RIN2INPPGA */ 706 + #define WM8985_RIN2INPPGA_WIDTH 1 /* RIN2INPPGA */ 707 + #define WM8985_RIP2INPPGA 0x0010 /* RIP2INPPGA */ 708 + #define WM8985_RIP2INPPGA_MASK 0x0010 /* RIP2INPPGA */ 709 + #define WM8985_RIP2INPPGA_SHIFT 4 /* RIP2INPPGA */ 710 + #define WM8985_RIP2INPPGA_WIDTH 1 /* RIP2INPPGA */ 711 + #define WM8985_L2_2INPPGA 0x0004 /* L2_2INPPGA */ 712 + #define WM8985_L2_2INPPGA_MASK 0x0004 /* L2_2INPPGA */ 713 + #define WM8985_L2_2INPPGA_SHIFT 2 /* L2_2INPPGA */ 714 + #define WM8985_L2_2INPPGA_WIDTH 1 /* L2_2INPPGA */ 715 + #define WM8985_LIN2INPPGA 0x0002 /* LIN2INPPGA */ 716 + #define WM8985_LIN2INPPGA_MASK 0x0002 /* LIN2INPPGA */ 717 + #define WM8985_LIN2INPPGA_SHIFT 1 /* LIN2INPPGA */ 718 + #define WM8985_LIN2INPPGA_WIDTH 1 /* LIN2INPPGA */ 719 + #define WM8985_LIP2INPPGA 0x0001 /* LIP2INPPGA */ 720 + #define WM8985_LIP2INPPGA_MASK 0x0001 /* LIP2INPPGA */ 721 + #define WM8985_LIP2INPPGA_SHIFT 0 /* LIP2INPPGA */ 722 + #define WM8985_LIP2INPPGA_WIDTH 1 /* LIP2INPPGA */ 723 + 724 + /* 725 + * R45 (0x2D) - Left INP PGA gain ctrl 726 + */ 727 + #define WM8985_INPGAVU 0x0100 /* INPGAVU */ 728 + #define WM8985_INPGAVU_MASK 0x0100 /* INPGAVU */ 729 + #define WM8985_INPGAVU_SHIFT 8 /* INPGAVU */ 730 + #define WM8985_INPGAVU_WIDTH 1 /* INPGAVU */ 731 + #define WM8985_INPPGAZCL 0x0080 /* INPPGAZCL */ 732 + #define WM8985_INPPGAZCL_MASK 0x0080 /* INPPGAZCL */ 733 + #define WM8985_INPPGAZCL_SHIFT 7 /* INPPGAZCL */ 734 + #define WM8985_INPPGAZCL_WIDTH 1 /* INPPGAZCL */ 735 + #define WM8985_INPPGAMUTEL 0x0040 /* INPPGAMUTEL */ 736 + #define WM8985_INPPGAMUTEL_MASK 0x0040 /* INPPGAMUTEL */ 737 + #define WM8985_INPPGAMUTEL_SHIFT 6 /* INPPGAMUTEL */ 738 + #define WM8985_INPPGAMUTEL_WIDTH 1 /* INPPGAMUTEL */ 739 + #define WM8985_INPPGAVOLL_MASK 0x003F /* INPPGAVOLL - [5:0] */ 740 + #define WM8985_INPPGAVOLL_SHIFT 0 /* INPPGAVOLL - [5:0] */ 741 + #define WM8985_INPPGAVOLL_WIDTH 6 /* INPPGAVOLL - [5:0] */ 742 + 743 + /* 744 + * R46 (0x2E) - Right INP PGA gain ctrl 745 + */ 746 + #define WM8985_INPGAVU 0x0100 /* INPGAVU */ 747 + #define WM8985_INPGAVU_MASK 0x0100 /* INPGAVU */ 748 + #define WM8985_INPGAVU_SHIFT 8 /* INPGAVU */ 749 + #define WM8985_INPGAVU_WIDTH 1 /* INPGAVU */ 750 + #define WM8985_INPPGAZCR 0x0080 /* INPPGAZCR */ 751 + #define WM8985_INPPGAZCR_MASK 0x0080 /* INPPGAZCR */ 752 + #define WM8985_INPPGAZCR_SHIFT 7 /* INPPGAZCR */ 753 + #define WM8985_INPPGAZCR_WIDTH 1 /* INPPGAZCR */ 754 + #define WM8985_INPPGAMUTER 0x0040 /* INPPGAMUTER */ 755 + #define WM8985_INPPGAMUTER_MASK 0x0040 /* INPPGAMUTER */ 756 + #define WM8985_INPPGAMUTER_SHIFT 6 /* INPPGAMUTER */ 757 + #define WM8985_INPPGAMUTER_WIDTH 1 /* INPPGAMUTER */ 758 + #define WM8985_INPPGAVOLR_MASK 0x003F /* INPPGAVOLR - [5:0] */ 759 + #define WM8985_INPPGAVOLR_SHIFT 0 /* INPPGAVOLR - [5:0] */ 760 + #define WM8985_INPPGAVOLR_WIDTH 6 /* INPPGAVOLR - [5:0] */ 761 + 762 + /* 763 + * R47 (0x2F) - Left ADC BOOST ctrl 764 + */ 765 + #define WM8985_PGABOOSTL 0x0100 /* PGABOOSTL */ 766 + #define WM8985_PGABOOSTL_MASK 0x0100 /* PGABOOSTL */ 767 + #define WM8985_PGABOOSTL_SHIFT 8 /* PGABOOSTL */ 768 + #define WM8985_PGABOOSTL_WIDTH 1 /* PGABOOSTL */ 769 + #define WM8985_L2_2BOOSTVOL_MASK 0x0070 /* L2_2BOOSTVOL - [6:4] */ 770 + #define WM8985_L2_2BOOSTVOL_SHIFT 4 /* L2_2BOOSTVOL - [6:4] */ 771 + #define WM8985_L2_2BOOSTVOL_WIDTH 3 /* L2_2BOOSTVOL - [6:4] */ 772 + #define WM8985_AUXL2BOOSTVOL_MASK 0x0007 /* AUXL2BOOSTVOL - [2:0] */ 773 + #define WM8985_AUXL2BOOSTVOL_SHIFT 0 /* AUXL2BOOSTVOL - [2:0] */ 774 + #define WM8985_AUXL2BOOSTVOL_WIDTH 3 /* AUXL2BOOSTVOL - [2:0] */ 775 + 776 + /* 777 + * R48 (0x30) - Right ADC BOOST ctrl 778 + */ 779 + #define WM8985_PGABOOSTR 0x0100 /* PGABOOSTR */ 780 + #define WM8985_PGABOOSTR_MASK 0x0100 /* PGABOOSTR */ 781 + #define WM8985_PGABOOSTR_SHIFT 8 /* PGABOOSTR */ 782 + #define WM8985_PGABOOSTR_WIDTH 1 /* PGABOOSTR */ 783 + #define WM8985_R2_2BOOSTVOL_MASK 0x0070 /* R2_2BOOSTVOL - [6:4] */ 784 + #define WM8985_R2_2BOOSTVOL_SHIFT 4 /* R2_2BOOSTVOL - [6:4] */ 785 + #define WM8985_R2_2BOOSTVOL_WIDTH 3 /* R2_2BOOSTVOL - [6:4] */ 786 + #define WM8985_AUXR2BOOSTVOL_MASK 0x0007 /* AUXR2BOOSTVOL - [2:0] */ 787 + #define WM8985_AUXR2BOOSTVOL_SHIFT 0 /* AUXR2BOOSTVOL - [2:0] */ 788 + #define WM8985_AUXR2BOOSTVOL_WIDTH 3 /* AUXR2BOOSTVOL - [2:0] */ 789 + 790 + /* 791 + * R49 (0x31) - Output ctrl 792 + */ 793 + #define WM8985_DACL2RMIX 0x0040 /* DACL2RMIX */ 794 + #define WM8985_DACL2RMIX_MASK 0x0040 /* DACL2RMIX */ 795 + #define WM8985_DACL2RMIX_SHIFT 6 /* DACL2RMIX */ 796 + #define WM8985_DACL2RMIX_WIDTH 1 /* DACL2RMIX */ 797 + #define WM8985_DACR2LMIX 0x0020 /* DACR2LMIX */ 798 + #define WM8985_DACR2LMIX_MASK 0x0020 /* DACR2LMIX */ 799 + #define WM8985_DACR2LMIX_SHIFT 5 /* DACR2LMIX */ 800 + #define WM8985_DACR2LMIX_WIDTH 1 /* DACR2LMIX */ 801 + #define WM8985_OUT4BOOST 0x0010 /* OUT4BOOST */ 802 + #define WM8985_OUT4BOOST_MASK 0x0010 /* OUT4BOOST */ 803 + #define WM8985_OUT4BOOST_SHIFT 4 /* OUT4BOOST */ 804 + #define WM8985_OUT4BOOST_WIDTH 1 /* OUT4BOOST */ 805 + #define WM8985_OUT3BOOST 0x0008 /* OUT3BOOST */ 806 + #define WM8985_OUT3BOOST_MASK 0x0008 /* OUT3BOOST */ 807 + #define WM8985_OUT3BOOST_SHIFT 3 /* OUT3BOOST */ 808 + #define WM8985_OUT3BOOST_WIDTH 1 /* OUT3BOOST */ 809 + #define WM8985_TSOPCTRL 0x0004 /* TSOPCTRL */ 810 + #define WM8985_TSOPCTRL_MASK 0x0004 /* TSOPCTRL */ 811 + #define WM8985_TSOPCTRL_SHIFT 2 /* TSOPCTRL */ 812 + #define WM8985_TSOPCTRL_WIDTH 1 /* TSOPCTRL */ 813 + #define WM8985_TSDEN 0x0002 /* TSDEN */ 814 + #define WM8985_TSDEN_MASK 0x0002 /* TSDEN */ 815 + #define WM8985_TSDEN_SHIFT 1 /* TSDEN */ 816 + #define WM8985_TSDEN_WIDTH 1 /* TSDEN */ 817 + #define WM8985_VROI 0x0001 /* VROI */ 818 + #define WM8985_VROI_MASK 0x0001 /* VROI */ 819 + #define WM8985_VROI_SHIFT 0 /* VROI */ 820 + #define WM8985_VROI_WIDTH 1 /* VROI */ 821 + 822 + /* 823 + * R50 (0x32) - Left mixer ctrl 824 + */ 825 + #define WM8985_AUXLMIXVOL_MASK 0x01C0 /* AUXLMIXVOL - [8:6] */ 826 + #define WM8985_AUXLMIXVOL_SHIFT 6 /* AUXLMIXVOL - [8:6] */ 827 + #define WM8985_AUXLMIXVOL_WIDTH 3 /* AUXLMIXVOL - [8:6] */ 828 + #define WM8985_AUXL2LMIX 0x0020 /* AUXL2LMIX */ 829 + #define WM8985_AUXL2LMIX_MASK 0x0020 /* AUXL2LMIX */ 830 + #define WM8985_AUXL2LMIX_SHIFT 5 /* AUXL2LMIX */ 831 + #define WM8985_AUXL2LMIX_WIDTH 1 /* AUXL2LMIX */ 832 + #define WM8985_BYPLMIXVOL_MASK 0x001C /* BYPLMIXVOL - [4:2] */ 833 + #define WM8985_BYPLMIXVOL_SHIFT 2 /* BYPLMIXVOL - [4:2] */ 834 + #define WM8985_BYPLMIXVOL_WIDTH 3 /* BYPLMIXVOL - [4:2] */ 835 + #define WM8985_BYPL2LMIX 0x0002 /* BYPL2LMIX */ 836 + #define WM8985_BYPL2LMIX_MASK 0x0002 /* BYPL2LMIX */ 837 + #define WM8985_BYPL2LMIX_SHIFT 1 /* BYPL2LMIX */ 838 + #define WM8985_BYPL2LMIX_WIDTH 1 /* BYPL2LMIX */ 839 + #define WM8985_DACL2LMIX 0x0001 /* DACL2LMIX */ 840 + #define WM8985_DACL2LMIX_MASK 0x0001 /* DACL2LMIX */ 841 + #define WM8985_DACL2LMIX_SHIFT 0 /* DACL2LMIX */ 842 + #define WM8985_DACL2LMIX_WIDTH 1 /* DACL2LMIX */ 843 + 844 + /* 845 + * R51 (0x33) - Right mixer ctrl 846 + */ 847 + #define WM8985_AUXRMIXVOL_MASK 0x01C0 /* AUXRMIXVOL - [8:6] */ 848 + #define WM8985_AUXRMIXVOL_SHIFT 6 /* AUXRMIXVOL - [8:6] */ 849 + #define WM8985_AUXRMIXVOL_WIDTH 3 /* AUXRMIXVOL - [8:6] */ 850 + #define WM8985_AUXR2RMIX 0x0020 /* AUXR2RMIX */ 851 + #define WM8985_AUXR2RMIX_MASK 0x0020 /* AUXR2RMIX */ 852 + #define WM8985_AUXR2RMIX_SHIFT 5 /* AUXR2RMIX */ 853 + #define WM8985_AUXR2RMIX_WIDTH 1 /* AUXR2RMIX */ 854 + #define WM8985_BYPRMIXVOL_MASK 0x001C /* BYPRMIXVOL - [4:2] */ 855 + #define WM8985_BYPRMIXVOL_SHIFT 2 /* BYPRMIXVOL - [4:2] */ 856 + #define WM8985_BYPRMIXVOL_WIDTH 3 /* BYPRMIXVOL - [4:2] */ 857 + #define WM8985_BYPR2RMIX 0x0002 /* BYPR2RMIX */ 858 + #define WM8985_BYPR2RMIX_MASK 0x0002 /* BYPR2RMIX */ 859 + #define WM8985_BYPR2RMIX_SHIFT 1 /* BYPR2RMIX */ 860 + #define WM8985_BYPR2RMIX_WIDTH 1 /* BYPR2RMIX */ 861 + #define WM8985_DACR2RMIX 0x0001 /* DACR2RMIX */ 862 + #define WM8985_DACR2RMIX_MASK 0x0001 /* DACR2RMIX */ 863 + #define WM8985_DACR2RMIX_SHIFT 0 /* DACR2RMIX */ 864 + #define WM8985_DACR2RMIX_WIDTH 1 /* DACR2RMIX */ 865 + 866 + /* 867 + * R52 (0x34) - LOUT1 (HP) volume ctrl 868 + */ 869 + #define WM8985_OUT1VU 0x0100 /* OUT1VU */ 870 + #define WM8985_OUT1VU_MASK 0x0100 /* OUT1VU */ 871 + #define WM8985_OUT1VU_SHIFT 8 /* OUT1VU */ 872 + #define WM8985_OUT1VU_WIDTH 1 /* OUT1VU */ 873 + #define WM8985_LOUT1ZC 0x0080 /* LOUT1ZC */ 874 + #define WM8985_LOUT1ZC_MASK 0x0080 /* LOUT1ZC */ 875 + #define WM8985_LOUT1ZC_SHIFT 7 /* LOUT1ZC */ 876 + #define WM8985_LOUT1ZC_WIDTH 1 /* LOUT1ZC */ 877 + #define WM8985_LOUT1MUTE 0x0040 /* LOUT1MUTE */ 878 + #define WM8985_LOUT1MUTE_MASK 0x0040 /* LOUT1MUTE */ 879 + #define WM8985_LOUT1MUTE_SHIFT 6 /* LOUT1MUTE */ 880 + #define WM8985_LOUT1MUTE_WIDTH 1 /* LOUT1MUTE */ 881 + #define WM8985_LOUT1VOL_MASK 0x003F /* LOUT1VOL - [5:0] */ 882 + #define WM8985_LOUT1VOL_SHIFT 0 /* LOUT1VOL - [5:0] */ 883 + #define WM8985_LOUT1VOL_WIDTH 6 /* LOUT1VOL - [5:0] */ 884 + 885 + /* 886 + * R53 (0x35) - ROUT1 (HP) volume ctrl 887 + */ 888 + #define WM8985_OUT1VU 0x0100 /* OUT1VU */ 889 + #define WM8985_OUT1VU_MASK 0x0100 /* OUT1VU */ 890 + #define WM8985_OUT1VU_SHIFT 8 /* OUT1VU */ 891 + #define WM8985_OUT1VU_WIDTH 1 /* OUT1VU */ 892 + #define WM8985_ROUT1ZC 0x0080 /* ROUT1ZC */ 893 + #define WM8985_ROUT1ZC_MASK 0x0080 /* ROUT1ZC */ 894 + #define WM8985_ROUT1ZC_SHIFT 7 /* ROUT1ZC */ 895 + #define WM8985_ROUT1ZC_WIDTH 1 /* ROUT1ZC */ 896 + #define WM8985_ROUT1MUTE 0x0040 /* ROUT1MUTE */ 897 + #define WM8985_ROUT1MUTE_MASK 0x0040 /* ROUT1MUTE */ 898 + #define WM8985_ROUT1MUTE_SHIFT 6 /* ROUT1MUTE */ 899 + #define WM8985_ROUT1MUTE_WIDTH 1 /* ROUT1MUTE */ 900 + #define WM8985_ROUT1VOL_MASK 0x003F /* ROUT1VOL - [5:0] */ 901 + #define WM8985_ROUT1VOL_SHIFT 0 /* ROUT1VOL - [5:0] */ 902 + #define WM8985_ROUT1VOL_WIDTH 6 /* ROUT1VOL - [5:0] */ 903 + 904 + /* 905 + * R54 (0x36) - LOUT2 (SPK) volume ctrl 906 + */ 907 + #define WM8985_OUT2VU 0x0100 /* OUT2VU */ 908 + #define WM8985_OUT2VU_MASK 0x0100 /* OUT2VU */ 909 + #define WM8985_OUT2VU_SHIFT 8 /* OUT2VU */ 910 + #define WM8985_OUT2VU_WIDTH 1 /* OUT2VU */ 911 + #define WM8985_LOUT2ZC 0x0080 /* LOUT2ZC */ 912 + #define WM8985_LOUT2ZC_MASK 0x0080 /* LOUT2ZC */ 913 + #define WM8985_LOUT2ZC_SHIFT 7 /* LOUT2ZC */ 914 + #define WM8985_LOUT2ZC_WIDTH 1 /* LOUT2ZC */ 915 + #define WM8985_LOUT2MUTE 0x0040 /* LOUT2MUTE */ 916 + #define WM8985_LOUT2MUTE_MASK 0x0040 /* LOUT2MUTE */ 917 + #define WM8985_LOUT2MUTE_SHIFT 6 /* LOUT2MUTE */ 918 + #define WM8985_LOUT2MUTE_WIDTH 1 /* LOUT2MUTE */ 919 + #define WM8985_LOUT2VOL_MASK 0x003F /* LOUT2VOL - [5:0] */ 920 + #define WM8985_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [5:0] */ 921 + #define WM8985_LOUT2VOL_WIDTH 6 /* LOUT2VOL - [5:0] */ 922 + 923 + /* 924 + * R55 (0x37) - ROUT2 (SPK) volume ctrl 925 + */ 926 + #define WM8985_OUT2VU 0x0100 /* OUT2VU */ 927 + #define WM8985_OUT2VU_MASK 0x0100 /* OUT2VU */ 928 + #define WM8985_OUT2VU_SHIFT 8 /* OUT2VU */ 929 + #define WM8985_OUT2VU_WIDTH 1 /* OUT2VU */ 930 + #define WM8985_ROUT2ZC 0x0080 /* ROUT2ZC */ 931 + #define WM8985_ROUT2ZC_MASK 0x0080 /* ROUT2ZC */ 932 + #define WM8985_ROUT2ZC_SHIFT 7 /* ROUT2ZC */ 933 + #define WM8985_ROUT2ZC_WIDTH 1 /* ROUT2ZC */ 934 + #define WM8985_ROUT2MUTE 0x0040 /* ROUT2MUTE */ 935 + #define WM8985_ROUT2MUTE_MASK 0x0040 /* ROUT2MUTE */ 936 + #define WM8985_ROUT2MUTE_SHIFT 6 /* ROUT2MUTE */ 937 + #define WM8985_ROUT2MUTE_WIDTH 1 /* ROUT2MUTE */ 938 + #define WM8985_ROUT2VOL_MASK 0x003F /* ROUT2VOL - [5:0] */ 939 + #define WM8985_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [5:0] */ 940 + #define WM8985_ROUT2VOL_WIDTH 6 /* ROUT2VOL - [5:0] */ 941 + 942 + /* 943 + * R56 (0x38) - OUT3 mixer ctrl 944 + */ 945 + #define WM8985_OUT3MUTE 0x0040 /* OUT3MUTE */ 946 + #define WM8985_OUT3MUTE_MASK 0x0040 /* OUT3MUTE */ 947 + #define WM8985_OUT3MUTE_SHIFT 6 /* OUT3MUTE */ 948 + #define WM8985_OUT3MUTE_WIDTH 1 /* OUT3MUTE */ 949 + #define WM8985_OUT4_2OUT3 0x0008 /* OUT4_2OUT3 */ 950 + #define WM8985_OUT4_2OUT3_MASK 0x0008 /* OUT4_2OUT3 */ 951 + #define WM8985_OUT4_2OUT3_SHIFT 3 /* OUT4_2OUT3 */ 952 + #define WM8985_OUT4_2OUT3_WIDTH 1 /* OUT4_2OUT3 */ 953 + #define WM8985_BYPL2OUT3 0x0004 /* BYPL2OUT3 */ 954 + #define WM8985_BYPL2OUT3_MASK 0x0004 /* BYPL2OUT3 */ 955 + #define WM8985_BYPL2OUT3_SHIFT 2 /* BYPL2OUT3 */ 956 + #define WM8985_BYPL2OUT3_WIDTH 1 /* BYPL2OUT3 */ 957 + #define WM8985_LMIX2OUT3 0x0002 /* LMIX2OUT3 */ 958 + #define WM8985_LMIX2OUT3_MASK 0x0002 /* LMIX2OUT3 */ 959 + #define WM8985_LMIX2OUT3_SHIFT 1 /* LMIX2OUT3 */ 960 + #define WM8985_LMIX2OUT3_WIDTH 1 /* LMIX2OUT3 */ 961 + #define WM8985_LDAC2OUT3 0x0001 /* LDAC2OUT3 */ 962 + #define WM8985_LDAC2OUT3_MASK 0x0001 /* LDAC2OUT3 */ 963 + #define WM8985_LDAC2OUT3_SHIFT 0 /* LDAC2OUT3 */ 964 + #define WM8985_LDAC2OUT3_WIDTH 1 /* LDAC2OUT3 */ 965 + 966 + /* 967 + * R57 (0x39) - OUT4 (MONO) mix ctrl 968 + */ 969 + #define WM8985_OUT3_2OUT4 0x0080 /* OUT3_2OUT4 */ 970 + #define WM8985_OUT3_2OUT4_MASK 0x0080 /* OUT3_2OUT4 */ 971 + #define WM8985_OUT3_2OUT4_SHIFT 7 /* OUT3_2OUT4 */ 972 + #define WM8985_OUT3_2OUT4_WIDTH 1 /* OUT3_2OUT4 */ 973 + #define WM8985_OUT4MUTE 0x0040 /* OUT4MUTE */ 974 + #define WM8985_OUT4MUTE_MASK 0x0040 /* OUT4MUTE */ 975 + #define WM8985_OUT4MUTE_SHIFT 6 /* OUT4MUTE */ 976 + #define WM8985_OUT4MUTE_WIDTH 1 /* OUT4MUTE */ 977 + #define WM8985_OUT4ATTN 0x0020 /* OUT4ATTN */ 978 + #define WM8985_OUT4ATTN_MASK 0x0020 /* OUT4ATTN */ 979 + #define WM8985_OUT4ATTN_SHIFT 5 /* OUT4ATTN */ 980 + #define WM8985_OUT4ATTN_WIDTH 1 /* OUT4ATTN */ 981 + #define WM8985_LMIX2OUT4 0x0010 /* LMIX2OUT4 */ 982 + #define WM8985_LMIX2OUT4_MASK 0x0010 /* LMIX2OUT4 */ 983 + #define WM8985_LMIX2OUT4_SHIFT 4 /* LMIX2OUT4 */ 984 + #define WM8985_LMIX2OUT4_WIDTH 1 /* LMIX2OUT4 */ 985 + #define WM8985_LDAC2OUT4 0x0008 /* LDAC2OUT4 */ 986 + #define WM8985_LDAC2OUT4_MASK 0x0008 /* LDAC2OUT4 */ 987 + #define WM8985_LDAC2OUT4_SHIFT 3 /* LDAC2OUT4 */ 988 + #define WM8985_LDAC2OUT4_WIDTH 1 /* LDAC2OUT4 */ 989 + #define WM8985_BYPR2OUT4 0x0004 /* BYPR2OUT4 */ 990 + #define WM8985_BYPR2OUT4_MASK 0x0004 /* BYPR2OUT4 */ 991 + #define WM8985_BYPR2OUT4_SHIFT 2 /* BYPR2OUT4 */ 992 + #define WM8985_BYPR2OUT4_WIDTH 1 /* BYPR2OUT4 */ 993 + #define WM8985_RMIX2OUT4 0x0002 /* RMIX2OUT4 */ 994 + #define WM8985_RMIX2OUT4_MASK 0x0002 /* RMIX2OUT4 */ 995 + #define WM8985_RMIX2OUT4_SHIFT 1 /* RMIX2OUT4 */ 996 + #define WM8985_RMIX2OUT4_WIDTH 1 /* RMIX2OUT4 */ 997 + #define WM8985_RDAC2OUT4 0x0001 /* RDAC2OUT4 */ 998 + #define WM8985_RDAC2OUT4_MASK 0x0001 /* RDAC2OUT4 */ 999 + #define WM8985_RDAC2OUT4_SHIFT 0 /* RDAC2OUT4 */ 1000 + #define WM8985_RDAC2OUT4_WIDTH 1 /* RDAC2OUT4 */ 1001 + 1002 + /* 1003 + * R60 (0x3C) - OUTPUT ctrl 1004 + */ 1005 + #define WM8985_VIDBUFFTST_MASK 0x01E0 /* VIDBUFFTST - [8:5] */ 1006 + #define WM8985_VIDBUFFTST_SHIFT 5 /* VIDBUFFTST - [8:5] */ 1007 + #define WM8985_VIDBUFFTST_WIDTH 4 /* VIDBUFFTST - [8:5] */ 1008 + #define WM8985_HPTOG 0x0008 /* HPTOG */ 1009 + #define WM8985_HPTOG_MASK 0x0008 /* HPTOG */ 1010 + #define WM8985_HPTOG_SHIFT 3 /* HPTOG */ 1011 + #define WM8985_HPTOG_WIDTH 1 /* HPTOG */ 1012 + 1013 + /* 1014 + * R61 (0x3D) - BIAS CTRL 1015 + */ 1016 + #define WM8985_BIASCUT 0x0100 /* BIASCUT */ 1017 + #define WM8985_BIASCUT_MASK 0x0100 /* BIASCUT */ 1018 + #define WM8985_BIASCUT_SHIFT 8 /* BIASCUT */ 1019 + #define WM8985_BIASCUT_WIDTH 1 /* BIASCUT */ 1020 + #define WM8985_HALFIPBIAS 0x0080 /* HALFIPBIAS */ 1021 + #define WM8985_HALFIPBIAS_MASK 0x0080 /* HALFIPBIAS */ 1022 + #define WM8985_HALFIPBIAS_SHIFT 7 /* HALFIPBIAS */ 1023 + #define WM8985_HALFIPBIAS_WIDTH 1 /* HALFIPBIAS */ 1024 + #define WM8985_VBBIASTST_MASK 0x0060 /* VBBIASTST - [6:5] */ 1025 + #define WM8985_VBBIASTST_SHIFT 5 /* VBBIASTST - [6:5] */ 1026 + #define WM8985_VBBIASTST_WIDTH 2 /* VBBIASTST - [6:5] */ 1027 + #define WM8985_BUFBIAS_MASK 0x0018 /* BUFBIAS - [4:3] */ 1028 + #define WM8985_BUFBIAS_SHIFT 3 /* BUFBIAS - [4:3] */ 1029 + #define WM8985_BUFBIAS_WIDTH 2 /* BUFBIAS - [4:3] */ 1030 + #define WM8985_ADCBIAS_MASK 0x0006 /* ADCBIAS - [2:1] */ 1031 + #define WM8985_ADCBIAS_SHIFT 1 /* ADCBIAS - [2:1] */ 1032 + #define WM8985_ADCBIAS_WIDTH 2 /* ADCBIAS - [2:1] */ 1033 + #define WM8985_HALFOPBIAS 0x0001 /* HALFOPBIAS */ 1034 + #define WM8985_HALFOPBIAS_MASK 0x0001 /* HALFOPBIAS */ 1035 + #define WM8985_HALFOPBIAS_SHIFT 0 /* HALFOPBIAS */ 1036 + #define WM8985_HALFOPBIAS_WIDTH 1 /* HALFOPBIAS */ 1037 + 1038 + enum clk_src { 1039 + WM8985_CLKSRC_MCLK, 1040 + WM8985_CLKSRC_PLL 1041 + }; 1042 + 1043 + #define WM8985_PLL 0 1044 + 1045 + #endif