diff options
-rw-r--r-- | sound/pci/hda/hda_intel.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 31 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 105 | ||||
-rw-r--r-- | sound/usb/mixer_quirks.c | 6 |
4 files changed, 116 insertions, 30 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9ab1e631cb32..16660f312043 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -219,6 +219,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
219 | "{Intel, LPT_LP}," | 219 | "{Intel, LPT_LP}," |
220 | "{Intel, WPT_LP}," | 220 | "{Intel, WPT_LP}," |
221 | "{Intel, SPT}," | 221 | "{Intel, SPT}," |
222 | "{Intel, SPT_LP}," | ||
222 | "{Intel, HPT}," | 223 | "{Intel, HPT}," |
223 | "{Intel, PBG}," | 224 | "{Intel, PBG}," |
224 | "{Intel, SCH}," | 225 | "{Intel, SCH}," |
@@ -2004,6 +2005,9 @@ static const struct pci_device_id azx_ids[] = { | |||
2004 | /* Sunrise Point */ | 2005 | /* Sunrise Point */ |
2005 | { PCI_DEVICE(0x8086, 0xa170), | 2006 | { PCI_DEVICE(0x8086, 0xa170), |
2006 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, | 2007 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, |
2008 | /* Sunrise Point-LP */ | ||
2009 | { PCI_DEVICE(0x8086, 0x9d70), | ||
2010 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, | ||
2007 | /* Haswell */ | 2011 | /* Haswell */ |
2008 | { PCI_DEVICE(0x8086, 0x0a0c), | 2012 | { PCI_DEVICE(0x8086, 0x0a0c), |
2009 | .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL }, | 2013 | .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL }, |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 71e4bad06345..e9ebc7bd752c 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -43,6 +43,7 @@ struct conexant_spec { | |||
43 | unsigned int num_eapds; | 43 | unsigned int num_eapds; |
44 | hda_nid_t eapds[4]; | 44 | hda_nid_t eapds[4]; |
45 | bool dynamic_eapd; | 45 | bool dynamic_eapd; |
46 | hda_nid_t mute_led_eapd; | ||
46 | 47 | ||
47 | unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ | 48 | unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ |
48 | 49 | ||
@@ -163,6 +164,17 @@ static void cx_auto_vmaster_hook(void *private_data, int enabled) | |||
163 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled); | 164 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled); |
164 | } | 165 | } |
165 | 166 | ||
167 | /* turn on/off EAPD according to Master switch (inversely!) for mute LED */ | ||
168 | static void cx_auto_vmaster_hook_mute_led(void *private_data, int enabled) | ||
169 | { | ||
170 | struct hda_codec *codec = private_data; | ||
171 | struct conexant_spec *spec = codec->spec; | ||
172 | |||
173 | snd_hda_codec_write(codec, spec->mute_led_eapd, 0, | ||
174 | AC_VERB_SET_EAPD_BTLENABLE, | ||
175 | enabled ? 0x00 : 0x02); | ||
176 | } | ||
177 | |||
166 | static int cx_auto_build_controls(struct hda_codec *codec) | 178 | static int cx_auto_build_controls(struct hda_codec *codec) |
167 | { | 179 | { |
168 | int err; | 180 | int err; |
@@ -223,6 +235,7 @@ enum { | |||
223 | CXT_FIXUP_TOSHIBA_P105, | 235 | CXT_FIXUP_TOSHIBA_P105, |
224 | CXT_FIXUP_HP_530, | 236 | CXT_FIXUP_HP_530, |
225 | CXT_FIXUP_CAP_MIX_AMP_5047, | 237 | CXT_FIXUP_CAP_MIX_AMP_5047, |
238 | CXT_FIXUP_MUTE_LED_EAPD, | ||
226 | }; | 239 | }; |
227 | 240 | ||
228 | /* for hda_fixup_thinkpad_acpi() */ | 241 | /* for hda_fixup_thinkpad_acpi() */ |
@@ -557,6 +570,18 @@ static void cxt_fixup_olpc_xo(struct hda_codec *codec, | |||
557 | } | 570 | } |
558 | } | 571 | } |
559 | 572 | ||
573 | static void cxt_fixup_mute_led_eapd(struct hda_codec *codec, | ||
574 | const struct hda_fixup *fix, int action) | ||
575 | { | ||
576 | struct conexant_spec *spec = codec->spec; | ||
577 | |||
578 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
579 | spec->mute_led_eapd = 0x1b; | ||
580 | spec->dynamic_eapd = 1; | ||
581 | spec->gen.vmaster_mute.hook = cx_auto_vmaster_hook_mute_led; | ||
582 | } | ||
583 | } | ||
584 | |||
560 | /* | 585 | /* |
561 | * Fix max input level on mixer widget to 0dB | 586 | * Fix max input level on mixer widget to 0dB |
562 | * (originally it has 0x2b steps with 0dB offset 0x14) | 587 | * (originally it has 0x2b steps with 0dB offset 0x14) |
@@ -705,6 +730,10 @@ static const struct hda_fixup cxt_fixups[] = { | |||
705 | .type = HDA_FIXUP_FUNC, | 730 | .type = HDA_FIXUP_FUNC, |
706 | .v.func = cxt_fixup_cap_mix_amp_5047, | 731 | .v.func = cxt_fixup_cap_mix_amp_5047, |
707 | }, | 732 | }, |
733 | [CXT_FIXUP_MUTE_LED_EAPD] = { | ||
734 | .type = HDA_FIXUP_FUNC, | ||
735 | .v.func = cxt_fixup_mute_led_eapd, | ||
736 | }, | ||
708 | }; | 737 | }; |
709 | 738 | ||
710 | static const struct snd_pci_quirk cxt5045_fixups[] = { | 739 | static const struct snd_pci_quirk cxt5045_fixups[] = { |
@@ -762,6 +791,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { | |||
762 | SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), | 791 | SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), |
763 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410), | 792 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410), |
764 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410), | 793 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410), |
794 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo IdeaPad Z560", CXT_FIXUP_MUTE_LED_EAPD), | ||
765 | SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), | 795 | SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), |
766 | SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), | 796 | SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), |
767 | SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), | 797 | SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), |
@@ -780,6 +810,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { | |||
780 | { .id = CXT_PINCFG_LEMOTE_A1004, .name = "lemote-a1004" }, | 810 | { .id = CXT_PINCFG_LEMOTE_A1004, .name = "lemote-a1004" }, |
781 | { .id = CXT_PINCFG_LEMOTE_A1205, .name = "lemote-a1205" }, | 811 | { .id = CXT_PINCFG_LEMOTE_A1205, .name = "lemote-a1205" }, |
782 | { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" }, | 812 | { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" }, |
813 | { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, | ||
783 | {} | 814 | {} |
784 | }; | 815 | }; |
785 | 816 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index da03693099eb..172395465e8a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -288,6 +288,80 @@ static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) | |||
288 | snd_hda_jack_unsol_event(codec, res >> 2); | 288 | snd_hda_jack_unsol_event(codec, res >> 2); |
289 | } | 289 | } |
290 | 290 | ||
291 | /* Change EAPD to verb control */ | ||
292 | static void alc_fill_eapd_coef(struct hda_codec *codec) | ||
293 | { | ||
294 | int coef; | ||
295 | |||
296 | coef = alc_get_coef0(codec); | ||
297 | |||
298 | switch (codec->vendor_id) { | ||
299 | case 0x10ec0262: | ||
300 | alc_update_coef_idx(codec, 0x7, 0, 1<<5); | ||
301 | break; | ||
302 | case 0x10ec0267: | ||
303 | case 0x10ec0268: | ||
304 | alc_update_coef_idx(codec, 0x7, 0, 1<<13); | ||
305 | break; | ||
306 | case 0x10ec0269: | ||
307 | if ((coef & 0x00f0) == 0x0010) | ||
308 | alc_update_coef_idx(codec, 0xd, 0, 1<<14); | ||
309 | if ((coef & 0x00f0) == 0x0020) | ||
310 | alc_update_coef_idx(codec, 0x4, 1<<15, 0); | ||
311 | if ((coef & 0x00f0) == 0x0030) | ||
312 | alc_update_coef_idx(codec, 0x10, 1<<9, 0); | ||
313 | break; | ||
314 | case 0x10ec0280: | ||
315 | case 0x10ec0284: | ||
316 | case 0x10ec0290: | ||
317 | case 0x10ec0292: | ||
318 | alc_update_coef_idx(codec, 0x4, 1<<15, 0); | ||
319 | break; | ||
320 | case 0x10ec0233: | ||
321 | case 0x10ec0255: | ||
322 | case 0x10ec0282: | ||
323 | case 0x10ec0283: | ||
324 | case 0x10ec0286: | ||
325 | case 0x10ec0288: | ||
326 | alc_update_coef_idx(codec, 0x10, 1<<9, 0); | ||
327 | break; | ||
328 | case 0x10ec0285: | ||
329 | case 0x10ec0293: | ||
330 | alc_update_coef_idx(codec, 0xa, 1<<13, 0); | ||
331 | break; | ||
332 | case 0x10ec0662: | ||
333 | if ((coef & 0x00f0) == 0x0030) | ||
334 | alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */ | ||
335 | break; | ||
336 | case 0x10ec0272: | ||
337 | case 0x10ec0273: | ||
338 | case 0x10ec0663: | ||
339 | case 0x10ec0665: | ||
340 | case 0x10ec0670: | ||
341 | case 0x10ec0671: | ||
342 | case 0x10ec0672: | ||
343 | alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */ | ||
344 | break; | ||
345 | case 0x10ec0668: | ||
346 | alc_update_coef_idx(codec, 0x7, 3<<13, 0); | ||
347 | break; | ||
348 | case 0x10ec0867: | ||
349 | alc_update_coef_idx(codec, 0x4, 1<<10, 0); | ||
350 | break; | ||
351 | case 0x10ec0888: | ||
352 | if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030) | ||
353 | alc_update_coef_idx(codec, 0x7, 1<<5, 0); | ||
354 | break; | ||
355 | case 0x10ec0892: | ||
356 | alc_update_coef_idx(codec, 0x7, 1<<5, 0); | ||
357 | break; | ||
358 | case 0x10ec0899: | ||
359 | case 0x10ec0900: | ||
360 | alc_update_coef_idx(codec, 0x7, 1<<1, 0); | ||
361 | break; | ||
362 | } | ||
363 | } | ||
364 | |||
291 | /* additional initialization for ALC888 variants */ | 365 | /* additional initialization for ALC888 variants */ |
292 | static void alc888_coef_init(struct hda_codec *codec) | 366 | static void alc888_coef_init(struct hda_codec *codec) |
293 | { | 367 | { |
@@ -339,6 +413,7 @@ static void alc_eapd_shutup(struct hda_codec *codec) | |||
339 | /* generic EAPD initialization */ | 413 | /* generic EAPD initialization */ |
340 | static void alc_auto_init_amp(struct hda_codec *codec, int type) | 414 | static void alc_auto_init_amp(struct hda_codec *codec, int type) |
341 | { | 415 | { |
416 | alc_fill_eapd_coef(codec); | ||
342 | alc_auto_setup_eapd(codec, true); | 417 | alc_auto_setup_eapd(codec, true); |
343 | switch (type) { | 418 | switch (type) { |
344 | case ALC_INIT_GPIO1: | 419 | case ALC_INIT_GPIO1: |
@@ -5212,9 +5287,6 @@ static void alc269_fill_coef(struct hda_codec *codec) | |||
5212 | } | 5287 | } |
5213 | } | 5288 | } |
5214 | 5289 | ||
5215 | /* Class D */ | ||
5216 | alc_update_coef_idx(codec, 0xd, 0, 1<<14); | ||
5217 | |||
5218 | /* HP */ | 5290 | /* HP */ |
5219 | alc_update_coef_idx(codec, 0x4, 0, 1<<11); | 5291 | alc_update_coef_idx(codec, 0x4, 0, 1<<11); |
5220 | } | 5292 | } |
@@ -6124,29 +6196,6 @@ static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = { | |||
6124 | {} | 6196 | {} |
6125 | }; | 6197 | }; |
6126 | 6198 | ||
6127 | static void alc662_fill_coef(struct hda_codec *codec) | ||
6128 | { | ||
6129 | int coef; | ||
6130 | |||
6131 | coef = alc_get_coef0(codec); | ||
6132 | |||
6133 | switch (codec->vendor_id) { | ||
6134 | case 0x10ec0662: | ||
6135 | if ((coef & 0x00f0) == 0x0030) | ||
6136 | alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */ | ||
6137 | break; | ||
6138 | case 0x10ec0272: | ||
6139 | case 0x10ec0273: | ||
6140 | case 0x10ec0663: | ||
6141 | case 0x10ec0665: | ||
6142 | case 0x10ec0670: | ||
6143 | case 0x10ec0671: | ||
6144 | case 0x10ec0672: | ||
6145 | alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */ | ||
6146 | break; | ||
6147 | } | ||
6148 | } | ||
6149 | |||
6150 | /* | 6199 | /* |
6151 | */ | 6200 | */ |
6152 | static int patch_alc662(struct hda_codec *codec) | 6201 | static int patch_alc662(struct hda_codec *codec) |
@@ -6169,10 +6218,6 @@ static int patch_alc662(struct hda_codec *codec) | |||
6169 | case 0x10ec0668: | 6218 | case 0x10ec0668: |
6170 | spec->init_hook = alc668_restore_default_value; | 6219 | spec->init_hook = alc668_restore_default_value; |
6171 | break; | 6220 | break; |
6172 | default: | ||
6173 | spec->init_hook = alc662_fill_coef; | ||
6174 | alc662_fill_coef(codec); | ||
6175 | break; | ||
6176 | } | 6221 | } |
6177 | 6222 | ||
6178 | snd_hda_pick_fixup(codec, alc662_fixup_models, | 6223 | snd_hda_pick_fixup(codec, alc662_fixup_models, |
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index f119a41ed9a9..7c83bab69dee 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
@@ -885,6 +885,11 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, | |||
885 | return changed; | 885 | return changed; |
886 | } | 886 | } |
887 | 887 | ||
888 | static void kctl_private_value_free(struct snd_kcontrol *kctl) | ||
889 | { | ||
890 | kfree((void *)kctl->private_value); | ||
891 | } | ||
892 | |||
888 | static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, | 893 | static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, |
889 | int validx, int bUnitID) | 894 | int validx, int bUnitID) |
890 | { | 895 | { |
@@ -919,6 +924,7 @@ static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, | |||
919 | return -ENOMEM; | 924 | return -ENOMEM; |
920 | } | 925 | } |
921 | 926 | ||
927 | kctl->private_free = kctl_private_value_free; | ||
922 | err = snd_ctl_add(mixer->chip->card, kctl); | 928 | err = snd_ctl_add(mixer->chip->card, kctl); |
923 | if (err < 0) | 929 | if (err < 0) |
924 | return err; | 930 | return err; |