Merge remote-tracking branches 'asoc/fix/blackfin', 'asoc/fix/da9055', 'asoc/fix...
[firefly-linux-kernel-4.4.55.git] / sound / pci / hda / patch_analog.c
index 699262a3e07abcd9558bb538de0916d96bc63bcd..df3652ad15ef36224fdbc121ee1018116bab28c0 100644 (file)
@@ -185,7 +185,7 @@ static const struct hda_codec_ops ad198x_auto_patch_ops = {
 };
 
 
-static int ad198x_parse_auto_config(struct hda_codec *codec)
+static int ad198x_parse_auto_config(struct hda_codec *codec, bool indep_hp)
 {
        struct ad198x_spec *spec = codec->spec;
        struct auto_pin_cfg *cfg = &spec->gen.autocfg;
@@ -195,7 +195,8 @@ static int ad198x_parse_auto_config(struct hda_codec *codec)
        codec->no_trigger_sense = 1;
        codec->no_sticky_stream = 1;
 
-       spec->gen.indep_hp = 1;
+       spec->gen.indep_hp = indep_hp;
+       spec->gen.add_stereo_mix_input = 1;
 
        err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
        if (err < 0)
@@ -243,6 +244,19 @@ static void ad_fixup_inv_jack_detect(struct hda_codec *codec,
        }
 }
 
+/* Toshiba Satellite L40 implements EAPD in a standard way unlike others */
+static void ad1986a_fixup_eapd(struct hda_codec *codec,
+                              const struct hda_fixup *fix, int action)
+{
+       struct ad198x_spec *spec = codec->spec;
+
+       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               codec->inv_eapd = 0;
+               spec->gen.keep_eapd_on = 1;
+               spec->eapd_nid = 0x1b;
+       }
+}
+
 enum {
        AD1986A_FIXUP_INV_JACK_DETECT,
        AD1986A_FIXUP_ULTRA,
@@ -250,6 +264,7 @@ enum {
        AD1986A_FIXUP_3STACK,
        AD1986A_FIXUP_LAPTOP,
        AD1986A_FIXUP_LAPTOP_IMIC,
+       AD1986A_FIXUP_EAPD,
 };
 
 static const struct hda_fixup ad1986a_fixups[] = {
@@ -280,11 +295,11 @@ static const struct hda_fixup ad1986a_fixups[] = {
                .v.pins = (const struct hda_pintbl[]) {
                        { 0x1a, 0x02214021 }, /* headphone */
                        { 0x1b, 0x01014011 }, /* front */
-                       { 0x1c, 0x01013012 }, /* surround */
-                       { 0x1d, 0x01019015 }, /* clfe */
+                       { 0x1c, 0x01813030 }, /* line-in */
+                       { 0x1d, 0x01a19020 }, /* rear mic */
                        { 0x1e, 0x411111f0 }, /* N/A */
                        { 0x1f, 0x02a190f0 }, /* mic */
-                       { 0x20, 0x018130f0 }, /* line-in */
+                       { 0x20, 0x411111f0 }, /* N/A */
                        {}
                },
        },
@@ -310,6 +325,10 @@ static const struct hda_fixup ad1986a_fixups[] = {
                .chained_before = 1,
                .chain_id = AD1986A_FIXUP_LAPTOP,
        },
+       [AD1986A_FIXUP_EAPD] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = ad1986a_fixup_eapd,
+       },
 };
 
 static const struct snd_pci_quirk ad1986a_fixup_tbl[] = {
@@ -317,6 +336,7 @@ static const struct snd_pci_quirk ad1986a_fixup_tbl[] = {
        SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK),
        SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK),
        SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK),
+       SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40", AD1986A_FIXUP_EAPD),
        SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP),
        SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG),
        SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA),
@@ -378,7 +398,7 @@ static int patch_ad1986a(struct hda_codec *codec)
                           ad1986a_fixups);
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
 
-       err = ad198x_parse_auto_config(codec);
+       err = ad198x_parse_auto_config(codec, false);
        if (err < 0) {
                snd_hda_gen_free(codec);
                return err;
@@ -471,6 +491,8 @@ static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec)
 static int patch_ad1983(struct hda_codec *codec)
 {
        struct ad198x_spec *spec;
+       static hda_nid_t conn_0c[] = { 0x08 };
+       static hda_nid_t conn_0d[] = { 0x09 };
        int err;
 
        err = alloc_ad_spec(codec);
@@ -478,9 +500,15 @@ static int patch_ad1983(struct hda_codec *codec)
                return err;
        spec = codec->spec;
 
+       spec->gen.mixer_nid = 0x0e;
        spec->gen.beep_nid = 0x10;
        set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
-       err = ad198x_parse_auto_config(codec);
+
+       /* limit the loopback routes not to confuse the parser */
+       snd_hda_override_conn_list(codec, 0x0c, ARRAY_SIZE(conn_0c), conn_0c);
+       snd_hda_override_conn_list(codec, 0x0d, ARRAY_SIZE(conn_0d), conn_0d);
+
+       err = ad198x_parse_auto_config(codec, false);
        if (err < 0)
                goto error;
        err = ad1983_add_spdif_mux_ctl(codec);
@@ -567,7 +595,7 @@ static int patch_ad1981(struct hda_codec *codec)
        snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups);
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
 
-       err = ad198x_parse_auto_config(codec);
+       err = ad198x_parse_auto_config(codec, false);
        if (err < 0)
                goto error;
        err = ad1983_add_spdif_mux_ctl(codec);
@@ -893,7 +921,7 @@ static int patch_ad1988(struct hda_codec *codec)
        snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups);
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
 
-       err = ad198x_parse_auto_config(codec);
+       err = ad198x_parse_auto_config(codec, true);
        if (err < 0)
                goto error;
        err = ad1988_add_spdif_mux_ctl(codec);
@@ -1070,7 +1098,7 @@ static int patch_ad1884(struct hda_codec *codec)
        snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups);
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
 
-       err = ad198x_parse_auto_config(codec);
+       err = ad198x_parse_auto_config(codec, true);
        if (err < 0)
                goto error;
        err = ad1983_add_spdif_mux_ctl(codec);
@@ -1112,7 +1140,7 @@ static int patch_ad1882(struct hda_codec *codec)
        spec->gen.mixer_merge_nid = 0x21;
        spec->gen.beep_nid = 0x10;
        set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
-       err = ad198x_parse_auto_config(codec);
+       err = ad198x_parse_auto_config(codec, true);
        if (err < 0)
                goto error;
        err = ad1988_add_spdif_mux_ctl(codec);