ALSA: hda/realtek – Update headset mode for ALC256 [Linux 4.14.128]

ALSA: hda/realtek – Update headset mode for ALC256 [Linux 4.14.128]

This Linux kernel change "ALSA: hda/realtek – Update headset mode for ALC256" is included in the Linux 4.14.128 release. This change is authored by Kailang Yang <kailang [at] realtek.com> on Fri May 31 17:16:53 2019 +0800. The commit for this change in Linux stable tree is f0666b6 (patch) which is from upstream commit 717f43d. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 717f43d.

ALSA: hda/realtek - Update headset mode for ALC256

commit 717f43d81afc1250300479075952a0e36d74ded3 upstream.

ALC255 and ALC256 were some difference for hidden register.
This update was suitable for ALC256.

Fixes: e69e7e03ed22 ("ALSA: hda/realtek - ALC256 speaker noise issue")
Signed-off-by: Kailang Yang <kailang@realtek.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

There are 75 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 sound/pci/hda/patch_realtek.c | 75 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 60 insertions(+), 15 deletions(-)

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index a9e3ee2..6d06f5d 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -3936,18 +3936,19 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
 static void alc_headset_mode_unplugged(struct hda_codec *codec)
 {
    static struct coef_fw coef0255[] = {
+       WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
        WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
        UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
        WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
        WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
        {}
    };
-   static struct coef_fw coef0255_1[] = {
-       WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
-       {}
-   };
    static struct coef_fw coef0256[] = {
        WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
+       WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
+       WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
+       WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
+       UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
        {}
    };
    static struct coef_fw coef0233[] = {
@@ -4010,13 +4011,11 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)

    switch (codec->core.vendor_id) {
    case 0x10ec0255:
-       alc_process_coef_fw(codec, coef0255_1);
        alc_process_coef_fw(codec, coef0255);
        break;
    case 0x10ec0236:
    case 0x10ec0256:
        alc_process_coef_fw(codec, coef0256);
-       alc_process_coef_fw(codec, coef0255);
        break;
    case 0x10ec0234:
    case 0x10ec0274:
@@ -4066,6 +4065,12 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
        WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
        {}
    };
+   static struct coef_fw coef0256[] = {
+       UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
+       WRITE_COEFEX(0x57, 0x03, 0x09a3),
+       WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
+       {}
+   };
    static struct coef_fw coef0233[] = {
        UPDATE_COEF(0x35, 0, 1<<14),
        WRITE_COEF(0x06, 0x2100),
@@ -4113,14 +4118,19 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
    };

    switch (codec->core.vendor_id) {
-   case 0x10ec0236:
    case 0x10ec0255:
-   case 0x10ec0256:
        alc_write_coef_idx(codec, 0x45, 0xc489);
        snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
        alc_process_coef_fw(codec, coef0255);
        snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
        break;
+   case 0x10ec0236:
+   case 0x10ec0256:
+       alc_write_coef_idx(codec, 0x45, 0xc489);
+       snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
+       alc_process_coef_fw(codec, coef0256);
+       snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
+       break;
    case 0x10ec0234:
    case 0x10ec0274:
    case 0x10ec0294:
@@ -4199,6 +4209,14 @@ static void alc_headset_mode_default(struct hda_codec *codec)
        WRITE_COEF(0x49, 0x0049),
        {}
    };
+   static struct coef_fw coef0256[] = {
+       WRITE_COEF(0x45, 0xc489),
+       WRITE_COEFEX(0x57, 0x03, 0x0da3),
+       WRITE_COEF(0x49, 0x0049),
+       UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
+       WRITE_COEF(0x06, 0x6100),
+       {}
+   };
    static struct coef_fw coef0233[] = {
        WRITE_COEF(0x06, 0x2100),
        WRITE_COEF(0x32, 0x4ea3),
@@ -4246,11 +4264,16 @@ static void alc_headset_mode_default(struct hda_codec *codec)
        alc_process_coef_fw(codec, alc225_pre_hsmode);
        alc_process_coef_fw(codec, coef0225);
        break;
-   case 0x10ec0236:
    case 0x10ec0255:
-   case 0x10ec0256:
        alc_process_coef_fw(codec, coef0255);
        break;
+   case 0x10ec0236:
+   case 0x10ec0256:
+       alc_write_coef_idx(codec, 0x1b, 0x0e4b);
+       alc_write_coef_idx(codec, 0x45, 0xc089);
+       msleep(50);
+       alc_process_coef_fw(codec, coef0256);
+       break;
    case 0x10ec0234:
    case 0x10ec0274:
    case 0x10ec0294:
@@ -4294,8 +4317,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
    };
    static struct coef_fw coef0256[] = {
        WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
-       WRITE_COEF(0x1b, 0x0c6b),
-       WRITE_COEFEX(0x57, 0x03, 0x8ea6),
+       WRITE_COEF(0x1b, 0x0e6b),
        {}
    };
    static struct coef_fw coef0233[] = {
@@ -4410,8 +4432,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
    };
    static struct coef_fw coef0256[] = {
        WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
-       WRITE_COEF(0x1b, 0x0c6b),
-       WRITE_COEFEX(0x57, 0x03, 0x8ea6),
+       WRITE_COEF(0x1b, 0x0e6b),
        {}
    };
    static struct coef_fw coef0233[] = {
@@ -4540,13 +4561,37 @@ static void alc_determine_headset_type(struct hda_codec *codec)
    };

    switch (codec->core.vendor_id) {
-   case 0x10ec0236:
    case 0x10ec0255:
+       alc_process_coef_fw(codec, coef0255);
+       msleep(300);
+       val = alc_read_coef_idx(codec, 0x46);
+       is_ctia = (val & 0x0070) == 0x0070;
+       break;
+   case 0x10ec0236:
    case 0x10ec0256:
+       alc_write_coef_idx(codec, 0x1b, 0x0e4b);
+       alc_write_coef_idx(codec, 0x06, 0x6104);
+       alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
+
+       snd_hda_codec_write(codec, 0x21, 0,
+               AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+       msleep(80);
+       snd_hda_codec_write(codec, 0x21, 0,
+               AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
+
        alc_process_coef_fw(codec, coef0255);
        msleep(300);
        val = alc_read_coef_idx(codec, 0x46);
        is_ctia = (val & 0x0070) == 0x0070;
+
+       alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
+       alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
+
+       snd_hda_codec_write(codec, 0x21, 0,
+               AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+       msleep(80);
+       snd_hda_codec_write(codec, 0x21, 0,
+               AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
        break;
    case 0x10ec0234:
    case 0x10ec0274:

Leave a Reply

Your email address will not be published. Required fields are marked *