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); > + ret = snd_soc_dapm_enable_pin(&card->dapm, pin); > else > - 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 >