aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Woithe <jwoithe@physics.adelaide.edu.au>2006-02-09 06:01:26 -0500
committerJaroslav Kysela <perex@suse.cz>2006-03-22 04:28:50 -0500
commit7cf51e48315d87b4c1cf600d611894f45f661142 (patch)
tree1c3d85f27af4d79ad146f7cbcc21aaae1057a766
parent8b33a5aa08c4e462360d812386dcecc0467efd7b (diff)
[ALSA] hda: ALC260 test model implementation
Modules: HDA Codec driver The following patch adds a 'test' ALC260 model specification to the patch_realtek.c driver if CONFIG_SND_DEBUG is set. This is similar to the 'test' ALC880 model in that it sets up mixer controls for almost everything to make it easier for people to test their laptop/soundcard when working out what pin widgets are connected to which real-world devices. This patch assumes my previous patch (adding the second PCM to the ALC260) has previously been applied since it uses infrastructure added by that patch. In developing this patch it was found that not all retasking pins accept all the modes - in particular, some ignore the VREFxx variants. The pin mode control has therefore been tweaked to prevent this becoming a problem in mixer applications. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-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)