diff options
author | David Henningsson <david.henningsson@canonical.com> | 2013-04-15 09:44:14 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-04-15 09:52:55 -0400 |
commit | 73bdd597823e2231dc882577dbbaf8df92fe1775 (patch) | |
tree | 29cf34127105d7f9b8b3348837a4317d56e7fa9b /sound/pci | |
parent | 1539d4f82ad534431cc67935e8e442ccf107d17d (diff) |
ALSA: hda - Implement headset jack functionality for some Dell hw
On some machines, there is a headset jack that can support both
headphone, headsets (of both CTIA and OMTP type) and mic-in.
On other machines, the headset jack supports headphone, headsets
(both CTIA and OMTP), but not mic-in.
This patch implements that functionality as different capture sources.
Buglink: https://bugs.launchpad.net/bugs/1169143
Tested-by: David Chen <david.chen@canonical.com>
Co-authored-by: Kailang <kailang@realtek.com>
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 145d078c9341..cd5f9e9f8838 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -52,6 +52,20 @@ enum { | |||
52 | ALC_INIT_GPIO3, | 52 | ALC_INIT_GPIO3, |
53 | }; | 53 | }; |
54 | 54 | ||
55 | enum { | ||
56 | ALC_HEADSET_MODE_UNKNOWN, | ||
57 | ALC_HEADSET_MODE_UNPLUGGED, | ||
58 | ALC_HEADSET_MODE_HEADSET, | ||
59 | ALC_HEADSET_MODE_MIC, | ||
60 | ALC_HEADSET_MODE_HEADPHONE, | ||
61 | }; | ||
62 | |||
63 | enum { | ||
64 | ALC_HEADSET_TYPE_UNKNOWN, | ||
65 | ALC_HEADSET_TYPE_CTIA, | ||
66 | ALC_HEADSET_TYPE_OMTP, | ||
67 | }; | ||
68 | |||
55 | struct alc_customize_define { | 69 | struct alc_customize_define { |
56 | unsigned int sku_cfg; | 70 | unsigned int sku_cfg; |
57 | unsigned char port_connectivity; | 71 | unsigned char port_connectivity; |
@@ -87,6 +101,11 @@ struct alc_spec { | |||
87 | 101 | ||
88 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ | 102 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ |
89 | 103 | ||
104 | hda_nid_t headset_mic_pin; | ||
105 | hda_nid_t headphone_mic_pin; | ||
106 | int current_headset_mode; | ||
107 | int current_headset_type; | ||
108 | |||
90 | /* hooks */ | 109 | /* hooks */ |
91 | void (*init_hook)(struct hda_codec *codec); | 110 | void (*init_hook)(struct hda_codec *codec); |
92 | #ifdef CONFIG_PM | 111 | #ifdef CONFIG_PM |
@@ -2798,6 +2817,302 @@ static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, | |||
2798 | } | 2817 | } |
2799 | } | 2818 | } |
2800 | 2819 | ||
2820 | static void alc_headset_mode_unplugged(struct hda_codec *codec) | ||
2821 | { | ||
2822 | int val; | ||
2823 | |||
2824 | switch (codec->vendor_id) { | ||
2825 | case 0x10ec0283: | ||
2826 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | ||
2827 | alc_write_coef_idx(codec, 0x45, 0xc429); | ||
2828 | val = alc_read_coef_idx(codec, 0x35); | ||
2829 | alc_write_coef_idx(codec, 0x35, val & 0xbfff); | ||
2830 | alc_write_coef_idx(codec, 0x06, 0x2104); | ||
2831 | alc_write_coef_idx(codec, 0x1a, 0x0001); | ||
2832 | alc_write_coef_idx(codec, 0x26, 0x0004); | ||
2833 | alc_write_coef_idx(codec, 0x32, 0x42a3); | ||
2834 | break; | ||
2835 | case 0x10ec0292: | ||
2836 | alc_write_coef_idx(codec, 0x76, 0x000e); | ||
2837 | alc_write_coef_idx(codec, 0x6c, 0x2400); | ||
2838 | alc_write_coef_idx(codec, 0x18, 0x7308); | ||
2839 | alc_write_coef_idx(codec, 0x6b, 0xc429); | ||
2840 | break; | ||
2841 | case 0x10ec0668: | ||
2842 | alc_write_coef_idx(codec, 0x15, 0x0d40); | ||
2843 | alc_write_coef_idx(codec, 0xb7, 0x802b); | ||
2844 | break; | ||
2845 | } | ||
2846 | snd_printdd("Headset jack set to unplugged mode.\n"); | ||
2847 | } | ||
2848 | |||
2849 | |||
2850 | static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | ||
2851 | hda_nid_t mic_pin) | ||
2852 | { | ||
2853 | int val; | ||
2854 | |||
2855 | switch (codec->vendor_id) { | ||
2856 | case 0x10ec0283: | ||
2857 | alc_write_coef_idx(codec, 0x45, 0xc429); | ||
2858 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | ||
2859 | val = alc_read_coef_idx(codec, 0x35); | ||
2860 | alc_write_coef_idx(codec, 0x35, val | 1<<14); | ||
2861 | alc_write_coef_idx(codec, 0x06, 0x2100); | ||
2862 | alc_write_coef_idx(codec, 0x1a, 0x0021); | ||
2863 | alc_write_coef_idx(codec, 0x26, 0x008c); | ||
2864 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | ||
2865 | break; | ||
2866 | case 0x10ec0292: | ||
2867 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | ||
2868 | alc_write_coef_idx(codec, 0x19, 0xa208); | ||
2869 | alc_write_coef_idx(codec, 0x2e, 0xacf0); | ||
2870 | break; | ||
2871 | case 0x10ec0668: | ||
2872 | alc_write_coef_idx(codec, 0x11, 0x0001); | ||
2873 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | ||
2874 | alc_write_coef_idx(codec, 0xb7, 0x802b); | ||
2875 | alc_write_coef_idx(codec, 0xb5, 0x1040); | ||
2876 | val = alc_read_coef_idx(codec, 0xc3); | ||
2877 | alc_write_coef_idx(codec, 0xc3, val | 1<<12); | ||
2878 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | ||
2879 | break; | ||
2880 | } | ||
2881 | snd_printdd("Headset jack set to mic-in mode.\n"); | ||
2882 | } | ||
2883 | |||
2884 | static void alc_headset_mode_default(struct hda_codec *codec) | ||
2885 | { | ||
2886 | switch (codec->vendor_id) { | ||
2887 | case 0x10ec0283: | ||
2888 | alc_write_coef_idx(codec, 0x06, 0x2100); | ||
2889 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | ||
2890 | break; | ||
2891 | case 0x10ec0292: | ||
2892 | alc_write_coef_idx(codec, 0x76, 0x000e); | ||
2893 | alc_write_coef_idx(codec, 0x6c, 0x2400); | ||
2894 | alc_write_coef_idx(codec, 0x6b, 0xc429); | ||
2895 | alc_write_coef_idx(codec, 0x18, 0x7308); | ||
2896 | break; | ||
2897 | case 0x10ec0668: | ||
2898 | alc_write_coef_idx(codec, 0x11, 0x0041); | ||
2899 | alc_write_coef_idx(codec, 0x15, 0x0d40); | ||
2900 | alc_write_coef_idx(codec, 0xb7, 0x802b); | ||
2901 | break; | ||
2902 | } | ||
2903 | snd_printdd("Headset jack set to headphone (default) mode.\n"); | ||
2904 | } | ||
2905 | |||
2906 | /* Iphone type */ | ||
2907 | static void alc_headset_mode_ctia(struct hda_codec *codec) | ||
2908 | { | ||
2909 | switch (codec->vendor_id) { | ||
2910 | case 0x10ec0283: | ||
2911 | alc_write_coef_idx(codec, 0x45, 0xd429); | ||
2912 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | ||
2913 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | ||
2914 | break; | ||
2915 | case 0x10ec0292: | ||
2916 | alc_write_coef_idx(codec, 0x6b, 0xd429); | ||
2917 | alc_write_coef_idx(codec, 0x76, 0x0008); | ||
2918 | alc_write_coef_idx(codec, 0x18, 0x7388); | ||
2919 | break; | ||
2920 | case 0x10ec0668: | ||
2921 | alc_write_coef_idx(codec, 0x15, 0x0d60); | ||
2922 | alc_write_coef_idx(codec, 0xc3, 0x0000); | ||
2923 | break; | ||
2924 | } | ||
2925 | snd_printdd("Headset jack set to iPhone-style headset mode.\n"); | ||
2926 | } | ||
2927 | |||
2928 | /* Nokia type */ | ||
2929 | static void alc_headset_mode_omtp(struct hda_codec *codec) | ||
2930 | { | ||
2931 | switch (codec->vendor_id) { | ||
2932 | case 0x10ec0283: | ||
2933 | alc_write_coef_idx(codec, 0x45, 0xe429); | ||
2934 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | ||
2935 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | ||
2936 | break; | ||
2937 | case 0x10ec0292: | ||
2938 | alc_write_coef_idx(codec, 0x6b, 0xe429); | ||
2939 | alc_write_coef_idx(codec, 0x76, 0x0008); | ||
2940 | alc_write_coef_idx(codec, 0x18, 0x7388); | ||
2941 | break; | ||
2942 | case 0x10ec0668: | ||
2943 | alc_write_coef_idx(codec, 0x15, 0x0d50); | ||
2944 | alc_write_coef_idx(codec, 0xc3, 0x0000); | ||
2945 | break; | ||
2946 | } | ||
2947 | snd_printdd("Headset jack set to Nokia-style headset mode.\n"); | ||
2948 | } | ||
2949 | |||
2950 | static void alc_determine_headset_type(struct hda_codec *codec) | ||
2951 | { | ||
2952 | int val; | ||
2953 | bool is_ctia = false; | ||
2954 | struct alc_spec *spec = codec->spec; | ||
2955 | |||
2956 | switch (codec->vendor_id) { | ||
2957 | case 0x10ec0283: | ||
2958 | alc_write_coef_idx(codec, 0x45, 0xd029); | ||
2959 | msleep(300); | ||
2960 | val = alc_read_coef_idx(codec, 0x46); | ||
2961 | is_ctia = (val & 0x0070) == 0x0070; | ||
2962 | break; | ||
2963 | case 0x10ec0292: | ||
2964 | alc_write_coef_idx(codec, 0x6b, 0xd429); | ||
2965 | msleep(300); | ||
2966 | val = alc_read_coef_idx(codec, 0x6c); | ||
2967 | is_ctia = (val & 0x001c) == 0x001c; | ||
2968 | break; | ||
2969 | case 0x10ec0668: | ||
2970 | alc_write_coef_idx(codec, 0x11, 0x0001); | ||
2971 | alc_write_coef_idx(codec, 0xb7, 0x802b); | ||
2972 | alc_write_coef_idx(codec, 0x15, 0x0d60); | ||
2973 | alc_write_coef_idx(codec, 0xc3, 0x0c00); | ||
2974 | msleep(300); | ||
2975 | val = alc_read_coef_idx(codec, 0xbe); | ||
2976 | is_ctia = (val & 0x1c02) == 0x1c02; | ||
2977 | break; | ||
2978 | } | ||
2979 | |||
2980 | snd_printdd("Headset jack detected iPhone-style headset: %s\n", | ||
2981 | is_ctia ? "yes" : "no"); | ||
2982 | spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; | ||
2983 | } | ||
2984 | |||
2985 | static void alc_update_headset_mode(struct hda_codec *codec) | ||
2986 | { | ||
2987 | struct alc_spec *spec = codec->spec; | ||
2988 | |||
2989 | hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; | ||
2990 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | ||
2991 | |||
2992 | int new_headset_mode; | ||
2993 | |||
2994 | if (!snd_hda_jack_detect(codec, hp_pin)) | ||
2995 | new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; | ||
2996 | else if (mux_pin == spec->headset_mic_pin) | ||
2997 | new_headset_mode = ALC_HEADSET_MODE_HEADSET; | ||
2998 | else if (mux_pin == spec->headphone_mic_pin) | ||
2999 | new_headset_mode = ALC_HEADSET_MODE_MIC; | ||
3000 | else | ||
3001 | new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; | ||
3002 | |||
3003 | if (new_headset_mode == spec->current_headset_mode) | ||
3004 | return; | ||
3005 | |||
3006 | switch (new_headset_mode) { | ||
3007 | case ALC_HEADSET_MODE_UNPLUGGED: | ||
3008 | alc_headset_mode_unplugged(codec); | ||
3009 | spec->gen.hp_jack_present = false; | ||
3010 | break; | ||
3011 | case ALC_HEADSET_MODE_HEADSET: | ||
3012 | if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) | ||
3013 | alc_determine_headset_type(codec); | ||
3014 | if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) | ||
3015 | alc_headset_mode_ctia(codec); | ||
3016 | else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) | ||
3017 | alc_headset_mode_omtp(codec); | ||
3018 | spec->gen.hp_jack_present = true; | ||
3019 | break; | ||
3020 | case ALC_HEADSET_MODE_MIC: | ||
3021 | alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); | ||
3022 | spec->gen.hp_jack_present = false; | ||
3023 | break; | ||
3024 | case ALC_HEADSET_MODE_HEADPHONE: | ||
3025 | alc_headset_mode_default(codec); | ||
3026 | spec->gen.hp_jack_present = true; | ||
3027 | break; | ||
3028 | } | ||
3029 | if (new_headset_mode != ALC_HEADSET_MODE_MIC) { | ||
3030 | snd_hda_set_pin_ctl_cache(codec, hp_pin, | ||
3031 | AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | ||
3032 | if (spec->headphone_mic_pin) | ||
3033 | snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, | ||
3034 | PIN_VREFHIZ); | ||
3035 | } | ||
3036 | spec->current_headset_mode = new_headset_mode; | ||
3037 | |||
3038 | snd_hda_gen_update_outputs(codec); | ||
3039 | } | ||
3040 | |||
3041 | static void alc_update_headset_mode_hook(struct hda_codec *codec, | ||
3042 | struct snd_ctl_elem_value *ucontrol) | ||
3043 | { | ||
3044 | alc_update_headset_mode(codec); | ||
3045 | } | ||
3046 | |||
3047 | static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
3048 | { | ||
3049 | struct alc_spec *spec = codec->spec; | ||
3050 | spec->current_headset_type = ALC_HEADSET_MODE_UNKNOWN; | ||
3051 | snd_hda_gen_hp_automute(codec, jack); | ||
3052 | } | ||
3053 | |||
3054 | static void alc_probe_headset_mode(struct hda_codec *codec) | ||
3055 | { | ||
3056 | int i; | ||
3057 | struct alc_spec *spec = codec->spec; | ||
3058 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | ||
3059 | |||
3060 | /* Find mic pins */ | ||
3061 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3062 | if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) | ||
3063 | spec->headset_mic_pin = cfg->inputs[i].pin; | ||
3064 | if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) | ||
3065 | spec->headphone_mic_pin = cfg->inputs[i].pin; | ||
3066 | } | ||
3067 | |||
3068 | spec->gen.cap_sync_hook = alc_update_headset_mode_hook; | ||
3069 | spec->gen.automute_hook = alc_update_headset_mode; | ||
3070 | spec->gen.hp_automute_hook = alc_update_headset_jack_cb; | ||
3071 | } | ||
3072 | |||
3073 | static void alc_fixup_headset_mode(struct hda_codec *codec, | ||
3074 | const struct hda_fixup *fix, int action) | ||
3075 | { | ||
3076 | struct alc_spec *spec = codec->spec; | ||
3077 | |||
3078 | switch (action) { | ||
3079 | case HDA_FIXUP_ACT_PRE_PROBE: | ||
3080 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; | ||
3081 | break; | ||
3082 | case HDA_FIXUP_ACT_PROBE: | ||
3083 | alc_probe_headset_mode(codec); | ||
3084 | break; | ||
3085 | case HDA_FIXUP_ACT_INIT: | ||
3086 | spec->current_headset_mode = 0; | ||
3087 | alc_update_headset_mode(codec); | ||
3088 | break; | ||
3089 | } | ||
3090 | } | ||
3091 | |||
3092 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, | ||
3093 | const struct hda_fixup *fix, int action) | ||
3094 | { | ||
3095 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3096 | struct alc_spec *spec = codec->spec; | ||
3097 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | ||
3098 | } | ||
3099 | else | ||
3100 | alc_fixup_headset_mode(codec, fix, action); | ||
3101 | } | ||
3102 | |||
3103 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, | ||
3104 | const struct hda_fixup *fix, int action) | ||
3105 | { | ||
3106 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3107 | int val; | ||
3108 | alc_write_coef_idx(codec, 0xc4, 0x8000); | ||
3109 | val = alc_read_coef_idx(codec, 0xc2); | ||
3110 | alc_write_coef_idx(codec, 0xc2, val & 0xfe); | ||
3111 | snd_hda_set_pin_ctl_cache(codec, 0x18, 0); | ||
3112 | } | ||
3113 | alc_fixup_headset_mode(codec, fix, action); | ||
3114 | } | ||
3115 | |||
2801 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, | 3116 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, |
2802 | const struct hda_fixup *fix, | 3117 | const struct hda_fixup *fix, |
2803 | int action) | 3118 | int action) |
@@ -2837,6 +3152,10 @@ enum { | |||
2837 | ALC269_FIXUP_INV_DMIC, | 3152 | ALC269_FIXUP_INV_DMIC, |
2838 | ALC269_FIXUP_LENOVO_DOCK, | 3153 | ALC269_FIXUP_LENOVO_DOCK, |
2839 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, | 3154 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, |
3155 | ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
3156 | ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, | ||
3157 | ALC269_FIXUP_HEADSET_MODE, | ||
3158 | ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, | ||
2840 | ALC271_FIXUP_AMIC_MIC2, | 3159 | ALC271_FIXUP_AMIC_MIC2, |
2841 | ALC271_FIXUP_HP_GATE_MIC_JACK, | 3160 | ALC271_FIXUP_HP_GATE_MIC_JACK, |
2842 | ALC269_FIXUP_ACER_AC700, | 3161 | ALC269_FIXUP_ACER_AC700, |
@@ -2996,6 +3315,35 @@ static const struct hda_fixup alc269_fixups[] = { | |||
2996 | .type = HDA_FIXUP_FUNC, | 3315 | .type = HDA_FIXUP_FUNC, |
2997 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, | 3316 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, |
2998 | }, | 3317 | }, |
3318 | [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = { | ||
3319 | .type = HDA_FIXUP_PINS, | ||
3320 | .v.pins = (const struct hda_pintbl[]) { | ||
3321 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | ||
3322 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ | ||
3323 | { } | ||
3324 | }, | ||
3325 | .chained = true, | ||
3326 | .chain_id = ALC269_FIXUP_HEADSET_MODE | ||
3327 | }, | ||
3328 | [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = { | ||
3329 | .type = HDA_FIXUP_PINS, | ||
3330 | .v.pins = (const struct hda_pintbl[]) { | ||
3331 | { 0x16, 0x21014020 }, /* dock line out */ | ||
3332 | { 0x19, 0x21a19030 }, /* dock mic */ | ||
3333 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | ||
3334 | { } | ||
3335 | }, | ||
3336 | .chained = true, | ||
3337 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC | ||
3338 | }, | ||
3339 | [ALC269_FIXUP_HEADSET_MODE] = { | ||
3340 | .type = HDA_FIXUP_FUNC, | ||
3341 | .v.func = alc_fixup_headset_mode, | ||
3342 | }, | ||
3343 | [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = { | ||
3344 | .type = HDA_FIXUP_FUNC, | ||
3345 | .v.func = alc_fixup_headset_mode_no_hp_mic, | ||
3346 | }, | ||
2999 | [ALC271_FIXUP_AMIC_MIC2] = { | 3347 | [ALC271_FIXUP_AMIC_MIC2] = { |
3000 | .type = HDA_FIXUP_PINS, | 3348 | .type = HDA_FIXUP_PINS, |
3001 | .v.pins = (const struct hda_pintbl[]) { | 3349 | .v.pins = (const struct hda_pintbl[]) { |
@@ -3030,6 +3378,26 @@ static const struct hda_fixup alc269_fixups[] = { | |||
3030 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 3378 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
3031 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), | 3379 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), |
3032 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), | 3380 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), |
3381 | SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | ||
3382 | SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | ||
3383 | SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3384 | SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3385 | SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3386 | SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3387 | SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3388 | SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3389 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | ||
3390 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | ||
3391 | SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3392 | SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3393 | SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3394 | SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3395 | SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3396 | SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3397 | SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3398 | SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3399 | SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3400 | SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3033 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 3401 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
3034 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), | 3402 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), |
3035 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 3403 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
@@ -3535,6 +3903,8 @@ enum { | |||
3535 | ALC662_FIXUP_NO_JACK_DETECT, | 3903 | ALC662_FIXUP_NO_JACK_DETECT, |
3536 | ALC662_FIXUP_ZOTAC_Z68, | 3904 | ALC662_FIXUP_ZOTAC_Z68, |
3537 | ALC662_FIXUP_INV_DMIC, | 3905 | ALC662_FIXUP_INV_DMIC, |
3906 | ALC668_FIXUP_DELL_MIC_NO_PRESENCE, | ||
3907 | ALC668_FIXUP_HEADSET_MODE, | ||
3538 | }; | 3908 | }; |
3539 | 3909 | ||
3540 | static const struct hda_fixup alc662_fixups[] = { | 3910 | static const struct hda_fixup alc662_fixups[] = { |
@@ -3695,6 +4065,20 @@ static const struct hda_fixup alc662_fixups[] = { | |||
3695 | .type = HDA_FIXUP_FUNC, | 4065 | .type = HDA_FIXUP_FUNC, |
3696 | .v.func = alc_fixup_inv_dmic_0x12, | 4066 | .v.func = alc_fixup_inv_dmic_0x12, |
3697 | }, | 4067 | }, |
4068 | [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { | ||
4069 | .type = HDA_FIXUP_PINS, | ||
4070 | .v.pins = (const struct hda_pintbl[]) { | ||
4071 | { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ | ||
4072 | { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ | ||
4073 | { } | ||
4074 | }, | ||
4075 | .chained = true, | ||
4076 | .chain_id = ALC668_FIXUP_HEADSET_MODE | ||
4077 | }, | ||
4078 | [ALC668_FIXUP_HEADSET_MODE] = { | ||
4079 | .type = HDA_FIXUP_FUNC, | ||
4080 | .v.func = alc_fixup_headset_mode_alc668, | ||
4081 | }, | ||
3698 | }; | 4082 | }; |
3699 | 4083 | ||
3700 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 4084 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
@@ -3703,6 +4087,8 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { | |||
3703 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | 4087 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), |
3704 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), | 4088 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), |
3705 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 4089 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
4090 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | ||
4091 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | ||
3706 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 4092 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
3707 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), | 4093 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), |
3708 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), | 4094 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), |