diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-01-22 12:18:42 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-01-22 15:20:39 -0500 |
commit | a928bd2c565c30e5906d1ddfc21177173b2eef49 (patch) | |
tree | 5f288d007b946cd1297801186dfebff18ab08596 /sound/pci/hda/patch_analog.c | |
parent | 9ff4bc8f72751d225f457c05f856657091573a16 (diff) |
ALSA: hda - Convert some static quirks to fixup codes for AD codecs
Other remaining quirks are mostly resolvable via pincfg fixes, even if
it matters.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_analog.c')
-rw-r--r-- | sound/pci/hda/patch_analog.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 98cbc983435a..9692265eef33 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -40,6 +40,7 @@ struct ad198x_spec { | |||
40 | /* for auto parser */ | 40 | /* for auto parser */ |
41 | int smux_paths[4]; | 41 | int smux_paths[4]; |
42 | unsigned int cur_smux; | 42 | unsigned int cur_smux; |
43 | hda_nid_t eapd_nid; | ||
43 | 44 | ||
44 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | 45 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ |
45 | hda_nid_t beep_dev_nid; | 46 | hda_nid_t beep_dev_nid; |
@@ -1196,6 +1197,34 @@ static int alloc_ad_spec(struct hda_codec *codec) | |||
1196 | } | 1197 | } |
1197 | 1198 | ||
1198 | /* | 1199 | /* |
1200 | * AD1986A fixup codes | ||
1201 | */ | ||
1202 | |||
1203 | /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */ | ||
1204 | static void ad_fixup_inv_jack_detect(struct hda_codec *codec, | ||
1205 | const struct hda_fixup *fix, int action) | ||
1206 | { | ||
1207 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
1208 | codec->inv_jack_detect = 1; | ||
1209 | } | ||
1210 | |||
1211 | enum { | ||
1212 | AD1986A_FIXUP_INV_JACK_DETECT, | ||
1213 | }; | ||
1214 | |||
1215 | static const struct hda_fixup ad1986a_fixups[] = { | ||
1216 | [AD1986A_FIXUP_INV_JACK_DETECT] = { | ||
1217 | .type = HDA_FIXUP_FUNC, | ||
1218 | .v.func = ad_fixup_inv_jack_detect, | ||
1219 | }, | ||
1220 | }; | ||
1221 | |||
1222 | static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { | ||
1223 | SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT), | ||
1224 | {} | ||
1225 | }; | ||
1226 | |||
1227 | /* | ||
1199 | */ | 1228 | */ |
1200 | static int ad1986a_parse_auto_config(struct hda_codec *codec) | 1229 | static int ad1986a_parse_auto_config(struct hda_codec *codec) |
1201 | { | 1230 | { |
@@ -1222,12 +1251,17 @@ static int ad1986a_parse_auto_config(struct hda_codec *codec) | |||
1222 | */ | 1251 | */ |
1223 | spec->gen.multiout.no_share_stream = 1; | 1252 | spec->gen.multiout.no_share_stream = 1; |
1224 | 1253 | ||
1254 | snd_hda_pick_fixup(codec, NULL, ad1986a_fixup_tbl, ad1986a_fixups); | ||
1255 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | ||
1256 | |||
1225 | err = ad198x_parse_auto_config(codec); | 1257 | err = ad198x_parse_auto_config(codec); |
1226 | if (err < 0) { | 1258 | if (err < 0) { |
1227 | ad198x_free(codec); | 1259 | ad198x_free(codec); |
1228 | return err; | 1260 | return err; |
1229 | } | 1261 | } |
1230 | 1262 | ||
1263 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | ||
1264 | |||
1231 | return 0; | 1265 | return 0; |
1232 | } | 1266 | } |
1233 | 1267 | ||
@@ -2068,6 +2102,68 @@ static const struct snd_pci_quirk ad1981_cfg_tbl[] = { | |||
2068 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | 2102 | #endif /* ENABLE_AD_STATIC_QUIRKS */ |
2069 | 2103 | ||
2070 | 2104 | ||
2105 | /* follow EAPD via vmaster hook */ | ||
2106 | static void ad_vmaster_eapd_hook(void *private_data, int enabled) | ||
2107 | { | ||
2108 | struct hda_codec *codec = private_data; | ||
2109 | struct ad198x_spec *spec = codec->spec; | ||
2110 | snd_hda_codec_update_cache(codec, spec->eapd_nid, 0, | ||
2111 | AC_VERB_SET_EAPD_BTLENABLE, | ||
2112 | enabled ? 0x02 : 0x00); | ||
2113 | } | ||
2114 | |||
2115 | static void ad1981_fixup_hp_eapd(struct hda_codec *codec, | ||
2116 | const struct hda_fixup *fix, int action) | ||
2117 | { | ||
2118 | struct ad198x_spec *spec = codec->spec; | ||
2119 | |||
2120 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
2121 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; | ||
2122 | spec->eapd_nid = 0x05; | ||
2123 | } | ||
2124 | } | ||
2125 | |||
2126 | /* set the upper-limit for mixer amp to 0dB for avoiding the possible | ||
2127 | * damage by overloading | ||
2128 | */ | ||
2129 | static void ad1981_fixup_amp_override(struct hda_codec *codec, | ||
2130 | const struct hda_fixup *fix, int action) | ||
2131 | { | ||
2132 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
2133 | snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, | ||
2134 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | ||
2135 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
2136 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
2137 | (1 << AC_AMPCAP_MUTE_SHIFT)); | ||
2138 | } | ||
2139 | |||
2140 | enum { | ||
2141 | AD1981_FIXUP_AMP_OVERRIDE, | ||
2142 | AD1981_FIXUP_HP_EAPD, | ||
2143 | }; | ||
2144 | |||
2145 | static const struct hda_fixup ad1981_fixups[] = { | ||
2146 | [AD1981_FIXUP_AMP_OVERRIDE] = { | ||
2147 | .type = HDA_FIXUP_FUNC, | ||
2148 | .v.func = ad1981_fixup_amp_override, | ||
2149 | }, | ||
2150 | [AD1981_FIXUP_HP_EAPD] = { | ||
2151 | .type = HDA_FIXUP_FUNC, | ||
2152 | .v.func = ad1981_fixup_hp_eapd, | ||
2153 | .chained = true, | ||
2154 | .chain_id = AD1981_FIXUP_AMP_OVERRIDE, | ||
2155 | }, | ||
2156 | }; | ||
2157 | |||
2158 | static const struct snd_pci_quirk ad1981_fixup_tbl[] = { | ||
2159 | SND_PCI_QUIRK_VENDOR(0x1014, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE), | ||
2160 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1981_FIXUP_HP_EAPD), | ||
2161 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE), | ||
2162 | /* HP nx6320 (reversed SSID, H/W bug) */ | ||
2163 | SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_FIXUP_HP_EAPD), | ||
2164 | {} | ||
2165 | }; | ||
2166 | |||
2071 | static int ad1981_parse_auto_config(struct hda_codec *codec) | 2167 | static int ad1981_parse_auto_config(struct hda_codec *codec) |
2072 | { | 2168 | { |
2073 | struct ad198x_spec *spec; | 2169 | struct ad198x_spec *spec; |
@@ -2081,12 +2177,19 @@ static int ad1981_parse_auto_config(struct hda_codec *codec) | |||
2081 | spec->gen.mixer_nid = 0x0e; | 2177 | spec->gen.mixer_nid = 0x0e; |
2082 | spec->beep_dev_nid = 0x10; | 2178 | spec->beep_dev_nid = 0x10; |
2083 | set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); | 2179 | set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); |
2180 | |||
2181 | snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups); | ||
2182 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | ||
2183 | |||
2084 | err = ad198x_parse_auto_config(codec); | 2184 | err = ad198x_parse_auto_config(codec); |
2085 | if (err < 0) | 2185 | if (err < 0) |
2086 | goto error; | 2186 | goto error; |
2087 | err = ad1983_add_spdif_mux_ctl(codec); | 2187 | err = ad1983_add_spdif_mux_ctl(codec); |
2088 | if (err < 0) | 2188 | if (err < 0) |
2089 | goto error; | 2189 | goto error; |
2190 | |||
2191 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | ||
2192 | |||
2090 | return 0; | 2193 | return 0; |
2091 | 2194 | ||
2092 | error: | 2195 | error: |
@@ -3466,6 +3569,60 @@ static const char * const ad1884_models[AD1884_MODELS] = { | |||
3466 | }; | 3569 | }; |
3467 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | 3570 | #endif /* ENABLE_AD_STATIC_QUIRKS */ |
3468 | 3571 | ||
3572 | |||
3573 | /* set the upper-limit for mixer amp to 0dB for avoiding the possible | ||
3574 | * damage by overloading | ||
3575 | */ | ||
3576 | static void ad1884_fixup_amp_override(struct hda_codec *codec, | ||
3577 | const struct hda_fixup *fix, int action) | ||
3578 | { | ||
3579 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
3580 | snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, | ||
3581 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | ||
3582 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
3583 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
3584 | (1 << AC_AMPCAP_MUTE_SHIFT)); | ||
3585 | } | ||
3586 | |||
3587 | static void ad1884_fixup_hp_eapd(struct hda_codec *codec, | ||
3588 | const struct hda_fixup *fix, int action) | ||
3589 | { | ||
3590 | struct ad198x_spec *spec = codec->spec; | ||
3591 | |||
3592 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3593 | if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
3594 | spec->eapd_nid = spec->gen.autocfg.line_out_pins[0]; | ||
3595 | else | ||
3596 | spec->eapd_nid = spec->gen.autocfg.speaker_pins[0]; | ||
3597 | if (spec->eapd_nid) | ||
3598 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; | ||
3599 | } | ||
3600 | } | ||
3601 | |||
3602 | enum { | ||
3603 | AD1884_FIXUP_AMP_OVERRIDE, | ||
3604 | AD1884_FIXUP_HP_EAPD, | ||
3605 | }; | ||
3606 | |||
3607 | static const struct hda_fixup ad1884_fixups[] = { | ||
3608 | [AD1884_FIXUP_AMP_OVERRIDE] = { | ||
3609 | .type = HDA_FIXUP_FUNC, | ||
3610 | .v.func = ad1884_fixup_amp_override, | ||
3611 | }, | ||
3612 | [AD1884_FIXUP_HP_EAPD] = { | ||
3613 | .type = HDA_FIXUP_FUNC, | ||
3614 | .v.func = ad1884_fixup_hp_eapd, | ||
3615 | .chained = true, | ||
3616 | .chain_id = AD1884_FIXUP_AMP_OVERRIDE, | ||
3617 | }, | ||
3618 | }; | ||
3619 | |||
3620 | static const struct snd_pci_quirk ad1884_fixup_tbl[] = { | ||
3621 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD), | ||
3622 | {} | ||
3623 | }; | ||
3624 | |||
3625 | |||
3469 | static int ad1884_parse_auto_config(struct hda_codec *codec) | 3626 | static int ad1884_parse_auto_config(struct hda_codec *codec) |
3470 | { | 3627 | { |
3471 | struct ad198x_spec *spec; | 3628 | struct ad198x_spec *spec; |
@@ -3479,12 +3636,19 @@ static int ad1884_parse_auto_config(struct hda_codec *codec) | |||
3479 | spec->gen.mixer_nid = 0x20; | 3636 | spec->gen.mixer_nid = 0x20; |
3480 | spec->beep_dev_nid = 0x10; | 3637 | spec->beep_dev_nid = 0x10; |
3481 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 3638 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
3639 | |||
3640 | snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups); | ||
3641 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | ||
3642 | |||
3482 | err = ad198x_parse_auto_config(codec); | 3643 | err = ad198x_parse_auto_config(codec); |
3483 | if (err < 0) | 3644 | if (err < 0) |
3484 | goto error; | 3645 | goto error; |
3485 | err = ad1983_add_spdif_mux_ctl(codec); | 3646 | err = ad1983_add_spdif_mux_ctl(codec); |
3486 | if (err < 0) | 3647 | if (err < 0) |
3487 | goto error; | 3648 | goto error; |
3649 | |||
3650 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | ||
3651 | |||
3488 | return 0; | 3652 | return 0; |
3489 | 3653 | ||
3490 | error: | 3654 | error: |