aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c173
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 */
227static char *alc_pin_mode_names[] = { 237static 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};
231static unsigned char alc_pin_mode_values[] = { 241static 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
2787static hda_nid_t alc260_test_dac_nids[1] = {
2788 0x02,
2789};
2790static hda_nid_t alc260_test_adc_nids[2] = {
2791 0x04, 0x05,
2792};
2793static 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};
2805static 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};
2841static 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
2773static struct hda_pcm_stream alc260_pcm_analog_playback = { 2923static 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
3115static int patch_alc260(struct hda_codec *codec) 3282static int patch_alc260(struct hda_codec *codec)