aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c108
1 files changed, 99 insertions, 9 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index e333b3e30e31..bddb1a28edc3 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1056,6 +1056,9 @@ static const struct snd_pci_quirk beep_white_list[] = {
SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
+ /* blacklist -- no beep available */
+ SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0),
+ SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0),
{}
};
@@ -2839,7 +2842,8 @@ static int patch_alc268(struct hda_codec *codec)
return err;
spec = codec->spec;
- spec->gen.beep_nid = 0x01;
+ if (has_cdefine_beep(codec))
+ spec->gen.beep_nid = 0x01;
spec->shutup = alc_eapd_shutup;
@@ -3753,6 +3757,72 @@ static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
vref);
}
+/*
+ * Magic sequence to make Huawei Matebook X right speaker working (bko#197801)
+ */
+struct hda_alc298_mbxinit {
+ unsigned char value_0x23;
+ unsigned char value_0x25;
+};
+
+static void alc298_huawei_mbx_stereo_seq(struct hda_codec *codec,
+ const struct hda_alc298_mbxinit *initval,
+ bool first)
+{
+ snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x0);
+ alc_write_coef_idx(codec, 0x26, 0xb000);
+
+ if (first)
+ snd_hda_codec_write(codec, 0x21, 0, AC_VERB_GET_PIN_SENSE, 0x0);
+
+ snd_hda_codec_write(codec, 0x6, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
+ alc_write_coef_idx(codec, 0x26, 0xf000);
+ alc_write_coef_idx(codec, 0x23, initval->value_0x23);
+
+ if (initval->value_0x23 != 0x1e)
+ alc_write_coef_idx(codec, 0x25, initval->value_0x25);
+
+ snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
+ snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
+}
+
+static void alc298_fixup_huawei_mbx_stereo(struct hda_codec *codec,
+ const struct hda_fixup *fix,
+ int action)
+{
+ /* Initialization magic */
+ static const struct hda_alc298_mbxinit dac_init[] = {
+ {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
+ {0x10, 0x00}, {0x1a, 0x40}, {0x1b, 0x82}, {0x1c, 0x00},
+ {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
+ {0x20, 0xc2}, {0x21, 0xc8}, {0x22, 0x26}, {0x23, 0x24},
+ {0x27, 0xff}, {0x28, 0xff}, {0x29, 0xff}, {0x2a, 0x8f},
+ {0x2b, 0x02}, {0x2c, 0x48}, {0x2d, 0x34}, {0x2e, 0x00},
+ {0x2f, 0x00},
+ {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
+ {0x34, 0x00}, {0x35, 0x01}, {0x36, 0x93}, {0x37, 0x0c},
+ {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0xf8}, {0x38, 0x80},
+ {}
+ };
+ const struct hda_alc298_mbxinit *seq;
+
+ if (action != HDA_FIXUP_ACT_INIT)
+ return;
+
+ /* Start */
+ snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x00);
+ snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
+ alc_write_coef_idx(codec, 0x26, 0xf000);
+ alc_write_coef_idx(codec, 0x22, 0x31);
+ alc_write_coef_idx(codec, 0x23, 0x0b);
+ alc_write_coef_idx(codec, 0x25, 0x00);
+ snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
+ snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
+
+ for (seq = dac_init; seq->value_0x23; seq++)
+ alc298_huawei_mbx_stereo_seq(codec, seq, seq == dac_init);
+}
+
static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
@@ -5778,6 +5848,7 @@ enum {
ALC255_FIXUP_DUMMY_LINEOUT_VERB,
ALC255_FIXUP_DELL_HEADSET_MIC,
ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
+ ALC298_FIXUP_HUAWEI_MBX_STEREO,
ALC295_FIXUP_HP_X360,
ALC221_FIXUP_HP_HEADSET_MIC,
ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
@@ -6086,6 +6157,12 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC255_FIXUP_MIC_MUTE_LED
},
+ [ALC298_FIXUP_HUAWEI_MBX_STEREO] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc298_fixup_huawei_mbx_stereo,
+ .chained = true,
+ .chain_id = ALC255_FIXUP_MIC_MUTE_LED
+ },
[ALC269_FIXUP_ASUS_X101_FUNC] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc269_fixup_x101_headset_mic,
@@ -7264,6 +7341,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
{.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
{.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
+ {.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
{}
};
#define ALC225_STANDARD_PINS \
@@ -7574,10 +7652,6 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
{0x12, 0x90a60120},
{0x14, 0x90170110},
{0x21, 0x0321101f}),
- SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
- {0x12, 0xb7a60130},
- {0x14, 0x90170110},
- {0x21, 0x04211020}),
SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
ALC290_STANDARD_PINS,
{0x15, 0x04211040},
@@ -7687,6 +7761,19 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
{}
};
+/* This is the fallback pin_fixup_tbl for alc269 family, to make the tbl match
+ * more machines, don't need to match all valid pins, just need to match
+ * all the pins defined in the tbl. Just because of this reason, it is possible
+ * that a single machine matches multiple tbls, so there is one limitation:
+ * at most one tbl is allowed to define for the same vendor and same codec
+ */
+static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
+ SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
+ {0x19, 0x40000000},
+ {0x1b, 0x40000000}),
+ {}
+};
+
static void alc269_fill_coef(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -7876,7 +7963,8 @@ static int patch_alc269(struct hda_codec *codec)
snd_hda_pick_fixup(codec, alc269_fixup_models,
alc269_fixup_tbl, alc269_fixups);
- snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
+ snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups, true);
+ snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false);
snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
alc269_fixups);
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -8010,7 +8098,8 @@ static int patch_alc861(struct hda_codec *codec)
return err;
spec = codec->spec;
- spec->gen.beep_nid = 0x23;
+ if (has_cdefine_beep(codec))
+ spec->gen.beep_nid = 0x23;
#ifdef CONFIG_PM
spec->power_hook = alc_power_eapd;
@@ -8111,7 +8200,8 @@ static int patch_alc861vd(struct hda_codec *codec)
return err;
spec = codec->spec;
- spec->gen.beep_nid = 0x23;
+ if (has_cdefine_beep(codec))
+ spec->gen.beep_nid = 0x23;
spec->shutup = alc_eapd_shutup;
@@ -8861,7 +8951,7 @@ static int patch_alc662(struct hda_codec *codec)
snd_hda_pick_fixup(codec, alc662_fixup_models,
alc662_fixup_tbl, alc662_fixups);
- snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
+ snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups, true);
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
alc_auto_parse_customize_define(codec);