[alsa-devel] [PATCH] ASoC: twl4030 - Add VDL path support
Adds DAPMs for VDL(voice down link) path. To support VDL path, we have to change DAPM of outputs(Earpiece, PreDrive Left/Right, Headset Left/Right, Carkit Left/Right) from mux to mixer.
Signed-off-by: Joonyoung Shim jy0922.shim@samsung.com --- sound/soc/codecs/twl4030.c | 226 ++++++++++++++++++++------------------------ 1 files changed, 103 insertions(+), 123 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 5ed5f1b..317d710 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -313,104 +313,60 @@ static void twl4030_power_down(struct snd_soc_codec *codec) }
/* Earpiece */ -static const char *twl4030_earpiece_texts[] = - {"Off", "DACL1", "DACL2", "DACR1"}; - -static const unsigned int twl4030_earpiece_values[] = - {0x0, 0x1, 0x2, 0x4}; - -static const struct soc_enum twl4030_earpiece_enum = - SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7, - ARRAY_SIZE(twl4030_earpiece_texts), - twl4030_earpiece_texts, - twl4030_earpiece_values); - -static const struct snd_kcontrol_new twl4030_dapm_earpiece_control = -SOC_DAPM_VALUE_ENUM("Route", twl4030_earpiece_enum); +static const struct snd_kcontrol_new twl4030_dapm_earpiece_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_EAR_CTL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_EAR_CTL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_EAR_CTL, 2, 1, 0), + SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_EAR_CTL, 3, 1, 0), +};
/* PreDrive Left */ -static const char *twl4030_predrivel_texts[] = - {"Off", "DACL1", "DACL2", "DACR2"}; - -static const unsigned int twl4030_predrivel_values[] = - {0x0, 0x1, 0x2, 0x4}; - -static const struct soc_enum twl4030_predrivel_enum = - SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7, - ARRAY_SIZE(twl4030_predrivel_texts), - twl4030_predrivel_texts, - twl4030_predrivel_values); - -static const struct snd_kcontrol_new twl4030_dapm_predrivel_control = -SOC_DAPM_VALUE_ENUM("Route", twl4030_predrivel_enum); +static const struct snd_kcontrol_new twl4030_dapm_predrivel_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDL_CTL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PREDL_CTL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDL_CTL, 2, 1, 0), + SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDL_CTL, 3, 1, 0), +};
/* PreDrive Right */ -static const char *twl4030_predriver_texts[] = - {"Off", "DACR1", "DACR2", "DACL2"}; - -static const unsigned int twl4030_predriver_values[] = - {0x0, 0x1, 0x2, 0x4}; - -static const struct soc_enum twl4030_predriver_enum = - SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7, - ARRAY_SIZE(twl4030_predriver_texts), - twl4030_predriver_texts, - twl4030_predriver_values); - -static const struct snd_kcontrol_new twl4030_dapm_predriver_control = -SOC_DAPM_VALUE_ENUM("Route", twl4030_predriver_enum); +static const struct snd_kcontrol_new twl4030_dapm_predriver_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDR_CTL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PREDR_CTL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDR_CTL, 2, 1, 0), + SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDR_CTL, 3, 1, 0), +};
/* Headset Left */ -static const char *twl4030_hsol_texts[] = - {"Off", "DACL1", "DACL2"}; - -static const struct soc_enum twl4030_hsol_enum = - SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 1, - ARRAY_SIZE(twl4030_hsol_texts), - twl4030_hsol_texts); - -static const struct snd_kcontrol_new twl4030_dapm_hsol_control = -SOC_DAPM_ENUM("Route", twl4030_hsol_enum); +static const struct snd_kcontrol_new twl4030_dapm_hsol_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_HS_SEL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_HS_SEL, 2, 1, 0), +};
/* Headset Right */ -static const char *twl4030_hsor_texts[] = - {"Off", "DACR1", "DACR2"}; - -static const struct soc_enum twl4030_hsor_enum = - SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 4, - ARRAY_SIZE(twl4030_hsor_texts), - twl4030_hsor_texts); - -static const struct snd_kcontrol_new twl4030_dapm_hsor_control = -SOC_DAPM_ENUM("Route", twl4030_hsor_enum); +static const struct snd_kcontrol_new twl4030_dapm_hsor_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 3, 1, 0), + SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_HS_SEL, 4, 1, 0), + SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_HS_SEL, 5, 1, 0), +};
/* Carkit Left */ -static const char *twl4030_carkitl_texts[] = - {"Off", "DACL1", "DACL2"}; - -static const struct soc_enum twl4030_carkitl_enum = - SOC_ENUM_SINGLE(TWL4030_REG_PRECKL_CTL, 1, - ARRAY_SIZE(twl4030_carkitl_texts), - twl4030_carkitl_texts); - -static const struct snd_kcontrol_new twl4030_dapm_carkitl_control = -SOC_DAPM_ENUM("Route", twl4030_carkitl_enum); +static const struct snd_kcontrol_new twl4030_dapm_carkitl_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKL_CTL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PRECKL_CTL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PRECKL_CTL, 2, 1, 0), +};
/* Carkit Right */ -static const char *twl4030_carkitr_texts[] = - {"Off", "DACR1", "DACR2"}; - -static const struct soc_enum twl4030_carkitr_enum = - SOC_ENUM_SINGLE(TWL4030_REG_PRECKR_CTL, 1, - ARRAY_SIZE(twl4030_carkitr_texts), - twl4030_carkitr_texts); - -static const struct snd_kcontrol_new twl4030_dapm_carkitr_control = -SOC_DAPM_ENUM("Route", twl4030_carkitr_enum); +static const struct snd_kcontrol_new twl4030_dapm_carkitr_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKR_CTL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PRECKR_CTL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PRECKR_CTL, 2, 1, 0), +};
/* Handsfree Left */ static const char *twl4030_handsfreel_texts[] = - {"Voice", "DACL1", "DACL2", "DACR2"}; + {"Voice", "AudioL1", "AudioL2", "AudioR2"};
static const struct soc_enum twl4030_handsfreel_enum = SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0, @@ -422,7 +378,7 @@ SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
/* Handsfree Right */ static const char *twl4030_handsfreer_texts[] = - {"Voice", "DACR1", "DACR2", "DACL2"}; + {"Voice", "AudioR1", "AudioR2", "AudioL2"};
static const struct soc_enum twl4030_handsfreer_enum = SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0, @@ -940,6 +896,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("HFR"),
/* DACs */ + SND_SOC_DAPM_DAC("DAC Voice", "Voice Down Link", + TWL4030_REG_AVDAC_CTL, 4, 0), SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback", SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback", @@ -950,6 +908,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_NOPM, 0, 0),
/* Analog PGAs */ + SND_SOC_DAPM_PGA("VDL_APGA", TWL4030_REG_VDL_APGA_CTL, + 0, 0, NULL, 0), SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("ARXL1_APGA", TWL4030_REG_ARXL1_APGA_CTL, @@ -990,26 +950,35 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL, 3, 0, NULL, 0),
- /* Output MUX controls */ + /* Output MIXER controls */ /* Earpiece */ - SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_earpiece_control), + SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_earpiece_controls[0], + ARRAY_SIZE(twl4030_dapm_earpiece_controls)), /* PreDrivL/R */ - SND_SOC_DAPM_VALUE_MUX("PredriveL Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_predrivel_control), - SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_predriver_control), + SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_predrivel_controls[0], + ARRAY_SIZE(twl4030_dapm_predrivel_controls)), + SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_predriver_controls[0], + ARRAY_SIZE(twl4030_dapm_predriver_controls)), /* HeadsetL/R */ - SND_SOC_DAPM_MUX_E("HeadsetL Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_hsol_control, headsetl_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_hsor_control), + SND_SOC_DAPM_MIXER_E("HeadsetL Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_hsol_controls[0], + ARRAY_SIZE(twl4030_dapm_hsol_controls), headsetl_event, + SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("HeadsetR Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_hsor_controls[0], + ARRAY_SIZE(twl4030_dapm_hsor_controls)), /* CarkitL/R */ - SND_SOC_DAPM_MUX("CarkitL Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_carkitl_control), - SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_carkitr_control), + SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_carkitl_controls[0], + ARRAY_SIZE(twl4030_dapm_carkitl_controls)), + SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_carkitr_controls[0], + ARRAY_SIZE(twl4030_dapm_carkitr_controls)), + + /* Output MUX controls */ /* HandsfreeL/R */ SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0, &twl4030_dapm_handsfreel_control, handsfree_event, @@ -1064,6 +1033,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { };
static const struct snd_soc_dapm_route intercon[] = { + {"VDL_APGA", NULL, "DAC Voice"}, + {"Analog L1 Playback Mixer", NULL, "DAC Left1"}, {"Analog R1 Playback Mixer", NULL, "DAC Right1"}, {"Analog L2 Playback Mixer", NULL, "DAC Left2"}, @@ -1076,37 +1047,46 @@ static const struct snd_soc_dapm_route intercon[] = {
/* Internal playback routings */ /* Earpiece */ - {"Earpiece Mux", "DACL1", "ARXL1_APGA"}, - {"Earpiece Mux", "DACL2", "ARXL2_APGA"}, - {"Earpiece Mux", "DACR1", "ARXR1_APGA"}, + {"Earpiece Mixer", "Voice", "VDL_APGA"}, + {"Earpiece Mixer", "AudioL1", "ARXL1_APGA"}, + {"Earpiece Mixer", "AudioL2", "ARXL2_APGA"}, + {"Earpiece Mixer", "AudioR1", "ARXR1_APGA"}, /* PreDrivL */ - {"PredriveL Mux", "DACL1", "ARXL1_APGA"}, - {"PredriveL Mux", "DACL2", "ARXL2_APGA"}, - {"PredriveL Mux", "DACR2", "ARXR2_APGA"}, + {"PredriveL Mixer", "Voice", "VDL_APGA"}, + {"PredriveL Mixer", "AudioL1", "ARXL1_APGA"}, + {"PredriveL Mixer", "AudioL2", "ARXL2_APGA"}, + {"PredriveL Mixer", "AudioR2", "ARXR2_APGA"}, /* PreDrivR */ - {"PredriveR Mux", "DACR1", "ARXR1_APGA"}, - {"PredriveR Mux", "DACR2", "ARXR2_APGA"}, - {"PredriveR Mux", "DACL2", "ARXL2_APGA"}, + {"PredriveR Mixer", "Voice", "VDL_APGA"}, + {"PredriveR Mixer", "AudioR1", "ARXR1_APGA"}, + {"PredriveR Mixer", "AudioR2", "ARXR2_APGA"}, + {"PredriveR Mixer", "AudioL2", "ARXL2_APGA"}, /* HeadsetL */ - {"HeadsetL Mux", "DACL1", "ARXL1_APGA"}, - {"HeadsetL Mux", "DACL2", "ARXL2_APGA"}, + {"HeadsetL Mixer", "Voice", "VDL_APGA"}, + {"HeadsetL Mixer", "AudioL1", "ARXL1_APGA"}, + {"HeadsetL Mixer", "AudioL2", "ARXL2_APGA"}, /* HeadsetR */ - {"HeadsetR Mux", "DACR1", "ARXR1_APGA"}, - {"HeadsetR Mux", "DACR2", "ARXR2_APGA"}, + {"HeadsetR Mixer", "Voice", "VDL_APGA"}, + {"HeadsetR Mixer", "AudioR1", "ARXR1_APGA"}, + {"HeadsetR Mixer", "AudioR2", "ARXR2_APGA"}, /* CarkitL */ - {"CarkitL Mux", "DACL1", "ARXL1_APGA"}, - {"CarkitL Mux", "DACL2", "ARXL2_APGA"}, + {"CarkitL Mixer", "Voice", "VDL_APGA"}, + {"CarkitL Mixer", "AudioL1", "ARXL1_APGA"}, + {"CarkitL Mixer", "AudioL2", "ARXL2_APGA"}, /* CarkitR */ - {"CarkitR Mux", "DACR1", "ARXR1_APGA"}, - {"CarkitR Mux", "DACR2", "ARXR2_APGA"}, + {"CarkitR Mixer", "Voice", "VDL_APGA"}, + {"CarkitR Mixer", "AudioR1", "ARXR1_APGA"}, + {"CarkitR Mixer", "AudioR2", "ARXR2_APGA"}, /* HandsfreeL */ - {"HandsfreeL Mux", "DACL1", "ARXL1_APGA"}, - {"HandsfreeL Mux", "DACL2", "ARXL2_APGA"}, - {"HandsfreeL Mux", "DACR2", "ARXR2_APGA"}, + {"HandsfreeL Mux", "Voice", "VDL_APGA"}, + {"HandsfreeL Mux", "AudioL1", "ARXL1_APGA"}, + {"HandsfreeL Mux", "AudioL2", "ARXL2_APGA"}, + {"HandsfreeL Mux", "AudioR2", "ARXR2_APGA"}, /* HandsfreeR */ - {"HandsfreeR Mux", "DACR1", "ARXR1_APGA"}, - {"HandsfreeR Mux", "DACR2", "ARXR2_APGA"}, - {"HandsfreeR Mux", "DACL2", "ARXL2_APGA"}, + {"HandsfreeR Mux", "Voice", "VDL_APGA"}, + {"HandsfreeR Mux", "AudioR1", "ARXR1_APGA"}, + {"HandsfreeR Mux", "AudioR2", "ARXR2_APGA"}, + {"HandsfreeR Mux", "AudioL2", "ARXL2_APGA"},
/* outputs */ {"OUTL", NULL, "ARXL2_APGA"},
On Tuesday 17 March 2009 10:28:48 ext Joonyoung Shim wrote:
Adds DAPMs for VDL(voice down link) path. To support VDL path, we have to change DAPM of outputs(Earpiece, PreDrive Left/Right, Headset Left/Right, Carkit Left/Right) from mux to mixer.
Signed-off-by: Joonyoung Shim jy0922.shim@samsung.com
sound/soc/codecs/twl4030.c | 226 ++++++++++++++++++++------------------------ 1 files changed, 103 insertions(+), 123 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 5ed5f1b..317d710 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -313,104 +313,60 @@ static void twl4030_power_down(struct snd_soc_codec *codec) }
/* Earpiece */ -static const char *twl4030_earpiece_texts[] =
{"Off", "DACL1", "DACL2", "DACR1"};
-static const unsigned int twl4030_earpiece_values[] =
{0x0, 0x1, 0x2, 0x4};
-static const struct soc_enum twl4030_earpiece_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_earpiece_texts),
twl4030_earpiece_texts,
twl4030_earpiece_values);
-static const struct snd_kcontrol_new twl4030_dapm_earpiece_control = -SOC_DAPM_VALUE_ENUM("Route", twl4030_earpiece_enum); +static const struct snd_kcontrol_new twl4030_dapm_earpiece_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_EAR_CTL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_EAR_CTL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_EAR_CTL, 2, 1, 0),
SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_EAR_CTL, 3, 1, 0),
+};
The reason to have the VALUE_ENUM for the audio path selection is that according to the TRM only one of the paths can be enabled at the time. While the voice path can be mixed with one of the audio paths (at least that is my understanding). So: AudioL*/AudioR* (DACL*/DACR*) = Mux Voice, AudioL/R* (DACL/R*) = Mix
I think it would be better to leave the current VALUE_ENUMS for the audio path and add a switch for the Voice enable/disable for the outputs and route them through a mixer to the output. Probably than it makes sense to rename the "Earpice Mux" and friends to something like "Earpiece aduio Mux"... So we would have two controls per outputs: "Earpiece aduio Mux" (Off, DACL1, DACL2, DACR1) "Earpiece voice Switch" (on, off) and internally we can have "Earpiece output mixer", which mixes them together.
/* PreDrive Left */ -static const char *twl4030_predrivel_texts[] =
{"Off", "DACL1", "DACL2", "DACR2"};
-static const unsigned int twl4030_predrivel_values[] =
{0x0, 0x1, 0x2, 0x4};
-static const struct soc_enum twl4030_predrivel_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_predrivel_texts),
twl4030_predrivel_texts,
twl4030_predrivel_values);
-static const struct snd_kcontrol_new twl4030_dapm_predrivel_control = -SOC_DAPM_VALUE_ENUM("Route", twl4030_predrivel_enum); +static const struct snd_kcontrol_new twl4030_dapm_predrivel_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDL_CTL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PREDL_CTL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDL_CTL, 2, 1, 0),
SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDL_CTL, 3, 1, 0),
+};
/* PreDrive Right */ -static const char *twl4030_predriver_texts[] =
{"Off", "DACR1", "DACR2", "DACL2"};
-static const unsigned int twl4030_predriver_values[] =
{0x0, 0x1, 0x2, 0x4};
-static const struct soc_enum twl4030_predriver_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_predriver_texts),
twl4030_predriver_texts,
twl4030_predriver_values);
-static const struct snd_kcontrol_new twl4030_dapm_predriver_control = -SOC_DAPM_VALUE_ENUM("Route", twl4030_predriver_enum); +static const struct snd_kcontrol_new twl4030_dapm_predriver_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDR_CTL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PREDR_CTL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDR_CTL, 2, 1, 0),
SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDR_CTL, 3, 1, 0),
+};
/* Headset Left */ -static const char *twl4030_hsol_texts[] =
{"Off", "DACL1", "DACL2"};
-static const struct soc_enum twl4030_hsol_enum =
SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 1,
ARRAY_SIZE(twl4030_hsol_texts),
twl4030_hsol_texts);
-static const struct snd_kcontrol_new twl4030_dapm_hsol_control = -SOC_DAPM_ENUM("Route", twl4030_hsol_enum); +static const struct snd_kcontrol_new twl4030_dapm_hsol_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_HS_SEL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_HS_SEL, 2, 1, 0),
+};
/* Headset Right */ -static const char *twl4030_hsor_texts[] =
{"Off", "DACR1", "DACR2"};
-static const struct soc_enum twl4030_hsor_enum =
SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 4,
ARRAY_SIZE(twl4030_hsor_texts),
twl4030_hsor_texts);
-static const struct snd_kcontrol_new twl4030_dapm_hsor_control = -SOC_DAPM_ENUM("Route", twl4030_hsor_enum); +static const struct snd_kcontrol_new twl4030_dapm_hsor_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 3, 1, 0),
SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_HS_SEL, 4, 1, 0),
SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_HS_SEL, 5, 1, 0),
+};
/* Carkit Left */ -static const char *twl4030_carkitl_texts[] =
{"Off", "DACL1", "DACL2"};
-static const struct soc_enum twl4030_carkitl_enum =
SOC_ENUM_SINGLE(TWL4030_REG_PRECKL_CTL, 1,
ARRAY_SIZE(twl4030_carkitl_texts),
twl4030_carkitl_texts);
-static const struct snd_kcontrol_new twl4030_dapm_carkitl_control = -SOC_DAPM_ENUM("Route", twl4030_carkitl_enum); +static const struct snd_kcontrol_new twl4030_dapm_carkitl_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKL_CTL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PRECKL_CTL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PRECKL_CTL, 2, 1, 0),
+};
/* Carkit Right */ -static const char *twl4030_carkitr_texts[] =
{"Off", "DACR1", "DACR2"};
-static const struct soc_enum twl4030_carkitr_enum =
SOC_ENUM_SINGLE(TWL4030_REG_PRECKR_CTL, 1,
ARRAY_SIZE(twl4030_carkitr_texts),
twl4030_carkitr_texts);
-static const struct snd_kcontrol_new twl4030_dapm_carkitr_control = -SOC_DAPM_ENUM("Route", twl4030_carkitr_enum); +static const struct snd_kcontrol_new twl4030_dapm_carkitr_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKR_CTL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PRECKR_CTL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PRECKR_CTL, 2, 1, 0),
+};
/* Handsfree Left */ static const char *twl4030_handsfreel_texts[] =
{"Voice", "DACL1", "DACL2", "DACR2"};
{"Voice", "AudioL1", "AudioL2", "AudioR2"};
static const struct soc_enum twl4030_handsfreel_enum = SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0, @@ -422,7 +378,7 @@ SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
/* Handsfree Right */ static const char *twl4030_handsfreer_texts[] =
{"Voice", "DACR1", "DACR2", "DACL2"};
{"Voice", "AudioR1", "AudioR2", "AudioL2"};
static const struct soc_enum twl4030_handsfreer_enum = SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0, @@ -940,6 +896,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("HFR"),
/* DACs */
SND_SOC_DAPM_DAC("DAC Voice", "Voice Down Link",
TWL4030_REG_AVDAC_CTL, 4, 0), SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback", SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback",
@@ -950,6 +908,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_NOPM, 0, 0),
/* Analog PGAs */
SND_SOC_DAPM_PGA("VDL_APGA", TWL4030_REG_VDL_APGA_CTL,
0, 0, NULL, 0), SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("ARXL1_APGA", TWL4030_REG_ARXL1_APGA_CTL,
@@ -990,26 +950,35 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL, 3, 0, NULL, 0),
/* Output MUX controls */
/* Output MIXER controls */ /* Earpiece */
SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_earpiece_control),
SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_earpiece_controls[0],
ARRAY_SIZE(twl4030_dapm_earpiece_controls)), /* PreDrivL/R */
SND_SOC_DAPM_VALUE_MUX("PredriveL Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predrivel_control),
SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predriver_control),
SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predrivel_controls[0],
ARRAY_SIZE(twl4030_dapm_predrivel_controls)),
SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predriver_controls[0],
ARRAY_SIZE(twl4030_dapm_predriver_controls)), /* HeadsetL/R */
SND_SOC_DAPM_MUX_E("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_hsol_control, headsetl_event,
SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_hsor_control),
SND_SOC_DAPM_MIXER_E("HeadsetL Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_hsol_controls[0],
ARRAY_SIZE(twl4030_dapm_hsol_controls),
headsetl_event, + SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("HeadsetR Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_hsor_controls[0],
ARRAY_SIZE(twl4030_dapm_hsor_controls)), /* CarkitL/R */
SND_SOC_DAPM_MUX("CarkitL Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_carkitl_control),
SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_carkitr_control),
SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_carkitl_controls[0],
ARRAY_SIZE(twl4030_dapm_carkitl_controls)),
SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_carkitr_controls[0],
ARRAY_SIZE(twl4030_dapm_carkitr_controls)),
/* Output MUX controls */ /* HandsfreeL/R */ SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0, &twl4030_dapm_handsfreel_control, handsfree_event,
@@ -1064,6 +1033,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { };
static const struct snd_soc_dapm_route intercon[] = {
{"VDL_APGA", NULL, "DAC Voice"},
{"Analog L1 Playback Mixer", NULL, "DAC Left1"}, {"Analog R1 Playback Mixer", NULL, "DAC Right1"}, {"Analog L2 Playback Mixer", NULL, "DAC Left2"},
@@ -1076,37 +1047,46 @@ static const struct snd_soc_dapm_route intercon[] = {
/* Internal playback routings */ /* Earpiece */
{"Earpiece Mux", "DACL1", "ARXL1_APGA"},
{"Earpiece Mux", "DACL2", "ARXL2_APGA"},
{"Earpiece Mux", "DACR1", "ARXR1_APGA"},
{"Earpiece Mixer", "Voice", "VDL_APGA"},
{"Earpiece Mixer", "AudioL1", "ARXL1_APGA"},
{"Earpiece Mixer", "AudioL2", "ARXL2_APGA"},
{"Earpiece Mixer", "AudioR1", "ARXR1_APGA"}, /* PreDrivL */
{"PredriveL Mux", "DACL1", "ARXL1_APGA"},
{"PredriveL Mux", "DACL2", "ARXL2_APGA"},
{"PredriveL Mux", "DACR2", "ARXR2_APGA"},
{"PredriveL Mixer", "Voice", "VDL_APGA"},
{"PredriveL Mixer", "AudioL1", "ARXL1_APGA"},
{"PredriveL Mixer", "AudioL2", "ARXL2_APGA"},
{"PredriveL Mixer", "AudioR2", "ARXR2_APGA"}, /* PreDrivR */
{"PredriveR Mux", "DACR1", "ARXR1_APGA"},
{"PredriveR Mux", "DACR2", "ARXR2_APGA"},
{"PredriveR Mux", "DACL2", "ARXL2_APGA"},
{"PredriveR Mixer", "Voice", "VDL_APGA"},
{"PredriveR Mixer", "AudioR1", "ARXR1_APGA"},
{"PredriveR Mixer", "AudioR2", "ARXR2_APGA"},
{"PredriveR Mixer", "AudioL2", "ARXL2_APGA"}, /* HeadsetL */
{"HeadsetL Mux", "DACL1", "ARXL1_APGA"},
{"HeadsetL Mux", "DACL2", "ARXL2_APGA"},
{"HeadsetL Mixer", "Voice", "VDL_APGA"},
{"HeadsetL Mixer", "AudioL1", "ARXL1_APGA"},
{"HeadsetL Mixer", "AudioL2", "ARXL2_APGA"}, /* HeadsetR */
{"HeadsetR Mux", "DACR1", "ARXR1_APGA"},
{"HeadsetR Mux", "DACR2", "ARXR2_APGA"},
{"HeadsetR Mixer", "Voice", "VDL_APGA"},
{"HeadsetR Mixer", "AudioR1", "ARXR1_APGA"},
{"HeadsetR Mixer", "AudioR2", "ARXR2_APGA"}, /* CarkitL */
{"CarkitL Mux", "DACL1", "ARXL1_APGA"},
{"CarkitL Mux", "DACL2", "ARXL2_APGA"},
{"CarkitL Mixer", "Voice", "VDL_APGA"},
{"CarkitL Mixer", "AudioL1", "ARXL1_APGA"},
{"CarkitL Mixer", "AudioL2", "ARXL2_APGA"}, /* CarkitR */
{"CarkitR Mux", "DACR1", "ARXR1_APGA"},
{"CarkitR Mux", "DACR2", "ARXR2_APGA"},
{"CarkitR Mixer", "Voice", "VDL_APGA"},
{"CarkitR Mixer", "AudioR1", "ARXR1_APGA"},
{"CarkitR Mixer", "AudioR2", "ARXR2_APGA"}, /* HandsfreeL */
{"HandsfreeL Mux", "DACL1", "ARXL1_APGA"},
{"HandsfreeL Mux", "DACL2", "ARXL2_APGA"},
{"HandsfreeL Mux", "DACR2", "ARXR2_APGA"},
{"HandsfreeL Mux", "Voice", "VDL_APGA"},
{"HandsfreeL Mux", "AudioL1", "ARXL1_APGA"},
{"HandsfreeL Mux", "AudioL2", "ARXL2_APGA"},
{"HandsfreeL Mux", "AudioR2", "ARXR2_APGA"}, /* HandsfreeR */
{"HandsfreeR Mux", "DACR1", "ARXR1_APGA"},
{"HandsfreeR Mux", "DACR2", "ARXR2_APGA"},
{"HandsfreeR Mux", "DACL2", "ARXL2_APGA"},
{"HandsfreeR Mux", "Voice", "VDL_APGA"},
{"HandsfreeR Mux", "AudioR1", "ARXR1_APGA"},
{"HandsfreeR Mux", "AudioR2", "ARXR2_APGA"},
{"HandsfreeR Mux", "AudioL2", "ARXL2_APGA"}, /* outputs */ {"OUTL", NULL, "ARXL2_APGA"},
-- 1.5.6.3
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
On Tue, Mar 17, 2009 at 11:22:21AM +0200, Peter Ujfalusi wrote:
Probably than it makes sense to rename the "Earpice Mux" and friends to something like "Earpiece aduio Mux"... So we would have two controls per outputs: "Earpiece aduio Mux" (Off, DACL1, DACL2, DACR1) "Earpiece voice Switch" (on, off) and internally we can have "Earpiece output mixer", which mixes them together.
I'd suggest "HiFi" rather than "aduio" - it's all audio, it's the quality of the audio that's the difference here. This naming is used for some other codecs.
On Tuesday 17 March 2009 12:42:00 ext Mark Brown wrote:
On Tue, Mar 17, 2009 at 11:22:21AM +0200, Peter Ujfalusi wrote:
Probably than it makes sense to rename the "Earpice Mux" and friends to something like "Earpiece aduio Mux"... So we would have two controls per outputs: "Earpiece aduio Mux" (Off, DACL1, DACL2, DACR1) "Earpiece voice Switch" (on, off) and internally we can have "Earpiece output mixer", which mixes them together.
I'd suggest "HiFi" rather than "aduio" - it's all audio, it's the quality of the audio that's the difference here. This naming is used for some other codecs.
Agree, "HiFi" is much better than "aduio" and better than "audio" also ;)
Hi, my thunderbird progrem breaked down, so i send from gmail
The reason to have the VALUE_ENUM for the audio path selection is that according to the TRM only one of the paths can be enabled at the time.
It's not true. I tested playback about Predrive Right audio path(My target is not connected with Predriver Left) The AudioL2 and AudioR2 was enabled and i played audio wav file of three type following; 1. wav file recorded only left channel 2. wav file recorded only right channel 3. wav file recorded left and right channel The result is that all was sounded. If the controller is mux, the case of 1 or 2 haven't to sound.
While the voice path can be mixed with one of the audio paths (at least that is my understanding). So: AudioL*/AudioR* (DACL*/DACR*) = Mux Voice, AudioL/R* (DACL/R*) = Mix
I think it would be better to leave the current VALUE_ENUMS for the audio path and add a switch for the Voice enable/disable for the outputs and route them through a mixer to the output.
The mixer DAPM is suitable the structure of control registers(0x21, 0x22, 0x25, 0x26, 0x27, 0x28) of path except Handsfree path because each bit for path is switchable. If we use the mixer DAPM, the switch DAPM for voice path doesn't need.
Probably than it makes sense to rename the "Earpice Mux" and friends to something like "Earpiece aduio Mux"... So we would have two controls per outputs: "Earpiece aduio Mux" (Off, DACL1, DACL2, DACR1) "Earpiece voice Switch" (on, off) and internally we can have "Earpiece output mixer", which mixes them together.
On Thursday 19 March 2009 07:44:23 ext Joonyoung Shim wrote:
Hi, my thunderbird progrem breaked down, so i send from gmail
The reason to have the VALUE_ENUM for the audio path selection is that according to the TRM only one of the paths can be enabled at the time.
It's not true. I tested playback about Predrive Right audio path(My target is not connected with Predriver Left) The AudioL2 and AudioR2 was enabled and i played audio wav file of three type following; 1. wav file recorded only left channel 2. wav file recorded only right channel 3. wav file recorded left and right channel The result is that all was sounded. If the controller is mux, the case of 1 or 2 haven't to sound.
While the voice path can be mixed with one of the audio paths (at least that is my understanding). So: AudioL*/AudioR* (DACL*/DACR*) = Mux Voice, AudioL/R* (DACL/R*) = Mix
I think it would be better to leave the current VALUE_ENUMS for the audio path and add a switch for the Voice enable/disable for the outputs and route them through a mixer to the output.
The mixer DAPM is suitable the structure of control registers(0x21, 0x22, 0x25, 0x26, 0x27, 0x28) of path except Handsfree path because each bit for path is switchable. If we use the mixer DAPM, the switch DAPM for voice path doesn't need.
Probably than it makes sense to rename the "Earpice Mux" and friends to something like "Earpiece aduio Mux"... So we would have two controls per outputs: "Earpiece aduio Mux" (Off, DACL1, DACL2, DACR1) "Earpiece voice Switch" (on, off) and internally we can have "Earpiece output mixer", which mixes them together.
I have given a try to your patch, although it does not work out of the box, but I can verify that you are indeed right. I have been also wondering about these mixer/mux controls for the outputs and the block diagrams in the TRM has MIX in these outputs, but in other places it hints that they are a mixture of mux and mixers.
PS 01: you have been missing this part from your patch, which is needed for DAPM to power on the path: /* outputs */ {"OUTL", NULL, "ARXL2_APGA"}, {"OUTR", NULL, "ARXR2_APGA"}, - {"EARPIECE", NULL, "Earpiece Mux"}, - {"PREDRIVEL", NULL, "PredriveL Mux"}, - {"PREDRIVER", NULL, "PredriveR Mux"}, - {"HSOL", NULL, "HeadsetL Mux"}, - {"HSOR", NULL, "HeadsetR Mux"}, - {"CARKITL", NULL, "CarkitL Mux"}, - {"CARKITR", NULL, "CarkitR Mux"}, + {"EARPIECE", NULL, "Earpiece Mixer"}, + {"PREDRIVEL", NULL, "PredriveL Mixer"}, + {"PREDRIVER", NULL, "PredriveR Mixer"}, + {"HSOL", NULL, "HeadsetL Mixer"}, + {"HSOR", NULL, "HeadsetR Mixer"}, + {"CARKITL", NULL, "CarkitL Mixer"}, + {"CARKITR", NULL, "CarkitR Mixer"}, {"HFL", NULL, "HandsfreeL Mux"}, {"HFR", NULL, "HandsfreeR Mux"},
If you add this to your patch, I'll be happy to ack it.
PS 02: I have hard time to get 'git am' to apply the patch: git am ../[PATCH]\ ASoC:\ twl4030\ -\ Add\ VDL\ path\ support.mbox fatal: cannot convert from ks_c_5601-1987 to utf-8
Does anyone know how to handle this?
Peter Ujfalusi 쓴 글:
On Thursday 19 March 2009 07:44:23 ext Joonyoung Shim wrote:
Hi, my thunderbird progrem breaked down, so i send from gmail
The reason to have the VALUE_ENUM for the audio path selection is that according to the TRM only one of the paths can be enabled at the time.
It's not true. I tested playback about Predrive Right audio path(My target is not connected with Predriver Left) The AudioL2 and AudioR2 was enabled and i played audio wav file of three type following; 1. wav file recorded only left channel 2. wav file recorded only right channel 3. wav file recorded left and right channel The result is that all was sounded. If the controller is mux, the case of 1 or 2 haven't to sound.
While the voice path can be mixed with one of the audio paths (at least that is my understanding). So: AudioL*/AudioR* (DACL*/DACR*) = Mux Voice, AudioL/R* (DACL/R*) = Mix
I think it would be better to leave the current VALUE_ENUMS for the audio path and add a switch for the Voice enable/disable for the outputs and route them through a mixer to the output.
The mixer DAPM is suitable the structure of control registers(0x21, 0x22, 0x25, 0x26, 0x27, 0x28) of path except Handsfree path because each bit for path is switchable. If we use the mixer DAPM, the switch DAPM for voice path doesn't need.
Probably than it makes sense to rename the "Earpice Mux" and friends to something like "Earpiece aduio Mux"... So we would have two controls per outputs: "Earpiece aduio Mux" (Off, DACL1, DACL2, DACR1) "Earpiece voice Switch" (on, off) and internally we can have "Earpiece output mixer", which mixes them together.
I have given a try to your patch, although it does not work out of the box, but I can verify that you are indeed right. I have been also wondering about these mixer/mux controls for the outputs and the block diagrams in the TRM has MIX in these outputs, but in other places it hints that they are a mixture of mux and mixers.
PS 01: you have been missing this part from your patch, which is needed for DAPM to power on the path: /* outputs */ {"OUTL", NULL, "ARXL2_APGA"}, {"OUTR", NULL, "ARXR2_APGA"},
{"EARPIECE", NULL, "Earpiece Mux"},
{"PREDRIVEL", NULL, "PredriveL Mux"},
{"PREDRIVER", NULL, "PredriveR Mux"},
{"HSOL", NULL, "HeadsetL Mux"},
{"HSOR", NULL, "HeadsetR Mux"},
{"CARKITL", NULL, "CarkitL Mux"},
{"CARKITR", NULL, "CarkitR Mux"},
{"EARPIECE", NULL, "Earpiece Mixer"},
{"PREDRIVEL", NULL, "PredriveL Mixer"},
{"PREDRIVER", NULL, "PredriveR Mixer"},
{"HSOL", NULL, "HeadsetL Mixer"},
{"HSOR", NULL, "HeadsetR Mixer"},
{"CARKITL", NULL, "CarkitL Mixer"},
{"CARKITR", NULL, "CarkitR Mixer"}, {"HFL", NULL, "HandsfreeL Mux"}, {"HFR", NULL, "HandsfreeR Mux"},
If you add this to your patch, I'll be happy to ack it.
Yes, i missed it and will add it. I will send new patch adding more controls for VDL path.
Thanks.
PS 02: I have hard time to get 'git am' to apply the patch: git am ../[PATCH]\ ASoC:\ twl4030\ -\ Add\ VDL\ path\ support.mbox fatal: cannot convert from ks_c_5601-1987 to utf-8
Does anyone know how to handle this?
Hmm, maybe this problem seems appear because of korean character encoding of thunderbird, so i will use utf-8 character.
participants (4)
-
Joonyoung Shim
-
Joonyoung Shim
-
Mark Brown
-
Peter Ujfalusi