[alsa-devel] [PATCH 0/9] ASoC: TWL4030: DAPM implementation for outputs (playback) - try3
Hello,
The whole series again, altrough 1 and 2 has been accepted already.
This series of patches (try3) adds DAPM implementation for all outputs found on TWL.
The design allows one to configure all outputs independently from each other, since the internal routing of TWL actually treats them individually.
The pre-DAC routings can be configured in the board specific files of needed. I have sent a patch which has added this to the codec driver.
Based on the output routing selections all the corresponding DAC and analog PGA on the chain will be powered on.
Remove the Headset output gain modifications from the twl4030_power_up and twl4030_power_down function, since they are not needed.
Changes since try1 (comments addressed): - Removed the " Switch" from the option texts and also from the intercon.
--- Peter Ujfalusi (9): ASoC: TWL4030: Correct DAPM_DAC with power control ASoC: TWL4030: Add Analog PGA control switch to DAPM ASoC: TWL4030: Add DAPM event handler for output MUX selection ASoC: TWL4030: DAPM mapping of the Earpiece output ASoC: TWL4030: DAPM mapping of the PreDriv outputs ASoC: TWL4030: DAPM mapping of the Headset outputs ASoC: TWL4030: DAPM mapping of the Carkit outputs ASoC: TWL4030: DAPM mapping of the Handsfree outputs ASoC: TWL4030: Do not alter the Headset output volume on power-up/down
sound/soc/codecs/twl4030.c | 263 +++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 248 insertions(+), 15 deletions(-)
Add all four DACs to dapm_widgets with power switch.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 3c9fdf2..3543bf6 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -616,8 +616,15 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("OUTL"), SND_SOC_DAPM_OUTPUT("OUTR"),
- SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0), + /* DACs */ + SND_SOC_DAPM_DAC("DACR1", "Right Front Playback", + TWL4030_REG_AVDAC_CTL, 0, 0), + SND_SOC_DAPM_DAC("DACL1", "Left Front Playback", + TWL4030_REG_AVDAC_CTL, 1, 0), + SND_SOC_DAPM_DAC("DACR2", "Right Rear Playback", + TWL4030_REG_AVDAC_CTL, 2, 0), + SND_SOC_DAPM_DAC("DACL2", "Left Rear Playback", + TWL4030_REG_AVDAC_CTL, 3, 0),
SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0), @@ -625,8 +632,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
static const struct snd_soc_dapm_route intercon[] = { /* outputs */ - {"OUTL", NULL, "DACL"}, - {"OUTR", NULL, "DACR"}, + {"OUTL", NULL, "DACL2"}, + {"OUTR", NULL, "DACR2"},
/* inputs */ {"ADCL", NULL, "INL"},
Add all four APGA switch to DAPM routing and widgets. Add user control for DA enable for all APGA as normal control.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 25 +++++++++++++++++++++++-- 1 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 3543bf6..4293ec7 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -562,6 +562,12 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { SOC_DOUBLE_R_TLV("DAC2 Analog Playback Volume", TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL, 3, 0x12, 1, analog_tlv), + SOC_DOUBLE_R("DAC1 Analog Playback Switch", + TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL, + 1, 1, 0), + SOC_DOUBLE_R("DAC2 Analog Playback Switch", + TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL, + 1, 1, 0),
/* Separate output gain controls */ SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume", @@ -626,14 +632,29 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_DAC("DACL2", "Left Rear Playback", TWL4030_REG_AVDAC_CTL, 3, 0),
+ /* Analog PGAs */ + 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, + 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("ARXR2_APGA", TWL4030_REG_ARXR2_APGA_CTL, + 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL, + 0, 0, NULL, 0), + SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0), };
static const struct snd_soc_dapm_route intercon[] = { + {"ARXL1_APGA", NULL, "DACL1"}, + {"ARXR1_APGA", NULL, "DACR1"}, + {"ARXL2_APGA", NULL, "DACL2"}, + {"ARXR2_APGA", NULL, "DACR2"}, + /* outputs */ - {"OUTL", NULL, "DACL2"}, - {"OUTR", NULL, "DACR2"}, + {"OUTL", NULL, "ARXL2_APGA"}, + {"OUTR", NULL, "ARXR2_APGA"},
/* inputs */ {"ADCL", NULL, "INL"},
DAPM event handler is set to filter out invalid MUX settings for certain outputs. Earpiece: - 0 = Off - 1 = DACL1 - 2 = DACL2 - 3 = *** Invalid *** - 4 = DACR1
PreDriveL/R: - 0 = Off/Off - 1 = DACL1/DACR1 - 2 = DACL2/DACR2 - 3 = *** Invalid/Invalid *** - 4 = DACR2/DACL2
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 4293ec7..9d10783 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -190,6 +190,30 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
}
+static int outmixer_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int ret = 0; + int val; + + switch (e->reg) { + case TWL4030_REG_PREDL_CTL: + case TWL4030_REG_PREDR_CTL: + case TWL4030_REG_EAR_CTL: + val = w->value >> e->shift_l; + if (val == 3) { + printk(KERN_WARNING + "Invalid MUX setting for register 0x%02x (%d)\n", + e->reg, val); + ret = -1; + } + break; + } + + return ret; +} + /* * Some of the gain controls in TWL (mostly those which are associated with * the outputs) are implemented in an interesting way:
Adds DAPM muxing, routing for the Earpiece output.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 9d10783..1da4617 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -190,6 +190,19 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
}
+/* Earpiece */ +static const char *twl4030_earpiece_texts[] = + {"Off", "DACL1", "DACL2", "Invalid", + "DACR1"}; + +static const struct soc_enum twl4030_earpiece_enum = + SOC_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, + ARRAY_SIZE(twl4030_earpiece_texts), + twl4030_earpiece_texts); + +static const struct snd_kcontrol_new twl4030_dapm_earpiece_control = +SOC_DAPM_ENUM("Route", twl4030_earpiece_enum); + static int outmixer_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -645,6 +658,7 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("OUTL"), SND_SOC_DAPM_OUTPUT("OUTR"), + SND_SOC_DAPM_OUTPUT("EARPIECE"),
/* DACs */ SND_SOC_DAPM_DAC("DACR1", "Right Front Playback", @@ -666,6 +680,12 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL, 0, 0, NULL, 0),
+ /* Output MUX controls */ + /* Earpiece */ + SND_SOC_DAPM_MUX_E("Earpiece Mux", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_earpiece_control, outmixer_event, + SND_SOC_DAPM_PRE_REG), + SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0), }; @@ -676,9 +696,16 @@ static const struct snd_soc_dapm_route intercon[] = { {"ARXL2_APGA", NULL, "DACL2"}, {"ARXR2_APGA", NULL, "DACR2"},
+ /* Internal playback routings */ + /* Earpiece */ + {"Earpiece Mux", "DACL1", "ARXL1_APGA"}, + {"Earpiece Mux", "DACL2", "ARXL2_APGA"}, + {"Earpiece Mux", "DACR1", "ARXR1_APGA"}, + /* outputs */ {"OUTL", NULL, "ARXL2_APGA"}, {"OUTR", NULL, "ARXR2_APGA"}, + {"EARPIECE", NULL, "Earpiece Mux"},
/* inputs */ {"ADCL", NULL, "INL"},
Adds DAPM muxing, routing for the PreDrive outputs.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 1da4617..c508344 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -203,6 +203,32 @@ static const struct soc_enum twl4030_earpiece_enum = static const struct snd_kcontrol_new twl4030_dapm_earpiece_control = SOC_DAPM_ENUM("Route", twl4030_earpiece_enum);
+/* PreDrive Left */ +static const char *twl4030_predrivel_texts[] = + {"Off", "DACL1", "DACL2", "Invalid", + "DACR2"}; + +static const struct soc_enum twl4030_predrivel_enum = + SOC_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, + ARRAY_SIZE(twl4030_predrivel_texts), + twl4030_predrivel_texts); + +static const struct snd_kcontrol_new twl4030_dapm_predrivel_control = +SOC_DAPM_ENUM("Route", twl4030_predrivel_enum); + +/* PreDrive Right */ +static const char *twl4030_predriver_texts[] = + {"Off", "DACR1", "DACR2", "Invalid", + "DACL2"}; + +static const struct soc_enum twl4030_predriver_enum = + SOC_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, + ARRAY_SIZE(twl4030_predriver_texts), + twl4030_predriver_texts); + +static const struct snd_kcontrol_new twl4030_dapm_predriver_control = +SOC_DAPM_ENUM("Route", twl4030_predriver_enum); + static int outmixer_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -659,6 +685,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("OUTL"), SND_SOC_DAPM_OUTPUT("OUTR"), SND_SOC_DAPM_OUTPUT("EARPIECE"), + SND_SOC_DAPM_OUTPUT("PREDRIVEL"), + SND_SOC_DAPM_OUTPUT("PREDRIVER"),
/* DACs */ SND_SOC_DAPM_DAC("DACR1", "Right Front Playback", @@ -685,6 +713,13 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_MUX_E("Earpiece Mux", SND_SOC_NOPM, 0, 0, &twl4030_dapm_earpiece_control, outmixer_event, SND_SOC_DAPM_PRE_REG), + /* PreDrivL/R */ + SND_SOC_DAPM_MUX_E("PredriveL Mux", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_predrivel_control, outmixer_event, + SND_SOC_DAPM_PRE_REG), + SND_SOC_DAPM_MUX_E("PredriveR Mux", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_predriver_control, outmixer_event, + SND_SOC_DAPM_PRE_REG),
SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0), @@ -701,11 +736,21 @@ static const struct snd_soc_dapm_route intercon[] = { {"Earpiece Mux", "DACL1", "ARXL1_APGA"}, {"Earpiece Mux", "DACL2", "ARXL2_APGA"}, {"Earpiece Mux", "DACR1", "ARXR1_APGA"}, + /* PreDrivL */ + {"PredriveL Mux", "DACL1", "ARXL1_APGA"}, + {"PredriveL Mux", "DACL2", "ARXL2_APGA"}, + {"PredriveL Mux", "DACR2", "ARXR2_APGA"}, + /* PreDrivR */ + {"PredriveR Mux", "DACR1", "ARXR1_APGA"}, + {"PredriveR Mux", "DACR2", "ARXR2_APGA"}, + {"PredriveR Mux", "DACL2", "ARXL2_APGA"},
/* outputs */ {"OUTL", NULL, "ARXL2_APGA"}, {"OUTR", NULL, "ARXR2_APGA"}, {"EARPIECE", NULL, "Earpiece Mux"}, + {"PREDRIVEL", NULL, "PredriveL Mux"}, + {"PREDRIVER", NULL, "PredriveR Mux"},
/* inputs */ {"ADCL", NULL, "INL"},
Adds DAPM muxing, routing for the Headset outputs.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 39 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index c508344..86ff5a9 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -229,6 +229,30 @@ static const struct soc_enum twl4030_predriver_enum = static const struct snd_kcontrol_new twl4030_dapm_predriver_control = SOC_DAPM_ENUM("Route", twl4030_predriver_enum);
+/* 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); + +/* 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 int outmixer_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -687,6 +711,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("EARPIECE"), SND_SOC_DAPM_OUTPUT("PREDRIVEL"), SND_SOC_DAPM_OUTPUT("PREDRIVER"), + SND_SOC_DAPM_OUTPUT("HSOL"), + SND_SOC_DAPM_OUTPUT("HSOR"),
/* DACs */ SND_SOC_DAPM_DAC("DACR1", "Right Front Playback", @@ -720,6 +746,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_MUX_E("PredriveR Mux", SND_SOC_NOPM, 0, 0, &twl4030_dapm_predriver_control, outmixer_event, SND_SOC_DAPM_PRE_REG), + /* HeadsetL/R */ + SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_hsol_control), + SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_hsor_control),
SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0), @@ -744,6 +775,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"PredriveR Mux", "DACR1", "ARXR1_APGA"}, {"PredriveR Mux", "DACR2", "ARXR2_APGA"}, {"PredriveR Mux", "DACL2", "ARXL2_APGA"}, + /* HeadsetL */ + {"HeadsetL Mux", "DACL1", "ARXL1_APGA"}, + {"HeadsetL Mux", "DACL2", "ARXL2_APGA"}, + /* HeadsetR */ + {"HeadsetR Mux", "DACR1", "ARXR1_APGA"}, + {"HeadsetR Mux", "DACR2", "ARXR2_APGA"},
/* outputs */ {"OUTL", NULL, "ARXL2_APGA"}, @@ -751,6 +788,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"EARPIECE", NULL, "Earpiece Mux"}, {"PREDRIVEL", NULL, "PredriveL Mux"}, {"PREDRIVER", NULL, "PredriveR Mux"}, + {"HSOL", NULL, "HeadsetL Mux"}, + {"HSOR", NULL, "HeadsetR Mux"},
/* inputs */ {"ADCL", NULL, "INL"},
Adds DAPM muxing, routing for the Carkit outputs.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 37 +++++++++++++++++++++++++++++++++++++ 1 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 86ff5a9..08c33e9 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -253,6 +253,30 @@ static const struct soc_enum twl4030_hsor_enum = static const struct snd_kcontrol_new twl4030_dapm_hsor_control = SOC_DAPM_ENUM("Route", twl4030_hsor_enum);
+/* 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); + +/* 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 int outmixer_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -751,6 +775,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { &twl4030_dapm_hsol_control), SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0, &twl4030_dapm_hsor_control), + /* 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_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0), @@ -781,6 +810,12 @@ static const struct snd_soc_dapm_route intercon[] = { /* HeadsetR */ {"HeadsetR Mux", "DACR1", "ARXR1_APGA"}, {"HeadsetR Mux", "DACR2", "ARXR2_APGA"}, + /* CarkitL */ + {"CarkitL Mux", "DACL1", "ARXL1_APGA"}, + {"CarkitL Mux", "DACL2", "ARXL2_APGA"}, + /* CarkitR */ + {"CarkitR Mux", "DACR1", "ARXR1_APGA"}, + {"CarkitR Mux", "DACR2", "ARXR2_APGA"},
/* outputs */ {"OUTL", NULL, "ARXL2_APGA"}, @@ -790,6 +825,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"PREDRIVER", NULL, "PredriveR Mux"}, {"HSOL", NULL, "HeadsetL Mux"}, {"HSOR", NULL, "HeadsetR Mux"}, + {"CARKITL", NULL, "CarkitL Mux"}, + {"CARKITR", NULL, "CarkitR Mux"},
/* inputs */ {"ADCL", NULL, "INL"},
Adds DAPM muxing, routing for the Handsfree outputs.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 08c33e9..d0612a4 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -277,6 +277,30 @@ static const struct soc_enum twl4030_carkitr_enum = static const struct snd_kcontrol_new twl4030_dapm_carkitr_control = SOC_DAPM_ENUM("Route", twl4030_carkitr_enum);
+/* Handsfree Left */ +static const char *twl4030_handsfreel_texts[] = + {"Voice", "DACL1", "DACL2", "DACR2"}; + +static const struct soc_enum twl4030_handsfreel_enum = + SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0, + ARRAY_SIZE(twl4030_handsfreel_texts), + twl4030_handsfreel_texts); + +static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control = +SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum); + +/* Handsfree Right */ +static const char *twl4030_handsfreer_texts[] = + {"Voice", "DACR1", "DACR2", "DACL2"}; + +static const struct soc_enum twl4030_handsfreer_enum = + SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0, + ARRAY_SIZE(twl4030_handsfreer_texts), + twl4030_handsfreer_texts); + +static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control = +SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum); + static int outmixer_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -737,6 +761,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("PREDRIVER"), SND_SOC_DAPM_OUTPUT("HSOL"), SND_SOC_DAPM_OUTPUT("HSOR"), + SND_SOC_DAPM_OUTPUT("HFL"), + SND_SOC_DAPM_OUTPUT("HFR"),
/* DACs */ SND_SOC_DAPM_DAC("DACR1", "Right Front Playback", @@ -780,6 +806,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { &twl4030_dapm_carkitl_control), SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0, &twl4030_dapm_carkitr_control), + /* HandsfreeL/R */ + SND_SOC_DAPM_MUX("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0, + &twl4030_dapm_handsfreel_control), + SND_SOC_DAPM_MUX("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0, + &twl4030_dapm_handsfreer_control),
SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0), @@ -816,6 +847,14 @@ static const struct snd_soc_dapm_route intercon[] = { /* CarkitR */ {"CarkitR Mux", "DACR1", "ARXR1_APGA"}, {"CarkitR Mux", "DACR2", "ARXR2_APGA"}, + /* HandsfreeL */ + {"HandsfreeL Mux", "DACL1", "ARXL1_APGA"}, + {"HandsfreeL Mux", "DACL2", "ARXL2_APGA"}, + {"HandsfreeL Mux", "DACR2", "ARXR2_APGA"}, + /* HandsfreeR */ + {"HandsfreeR Mux", "DACR1", "ARXR1_APGA"}, + {"HandsfreeR Mux", "DACR2", "ARXR2_APGA"}, + {"HandsfreeR Mux", "DACL2", "ARXL2_APGA"},
/* outputs */ {"OUTL", NULL, "ARXL2_APGA"}, @@ -827,6 +866,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"HSOR", NULL, "HeadsetR Mux"}, {"CARKITL", NULL, "CarkitL Mux"}, {"CARKITR", NULL, "CarkitR Mux"}, + {"HFL", NULL, "HandsfreeL Mux"}, + {"HFR", NULL, "HandsfreeR Mux"},
/* inputs */ {"ADCL", NULL, "INL"},
There is a separate gain control for the Headset output already. Do not reset the gain to 0 dB at power up. In power-down, there is no need to set the Headset output gain to power-down mode, since if the CODECPDZ is in powered off this setting has no effect.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com --- sound/soc/codecs/twl4030.c | 12 ++---------- 1 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index d0612a4..358aa2b 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -887,7 +887,7 @@ static int twl4030_add_widgets(struct snd_soc_codec *codec)
static void twl4030_power_up(struct snd_soc_codec *codec) { - u8 anamicl, regmisc1, byte, popn, hsgain; + u8 anamicl, regmisc1, byte, popn; int i = 0;
/* set CODECPDZ to turn on codec */ @@ -925,10 +925,6 @@ static void twl4030_power_up(struct snd_soc_codec *codec) popn |= TWL4030_VMID_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
- /* enable output stage and gain setting */ - hsgain = TWL4030_HSR_GAIN_0DB | TWL4030_HSL_GAIN_0DB; - twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hsgain); - /* enable anti-pop ramp */ popn |= TWL4030_RAMP_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn); @@ -936,17 +932,13 @@ static void twl4030_power_up(struct snd_soc_codec *codec)
static void twl4030_power_down(struct snd_soc_codec *codec) { - u8 popn, hsgain; + u8 popn;
/* disable anti-pop ramp */ popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); popn &= ~TWL4030_RAMP_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
- /* disable output stage and gain setting */ - hsgain = TWL4030_HSR_GAIN_PWR_DOWN | TWL4030_HSL_GAIN_PWR_DOWN; - twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hsgain); - /* disable bias out */ popn &= ~TWL4030_VMID_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
participants (2)
-
Mark Brown
-
Peter Ujfalusi