diff options
-rw-r--r-- | sound/soc/codecs/da7210.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 7a4b952a05e..0ebcbd53449 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c | |||
@@ -54,6 +54,9 @@ | |||
54 | #define DA7210_DAC_EQ5 0x1B | 54 | #define DA7210_DAC_EQ5 0x1B |
55 | #define DA7210_OUTMIX_L 0x1C | 55 | #define DA7210_OUTMIX_L 0x1C |
56 | #define DA7210_OUTMIX_R 0x1D | 56 | #define DA7210_OUTMIX_R 0x1D |
57 | #define DA7210_OUT1_L 0x1E | ||
58 | #define DA7210_OUT1_R 0x1F | ||
59 | #define DA7210_OUT2 0x20 | ||
57 | #define DA7210_HP_L_VOL 0x21 | 60 | #define DA7210_HP_L_VOL 0x21 |
58 | #define DA7210_HP_R_VOL 0x22 | 61 | #define DA7210_HP_R_VOL 0x22 |
59 | #define DA7210_HP_CFG 0x23 | 62 | #define DA7210_HP_CFG 0x23 |
@@ -186,6 +189,17 @@ | |||
186 | #define DA7210_INPGA_MIN_VOL_NS 0x0A /* 10.5dB */ | 189 | #define DA7210_INPGA_MIN_VOL_NS 0x0A /* 10.5dB */ |
187 | #define DA7210_AUX1_MIN_VOL_NS 0x35 /* 6dB */ | 190 | #define DA7210_AUX1_MIN_VOL_NS 0x35 /* 6dB */ |
188 | 191 | ||
192 | /* OUT1_L bit fields */ | ||
193 | #define DA7210_OUT1_L_EN (1 << 7) | ||
194 | |||
195 | /* OUT1_R bit fields */ | ||
196 | #define DA7210_OUT1_R_EN (1 << 7) | ||
197 | |||
198 | /* OUT2 bit fields */ | ||
199 | #define DA7210_OUT2_OUTMIX_R (1 << 5) | ||
200 | #define DA7210_OUT2_OUTMIX_L (1 << 6) | ||
201 | #define DA7210_OUT2_EN (1 << 7) | ||
202 | |||
189 | #define DA7210_VERSION "0.0.1" | 203 | #define DA7210_VERSION "0.0.1" |
190 | 204 | ||
191 | /* | 205 | /* |
@@ -206,8 +220,23 @@ static const unsigned int hp_out_tlv[] = { | |||
206 | 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0), | 220 | 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0), |
207 | }; | 221 | }; |
208 | 222 | ||
223 | static const unsigned int lineout_vol_tlv[] = { | ||
224 | TLV_DB_RANGE_HEAD(2), | ||
225 | 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), | ||
226 | /* -54dB to 15dB */ | ||
227 | 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0) | ||
228 | }; | ||
229 | |||
230 | static const unsigned int mono_vol_tlv[] = { | ||
231 | TLV_DB_RANGE_HEAD(2), | ||
232 | 0x0, 0x2, TLV_DB_SCALE_ITEM(-1800, 0, 1), | ||
233 | /* -18dB to 6dB */ | ||
234 | 0x3, 0x7, TLV_DB_SCALE_ITEM(-1800, 600, 0) | ||
235 | }; | ||
236 | |||
209 | static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0); | 237 | static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0); |
210 | static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1); | 238 | static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1); |
239 | static const DECLARE_TLV_DB_SCALE(dac_gain_tlv, -7725, 75, 0); | ||
211 | 240 | ||
212 | /* ADC and DAC high pass filter f0 value */ | 241 | /* ADC and DAC high pass filter f0 value */ |
213 | static const char const *da7210_hpf_cutoff_txt[] = { | 242 | static const char const *da7210_hpf_cutoff_txt[] = { |
@@ -306,6 +335,14 @@ static const struct snd_kcontrol_new da7210_snd_controls[] = { | |||
306 | SOC_DOUBLE_R_TLV("HeadPhone Playback Volume", | 335 | SOC_DOUBLE_R_TLV("HeadPhone Playback Volume", |
307 | DA7210_HP_L_VOL, DA7210_HP_R_VOL, | 336 | DA7210_HP_L_VOL, DA7210_HP_R_VOL, |
308 | 0, 0x3F, 0, hp_out_tlv), | 337 | 0, 0x3F, 0, hp_out_tlv), |
338 | SOC_DOUBLE_R_TLV("Digital Playback Volume", | ||
339 | DA7210_DAC_L, DA7210_DAC_R, | ||
340 | 0, 0x77, 1, dac_gain_tlv), | ||
341 | SOC_DOUBLE_R_TLV("Lineout Playback Volume", | ||
342 | DA7210_OUT1_L, DA7210_OUT1_R, | ||
343 | 0, 0x3f, 0, lineout_vol_tlv), | ||
344 | SOC_SINGLE_TLV("Mono Playback Volume", DA7210_OUT2, 0, 0x7, 0, | ||
345 | mono_vol_tlv), | ||
309 | 346 | ||
310 | /* DAC Equalizer controls */ | 347 | /* DAC Equalizer controls */ |
311 | SOC_SINGLE("DAC EQ Switch", DA7210_DAC_EQ5, 7, 1, 0), | 348 | SOC_SINGLE("DAC EQ Switch", DA7210_DAC_EQ5, 7, 1, 0), |
@@ -402,6 +439,12 @@ static const struct snd_kcontrol_new da7210_dapm_outmixr_controls[] = { | |||
402 | SOC_DAPM_SINGLE("DAC Right Switch", DA7210_OUTMIX_R, 4, 1, 0), | 439 | SOC_DAPM_SINGLE("DAC Right Switch", DA7210_OUTMIX_R, 4, 1, 0), |
403 | }; | 440 | }; |
404 | 441 | ||
442 | /* Mono Mixer */ | ||
443 | static const struct snd_kcontrol_new da7210_dapm_monomix_controls[] = { | ||
444 | SOC_DAPM_SINGLE("Outmix Right Switch", DA7210_OUT2, 5, 1, 0), | ||
445 | SOC_DAPM_SINGLE("Outmix Left Switch", DA7210_OUT2, 6, 1, 0), | ||
446 | }; | ||
447 | |||
405 | /* DAPM widgets */ | 448 | /* DAPM widgets */ |
406 | static const struct snd_soc_dapm_widget da7210_dapm_widgets[] = { | 449 | static const struct snd_soc_dapm_widget da7210_dapm_widgets[] = { |
407 | /* Input Side */ | 450 | /* Input Side */ |
@@ -443,16 +486,26 @@ static const struct snd_soc_dapm_widget da7210_dapm_widgets[] = { | |||
443 | &da7210_dapm_outmixr_controls[0], | 486 | &da7210_dapm_outmixr_controls[0], |
444 | ARRAY_SIZE(da7210_dapm_outmixr_controls)), | 487 | ARRAY_SIZE(da7210_dapm_outmixr_controls)), |
445 | 488 | ||
489 | SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0, | ||
490 | &da7210_dapm_monomix_controls[0], | ||
491 | ARRAY_SIZE(da7210_dapm_monomix_controls)), | ||
492 | |||
446 | /* Output PGAs */ | 493 | /* Output PGAs */ |
447 | SND_SOC_DAPM_PGA("OUTPGA Left Enable", DA7210_OUTMIX_L, 7, 0, NULL, 0), | 494 | SND_SOC_DAPM_PGA("OUTPGA Left Enable", DA7210_OUTMIX_L, 7, 0, NULL, 0), |
448 | SND_SOC_DAPM_PGA("OUTPGA Right Enable", DA7210_OUTMIX_R, 7, 0, NULL, 0), | 495 | SND_SOC_DAPM_PGA("OUTPGA Right Enable", DA7210_OUTMIX_R, 7, 0, NULL, 0), |
449 | 496 | ||
497 | SND_SOC_DAPM_PGA("Out1 Left", DA7210_STARTUP2, 0, 1, NULL, 0), | ||
498 | SND_SOC_DAPM_PGA("Out1 Right", DA7210_STARTUP2, 1, 1, NULL, 0), | ||
499 | SND_SOC_DAPM_PGA("Out2 Mono", DA7210_STARTUP2, 2, 1, NULL, 0), | ||
450 | SND_SOC_DAPM_PGA("Headphone Left", DA7210_STARTUP2, 3, 1, NULL, 0), | 500 | SND_SOC_DAPM_PGA("Headphone Left", DA7210_STARTUP2, 3, 1, NULL, 0), |
451 | SND_SOC_DAPM_PGA("Headphone Right", DA7210_STARTUP2, 4, 1, NULL, 0), | 501 | SND_SOC_DAPM_PGA("Headphone Right", DA7210_STARTUP2, 4, 1, NULL, 0), |
452 | 502 | ||
453 | /* Output Lines */ | 503 | /* Output Lines */ |
504 | SND_SOC_DAPM_OUTPUT("OUT1L"), | ||
505 | SND_SOC_DAPM_OUTPUT("OUT1R"), | ||
454 | SND_SOC_DAPM_OUTPUT("HPL"), | 506 | SND_SOC_DAPM_OUTPUT("HPL"), |
455 | SND_SOC_DAPM_OUTPUT("HPR"), | 507 | SND_SOC_DAPM_OUTPUT("HPR"), |
508 | SND_SOC_DAPM_OUTPUT("OUT2"), | ||
456 | }; | 509 | }; |
457 | 510 | ||
458 | /* DAPM audio route definition */ | 511 | /* DAPM audio route definition */ |
@@ -478,14 +531,26 @@ static const struct snd_soc_dapm_route da7210_audio_map[] = { | |||
478 | {"Out Mixer Left", "DAC Left Switch", "DAC Left"}, | 531 | {"Out Mixer Left", "DAC Left Switch", "DAC Left"}, |
479 | {"Out Mixer Right", "DAC Right Switch", "DAC Right"}, | 532 | {"Out Mixer Right", "DAC Right Switch", "DAC Right"}, |
480 | 533 | ||
534 | {"Mono Mixer", "Outmix Right Switch", "Out Mixer Right"}, | ||
535 | {"Mono Mixer", "Outmix Left Switch", "Out Mixer Left"}, | ||
536 | |||
481 | {"OUTPGA Left Enable", NULL, "Out Mixer Left"}, | 537 | {"OUTPGA Left Enable", NULL, "Out Mixer Left"}, |
482 | {"OUTPGA Right Enable", NULL, "Out Mixer Right"}, | 538 | {"OUTPGA Right Enable", NULL, "Out Mixer Right"}, |
483 | 539 | ||
540 | {"Out1 Left", NULL, "OUTPGA Left Enable"}, | ||
541 | {"OUT1L", NULL, "Out1 Left"}, | ||
542 | |||
543 | {"Out1 Right", NULL, "OUTPGA Right Enable"}, | ||
544 | {"OUT1R", NULL, "Out1 Right"}, | ||
545 | |||
484 | {"Headphone Left", NULL, "OUTPGA Left Enable"}, | 546 | {"Headphone Left", NULL, "OUTPGA Left Enable"}, |
485 | {"HPL", NULL, "Headphone Left"}, | 547 | {"HPL", NULL, "Headphone Left"}, |
486 | 548 | ||
487 | {"Headphone Right", NULL, "OUTPGA Right Enable"}, | 549 | {"Headphone Right", NULL, "OUTPGA Right Enable"}, |
488 | {"HPR", NULL, "Headphone Right"}, | 550 | {"HPR", NULL, "Headphone Right"}, |
551 | |||
552 | {"Out2 Mono", NULL, "Mono Mixer"}, | ||
553 | {"OUT2", NULL, "Out2 Mono"}, | ||
489 | }; | 554 | }; |
490 | 555 | ||
491 | /* Codec private data */ | 556 | /* Codec private data */ |
@@ -791,6 +856,37 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
791 | /* Enable ramp mode for DAC gain update */ | 856 | /* Enable ramp mode for DAC gain update */ |
792 | snd_soc_write(codec, DA7210_SOFTMUTE, DA7210_RAMP_EN); | 857 | snd_soc_write(codec, DA7210_SOFTMUTE, DA7210_RAMP_EN); |
793 | 858 | ||
859 | /* | ||
860 | * For DA7210 codec, there are two ways to enable/disable analog IOs | ||
861 | * and ADC/DAC, | ||
862 | * (1) Using "Enable Bit" of register associated with that IO | ||
863 | * (or ADC/DAC) | ||
864 | * e.g. Mic Left can be enabled using bit 7 of MIC_L(0x7) reg | ||
865 | * | ||
866 | * (2) Using "Standby Bit" of STARTUP2 or STARTUP3 register | ||
867 | * e.g. Mic left can be put to STANDBY using bit 0 of STARTUP3(0x5) | ||
868 | * | ||
869 | * Out of these two methods, the one using STANDBY bits is preferred | ||
870 | * way to enable/disable individual blocks. This is because STANDBY | ||
871 | * registers are part of system controller which allows system power | ||
872 | * up/down in a controlled, pop-free manner. Also, as per application | ||
873 | * note of DA7210, STANDBY register bits are only effective if a | ||
874 | * particular IO (or ADC/DAC) is already enabled using enable/disable | ||
875 | * register bits. Keeping these things in mind, current DAPM | ||
876 | * implementation manipulates only STANDBY bits. | ||
877 | * | ||
878 | * Overall implementation can be outlined as below, | ||
879 | * | ||
880 | * - "Enable bit" of an IO or ADC/DAC is used to enable it in probe() | ||
881 | * - "STANDBY bit" is controlled by DAPM | ||
882 | */ | ||
883 | |||
884 | /* Enable Line out amplifiers */ | ||
885 | snd_soc_write(codec, DA7210_OUT1_L, DA7210_OUT1_L_EN); | ||
886 | snd_soc_write(codec, DA7210_OUT1_R, DA7210_OUT1_R_EN); | ||
887 | snd_soc_write(codec, DA7210_OUT2, DA7210_OUT2_EN | | ||
888 | DA7210_OUT2_OUTMIX_L | DA7210_OUT2_OUTMIX_R); | ||
889 | |||
794 | /* Diable PLL and bypass it */ | 890 | /* Diable PLL and bypass it */ |
795 | snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); | 891 | snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); |
796 | 892 | ||