aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2007-06-20 09:46:13 -0400
committerJaroslav Kysela <perex@suse.cz>2007-07-20 05:11:33 -0400
commit0ac8551ea08e655fc6f35874803f091a17dacf90 (patch)
tree9f04215414516587d393e631d1718e271dc38114 /sound/pci
parente25c05f1d5cf4e332db88b15e9daa1cabd6e17e0 (diff)
[ALSA] hda-codec - Add AD1882 codec support
Added AD1882 codec support. It has currently two models, 3stack and 6stack. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_analog.c287
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
3128static hda_nid_t ad1882_dac_nids[3] = {
3129 0x04, 0x03, 0x05
3130};
3131
3132static hda_nid_t ad1882_adc_nids[2] = {
3133 0x08, 0x09,
3134};
3135
3136static 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 */
3143static 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
3154static 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
3206static 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
3220static 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
3227static 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
3237static 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
3247static 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
3257static 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 */
3266static 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 */
3335enum {
3336 AD1882_3STACK,
3337 AD1882_6STACK,
3338 AD1882_MODELS
3339};
3340
3341static const char *ad1882_models[AD1986A_MODELS] = {
3342 [AD1882_3STACK] = "3stack",
3343 [AD1882_6STACK] = "6stack",
3344};
3345
3346
3347static 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 */
3119struct hda_codec_preset snd_hda_preset_analog[] = { 3401struct 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 },