diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_analog.c | 287 |
1 files changed, 285 insertions, 2 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 760c897cde7c..4d7f8d11ad75 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * HD audio interface patch for AD1884, AD1981HD, AD1983, AD1984, AD1986A, | 2 | * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984, |
3 | * AD1988 | 3 | * AD1986A, AD1988 |
4 | * | 4 | * |
5 | * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de> | 5 | * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de> |
6 | * | 6 | * |
@@ -3114,9 +3114,292 @@ static int patch_ad1984(struct hda_codec *codec) | |||
3114 | 3114 | ||
3115 | 3115 | ||
3116 | /* | 3116 | /* |
3117 | * AD1882 | ||
3118 | * | ||
3119 | * port-A - front hp-out | ||
3120 | * port-B - front mic-in | ||
3121 | * port-C - rear line-in, shared surr-out (3stack) | ||
3122 | * port-D - rear line-out | ||
3123 | * port-E - rear mic-in, shared clfe-out (3stack) | ||
3124 | * port-F - rear surr-out (6stack) | ||
3125 | * port-G - rear clfe-out (6stack) | ||
3126 | */ | ||
3127 | |||
3128 | static hda_nid_t ad1882_dac_nids[3] = { | ||
3129 | 0x04, 0x03, 0x05 | ||
3130 | }; | ||
3131 | |||
3132 | static hda_nid_t ad1882_adc_nids[2] = { | ||
3133 | 0x08, 0x09, | ||
3134 | }; | ||
3135 | |||
3136 | static hda_nid_t ad1882_capsrc_nids[2] = { | ||
3137 | 0x0c, 0x0d, | ||
3138 | }; | ||
3139 | |||
3140 | #define AD1882_SPDIF_OUT 0x02 | ||
3141 | |||
3142 | /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */ | ||
3143 | static struct hda_input_mux ad1882_capture_source = { | ||
3144 | .num_items = 5, | ||
3145 | .items = { | ||
3146 | { "Front Mic", 0x1 }, | ||
3147 | { "Mic", 0x4 }, | ||
3148 | { "Line", 0x2 }, | ||
3149 | { "CD", 0x3 }, | ||
3150 | { "Mix", 0x7 }, | ||
3151 | }, | ||
3152 | }; | ||
3153 | |||
3154 | static struct snd_kcontrol_new ad1882_base_mixers[] = { | ||
3155 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | ||
3156 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
3157 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), | ||
3158 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), | ||
3159 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), | ||
3160 | HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), | ||
3161 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), | ||
3162 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), | ||
3163 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), | ||
3164 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), | ||
3165 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), | ||
3166 | HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), | ||
3167 | HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT), | ||
3168 | HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT), | ||
3169 | HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), | ||
3170 | HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), | ||
3171 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT), | ||
3172 | HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT), | ||
3173 | HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), | ||
3174 | HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), | ||
3175 | HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT), | ||
3176 | HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
3177 | HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), | ||
3178 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), | ||
3179 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), | ||
3180 | { | ||
3181 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3182 | /* The multiple "Capture Source" controls confuse alsamixer | ||
3183 | * So call somewhat different.. | ||
3184 | * FIXME: the controls appear in the "playback" view! | ||
3185 | */ | ||
3186 | /* .name = "Capture Source", */ | ||
3187 | .name = "Input Source", | ||
3188 | .count = 2, | ||
3189 | .info = ad198x_mux_enum_info, | ||
3190 | .get = ad198x_mux_enum_get, | ||
3191 | .put = ad198x_mux_enum_put, | ||
3192 | }, | ||
3193 | /* SPDIF controls */ | ||
3194 | HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), | ||
3195 | { | ||
3196 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3197 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", | ||
3198 | /* identical with ad1983 */ | ||
3199 | .info = ad1983_spdif_route_info, | ||
3200 | .get = ad1983_spdif_route_get, | ||
3201 | .put = ad1983_spdif_route_put, | ||
3202 | }, | ||
3203 | { } /* end */ | ||
3204 | }; | ||
3205 | |||
3206 | static struct snd_kcontrol_new ad1882_3stack_mixers[] = { | ||
3207 | HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
3208 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), | ||
3209 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT), | ||
3210 | { | ||
3211 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3212 | .name = "Channel Mode", | ||
3213 | .info = ad198x_ch_mode_info, | ||
3214 | .get = ad198x_ch_mode_get, | ||
3215 | .put = ad198x_ch_mode_put, | ||
3216 | }, | ||
3217 | { } /* end */ | ||
3218 | }; | ||
3219 | |||
3220 | static struct snd_kcontrol_new ad1882_6stack_mixers[] = { | ||
3221 | HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT), | ||
3222 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT), | ||
3223 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT), | ||
3224 | { } /* end */ | ||
3225 | }; | ||
3226 | |||
3227 | static struct hda_verb ad1882_ch2_init[] = { | ||
3228 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
3229 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3230 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3231 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3232 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3233 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3234 | { } /* end */ | ||
3235 | }; | ||
3236 | |||
3237 | static struct hda_verb ad1882_ch4_init[] = { | ||
3238 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3239 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3240 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3241 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3242 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3243 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3244 | { } /* end */ | ||
3245 | }; | ||
3246 | |||
3247 | static struct hda_verb ad1882_ch6_init[] = { | ||
3248 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3249 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3250 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3251 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3252 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3253 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3254 | { } /* end */ | ||
3255 | }; | ||
3256 | |||
3257 | static struct hda_channel_mode ad1882_modes[3] = { | ||
3258 | { 2, ad1882_ch2_init }, | ||
3259 | { 4, ad1882_ch4_init }, | ||
3260 | { 6, ad1882_ch6_init }, | ||
3261 | }; | ||
3262 | |||
3263 | /* | ||
3264 | * initialization verbs | ||
3265 | */ | ||
3266 | static struct hda_verb ad1882_init_verbs[] = { | ||
3267 | /* DACs; mute as default */ | ||
3268 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3269 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3270 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3271 | /* Port-A (HP) mixer */ | ||
3272 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3273 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3274 | /* Port-A pin */ | ||
3275 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3276 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3277 | /* HP selector - select DAC2 */ | ||
3278 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
3279 | /* Port-D (Line-out) mixer */ | ||
3280 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3281 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3282 | /* Port-D pin */ | ||
3283 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3284 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3285 | /* Mono-out mixer */ | ||
3286 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3287 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3288 | /* Mono-out pin */ | ||
3289 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3290 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3291 | /* Port-B (front mic) pin */ | ||
3292 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3293 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3294 | {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ | ||
3295 | /* Port-C (line-in) pin */ | ||
3296 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
3297 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3298 | {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ | ||
3299 | /* Port-C mixer - mute as input */ | ||
3300 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3301 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3302 | /* Port-E (mic-in) pin */ | ||
3303 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3304 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3305 | {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ | ||
3306 | /* Port-E mixer - mute as input */ | ||
3307 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3308 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3309 | /* Port-F (surround) */ | ||
3310 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3311 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3312 | /* Port-G (CLFE) */ | ||
3313 | {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3314 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3315 | /* Analog mixer; mute as default */ | ||
3316 | /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */ | ||
3317 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3318 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3319 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
3320 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
3321 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
3322 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | ||
3323 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, | ||
3324 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, | ||
3325 | /* Analog Mix output amp */ | ||
3326 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ | ||
3327 | /* SPDIF output selector */ | ||
3328 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ | ||
3329 | {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ | ||
3330 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ | ||
3331 | { } /* end */ | ||
3332 | }; | ||
3333 | |||
3334 | /* models */ | ||
3335 | enum { | ||
3336 | AD1882_3STACK, | ||
3337 | AD1882_6STACK, | ||
3338 | AD1882_MODELS | ||
3339 | }; | ||
3340 | |||
3341 | static const char *ad1882_models[AD1986A_MODELS] = { | ||
3342 | [AD1882_3STACK] = "3stack", | ||
3343 | [AD1882_6STACK] = "6stack", | ||
3344 | }; | ||
3345 | |||
3346 | |||
3347 | static int patch_ad1882(struct hda_codec *codec) | ||
3348 | { | ||
3349 | struct ad198x_spec *spec; | ||
3350 | int board_config; | ||
3351 | |||
3352 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
3353 | if (spec == NULL) | ||
3354 | return -ENOMEM; | ||
3355 | |||
3356 | mutex_init(&spec->amp_mutex); | ||
3357 | codec->spec = spec; | ||
3358 | |||
3359 | spec->multiout.max_channels = 6; | ||
3360 | spec->multiout.num_dacs = 3; | ||
3361 | spec->multiout.dac_nids = ad1882_dac_nids; | ||
3362 | spec->multiout.dig_out_nid = AD1882_SPDIF_OUT; | ||
3363 | spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); | ||
3364 | spec->adc_nids = ad1882_adc_nids; | ||
3365 | spec->capsrc_nids = ad1882_capsrc_nids; | ||
3366 | spec->input_mux = &ad1882_capture_source; | ||
3367 | spec->num_mixers = 1; | ||
3368 | spec->mixers[0] = ad1882_base_mixers; | ||
3369 | spec->num_init_verbs = 1; | ||
3370 | spec->init_verbs[0] = ad1882_init_verbs; | ||
3371 | spec->spdif_route = 0; | ||
3372 | |||
3373 | codec->patch_ops = ad198x_patch_ops; | ||
3374 | |||
3375 | /* override some parameters */ | ||
3376 | board_config = snd_hda_check_board_config(codec, AD1882_MODELS, | ||
3377 | ad1882_models, NULL); | ||
3378 | switch (board_config) { | ||
3379 | default: | ||
3380 | case AD1882_3STACK: | ||
3381 | spec->num_mixers = 2; | ||
3382 | spec->mixers[1] = ad1882_3stack_mixers; | ||
3383 | spec->channel_mode = ad1882_modes; | ||
3384 | spec->num_channel_mode = ARRAY_SIZE(ad1882_modes); | ||
3385 | spec->need_dac_fix = 1; | ||
3386 | spec->multiout.max_channels = 2; | ||
3387 | spec->multiout.num_dacs = 1; | ||
3388 | break; | ||
3389 | case AD1882_6STACK: | ||
3390 | spec->num_mixers = 2; | ||
3391 | spec->mixers[1] = ad1882_6stack_mixers; | ||
3392 | break; | ||
3393 | } | ||
3394 | return 0; | ||
3395 | } | ||
3396 | |||
3397 | |||
3398 | /* | ||
3117 | * patch entries | 3399 | * patch entries |
3118 | */ | 3400 | */ |
3119 | struct hda_codec_preset snd_hda_preset_analog[] = { | 3401 | struct hda_codec_preset snd_hda_preset_analog[] = { |
3402 | { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, | ||
3120 | { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, | 3403 | { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, |
3121 | { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, | 3404 | { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, |
3122 | { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, | 3405 | { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, |