Hi Takashi,
On 10/3/21 4:46 PM, Takashi Iwai wrote:
On Sun, 03 Oct 2021 15:12:57 +0200, Hans de Goede wrote:
Hi All,
I notice that DAPM PIN switches, such as e.g. the "Headphone" SOC_DAPM_PIN_SWITCH defined in: sound/soc/intel/boards/cht_bsw_nau8824.c:
static const struct snd_kcontrol_new cht_mc_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), SOC_DAPM_PIN_SWITCH("Int Mic"), SOC_DAPM_PIN_SWITCH("Ext Spk"), };
Do not get updated to reflect state-changes when the output is switched between e.g. Headphone / "Ext Spk" by pulseaudio/pipewire through the UCM profile mechanism.
If I exit alsa-mixer after changing the output and start it again then the control does show the expect value. So it seems that we are failing to send a change event about this somewhere?
Does the patch below work?
Thank you for the quick response.
This works for the "Speaker" DAPM PIN switch on a rt5640 board:
static const struct snd_kcontrol_new byt_rt5640_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), SOC_DAPM_PIN_SWITCH("Headset Mic 2"), SOC_DAPM_PIN_SWITCH("Internal Mic"), SOC_DAPM_PIN_SWITCH("Speaker"), SOC_DAPM_PIN_SWITCH("Line Out"), };
But it does not work for the "Headphone" and "Line Out" switches, these are actually hooked up to jack-detect, so I guess that the jack-detection is already flipping them and then when the UCM profile changes them it is a no-op causing the UCM setting of the control to not cause an event because it is not a change.
Relevant jack-detect bits from sound/soc/intel/boards/bytcr_rt5640.c:
static struct snd_soc_jack_pin rt5640_pins[] = { { .pin = "Headphone", .mask = SND_JACK_HEADPHONE, }, { .pin = "Headset Mic", .mask = SND_JACK_MICROPHONE, }, };
static struct snd_soc_jack_pin rt5640_pins2[] = { { /* The 2nd headset jack uses lineout with an external HP-amp */ .pin = "Line Out", .mask = SND_JACK_HEADPHONE, }, { .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, }, };
ret = snd_soc_card_jack_new(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, &priv->jack, rt5640_pins, ARRAY_SIZE(rt5640_pins));
ret = snd_soc_card_jack_new(card, "Headset 2", SND_JACK_HEADSET, &priv->jack2, rt5640_pins2, ARRAY_SIZE(rt5640_pins2));
I tried both jacks a HP Elitepad 1000G2 with dock (one on the tablet and one on the dock).
With your patch the SOC_DAPM_PIN_SWITCH("Speaker") control correctly updates (which it did not do before). But the "Line Out" (used for the second headset jack) and the "Headphone" controls do not update.
(exiting alsa-mixer and starting it again does show the "Line Out" and "Headphone" controls have changed.
Regards,
Hans
--- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2561,6 +2561,7 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, const char *pin, int status) { struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
int ret = 0;
dapm_assert_locked(dapm);
@@ -2573,13 +2574,14 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, dapm_mark_dirty(w, "pin configuration"); dapm_widget_invalidate_input_paths(w); dapm_widget_invalidate_output_paths(w);
ret = 1;
}
w->connected = status; if (status == 0) w->force = 0;
- return 0;
- return ret;
}
/** @@ -3583,14 +3585,15 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); const char *pin = (const char *)kcontrol->private_value;
int ret;
if (ucontrol->value.integer.value[0])
snd_soc_dapm_enable_pin(&card->dapm, pin);
elseret = snd_soc_dapm_enable_pin(&card->dapm, pin);
snd_soc_dapm_disable_pin(&card->dapm, pin);
ret = snd_soc_dapm_disable_pin(&card->dapm, pin);
snd_soc_dapm_sync(&card->dapm);
- return 0;
- return ret;
} EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
@@ -4023,7 +4026,7 @@ static int snd_soc_dapm_dai_link_put(struct snd_kcontrol *kcontrol,
rtd->params_select = ucontrol->value.enumerated.item[0];
- return 0;
- return 1;
}
static void