| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961 codec |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2011-2013 Analog Devices Inc. |
|---|
| 5 | 6 | * Author: Lars-Peter Clausen <lars@metafoo.de> |
|---|
| 6 | | - * |
|---|
| 7 | | - * Licensed under the GPL-2 or later. |
|---|
| 8 | 7 | */ |
|---|
| 9 | 8 | |
|---|
| 10 | 9 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 29 | 28 | #define ADAU1761_REC_MIXER_RIGHT1 0x400d |
|---|
| 30 | 29 | #define ADAU1761_LEFT_DIFF_INPUT_VOL 0x400e |
|---|
| 31 | 30 | #define ADAU1761_RIGHT_DIFF_INPUT_VOL 0x400f |
|---|
| 31 | +#define ADAU1761_ALC_CTRL0 0x4011 |
|---|
| 32 | +#define ADAU1761_ALC_CTRL1 0x4012 |
|---|
| 33 | +#define ADAU1761_ALC_CTRL2 0x4013 |
|---|
| 34 | +#define ADAU1761_ALC_CTRL3 0x4014 |
|---|
| 32 | 35 | #define ADAU1761_PLAY_LR_MIXER_LEFT 0x4020 |
|---|
| 33 | 36 | #define ADAU1761_PLAY_MIXER_LEFT0 0x401c |
|---|
| 34 | 37 | #define ADAU1761_PLAY_MIXER_LEFT1 0x401d |
|---|
| .. | .. |
|---|
| 72 | 75 | { ADAU1761_REC_MIXER_RIGHT0, 0x00 }, |
|---|
| 73 | 76 | { ADAU1761_REC_MIXER_RIGHT1, 0x00 }, |
|---|
| 74 | 77 | { ADAU1761_LEFT_DIFF_INPUT_VOL, 0x00 }, |
|---|
| 78 | + { ADAU1761_ALC_CTRL0, 0x00 }, |
|---|
| 79 | + { ADAU1761_ALC_CTRL1, 0x00 }, |
|---|
| 80 | + { ADAU1761_ALC_CTRL2, 0x00 }, |
|---|
| 81 | + { ADAU1761_ALC_CTRL3, 0x00 }, |
|---|
| 75 | 82 | { ADAU1761_RIGHT_DIFF_INPUT_VOL, 0x00 }, |
|---|
| 76 | 83 | { ADAU1761_PLAY_LR_MIXER_LEFT, 0x00 }, |
|---|
| 77 | 84 | { ADAU1761_PLAY_MIXER_LEFT0, 0x00 }, |
|---|
| .. | .. |
|---|
| 122 | 129 | static const DECLARE_TLV_DB_SCALE(adau1761_boost_tlv, -600, 600, 1); |
|---|
| 123 | 130 | static const DECLARE_TLV_DB_SCALE(adau1761_pga_boost_tlv, -2000, 2000, 1); |
|---|
| 124 | 131 | |
|---|
| 132 | +static const DECLARE_TLV_DB_SCALE(adau1761_alc_max_gain_tlv, -1200, 600, 0); |
|---|
| 133 | +static const DECLARE_TLV_DB_SCALE(adau1761_alc_target_tlv, -2850, 150, 0); |
|---|
| 134 | +static const DECLARE_TLV_DB_SCALE(adau1761_alc_ng_threshold_tlv, -7650, 150, 0); |
|---|
| 135 | + |
|---|
| 125 | 136 | static const unsigned int adau1761_bias_select_values[] = { |
|---|
| 126 | 137 | 0, 2, 3, |
|---|
| 127 | 138 | }; |
|---|
| .. | .. |
|---|
| 148 | 159 | ADAU17X1_REC_POWER_MGMT, 1, 0x3, adau1761_bias_select_text, |
|---|
| 149 | 160 | adau1761_bias_select_values); |
|---|
| 150 | 161 | |
|---|
| 162 | +static const unsigned int adau1761_pga_slew_time_values[] = { |
|---|
| 163 | + 3, 0, 1, 2, |
|---|
| 164 | +}; |
|---|
| 165 | + |
|---|
| 166 | +static const char * const adau1761_pga_slew_time_text[] = { |
|---|
| 167 | + "Off", |
|---|
| 168 | + "24 ms", |
|---|
| 169 | + "48 ms", |
|---|
| 170 | + "96 ms", |
|---|
| 171 | +}; |
|---|
| 172 | + |
|---|
| 173 | +static const char * const adau1761_alc_function_text[] = { |
|---|
| 174 | + "Off", |
|---|
| 175 | + "Right", |
|---|
| 176 | + "Left", |
|---|
| 177 | + "Stereo", |
|---|
| 178 | + "DSP control", |
|---|
| 179 | +}; |
|---|
| 180 | + |
|---|
| 181 | +static const char * const adau1761_alc_hold_time_text[] = { |
|---|
| 182 | + "2.67 ms", |
|---|
| 183 | + "5.34 ms", |
|---|
| 184 | + "10.68 ms", |
|---|
| 185 | + "21.36 ms", |
|---|
| 186 | + "42.72 ms", |
|---|
| 187 | + "85.44 ms", |
|---|
| 188 | + "170.88 ms", |
|---|
| 189 | + "341.76 ms", |
|---|
| 190 | + "683.52 ms", |
|---|
| 191 | + "1367 ms", |
|---|
| 192 | + "2734.1 ms", |
|---|
| 193 | + "5468.2 ms", |
|---|
| 194 | + "10936 ms", |
|---|
| 195 | + "21873 ms", |
|---|
| 196 | + "43745 ms", |
|---|
| 197 | + "87491 ms", |
|---|
| 198 | +}; |
|---|
| 199 | + |
|---|
| 200 | +static const char * const adau1761_alc_attack_time_text[] = { |
|---|
| 201 | + "6 ms", |
|---|
| 202 | + "12 ms", |
|---|
| 203 | + "24 ms", |
|---|
| 204 | + "48 ms", |
|---|
| 205 | + "96 ms", |
|---|
| 206 | + "192 ms", |
|---|
| 207 | + "384 ms", |
|---|
| 208 | + "768 ms", |
|---|
| 209 | + "1540 ms", |
|---|
| 210 | + "3070 ms", |
|---|
| 211 | + "6140 ms", |
|---|
| 212 | + "12290 ms", |
|---|
| 213 | + "24580 ms", |
|---|
| 214 | + "49150 ms", |
|---|
| 215 | + "98300 ms", |
|---|
| 216 | + "196610 ms", |
|---|
| 217 | +}; |
|---|
| 218 | + |
|---|
| 219 | +static const char * const adau1761_alc_decay_time_text[] = { |
|---|
| 220 | + "24 ms", |
|---|
| 221 | + "48 ms", |
|---|
| 222 | + "96 ms", |
|---|
| 223 | + "192 ms", |
|---|
| 224 | + "384 ms", |
|---|
| 225 | + "768 ms", |
|---|
| 226 | + "15400 ms", |
|---|
| 227 | + "30700 ms", |
|---|
| 228 | + "61400 ms", |
|---|
| 229 | + "12290 ms", |
|---|
| 230 | + "24580 ms", |
|---|
| 231 | + "49150 ms", |
|---|
| 232 | + "98300 ms", |
|---|
| 233 | + "196610 ms", |
|---|
| 234 | + "393220 ms", |
|---|
| 235 | + "786430 ms", |
|---|
| 236 | +}; |
|---|
| 237 | + |
|---|
| 238 | +static const char * const adau1761_alc_ng_type_text[] = { |
|---|
| 239 | + "Hold", |
|---|
| 240 | + "Mute", |
|---|
| 241 | + "Fade", |
|---|
| 242 | + "Fade + Mute", |
|---|
| 243 | +}; |
|---|
| 244 | + |
|---|
| 245 | +static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_pga_slew_time_enum, |
|---|
| 246 | + ADAU1761_ALC_CTRL0, 6, 0x3, adau1761_pga_slew_time_text, |
|---|
| 247 | + adau1761_pga_slew_time_values); |
|---|
| 248 | +static SOC_ENUM_SINGLE_DECL(adau1761_alc_function_enum, |
|---|
| 249 | + ADAU1761_ALC_CTRL0, 0, adau1761_alc_function_text); |
|---|
| 250 | +static SOC_ENUM_SINGLE_DECL(adau1761_alc_hold_time_enum, |
|---|
| 251 | + ADAU1761_ALC_CTRL1, 4, adau1761_alc_hold_time_text); |
|---|
| 252 | +static SOC_ENUM_SINGLE_DECL(adau1761_alc_attack_time_enum, |
|---|
| 253 | + ADAU1761_ALC_CTRL2, 4, adau1761_alc_attack_time_text); |
|---|
| 254 | +static SOC_ENUM_SINGLE_DECL(adau1761_alc_decay_time_enum, |
|---|
| 255 | + ADAU1761_ALC_CTRL2, 0, adau1761_alc_decay_time_text); |
|---|
| 256 | +static SOC_ENUM_SINGLE_DECL(adau1761_alc_ng_type_enum, |
|---|
| 257 | + ADAU1761_ALC_CTRL3, 6, adau1761_alc_ng_type_text); |
|---|
| 258 | + |
|---|
| 151 | 259 | static const struct snd_kcontrol_new adau1761_jack_detect_controls[] = { |
|---|
| 152 | 260 | SOC_SINGLE("Speaker Auto-mute Switch", ADAU1761_DIGMIC_JACKDETECT, |
|---|
| 153 | 261 | 4, 1, 0), |
|---|
| .. | .. |
|---|
| 162 | 270 | |
|---|
| 163 | 271 | SOC_DOUBLE_R_TLV("PGA Boost Capture Volume", ADAU1761_REC_MIXER_LEFT1, |
|---|
| 164 | 272 | ADAU1761_REC_MIXER_RIGHT1, 3, 2, 0, adau1761_pga_boost_tlv), |
|---|
| 273 | + |
|---|
| 274 | + SOC_ENUM("PGA Capture Slew Time", adau1761_pga_slew_time_enum), |
|---|
| 275 | + |
|---|
| 276 | + SOC_SINGLE_TLV("ALC Capture Max Gain Volume", ADAU1761_ALC_CTRL0, |
|---|
| 277 | + 3, 7, 0, adau1761_alc_max_gain_tlv), |
|---|
| 278 | + SOC_ENUM("ALC Capture Function", adau1761_alc_function_enum), |
|---|
| 279 | + SOC_ENUM("ALC Capture Hold Time", adau1761_alc_hold_time_enum), |
|---|
| 280 | + SOC_SINGLE_TLV("ALC Capture Target Volume", ADAU1761_ALC_CTRL1, |
|---|
| 281 | + 0, 15, 0, adau1761_alc_target_tlv), |
|---|
| 282 | + SOC_ENUM("ALC Capture Attack Time", adau1761_alc_decay_time_enum), |
|---|
| 283 | + SOC_ENUM("ALC Capture Decay Time", adau1761_alc_attack_time_enum), |
|---|
| 284 | + SOC_ENUM("ALC Capture Noise Gate Type", adau1761_alc_ng_type_enum), |
|---|
| 285 | + SOC_SINGLE("ALC Capture Noise Gate Switch", |
|---|
| 286 | + ADAU1761_ALC_CTRL3, 5, 1, 0), |
|---|
| 287 | + SOC_SINGLE_TLV("ALC Capture Noise Gate Threshold Volume", |
|---|
| 288 | + ADAU1761_ALC_CTRL3, 0, 31, 0, adau1761_alc_ng_threshold_tlv), |
|---|
| 165 | 289 | }; |
|---|
| 166 | 290 | |
|---|
| 167 | 291 | static const struct snd_kcontrol_new adau1761_single_mode_controls[] = { |
|---|
| .. | .. |
|---|
| 518 | 642 | ARRAY_SIZE(adau1761_jack_detect_controls)); |
|---|
| 519 | 643 | if (ret) |
|---|
| 520 | 644 | return ret; |
|---|
| 521 | | - case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: /* fallthrough */ |
|---|
| 645 | + fallthrough; |
|---|
| 646 | + case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: |
|---|
| 522 | 647 | ret = snd_soc_dapm_add_routes(dapm, adau1761_no_dmic_routes, |
|---|
| 523 | 648 | ARRAY_SIZE(adau1761_no_dmic_routes)); |
|---|
| 524 | 649 | if (ret) |
|---|
| .. | .. |
|---|
| 568 | 693 | ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE, |
|---|
| 569 | 694 | ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP | |
|---|
| 570 | 695 | ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE); |
|---|
| 571 | | - /* fallthrough */ |
|---|
| 696 | + fallthrough; |
|---|
| 572 | 697 | case ADAU1761_OUTPUT_MODE_HEADPHONE: |
|---|
| 573 | 698 | regmap_update_bits(adau->regmap, ADAU1761_PLAY_HP_RIGHT_VOL, |
|---|
| 574 | 699 | ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP, |
|---|
| .. | .. |
|---|
| 632 | 757 | case ADAU1761_DEJITTER: |
|---|
| 633 | 758 | case ADAU1761_CLK_ENABLE0: |
|---|
| 634 | 759 | case ADAU1761_CLK_ENABLE1: |
|---|
| 760 | + case ADAU1761_ALC_CTRL0: |
|---|
| 761 | + case ADAU1761_ALC_CTRL1: |
|---|
| 762 | + case ADAU1761_ALC_CTRL2: |
|---|
| 763 | + case ADAU1761_ALC_CTRL3: |
|---|
| 635 | 764 | return true; |
|---|
| 636 | 765 | default: |
|---|
| 637 | 766 | break; |
|---|