1 /* 2 * wm8400.c -- WM8400 ALSA Soc Audio driver 3 * 4 * Copyright 2008, 2009 Wolfson Microelectronics PLC. 5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 * 12 */ 13 14 #include <linux/module.h> 15 #include <linux/moduleparam.h> 16 #include <linux/kernel.h> 17 #include <linux/slab.h> 18 #include <linux/init.h> 19 #include <linux/delay.h> 20 #include <linux/pm.h> 21 #include <linux/platform_device.h> 22 #include <linux/regulator/consumer.h> 23 #include <linux/mfd/wm8400-audio.h> 24 #include <linux/mfd/wm8400-private.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/initval.h> 30 #include <sound/tlv.h> 31 32 #include "wm8400.h" 33 34 /* Fake register for internal state */ 35 #define WM8400_INTDRIVBITS (WM8400_REGISTER_COUNT + 1) 36 #define WM8400_INMIXL_PWR 0 37 #define WM8400_AINLMUX_PWR 1 38 #define WM8400_INMIXR_PWR 2 39 #define WM8400_AINRMUX_PWR 3 40 41 static struct regulator_bulk_data power[] = { 42 { 43 .supply = "I2S1VDD", 44 }, 45 { 46 .supply = "I2S2VDD", 47 }, 48 { 49 .supply = "DCVDD", 50 }, 51 { 52 .supply = "AVDD", 53 }, 54 { 55 .supply = "FLLVDD", 56 }, 57 { 58 .supply = "HPVDD", 59 }, 60 { 61 .supply = "SPKVDD", 62 }, 63 }; 64 65 /* codec private data */ 66 struct wm8400_priv { 67 struct snd_soc_codec *codec; 68 struct wm8400 *wm8400; 69 u16 fake_register; 70 unsigned int sysclk; 71 unsigned int pcmclk; 72 struct work_struct work; 73 int fll_in, fll_out; 74 }; 75 76 static inline unsigned int wm8400_read(struct snd_soc_codec *codec, 77 unsigned int reg) 78 { 79 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec); 80 81 if (reg == WM8400_INTDRIVBITS) 82 return wm8400->fake_register; 83 else 84 return wm8400_reg_read(wm8400->wm8400, reg); 85 } 86 87 /* 88 * write to the wm8400 register space 89 */ 90 static int wm8400_write(struct snd_soc_codec *codec, unsigned int reg, 91 unsigned int value) 92 { 93 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec); 94 95 if (reg == WM8400_INTDRIVBITS) { 96 wm8400->fake_register = value; 97 return 0; 98 } else 99 return wm8400_set_bits(wm8400->wm8400, reg, 0xffff, value); 100 } 101 102 static void wm8400_codec_reset(struct snd_soc_codec *codec) 103 { 104 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec); 105 106 wm8400_reset_codec_reg_cache(wm8400->wm8400); 107 } 108 109 static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 600, 0); 110 111 static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1650, 3000, 0); 112 113 static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -2100, 0, 0); 114 115 static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -7300, 600, 0); 116 117 static const DECLARE_TLV_DB_SCALE(out_omix_tlv, -600, 0, 0); 118 119 static const DECLARE_TLV_DB_SCALE(out_dac_tlv, -7163, 0, 0); 120 121 static const DECLARE_TLV_DB_SCALE(in_adc_tlv, -7163, 1763, 0); 122 123 static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0); 124 125 static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, 126 struct snd_ctl_elem_value *ucontrol) 127 { 128 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 129 struct soc_mixer_control *mc = 130 (struct soc_mixer_control *)kcontrol->private_value; 131 int reg = mc->reg; 132 int ret; 133 u16 val; 134 135 ret = snd_soc_put_volsw(kcontrol, ucontrol); 136 if (ret < 0) 137 return ret; 138 139 /* now hit the volume update bits (always bit 8) */ 140 val = wm8400_read(codec, reg); 141 return wm8400_write(codec, reg, val | 0x0100); 142 } 143 144 #define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \ 145 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 146 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 147 SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 148 .tlv.p = (tlv_array), \ 149 .info = snd_soc_info_volsw, \ 150 .get = snd_soc_get_volsw, .put = wm8400_outpga_put_volsw_vu, \ 151 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } 152 153 154 static const char *wm8400_digital_sidetone[] = 155 {"None", "Left ADC", "Right ADC", "Reserved"}; 156 157 static const struct soc_enum wm8400_left_digital_sidetone_enum = 158 SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, 159 WM8400_ADC_TO_DACL_SHIFT, 2, wm8400_digital_sidetone); 160 161 static const struct soc_enum wm8400_right_digital_sidetone_enum = 162 SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE, 163 WM8400_ADC_TO_DACR_SHIFT, 2, wm8400_digital_sidetone); 164 165 static const char *wm8400_adcmode[] = 166 {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"}; 167 168 static const struct soc_enum wm8400_right_adcmode_enum = 169 SOC_ENUM_SINGLE(WM8400_ADC_CTRL, WM8400_ADC_HPF_CUT_SHIFT, 3, wm8400_adcmode); 170 171 static const struct snd_kcontrol_new wm8400_snd_controls[] = { 172 /* INMIXL */ 173 SOC_SINGLE("LIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L12MNBST_SHIFT, 174 1, 0), 175 SOC_SINGLE("LIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L34MNBST_SHIFT, 176 1, 0), 177 /* INMIXR */ 178 SOC_SINGLE("RIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R12MNBST_SHIFT, 179 1, 0), 180 SOC_SINGLE("RIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R34MNBST_SHIFT, 181 1, 0), 182 183 /* LOMIX */ 184 SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER3, 185 WM8400_LLI3LOVOL_SHIFT, 7, 0, out_mix_tlv), 186 SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3, 187 WM8400_LR12LOVOL_SHIFT, 7, 0, out_mix_tlv), 188 SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3, 189 WM8400_LL12LOVOL_SHIFT, 7, 0, out_mix_tlv), 190 SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER5, 191 WM8400_LRI3LOVOL_SHIFT, 7, 0, out_mix_tlv), 192 SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER5, 193 WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv), 194 SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER5, 195 WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv), 196 197 /* ROMIX */ 198 SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER4, 199 WM8400_RRI3ROVOL_SHIFT, 7, 0, out_mix_tlv), 200 SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4, 201 WM8400_RL12ROVOL_SHIFT, 7, 0, out_mix_tlv), 202 SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4, 203 WM8400_RR12ROVOL_SHIFT, 7, 0, out_mix_tlv), 204 SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER6, 205 WM8400_RLI3ROVOL_SHIFT, 7, 0, out_mix_tlv), 206 SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER6, 207 WM8400_RLBROVOL_SHIFT, 7, 0, out_mix_tlv), 208 SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER6, 209 WM8400_RRBROVOL_SHIFT, 7, 0, out_mix_tlv), 210 211 /* LOUT */ 212 WM8400_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8400_LEFT_OUTPUT_VOLUME, 213 WM8400_LOUTVOL_SHIFT, WM8400_LOUTVOL_MASK, 0, out_pga_tlv), 214 SOC_SINGLE("LOUT ZC", WM8400_LEFT_OUTPUT_VOLUME, WM8400_LOZC_SHIFT, 1, 0), 215 216 /* ROUT */ 217 WM8400_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8400_RIGHT_OUTPUT_VOLUME, 218 WM8400_ROUTVOL_SHIFT, WM8400_ROUTVOL_MASK, 0, out_pga_tlv), 219 SOC_SINGLE("ROUT ZC", WM8400_RIGHT_OUTPUT_VOLUME, WM8400_ROZC_SHIFT, 1, 0), 220 221 /* LOPGA */ 222 WM8400_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8400_LEFT_OPGA_VOLUME, 223 WM8400_LOPGAVOL_SHIFT, WM8400_LOPGAVOL_MASK, 0, out_pga_tlv), 224 SOC_SINGLE("LOPGA ZC Switch", WM8400_LEFT_OPGA_VOLUME, 225 WM8400_LOPGAZC_SHIFT, 1, 0), 226 227 /* ROPGA */ 228 WM8400_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8400_RIGHT_OPGA_VOLUME, 229 WM8400_ROPGAVOL_SHIFT, WM8400_ROPGAVOL_MASK, 0, out_pga_tlv), 230 SOC_SINGLE("ROPGA ZC Switch", WM8400_RIGHT_OPGA_VOLUME, 231 WM8400_ROPGAZC_SHIFT, 1, 0), 232 233 SOC_SINGLE("LON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME, 234 WM8400_LONMUTE_SHIFT, 1, 0), 235 SOC_SINGLE("LOP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME, 236 WM8400_LOPMUTE_SHIFT, 1, 0), 237 SOC_SINGLE("LOP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME, 238 WM8400_LOATTN_SHIFT, 1, 0), 239 SOC_SINGLE("RON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME, 240 WM8400_RONMUTE_SHIFT, 1, 0), 241 SOC_SINGLE("ROP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME, 242 WM8400_ROPMUTE_SHIFT, 1, 0), 243 SOC_SINGLE("ROP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME, 244 WM8400_ROATTN_SHIFT, 1, 0), 245 246 SOC_SINGLE("OUT3 Mute Switch", WM8400_OUT3_4_VOLUME, 247 WM8400_OUT3MUTE_SHIFT, 1, 0), 248 SOC_SINGLE("OUT3 Attenuation Switch", WM8400_OUT3_4_VOLUME, 249 WM8400_OUT3ATTN_SHIFT, 1, 0), 250 251 SOC_SINGLE("OUT4 Mute Switch", WM8400_OUT3_4_VOLUME, 252 WM8400_OUT4MUTE_SHIFT, 1, 0), 253 SOC_SINGLE("OUT4 Attenuation Switch", WM8400_OUT3_4_VOLUME, 254 WM8400_OUT4ATTN_SHIFT, 1, 0), 255 256 SOC_SINGLE("Speaker Mode Switch", WM8400_CLASSD1, 257 WM8400_CDMODE_SHIFT, 1, 0), 258 259 SOC_SINGLE("Speaker Output Attenuation Volume", WM8400_SPEAKER_VOLUME, 260 WM8400_SPKATTN_SHIFT, WM8400_SPKATTN_MASK, 0), 261 SOC_SINGLE("Speaker DC Boost Volume", WM8400_CLASSD3, 262 WM8400_DCGAIN_SHIFT, 6, 0), 263 SOC_SINGLE("Speaker AC Boost Volume", WM8400_CLASSD3, 264 WM8400_ACGAIN_SHIFT, 6, 0), 265 266 WM8400_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume", 267 WM8400_LEFT_DAC_DIGITAL_VOLUME, WM8400_DACL_VOL_SHIFT, 268 127, 0, out_dac_tlv), 269 270 WM8400_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume", 271 WM8400_RIGHT_DAC_DIGITAL_VOLUME, WM8400_DACR_VOL_SHIFT, 272 127, 0, out_dac_tlv), 273 274 SOC_ENUM("Left Digital Sidetone", wm8400_left_digital_sidetone_enum), 275 SOC_ENUM("Right Digital Sidetone", wm8400_right_digital_sidetone_enum), 276 277 SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE, 278 WM8400_ADCL_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv), 279 SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE, 280 WM8400_ADCR_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv), 281 282 SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8400_ADC_CTRL, 283 WM8400_ADC_HPF_ENA_SHIFT, 1, 0), 284 285 SOC_ENUM("ADC HPF Mode", wm8400_right_adcmode_enum), 286 287 WM8400_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume", 288 WM8400_LEFT_ADC_DIGITAL_VOLUME, 289 WM8400_ADCL_VOL_SHIFT, 290 WM8400_ADCL_VOL_MASK, 291 0, 292 in_adc_tlv), 293 294 WM8400_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume", 295 WM8400_RIGHT_ADC_DIGITAL_VOLUME, 296 WM8400_ADCR_VOL_SHIFT, 297 WM8400_ADCR_VOL_MASK, 298 0, 299 in_adc_tlv), 300 301 WM8400_OUTPGA_SINGLE_R_TLV("LIN12 Volume", 302 WM8400_LEFT_LINE_INPUT_1_2_VOLUME, 303 WM8400_LIN12VOL_SHIFT, 304 WM8400_LIN12VOL_MASK, 305 0, 306 in_pga_tlv), 307 308 SOC_SINGLE("LIN12 ZC Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME, 309 WM8400_LI12ZC_SHIFT, 1, 0), 310 311 SOC_SINGLE("LIN12 Mute Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME, 312 WM8400_LI12MUTE_SHIFT, 1, 0), 313 314 WM8400_OUTPGA_SINGLE_R_TLV("LIN34 Volume", 315 WM8400_LEFT_LINE_INPUT_3_4_VOLUME, 316 WM8400_LIN34VOL_SHIFT, 317 WM8400_LIN34VOL_MASK, 318 0, 319 in_pga_tlv), 320 321 SOC_SINGLE("LIN34 ZC Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME, 322 WM8400_LI34ZC_SHIFT, 1, 0), 323 324 SOC_SINGLE("LIN34 Mute Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME, 325 WM8400_LI34MUTE_SHIFT, 1, 0), 326 327 WM8400_OUTPGA_SINGLE_R_TLV("RIN12 Volume", 328 WM8400_RIGHT_LINE_INPUT_1_2_VOLUME, 329 WM8400_RIN12VOL_SHIFT, 330 WM8400_RIN12VOL_MASK, 331 0, 332 in_pga_tlv), 333 334 SOC_SINGLE("RIN12 ZC Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME, 335 WM8400_RI12ZC_SHIFT, 1, 0), 336 337 SOC_SINGLE("RIN12 Mute Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME, 338 WM8400_RI12MUTE_SHIFT, 1, 0), 339 340 WM8400_OUTPGA_SINGLE_R_TLV("RIN34 Volume", 341 WM8400_RIGHT_LINE_INPUT_3_4_VOLUME, 342 WM8400_RIN34VOL_SHIFT, 343 WM8400_RIN34VOL_MASK, 344 0, 345 in_pga_tlv), 346 347 SOC_SINGLE("RIN34 ZC Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME, 348 WM8400_RI34ZC_SHIFT, 1, 0), 349 350 SOC_SINGLE("RIN34 Mute Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME, 351 WM8400_RI34MUTE_SHIFT, 1, 0), 352 353 }; 354 355 /* add non dapm controls */ 356 static int wm8400_add_controls(struct snd_soc_codec *codec) 357 { 358 return snd_soc_add_controls(codec, wm8400_snd_controls, 359 ARRAY_SIZE(wm8400_snd_controls)); 360 } 361 362 /* 363 * _DAPM_ Controls 364 */ 365 366 static int inmixer_event (struct snd_soc_dapm_widget *w, 367 struct snd_kcontrol *kcontrol, int event) 368 { 369 u16 reg, fakepower; 370 371 reg = wm8400_read(w->codec, WM8400_POWER_MANAGEMENT_2); 372 fakepower = wm8400_read(w->codec, WM8400_INTDRIVBITS); 373 374 if (fakepower & ((1 << WM8400_INMIXL_PWR) | 375 (1 << WM8400_AINLMUX_PWR))) { 376 reg |= WM8400_AINL_ENA; 377 } else { 378 reg &= ~WM8400_AINL_ENA; 379 } 380 381 if (fakepower & ((1 << WM8400_INMIXR_PWR) | 382 (1 << WM8400_AINRMUX_PWR))) { 383 reg |= WM8400_AINR_ENA; 384 } else { 385 reg &= ~WM8400_AINL_ENA; 386 } 387 wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg); 388 389 return 0; 390 } 391 392 static int outmixer_event (struct snd_soc_dapm_widget *w, 393 struct snd_kcontrol * kcontrol, int event) 394 { 395 struct soc_mixer_control *mc = 396 (struct soc_mixer_control *)kcontrol->private_value; 397 u32 reg_shift = mc->shift; 398 int ret = 0; 399 u16 reg; 400 401 switch (reg_shift) { 402 case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) : 403 reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER1); 404 if (reg & WM8400_LDLO) { 405 printk(KERN_WARNING 406 "Cannot set as Output Mixer 1 LDLO Set\n"); 407 ret = -1; 408 } 409 break; 410 case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8): 411 reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER2); 412 if (reg & WM8400_RDRO) { 413 printk(KERN_WARNING 414 "Cannot set as Output Mixer 2 RDRO Set\n"); 415 ret = -1; 416 } 417 break; 418 case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8): 419 reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER); 420 if (reg & WM8400_LDSPK) { 421 printk(KERN_WARNING 422 "Cannot set as Speaker Mixer LDSPK Set\n"); 423 ret = -1; 424 } 425 break; 426 case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8): 427 reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER); 428 if (reg & WM8400_RDSPK) { 429 printk(KERN_WARNING 430 "Cannot set as Speaker Mixer RDSPK Set\n"); 431 ret = -1; 432 } 433 break; 434 } 435 436 return ret; 437 } 438 439 /* INMIX dB values */ 440 static const unsigned int in_mix_tlv[] = { 441 TLV_DB_RANGE_HEAD(1), 442 0,7, TLV_DB_SCALE_ITEM(-1200, 600, 0), 443 }; 444 445 /* Left In PGA Connections */ 446 static const struct snd_kcontrol_new wm8400_dapm_lin12_pga_controls[] = { 447 SOC_DAPM_SINGLE("LIN1 Switch", WM8400_INPUT_MIXER2, WM8400_LMN1_SHIFT, 1, 0), 448 SOC_DAPM_SINGLE("LIN2 Switch", WM8400_INPUT_MIXER2, WM8400_LMP2_SHIFT, 1, 0), 449 }; 450 451 static const struct snd_kcontrol_new wm8400_dapm_lin34_pga_controls[] = { 452 SOC_DAPM_SINGLE("LIN3 Switch", WM8400_INPUT_MIXER2, WM8400_LMN3_SHIFT, 1, 0), 453 SOC_DAPM_SINGLE("LIN4 Switch", WM8400_INPUT_MIXER2, WM8400_LMP4_SHIFT, 1, 0), 454 }; 455 456 /* Right In PGA Connections */ 457 static const struct snd_kcontrol_new wm8400_dapm_rin12_pga_controls[] = { 458 SOC_DAPM_SINGLE("RIN1 Switch", WM8400_INPUT_MIXER2, WM8400_RMN1_SHIFT, 1, 0), 459 SOC_DAPM_SINGLE("RIN2 Switch", WM8400_INPUT_MIXER2, WM8400_RMP2_SHIFT, 1, 0), 460 }; 461 462 static const struct snd_kcontrol_new wm8400_dapm_rin34_pga_controls[] = { 463 SOC_DAPM_SINGLE("RIN3 Switch", WM8400_INPUT_MIXER2, WM8400_RMN3_SHIFT, 1, 0), 464 SOC_DAPM_SINGLE("RIN4 Switch", WM8400_INPUT_MIXER2, WM8400_RMP4_SHIFT, 1, 0), 465 }; 466 467 /* INMIXL */ 468 static const struct snd_kcontrol_new wm8400_dapm_inmixl_controls[] = { 469 SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8400_INPUT_MIXER3, 470 WM8400_LDBVOL_SHIFT, WM8400_LDBVOL_MASK, 0, in_mix_tlv), 471 SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8400_INPUT_MIXER5, WM8400_LI2BVOL_SHIFT, 472 7, 0, in_mix_tlv), 473 SOC_DAPM_SINGLE("LINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT, 474 1, 0), 475 SOC_DAPM_SINGLE("LINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT, 476 1, 0), 477 }; 478 479 /* INMIXR */ 480 static const struct snd_kcontrol_new wm8400_dapm_inmixr_controls[] = { 481 SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8400_INPUT_MIXER4, 482 WM8400_RDBVOL_SHIFT, WM8400_RDBVOL_MASK, 0, in_mix_tlv), 483 SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8400_INPUT_MIXER6, WM8400_RI2BVOL_SHIFT, 484 7, 0, in_mix_tlv), 485 SOC_DAPM_SINGLE("RINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT, 486 1, 0), 487 SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT, 488 1, 0), 489 }; 490 491 /* AINLMUX */ 492 static const char *wm8400_ainlmux[] = 493 {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"}; 494 495 static const struct soc_enum wm8400_ainlmux_enum = 496 SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINLMODE_SHIFT, 497 ARRAY_SIZE(wm8400_ainlmux), wm8400_ainlmux); 498 499 static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls = 500 SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum); 501 502 /* DIFFINL */ 503 504 /* AINRMUX */ 505 static const char *wm8400_ainrmux[] = 506 {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"}; 507 508 static const struct soc_enum wm8400_ainrmux_enum = 509 SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINRMODE_SHIFT, 510 ARRAY_SIZE(wm8400_ainrmux), wm8400_ainrmux); 511 512 static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = 513 SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); 514 515 /* RXVOICE */ 516 static const struct snd_kcontrol_new wm8400_dapm_rxvoice_controls[] = { 517 SOC_DAPM_SINGLE_TLV("LIN4/RXN", WM8400_INPUT_MIXER5, WM8400_LR4BVOL_SHIFT, 518 WM8400_LR4BVOL_MASK, 0, in_mix_tlv), 519 SOC_DAPM_SINGLE_TLV("RIN4/RXP", WM8400_INPUT_MIXER6, WM8400_RL4BVOL_SHIFT, 520 WM8400_RL4BVOL_MASK, 0, in_mix_tlv), 521 }; 522 523 /* LOMIX */ 524 static const struct snd_kcontrol_new wm8400_dapm_lomix_controls[] = { 525 SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER1, 526 WM8400_LRBLO_SHIFT, 1, 0), 527 SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER1, 528 WM8400_LLBLO_SHIFT, 1, 0), 529 SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER1, 530 WM8400_LRI3LO_SHIFT, 1, 0), 531 SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER1, 532 WM8400_LLI3LO_SHIFT, 1, 0), 533 SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1, 534 WM8400_LR12LO_SHIFT, 1, 0), 535 SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1, 536 WM8400_LL12LO_SHIFT, 1, 0), 537 SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8400_OUTPUT_MIXER1, 538 WM8400_LDLO_SHIFT, 1, 0), 539 }; 540 541 /* ROMIX */ 542 static const struct snd_kcontrol_new wm8400_dapm_romix_controls[] = { 543 SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER2, 544 WM8400_RLBRO_SHIFT, 1, 0), 545 SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER2, 546 WM8400_RRBRO_SHIFT, 1, 0), 547 SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER2, 548 WM8400_RLI3RO_SHIFT, 1, 0), 549 SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER2, 550 WM8400_RRI3RO_SHIFT, 1, 0), 551 SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2, 552 WM8400_RL12RO_SHIFT, 1, 0), 553 SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2, 554 WM8400_RR12RO_SHIFT, 1, 0), 555 SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8400_OUTPUT_MIXER2, 556 WM8400_RDRO_SHIFT, 1, 0), 557 }; 558 559 /* LONMIX */ 560 static const struct snd_kcontrol_new wm8400_dapm_lonmix_controls[] = { 561 SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1, 562 WM8400_LLOPGALON_SHIFT, 1, 0), 563 SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER1, 564 WM8400_LROPGALON_SHIFT, 1, 0), 565 SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8400_LINE_MIXER1, 566 WM8400_LOPLON_SHIFT, 1, 0), 567 }; 568 569 /* LOPMIX */ 570 static const struct snd_kcontrol_new wm8400_dapm_lopmix_controls[] = { 571 SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER1, 572 WM8400_LR12LOP_SHIFT, 1, 0), 573 SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER1, 574 WM8400_LL12LOP_SHIFT, 1, 0), 575 SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1, 576 WM8400_LLOPGALOP_SHIFT, 1, 0), 577 }; 578 579 /* RONMIX */ 580 static const struct snd_kcontrol_new wm8400_dapm_ronmix_controls[] = { 581 SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2, 582 WM8400_RROPGARON_SHIFT, 1, 0), 583 SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER2, 584 WM8400_RLOPGARON_SHIFT, 1, 0), 585 SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8400_LINE_MIXER2, 586 WM8400_ROPRON_SHIFT, 1, 0), 587 }; 588 589 /* ROPMIX */ 590 static const struct snd_kcontrol_new wm8400_dapm_ropmix_controls[] = { 591 SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER2, 592 WM8400_RL12ROP_SHIFT, 1, 0), 593 SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER2, 594 WM8400_RR12ROP_SHIFT, 1, 0), 595 SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2, 596 WM8400_RROPGAROP_SHIFT, 1, 0), 597 }; 598 599 /* OUT3MIX */ 600 static const struct snd_kcontrol_new wm8400_dapm_out3mix_controls[] = { 601 SOC_DAPM_SINGLE("OUT3MIX LIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER, 602 WM8400_LI4O3_SHIFT, 1, 0), 603 SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8400_OUT3_4_MIXER, 604 WM8400_LPGAO3_SHIFT, 1, 0), 605 }; 606 607 /* OUT4MIX */ 608 static const struct snd_kcontrol_new wm8400_dapm_out4mix_controls[] = { 609 SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8400_OUT3_4_MIXER, 610 WM8400_RPGAO4_SHIFT, 1, 0), 611 SOC_DAPM_SINGLE("OUT4MIX RIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER, 612 WM8400_RI4O4_SHIFT, 1, 0), 613 }; 614 615 /* SPKMIX */ 616 static const struct snd_kcontrol_new wm8400_dapm_spkmix_controls[] = { 617 SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8400_SPEAKER_MIXER, 618 WM8400_LI2SPK_SHIFT, 1, 0), 619 SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8400_SPEAKER_MIXER, 620 WM8400_LB2SPK_SHIFT, 1, 0), 621 SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8400_SPEAKER_MIXER, 622 WM8400_LOPGASPK_SHIFT, 1, 0), 623 SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8400_SPEAKER_MIXER, 624 WM8400_LDSPK_SHIFT, 1, 0), 625 SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8400_SPEAKER_MIXER, 626 WM8400_RDSPK_SHIFT, 1, 0), 627 SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8400_SPEAKER_MIXER, 628 WM8400_ROPGASPK_SHIFT, 1, 0), 629 SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8400_SPEAKER_MIXER, 630 WM8400_RL12ROP_SHIFT, 1, 0), 631 SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8400_SPEAKER_MIXER, 632 WM8400_RI2SPK_SHIFT, 1, 0), 633 }; 634 635 static const struct snd_soc_dapm_widget wm8400_dapm_widgets[] = { 636 /* Input Side */ 637 /* Input Lines */ 638 SND_SOC_DAPM_INPUT("LIN1"), 639 SND_SOC_DAPM_INPUT("LIN2"), 640 SND_SOC_DAPM_INPUT("LIN3"), 641 SND_SOC_DAPM_INPUT("LIN4/RXN"), 642 SND_SOC_DAPM_INPUT("RIN3"), 643 SND_SOC_DAPM_INPUT("RIN4/RXP"), 644 SND_SOC_DAPM_INPUT("RIN1"), 645 SND_SOC_DAPM_INPUT("RIN2"), 646 SND_SOC_DAPM_INPUT("Internal ADC Source"), 647 648 /* DACs */ 649 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8400_POWER_MANAGEMENT_2, 650 WM8400_ADCL_ENA_SHIFT, 0), 651 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8400_POWER_MANAGEMENT_2, 652 WM8400_ADCR_ENA_SHIFT, 0), 653 654 /* Input PGAs */ 655 SND_SOC_DAPM_MIXER("LIN12 PGA", WM8400_POWER_MANAGEMENT_2, 656 WM8400_LIN12_ENA_SHIFT, 657 0, &wm8400_dapm_lin12_pga_controls[0], 658 ARRAY_SIZE(wm8400_dapm_lin12_pga_controls)), 659 SND_SOC_DAPM_MIXER("LIN34 PGA", WM8400_POWER_MANAGEMENT_2, 660 WM8400_LIN34_ENA_SHIFT, 661 0, &wm8400_dapm_lin34_pga_controls[0], 662 ARRAY_SIZE(wm8400_dapm_lin34_pga_controls)), 663 SND_SOC_DAPM_MIXER("RIN12 PGA", WM8400_POWER_MANAGEMENT_2, 664 WM8400_RIN12_ENA_SHIFT, 665 0, &wm8400_dapm_rin12_pga_controls[0], 666 ARRAY_SIZE(wm8400_dapm_rin12_pga_controls)), 667 SND_SOC_DAPM_MIXER("RIN34 PGA", WM8400_POWER_MANAGEMENT_2, 668 WM8400_RIN34_ENA_SHIFT, 669 0, &wm8400_dapm_rin34_pga_controls[0], 670 ARRAY_SIZE(wm8400_dapm_rin34_pga_controls)), 671 672 /* INMIXL */ 673 SND_SOC_DAPM_MIXER_E("INMIXL", WM8400_INTDRIVBITS, WM8400_INMIXL_PWR, 0, 674 &wm8400_dapm_inmixl_controls[0], 675 ARRAY_SIZE(wm8400_dapm_inmixl_controls), 676 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 677 678 /* AINLMUX */ 679 SND_SOC_DAPM_MUX_E("AILNMUX", WM8400_INTDRIVBITS, WM8400_AINLMUX_PWR, 0, 680 &wm8400_dapm_ainlmux_controls, inmixer_event, 681 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 682 683 /* INMIXR */ 684 SND_SOC_DAPM_MIXER_E("INMIXR", WM8400_INTDRIVBITS, WM8400_INMIXR_PWR, 0, 685 &wm8400_dapm_inmixr_controls[0], 686 ARRAY_SIZE(wm8400_dapm_inmixr_controls), 687 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 688 689 /* AINRMUX */ 690 SND_SOC_DAPM_MUX_E("AIRNMUX", WM8400_INTDRIVBITS, WM8400_AINRMUX_PWR, 0, 691 &wm8400_dapm_ainrmux_controls, inmixer_event, 692 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 693 694 /* Output Side */ 695 /* DACs */ 696 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8400_POWER_MANAGEMENT_3, 697 WM8400_DACL_ENA_SHIFT, 0), 698 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8400_POWER_MANAGEMENT_3, 699 WM8400_DACR_ENA_SHIFT, 0), 700 701 /* LOMIX */ 702 SND_SOC_DAPM_MIXER_E("LOMIX", WM8400_POWER_MANAGEMENT_3, 703 WM8400_LOMIX_ENA_SHIFT, 704 0, &wm8400_dapm_lomix_controls[0], 705 ARRAY_SIZE(wm8400_dapm_lomix_controls), 706 outmixer_event, SND_SOC_DAPM_PRE_REG), 707 708 /* LONMIX */ 709 SND_SOC_DAPM_MIXER("LONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LON_ENA_SHIFT, 710 0, &wm8400_dapm_lonmix_controls[0], 711 ARRAY_SIZE(wm8400_dapm_lonmix_controls)), 712 713 /* LOPMIX */ 714 SND_SOC_DAPM_MIXER("LOPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LOP_ENA_SHIFT, 715 0, &wm8400_dapm_lopmix_controls[0], 716 ARRAY_SIZE(wm8400_dapm_lopmix_controls)), 717 718 /* OUT3MIX */ 719 SND_SOC_DAPM_MIXER("OUT3MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT3_ENA_SHIFT, 720 0, &wm8400_dapm_out3mix_controls[0], 721 ARRAY_SIZE(wm8400_dapm_out3mix_controls)), 722 723 /* SPKMIX */ 724 SND_SOC_DAPM_MIXER_E("SPKMIX", WM8400_POWER_MANAGEMENT_1, WM8400_SPK_ENA_SHIFT, 725 0, &wm8400_dapm_spkmix_controls[0], 726 ARRAY_SIZE(wm8400_dapm_spkmix_controls), outmixer_event, 727 SND_SOC_DAPM_PRE_REG), 728 729 /* OUT4MIX */ 730 SND_SOC_DAPM_MIXER("OUT4MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT4_ENA_SHIFT, 731 0, &wm8400_dapm_out4mix_controls[0], 732 ARRAY_SIZE(wm8400_dapm_out4mix_controls)), 733 734 /* ROPMIX */ 735 SND_SOC_DAPM_MIXER("ROPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_ROP_ENA_SHIFT, 736 0, &wm8400_dapm_ropmix_controls[0], 737 ARRAY_SIZE(wm8400_dapm_ropmix_controls)), 738 739 /* RONMIX */ 740 SND_SOC_DAPM_MIXER("RONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_RON_ENA_SHIFT, 741 0, &wm8400_dapm_ronmix_controls[0], 742 ARRAY_SIZE(wm8400_dapm_ronmix_controls)), 743 744 /* ROMIX */ 745 SND_SOC_DAPM_MIXER_E("ROMIX", WM8400_POWER_MANAGEMENT_3, 746 WM8400_ROMIX_ENA_SHIFT, 747 0, &wm8400_dapm_romix_controls[0], 748 ARRAY_SIZE(wm8400_dapm_romix_controls), 749 outmixer_event, SND_SOC_DAPM_PRE_REG), 750 751 /* LOUT PGA */ 752 SND_SOC_DAPM_PGA("LOUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_LOUT_ENA_SHIFT, 753 0, NULL, 0), 754 755 /* ROUT PGA */ 756 SND_SOC_DAPM_PGA("ROUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_ROUT_ENA_SHIFT, 757 0, NULL, 0), 758 759 /* LOPGA */ 760 SND_SOC_DAPM_PGA("LOPGA", WM8400_POWER_MANAGEMENT_3, WM8400_LOPGA_ENA_SHIFT, 0, 761 NULL, 0), 762 763 /* ROPGA */ 764 SND_SOC_DAPM_PGA("ROPGA", WM8400_POWER_MANAGEMENT_3, WM8400_ROPGA_ENA_SHIFT, 0, 765 NULL, 0), 766 767 /* MICBIAS */ 768 SND_SOC_DAPM_MICBIAS("MICBIAS", WM8400_POWER_MANAGEMENT_1, 769 WM8400_MIC1BIAS_ENA_SHIFT, 0), 770 771 SND_SOC_DAPM_OUTPUT("LON"), 772 SND_SOC_DAPM_OUTPUT("LOP"), 773 SND_SOC_DAPM_OUTPUT("OUT3"), 774 SND_SOC_DAPM_OUTPUT("LOUT"), 775 SND_SOC_DAPM_OUTPUT("SPKN"), 776 SND_SOC_DAPM_OUTPUT("SPKP"), 777 SND_SOC_DAPM_OUTPUT("ROUT"), 778 SND_SOC_DAPM_OUTPUT("OUT4"), 779 SND_SOC_DAPM_OUTPUT("ROP"), 780 SND_SOC_DAPM_OUTPUT("RON"), 781 782 SND_SOC_DAPM_OUTPUT("Internal DAC Sink"), 783 }; 784 785 static const struct snd_soc_dapm_route audio_map[] = { 786 /* Make DACs turn on when playing even if not mixed into any outputs */ 787 {"Internal DAC Sink", NULL, "Left DAC"}, 788 {"Internal DAC Sink", NULL, "Right DAC"}, 789 790 /* Make ADCs turn on when recording 791 * even if not mixed from any inputs */ 792 {"Left ADC", NULL, "Internal ADC Source"}, 793 {"Right ADC", NULL, "Internal ADC Source"}, 794 795 /* Input Side */ 796 /* LIN12 PGA */ 797 {"LIN12 PGA", "LIN1 Switch", "LIN1"}, 798 {"LIN12 PGA", "LIN2 Switch", "LIN2"}, 799 /* LIN34 PGA */ 800 {"LIN34 PGA", "LIN3 Switch", "LIN3"}, 801 {"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"}, 802 /* INMIXL */ 803 {"INMIXL", "Record Left Volume", "LOMIX"}, 804 {"INMIXL", "LIN2 Volume", "LIN2"}, 805 {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"}, 806 {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"}, 807 /* AILNMUX */ 808 {"AILNMUX", "INMIXL Mix", "INMIXL"}, 809 {"AILNMUX", "DIFFINL Mix", "LIN12 PGA"}, 810 {"AILNMUX", "DIFFINL Mix", "LIN34 PGA"}, 811 {"AILNMUX", "RXVOICE Mix", "LIN4/RXN"}, 812 {"AILNMUX", "RXVOICE Mix", "RIN4/RXP"}, 813 /* ADC */ 814 {"Left ADC", NULL, "AILNMUX"}, 815 816 /* RIN12 PGA */ 817 {"RIN12 PGA", "RIN1 Switch", "RIN1"}, 818 {"RIN12 PGA", "RIN2 Switch", "RIN2"}, 819 /* RIN34 PGA */ 820 {"RIN34 PGA", "RIN3 Switch", "RIN3"}, 821 {"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"}, 822 /* INMIXL */ 823 {"INMIXR", "Record Right Volume", "ROMIX"}, 824 {"INMIXR", "RIN2 Volume", "RIN2"}, 825 {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"}, 826 {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"}, 827 /* AIRNMUX */ 828 {"AIRNMUX", "INMIXR Mix", "INMIXR"}, 829 {"AIRNMUX", "DIFFINR Mix", "RIN12 PGA"}, 830 {"AIRNMUX", "DIFFINR Mix", "RIN34 PGA"}, 831 {"AIRNMUX", "RXVOICE Mix", "LIN4/RXN"}, 832 {"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"}, 833 /* ADC */ 834 {"Right ADC", NULL, "AIRNMUX"}, 835 836 /* LOMIX */ 837 {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"}, 838 {"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"}, 839 {"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"}, 840 {"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"}, 841 {"LOMIX", "LOMIX Right ADC Bypass Switch", "AIRNMUX"}, 842 {"LOMIX", "LOMIX Left ADC Bypass Switch", "AILNMUX"}, 843 {"LOMIX", "LOMIX Left DAC Switch", "Left DAC"}, 844 845 /* ROMIX */ 846 {"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"}, 847 {"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"}, 848 {"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"}, 849 {"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"}, 850 {"ROMIX", "ROMIX Right ADC Bypass Switch", "AIRNMUX"}, 851 {"ROMIX", "ROMIX Left ADC Bypass Switch", "AILNMUX"}, 852 {"ROMIX", "ROMIX Right DAC Switch", "Right DAC"}, 853 854 /* SPKMIX */ 855 {"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"}, 856 {"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"}, 857 {"SPKMIX", "SPKMIX LADC Bypass Switch", "AILNMUX"}, 858 {"SPKMIX", "SPKMIX RADC Bypass Switch", "AIRNMUX"}, 859 {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"}, 860 {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"}, 861 {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"}, 862 {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"}, 863 864 /* LONMIX */ 865 {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"}, 866 {"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"}, 867 {"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"}, 868 869 /* LOPMIX */ 870 {"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"}, 871 {"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"}, 872 {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"}, 873 874 /* OUT3MIX */ 875 {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"}, 876 {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"}, 877 878 /* OUT4MIX */ 879 {"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"}, 880 {"OUT4MIX", "OUT4MIX RIN4/RXP Bypass Switch", "RIN4/RXP"}, 881 882 /* RONMIX */ 883 {"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"}, 884 {"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"}, 885 {"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"}, 886 887 /* ROPMIX */ 888 {"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"}, 889 {"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"}, 890 {"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"}, 891 892 /* Out Mixer PGAs */ 893 {"LOPGA", NULL, "LOMIX"}, 894 {"ROPGA", NULL, "ROMIX"}, 895 896 {"LOUT PGA", NULL, "LOMIX"}, 897 {"ROUT PGA", NULL, "ROMIX"}, 898 899 /* Output Pins */ 900 {"LON", NULL, "LONMIX"}, 901 {"LOP", NULL, "LOPMIX"}, 902 {"OUT3", NULL, "OUT3MIX"}, 903 {"LOUT", NULL, "LOUT PGA"}, 904 {"SPKN", NULL, "SPKMIX"}, 905 {"ROUT", NULL, "ROUT PGA"}, 906 {"OUT4", NULL, "OUT4MIX"}, 907 {"ROP", NULL, "ROPMIX"}, 908 {"RON", NULL, "RONMIX"}, 909 }; 910 911 static int wm8400_add_widgets(struct snd_soc_codec *codec) 912 { 913 struct snd_soc_dapm_context *dapm = &codec->dapm; 914 915 snd_soc_dapm_new_controls(dapm, wm8400_dapm_widgets, 916 ARRAY_SIZE(wm8400_dapm_widgets)); 917 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 918 919 return 0; 920 } 921 922 /* 923 * Clock after FLL and dividers 924 */ 925 static int wm8400_set_dai_sysclk(struct snd_soc_dai *codec_dai, 926 int clk_id, unsigned int freq, int dir) 927 { 928 struct snd_soc_codec *codec = codec_dai->codec; 929 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec); 930 931 wm8400->sysclk = freq; 932 return 0; 933 } 934 935 struct fll_factors { 936 u16 n; 937 u16 k; 938 u16 outdiv; 939 u16 fratio; 940 u16 freq_ref; 941 }; 942 943 #define FIXED_FLL_SIZE ((1 << 16) * 10) 944 945 static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors, 946 unsigned int Fref, unsigned int Fout) 947 { 948 u64 Kpart; 949 unsigned int K, Nmod, target; 950 951 factors->outdiv = 2; 952 while (Fout * factors->outdiv < 90000000 || 953 Fout * factors->outdiv > 100000000) { 954 factors->outdiv *= 2; 955 if (factors->outdiv > 32) { 956 dev_err(wm8400->wm8400->dev, 957 "Unsupported FLL output frequency %uHz\n", 958 Fout); 959 return -EINVAL; 960 } 961 } 962 target = Fout * factors->outdiv; 963 factors->outdiv = factors->outdiv >> 2; 964 965 if (Fref < 48000) 966 factors->freq_ref = 1; 967 else 968 factors->freq_ref = 0; 969 970 if (Fref < 1000000) 971 factors->fratio = 9; 972 else 973 factors->fratio = 0; 974 975 /* Ensure we have a fractional part */ 976 do { 977 if (Fref < 1000000) 978 factors->fratio--; 979 else 980 factors->fratio++; 981 982 if (factors->fratio < 1 || factors->fratio > 8) { 983 dev_err(wm8400->wm8400->dev, 984 "Unable to calculate FRATIO\n"); 985 return -EINVAL; 986 } 987 988 factors->n = target / (Fref * factors->fratio); 989 Nmod = target % (Fref * factors->fratio); 990 } while (Nmod == 0); 991 992 /* Calculate fractional part - scale up so we can round. */ 993 Kpart = FIXED_FLL_SIZE * (long long)Nmod; 994 995 do_div(Kpart, (Fref * factors->fratio)); 996 997 K = Kpart & 0xFFFFFFFF; 998 999 if ((K % 10) >= 5) 1000 K += 5; 1001 1002 /* Move down to proper range now rounding is done */ 1003 factors->k = K / 10; 1004 1005 dev_dbg(wm8400->wm8400->dev, 1006 "FLL: Fref=%u Fout=%u N=%x K=%x, FRATIO=%x OUTDIV=%x\n", 1007 Fref, Fout, 1008 factors->n, factors->k, factors->fratio, factors->outdiv); 1009 1010 return 0; 1011 } 1012 1013 static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 1014 int source, unsigned int freq_in, 1015 unsigned int freq_out) 1016 { 1017 struct snd_soc_codec *codec = codec_dai->codec; 1018 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec); 1019 struct fll_factors factors; 1020 int ret; 1021 u16 reg; 1022 1023 if (freq_in == wm8400->fll_in && freq_out == wm8400->fll_out) 1024 return 0; 1025 1026 if (freq_out) { 1027 ret = fll_factors(wm8400, &factors, freq_in, freq_out); 1028 if (ret != 0) 1029 return ret; 1030 } else { 1031 /* Bodge GCC 4.4.0 uninitialised variable warning - it 1032 * doesn't seem capable of working out that we exit if 1033 * freq_out is 0 before any of the uses. */ 1034 memset(&factors, 0, sizeof(factors)); 1035 } 1036 1037 wm8400->fll_out = freq_out; 1038 wm8400->fll_in = freq_in; 1039 1040 /* We *must* disable the FLL before any changes */ 1041 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_2); 1042 reg &= ~WM8400_FLL_ENA; 1043 wm8400_write(codec, WM8400_POWER_MANAGEMENT_2, reg); 1044 1045 reg = wm8400_read(codec, WM8400_FLL_CONTROL_1); 1046 reg &= ~WM8400_FLL_OSC_ENA; 1047 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg); 1048 1049 if (!freq_out) 1050 return 0; 1051 1052 reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK); 1053 reg |= WM8400_FLL_FRAC | factors.fratio; 1054 reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT; 1055 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg); 1056 1057 wm8400_write(codec, WM8400_FLL_CONTROL_2, factors.k); 1058 wm8400_write(codec, WM8400_FLL_CONTROL_3, factors.n); 1059 1060 reg = wm8400_read(codec, WM8400_FLL_CONTROL_4); 1061 reg &= WM8400_FLL_OUTDIV_MASK; 1062 reg |= factors.outdiv; 1063 wm8400_write(codec, WM8400_FLL_CONTROL_4, reg); 1064 1065 return 0; 1066 } 1067 1068 /* 1069 * Sets ADC and Voice DAC format. 1070 */ 1071 static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai, 1072 unsigned int fmt) 1073 { 1074 struct snd_soc_codec *codec = codec_dai->codec; 1075 u16 audio1, audio3; 1076 1077 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1); 1078 audio3 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_3); 1079 1080 /* set master/slave audio interface */ 1081 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1082 case SND_SOC_DAIFMT_CBS_CFS: 1083 audio3 &= ~WM8400_AIF_MSTR1; 1084 break; 1085 case SND_SOC_DAIFMT_CBM_CFM: 1086 audio3 |= WM8400_AIF_MSTR1; 1087 break; 1088 default: 1089 return -EINVAL; 1090 } 1091 1092 audio1 &= ~WM8400_AIF_FMT_MASK; 1093 1094 /* interface format */ 1095 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1096 case SND_SOC_DAIFMT_I2S: 1097 audio1 |= WM8400_AIF_FMT_I2S; 1098 audio1 &= ~WM8400_AIF_LRCLK_INV; 1099 break; 1100 case SND_SOC_DAIFMT_RIGHT_J: 1101 audio1 |= WM8400_AIF_FMT_RIGHTJ; 1102 audio1 &= ~WM8400_AIF_LRCLK_INV; 1103 break; 1104 case SND_SOC_DAIFMT_LEFT_J: 1105 audio1 |= WM8400_AIF_FMT_LEFTJ; 1106 audio1 &= ~WM8400_AIF_LRCLK_INV; 1107 break; 1108 case SND_SOC_DAIFMT_DSP_A: 1109 audio1 |= WM8400_AIF_FMT_DSP; 1110 audio1 &= ~WM8400_AIF_LRCLK_INV; 1111 break; 1112 case SND_SOC_DAIFMT_DSP_B: 1113 audio1 |= WM8400_AIF_FMT_DSP | WM8400_AIF_LRCLK_INV; 1114 break; 1115 default: 1116 return -EINVAL; 1117 } 1118 1119 wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1); 1120 wm8400_write(codec, WM8400_AUDIO_INTERFACE_3, audio3); 1121 return 0; 1122 } 1123 1124 static int wm8400_set_dai_clkdiv(struct snd_soc_dai *codec_dai, 1125 int div_id, int div) 1126 { 1127 struct snd_soc_codec *codec = codec_dai->codec; 1128 u16 reg; 1129 1130 switch (div_id) { 1131 case WM8400_MCLK_DIV: 1132 reg = wm8400_read(codec, WM8400_CLOCKING_2) & 1133 ~WM8400_MCLK_DIV_MASK; 1134 wm8400_write(codec, WM8400_CLOCKING_2, reg | div); 1135 break; 1136 case WM8400_DACCLK_DIV: 1137 reg = wm8400_read(codec, WM8400_CLOCKING_2) & 1138 ~WM8400_DAC_CLKDIV_MASK; 1139 wm8400_write(codec, WM8400_CLOCKING_2, reg | div); 1140 break; 1141 case WM8400_ADCCLK_DIV: 1142 reg = wm8400_read(codec, WM8400_CLOCKING_2) & 1143 ~WM8400_ADC_CLKDIV_MASK; 1144 wm8400_write(codec, WM8400_CLOCKING_2, reg | div); 1145 break; 1146 case WM8400_BCLK_DIV: 1147 reg = wm8400_read(codec, WM8400_CLOCKING_1) & 1148 ~WM8400_BCLK_DIV_MASK; 1149 wm8400_write(codec, WM8400_CLOCKING_1, reg | div); 1150 break; 1151 default: 1152 return -EINVAL; 1153 } 1154 1155 return 0; 1156 } 1157 1158 /* 1159 * Set PCM DAI bit size and sample rate. 1160 */ 1161 static int wm8400_hw_params(struct snd_pcm_substream *substream, 1162 struct snd_pcm_hw_params *params, 1163 struct snd_soc_dai *dai) 1164 { 1165 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1166 struct snd_soc_codec *codec = rtd->codec; 1167 u16 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1); 1168 1169 audio1 &= ~WM8400_AIF_WL_MASK; 1170 /* bit size */ 1171 switch (params_format(params)) { 1172 case SNDRV_PCM_FORMAT_S16_LE: 1173 break; 1174 case SNDRV_PCM_FORMAT_S20_3LE: 1175 audio1 |= WM8400_AIF_WL_20BITS; 1176 break; 1177 case SNDRV_PCM_FORMAT_S24_LE: 1178 audio1 |= WM8400_AIF_WL_24BITS; 1179 break; 1180 case SNDRV_PCM_FORMAT_S32_LE: 1181 audio1 |= WM8400_AIF_WL_32BITS; 1182 break; 1183 } 1184 1185 wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1); 1186 return 0; 1187 } 1188 1189 static int wm8400_mute(struct snd_soc_dai *dai, int mute) 1190 { 1191 struct snd_soc_codec *codec = dai->codec; 1192 u16 val = wm8400_read(codec, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE; 1193 1194 if (mute) 1195 wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE); 1196 else 1197 wm8400_write(codec, WM8400_DAC_CTRL, val); 1198 1199 return 0; 1200 } 1201 1202 /* TODO: set bias for best performance at standby */ 1203 static int wm8400_set_bias_level(struct snd_soc_codec *codec, 1204 enum snd_soc_bias_level level) 1205 { 1206 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec); 1207 u16 val; 1208 int ret; 1209 1210 switch (level) { 1211 case SND_SOC_BIAS_ON: 1212 break; 1213 1214 case SND_SOC_BIAS_PREPARE: 1215 /* VMID=2*50k */ 1216 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) & 1217 ~WM8400_VMID_MODE_MASK; 1218 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x2); 1219 break; 1220 1221 case SND_SOC_BIAS_STANDBY: 1222 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1223 ret = regulator_bulk_enable(ARRAY_SIZE(power), 1224 &power[0]); 1225 if (ret != 0) { 1226 dev_err(wm8400->wm8400->dev, 1227 "Failed to enable regulators: %d\n", 1228 ret); 1229 return ret; 1230 } 1231 1232 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, 1233 WM8400_CODEC_ENA | WM8400_SYSCLK_ENA); 1234 1235 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */ 1236 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1237 WM8400_BUFDCOPEN | WM8400_POBCTRL); 1238 1239 msleep(50); 1240 1241 /* Enable VREF & VMID at 2x50k */ 1242 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1243 val |= 0x2 | WM8400_VREF_ENA; 1244 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1245 1246 /* Enable BUFIOEN */ 1247 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1248 WM8400_BUFDCOPEN | WM8400_POBCTRL | 1249 WM8400_BUFIOEN); 1250 1251 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1252 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_BUFIOEN); 1253 } 1254 1255 /* VMID=2*300k */ 1256 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) & 1257 ~WM8400_VMID_MODE_MASK; 1258 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x4); 1259 break; 1260 1261 case SND_SOC_BIAS_OFF: 1262 /* Enable POBCTRL and SOFT_ST */ 1263 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1264 WM8400_POBCTRL | WM8400_BUFIOEN); 1265 1266 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */ 1267 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1268 WM8400_BUFDCOPEN | WM8400_POBCTRL | 1269 WM8400_BUFIOEN); 1270 1271 /* mute DAC */ 1272 val = wm8400_read(codec, WM8400_DAC_CTRL); 1273 wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE); 1274 1275 /* Enable any disabled outputs */ 1276 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1277 val |= WM8400_SPK_ENA | WM8400_OUT3_ENA | 1278 WM8400_OUT4_ENA | WM8400_LOUT_ENA | 1279 WM8400_ROUT_ENA; 1280 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1281 1282 /* Disable VMID */ 1283 val &= ~WM8400_VMID_MODE_MASK; 1284 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1285 1286 msleep(300); 1287 1288 /* Enable all output discharge bits */ 1289 wm8400_write(codec, WM8400_ANTIPOP1, WM8400_DIS_LLINE | 1290 WM8400_DIS_RLINE | WM8400_DIS_OUT3 | 1291 WM8400_DIS_OUT4 | WM8400_DIS_LOUT | 1292 WM8400_DIS_ROUT); 1293 1294 /* Disable VREF */ 1295 val &= ~WM8400_VREF_ENA; 1296 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1297 1298 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1299 wm8400_write(codec, WM8400_ANTIPOP2, 0x0); 1300 1301 ret = regulator_bulk_disable(ARRAY_SIZE(power), 1302 &power[0]); 1303 if (ret != 0) 1304 return ret; 1305 1306 break; 1307 } 1308 1309 codec->dapm.bias_level = level; 1310 return 0; 1311 } 1312 1313 #define WM8400_RATES SNDRV_PCM_RATE_8000_96000 1314 1315 #define WM8400_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 1316 SNDRV_PCM_FMTBIT_S24_LE) 1317 1318 static struct snd_soc_dai_ops wm8400_dai_ops = { 1319 .hw_params = wm8400_hw_params, 1320 .digital_mute = wm8400_mute, 1321 .set_fmt = wm8400_set_dai_fmt, 1322 .set_clkdiv = wm8400_set_dai_clkdiv, 1323 .set_sysclk = wm8400_set_dai_sysclk, 1324 .set_pll = wm8400_set_dai_pll, 1325 }; 1326 1327 /* 1328 * The WM8400 supports 2 different and mutually exclusive DAI 1329 * configurations. 1330 * 1331 * 1. ADC/DAC on Primary Interface 1332 * 2. ADC on Primary Interface/DAC on secondary 1333 */ 1334 static struct snd_soc_dai_driver wm8400_dai = { 1335 /* ADC/DAC on primary */ 1336 .name = "wm8400-hifi", 1337 .playback = { 1338 .stream_name = "Playback", 1339 .channels_min = 1, 1340 .channels_max = 2, 1341 .rates = WM8400_RATES, 1342 .formats = WM8400_FORMATS, 1343 }, 1344 .capture = { 1345 .stream_name = "Capture", 1346 .channels_min = 1, 1347 .channels_max = 2, 1348 .rates = WM8400_RATES, 1349 .formats = WM8400_FORMATS, 1350 }, 1351 .ops = &wm8400_dai_ops, 1352 }; 1353 1354 static int wm8400_suspend(struct snd_soc_codec *codec, pm_message_t state) 1355 { 1356 wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF); 1357 1358 return 0; 1359 } 1360 1361 static int wm8400_resume(struct snd_soc_codec *codec) 1362 { 1363 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1364 1365 return 0; 1366 } 1367 1368 static void wm8400_probe_deferred(struct work_struct *work) 1369 { 1370 struct wm8400_priv *priv = container_of(work, struct wm8400_priv, 1371 work); 1372 struct snd_soc_codec *codec = priv->codec; 1373 1374 /* charge output caps */ 1375 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1376 } 1377 1378 static int wm8400_codec_probe(struct snd_soc_codec *codec) 1379 { 1380 struct wm8400 *wm8400 = dev_get_platdata(codec->dev); 1381 struct wm8400_priv *priv; 1382 int ret; 1383 u16 reg; 1384 1385 priv = kzalloc(sizeof(struct wm8400_priv), GFP_KERNEL); 1386 if (priv == NULL) 1387 return -ENOMEM; 1388 1389 snd_soc_codec_set_drvdata(codec, priv); 1390 codec->control_data = priv->wm8400 = wm8400; 1391 priv->codec = codec; 1392 1393 ret = regulator_bulk_get(wm8400->dev, 1394 ARRAY_SIZE(power), &power[0]); 1395 if (ret != 0) { 1396 dev_err(codec->dev, "Failed to get regulators: %d\n", ret); 1397 goto err; 1398 } 1399 1400 INIT_WORK(&priv->work, wm8400_probe_deferred); 1401 1402 wm8400_codec_reset(codec); 1403 1404 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1405 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA); 1406 1407 /* Latch volume update bits */ 1408 reg = wm8400_read(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME); 1409 wm8400_write(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME, 1410 reg & WM8400_IPVU); 1411 reg = wm8400_read(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME); 1412 wm8400_write(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME, 1413 reg & WM8400_IPVU); 1414 1415 wm8400_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1416 wm8400_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1417 1418 if (!schedule_work(&priv->work)) { 1419 ret = -EINVAL; 1420 goto err_regulator; 1421 } 1422 wm8400_add_controls(codec); 1423 wm8400_add_widgets(codec); 1424 return 0; 1425 1426 err_regulator: 1427 regulator_bulk_free(ARRAY_SIZE(power), power); 1428 err: 1429 kfree(priv); 1430 return ret; 1431 } 1432 1433 static int wm8400_codec_remove(struct snd_soc_codec *codec) 1434 { 1435 struct wm8400_priv *priv = snd_soc_codec_get_drvdata(codec); 1436 u16 reg; 1437 1438 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1439 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, 1440 reg & (~WM8400_CODEC_ENA)); 1441 1442 regulator_bulk_free(ARRAY_SIZE(power), power); 1443 kfree(priv); 1444 1445 return 0; 1446 } 1447 1448 static struct snd_soc_codec_driver soc_codec_dev_wm8400 = { 1449 .probe = wm8400_codec_probe, 1450 .remove = wm8400_codec_remove, 1451 .suspend = wm8400_suspend, 1452 .resume = wm8400_resume, 1453 .read = wm8400_read, 1454 .write = wm8400_write, 1455 .set_bias_level = wm8400_set_bias_level, 1456 }; 1457 1458 static int __devinit wm8400_probe(struct platform_device *pdev) 1459 { 1460 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8400, 1461 &wm8400_dai, 1); 1462 } 1463 1464 static int __devexit wm8400_remove(struct platform_device *pdev) 1465 { 1466 snd_soc_unregister_codec(&pdev->dev); 1467 return 0; 1468 } 1469 1470 static struct platform_driver wm8400_codec_driver = { 1471 .driver = { 1472 .name = "wm8400-codec", 1473 .owner = THIS_MODULE, 1474 }, 1475 .probe = wm8400_probe, 1476 .remove = __devexit_p(wm8400_remove), 1477 }; 1478 1479 static __init int wm8400_init(void) 1480 { 1481 return platform_driver_register(&wm8400_codec_driver); 1482 } 1483 module_init(wm8400_init); 1484 1485 static __exit void wm8400_exit(void) 1486 { 1487 platform_driver_unregister(&wm8400_codec_driver); 1488 } 1489 module_exit(wm8400_exit); 1490 1491 MODULE_DESCRIPTION("ASoC WM8400 driver"); 1492 MODULE_AUTHOR("Mark Brown"); 1493 MODULE_LICENSE("GPL"); 1494 MODULE_ALIAS("platform:wm8400-codec"); 1495