aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/da7210.c
diff options
context:
space:
mode:
authorAshish Chavan <ashish.chavan@kpitcummins.com>2011-10-21 09:36:23 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-10-22 05:34:50 -0400
commit52082d8f562bb4ed4045ea691a3ec1f44d828eab (patch)
treed1bf3322e84d7ec03d7e146c692faec1487ce8f6 /sound/soc/codecs/da7210.c
parent6950c60dc1a0981a6a99bece52437965be8e1be0 (diff)
ASoC: da7210: Add support for line out and DAC
DA7210 has three line outputs. OUT1 Left, OUT1 Right and OUT2 (mono). This patch adds support for gain controls for these three line outs. It also adds support for overall DAC gain control. Signed-off-by: Ashish Chavan <ashish.chavan@kpitcummins.com> Signed-off-by: David Dajun Chen <dchen@diasemi.com> Acked-by: Liam Girdwood <lrg@ti.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/da7210.c')
-rw-r--r--sound/soc/codecs/da7210.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 7a4b952a05eb..0ebcbd534490 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
223static 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
230static 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
209static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0); 237static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0);
210static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1); 238static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1);
239static 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 */
213static const char const *da7210_hpf_cutoff_txt[] = { 242static 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 */
443static 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 */
406static const struct snd_soc_dapm_widget da7210_dapm_widgets[] = { 449static 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