]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: hda/analog: Fix GPIO verb orders
authorTakashi Iwai <tiwai@suse.de>
Thu, 9 Apr 2026 09:38:18 +0000 (11:38 +0200)
committerTakashi Iwai <tiwai@suse.de>
Thu, 9 Apr 2026 10:05:54 +0000 (12:05 +0200)
So far we used the verb cache to restore the GPIO mask, direction and
data bits at PM resume.  But, due to the nature of the cache resume
mechanism, the calling order isn't guaranteed, and this might lead to
some inconsistency at the restored state.

For assuring the GPIO verb orders, use the new GPIO helper function to
explicitly set up the GPIO bits, instead of using the codec verb
caches, while keeping the current data bits in ad198x_spec.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260409093826.1317626-6-tiwai@suse.de
sound/hda/codecs/analog.c

index 11b1d30b23fdf63022b58a7cf0e3b7845af46747..1ba8ae54e25ed261961dbd3ce590bd7ac53bda41 100644 (file)
@@ -38,6 +38,8 @@ struct ad198x_spec {
 
        unsigned int beep_amp;  /* beep amp value, set via set_beep_amp() */
        int num_smux_conns;
+
+       unsigned int gpio_data;
 };
 
 
@@ -934,9 +936,9 @@ static void ad1884_vmaster_hp_gpio_hook(void *private_data, int enabled)
 
        if (spec->eapd_nid)
                ad_vmaster_eapd_hook(private_data, enabled);
-       snd_hda_codec_write_cache(codec, 0x01, 0,
-                                  AC_VERB_SET_GPIO_DATA,
-                                  enabled ? 0x00 : 0x02);
+       spec->gpio_data = enabled ? 0x00 : 0x02;
+       snd_hda_codec_write(codec, 0x01, 0,
+                           AC_VERB_SET_GPIO_DATA, spec->gpio_data);
 }
 
 static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
@@ -948,12 +950,7 @@ static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
        case HDA_FIXUP_ACT_PRE_PROBE:
                spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook;
                spec->gen.own_eapd_ctl = 1;
-               snd_hda_codec_write_cache(codec, 0x01, 0,
-                                         AC_VERB_SET_GPIO_MASK, 0x02);
-               snd_hda_codec_write_cache(codec, 0x01, 0,
-                                         AC_VERB_SET_GPIO_DIRECTION, 0x02);
-               snd_hda_codec_write_cache(codec, 0x01, 0,
-                                         AC_VERB_SET_GPIO_DATA, 0x02);
+               spec->gpio_data = 0x02;
                break;
        case HDA_FIXUP_ACT_PROBE:
                if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
@@ -961,6 +958,9 @@ static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
                else
                        spec->eapd_nid = spec->gen.autocfg.speaker_pins[0];
                break;
+       case HDA_FIXUP_ACT_INIT:
+               snd_hda_codec_set_gpio(codec, 0x02, 0x02, spec->gpio_data, 0);
+               break;
        }
 }