1 /* 2 * da7219.c - DA7219 ALSA SoC Codec Driver 3 * 4 * Copyright (c) 2015 Dialog Semiconductor 5 * 6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 */ 13 14 #include <linux/acpi.h> 15 #include <linux/clk.h> 16 #include <linux/i2c.h> 17 #include <linux/of_device.h> 18 #include <linux/regmap.h> 19 #include <linux/slab.h> 20 #include <linux/pm.h> 21 #include <linux/module.h> 22 #include <linux/delay.h> 23 #include <linux/regulator/consumer.h> 24 #include <sound/pcm.h> 25 #include <sound/pcm_params.h> 26 #include <sound/soc.h> 27 #include <sound/soc-dapm.h> 28 #include <sound/initval.h> 29 #include <sound/tlv.h> 30 #include <asm/div64.h> 31 32 #include <sound/da7219.h> 33 #include "da7219.h" 34 #include "da7219-aad.h" 35 36 37 /* 38 * TLVs and Enums 39 */ 40 41 /* Input TLVs */ 42 static const DECLARE_TLV_DB_SCALE(da7219_mic_gain_tlv, -600, 600, 0); 43 static const DECLARE_TLV_DB_SCALE(da7219_mixin_gain_tlv, -450, 150, 0); 44 static const DECLARE_TLV_DB_SCALE(da7219_adc_dig_gain_tlv, -8325, 75, 0); 45 static const DECLARE_TLV_DB_SCALE(da7219_alc_threshold_tlv, -9450, 150, 0); 46 static const DECLARE_TLV_DB_SCALE(da7219_alc_gain_tlv, 0, 600, 0); 47 static const DECLARE_TLV_DB_SCALE(da7219_alc_ana_gain_tlv, 0, 600, 0); 48 static const DECLARE_TLV_DB_SCALE(da7219_sidetone_gain_tlv, -4200, 300, 0); 49 static const DECLARE_TLV_DB_SCALE(da7219_tonegen_gain_tlv, -4500, 300, 0); 50 51 /* Output TLVs */ 52 static const DECLARE_TLV_DB_SCALE(da7219_dac_eq_band_tlv, -1050, 150, 0); 53 54 static const DECLARE_TLV_DB_RANGE(da7219_dac_dig_gain_tlv, 55 0x0, 0x07, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), 56 /* -77.25dB to 12dB */ 57 0x08, 0x7f, TLV_DB_SCALE_ITEM(-7725, 75, 0) 58 ); 59 60 static const DECLARE_TLV_DB_SCALE(da7219_dac_ng_threshold_tlv, -10200, 600, 0); 61 static const DECLARE_TLV_DB_SCALE(da7219_hp_gain_tlv, -5700, 100, 0); 62 63 /* Input Enums */ 64 static const char * const da7219_alc_attack_rate_txt[] = { 65 "7.33/fs", "14.66/fs", "29.32/fs", "58.64/fs", "117.3/fs", "234.6/fs", 66 "469.1/fs", "938.2/fs", "1876/fs", "3753/fs", "7506/fs", "15012/fs", 67 "30024/fs" 68 }; 69 70 static const struct soc_enum da7219_alc_attack_rate = 71 SOC_ENUM_SINGLE(DA7219_ALC_CTRL2, DA7219_ALC_ATTACK_SHIFT, 72 DA7219_ALC_ATTACK_MAX, da7219_alc_attack_rate_txt); 73 74 static const char * const da7219_alc_release_rate_txt[] = { 75 "28.66/fs", "57.33/fs", "114.6/fs", "229.3/fs", "458.6/fs", "917.1/fs", 76 "1834/fs", "3668/fs", "7337/fs", "14674/fs", "29348/fs" 77 }; 78 79 static const struct soc_enum da7219_alc_release_rate = 80 SOC_ENUM_SINGLE(DA7219_ALC_CTRL2, DA7219_ALC_RELEASE_SHIFT, 81 DA7219_ALC_RELEASE_MAX, da7219_alc_release_rate_txt); 82 83 static const char * const da7219_alc_hold_time_txt[] = { 84 "62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs", 85 "7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs", 86 "253952/fs", "507904/fs", "1015808/fs", "2031616/fs" 87 }; 88 89 static const struct soc_enum da7219_alc_hold_time = 90 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3, DA7219_ALC_HOLD_SHIFT, 91 DA7219_ALC_HOLD_MAX, da7219_alc_hold_time_txt); 92 93 static const char * const da7219_alc_env_rate_txt[] = { 94 "1/4", "1/16", "1/256", "1/65536" 95 }; 96 97 static const struct soc_enum da7219_alc_env_attack_rate = 98 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3, DA7219_ALC_INTEG_ATTACK_SHIFT, 99 DA7219_ALC_INTEG_MAX, da7219_alc_env_rate_txt); 100 101 static const struct soc_enum da7219_alc_env_release_rate = 102 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3, DA7219_ALC_INTEG_RELEASE_SHIFT, 103 DA7219_ALC_INTEG_MAX, da7219_alc_env_rate_txt); 104 105 static const char * const da7219_alc_anticlip_step_txt[] = { 106 "0.034dB/fs", "0.068dB/fs", "0.136dB/fs", "0.272dB/fs" 107 }; 108 109 static const struct soc_enum da7219_alc_anticlip_step = 110 SOC_ENUM_SINGLE(DA7219_ALC_ANTICLIP_CTRL, 111 DA7219_ALC_ANTICLIP_STEP_SHIFT, 112 DA7219_ALC_ANTICLIP_STEP_MAX, 113 da7219_alc_anticlip_step_txt); 114 115 /* Input/Output Enums */ 116 static const char * const da7219_gain_ramp_rate_txt[] = { 117 "Nominal Rate * 8", "Nominal Rate", "Nominal Rate / 8", 118 "Nominal Rate / 16" 119 }; 120 121 static const struct soc_enum da7219_gain_ramp_rate = 122 SOC_ENUM_SINGLE(DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_SHIFT, 123 DA7219_GAIN_RAMP_RATE_MAX, da7219_gain_ramp_rate_txt); 124 125 static const char * const da7219_hpf_mode_txt[] = { 126 "Disabled", "Audio", "Voice" 127 }; 128 129 static const unsigned int da7219_hpf_mode_val[] = { 130 DA7219_HPF_DISABLED, DA7219_HPF_AUDIO_EN, DA7219_HPF_VOICE_EN, 131 }; 132 133 static const struct soc_enum da7219_adc_hpf_mode = 134 SOC_VALUE_ENUM_SINGLE(DA7219_ADC_FILTERS1, DA7219_HPF_MODE_SHIFT, 135 DA7219_HPF_MODE_MASK, DA7219_HPF_MODE_MAX, 136 da7219_hpf_mode_txt, da7219_hpf_mode_val); 137 138 static const struct soc_enum da7219_dac_hpf_mode = 139 SOC_VALUE_ENUM_SINGLE(DA7219_DAC_FILTERS1, DA7219_HPF_MODE_SHIFT, 140 DA7219_HPF_MODE_MASK, DA7219_HPF_MODE_MAX, 141 da7219_hpf_mode_txt, da7219_hpf_mode_val); 142 143 static const char * const da7219_audio_hpf_corner_txt[] = { 144 "2Hz", "4Hz", "8Hz", "16Hz" 145 }; 146 147 static const struct soc_enum da7219_adc_audio_hpf_corner = 148 SOC_ENUM_SINGLE(DA7219_ADC_FILTERS1, 149 DA7219_ADC_AUDIO_HPF_CORNER_SHIFT, 150 DA7219_AUDIO_HPF_CORNER_MAX, 151 da7219_audio_hpf_corner_txt); 152 153 static const struct soc_enum da7219_dac_audio_hpf_corner = 154 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS1, 155 DA7219_DAC_AUDIO_HPF_CORNER_SHIFT, 156 DA7219_AUDIO_HPF_CORNER_MAX, 157 da7219_audio_hpf_corner_txt); 158 159 static const char * const da7219_voice_hpf_corner_txt[] = { 160 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" 161 }; 162 163 static const struct soc_enum da7219_adc_voice_hpf_corner = 164 SOC_ENUM_SINGLE(DA7219_ADC_FILTERS1, 165 DA7219_ADC_VOICE_HPF_CORNER_SHIFT, 166 DA7219_VOICE_HPF_CORNER_MAX, 167 da7219_voice_hpf_corner_txt); 168 169 static const struct soc_enum da7219_dac_voice_hpf_corner = 170 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS1, 171 DA7219_DAC_VOICE_HPF_CORNER_SHIFT, 172 DA7219_VOICE_HPF_CORNER_MAX, 173 da7219_voice_hpf_corner_txt); 174 175 static const char * const da7219_tonegen_dtmf_key_txt[] = { 176 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", 177 "*", "#" 178 }; 179 180 static const struct soc_enum da7219_tonegen_dtmf_key = 181 SOC_ENUM_SINGLE(DA7219_TONE_GEN_CFG1, DA7219_DTMF_REG_SHIFT, 182 DA7219_DTMF_REG_MAX, da7219_tonegen_dtmf_key_txt); 183 184 static const char * const da7219_tonegen_swg_sel_txt[] = { 185 "Sum", "SWG1", "SWG2", "SWG1_1-Cos" 186 }; 187 188 static const struct soc_enum da7219_tonegen_swg_sel = 189 SOC_ENUM_SINGLE(DA7219_TONE_GEN_CFG2, DA7219_SWG_SEL_SHIFT, 190 DA7219_SWG_SEL_MAX, da7219_tonegen_swg_sel_txt); 191 192 /* Output Enums */ 193 static const char * const da7219_dac_softmute_rate_txt[] = { 194 "1 Sample", "2 Samples", "4 Samples", "8 Samples", "16 Samples", 195 "32 Samples", "64 Samples" 196 }; 197 198 static const struct soc_enum da7219_dac_softmute_rate = 199 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS5, DA7219_DAC_SOFTMUTE_RATE_SHIFT, 200 DA7219_DAC_SOFTMUTE_RATE_MAX, 201 da7219_dac_softmute_rate_txt); 202 203 static const char * const da7219_dac_ng_setup_time_txt[] = { 204 "256 Samples", "512 Samples", "1024 Samples", "2048 Samples" 205 }; 206 207 static const struct soc_enum da7219_dac_ng_setup_time = 208 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME, 209 DA7219_DAC_NG_SETUP_TIME_SHIFT, 210 DA7219_DAC_NG_SETUP_TIME_MAX, 211 da7219_dac_ng_setup_time_txt); 212 213 static const char * const da7219_dac_ng_rampup_txt[] = { 214 "0.22ms/dB", "0.0138ms/dB" 215 }; 216 217 static const struct soc_enum da7219_dac_ng_rampup_rate = 218 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME, 219 DA7219_DAC_NG_RAMPUP_RATE_SHIFT, 220 DA7219_DAC_NG_RAMP_RATE_MAX, 221 da7219_dac_ng_rampup_txt); 222 223 static const char * const da7219_dac_ng_rampdown_txt[] = { 224 "0.88ms/dB", "14.08ms/dB" 225 }; 226 227 static const struct soc_enum da7219_dac_ng_rampdown_rate = 228 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME, 229 DA7219_DAC_NG_RAMPDN_RATE_SHIFT, 230 DA7219_DAC_NG_RAMP_RATE_MAX, 231 da7219_dac_ng_rampdown_txt); 232 233 234 static const char * const da7219_cp_track_mode_txt[] = { 235 "Largest Volume", "DAC Volume", "Signal Magnitude" 236 }; 237 238 static const unsigned int da7219_cp_track_mode_val[] = { 239 DA7219_CP_MCHANGE_LARGEST_VOL, DA7219_CP_MCHANGE_DAC_VOL, 240 DA7219_CP_MCHANGE_SIG_MAG 241 }; 242 243 static const struct soc_enum da7219_cp_track_mode = 244 SOC_VALUE_ENUM_SINGLE(DA7219_CP_CTRL, DA7219_CP_MCHANGE_SHIFT, 245 DA7219_CP_MCHANGE_REL_MASK, DA7219_CP_MCHANGE_MAX, 246 da7219_cp_track_mode_txt, 247 da7219_cp_track_mode_val); 248 249 250 /* 251 * Control Functions 252 */ 253 254 /* Locked Kcontrol calls */ 255 static int da7219_volsw_locked_get(struct snd_kcontrol *kcontrol, 256 struct snd_ctl_elem_value *ucontrol) 257 { 258 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 259 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 260 int ret; 261 262 mutex_lock(&da7219->lock); 263 ret = snd_soc_get_volsw(kcontrol, ucontrol); 264 mutex_unlock(&da7219->lock); 265 266 return ret; 267 } 268 269 static int da7219_volsw_locked_put(struct snd_kcontrol *kcontrol, 270 struct snd_ctl_elem_value *ucontrol) 271 { 272 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 273 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 274 int ret; 275 276 mutex_lock(&da7219->lock); 277 ret = snd_soc_put_volsw(kcontrol, ucontrol); 278 mutex_unlock(&da7219->lock); 279 280 return ret; 281 } 282 283 static int da7219_enum_locked_get(struct snd_kcontrol *kcontrol, 284 struct snd_ctl_elem_value *ucontrol) 285 { 286 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 287 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 288 int ret; 289 290 mutex_lock(&da7219->lock); 291 ret = snd_soc_get_enum_double(kcontrol, ucontrol); 292 mutex_unlock(&da7219->lock); 293 294 return ret; 295 } 296 297 static int da7219_enum_locked_put(struct snd_kcontrol *kcontrol, 298 struct snd_ctl_elem_value *ucontrol) 299 { 300 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 301 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 302 int ret; 303 304 mutex_lock(&da7219->lock); 305 ret = snd_soc_put_enum_double(kcontrol, ucontrol); 306 mutex_unlock(&da7219->lock); 307 308 return ret; 309 } 310 311 /* ALC */ 312 static void da7219_alc_calib(struct snd_soc_codec *codec) 313 { 314 u8 mic_ctrl, mixin_ctrl, adc_ctrl, calib_ctrl; 315 316 /* Save current state of mic control register */ 317 mic_ctrl = snd_soc_read(codec, DA7219_MIC_1_CTRL); 318 319 /* Save current state of input mixer control register */ 320 mixin_ctrl = snd_soc_read(codec, DA7219_MIXIN_L_CTRL); 321 322 /* Save current state of input ADC control register */ 323 adc_ctrl = snd_soc_read(codec, DA7219_ADC_L_CTRL); 324 325 /* Enable then Mute MIC PGAs */ 326 snd_soc_update_bits(codec, DA7219_MIC_1_CTRL, DA7219_MIC_1_AMP_EN_MASK, 327 DA7219_MIC_1_AMP_EN_MASK); 328 snd_soc_update_bits(codec, DA7219_MIC_1_CTRL, 329 DA7219_MIC_1_AMP_MUTE_EN_MASK, 330 DA7219_MIC_1_AMP_MUTE_EN_MASK); 331 332 /* Enable input mixers unmuted */ 333 snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL, 334 DA7219_MIXIN_L_AMP_EN_MASK | 335 DA7219_MIXIN_L_AMP_MUTE_EN_MASK, 336 DA7219_MIXIN_L_AMP_EN_MASK); 337 338 /* Enable input filters unmuted */ 339 snd_soc_update_bits(codec, DA7219_ADC_L_CTRL, 340 DA7219_ADC_L_MUTE_EN_MASK | DA7219_ADC_L_EN_MASK, 341 DA7219_ADC_L_EN_MASK); 342 343 /* Perform auto calibration */ 344 snd_soc_update_bits(codec, DA7219_ALC_CTRL1, 345 DA7219_ALC_AUTO_CALIB_EN_MASK, 346 DA7219_ALC_AUTO_CALIB_EN_MASK); 347 do { 348 calib_ctrl = snd_soc_read(codec, DA7219_ALC_CTRL1); 349 } while (calib_ctrl & DA7219_ALC_AUTO_CALIB_EN_MASK); 350 351 /* If auto calibration fails, disable DC offset, hybrid ALC */ 352 if (calib_ctrl & DA7219_ALC_CALIB_OVERFLOW_MASK) { 353 dev_warn(codec->dev, 354 "ALC auto calibration failed with overflow\n"); 355 snd_soc_update_bits(codec, DA7219_ALC_CTRL1, 356 DA7219_ALC_OFFSET_EN_MASK | 357 DA7219_ALC_SYNC_MODE_MASK, 0); 358 } else { 359 /* Enable DC offset cancellation, hybrid mode */ 360 snd_soc_update_bits(codec, DA7219_ALC_CTRL1, 361 DA7219_ALC_OFFSET_EN_MASK | 362 DA7219_ALC_SYNC_MODE_MASK, 363 DA7219_ALC_OFFSET_EN_MASK | 364 DA7219_ALC_SYNC_MODE_MASK); 365 } 366 367 /* Restore input filter control register to original state */ 368 snd_soc_write(codec, DA7219_ADC_L_CTRL, adc_ctrl); 369 370 /* Restore input mixer control registers to original state */ 371 snd_soc_write(codec, DA7219_MIXIN_L_CTRL, mixin_ctrl); 372 373 /* Restore MIC control registers to original states */ 374 snd_soc_write(codec, DA7219_MIC_1_CTRL, mic_ctrl); 375 } 376 377 static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol, 378 struct snd_ctl_elem_value *ucontrol) 379 { 380 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 381 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 382 int ret; 383 384 ret = snd_soc_put_volsw(kcontrol, ucontrol); 385 386 /* 387 * If ALC in operation and value of control has been updated, 388 * make sure calibrated offsets are updated. 389 */ 390 if ((ret == 1) && (da7219->alc_en)) 391 da7219_alc_calib(codec); 392 393 return ret; 394 } 395 396 static int da7219_alc_sw_put(struct snd_kcontrol *kcontrol, 397 struct snd_ctl_elem_value *ucontrol) 398 { 399 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 400 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 401 402 403 /* Force ALC offset calibration if enabling ALC */ 404 if ((ucontrol->value.integer.value[0]) && (!da7219->alc_en)) { 405 da7219_alc_calib(codec); 406 da7219->alc_en = true; 407 } else { 408 da7219->alc_en = false; 409 } 410 411 return snd_soc_put_volsw(kcontrol, ucontrol); 412 } 413 414 /* ToneGen */ 415 static int da7219_tonegen_freq_get(struct snd_kcontrol *kcontrol, 416 struct snd_ctl_elem_value *ucontrol) 417 { 418 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 419 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 420 struct soc_mixer_control *mixer_ctrl = 421 (struct soc_mixer_control *) kcontrol->private_value; 422 unsigned int reg = mixer_ctrl->reg; 423 u16 val; 424 int ret; 425 426 mutex_lock(&da7219->lock); 427 ret = regmap_raw_read(da7219->regmap, reg, &val, sizeof(val)); 428 mutex_unlock(&da7219->lock); 429 430 if (ret) 431 return ret; 432 433 /* 434 * Frequency value spans two 8-bit registers, lower then upper byte. 435 * Therefore we need to convert to host endianness here. 436 */ 437 ucontrol->value.integer.value[0] = le16_to_cpu(val); 438 439 return 0; 440 } 441 442 static int da7219_tonegen_freq_put(struct snd_kcontrol *kcontrol, 443 struct snd_ctl_elem_value *ucontrol) 444 { 445 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 446 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 447 struct soc_mixer_control *mixer_ctrl = 448 (struct soc_mixer_control *) kcontrol->private_value; 449 unsigned int reg = mixer_ctrl->reg; 450 u16 val; 451 int ret; 452 453 /* 454 * Frequency value spans two 8-bit registers, lower then upper byte. 455 * Therefore we need to convert to little endian here to align with 456 * HW registers. 457 */ 458 val = cpu_to_le16(ucontrol->value.integer.value[0]); 459 460 mutex_lock(&da7219->lock); 461 ret = regmap_raw_write(da7219->regmap, reg, &val, sizeof(val)); 462 mutex_unlock(&da7219->lock); 463 464 return ret; 465 } 466 467 468 /* 469 * KControls 470 */ 471 472 static const struct snd_kcontrol_new da7219_snd_controls[] = { 473 /* Mics */ 474 SOC_SINGLE_TLV("Mic Volume", DA7219_MIC_1_GAIN, 475 DA7219_MIC_1_AMP_GAIN_SHIFT, DA7219_MIC_1_AMP_GAIN_MAX, 476 DA7219_NO_INVERT, da7219_mic_gain_tlv), 477 SOC_SINGLE("Mic Switch", DA7219_MIC_1_CTRL, 478 DA7219_MIC_1_AMP_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX, 479 DA7219_INVERT), 480 481 /* Mixer Input */ 482 SOC_SINGLE_EXT_TLV("Mixin Volume", DA7219_MIXIN_L_GAIN, 483 DA7219_MIXIN_L_AMP_GAIN_SHIFT, 484 DA7219_MIXIN_L_AMP_GAIN_MAX, DA7219_NO_INVERT, 485 snd_soc_get_volsw, da7219_mixin_gain_put, 486 da7219_mixin_gain_tlv), 487 SOC_SINGLE("Mixin Switch", DA7219_MIXIN_L_CTRL, 488 DA7219_MIXIN_L_AMP_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX, 489 DA7219_INVERT), 490 SOC_SINGLE("Mixin Gain Ramp Switch", DA7219_MIXIN_L_CTRL, 491 DA7219_MIXIN_L_AMP_RAMP_EN_SHIFT, DA7219_SWITCH_EN_MAX, 492 DA7219_NO_INVERT), 493 SOC_SINGLE("Mixin ZC Gain Switch", DA7219_MIXIN_L_CTRL, 494 DA7219_MIXIN_L_AMP_ZC_EN_SHIFT, DA7219_SWITCH_EN_MAX, 495 DA7219_NO_INVERT), 496 497 /* ADC */ 498 SOC_SINGLE_TLV("Capture Digital Volume", DA7219_ADC_L_GAIN, 499 DA7219_ADC_L_DIGITAL_GAIN_SHIFT, 500 DA7219_ADC_L_DIGITAL_GAIN_MAX, DA7219_NO_INVERT, 501 da7219_adc_dig_gain_tlv), 502 SOC_SINGLE("Capture Digital Switch", DA7219_ADC_L_CTRL, 503 DA7219_ADC_L_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX, 504 DA7219_INVERT), 505 SOC_SINGLE("Capture Digital Gain Ramp Switch", DA7219_ADC_L_CTRL, 506 DA7219_ADC_L_RAMP_EN_SHIFT, DA7219_SWITCH_EN_MAX, 507 DA7219_NO_INVERT), 508 509 /* ALC */ 510 SOC_ENUM("ALC Attack Rate", da7219_alc_attack_rate), 511 SOC_ENUM("ALC Release Rate", da7219_alc_release_rate), 512 SOC_ENUM("ALC Hold Time", da7219_alc_hold_time), 513 SOC_ENUM("ALC Envelope Attack Rate", da7219_alc_env_attack_rate), 514 SOC_ENUM("ALC Envelope Release Rate", da7219_alc_env_release_rate), 515 SOC_SINGLE_TLV("ALC Noise Threshold", DA7219_ALC_NOISE, 516 DA7219_ALC_NOISE_SHIFT, DA7219_ALC_THRESHOLD_MAX, 517 DA7219_INVERT, da7219_alc_threshold_tlv), 518 SOC_SINGLE_TLV("ALC Min Threshold", DA7219_ALC_TARGET_MIN, 519 DA7219_ALC_THRESHOLD_MIN_SHIFT, DA7219_ALC_THRESHOLD_MAX, 520 DA7219_INVERT, da7219_alc_threshold_tlv), 521 SOC_SINGLE_TLV("ALC Max Threshold", DA7219_ALC_TARGET_MAX, 522 DA7219_ALC_THRESHOLD_MAX_SHIFT, DA7219_ALC_THRESHOLD_MAX, 523 DA7219_INVERT, da7219_alc_threshold_tlv), 524 SOC_SINGLE_TLV("ALC Max Attenuation", DA7219_ALC_GAIN_LIMITS, 525 DA7219_ALC_ATTEN_MAX_SHIFT, DA7219_ALC_ATTEN_GAIN_MAX, 526 DA7219_NO_INVERT, da7219_alc_gain_tlv), 527 SOC_SINGLE_TLV("ALC Max Volume", DA7219_ALC_GAIN_LIMITS, 528 DA7219_ALC_GAIN_MAX_SHIFT, DA7219_ALC_ATTEN_GAIN_MAX, 529 DA7219_NO_INVERT, da7219_alc_gain_tlv), 530 SOC_SINGLE_RANGE_TLV("ALC Min Analog Volume", DA7219_ALC_ANA_GAIN_LIMITS, 531 DA7219_ALC_ANA_GAIN_MIN_SHIFT, 532 DA7219_ALC_ANA_GAIN_MIN, DA7219_ALC_ANA_GAIN_MAX, 533 DA7219_NO_INVERT, da7219_alc_ana_gain_tlv), 534 SOC_SINGLE_RANGE_TLV("ALC Max Analog Volume", DA7219_ALC_ANA_GAIN_LIMITS, 535 DA7219_ALC_ANA_GAIN_MAX_SHIFT, 536 DA7219_ALC_ANA_GAIN_MIN, DA7219_ALC_ANA_GAIN_MAX, 537 DA7219_NO_INVERT, da7219_alc_ana_gain_tlv), 538 SOC_ENUM("ALC Anticlip Step", da7219_alc_anticlip_step), 539 SOC_SINGLE("ALC Anticlip Switch", DA7219_ALC_ANTICLIP_CTRL, 540 DA7219_ALC_ANTIPCLIP_EN_SHIFT, DA7219_SWITCH_EN_MAX, 541 DA7219_NO_INVERT), 542 SOC_SINGLE_EXT("ALC Switch", DA7219_ALC_CTRL1, DA7219_ALC_EN_SHIFT, 543 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT, 544 snd_soc_get_volsw, da7219_alc_sw_put), 545 546 /* Input High-Pass Filters */ 547 SOC_ENUM("ADC HPF Mode", da7219_adc_hpf_mode), 548 SOC_ENUM("ADC HPF Corner Audio", da7219_adc_audio_hpf_corner), 549 SOC_ENUM("ADC HPF Corner Voice", da7219_adc_voice_hpf_corner), 550 551 /* Sidetone Filter */ 552 SOC_SINGLE_TLV("Sidetone Volume", DA7219_SIDETONE_GAIN, 553 DA7219_SIDETONE_GAIN_SHIFT, DA7219_SIDETONE_GAIN_MAX, 554 DA7219_NO_INVERT, da7219_sidetone_gain_tlv), 555 SOC_SINGLE("Sidetone Switch", DA7219_SIDETONE_CTRL, 556 DA7219_SIDETONE_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX, 557 DA7219_INVERT), 558 559 /* Tone Generator */ 560 SOC_SINGLE_EXT_TLV("ToneGen Volume", DA7219_TONE_GEN_CFG2, 561 DA7219_TONE_GEN_GAIN_SHIFT, DA7219_TONE_GEN_GAIN_MAX, 562 DA7219_NO_INVERT, da7219_volsw_locked_get, 563 da7219_volsw_locked_put, da7219_tonegen_gain_tlv), 564 SOC_ENUM_EXT("ToneGen DTMF Key", da7219_tonegen_dtmf_key, 565 da7219_enum_locked_get, da7219_enum_locked_put), 566 SOC_SINGLE_EXT("ToneGen DTMF Switch", DA7219_TONE_GEN_CFG1, 567 DA7219_DTMF_EN_SHIFT, DA7219_SWITCH_EN_MAX, 568 DA7219_NO_INVERT, da7219_volsw_locked_get, 569 da7219_volsw_locked_put), 570 SOC_ENUM_EXT("ToneGen Sinewave Gen Type", da7219_tonegen_swg_sel, 571 da7219_enum_locked_get, da7219_enum_locked_put), 572 SOC_SINGLE_EXT("ToneGen Sinewave1 Freq", DA7219_TONE_GEN_FREQ1_L, 573 DA7219_FREQ1_L_SHIFT, DA7219_FREQ_MAX, DA7219_NO_INVERT, 574 da7219_tonegen_freq_get, da7219_tonegen_freq_put), 575 SOC_SINGLE_EXT("ToneGen Sinewave2 Freq", DA7219_TONE_GEN_FREQ2_L, 576 DA7219_FREQ2_L_SHIFT, DA7219_FREQ_MAX, DA7219_NO_INVERT, 577 da7219_tonegen_freq_get, da7219_tonegen_freq_put), 578 SOC_SINGLE_EXT("ToneGen On Time", DA7219_TONE_GEN_ON_PER, 579 DA7219_BEEP_ON_PER_SHIFT, DA7219_BEEP_ON_OFF_MAX, 580 DA7219_NO_INVERT, da7219_volsw_locked_get, 581 da7219_volsw_locked_put), 582 SOC_SINGLE("ToneGen Off Time", DA7219_TONE_GEN_OFF_PER, 583 DA7219_BEEP_OFF_PER_SHIFT, DA7219_BEEP_ON_OFF_MAX, 584 DA7219_NO_INVERT), 585 586 /* Gain ramping */ 587 SOC_ENUM("Gain Ramp Rate", da7219_gain_ramp_rate), 588 589 /* DAC High-Pass Filter */ 590 SOC_ENUM_EXT("DAC HPF Mode", da7219_dac_hpf_mode, 591 da7219_enum_locked_get, da7219_enum_locked_put), 592 SOC_ENUM("DAC HPF Corner Audio", da7219_dac_audio_hpf_corner), 593 SOC_ENUM("DAC HPF Corner Voice", da7219_dac_voice_hpf_corner), 594 595 /* DAC 5-Band Equaliser */ 596 SOC_SINGLE_TLV("DAC EQ Band1 Volume", DA7219_DAC_FILTERS2, 597 DA7219_DAC_EQ_BAND1_SHIFT, DA7219_DAC_EQ_BAND_MAX, 598 DA7219_NO_INVERT, da7219_dac_eq_band_tlv), 599 SOC_SINGLE_TLV("DAC EQ Band2 Volume", DA7219_DAC_FILTERS2, 600 DA7219_DAC_EQ_BAND2_SHIFT, DA7219_DAC_EQ_BAND_MAX, 601 DA7219_NO_INVERT, da7219_dac_eq_band_tlv), 602 SOC_SINGLE_TLV("DAC EQ Band3 Volume", DA7219_DAC_FILTERS3, 603 DA7219_DAC_EQ_BAND3_SHIFT, DA7219_DAC_EQ_BAND_MAX, 604 DA7219_NO_INVERT, da7219_dac_eq_band_tlv), 605 SOC_SINGLE_TLV("DAC EQ Band4 Volume", DA7219_DAC_FILTERS3, 606 DA7219_DAC_EQ_BAND4_SHIFT, DA7219_DAC_EQ_BAND_MAX, 607 DA7219_NO_INVERT, da7219_dac_eq_band_tlv), 608 SOC_SINGLE_TLV("DAC EQ Band5 Volume", DA7219_DAC_FILTERS4, 609 DA7219_DAC_EQ_BAND5_SHIFT, DA7219_DAC_EQ_BAND_MAX, 610 DA7219_NO_INVERT, da7219_dac_eq_band_tlv), 611 SOC_SINGLE_EXT("DAC EQ Switch", DA7219_DAC_FILTERS4, 612 DA7219_DAC_EQ_EN_SHIFT, DA7219_SWITCH_EN_MAX, 613 DA7219_NO_INVERT, da7219_volsw_locked_get, 614 da7219_volsw_locked_put), 615 616 /* DAC Softmute */ 617 SOC_ENUM("DAC Soft Mute Rate", da7219_dac_softmute_rate), 618 SOC_SINGLE_EXT("DAC Soft Mute Switch", DA7219_DAC_FILTERS5, 619 DA7219_DAC_SOFTMUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX, 620 DA7219_NO_INVERT, da7219_volsw_locked_get, 621 da7219_volsw_locked_put), 622 623 /* DAC Noise Gate */ 624 SOC_ENUM("DAC NG Setup Time", da7219_dac_ng_setup_time), 625 SOC_ENUM("DAC NG Rampup Rate", da7219_dac_ng_rampup_rate), 626 SOC_ENUM("DAC NG Rampdown Rate", da7219_dac_ng_rampdown_rate), 627 SOC_SINGLE_TLV("DAC NG Off Threshold", DA7219_DAC_NG_OFF_THRESH, 628 DA7219_DAC_NG_OFF_THRESHOLD_SHIFT, 629 DA7219_DAC_NG_THRESHOLD_MAX, DA7219_NO_INVERT, 630 da7219_dac_ng_threshold_tlv), 631 SOC_SINGLE_TLV("DAC NG On Threshold", DA7219_DAC_NG_ON_THRESH, 632 DA7219_DAC_NG_ON_THRESHOLD_SHIFT, 633 DA7219_DAC_NG_THRESHOLD_MAX, DA7219_NO_INVERT, 634 da7219_dac_ng_threshold_tlv), 635 SOC_SINGLE("DAC NG Switch", DA7219_DAC_NG_CTRL, DA7219_DAC_NG_EN_SHIFT, 636 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), 637 638 /* DACs */ 639 SOC_DOUBLE_R_EXT_TLV("Playback Digital Volume", DA7219_DAC_L_GAIN, 640 DA7219_DAC_R_GAIN, DA7219_DAC_L_DIGITAL_GAIN_SHIFT, 641 DA7219_DAC_DIGITAL_GAIN_MAX, DA7219_NO_INVERT, 642 da7219_volsw_locked_get, da7219_volsw_locked_put, 643 da7219_dac_dig_gain_tlv), 644 SOC_DOUBLE_R_EXT("Playback Digital Switch", DA7219_DAC_L_CTRL, 645 DA7219_DAC_R_CTRL, DA7219_DAC_L_MUTE_EN_SHIFT, 646 DA7219_SWITCH_EN_MAX, DA7219_INVERT, 647 da7219_volsw_locked_get, da7219_volsw_locked_put), 648 SOC_DOUBLE_R("Playback Digital Gain Ramp Switch", DA7219_DAC_L_CTRL, 649 DA7219_DAC_R_CTRL, DA7219_DAC_L_RAMP_EN_SHIFT, 650 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), 651 652 /* CP */ 653 SOC_ENUM("Charge Pump Track Mode", da7219_cp_track_mode), 654 SOC_SINGLE("Charge Pump Threshold", DA7219_CP_VOL_THRESHOLD1, 655 DA7219_CP_THRESH_VDD2_SHIFT, DA7219_CP_THRESH_VDD2_MAX, 656 DA7219_NO_INVERT), 657 658 /* Headphones */ 659 SOC_DOUBLE_R_EXT_TLV("Headphone Volume", DA7219_HP_L_GAIN, 660 DA7219_HP_R_GAIN, DA7219_HP_L_AMP_GAIN_SHIFT, 661 DA7219_HP_AMP_GAIN_MAX, DA7219_NO_INVERT, 662 da7219_volsw_locked_get, da7219_volsw_locked_put, 663 da7219_hp_gain_tlv), 664 SOC_DOUBLE_R_EXT("Headphone Switch", DA7219_HP_L_CTRL, DA7219_HP_R_CTRL, 665 DA7219_HP_L_AMP_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX, 666 DA7219_INVERT, da7219_volsw_locked_get, 667 da7219_volsw_locked_put), 668 SOC_DOUBLE_R("Headphone Gain Ramp Switch", DA7219_HP_L_CTRL, 669 DA7219_HP_R_CTRL, DA7219_HP_L_AMP_RAMP_EN_SHIFT, 670 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), 671 SOC_DOUBLE_R("Headphone ZC Gain Switch", DA7219_HP_L_CTRL, 672 DA7219_HP_R_CTRL, DA7219_HP_L_AMP_ZC_EN_SHIFT, 673 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), 674 }; 675 676 677 /* 678 * DAPM Mux Controls 679 */ 680 681 static const char * const da7219_out_sel_txt[] = { 682 "ADC", "Tone Generator", "DAIL", "DAIR" 683 }; 684 685 static const struct soc_enum da7219_out_dail_sel = 686 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAI, 687 DA7219_DAI_L_SRC_SHIFT, 688 DA7219_OUT_SRC_MAX, 689 da7219_out_sel_txt); 690 691 static const struct snd_kcontrol_new da7219_out_dail_sel_mux = 692 SOC_DAPM_ENUM("Out DAIL Mux", da7219_out_dail_sel); 693 694 static const struct soc_enum da7219_out_dair_sel = 695 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAI, 696 DA7219_DAI_R_SRC_SHIFT, 697 DA7219_OUT_SRC_MAX, 698 da7219_out_sel_txt); 699 700 static const struct snd_kcontrol_new da7219_out_dair_sel_mux = 701 SOC_DAPM_ENUM("Out DAIR Mux", da7219_out_dair_sel); 702 703 static const struct soc_enum da7219_out_dacl_sel = 704 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAC, 705 DA7219_DAC_L_SRC_SHIFT, 706 DA7219_OUT_SRC_MAX, 707 da7219_out_sel_txt); 708 709 static const struct snd_kcontrol_new da7219_out_dacl_sel_mux = 710 SOC_DAPM_ENUM("Out DACL Mux", da7219_out_dacl_sel); 711 712 static const struct soc_enum da7219_out_dacr_sel = 713 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAC, 714 DA7219_DAC_R_SRC_SHIFT, 715 DA7219_OUT_SRC_MAX, 716 da7219_out_sel_txt); 717 718 static const struct snd_kcontrol_new da7219_out_dacr_sel_mux = 719 SOC_DAPM_ENUM("Out DACR Mux", da7219_out_dacr_sel); 720 721 722 /* 723 * DAPM Mixer Controls 724 */ 725 726 static const struct snd_kcontrol_new da7219_mixin_controls[] = { 727 SOC_DAPM_SINGLE("Mic Switch", DA7219_MIXIN_L_SELECT, 728 DA7219_MIXIN_L_MIX_SELECT_SHIFT, 729 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), 730 }; 731 732 static const struct snd_kcontrol_new da7219_mixout_l_controls[] = { 733 SOC_DAPM_SINGLE("DACL Switch", DA7219_MIXOUT_L_SELECT, 734 DA7219_MIXOUT_L_MIX_SELECT_SHIFT, 735 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), 736 }; 737 738 static const struct snd_kcontrol_new da7219_mixout_r_controls[] = { 739 SOC_DAPM_SINGLE("DACR Switch", DA7219_MIXOUT_R_SELECT, 740 DA7219_MIXOUT_R_MIX_SELECT_SHIFT, 741 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), 742 }; 743 744 #define DA7219_DMIX_ST_CTRLS(reg) \ 745 SOC_DAPM_SINGLE("Out FilterL Switch", reg, \ 746 DA7219_DMIX_ST_SRC_OUTFILT1L_SHIFT, \ 747 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), \ 748 SOC_DAPM_SINGLE("Out FilterR Switch", reg, \ 749 DA7219_DMIX_ST_SRC_OUTFILT1R_SHIFT, \ 750 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), \ 751 SOC_DAPM_SINGLE("Sidetone Switch", reg, \ 752 DA7219_DMIX_ST_SRC_SIDETONE_SHIFT, \ 753 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT) \ 754 755 static const struct snd_kcontrol_new da7219_st_out_filtl_mix_controls[] = { 756 DA7219_DMIX_ST_CTRLS(DA7219_DROUTING_ST_OUTFILT_1L), 757 }; 758 759 static const struct snd_kcontrol_new da7219_st_out_filtr_mix_controls[] = { 760 DA7219_DMIX_ST_CTRLS(DA7219_DROUTING_ST_OUTFILT_1R), 761 }; 762 763 764 /* 765 * DAPM Events 766 */ 767 768 static int da7219_dai_event(struct snd_soc_dapm_widget *w, 769 struct snd_kcontrol *kcontrol, int event) 770 { 771 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 772 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 773 u8 pll_ctrl, pll_status; 774 int i = 0; 775 bool srm_lock = false; 776 777 switch (event) { 778 case SND_SOC_DAPM_PRE_PMU: 779 if (da7219->master) 780 /* Enable DAI clks for master mode */ 781 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE, 782 DA7219_DAI_CLK_EN_MASK, 783 DA7219_DAI_CLK_EN_MASK); 784 785 /* PC synchronised to DAI */ 786 snd_soc_update_bits(codec, DA7219_PC_COUNT, 787 DA7219_PC_FREERUN_MASK, 0); 788 789 /* Slave mode, if SRM not enabled no need for status checks */ 790 pll_ctrl = snd_soc_read(codec, DA7219_PLL_CTRL); 791 if ((pll_ctrl & DA7219_PLL_MODE_MASK) != DA7219_PLL_MODE_SRM) 792 return 0; 793 794 /* Check SRM has locked */ 795 do { 796 pll_status = snd_soc_read(codec, DA7219_PLL_SRM_STS); 797 if (pll_status & DA7219_PLL_SRM_STS_SRM_LOCK) { 798 srm_lock = true; 799 } else { 800 ++i; 801 msleep(50); 802 } 803 } while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock)); 804 805 if (!srm_lock) 806 dev_warn(codec->dev, "SRM failed to lock\n"); 807 808 return 0; 809 case SND_SOC_DAPM_POST_PMD: 810 /* PC free-running */ 811 snd_soc_update_bits(codec, DA7219_PC_COUNT, 812 DA7219_PC_FREERUN_MASK, 813 DA7219_PC_FREERUN_MASK); 814 815 /* Disable DAI clks if in master mode */ 816 if (da7219->master) 817 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE, 818 DA7219_DAI_CLK_EN_MASK, 0); 819 return 0; 820 default: 821 return -EINVAL; 822 } 823 } 824 825 826 /* 827 * DAPM Widgets 828 */ 829 830 static const struct snd_soc_dapm_widget da7219_dapm_widgets[] = { 831 /* Input Supplies */ 832 SND_SOC_DAPM_SUPPLY("Mic Bias", DA7219_MICBIAS_CTRL, 833 DA7219_MICBIAS1_EN_SHIFT, DA7219_NO_INVERT, 834 NULL, 0), 835 836 /* Inputs */ 837 SND_SOC_DAPM_INPUT("MIC"), 838 839 /* Input PGAs */ 840 SND_SOC_DAPM_PGA("Mic PGA", DA7219_MIC_1_CTRL, 841 DA7219_MIC_1_AMP_EN_SHIFT, DA7219_NO_INVERT, 842 NULL, 0), 843 SND_SOC_DAPM_PGA("Mixin PGA", DA7219_MIXIN_L_CTRL, 844 DA7219_MIXIN_L_AMP_EN_SHIFT, DA7219_NO_INVERT, 845 NULL, 0), 846 847 /* Input Filters */ 848 SND_SOC_DAPM_ADC("ADC", NULL, DA7219_ADC_L_CTRL, DA7219_ADC_L_EN_SHIFT, 849 DA7219_NO_INVERT), 850 851 /* Tone Generator */ 852 SND_SOC_DAPM_SIGGEN("TONE"), 853 SND_SOC_DAPM_PGA("Tone Generator", DA7219_TONE_GEN_CFG1, 854 DA7219_START_STOPN_SHIFT, DA7219_NO_INVERT, NULL, 0), 855 856 /* Sidetone Input */ 857 SND_SOC_DAPM_ADC("Sidetone Filter", NULL, DA7219_SIDETONE_CTRL, 858 DA7219_SIDETONE_EN_SHIFT, DA7219_NO_INVERT), 859 860 /* Input Mixer Supply */ 861 SND_SOC_DAPM_SUPPLY("Mixer In Supply", DA7219_MIXIN_L_CTRL, 862 DA7219_MIXIN_L_MIX_EN_SHIFT, DA7219_NO_INVERT, 863 NULL, 0), 864 865 /* Input Mixer */ 866 SND_SOC_DAPM_MIXER("Mixer In", SND_SOC_NOPM, 0, 0, 867 da7219_mixin_controls, 868 ARRAY_SIZE(da7219_mixin_controls)), 869 870 /* Input Muxes */ 871 SND_SOC_DAPM_MUX("Out DAIL Mux", SND_SOC_NOPM, 0, 0, 872 &da7219_out_dail_sel_mux), 873 SND_SOC_DAPM_MUX("Out DAIR Mux", SND_SOC_NOPM, 0, 0, 874 &da7219_out_dair_sel_mux), 875 876 /* DAI Supply */ 877 SND_SOC_DAPM_SUPPLY("DAI", DA7219_DAI_CTRL, DA7219_DAI_EN_SHIFT, 878 DA7219_NO_INVERT, da7219_dai_event, 879 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 880 881 /* DAI */ 882 SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, SND_SOC_NOPM, 0, 0), 883 SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0), 884 885 /* Output Muxes */ 886 SND_SOC_DAPM_MUX("Out DACL Mux", SND_SOC_NOPM, 0, 0, 887 &da7219_out_dacl_sel_mux), 888 SND_SOC_DAPM_MUX("Out DACR Mux", SND_SOC_NOPM, 0, 0, 889 &da7219_out_dacr_sel_mux), 890 891 /* Output Mixers */ 892 SND_SOC_DAPM_MIXER("Mixer Out FilterL", SND_SOC_NOPM, 0, 0, 893 da7219_mixout_l_controls, 894 ARRAY_SIZE(da7219_mixout_l_controls)), 895 SND_SOC_DAPM_MIXER("Mixer Out FilterR", SND_SOC_NOPM, 0, 0, 896 da7219_mixout_r_controls, 897 ARRAY_SIZE(da7219_mixout_r_controls)), 898 899 /* Sidetone Mixers */ 900 SND_SOC_DAPM_MIXER("ST Mixer Out FilterL", SND_SOC_NOPM, 0, 0, 901 da7219_st_out_filtl_mix_controls, 902 ARRAY_SIZE(da7219_st_out_filtl_mix_controls)), 903 SND_SOC_DAPM_MIXER("ST Mixer Out FilterR", SND_SOC_NOPM, 0, 904 0, da7219_st_out_filtr_mix_controls, 905 ARRAY_SIZE(da7219_st_out_filtr_mix_controls)), 906 907 /* DACs */ 908 SND_SOC_DAPM_DAC("DACL", NULL, DA7219_DAC_L_CTRL, DA7219_DAC_L_EN_SHIFT, 909 DA7219_NO_INVERT), 910 SND_SOC_DAPM_DAC("DACR", NULL, DA7219_DAC_R_CTRL, DA7219_DAC_R_EN_SHIFT, 911 DA7219_NO_INVERT), 912 913 /* Output PGAs */ 914 SND_SOC_DAPM_PGA("Mixout Left PGA", DA7219_MIXOUT_L_CTRL, 915 DA7219_MIXOUT_L_AMP_EN_SHIFT, DA7219_NO_INVERT, 916 NULL, 0), 917 SND_SOC_DAPM_PGA("Mixout Right PGA", DA7219_MIXOUT_R_CTRL, 918 DA7219_MIXOUT_R_AMP_EN_SHIFT, DA7219_NO_INVERT, 919 NULL, 0), 920 SND_SOC_DAPM_PGA("Headphone Left PGA", DA7219_HP_L_CTRL, 921 DA7219_HP_L_AMP_EN_SHIFT, DA7219_NO_INVERT, NULL, 0), 922 SND_SOC_DAPM_PGA("Headphone Right PGA", DA7219_HP_R_CTRL, 923 DA7219_HP_R_AMP_EN_SHIFT, DA7219_NO_INVERT, NULL, 0), 924 925 /* Output Supplies */ 926 SND_SOC_DAPM_SUPPLY("Charge Pump", DA7219_CP_CTRL, DA7219_CP_EN_SHIFT, 927 DA7219_NO_INVERT, NULL, 0), 928 929 /* Outputs */ 930 SND_SOC_DAPM_OUTPUT("HPL"), 931 SND_SOC_DAPM_OUTPUT("HPR"), 932 }; 933 934 935 /* 936 * DAPM Mux Routes 937 */ 938 939 #define DA7219_OUT_DAI_MUX_ROUTES(name) \ 940 {name, "ADC", "Mixer In"}, \ 941 {name, "Tone Generator", "Tone Generator"}, \ 942 {name, "DAIL", "DAIOUT"}, \ 943 {name, "DAIR", "DAIOUT"} 944 945 #define DA7219_OUT_DAC_MUX_ROUTES(name) \ 946 {name, "ADC", "Mixer In"}, \ 947 {name, "Tone Generator", "Tone Generator"}, \ 948 {name, "DAIL", "DAIIN"}, \ 949 {name, "DAIR", "DAIIN"} 950 951 /* 952 * DAPM Mixer Routes 953 */ 954 955 #define DA7219_DMIX_ST_ROUTES(name) \ 956 {name, "Out FilterL Switch", "Mixer Out FilterL"}, \ 957 {name, "Out FilterR Switch", "Mixer Out FilterR"}, \ 958 {name, "Sidetone Switch", "Sidetone Filter"} 959 960 961 /* 962 * DAPM audio route definition 963 */ 964 965 static const struct snd_soc_dapm_route da7219_audio_map[] = { 966 /* Input paths */ 967 {"MIC", NULL, "Mic Bias"}, 968 {"Mic PGA", NULL, "MIC"}, 969 {"Mixin PGA", NULL, "Mic PGA"}, 970 {"ADC", NULL, "Mixin PGA"}, 971 972 {"Mixer In", NULL, "Mixer In Supply"}, 973 {"Mixer In", "Mic Switch", "ADC"}, 974 975 {"Sidetone Filter", NULL, "Mixer In"}, 976 977 {"Tone Generator", NULL, "TONE"}, 978 979 DA7219_OUT_DAI_MUX_ROUTES("Out DAIL Mux"), 980 DA7219_OUT_DAI_MUX_ROUTES("Out DAIR Mux"), 981 982 {"DAIOUT", NULL, "Out DAIL Mux"}, 983 {"DAIOUT", NULL, "Out DAIR Mux"}, 984 {"DAIOUT", NULL, "DAI"}, 985 986 /* Output paths */ 987 {"DAIIN", NULL, "DAI"}, 988 989 DA7219_OUT_DAC_MUX_ROUTES("Out DACL Mux"), 990 DA7219_OUT_DAC_MUX_ROUTES("Out DACR Mux"), 991 992 {"Mixer Out FilterL", "DACL Switch", "Out DACL Mux"}, 993 {"Mixer Out FilterR", "DACR Switch", "Out DACR Mux"}, 994 995 DA7219_DMIX_ST_ROUTES("ST Mixer Out FilterL"), 996 DA7219_DMIX_ST_ROUTES("ST Mixer Out FilterR"), 997 998 {"DACL", NULL, "ST Mixer Out FilterL"}, 999 {"DACR", NULL, "ST Mixer Out FilterR"}, 1000 1001 {"Mixout Left PGA", NULL, "DACL"}, 1002 {"Mixout Right PGA", NULL, "DACR"}, 1003 1004 {"Headphone Left PGA", NULL, "Mixout Left PGA"}, 1005 {"Headphone Right PGA", NULL, "Mixout Right PGA"}, 1006 1007 {"HPL", NULL, "Headphone Left PGA"}, 1008 {"HPR", NULL, "Headphone Right PGA"}, 1009 1010 {"HPL", NULL, "Charge Pump"}, 1011 {"HPR", NULL, "Charge Pump"}, 1012 }; 1013 1014 1015 /* 1016 * DAI operations 1017 */ 1018 1019 static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai, 1020 int clk_id, unsigned int freq, int dir) 1021 { 1022 struct snd_soc_codec *codec = codec_dai->codec; 1023 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1024 int ret = 0; 1025 1026 if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq)) 1027 return 0; 1028 1029 if ((freq < 2000000) || (freq > 54000000)) { 1030 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n", 1031 freq); 1032 return -EINVAL; 1033 } 1034 1035 switch (clk_id) { 1036 case DA7219_CLKSRC_MCLK_SQR: 1037 snd_soc_update_bits(codec, DA7219_PLL_CTRL, 1038 DA7219_PLL_MCLK_SQR_EN_MASK, 1039 DA7219_PLL_MCLK_SQR_EN_MASK); 1040 break; 1041 case DA7219_CLKSRC_MCLK: 1042 snd_soc_update_bits(codec, DA7219_PLL_CTRL, 1043 DA7219_PLL_MCLK_SQR_EN_MASK, 0); 1044 break; 1045 default: 1046 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); 1047 return -EINVAL; 1048 } 1049 1050 da7219->clk_src = clk_id; 1051 1052 if (da7219->mclk) { 1053 freq = clk_round_rate(da7219->mclk, freq); 1054 ret = clk_set_rate(da7219->mclk, freq); 1055 if (ret) { 1056 dev_err(codec_dai->dev, "Failed to set clock rate %d\n", 1057 freq); 1058 return ret; 1059 } 1060 } 1061 1062 da7219->mclk_rate = freq; 1063 1064 return 0; 1065 } 1066 1067 static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 1068 int source, unsigned int fref, unsigned int fout) 1069 { 1070 struct snd_soc_codec *codec = codec_dai->codec; 1071 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1072 1073 u8 pll_ctrl, indiv_bits, indiv; 1074 u8 pll_frac_top, pll_frac_bot, pll_integer; 1075 u32 freq_ref; 1076 u64 frac_div; 1077 1078 /* Verify 2MHz - 54MHz MCLK provided, and set input divider */ 1079 if (da7219->mclk_rate < 2000000) { 1080 dev_err(codec->dev, "PLL input clock %d below valid range\n", 1081 da7219->mclk_rate); 1082 return -EINVAL; 1083 } else if (da7219->mclk_rate <= 4500000) { 1084 indiv_bits = DA7219_PLL_INDIV_2_TO_4_5_MHZ; 1085 indiv = DA7219_PLL_INDIV_2_TO_4_5_MHZ_VAL; 1086 } else if (da7219->mclk_rate <= 9000000) { 1087 indiv_bits = DA7219_PLL_INDIV_4_5_TO_9_MHZ; 1088 indiv = DA7219_PLL_INDIV_4_5_TO_9_MHZ_VAL; 1089 } else if (da7219->mclk_rate <= 18000000) { 1090 indiv_bits = DA7219_PLL_INDIV_9_TO_18_MHZ; 1091 indiv = DA7219_PLL_INDIV_9_TO_18_MHZ_VAL; 1092 } else if (da7219->mclk_rate <= 36000000) { 1093 indiv_bits = DA7219_PLL_INDIV_18_TO_36_MHZ; 1094 indiv = DA7219_PLL_INDIV_18_TO_36_MHZ_VAL; 1095 } else if (da7219->mclk_rate <= 54000000) { 1096 indiv_bits = DA7219_PLL_INDIV_36_TO_54_MHZ; 1097 indiv = DA7219_PLL_INDIV_36_TO_54_MHZ_VAL; 1098 } else { 1099 dev_err(codec->dev, "PLL input clock %d above valid range\n", 1100 da7219->mclk_rate); 1101 return -EINVAL; 1102 } 1103 freq_ref = (da7219->mclk_rate / indiv); 1104 pll_ctrl = indiv_bits; 1105 1106 /* Configure PLL */ 1107 switch (source) { 1108 case DA7219_SYSCLK_MCLK: 1109 pll_ctrl |= DA7219_PLL_MODE_BYPASS; 1110 snd_soc_update_bits(codec, DA7219_PLL_CTRL, 1111 DA7219_PLL_INDIV_MASK | 1112 DA7219_PLL_MODE_MASK, pll_ctrl); 1113 return 0; 1114 case DA7219_SYSCLK_PLL: 1115 pll_ctrl |= DA7219_PLL_MODE_NORMAL; 1116 break; 1117 case DA7219_SYSCLK_PLL_SRM: 1118 pll_ctrl |= DA7219_PLL_MODE_SRM; 1119 break; 1120 default: 1121 dev_err(codec->dev, "Invalid PLL config\n"); 1122 return -EINVAL; 1123 } 1124 1125 /* Calculate dividers for PLL */ 1126 pll_integer = fout / freq_ref; 1127 frac_div = (u64)(fout % freq_ref) * 8192ULL; 1128 do_div(frac_div, freq_ref); 1129 pll_frac_top = (frac_div >> DA7219_BYTE_SHIFT) & DA7219_BYTE_MASK; 1130 pll_frac_bot = (frac_div) & DA7219_BYTE_MASK; 1131 1132 /* Write PLL config & dividers */ 1133 snd_soc_write(codec, DA7219_PLL_FRAC_TOP, pll_frac_top); 1134 snd_soc_write(codec, DA7219_PLL_FRAC_BOT, pll_frac_bot); 1135 snd_soc_write(codec, DA7219_PLL_INTEGER, pll_integer); 1136 snd_soc_update_bits(codec, DA7219_PLL_CTRL, 1137 DA7219_PLL_INDIV_MASK | DA7219_PLL_MODE_MASK, 1138 pll_ctrl); 1139 1140 return 0; 1141 } 1142 1143 static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 1144 { 1145 struct snd_soc_codec *codec = codec_dai->codec; 1146 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1147 u8 dai_clk_mode = 0, dai_ctrl = 0; 1148 1149 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1150 case SND_SOC_DAIFMT_CBM_CFM: 1151 da7219->master = true; 1152 break; 1153 case SND_SOC_DAIFMT_CBS_CFS: 1154 da7219->master = false; 1155 break; 1156 default: 1157 return -EINVAL; 1158 } 1159 1160 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1161 case SND_SOC_DAIFMT_I2S: 1162 case SND_SOC_DAIFMT_LEFT_J: 1163 case SND_SOC_DAIFMT_RIGHT_J: 1164 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1165 case SND_SOC_DAIFMT_NB_NF: 1166 break; 1167 case SND_SOC_DAIFMT_NB_IF: 1168 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV; 1169 break; 1170 case SND_SOC_DAIFMT_IB_NF: 1171 dai_clk_mode |= DA7219_DAI_CLK_POL_INV; 1172 break; 1173 case SND_SOC_DAIFMT_IB_IF: 1174 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV | 1175 DA7219_DAI_CLK_POL_INV; 1176 break; 1177 default: 1178 return -EINVAL; 1179 } 1180 break; 1181 case SND_SOC_DAIFMT_DSP_B: 1182 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1183 case SND_SOC_DAIFMT_NB_NF: 1184 dai_clk_mode |= DA7219_DAI_CLK_POL_INV; 1185 break; 1186 case SND_SOC_DAIFMT_NB_IF: 1187 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV | 1188 DA7219_DAI_CLK_POL_INV; 1189 break; 1190 case SND_SOC_DAIFMT_IB_NF: 1191 break; 1192 case SND_SOC_DAIFMT_IB_IF: 1193 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV; 1194 break; 1195 default: 1196 return -EINVAL; 1197 } 1198 break; 1199 default: 1200 return -EINVAL; 1201 } 1202 1203 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1204 case SND_SOC_DAIFMT_I2S: 1205 dai_ctrl |= DA7219_DAI_FORMAT_I2S; 1206 break; 1207 case SND_SOC_DAIFMT_LEFT_J: 1208 dai_ctrl |= DA7219_DAI_FORMAT_LEFT_J; 1209 break; 1210 case SND_SOC_DAIFMT_RIGHT_J: 1211 dai_ctrl |= DA7219_DAI_FORMAT_RIGHT_J; 1212 break; 1213 case SND_SOC_DAIFMT_DSP_B: 1214 dai_ctrl |= DA7219_DAI_FORMAT_DSP; 1215 break; 1216 default: 1217 return -EINVAL; 1218 } 1219 1220 /* By default 64 BCLKs per WCLK is supported */ 1221 dai_clk_mode |= DA7219_DAI_BCLKS_PER_WCLK_64; 1222 1223 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE, 1224 DA7219_DAI_BCLKS_PER_WCLK_MASK | 1225 DA7219_DAI_CLK_POL_MASK | DA7219_DAI_WCLK_POL_MASK, 1226 dai_clk_mode); 1227 snd_soc_update_bits(codec, DA7219_DAI_CTRL, DA7219_DAI_FORMAT_MASK, 1228 dai_ctrl); 1229 1230 return 0; 1231 } 1232 1233 static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai, 1234 unsigned int tx_mask, unsigned int rx_mask, 1235 int slots, int slot_width) 1236 { 1237 struct snd_soc_codec *codec = dai->codec; 1238 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1239 u8 dai_bclks_per_wclk; 1240 u16 offset; 1241 u32 frame_size; 1242 1243 /* No channels enabled so disable TDM, revert to 64-bit frames */ 1244 if (!tx_mask) { 1245 snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL, 1246 DA7219_DAI_TDM_CH_EN_MASK | 1247 DA7219_DAI_TDM_MODE_EN_MASK, 0); 1248 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE, 1249 DA7219_DAI_BCLKS_PER_WCLK_MASK, 1250 DA7219_DAI_BCLKS_PER_WCLK_64); 1251 return 0; 1252 } 1253 1254 /* Check we have valid slots */ 1255 if (fls(tx_mask) > DA7219_DAI_TDM_MAX_SLOTS) { 1256 dev_err(codec->dev, "Invalid number of slots, max = %d\n", 1257 DA7219_DAI_TDM_MAX_SLOTS); 1258 return -EINVAL; 1259 } 1260 1261 /* Check we have a valid offset given */ 1262 if (rx_mask > DA7219_DAI_OFFSET_MAX) { 1263 dev_err(codec->dev, "Invalid slot offset, max = %d\n", 1264 DA7219_DAI_OFFSET_MAX); 1265 return -EINVAL; 1266 } 1267 1268 /* Calculate & validate frame size based on slot info provided. */ 1269 frame_size = slots * slot_width; 1270 switch (frame_size) { 1271 case 32: 1272 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_32; 1273 break; 1274 case 64: 1275 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_64; 1276 break; 1277 case 128: 1278 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_128; 1279 break; 1280 case 256: 1281 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256; 1282 break; 1283 default: 1284 dev_err(codec->dev, "Invalid frame size %d\n", frame_size); 1285 return -EINVAL; 1286 } 1287 1288 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE, 1289 DA7219_DAI_BCLKS_PER_WCLK_MASK, 1290 dai_bclks_per_wclk); 1291 1292 offset = cpu_to_le16(rx_mask); 1293 regmap_bulk_write(da7219->regmap, DA7219_DAI_OFFSET_LOWER, 1294 &offset, sizeof(offset)); 1295 1296 snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL, 1297 DA7219_DAI_TDM_CH_EN_MASK | 1298 DA7219_DAI_TDM_MODE_EN_MASK, 1299 (tx_mask << DA7219_DAI_TDM_CH_EN_SHIFT) | 1300 DA7219_DAI_TDM_MODE_EN_MASK); 1301 1302 return 0; 1303 } 1304 1305 static int da7219_hw_params(struct snd_pcm_substream *substream, 1306 struct snd_pcm_hw_params *params, 1307 struct snd_soc_dai *dai) 1308 { 1309 struct snd_soc_codec *codec = dai->codec; 1310 u8 dai_ctrl = 0, fs; 1311 unsigned int channels; 1312 1313 switch (params_width(params)) { 1314 case 16: 1315 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S16_LE; 1316 break; 1317 case 20: 1318 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S20_LE; 1319 break; 1320 case 24: 1321 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S24_LE; 1322 break; 1323 case 32: 1324 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S32_LE; 1325 break; 1326 default: 1327 return -EINVAL; 1328 } 1329 1330 channels = params_channels(params); 1331 if ((channels < 1) || (channels > DA7219_DAI_CH_NUM_MAX)) { 1332 dev_err(codec->dev, 1333 "Invalid number of channels, only 1 to %d supported\n", 1334 DA7219_DAI_CH_NUM_MAX); 1335 return -EINVAL; 1336 } 1337 dai_ctrl |= channels << DA7219_DAI_CH_NUM_SHIFT; 1338 1339 switch (params_rate(params)) { 1340 case 8000: 1341 fs = DA7219_SR_8000; 1342 break; 1343 case 11025: 1344 fs = DA7219_SR_11025; 1345 break; 1346 case 12000: 1347 fs = DA7219_SR_12000; 1348 break; 1349 case 16000: 1350 fs = DA7219_SR_16000; 1351 break; 1352 case 22050: 1353 fs = DA7219_SR_22050; 1354 break; 1355 case 24000: 1356 fs = DA7219_SR_24000; 1357 break; 1358 case 32000: 1359 fs = DA7219_SR_32000; 1360 break; 1361 case 44100: 1362 fs = DA7219_SR_44100; 1363 break; 1364 case 48000: 1365 fs = DA7219_SR_48000; 1366 break; 1367 case 88200: 1368 fs = DA7219_SR_88200; 1369 break; 1370 case 96000: 1371 fs = DA7219_SR_96000; 1372 break; 1373 default: 1374 return -EINVAL; 1375 } 1376 1377 snd_soc_update_bits(codec, DA7219_DAI_CTRL, 1378 DA7219_DAI_WORD_LENGTH_MASK | 1379 DA7219_DAI_CH_NUM_MASK, 1380 dai_ctrl); 1381 snd_soc_write(codec, DA7219_SR, fs); 1382 1383 return 0; 1384 } 1385 1386 static const struct snd_soc_dai_ops da7219_dai_ops = { 1387 .hw_params = da7219_hw_params, 1388 .set_sysclk = da7219_set_dai_sysclk, 1389 .set_pll = da7219_set_dai_pll, 1390 .set_fmt = da7219_set_dai_fmt, 1391 .set_tdm_slot = da7219_set_dai_tdm_slot, 1392 }; 1393 1394 #define DA7219_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 1395 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 1396 1397 static struct snd_soc_dai_driver da7219_dai = { 1398 .name = "da7219-hifi", 1399 .playback = { 1400 .stream_name = "Playback", 1401 .channels_min = 1, 1402 .channels_max = DA7219_DAI_CH_NUM_MAX, 1403 .rates = SNDRV_PCM_RATE_8000_96000, 1404 .formats = DA7219_FORMATS, 1405 }, 1406 .capture = { 1407 .stream_name = "Capture", 1408 .channels_min = 1, 1409 .channels_max = DA7219_DAI_CH_NUM_MAX, 1410 .rates = SNDRV_PCM_RATE_8000_96000, 1411 .formats = DA7219_FORMATS, 1412 }, 1413 .ops = &da7219_dai_ops, 1414 .symmetric_rates = 1, 1415 .symmetric_channels = 1, 1416 .symmetric_samplebits = 1, 1417 }; 1418 1419 1420 /* 1421 * DT 1422 */ 1423 1424 static const struct of_device_id da7219_of_match[] = { 1425 { .compatible = "dlg,da7219", }, 1426 { } 1427 }; 1428 MODULE_DEVICE_TABLE(of, da7219_of_match); 1429 1430 static const struct acpi_device_id da7219_acpi_match[] = { 1431 { .id = "DLGS7219", }, 1432 { } 1433 }; 1434 MODULE_DEVICE_TABLE(acpi, da7219_acpi_match); 1435 1436 static enum da7219_micbias_voltage 1437 da7219_of_micbias_lvl(struct snd_soc_codec *codec, u32 val) 1438 { 1439 switch (val) { 1440 case 1600: 1441 return DA7219_MICBIAS_1_6V; 1442 case 1800: 1443 return DA7219_MICBIAS_1_8V; 1444 case 2000: 1445 return DA7219_MICBIAS_2_0V; 1446 case 2200: 1447 return DA7219_MICBIAS_2_2V; 1448 case 2400: 1449 return DA7219_MICBIAS_2_4V; 1450 case 2600: 1451 return DA7219_MICBIAS_2_6V; 1452 default: 1453 dev_warn(codec->dev, "Invalid micbias level"); 1454 return DA7219_MICBIAS_2_2V; 1455 } 1456 } 1457 1458 static enum da7219_mic_amp_in_sel 1459 da7219_of_mic_amp_in_sel(struct snd_soc_codec *codec, const char *str) 1460 { 1461 if (!strcmp(str, "diff")) { 1462 return DA7219_MIC_AMP_IN_SEL_DIFF; 1463 } else if (!strcmp(str, "se_p")) { 1464 return DA7219_MIC_AMP_IN_SEL_SE_P; 1465 } else if (!strcmp(str, "se_n")) { 1466 return DA7219_MIC_AMP_IN_SEL_SE_N; 1467 } else { 1468 dev_warn(codec->dev, "Invalid mic input type selection"); 1469 return DA7219_MIC_AMP_IN_SEL_DIFF; 1470 } 1471 } 1472 1473 static struct da7219_pdata *da7219_of_to_pdata(struct snd_soc_codec *codec) 1474 { 1475 struct device_node *np = codec->dev->of_node; 1476 struct da7219_pdata *pdata; 1477 const char *of_str; 1478 u32 of_val32; 1479 1480 pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL); 1481 if (!pdata) 1482 return NULL; 1483 1484 if (of_property_read_u32(np, "dlg,micbias-lvl", &of_val32) >= 0) 1485 pdata->micbias_lvl = da7219_of_micbias_lvl(codec, of_val32); 1486 else 1487 pdata->micbias_lvl = DA7219_MICBIAS_2_2V; 1488 1489 if (!of_property_read_string(np, "dlg,mic-amp-in-sel", &of_str)) 1490 pdata->mic_amp_in_sel = da7219_of_mic_amp_in_sel(codec, of_str); 1491 else 1492 pdata->mic_amp_in_sel = DA7219_MIC_AMP_IN_SEL_DIFF; 1493 1494 return pdata; 1495 } 1496 1497 1498 /* 1499 * Codec driver functions 1500 */ 1501 1502 static int da7219_set_bias_level(struct snd_soc_codec *codec, 1503 enum snd_soc_bias_level level) 1504 { 1505 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1506 int ret; 1507 1508 switch (level) { 1509 case SND_SOC_BIAS_ON: 1510 case SND_SOC_BIAS_PREPARE: 1511 break; 1512 case SND_SOC_BIAS_STANDBY: 1513 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { 1514 /* MCLK */ 1515 if (da7219->mclk) { 1516 ret = clk_prepare_enable(da7219->mclk); 1517 if (ret) { 1518 dev_err(codec->dev, 1519 "Failed to enable mclk\n"); 1520 return ret; 1521 } 1522 } 1523 1524 /* Master bias */ 1525 snd_soc_update_bits(codec, DA7219_REFERENCES, 1526 DA7219_BIAS_EN_MASK, 1527 DA7219_BIAS_EN_MASK); 1528 } 1529 break; 1530 case SND_SOC_BIAS_OFF: 1531 /* Only disable master bias if jack detection not active */ 1532 if (!da7219->aad->jack) 1533 snd_soc_update_bits(codec, DA7219_REFERENCES, 1534 DA7219_BIAS_EN_MASK, 0); 1535 1536 /* MCLK */ 1537 if (da7219->mclk) 1538 clk_disable_unprepare(da7219->mclk); 1539 break; 1540 } 1541 1542 return 0; 1543 } 1544 1545 static const char *da7219_supply_names[DA7219_NUM_SUPPLIES] = { 1546 [DA7219_SUPPLY_VDD] = "VDD", 1547 [DA7219_SUPPLY_VDDMIC] = "VDDMIC", 1548 [DA7219_SUPPLY_VDDIO] = "VDDIO", 1549 }; 1550 1551 static int da7219_handle_supplies(struct snd_soc_codec *codec) 1552 { 1553 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1554 struct regulator *vddio; 1555 u8 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V; 1556 int i, ret; 1557 1558 /* Get required supplies */ 1559 for (i = 0; i < DA7219_NUM_SUPPLIES; ++i) 1560 da7219->supplies[i].supply = da7219_supply_names[i]; 1561 1562 ret = devm_regulator_bulk_get(codec->dev, DA7219_NUM_SUPPLIES, 1563 da7219->supplies); 1564 if (ret) { 1565 dev_err(codec->dev, "Failed to get supplies"); 1566 return ret; 1567 } 1568 1569 /* Determine VDDIO voltage provided */ 1570 vddio = da7219->supplies[DA7219_SUPPLY_VDDIO].consumer; 1571 ret = regulator_get_voltage(vddio); 1572 if (ret < 1200000) 1573 dev_warn(codec->dev, "Invalid VDDIO voltage\n"); 1574 else if (ret < 2800000) 1575 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V; 1576 1577 /* Enable main supplies */ 1578 ret = regulator_bulk_enable(DA7219_NUM_SUPPLIES, da7219->supplies); 1579 if (ret) { 1580 dev_err(codec->dev, "Failed to enable supplies"); 1581 return ret; 1582 } 1583 1584 /* Ensure device in active mode */ 1585 snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, DA7219_SYSTEM_ACTIVE_MASK); 1586 1587 /* Update IO voltage level range */ 1588 snd_soc_write(codec, DA7219_IO_CTRL, io_voltage_lvl); 1589 1590 return 0; 1591 } 1592 1593 static void da7219_handle_pdata(struct snd_soc_codec *codec) 1594 { 1595 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1596 struct da7219_pdata *pdata = da7219->pdata; 1597 1598 if (pdata) { 1599 u8 micbias_lvl = 0; 1600 1601 /* Mic Bias voltages */ 1602 switch (pdata->micbias_lvl) { 1603 case DA7219_MICBIAS_1_6V: 1604 case DA7219_MICBIAS_1_8V: 1605 case DA7219_MICBIAS_2_0V: 1606 case DA7219_MICBIAS_2_2V: 1607 case DA7219_MICBIAS_2_4V: 1608 case DA7219_MICBIAS_2_6V: 1609 micbias_lvl |= (pdata->micbias_lvl << 1610 DA7219_MICBIAS1_LEVEL_SHIFT); 1611 break; 1612 } 1613 1614 snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_lvl); 1615 1616 /* Mic */ 1617 switch (pdata->mic_amp_in_sel) { 1618 case DA7219_MIC_AMP_IN_SEL_DIFF: 1619 case DA7219_MIC_AMP_IN_SEL_SE_P: 1620 case DA7219_MIC_AMP_IN_SEL_SE_N: 1621 snd_soc_write(codec, DA7219_MIC_1_SELECT, 1622 pdata->mic_amp_in_sel); 1623 break; 1624 } 1625 } 1626 } 1627 1628 static struct reg_sequence da7219_rev_aa_patch[] = { 1629 { DA7219_REFERENCES, 0x08 }, 1630 }; 1631 1632 static int da7219_probe(struct snd_soc_codec *codec) 1633 { 1634 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1635 unsigned int rev; 1636 int ret; 1637 1638 mutex_init(&da7219->lock); 1639 1640 /* Regulator configuration */ 1641 ret = da7219_handle_supplies(codec); 1642 if (ret) 1643 return ret; 1644 1645 ret = regmap_read(da7219->regmap, DA7219_CHIP_REVISION, &rev); 1646 if (ret) { 1647 dev_err(codec->dev, "Failed to read chip revision: %d\n", ret); 1648 goto err_disable_reg; 1649 } 1650 1651 switch (rev & DA7219_CHIP_MINOR_MASK) { 1652 case 0: 1653 ret = regmap_register_patch(da7219->regmap, da7219_rev_aa_patch, 1654 ARRAY_SIZE(da7219_rev_aa_patch)); 1655 if (ret) { 1656 dev_err(codec->dev, "Failed to register AA patch: %d\n", 1657 ret); 1658 goto err_disable_reg; 1659 } 1660 break; 1661 default: 1662 break; 1663 } 1664 1665 /* Handle DT/Platform data */ 1666 if (codec->dev->of_node) 1667 da7219->pdata = da7219_of_to_pdata(codec); 1668 else 1669 da7219->pdata = dev_get_platdata(codec->dev); 1670 1671 da7219_handle_pdata(codec); 1672 1673 /* Check if MCLK provided */ 1674 da7219->mclk = devm_clk_get(codec->dev, "mclk"); 1675 if (IS_ERR(da7219->mclk)) { 1676 if (PTR_ERR(da7219->mclk) != -ENOENT) { 1677 ret = PTR_ERR(da7219->mclk); 1678 goto err_disable_reg; 1679 } else { 1680 da7219->mclk = NULL; 1681 } 1682 } 1683 1684 /* Default PC counter to free-running */ 1685 snd_soc_update_bits(codec, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK, 1686 DA7219_PC_FREERUN_MASK); 1687 1688 /* Default gain ramping */ 1689 snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL, 1690 DA7219_MIXIN_L_AMP_RAMP_EN_MASK, 1691 DA7219_MIXIN_L_AMP_RAMP_EN_MASK); 1692 snd_soc_update_bits(codec, DA7219_ADC_L_CTRL, DA7219_ADC_L_RAMP_EN_MASK, 1693 DA7219_ADC_L_RAMP_EN_MASK); 1694 snd_soc_update_bits(codec, DA7219_DAC_L_CTRL, DA7219_DAC_L_RAMP_EN_MASK, 1695 DA7219_DAC_L_RAMP_EN_MASK); 1696 snd_soc_update_bits(codec, DA7219_DAC_R_CTRL, DA7219_DAC_R_RAMP_EN_MASK, 1697 DA7219_DAC_R_RAMP_EN_MASK); 1698 snd_soc_update_bits(codec, DA7219_HP_L_CTRL, 1699 DA7219_HP_L_AMP_RAMP_EN_MASK, 1700 DA7219_HP_L_AMP_RAMP_EN_MASK); 1701 snd_soc_update_bits(codec, DA7219_HP_R_CTRL, 1702 DA7219_HP_R_AMP_RAMP_EN_MASK, 1703 DA7219_HP_R_AMP_RAMP_EN_MASK); 1704 1705 /* Default infinite tone gen, start/stop by Kcontrol */ 1706 snd_soc_write(codec, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK); 1707 1708 /* Initialise AAD block */ 1709 ret = da7219_aad_init(codec); 1710 if (ret) 1711 goto err_disable_reg; 1712 1713 return 0; 1714 1715 err_disable_reg: 1716 regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies); 1717 1718 return ret; 1719 } 1720 1721 static int da7219_remove(struct snd_soc_codec *codec) 1722 { 1723 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1724 1725 da7219_aad_exit(codec); 1726 1727 /* Supplies */ 1728 return regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies); 1729 } 1730 1731 #ifdef CONFIG_PM 1732 static int da7219_suspend(struct snd_soc_codec *codec) 1733 { 1734 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1735 1736 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); 1737 1738 /* Put device into standby mode if jack detection disabled */ 1739 if (!da7219->aad->jack) 1740 snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, 0); 1741 1742 return 0; 1743 } 1744 1745 static int da7219_resume(struct snd_soc_codec *codec) 1746 { 1747 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1748 1749 /* Put device into active mode if previously pushed to standby */ 1750 if (!da7219->aad->jack) 1751 snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, 1752 DA7219_SYSTEM_ACTIVE_MASK); 1753 1754 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY); 1755 1756 return 0; 1757 } 1758 #else 1759 #define da7219_suspend NULL 1760 #define da7219_resume NULL 1761 #endif 1762 1763 static struct snd_soc_codec_driver soc_codec_dev_da7219 = { 1764 .probe = da7219_probe, 1765 .remove = da7219_remove, 1766 .suspend = da7219_suspend, 1767 .resume = da7219_resume, 1768 .set_bias_level = da7219_set_bias_level, 1769 1770 .controls = da7219_snd_controls, 1771 .num_controls = ARRAY_SIZE(da7219_snd_controls), 1772 1773 .dapm_widgets = da7219_dapm_widgets, 1774 .num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets), 1775 .dapm_routes = da7219_audio_map, 1776 .num_dapm_routes = ARRAY_SIZE(da7219_audio_map), 1777 }; 1778 1779 1780 /* 1781 * Regmap configs 1782 */ 1783 1784 static struct reg_default da7219_reg_defaults[] = { 1785 { DA7219_MIC_1_SELECT, 0x00 }, 1786 { DA7219_CIF_TIMEOUT_CTRL, 0x01 }, 1787 { DA7219_SR_24_48, 0x00 }, 1788 { DA7219_SR, 0x0A }, 1789 { DA7219_CIF_I2C_ADDR_CFG, 0x02 }, 1790 { DA7219_PLL_CTRL, 0x10 }, 1791 { DA7219_PLL_FRAC_TOP, 0x00 }, 1792 { DA7219_PLL_FRAC_BOT, 0x00 }, 1793 { DA7219_PLL_INTEGER, 0x20 }, 1794 { DA7219_DIG_ROUTING_DAI, 0x10 }, 1795 { DA7219_DAI_CLK_MODE, 0x01 }, 1796 { DA7219_DAI_CTRL, 0x28 }, 1797 { DA7219_DAI_TDM_CTRL, 0x40 }, 1798 { DA7219_DIG_ROUTING_DAC, 0x32 }, 1799 { DA7219_DAI_OFFSET_LOWER, 0x00 }, 1800 { DA7219_DAI_OFFSET_UPPER, 0x00 }, 1801 { DA7219_REFERENCES, 0x08 }, 1802 { DA7219_MIXIN_L_SELECT, 0x00 }, 1803 { DA7219_MIXIN_L_GAIN, 0x03 }, 1804 { DA7219_ADC_L_GAIN, 0x6F }, 1805 { DA7219_ADC_FILTERS1, 0x80 }, 1806 { DA7219_MIC_1_GAIN, 0x01 }, 1807 { DA7219_SIDETONE_CTRL, 0x40 }, 1808 { DA7219_SIDETONE_GAIN, 0x0E }, 1809 { DA7219_DROUTING_ST_OUTFILT_1L, 0x01 }, 1810 { DA7219_DROUTING_ST_OUTFILT_1R, 0x02 }, 1811 { DA7219_DAC_FILTERS5, 0x00 }, 1812 { DA7219_DAC_FILTERS2, 0x88 }, 1813 { DA7219_DAC_FILTERS3, 0x88 }, 1814 { DA7219_DAC_FILTERS4, 0x08 }, 1815 { DA7219_DAC_FILTERS1, 0x80 }, 1816 { DA7219_DAC_L_GAIN, 0x6F }, 1817 { DA7219_DAC_R_GAIN, 0x6F }, 1818 { DA7219_CP_CTRL, 0x20 }, 1819 { DA7219_HP_L_GAIN, 0x39 }, 1820 { DA7219_HP_R_GAIN, 0x39 }, 1821 { DA7219_MIXOUT_L_SELECT, 0x00 }, 1822 { DA7219_MIXOUT_R_SELECT, 0x00 }, 1823 { DA7219_MICBIAS_CTRL, 0x03 }, 1824 { DA7219_MIC_1_CTRL, 0x40 }, 1825 { DA7219_MIXIN_L_CTRL, 0x40 }, 1826 { DA7219_ADC_L_CTRL, 0x40 }, 1827 { DA7219_DAC_L_CTRL, 0x40 }, 1828 { DA7219_DAC_R_CTRL, 0x40 }, 1829 { DA7219_HP_L_CTRL, 0x40 }, 1830 { DA7219_HP_R_CTRL, 0x40 }, 1831 { DA7219_MIXOUT_L_CTRL, 0x10 }, 1832 { DA7219_MIXOUT_R_CTRL, 0x10 }, 1833 { DA7219_CHIP_ID1, 0x23 }, 1834 { DA7219_CHIP_ID2, 0x93 }, 1835 { DA7219_IO_CTRL, 0x00 }, 1836 { DA7219_GAIN_RAMP_CTRL, 0x00 }, 1837 { DA7219_PC_COUNT, 0x02 }, 1838 { DA7219_CP_VOL_THRESHOLD1, 0x0E }, 1839 { DA7219_DIG_CTRL, 0x00 }, 1840 { DA7219_ALC_CTRL2, 0x00 }, 1841 { DA7219_ALC_CTRL3, 0x00 }, 1842 { DA7219_ALC_NOISE, 0x3F }, 1843 { DA7219_ALC_TARGET_MIN, 0x3F }, 1844 { DA7219_ALC_TARGET_MAX, 0x00 }, 1845 { DA7219_ALC_GAIN_LIMITS, 0xFF }, 1846 { DA7219_ALC_ANA_GAIN_LIMITS, 0x71 }, 1847 { DA7219_ALC_ANTICLIP_CTRL, 0x00 }, 1848 { DA7219_ALC_ANTICLIP_LEVEL, 0x00 }, 1849 { DA7219_DAC_NG_SETUP_TIME, 0x00 }, 1850 { DA7219_DAC_NG_OFF_THRESH, 0x00 }, 1851 { DA7219_DAC_NG_ON_THRESH, 0x00 }, 1852 { DA7219_DAC_NG_CTRL, 0x00 }, 1853 { DA7219_TONE_GEN_CFG1, 0x00 }, 1854 { DA7219_TONE_GEN_CFG2, 0x00 }, 1855 { DA7219_TONE_GEN_CYCLES, 0x00 }, 1856 { DA7219_TONE_GEN_FREQ1_L, 0x55 }, 1857 { DA7219_TONE_GEN_FREQ1_U, 0x15 }, 1858 { DA7219_TONE_GEN_FREQ2_L, 0x00 }, 1859 { DA7219_TONE_GEN_FREQ2_U, 0x40 }, 1860 { DA7219_TONE_GEN_ON_PER, 0x02 }, 1861 { DA7219_TONE_GEN_OFF_PER, 0x01 }, 1862 { DA7219_ACCDET_IRQ_MASK_A, 0x00 }, 1863 { DA7219_ACCDET_IRQ_MASK_B, 0x00 }, 1864 { DA7219_ACCDET_CONFIG_1, 0xD6 }, 1865 { DA7219_ACCDET_CONFIG_2, 0x34 }, 1866 { DA7219_ACCDET_CONFIG_3, 0x0A }, 1867 { DA7219_ACCDET_CONFIG_4, 0x16 }, 1868 { DA7219_ACCDET_CONFIG_5, 0x21 }, 1869 { DA7219_ACCDET_CONFIG_6, 0x3E }, 1870 { DA7219_ACCDET_CONFIG_7, 0x01 }, 1871 { DA7219_SYSTEM_ACTIVE, 0x00 }, 1872 }; 1873 1874 static bool da7219_volatile_register(struct device *dev, unsigned int reg) 1875 { 1876 switch (reg) { 1877 case DA7219_MIC_1_GAIN_STATUS: 1878 case DA7219_MIXIN_L_GAIN_STATUS: 1879 case DA7219_ADC_L_GAIN_STATUS: 1880 case DA7219_DAC_L_GAIN_STATUS: 1881 case DA7219_DAC_R_GAIN_STATUS: 1882 case DA7219_HP_L_GAIN_STATUS: 1883 case DA7219_HP_R_GAIN_STATUS: 1884 case DA7219_CIF_CTRL: 1885 case DA7219_PLL_SRM_STS: 1886 case DA7219_ALC_CTRL1: 1887 case DA7219_SYSTEM_MODES_INPUT: 1888 case DA7219_SYSTEM_MODES_OUTPUT: 1889 case DA7219_ALC_OFFSET_AUTO_M_L: 1890 case DA7219_ALC_OFFSET_AUTO_U_L: 1891 case DA7219_TONE_GEN_CFG1: 1892 case DA7219_ACCDET_STATUS_A: 1893 case DA7219_ACCDET_STATUS_B: 1894 case DA7219_ACCDET_IRQ_EVENT_A: 1895 case DA7219_ACCDET_IRQ_EVENT_B: 1896 case DA7219_ACCDET_CONFIG_8: 1897 case DA7219_SYSTEM_STATUS: 1898 return 1; 1899 default: 1900 return 0; 1901 } 1902 } 1903 1904 static const struct regmap_config da7219_regmap_config = { 1905 .reg_bits = 8, 1906 .val_bits = 8, 1907 1908 .max_register = DA7219_SYSTEM_ACTIVE, 1909 .reg_defaults = da7219_reg_defaults, 1910 .num_reg_defaults = ARRAY_SIZE(da7219_reg_defaults), 1911 .volatile_reg = da7219_volatile_register, 1912 .cache_type = REGCACHE_RBTREE, 1913 }; 1914 1915 1916 /* 1917 * I2C layer 1918 */ 1919 1920 static int da7219_i2c_probe(struct i2c_client *i2c, 1921 const struct i2c_device_id *id) 1922 { 1923 struct da7219_priv *da7219; 1924 int ret; 1925 1926 da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv), 1927 GFP_KERNEL); 1928 if (!da7219) 1929 return -ENOMEM; 1930 1931 i2c_set_clientdata(i2c, da7219); 1932 1933 da7219->regmap = devm_regmap_init_i2c(i2c, &da7219_regmap_config); 1934 if (IS_ERR(da7219->regmap)) { 1935 ret = PTR_ERR(da7219->regmap); 1936 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); 1937 return ret; 1938 } 1939 1940 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219, 1941 &da7219_dai, 1); 1942 if (ret < 0) { 1943 dev_err(&i2c->dev, "Failed to register da7219 codec: %d\n", 1944 ret); 1945 } 1946 return ret; 1947 } 1948 1949 static int da7219_i2c_remove(struct i2c_client *client) 1950 { 1951 snd_soc_unregister_codec(&client->dev); 1952 return 0; 1953 } 1954 1955 static const struct i2c_device_id da7219_i2c_id[] = { 1956 { "da7219", }, 1957 { } 1958 }; 1959 MODULE_DEVICE_TABLE(i2c, da7219_i2c_id); 1960 1961 static struct i2c_driver da7219_i2c_driver = { 1962 .driver = { 1963 .name = "da7219", 1964 .of_match_table = of_match_ptr(da7219_of_match), 1965 .acpi_match_table = ACPI_PTR(da7219_acpi_match), 1966 }, 1967 .probe = da7219_i2c_probe, 1968 .remove = da7219_i2c_remove, 1969 .id_table = da7219_i2c_id, 1970 }; 1971 1972 module_i2c_driver(da7219_i2c_driver); 1973 1974 MODULE_DESCRIPTION("ASoC DA7219 Codec Driver"); 1975 MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>"); 1976 MODULE_LICENSE("GPL"); 1977