diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 173 |
1 files changed, 170 insertions, 3 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8ec2db2e9b60..ea4200a4ee42 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> | 6 | * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> |
7 | * PeiSen Hou <pshou@realtek.com.tw> | 7 | * PeiSen Hou <pshou@realtek.com.tw> |
8 | * Takashi Iwai <tiwai@suse.de> | 8 | * Takashi Iwai <tiwai@suse.de> |
9 | * Jonathan Woithe <jwoithe@physics.adelaide.edu.au> | ||
9 | * | 10 | * |
10 | * This driver is free software; you can redistribute it and/or modify | 11 | * This driver is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
@@ -63,6 +64,9 @@ enum { | |||
63 | ALC260_HP, | 64 | ALC260_HP, |
64 | ALC260_HP_3013, | 65 | ALC260_HP_3013, |
65 | ALC260_FUJITSU_S702X, | 66 | ALC260_FUJITSU_S702X, |
67 | #ifdef CONFIG_SND_DEBUG | ||
68 | ALC260_TEST, | ||
69 | #endif | ||
66 | ALC260_AUTO, | 70 | ALC260_AUTO, |
67 | ALC260_MODEL_LAST /* last tag */ | 71 | ALC260_MODEL_LAST /* last tag */ |
68 | }; | 72 | }; |
@@ -223,13 +227,19 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va | |||
223 | * instead of "%" to avoid consequences of accidently treating the % as | 227 | * instead of "%" to avoid consequences of accidently treating the % as |
224 | * being part of a format specifier. Maximum allowed length of a value is | 228 | * being part of a format specifier. Maximum allowed length of a value is |
225 | * 63 characters plus NULL terminator. | 229 | * 63 characters plus NULL terminator. |
230 | * | ||
231 | * Note: some retasking pin complexes seem to ignore requests for input | ||
232 | * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these | ||
233 | * are requested. Therefore order this list so that this behaviour will not | ||
234 | * cause problems when mixer clients move through the enum sequentially. | ||
235 | * NIDs 0x0f and 0x10 have been observed to have this behaviour. | ||
226 | */ | 236 | */ |
227 | static char *alc_pin_mode_names[] = { | 237 | static char *alc_pin_mode_names[] = { |
228 | "Line in", "Mic 80pc bias", "Mic 50pc bias", | 238 | "Mic 50pc bias", "Mic 80pc bias", |
229 | "Line out", "Headphone out", | 239 | "Line in", "Line out", "Headphone out", |
230 | }; | 240 | }; |
231 | static unsigned char alc_pin_mode_values[] = { | 241 | static unsigned char alc_pin_mode_values[] = { |
232 | PIN_IN, PIN_VREF80, PIN_VREF50, PIN_OUT, PIN_HP, | 242 | PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, |
233 | }; | 243 | }; |
234 | /* The control can present all 5 options, or it can limit the options based | 244 | /* The control can present all 5 options, or it can limit the options based |
235 | * in the pin being assumed to be exclusively an input or an output pin. | 245 | * in the pin being assumed to be exclusively an input or an output pin. |
@@ -2770,6 +2780,146 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = { | |||
2770 | { } | 2780 | { } |
2771 | }; | 2781 | }; |
2772 | 2782 | ||
2783 | /* Test configuration for debugging, modelled after the ALC880 test | ||
2784 | * configuration. | ||
2785 | */ | ||
2786 | #ifdef CONFIG_SND_DEBUG | ||
2787 | static hda_nid_t alc260_test_dac_nids[1] = { | ||
2788 | 0x02, | ||
2789 | }; | ||
2790 | static hda_nid_t alc260_test_adc_nids[2] = { | ||
2791 | 0x04, 0x05, | ||
2792 | }; | ||
2793 | static struct hda_input_mux alc260_test_capture_source = { | ||
2794 | .num_items = 7, | ||
2795 | .items = { | ||
2796 | { "MIC1 pin", 0x0 }, | ||
2797 | { "MIC2 pin", 0x1 }, | ||
2798 | { "LINE1 pin", 0x2 }, | ||
2799 | { "LINE2 pin", 0x3 }, | ||
2800 | { "CD pin", 0x4 }, | ||
2801 | { "LINE-OUT pin", 0x5 }, | ||
2802 | { "HP-OUT pin", 0x6 }, | ||
2803 | }, | ||
2804 | }; | ||
2805 | static struct snd_kcontrol_new alc260_test_mixer[] = { | ||
2806 | /* Output driver widgets */ | ||
2807 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | ||
2808 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | ||
2809 | HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
2810 | HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), | ||
2811 | HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
2812 | HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), | ||
2813 | |||
2814 | /* Modes for retasking pin widgets */ | ||
2815 | ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), | ||
2816 | ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), | ||
2817 | ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), | ||
2818 | ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), | ||
2819 | ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), | ||
2820 | ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), | ||
2821 | |||
2822 | /* Loopback mixer controls */ | ||
2823 | HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), | ||
2824 | HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), | ||
2825 | HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), | ||
2826 | HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), | ||
2827 | HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
2828 | HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
2829 | HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), | ||
2830 | HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), | ||
2831 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
2832 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
2833 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | ||
2834 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | ||
2835 | HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), | ||
2836 | HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), | ||
2837 | HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), | ||
2838 | HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), | ||
2839 | { } /* end */ | ||
2840 | }; | ||
2841 | static struct hda_verb alc260_test_init_verbs[] = { | ||
2842 | /* Disable all GPIOs */ | ||
2843 | {0x01, AC_VERB_SET_GPIO_MASK, 0}, | ||
2844 | /* Enable retasking pins as output, initially without power amp */ | ||
2845 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2846 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2847 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2848 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2849 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2850 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2851 | |||
2852 | /* Disable digital (SPDIF) pins for now */ | ||
2853 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
2854 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
2855 | |||
2856 | /* Ensure mic1, mic2, line1 and line2 pin widget take input from the | ||
2857 | * OUT1 sum bus when acting as an output. | ||
2858 | */ | ||
2859 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, | ||
2860 | {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, | ||
2861 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
2862 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, | ||
2863 | |||
2864 | /* Start with output sum widgets muted and their output gains at min */ | ||
2865 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2866 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2867 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2868 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2869 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2870 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2871 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2872 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2873 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2874 | |||
2875 | /* Unmute retasking pin widget output amp left/right (no mixer ctrl) */ | ||
2876 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2877 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2878 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2879 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2880 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2881 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2882 | /* Also unmute the mono-out pin widget */ | ||
2883 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2884 | |||
2885 | /* Also unmute the retasking pin input amps. Having the input and | ||
2886 | * output amps unmuted at the same time doesn't appear to cause any | ||
2887 | * trouble. | ||
2888 | */ | ||
2889 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2890 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2891 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2892 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2893 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2894 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2895 | |||
2896 | /* Mute capture amp left and right */ | ||
2897 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2898 | /* Set ADC connection select to match default mixer setting - line | ||
2899 | * in (on mic1 pin) | ||
2900 | */ | ||
2901 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
2902 | |||
2903 | /* Do the same for the second ADC: mute capture input amp and | ||
2904 | * set ADC connection to line in | ||
2905 | */ | ||
2906 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2907 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
2908 | |||
2909 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
2910 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
2911 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
2912 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
2913 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
2914 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
2915 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
2916 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
2917 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
2918 | |||
2919 | { } | ||
2920 | }; | ||
2921 | #endif | ||
2922 | |||
2773 | static struct hda_pcm_stream alc260_pcm_analog_playback = { | 2923 | static struct hda_pcm_stream alc260_pcm_analog_playback = { |
2774 | .substreams = 1, | 2924 | .substreams = 1, |
2775 | .channels_min = 2, | 2925 | .channels_min = 2, |
@@ -3053,6 +3203,9 @@ static struct hda_board_config alc260_cfg_tbl[] = { | |||
3053 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP }, | 3203 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP }, |
3054 | { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X }, | 3204 | { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X }, |
3055 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X }, | 3205 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X }, |
3206 | #ifdef CONFIG_SND_DEBUG | ||
3207 | { .modelname = "test", .config = ALC260_TEST }, | ||
3208 | #endif | ||
3056 | { .modelname = "auto", .config = ALC260_AUTO }, | 3209 | { .modelname = "auto", .config = ALC260_AUTO }, |
3057 | {} | 3210 | {} |
3058 | }; | 3211 | }; |
@@ -3110,6 +3263,20 @@ static struct alc_config_preset alc260_presets[] = { | |||
3110 | .channel_mode = alc260_modes, | 3263 | .channel_mode = alc260_modes, |
3111 | .input_mux = &alc260_fujitsu_capture_source, | 3264 | .input_mux = &alc260_fujitsu_capture_source, |
3112 | }, | 3265 | }, |
3266 | #ifdef CONFIG_SND_DEBUG | ||
3267 | [ALC260_TEST] = { | ||
3268 | .mixers = { alc260_test_mixer, | ||
3269 | alc260_capture_mixer }, | ||
3270 | .init_verbs = { alc260_test_init_verbs }, | ||
3271 | .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), | ||
3272 | .dac_nids = alc260_test_dac_nids, | ||
3273 | .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), | ||
3274 | .adc_nids = alc260_test_adc_nids, | ||
3275 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
3276 | .channel_mode = alc260_modes, | ||
3277 | .input_mux = &alc260_test_capture_source, | ||
3278 | }, | ||
3279 | #endif | ||
3113 | }; | 3280 | }; |
3114 | 3281 | ||
3115 | static int patch_alc260(struct hda_codec *codec) | 3282 | static int patch_alc260(struct hda_codec *codec) |