diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-08-05 05:16:56 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-08-05 05:16:56 -0400 |
commit | 2603798070a80d76e7e6d2992ba4ec74addcec90 (patch) | |
tree | 7a1cdc33bd9bbf3807db239205de02d6beb58e30 /sound/pci | |
parent | 9fe6206f400646a2322096b56c59891d530e8d51 (diff) | |
parent | fc091769a5aa65c045bfbda149c424ba33d0abbb (diff) |
Merge branch 'topic/hda' into for-linus
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 87 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 27 | ||||
-rw-r--r-- | sound/pci/hda/hda_hwdep.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 5 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 7 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 95 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 43 | ||||
-rw-r--r-- | sound/pci/hda/patch_intelhdmi.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_nvhdmi.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 720 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 12 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 32 |
12 files changed, 891 insertions, 147 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index ba2098d20ccc..05e8995f9aec 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -396,15 +396,18 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
396 | } | 396 | } |
397 | for (n = prev_nid + 1; n <= val; n++) { | 397 | for (n = prev_nid + 1; n <= val; n++) { |
398 | if (conns >= max_conns) { | 398 | if (conns >= max_conns) { |
399 | snd_printk(KERN_ERR | 399 | snd_printk(KERN_ERR "hda_codec: " |
400 | "Too many connections\n"); | 400 | "Too many connections %d for NID 0x%x\n", |
401 | conns, nid); | ||
401 | return -EINVAL; | 402 | return -EINVAL; |
402 | } | 403 | } |
403 | conn_list[conns++] = n; | 404 | conn_list[conns++] = n; |
404 | } | 405 | } |
405 | } else { | 406 | } else { |
406 | if (conns >= max_conns) { | 407 | if (conns >= max_conns) { |
407 | snd_printk(KERN_ERR "Too many connections\n"); | 408 | snd_printk(KERN_ERR "hda_codec: " |
409 | "Too many connections %d for NID 0x%x\n", | ||
410 | conns, nid); | ||
408 | return -EINVAL; | 411 | return -EINVAL; |
409 | } | 412 | } |
410 | conn_list[conns++] = val; | 413 | conn_list[conns++] = val; |
@@ -1565,6 +1568,17 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec) | |||
1565 | EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); | 1568 | EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); |
1566 | #endif /* SND_HDA_NEEDS_RESUME */ | 1569 | #endif /* SND_HDA_NEEDS_RESUME */ |
1567 | 1570 | ||
1571 | static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir, | ||
1572 | unsigned int ofs) | ||
1573 | { | ||
1574 | u32 caps = query_amp_caps(codec, nid, dir); | ||
1575 | /* get num steps */ | ||
1576 | caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | ||
1577 | if (ofs < caps) | ||
1578 | caps -= ofs; | ||
1579 | return caps; | ||
1580 | } | ||
1581 | |||
1568 | /** | 1582 | /** |
1569 | * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer | 1583 | * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer |
1570 | * | 1584 | * |
@@ -1579,23 +1593,17 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, | |||
1579 | u8 chs = get_amp_channels(kcontrol); | 1593 | u8 chs = get_amp_channels(kcontrol); |
1580 | int dir = get_amp_direction(kcontrol); | 1594 | int dir = get_amp_direction(kcontrol); |
1581 | unsigned int ofs = get_amp_offset(kcontrol); | 1595 | unsigned int ofs = get_amp_offset(kcontrol); |
1582 | u32 caps; | ||
1583 | 1596 | ||
1584 | caps = query_amp_caps(codec, nid, dir); | 1597 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1585 | /* num steps */ | 1598 | uinfo->count = chs == 3 ? 2 : 1; |
1586 | caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | 1599 | uinfo->value.integer.min = 0; |
1587 | if (!caps) { | 1600 | uinfo->value.integer.max = get_amp_max_value(codec, nid, dir, ofs); |
1601 | if (!uinfo->value.integer.max) { | ||
1588 | printk(KERN_WARNING "hda_codec: " | 1602 | printk(KERN_WARNING "hda_codec: " |
1589 | "num_steps = 0 for NID=0x%x (ctl = %s)\n", nid, | 1603 | "num_steps = 0 for NID=0x%x (ctl = %s)\n", nid, |
1590 | kcontrol->id.name); | 1604 | kcontrol->id.name); |
1591 | return -EINVAL; | 1605 | return -EINVAL; |
1592 | } | 1606 | } |
1593 | if (ofs < caps) | ||
1594 | caps -= ofs; | ||
1595 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1596 | uinfo->count = chs == 3 ? 2 : 1; | ||
1597 | uinfo->value.integer.min = 0; | ||
1598 | uinfo->value.integer.max = caps; | ||
1599 | return 0; | 1607 | return 0; |
1600 | } | 1608 | } |
1601 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info); | 1609 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info); |
@@ -1620,8 +1628,14 @@ update_amp_value(struct hda_codec *codec, hda_nid_t nid, | |||
1620 | int ch, int dir, int idx, unsigned int ofs, | 1628 | int ch, int dir, int idx, unsigned int ofs, |
1621 | unsigned int val) | 1629 | unsigned int val) |
1622 | { | 1630 | { |
1631 | unsigned int maxval; | ||
1632 | |||
1623 | if (val > 0) | 1633 | if (val > 0) |
1624 | val += ofs; | 1634 | val += ofs; |
1635 | /* ofs = 0: raw max value */ | ||
1636 | maxval = get_amp_max_value(codec, nid, dir, 0); | ||
1637 | if (val > maxval) | ||
1638 | val = maxval; | ||
1625 | return snd_hda_codec_amp_update(codec, nid, ch, dir, idx, | 1639 | return snd_hda_codec_amp_update(codec, nid, ch, dir, idx, |
1626 | HDA_AMP_VOLMASK, val); | 1640 | HDA_AMP_VOLMASK, val); |
1627 | } | 1641 | } |
@@ -2999,26 +3013,31 @@ struct hda_rate_tbl { | |||
2999 | unsigned int hda_fmt; | 3013 | unsigned int hda_fmt; |
3000 | }; | 3014 | }; |
3001 | 3015 | ||
3016 | /* rate = base * mult / div */ | ||
3017 | #define HDA_RATE(base, mult, div) \ | ||
3018 | (AC_FMT_BASE_##base##K | (((mult) - 1) << AC_FMT_MULT_SHIFT) | \ | ||
3019 | (((div) - 1) << AC_FMT_DIV_SHIFT)) | ||
3020 | |||
3002 | static struct hda_rate_tbl rate_bits[] = { | 3021 | static struct hda_rate_tbl rate_bits[] = { |
3003 | /* rate in Hz, ALSA rate bitmask, HDA format value */ | 3022 | /* rate in Hz, ALSA rate bitmask, HDA format value */ |
3004 | 3023 | ||
3005 | /* autodetected value used in snd_hda_query_supported_pcm */ | 3024 | /* autodetected value used in snd_hda_query_supported_pcm */ |
3006 | { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */ | 3025 | { 8000, SNDRV_PCM_RATE_8000, HDA_RATE(48, 1, 6) }, |
3007 | { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */ | 3026 | { 11025, SNDRV_PCM_RATE_11025, HDA_RATE(44, 1, 4) }, |
3008 | { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */ | 3027 | { 16000, SNDRV_PCM_RATE_16000, HDA_RATE(48, 1, 3) }, |
3009 | { 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */ | 3028 | { 22050, SNDRV_PCM_RATE_22050, HDA_RATE(44, 1, 2) }, |
3010 | { 32000, SNDRV_PCM_RATE_32000, 0x0a00 }, /* 2/3 x 48 */ | 3029 | { 32000, SNDRV_PCM_RATE_32000, HDA_RATE(48, 2, 3) }, |
3011 | { 44100, SNDRV_PCM_RATE_44100, 0x4000 }, /* 44 */ | 3030 | { 44100, SNDRV_PCM_RATE_44100, HDA_RATE(44, 1, 1) }, |
3012 | { 48000, SNDRV_PCM_RATE_48000, 0x0000 }, /* 48 */ | 3031 | { 48000, SNDRV_PCM_RATE_48000, HDA_RATE(48, 1, 1) }, |
3013 | { 88200, SNDRV_PCM_RATE_88200, 0x4800 }, /* 2 x 44 */ | 3032 | { 88200, SNDRV_PCM_RATE_88200, HDA_RATE(44, 2, 1) }, |
3014 | { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ | 3033 | { 96000, SNDRV_PCM_RATE_96000, HDA_RATE(48, 2, 1) }, |
3015 | { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ | 3034 | { 176400, SNDRV_PCM_RATE_176400, HDA_RATE(44, 4, 1) }, |
3016 | { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ | 3035 | { 192000, SNDRV_PCM_RATE_192000, HDA_RATE(48, 4, 1) }, |
3017 | #define AC_PAR_PCM_RATE_BITS 11 | 3036 | #define AC_PAR_PCM_RATE_BITS 11 |
3018 | /* up to bits 10, 384kHZ isn't supported properly */ | 3037 | /* up to bits 10, 384kHZ isn't supported properly */ |
3019 | 3038 | ||
3020 | /* not autodetected value */ | 3039 | /* not autodetected value */ |
3021 | { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ | 3040 | { 9600, SNDRV_PCM_RATE_KNOT, HDA_RATE(48, 1, 5) }, |
3022 | 3041 | ||
3023 | { 0 } /* terminator */ | 3042 | { 0 } /* terminator */ |
3024 | }; | 3043 | }; |
@@ -3037,7 +3056,8 @@ static struct hda_rate_tbl rate_bits[] = { | |||
3037 | unsigned int snd_hda_calc_stream_format(unsigned int rate, | 3056 | unsigned int snd_hda_calc_stream_format(unsigned int rate, |
3038 | unsigned int channels, | 3057 | unsigned int channels, |
3039 | unsigned int format, | 3058 | unsigned int format, |
3040 | unsigned int maxbps) | 3059 | unsigned int maxbps, |
3060 | unsigned short spdif_ctls) | ||
3041 | { | 3061 | { |
3042 | int i; | 3062 | int i; |
3043 | unsigned int val = 0; | 3063 | unsigned int val = 0; |
@@ -3060,20 +3080,20 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
3060 | 3080 | ||
3061 | switch (snd_pcm_format_width(format)) { | 3081 | switch (snd_pcm_format_width(format)) { |
3062 | case 8: | 3082 | case 8: |
3063 | val |= 0x00; | 3083 | val |= AC_FMT_BITS_8; |
3064 | break; | 3084 | break; |
3065 | case 16: | 3085 | case 16: |
3066 | val |= 0x10; | 3086 | val |= AC_FMT_BITS_16; |
3067 | break; | 3087 | break; |
3068 | case 20: | 3088 | case 20: |
3069 | case 24: | 3089 | case 24: |
3070 | case 32: | 3090 | case 32: |
3071 | if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE) | 3091 | if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE) |
3072 | val |= 0x40; | 3092 | val |= AC_FMT_BITS_32; |
3073 | else if (maxbps >= 24) | 3093 | else if (maxbps >= 24) |
3074 | val |= 0x30; | 3094 | val |= AC_FMT_BITS_24; |
3075 | else | 3095 | else |
3076 | val |= 0x20; | 3096 | val |= AC_FMT_BITS_20; |
3077 | break; | 3097 | break; |
3078 | default: | 3098 | default: |
3079 | snd_printdd("invalid format width %d\n", | 3099 | snd_printdd("invalid format width %d\n", |
@@ -3081,6 +3101,9 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
3081 | return 0; | 3101 | return 0; |
3082 | } | 3102 | } |
3083 | 3103 | ||
3104 | if (spdif_ctls & AC_DIG1_NONAUDIO) | ||
3105 | val |= AC_FMT_TYPE_NON_PCM; | ||
3106 | |||
3084 | return val; | 3107 | return val; |
3085 | } | 3108 | } |
3086 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); | 3109 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 5991d14e1ec0..46f75bccf0d3 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -224,6 +224,27 @@ enum { | |||
224 | /* Input converter SDI select */ | 224 | /* Input converter SDI select */ |
225 | #define AC_SDI_SELECT (0xf<<0) | 225 | #define AC_SDI_SELECT (0xf<<0) |
226 | 226 | ||
227 | /* stream format id */ | ||
228 | #define AC_FMT_CHAN_SHIFT 0 | ||
229 | #define AC_FMT_CHAN_MASK (0x0f << 0) | ||
230 | #define AC_FMT_BITS_SHIFT 4 | ||
231 | #define AC_FMT_BITS_MASK (7 << 4) | ||
232 | #define AC_FMT_BITS_8 (0 << 4) | ||
233 | #define AC_FMT_BITS_16 (1 << 4) | ||
234 | #define AC_FMT_BITS_20 (2 << 4) | ||
235 | #define AC_FMT_BITS_24 (3 << 4) | ||
236 | #define AC_FMT_BITS_32 (4 << 4) | ||
237 | #define AC_FMT_DIV_SHIFT 8 | ||
238 | #define AC_FMT_DIV_MASK (7 << 8) | ||
239 | #define AC_FMT_MULT_SHIFT 11 | ||
240 | #define AC_FMT_MULT_MASK (7 << 11) | ||
241 | #define AC_FMT_BASE_SHIFT 14 | ||
242 | #define AC_FMT_BASE_48K (0 << 14) | ||
243 | #define AC_FMT_BASE_44K (1 << 14) | ||
244 | #define AC_FMT_TYPE_SHIFT 15 | ||
245 | #define AC_FMT_TYPE_PCM (0 << 15) | ||
246 | #define AC_FMT_TYPE_NON_PCM (1 << 15) | ||
247 | |||
227 | /* Unsolicited response control */ | 248 | /* Unsolicited response control */ |
228 | #define AC_UNSOL_TAG (0x3f<<0) | 249 | #define AC_UNSOL_TAG (0x3f<<0) |
229 | #define AC_UNSOL_ENABLED (1<<7) | 250 | #define AC_UNSOL_ENABLED (1<<7) |
@@ -364,6 +385,9 @@ enum { | |||
364 | #define AC_DIG2_CC (0x7f<<0) | 385 | #define AC_DIG2_CC (0x7f<<0) |
365 | 386 | ||
366 | /* Pin widget control - 8bit */ | 387 | /* Pin widget control - 8bit */ |
388 | #define AC_PINCTL_EPT (0x3<<0) | ||
389 | #define AC_PINCTL_EPT_NATIVE 0 | ||
390 | #define AC_PINCTL_EPT_HBR 3 | ||
367 | #define AC_PINCTL_VREFEN (0x7<<0) | 391 | #define AC_PINCTL_VREFEN (0x7<<0) |
368 | #define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */ | 392 | #define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */ |
369 | #define AC_PINCTL_VREF_50 1 /* 50% */ | 393 | #define AC_PINCTL_VREF_50 1 /* 50% */ |
@@ -928,7 +952,8 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid); | |||
928 | unsigned int snd_hda_calc_stream_format(unsigned int rate, | 952 | unsigned int snd_hda_calc_stream_format(unsigned int rate, |
929 | unsigned int channels, | 953 | unsigned int channels, |
930 | unsigned int format, | 954 | unsigned int format, |
931 | unsigned int maxbps); | 955 | unsigned int maxbps, |
956 | unsigned short spdif_ctls); | ||
932 | int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, | 957 | int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, |
933 | unsigned int format); | 958 | unsigned int format); |
934 | 959 | ||
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index a1fc83753cc6..bf3ced51e0f8 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
@@ -649,7 +649,9 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus, | |||
649 | *codecp = NULL; | 649 | *codecp = NULL; |
650 | if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { | 650 | if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { |
651 | list_for_each_entry(codec, &bus->codec_list, list) { | 651 | list_for_each_entry(codec, &bus->codec_list, list) { |
652 | if (codec->addr == caddr) { | 652 | if (codec->vendor_id == vendorid && |
653 | codec->subsystem_id == subid && | ||
654 | codec->addr == caddr) { | ||
653 | *codecp = codec; | 655 | *codecp = codec; |
654 | break; | 656 | break; |
655 | } | 657 | } |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1df25cf5ce38..66d420212d9a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1653,7 +1653,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1653 | format_val = snd_hda_calc_stream_format(runtime->rate, | 1653 | format_val = snd_hda_calc_stream_format(runtime->rate, |
1654 | runtime->channels, | 1654 | runtime->channels, |
1655 | runtime->format, | 1655 | runtime->format, |
1656 | hinfo->maxbps); | 1656 | hinfo->maxbps, |
1657 | apcm->codec->spdif_ctls); | ||
1657 | if (!format_val) { | 1658 | if (!format_val) { |
1658 | snd_printk(KERN_ERR SFX | 1659 | snd_printk(KERN_ERR SFX |
1659 | "invalid format_val, rate=%d, ch=%d, format=%d\n", | 1660 | "invalid format_val, rate=%d, ch=%d, format=%d\n", |
@@ -1960,7 +1961,7 @@ static void azx_irq_pending_work(struct work_struct *work) | |||
1960 | spin_unlock_irq(&chip->reg_lock); | 1961 | spin_unlock_irq(&chip->reg_lock); |
1961 | if (!pending) | 1962 | if (!pending) |
1962 | return; | 1963 | return; |
1963 | cond_resched(); | 1964 | msleep(1); |
1964 | } | 1965 | } |
1965 | } | 1966 | } |
1966 | 1967 | ||
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index afbe314a5bf3..b697fd2a6f8b 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -3662,7 +3662,12 @@ static int patch_ad1984(struct hda_codec *codec) | |||
3662 | codec->patch_ops.build_pcms = ad1984_build_pcms; | 3662 | codec->patch_ops.build_pcms = ad1984_build_pcms; |
3663 | break; | 3663 | break; |
3664 | case AD1984_THINKPAD: | 3664 | case AD1984_THINKPAD: |
3665 | spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; | 3665 | if (codec->subsystem_id == 0x17aa20fb) { |
3666 | /* Thinpad X300 does not have the ability to do SPDIF, | ||
3667 | or attach to docking station to use SPDIF */ | ||
3668 | spec->multiout.dig_out_nid = 0; | ||
3669 | } else | ||
3670 | spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; | ||
3666 | spec->input_mux = &ad1984_thinkpad_capture_source; | 3671 | spec->input_mux = &ad1984_thinkpad_capture_source; |
3667 | spec->mixers[0] = ad1984_thinkpad_mixers; | 3672 | spec->mixers[0] = ad1984_thinkpad_mixers; |
3668 | spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; | 3673 | spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 2bf2cb5da956..df8b19b17308 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -131,6 +131,8 @@ struct conexant_spec { | |||
131 | unsigned int dc_enable; | 131 | unsigned int dc_enable; |
132 | unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ | 132 | unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ |
133 | unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ | 133 | unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ |
134 | |||
135 | unsigned int beep_amp; | ||
134 | }; | 136 | }; |
135 | 137 | ||
136 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, | 138 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, |
@@ -515,6 +517,15 @@ static struct snd_kcontrol_new cxt_capture_mixers[] = { | |||
515 | {} | 517 | {} |
516 | }; | 518 | }; |
517 | 519 | ||
520 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
521 | /* additional beep mixers; the actual parameters are overwritten at build */ | ||
522 | static struct snd_kcontrol_new cxt_beep_mixer[] = { | ||
523 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), | ||
524 | HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), | ||
525 | { } /* end */ | ||
526 | }; | ||
527 | #endif | ||
528 | |||
518 | static const char *slave_vols[] = { | 529 | static const char *slave_vols[] = { |
519 | "Headphone Playback Volume", | 530 | "Headphone Playback Volume", |
520 | "Speaker Playback Volume", | 531 | "Speaker Playback Volume", |
@@ -580,16 +591,52 @@ static int conexant_build_controls(struct hda_codec *codec) | |||
580 | return err; | 591 | return err; |
581 | } | 592 | } |
582 | 593 | ||
594 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
595 | /* create beep controls if needed */ | ||
596 | if (spec->beep_amp) { | ||
597 | struct snd_kcontrol_new *knew; | ||
598 | for (knew = cxt_beep_mixer; knew->name; knew++) { | ||
599 | struct snd_kcontrol *kctl; | ||
600 | kctl = snd_ctl_new1(knew, codec); | ||
601 | if (!kctl) | ||
602 | return -ENOMEM; | ||
603 | kctl->private_value = spec->beep_amp; | ||
604 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
605 | if (err < 0) | ||
606 | return err; | ||
607 | } | ||
608 | } | ||
609 | #endif | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
615 | static int conexant_suspend(struct hda_codec *codec, pm_message_t state) | ||
616 | { | ||
617 | snd_hda_shutup_pins(codec); | ||
583 | return 0; | 618 | return 0; |
584 | } | 619 | } |
620 | #endif | ||
585 | 621 | ||
586 | static struct hda_codec_ops conexant_patch_ops = { | 622 | static struct hda_codec_ops conexant_patch_ops = { |
587 | .build_controls = conexant_build_controls, | 623 | .build_controls = conexant_build_controls, |
588 | .build_pcms = conexant_build_pcms, | 624 | .build_pcms = conexant_build_pcms, |
589 | .init = conexant_init, | 625 | .init = conexant_init, |
590 | .free = conexant_free, | 626 | .free = conexant_free, |
627 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
628 | .suspend = conexant_suspend, | ||
629 | #endif | ||
630 | .reboot_notify = snd_hda_shutup_pins, | ||
591 | }; | 631 | }; |
592 | 632 | ||
633 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
634 | #define set_beep_amp(spec, nid, idx, dir) \ | ||
635 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) | ||
636 | #else | ||
637 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | ||
638 | #endif | ||
639 | |||
593 | /* | 640 | /* |
594 | * EAPD control | 641 | * EAPD control |
595 | * the private value = nid | (invert << 8) | 642 | * the private value = nid | (invert << 8) |
@@ -1130,9 +1177,10 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
1130 | spec->num_init_verbs = 1; | 1177 | spec->num_init_verbs = 1; |
1131 | spec->init_verbs[0] = cxt5045_init_verbs; | 1178 | spec->init_verbs[0] = cxt5045_init_verbs; |
1132 | spec->spdif_route = 0; | 1179 | spec->spdif_route = 0; |
1133 | spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes), | 1180 | spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes); |
1134 | spec->channel_mode = cxt5045_modes, | 1181 | spec->channel_mode = cxt5045_modes; |
1135 | 1182 | ||
1183 | set_beep_amp(spec, 0x16, 0, 1); | ||
1136 | 1184 | ||
1137 | codec->patch_ops = conexant_patch_ops; | 1185 | codec->patch_ops = conexant_patch_ops; |
1138 | 1186 | ||
@@ -1211,6 +1259,9 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
1211 | break; | 1259 | break; |
1212 | } | 1260 | } |
1213 | 1261 | ||
1262 | if (spec->beep_amp) | ||
1263 | snd_hda_attach_beep_device(codec, spec->beep_amp); | ||
1264 | |||
1214 | return 0; | 1265 | return 0; |
1215 | } | 1266 | } |
1216 | 1267 | ||
@@ -1632,6 +1683,11 @@ static void cxt5051_update_speaker(struct hda_codec *codec) | |||
1632 | pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; | 1683 | pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; |
1633 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 1684 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
1634 | pinctl); | 1685 | pinctl); |
1686 | /* on ideapad there is an aditional speaker (subwoofer) to mute */ | ||
1687 | if (spec->ideapad) | ||
1688 | snd_hda_codec_write(codec, 0x1b, 0, | ||
1689 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1690 | pinctl); | ||
1635 | } | 1691 | } |
1636 | 1692 | ||
1637 | /* turn on/off EAPD (+ mute HP) as a master switch */ | 1693 | /* turn on/off EAPD (+ mute HP) as a master switch */ |
@@ -1888,6 +1944,13 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid, | |||
1888 | #endif | 1944 | #endif |
1889 | } | 1945 | } |
1890 | 1946 | ||
1947 | static struct hda_verb cxt5051_ideapad_init_verbs[] = { | ||
1948 | /* Subwoofer */ | ||
1949 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1950 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1951 | { } /* end */ | ||
1952 | }; | ||
1953 | |||
1891 | /* initialize jack-sensing, too */ | 1954 | /* initialize jack-sensing, too */ |
1892 | static int cxt5051_init(struct hda_codec *codec) | 1955 | static int cxt5051_init(struct hda_codec *codec) |
1893 | { | 1956 | { |
@@ -1917,6 +1980,7 @@ enum { | |||
1917 | CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */ | 1980 | CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */ |
1918 | CXT5051_F700, /* HP Compaq Presario F700 */ | 1981 | CXT5051_F700, /* HP Compaq Presario F700 */ |
1919 | CXT5051_TOSHIBA, /* Toshiba M300 & co */ | 1982 | CXT5051_TOSHIBA, /* Toshiba M300 & co */ |
1983 | CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ | ||
1920 | CXT5051_MODELS | 1984 | CXT5051_MODELS |
1921 | }; | 1985 | }; |
1922 | 1986 | ||
@@ -1927,6 +1991,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = { | |||
1927 | [CXT5051_LENOVO_X200] = "lenovo-x200", | 1991 | [CXT5051_LENOVO_X200] = "lenovo-x200", |
1928 | [CXT5051_F700] = "hp-700", | 1992 | [CXT5051_F700] = "hp-700", |
1929 | [CXT5051_TOSHIBA] = "toshiba", | 1993 | [CXT5051_TOSHIBA] = "toshiba", |
1994 | [CXT5051_IDEAPAD] = "ideapad", | ||
1930 | }; | 1995 | }; |
1931 | 1996 | ||
1932 | static struct snd_pci_quirk cxt5051_cfg_tbl[] = { | 1997 | static struct snd_pci_quirk cxt5051_cfg_tbl[] = { |
@@ -1938,6 +2003,7 @@ static struct snd_pci_quirk cxt5051_cfg_tbl[] = { | |||
1938 | CXT5051_LAPTOP), | 2003 | CXT5051_LAPTOP), |
1939 | SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), | 2004 | SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), |
1940 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), | 2005 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), |
2006 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD), | ||
1941 | {} | 2007 | {} |
1942 | }; | 2008 | }; |
1943 | 2009 | ||
@@ -1972,6 +2038,8 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
1972 | spec->cur_adc = 0; | 2038 | spec->cur_adc = 0; |
1973 | spec->cur_adc_idx = 0; | 2039 | spec->cur_adc_idx = 0; |
1974 | 2040 | ||
2041 | set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); | ||
2042 | |||
1975 | codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; | 2043 | codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; |
1976 | 2044 | ||
1977 | board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, | 2045 | board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, |
@@ -1989,6 +2057,10 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
1989 | break; | 2057 | break; |
1990 | case CXT5051_LENOVO_X200: | 2058 | case CXT5051_LENOVO_X200: |
1991 | spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; | 2059 | spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; |
2060 | /* Thinkpad X301 does not have S/PDIF wired and no ability | ||
2061 | to use a docking station. */ | ||
2062 | if (codec->subsystem_id == 0x17aa211f) | ||
2063 | spec->multiout.dig_out_nid = 0; | ||
1992 | break; | 2064 | break; |
1993 | case CXT5051_F700: | 2065 | case CXT5051_F700: |
1994 | spec->init_verbs[0] = cxt5051_f700_init_verbs; | 2066 | spec->init_verbs[0] = cxt5051_f700_init_verbs; |
@@ -1999,8 +2071,16 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
1999 | spec->mixers[0] = cxt5051_toshiba_mixers; | 2071 | spec->mixers[0] = cxt5051_toshiba_mixers; |
2000 | spec->auto_mic = AUTO_MIC_PORTB; | 2072 | spec->auto_mic = AUTO_MIC_PORTB; |
2001 | break; | 2073 | break; |
2074 | case CXT5051_IDEAPAD: | ||
2075 | spec->init_verbs[spec->num_init_verbs++] = | ||
2076 | cxt5051_ideapad_init_verbs; | ||
2077 | spec->ideapad = 1; | ||
2078 | break; | ||
2002 | } | 2079 | } |
2003 | 2080 | ||
2081 | if (spec->beep_amp) | ||
2082 | snd_hda_attach_beep_device(codec, spec->beep_amp); | ||
2083 | |||
2004 | return 0; | 2084 | return 0; |
2005 | } | 2085 | } |
2006 | 2086 | ||
@@ -2616,7 +2696,6 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { | |||
2616 | .put = cxt5066_mic_boost_mux_enum_put, | 2696 | .put = cxt5066_mic_boost_mux_enum_put, |
2617 | .private_value = 0x23 | 0x100, | 2697 | .private_value = 0x23 | 0x100, |
2618 | }, | 2698 | }, |
2619 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), | ||
2620 | {} | 2699 | {} |
2621 | }; | 2700 | }; |
2622 | 2701 | ||
@@ -2977,8 +3056,10 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
2977 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), | 3056 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), |
2978 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), | 3057 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), |
2979 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), | 3058 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), |
3059 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | ||
3060 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), | ||
3061 | SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD), | ||
2980 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), | 3062 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), |
2981 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | ||
2982 | {} | 3063 | {} |
2983 | }; | 3064 | }; |
2984 | 3065 | ||
@@ -3014,6 +3095,8 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3014 | spec->cur_adc = 0; | 3095 | spec->cur_adc = 0; |
3015 | spec->cur_adc_idx = 0; | 3096 | spec->cur_adc_idx = 0; |
3016 | 3097 | ||
3098 | set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); | ||
3099 | |||
3017 | board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, | 3100 | board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, |
3018 | cxt5066_models, cxt5066_cfg_tbl); | 3101 | cxt5066_models, cxt5066_cfg_tbl); |
3019 | switch (board_config) { | 3102 | switch (board_config) { |
@@ -3062,7 +3145,6 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3062 | spec->port_d_mode = 0; | 3145 | spec->port_d_mode = 0; |
3063 | spec->dell_vostro = 1; | 3146 | spec->dell_vostro = 1; |
3064 | spec->mic_boost = 3; /* default 30dB gain */ | 3147 | spec->mic_boost = 3; /* default 30dB gain */ |
3065 | snd_hda_attach_beep_device(codec, 0x13); | ||
3066 | 3148 | ||
3067 | /* no S/PDIF out */ | 3149 | /* no S/PDIF out */ |
3068 | spec->multiout.dig_out_nid = 0; | 3150 | spec->multiout.dig_out_nid = 0; |
@@ -3104,6 +3186,9 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3104 | break; | 3186 | break; |
3105 | } | 3187 | } |
3106 | 3188 | ||
3189 | if (spec->beep_amp) | ||
3190 | snd_hda_attach_beep_device(codec, spec->beep_amp); | ||
3191 | |||
3107 | return 0; | 3192 | return 0; |
3108 | } | 3193 | } |
3109 | 3194 | ||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 2fc53961054e..522e0748ee99 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -698,11 +698,51 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res) | |||
698 | * Callbacks | 698 | * Callbacks |
699 | */ | 699 | */ |
700 | 700 | ||
701 | static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | 701 | /* HBR should be Non-PCM, 8 channels */ |
702 | #define is_hbr_format(format) \ | ||
703 | ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7) | ||
704 | |||
705 | static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | ||
702 | u32 stream_tag, int format) | 706 | u32 stream_tag, int format) |
703 | { | 707 | { |
708 | struct hdmi_spec *spec = codec->spec; | ||
704 | int tag; | 709 | int tag; |
705 | int fmt; | 710 | int fmt; |
711 | int pinctl; | ||
712 | int new_pinctl = 0; | ||
713 | int i; | ||
714 | |||
715 | for (i = 0; i < spec->num_pins; i++) { | ||
716 | if (spec->pin_cvt[i] != nid) | ||
717 | continue; | ||
718 | if (!(snd_hda_query_pin_caps(codec, spec->pin[i]) & AC_PINCAP_HBR)) | ||
719 | continue; | ||
720 | |||
721 | pinctl = snd_hda_codec_read(codec, spec->pin[i], 0, | ||
722 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
723 | |||
724 | new_pinctl = pinctl & ~AC_PINCTL_EPT; | ||
725 | if (is_hbr_format(format)) | ||
726 | new_pinctl |= AC_PINCTL_EPT_HBR; | ||
727 | else | ||
728 | new_pinctl |= AC_PINCTL_EPT_NATIVE; | ||
729 | |||
730 | snd_printdd("hdmi_setup_stream: " | ||
731 | "NID=0x%x, %spinctl=0x%x\n", | ||
732 | spec->pin[i], | ||
733 | pinctl == new_pinctl ? "" : "new-", | ||
734 | new_pinctl); | ||
735 | |||
736 | if (pinctl != new_pinctl) | ||
737 | snd_hda_codec_write(codec, spec->pin[i], 0, | ||
738 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
739 | new_pinctl); | ||
740 | } | ||
741 | |||
742 | if (is_hbr_format(format) && !new_pinctl) { | ||
743 | snd_printdd("hdmi_setup_stream: HBR is not supported\n"); | ||
744 | return -EINVAL; | ||
745 | } | ||
706 | 746 | ||
707 | tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4; | 747 | tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4; |
708 | fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0); | 748 | fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0); |
@@ -722,6 +762,7 @@ static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
722 | if (fmt != format) | 762 | if (fmt != format) |
723 | snd_hda_codec_write(codec, nid, 0, | 763 | snd_hda_codec_write(codec, nid, 0, |
724 | AC_VERB_SET_STREAM_FORMAT, format); | 764 | AC_VERB_SET_STREAM_FORMAT, format); |
765 | return 0; | ||
725 | } | 766 | } |
726 | 767 | ||
727 | /* | 768 | /* |
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c index b81d23e42ace..5972d5e7d01f 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
@@ -66,8 +66,7 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
66 | 66 | ||
67 | hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); | 67 | hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); |
68 | 68 | ||
69 | hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); | 69 | return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); |
70 | return 0; | ||
71 | } | 70 | } |
72 | 71 | ||
73 | static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 72 | static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index b0652acee9b2..a281836fd472 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c | |||
@@ -202,8 +202,7 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo, | |||
202 | 202 | ||
203 | hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); | 203 | hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); |
204 | 204 | ||
205 | hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); | 205 | return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); |
206 | return 0; | ||
207 | } | 206 | } |
208 | 207 | ||
209 | static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, | 208 | static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 596ea2f12cf6..6ac53f7de549 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -256,6 +256,13 @@ enum { | |||
256 | ALC882_MODEL_LAST, | 256 | ALC882_MODEL_LAST, |
257 | }; | 257 | }; |
258 | 258 | ||
259 | /* ALC680 models */ | ||
260 | enum { | ||
261 | ALC680_BASE, | ||
262 | ALC680_AUTO, | ||
263 | ALC680_MODEL_LAST, | ||
264 | }; | ||
265 | |||
259 | /* for GPIO Poll */ | 266 | /* for GPIO Poll */ |
260 | #define GPIO_MASK 0x03 | 267 | #define GPIO_MASK 0x03 |
261 | 268 | ||
@@ -326,6 +333,12 @@ struct alc_spec { | |||
326 | hda_nid_t *capsrc_nids; | 333 | hda_nid_t *capsrc_nids; |
327 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | 334 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ |
328 | 335 | ||
336 | /* capture setup for dynamic dual-adc switch */ | ||
337 | unsigned int cur_adc_idx; | ||
338 | hda_nid_t cur_adc; | ||
339 | unsigned int cur_adc_stream_tag; | ||
340 | unsigned int cur_adc_format; | ||
341 | |||
329 | /* capture source */ | 342 | /* capture source */ |
330 | unsigned int num_mux_defs; | 343 | unsigned int num_mux_defs; |
331 | const struct hda_input_mux *input_mux; | 344 | const struct hda_input_mux *input_mux; |
@@ -367,6 +380,7 @@ struct alc_spec { | |||
367 | 380 | ||
368 | /* other flags */ | 381 | /* other flags */ |
369 | unsigned int no_analog :1; /* digital I/O only */ | 382 | unsigned int no_analog :1; /* digital I/O only */ |
383 | unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ | ||
370 | int init_amp; | 384 | int init_amp; |
371 | 385 | ||
372 | /* for virtual master */ | 386 | /* for virtual master */ |
@@ -833,9 +847,13 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, | |||
833 | 847 | ||
834 | if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { | 848 | if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { |
835 | unsigned int pincap; | 849 | unsigned int pincap; |
850 | unsigned int oldval; | ||
851 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
852 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
836 | pincap = snd_hda_query_pin_caps(codec, nid); | 853 | pincap = snd_hda_query_pin_caps(codec, nid); |
837 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; | 854 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; |
838 | if (pincap & AC_PINCAP_VREF_80) | 855 | /* if the default pin setup is vref50, we give it priority */ |
856 | if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) | ||
839 | val = PIN_VREF80; | 857 | val = PIN_VREF80; |
840 | else if (pincap & AC_PINCAP_VREF_50) | 858 | else if (pincap & AC_PINCAP_VREF_50) |
841 | val = PIN_VREF50; | 859 | val = PIN_VREF50; |
@@ -1003,6 +1021,29 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | |||
1003 | return -1; | 1021 | return -1; |
1004 | } | 1022 | } |
1005 | 1023 | ||
1024 | /* switch the current ADC according to the jack state */ | ||
1025 | static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) | ||
1026 | { | ||
1027 | struct alc_spec *spec = codec->spec; | ||
1028 | unsigned int present; | ||
1029 | hda_nid_t new_adc; | ||
1030 | |||
1031 | present = snd_hda_jack_detect(codec, spec->ext_mic.pin); | ||
1032 | if (present) | ||
1033 | spec->cur_adc_idx = 1; | ||
1034 | else | ||
1035 | spec->cur_adc_idx = 0; | ||
1036 | new_adc = spec->adc_nids[spec->cur_adc_idx]; | ||
1037 | if (spec->cur_adc && spec->cur_adc != new_adc) { | ||
1038 | /* stream is running, let's swap the current ADC */ | ||
1039 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
1040 | spec->cur_adc = new_adc; | ||
1041 | snd_hda_codec_setup_stream(codec, new_adc, | ||
1042 | spec->cur_adc_stream_tag, 0, | ||
1043 | spec->cur_adc_format); | ||
1044 | } | ||
1045 | } | ||
1046 | |||
1006 | static void alc_mic_automute(struct hda_codec *codec) | 1047 | static void alc_mic_automute(struct hda_codec *codec) |
1007 | { | 1048 | { |
1008 | struct alc_spec *spec = codec->spec; | 1049 | struct alc_spec *spec = codec->spec; |
@@ -1017,6 +1058,11 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
1017 | if (snd_BUG_ON(!spec->adc_nids)) | 1058 | if (snd_BUG_ON(!spec->adc_nids)) |
1018 | return; | 1059 | return; |
1019 | 1060 | ||
1061 | if (spec->dual_adc_switch) { | ||
1062 | alc_dual_mic_adc_auto_switch(codec); | ||
1063 | return; | ||
1064 | } | ||
1065 | |||
1020 | cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; | 1066 | cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; |
1021 | 1067 | ||
1022 | present = snd_hda_jack_detect(codec, spec->ext_mic.pin); | 1068 | present = snd_hda_jack_detect(codec, spec->ext_mic.pin); |
@@ -1499,6 +1545,63 @@ static int alc_read_coef_idx(struct hda_codec *codec, | |||
1499 | return val; | 1545 | return val; |
1500 | } | 1546 | } |
1501 | 1547 | ||
1548 | /* set right pin controls for digital I/O */ | ||
1549 | static void alc_auto_init_digital(struct hda_codec *codec) | ||
1550 | { | ||
1551 | struct alc_spec *spec = codec->spec; | ||
1552 | int i; | ||
1553 | hda_nid_t pin; | ||
1554 | |||
1555 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
1556 | pin = spec->autocfg.dig_out_pins[i]; | ||
1557 | if (pin) { | ||
1558 | snd_hda_codec_write(codec, pin, 0, | ||
1559 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1560 | PIN_OUT); | ||
1561 | } | ||
1562 | } | ||
1563 | pin = spec->autocfg.dig_in_pin; | ||
1564 | if (pin) | ||
1565 | snd_hda_codec_write(codec, pin, 0, | ||
1566 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1567 | PIN_IN); | ||
1568 | } | ||
1569 | |||
1570 | /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ | ||
1571 | static void alc_auto_parse_digital(struct hda_codec *codec) | ||
1572 | { | ||
1573 | struct alc_spec *spec = codec->spec; | ||
1574 | int i, err; | ||
1575 | hda_nid_t dig_nid; | ||
1576 | |||
1577 | /* support multiple SPDIFs; the secondary is set up as a slave */ | ||
1578 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
1579 | err = snd_hda_get_connections(codec, | ||
1580 | spec->autocfg.dig_out_pins[i], | ||
1581 | &dig_nid, 1); | ||
1582 | if (err < 0) | ||
1583 | continue; | ||
1584 | if (!i) { | ||
1585 | spec->multiout.dig_out_nid = dig_nid; | ||
1586 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
1587 | } else { | ||
1588 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
1589 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
1590 | break; | ||
1591 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
1592 | } | ||
1593 | } | ||
1594 | |||
1595 | if (spec->autocfg.dig_in_pin) { | ||
1596 | hda_nid_t dig_nid; | ||
1597 | err = snd_hda_get_connections(codec, | ||
1598 | spec->autocfg.dig_in_pin, | ||
1599 | &dig_nid, 1); | ||
1600 | if (err > 0) | ||
1601 | spec->dig_in_nid = dig_nid; | ||
1602 | } | ||
1603 | } | ||
1604 | |||
1502 | /* | 1605 | /* |
1503 | * ALC888 | 1606 | * ALC888 |
1504 | */ | 1607 | */ |
@@ -3607,6 +3710,41 @@ static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
3607 | return 0; | 3710 | return 0; |
3608 | } | 3711 | } |
3609 | 3712 | ||
3713 | /* analog capture with dynamic dual-adc changes */ | ||
3714 | static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
3715 | struct hda_codec *codec, | ||
3716 | unsigned int stream_tag, | ||
3717 | unsigned int format, | ||
3718 | struct snd_pcm_substream *substream) | ||
3719 | { | ||
3720 | struct alc_spec *spec = codec->spec; | ||
3721 | spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; | ||
3722 | spec->cur_adc_stream_tag = stream_tag; | ||
3723 | spec->cur_adc_format = format; | ||
3724 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); | ||
3725 | return 0; | ||
3726 | } | ||
3727 | |||
3728 | static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
3729 | struct hda_codec *codec, | ||
3730 | struct snd_pcm_substream *substream) | ||
3731 | { | ||
3732 | struct alc_spec *spec = codec->spec; | ||
3733 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
3734 | spec->cur_adc = 0; | ||
3735 | return 0; | ||
3736 | } | ||
3737 | |||
3738 | static struct hda_pcm_stream dualmic_pcm_analog_capture = { | ||
3739 | .substreams = 1, | ||
3740 | .channels_min = 2, | ||
3741 | .channels_max = 2, | ||
3742 | .nid = 0, /* fill later */ | ||
3743 | .ops = { | ||
3744 | .prepare = dualmic_capture_pcm_prepare, | ||
3745 | .cleanup = dualmic_capture_pcm_cleanup | ||
3746 | }, | ||
3747 | }; | ||
3610 | 3748 | ||
3611 | /* | 3749 | /* |
3612 | */ | 3750 | */ |
@@ -4936,7 +5074,7 @@ static void alc880_auto_init_input_src(struct hda_codec *codec) | |||
4936 | static int alc880_parse_auto_config(struct hda_codec *codec) | 5074 | static int alc880_parse_auto_config(struct hda_codec *codec) |
4937 | { | 5075 | { |
4938 | struct alc_spec *spec = codec->spec; | 5076 | struct alc_spec *spec = codec->spec; |
4939 | int i, err; | 5077 | int err; |
4940 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; | 5078 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; |
4941 | 5079 | ||
4942 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 5080 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
@@ -4967,25 +5105,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
4967 | 5105 | ||
4968 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 5106 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
4969 | 5107 | ||
4970 | /* check multiple SPDIF-out (for recent codecs) */ | 5108 | alc_auto_parse_digital(codec); |
4971 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
4972 | hda_nid_t dig_nid; | ||
4973 | err = snd_hda_get_connections(codec, | ||
4974 | spec->autocfg.dig_out_pins[i], | ||
4975 | &dig_nid, 1); | ||
4976 | if (err < 0) | ||
4977 | continue; | ||
4978 | if (!i) | ||
4979 | spec->multiout.dig_out_nid = dig_nid; | ||
4980 | else { | ||
4981 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
4982 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
4983 | break; | ||
4984 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
4985 | } | ||
4986 | } | ||
4987 | if (spec->autocfg.dig_in_pin) | ||
4988 | spec->dig_in_nid = ALC880_DIGIN_NID; | ||
4989 | 5109 | ||
4990 | if (spec->kctls.list) | 5110 | if (spec->kctls.list) |
4991 | add_mixer(spec, spec->kctls.list); | 5111 | add_mixer(spec, spec->kctls.list); |
@@ -5008,6 +5128,7 @@ static void alc880_auto_init(struct hda_codec *codec) | |||
5008 | alc880_auto_init_extra_out(codec); | 5128 | alc880_auto_init_extra_out(codec); |
5009 | alc880_auto_init_analog_input(codec); | 5129 | alc880_auto_init_analog_input(codec); |
5010 | alc880_auto_init_input_src(codec); | 5130 | alc880_auto_init_input_src(codec); |
5131 | alc_auto_init_digital(codec); | ||
5011 | if (spec->unsol_event) | 5132 | if (spec->unsol_event) |
5012 | alc_inithook(codec); | 5133 | alc_inithook(codec); |
5013 | } | 5134 | } |
@@ -5045,6 +5166,39 @@ static void fixup_automic_adc(struct hda_codec *codec) | |||
5045 | spec->auto_mic = 0; /* disable auto-mic to be sure */ | 5166 | spec->auto_mic = 0; /* disable auto-mic to be sure */ |
5046 | } | 5167 | } |
5047 | 5168 | ||
5169 | /* select or unmute the given capsrc route */ | ||
5170 | static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, | ||
5171 | int idx) | ||
5172 | { | ||
5173 | if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { | ||
5174 | snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, | ||
5175 | HDA_AMP_MUTE, 0); | ||
5176 | } else { | ||
5177 | snd_hda_codec_write_cache(codec, cap, 0, | ||
5178 | AC_VERB_SET_CONNECT_SEL, idx); | ||
5179 | } | ||
5180 | } | ||
5181 | |||
5182 | /* set the default connection to that pin */ | ||
5183 | static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) | ||
5184 | { | ||
5185 | struct alc_spec *spec = codec->spec; | ||
5186 | int i; | ||
5187 | |||
5188 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
5189 | hda_nid_t cap = spec->capsrc_nids ? | ||
5190 | spec->capsrc_nids[i] : spec->adc_nids[i]; | ||
5191 | int idx; | ||
5192 | |||
5193 | idx = get_connection_index(codec, cap, pin); | ||
5194 | if (idx < 0) | ||
5195 | continue; | ||
5196 | select_or_unmute_capsrc(codec, cap, idx); | ||
5197 | return i; /* return the found index */ | ||
5198 | } | ||
5199 | return -1; /* not found */ | ||
5200 | } | ||
5201 | |||
5048 | /* choose the ADC/MUX containing the input pin and initialize the setup */ | 5202 | /* choose the ADC/MUX containing the input pin and initialize the setup */ |
5049 | static void fixup_single_adc(struct hda_codec *codec) | 5203 | static void fixup_single_adc(struct hda_codec *codec) |
5050 | { | 5204 | { |
@@ -5061,33 +5215,24 @@ static void fixup_single_adc(struct hda_codec *codec) | |||
5061 | } | 5215 | } |
5062 | if (!pin) | 5216 | if (!pin) |
5063 | return; | 5217 | return; |
5064 | 5218 | i = init_capsrc_for_pin(codec, pin); | |
5065 | /* set the default connection to that pin */ | 5219 | if (i >= 0) { |
5066 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
5067 | hda_nid_t cap = spec->capsrc_nids ? | ||
5068 | spec->capsrc_nids[i] : spec->adc_nids[i]; | ||
5069 | int idx; | ||
5070 | |||
5071 | idx = get_connection_index(codec, cap, pin); | ||
5072 | if (idx < 0) | ||
5073 | continue; | ||
5074 | /* use only this ADC */ | 5220 | /* use only this ADC */ |
5075 | if (spec->capsrc_nids) | 5221 | if (spec->capsrc_nids) |
5076 | spec->capsrc_nids += i; | 5222 | spec->capsrc_nids += i; |
5077 | spec->adc_nids += i; | 5223 | spec->adc_nids += i; |
5078 | spec->num_adc_nids = 1; | 5224 | spec->num_adc_nids = 1; |
5079 | /* select or unmute this route */ | ||
5080 | if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { | ||
5081 | snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, | ||
5082 | HDA_AMP_MUTE, 0); | ||
5083 | } else { | ||
5084 | snd_hda_codec_write_cache(codec, cap, 0, | ||
5085 | AC_VERB_SET_CONNECT_SEL, idx); | ||
5086 | } | ||
5087 | return; | ||
5088 | } | 5225 | } |
5089 | } | 5226 | } |
5090 | 5227 | ||
5228 | /* initialize dual adcs */ | ||
5229 | static void fixup_dual_adc_switch(struct hda_codec *codec) | ||
5230 | { | ||
5231 | struct alc_spec *spec = codec->spec; | ||
5232 | init_capsrc_for_pin(codec, spec->ext_mic.pin); | ||
5233 | init_capsrc_for_pin(codec, spec->int_mic.pin); | ||
5234 | } | ||
5235 | |||
5091 | static void set_capture_mixer(struct hda_codec *codec) | 5236 | static void set_capture_mixer(struct hda_codec *codec) |
5092 | { | 5237 | { |
5093 | struct alc_spec *spec = codec->spec; | 5238 | struct alc_spec *spec = codec->spec; |
@@ -5101,7 +5246,10 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
5101 | }; | 5246 | }; |
5102 | if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { | 5247 | if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { |
5103 | int mux = 0; | 5248 | int mux = 0; |
5104 | if (spec->auto_mic) | 5249 | int num_adcs = spec->num_adc_nids; |
5250 | if (spec->dual_adc_switch) | ||
5251 | fixup_dual_adc_switch(codec); | ||
5252 | else if (spec->auto_mic) | ||
5105 | fixup_automic_adc(codec); | 5253 | fixup_automic_adc(codec); |
5106 | else if (spec->input_mux) { | 5254 | else if (spec->input_mux) { |
5107 | if (spec->input_mux->num_items > 1) | 5255 | if (spec->input_mux->num_items > 1) |
@@ -5109,7 +5257,9 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
5109 | else if (spec->input_mux->num_items == 1) | 5257 | else if (spec->input_mux->num_items == 1) |
5110 | fixup_single_adc(codec); | 5258 | fixup_single_adc(codec); |
5111 | } | 5259 | } |
5112 | spec->cap_mixer = caps[mux][spec->num_adc_nids - 1]; | 5260 | if (spec->dual_adc_switch) |
5261 | num_adcs = 1; | ||
5262 | spec->cap_mixer = caps[mux][num_adcs - 1]; | ||
5113 | } | 5263 | } |
5114 | } | 5264 | } |
5115 | 5265 | ||
@@ -5183,6 +5333,7 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5183 | 5333 | ||
5184 | static struct snd_pci_quirk beep_white_list[] = { | 5334 | static struct snd_pci_quirk beep_white_list[] = { |
5185 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), | 5335 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), |
5336 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), | ||
5186 | {} | 5337 | {} |
5187 | }; | 5338 | }; |
5188 | 5339 | ||
@@ -6624,6 +6775,7 @@ static void alc260_auto_init(struct hda_codec *codec) | |||
6624 | alc260_auto_init_multi_out(codec); | 6775 | alc260_auto_init_multi_out(codec); |
6625 | alc260_auto_init_analog_input(codec); | 6776 | alc260_auto_init_analog_input(codec); |
6626 | alc260_auto_init_input_src(codec); | 6777 | alc260_auto_init_input_src(codec); |
6778 | alc_auto_init_digital(codec); | ||
6627 | if (spec->unsol_event) | 6779 | if (spec->unsol_event) |
6628 | alc_inithook(codec); | 6780 | alc_inithook(codec); |
6629 | } | 6781 | } |
@@ -6640,6 +6792,29 @@ static struct hda_amp_list alc260_loopbacks[] = { | |||
6640 | #endif | 6792 | #endif |
6641 | 6793 | ||
6642 | /* | 6794 | /* |
6795 | * Pin config fixes | ||
6796 | */ | ||
6797 | enum { | ||
6798 | PINFIX_HP_DC5750, | ||
6799 | }; | ||
6800 | |||
6801 | static struct alc_pincfg alc260_hp_dc5750_pinfix[] = { | ||
6802 | { 0x11, 0x90130110 }, /* speaker */ | ||
6803 | { } | ||
6804 | }; | ||
6805 | |||
6806 | static const struct alc_fixup alc260_fixups[] = { | ||
6807 | [PINFIX_HP_DC5750] = { | ||
6808 | .pins = alc260_hp_dc5750_pinfix | ||
6809 | }, | ||
6810 | }; | ||
6811 | |||
6812 | static struct snd_pci_quirk alc260_fixup_tbl[] = { | ||
6813 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), | ||
6814 | {} | ||
6815 | }; | ||
6816 | |||
6817 | /* | ||
6643 | * ALC260 configurations | 6818 | * ALC260 configurations |
6644 | */ | 6819 | */ |
6645 | static const char *alc260_models[ALC260_MODEL_LAST] = { | 6820 | static const char *alc260_models[ALC260_MODEL_LAST] = { |
@@ -6838,6 +7013,9 @@ static int patch_alc260(struct hda_codec *codec) | |||
6838 | board_config = ALC260_AUTO; | 7013 | board_config = ALC260_AUTO; |
6839 | } | 7014 | } |
6840 | 7015 | ||
7016 | if (board_config == ALC260_AUTO) | ||
7017 | alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1); | ||
7018 | |||
6841 | if (board_config == ALC260_AUTO) { | 7019 | if (board_config == ALC260_AUTO) { |
6842 | /* automatic parse from the BIOS config */ | 7020 | /* automatic parse from the BIOS config */ |
6843 | err = alc260_parse_auto_config(codec); | 7021 | err = alc260_parse_auto_config(codec); |
@@ -6883,6 +7061,9 @@ static int patch_alc260(struct hda_codec *codec) | |||
6883 | set_capture_mixer(codec); | 7061 | set_capture_mixer(codec); |
6884 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); | 7062 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); |
6885 | 7063 | ||
7064 | if (board_config == ALC260_AUTO) | ||
7065 | alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0); | ||
7066 | |||
6886 | spec->vmaster_nid = 0x08; | 7067 | spec->vmaster_nid = 0x08; |
6887 | 7068 | ||
6888 | codec->patch_ops = alc_patch_ops; | 7069 | codec->patch_ops = alc_patch_ops; |
@@ -7003,7 +7184,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { | |||
7003 | .num_items = 4, | 7184 | .num_items = 4, |
7004 | .items = { | 7185 | .items = { |
7005 | { "Mic", 0x0 }, | 7186 | { "Mic", 0x0 }, |
7006 | { "iMic", 0x1 }, | 7187 | { "Int Mic", 0x1 }, |
7007 | { "Line", 0x2 }, | 7188 | { "Line", 0x2 }, |
7008 | { "CD", 0x4 }, | 7189 | { "CD", 0x4 }, |
7009 | }, | 7190 | }, |
@@ -8573,8 +8754,8 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { | |||
8573 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 8754 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
8574 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 8755 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
8575 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 8756 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
8576 | HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 8757 | HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
8577 | HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 8758 | HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
8578 | { } /* end */ | 8759 | { } /* end */ |
8579 | }; | 8760 | }; |
8580 | 8761 | ||
@@ -10265,7 +10446,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
10265 | * Pin config fixes | 10446 | * Pin config fixes |
10266 | */ | 10447 | */ |
10267 | enum { | 10448 | enum { |
10268 | PINFIX_ABIT_AW9D_MAX | 10449 | PINFIX_ABIT_AW9D_MAX, |
10450 | PINFIX_PB_M5210, | ||
10269 | }; | 10451 | }; |
10270 | 10452 | ||
10271 | static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { | 10453 | static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { |
@@ -10275,13 +10457,22 @@ static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { | |||
10275 | { } | 10457 | { } |
10276 | }; | 10458 | }; |
10277 | 10459 | ||
10460 | static const struct hda_verb pb_m5210_verbs[] = { | ||
10461 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, | ||
10462 | {} | ||
10463 | }; | ||
10464 | |||
10278 | static const struct alc_fixup alc882_fixups[] = { | 10465 | static const struct alc_fixup alc882_fixups[] = { |
10279 | [PINFIX_ABIT_AW9D_MAX] = { | 10466 | [PINFIX_ABIT_AW9D_MAX] = { |
10280 | .pins = alc882_abit_aw9d_pinfix | 10467 | .pins = alc882_abit_aw9d_pinfix |
10281 | }, | 10468 | }, |
10469 | [PINFIX_PB_M5210] = { | ||
10470 | .verbs = pb_m5210_verbs | ||
10471 | }, | ||
10282 | }; | 10472 | }; |
10283 | 10473 | ||
10284 | static struct snd_pci_quirk alc882_fixup_tbl[] = { | 10474 | static struct snd_pci_quirk alc882_fixup_tbl[] = { |
10475 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), | ||
10285 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), | 10476 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), |
10286 | {} | 10477 | {} |
10287 | }; | 10478 | }; |
@@ -10446,7 +10637,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
10446 | { | 10637 | { |
10447 | struct alc_spec *spec = codec->spec; | 10638 | struct alc_spec *spec = codec->spec; |
10448 | static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; | 10639 | static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; |
10449 | int i, err; | 10640 | int err; |
10450 | 10641 | ||
10451 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 10642 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
10452 | alc882_ignore); | 10643 | alc882_ignore); |
@@ -10476,25 +10667,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
10476 | 10667 | ||
10477 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 10668 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
10478 | 10669 | ||
10479 | /* check multiple SPDIF-out (for recent codecs) */ | 10670 | alc_auto_parse_digital(codec); |
10480 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
10481 | hda_nid_t dig_nid; | ||
10482 | err = snd_hda_get_connections(codec, | ||
10483 | spec->autocfg.dig_out_pins[i], | ||
10484 | &dig_nid, 1); | ||
10485 | if (err < 0) | ||
10486 | continue; | ||
10487 | if (!i) | ||
10488 | spec->multiout.dig_out_nid = dig_nid; | ||
10489 | else { | ||
10490 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
10491 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
10492 | break; | ||
10493 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
10494 | } | ||
10495 | } | ||
10496 | if (spec->autocfg.dig_in_pin) | ||
10497 | spec->dig_in_nid = ALC880_DIGIN_NID; | ||
10498 | 10671 | ||
10499 | if (spec->kctls.list) | 10672 | if (spec->kctls.list) |
10500 | add_mixer(spec, spec->kctls.list); | 10673 | add_mixer(spec, spec->kctls.list); |
@@ -10524,6 +10697,7 @@ static void alc882_auto_init(struct hda_codec *codec) | |||
10524 | alc882_auto_init_hp_out(codec); | 10697 | alc882_auto_init_hp_out(codec); |
10525 | alc882_auto_init_analog_input(codec); | 10698 | alc882_auto_init_analog_input(codec); |
10526 | alc882_auto_init_input_src(codec); | 10699 | alc882_auto_init_input_src(codec); |
10700 | alc_auto_init_digital(codec); | ||
10527 | if (spec->unsol_event) | 10701 | if (spec->unsol_event) |
10528 | alc_inithook(codec); | 10702 | alc_inithook(codec); |
10529 | } | 10703 | } |
@@ -12054,12 +12228,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
12054 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 12228 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
12055 | 12229 | ||
12056 | dig_only: | 12230 | dig_only: |
12057 | if (spec->autocfg.dig_outs) { | 12231 | alc_auto_parse_digital(codec); |
12058 | spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; | ||
12059 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
12060 | } | ||
12061 | if (spec->autocfg.dig_in_pin) | ||
12062 | spec->dig_in_nid = ALC262_DIGIN_NID; | ||
12063 | 12232 | ||
12064 | if (spec->kctls.list) | 12233 | if (spec->kctls.list) |
12065 | add_mixer(spec, spec->kctls.list); | 12234 | add_mixer(spec, spec->kctls.list); |
@@ -12091,6 +12260,7 @@ static void alc262_auto_init(struct hda_codec *codec) | |||
12091 | alc262_auto_init_hp_out(codec); | 12260 | alc262_auto_init_hp_out(codec); |
12092 | alc262_auto_init_analog_input(codec); | 12261 | alc262_auto_init_analog_input(codec); |
12093 | alc262_auto_init_input_src(codec); | 12262 | alc262_auto_init_input_src(codec); |
12263 | alc_auto_init_digital(codec); | ||
12094 | if (spec->unsol_event) | 12264 | if (spec->unsol_event) |
12095 | alc_inithook(codec); | 12265 | alc_inithook(codec); |
12096 | } | 12266 | } |
@@ -13024,10 +13194,14 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | |||
13024 | dac = 0x02; | 13194 | dac = 0x02; |
13025 | break; | 13195 | break; |
13026 | case 0x15: | 13196 | case 0x15: |
13197 | case 0x1a: /* ALC259/269 only */ | ||
13198 | case 0x1b: /* ALC259/269 only */ | ||
13027 | case 0x21: /* ALC269vb has this pin, too */ | 13199 | case 0x21: /* ALC269vb has this pin, too */ |
13028 | dac = 0x03; | 13200 | dac = 0x03; |
13029 | break; | 13201 | break; |
13030 | default: | 13202 | default: |
13203 | snd_printd(KERN_WARNING "hda_codec: " | ||
13204 | "ignoring pin 0x%x as unknown\n", nid); | ||
13031 | return 0; | 13205 | return 0; |
13032 | } | 13206 | } |
13033 | if (spec->multiout.dac_nids[0] != dac && | 13207 | if (spec->multiout.dac_nids[0] != dac && |
@@ -13078,7 +13252,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
13078 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 13252 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); |
13079 | if (err < 0) | 13253 | if (err < 0) |
13080 | return err; | 13254 | return err; |
13081 | } else { | 13255 | } else if (nid) { |
13082 | err = alc268_new_analog_output(spec, nid, "Speaker", 0); | 13256 | err = alc268_new_analog_output(spec, nid, "Speaker", 0); |
13083 | if (err < 0) | 13257 | if (err < 0) |
13084 | return err; | 13258 | return err; |
@@ -13227,10 +13401,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
13227 | 13401 | ||
13228 | dig_only: | 13402 | dig_only: |
13229 | /* digital only support output */ | 13403 | /* digital only support output */ |
13230 | if (spec->autocfg.dig_outs) { | 13404 | alc_auto_parse_digital(codec); |
13231 | spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; | ||
13232 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
13233 | } | ||
13234 | if (spec->kctls.list) | 13405 | if (spec->kctls.list) |
13235 | add_mixer(spec, spec->kctls.list); | 13406 | add_mixer(spec, spec->kctls.list); |
13236 | 13407 | ||
@@ -13260,6 +13431,7 @@ static void alc268_auto_init(struct hda_codec *codec) | |||
13260 | alc268_auto_init_hp_out(codec); | 13431 | alc268_auto_init_hp_out(codec); |
13261 | alc268_auto_init_mono_speaker_out(codec); | 13432 | alc268_auto_init_mono_speaker_out(codec); |
13262 | alc268_auto_init_analog_input(codec); | 13433 | alc268_auto_init_analog_input(codec); |
13434 | alc_auto_init_digital(codec); | ||
13263 | if (spec->unsol_event) | 13435 | if (spec->unsol_event) |
13264 | alc_inithook(codec); | 13436 | alc_inithook(codec); |
13265 | } | 13437 | } |
@@ -14152,6 +14324,36 @@ static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) | |||
14152 | } | 14324 | } |
14153 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | 14325 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ |
14154 | 14326 | ||
14327 | static int alc275_setup_dual_adc(struct hda_codec *codec) | ||
14328 | { | ||
14329 | struct alc_spec *spec = codec->spec; | ||
14330 | |||
14331 | if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic) | ||
14332 | return 0; | ||
14333 | if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) || | ||
14334 | (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) { | ||
14335 | if (spec->ext_mic.pin <= 0x12) { | ||
14336 | spec->private_adc_nids[0] = 0x08; | ||
14337 | spec->private_adc_nids[1] = 0x11; | ||
14338 | spec->private_capsrc_nids[0] = 0x23; | ||
14339 | spec->private_capsrc_nids[1] = 0x22; | ||
14340 | } else { | ||
14341 | spec->private_adc_nids[0] = 0x11; | ||
14342 | spec->private_adc_nids[1] = 0x08; | ||
14343 | spec->private_capsrc_nids[0] = 0x22; | ||
14344 | spec->private_capsrc_nids[1] = 0x23; | ||
14345 | } | ||
14346 | spec->adc_nids = spec->private_adc_nids; | ||
14347 | spec->capsrc_nids = spec->private_capsrc_nids; | ||
14348 | spec->num_adc_nids = 2; | ||
14349 | spec->dual_adc_switch = 1; | ||
14350 | snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n", | ||
14351 | spec->adc_nids[0], spec->adc_nids[1]); | ||
14352 | return 1; | ||
14353 | } | ||
14354 | return 0; | ||
14355 | } | ||
14356 | |||
14155 | /* | 14357 | /* |
14156 | * BIOS auto configuration | 14358 | * BIOS auto configuration |
14157 | */ | 14359 | */ |
@@ -14175,8 +14377,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
14175 | 14377 | ||
14176 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 14378 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
14177 | 14379 | ||
14178 | if (spec->autocfg.dig_outs) | 14380 | alc_auto_parse_digital(codec); |
14179 | spec->multiout.dig_out_nid = ALC269_DIGOUT_NID; | ||
14180 | 14381 | ||
14181 | if (spec->kctls.list) | 14382 | if (spec->kctls.list) |
14182 | add_mixer(spec, spec->kctls.list); | 14383 | add_mixer(spec, spec->kctls.list); |
@@ -14191,13 +14392,15 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
14191 | 14392 | ||
14192 | spec->num_mux_defs = 1; | 14393 | spec->num_mux_defs = 1; |
14193 | spec->input_mux = &spec->private_imux[0]; | 14394 | spec->input_mux = &spec->private_imux[0]; |
14194 | fillup_priv_adc_nids(codec, alc269_adc_candidates, | 14395 | |
14195 | sizeof(alc269_adc_candidates)); | 14396 | if (!alc275_setup_dual_adc(codec)) |
14397 | fillup_priv_adc_nids(codec, alc269_adc_candidates, | ||
14398 | sizeof(alc269_adc_candidates)); | ||
14196 | 14399 | ||
14197 | /* set default input source */ | 14400 | /* set default input source */ |
14198 | snd_hda_codec_write_cache(codec, spec->capsrc_nids[0], | 14401 | if (!spec->dual_adc_switch) |
14199 | 0, AC_VERB_SET_CONNECT_SEL, | 14402 | select_or_unmute_capsrc(codec, spec->capsrc_nids[0], |
14200 | spec->input_mux->items[0].index); | 14403 | spec->input_mux->items[0].index); |
14201 | 14404 | ||
14202 | err = alc_auto_add_mic_boost(codec); | 14405 | err = alc_auto_add_mic_boost(codec); |
14203 | if (err < 0) | 14406 | if (err < 0) |
@@ -14221,6 +14424,7 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
14221 | alc269_auto_init_multi_out(codec); | 14424 | alc269_auto_init_multi_out(codec); |
14222 | alc269_auto_init_hp_out(codec); | 14425 | alc269_auto_init_hp_out(codec); |
14223 | alc269_auto_init_analog_input(codec); | 14426 | alc269_auto_init_analog_input(codec); |
14427 | alc_auto_init_digital(codec); | ||
14224 | if (spec->unsol_event) | 14428 | if (spec->unsol_event) |
14225 | alc_inithook(codec); | 14429 | alc_inithook(codec); |
14226 | } | 14430 | } |
@@ -14493,6 +14697,10 @@ static int patch_alc269(struct hda_codec *codec) | |||
14493 | */ | 14697 | */ |
14494 | spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; | 14698 | spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; |
14495 | spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; | 14699 | spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; |
14700 | } else if (spec->dual_adc_switch) { | ||
14701 | spec->stream_analog_playback = &alc269_pcm_analog_playback; | ||
14702 | /* switch ADC dynamically */ | ||
14703 | spec->stream_analog_capture = &dualmic_pcm_analog_capture; | ||
14496 | } else { | 14704 | } else { |
14497 | spec->stream_analog_playback = &alc269_pcm_analog_playback; | 14705 | spec->stream_analog_playback = &alc269_pcm_analog_playback; |
14498 | spec->stream_analog_capture = &alc269_pcm_analog_capture; | 14706 | spec->stream_analog_capture = &alc269_pcm_analog_capture; |
@@ -15378,8 +15586,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
15378 | 15586 | ||
15379 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 15587 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
15380 | 15588 | ||
15381 | if (spec->autocfg.dig_outs) | 15589 | alc_auto_parse_digital(codec); |
15382 | spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; | ||
15383 | 15590 | ||
15384 | if (spec->kctls.list) | 15591 | if (spec->kctls.list) |
15385 | add_mixer(spec, spec->kctls.list); | 15592 | add_mixer(spec, spec->kctls.list); |
@@ -15405,6 +15612,7 @@ static void alc861_auto_init(struct hda_codec *codec) | |||
15405 | alc861_auto_init_multi_out(codec); | 15612 | alc861_auto_init_multi_out(codec); |
15406 | alc861_auto_init_hp_out(codec); | 15613 | alc861_auto_init_hp_out(codec); |
15407 | alc861_auto_init_analog_input(codec); | 15614 | alc861_auto_init_analog_input(codec); |
15615 | alc_auto_init_digital(codec); | ||
15408 | if (spec->unsol_event) | 15616 | if (spec->unsol_event) |
15409 | alc_inithook(codec); | 15617 | alc_inithook(codec); |
15410 | } | 15618 | } |
@@ -16509,8 +16717,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
16509 | 16717 | ||
16510 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 16718 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
16511 | 16719 | ||
16512 | if (spec->autocfg.dig_outs) | 16720 | alc_auto_parse_digital(codec); |
16513 | spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; | ||
16514 | 16721 | ||
16515 | if (spec->kctls.list) | 16722 | if (spec->kctls.list) |
16516 | add_mixer(spec, spec->kctls.list); | 16723 | add_mixer(spec, spec->kctls.list); |
@@ -16537,6 +16744,7 @@ static void alc861vd_auto_init(struct hda_codec *codec) | |||
16537 | alc861vd_auto_init_hp_out(codec); | 16744 | alc861vd_auto_init_hp_out(codec); |
16538 | alc861vd_auto_init_analog_input(codec); | 16745 | alc861vd_auto_init_analog_input(codec); |
16539 | alc861vd_auto_init_input_src(codec); | 16746 | alc861vd_auto_init_input_src(codec); |
16747 | alc_auto_init_digital(codec); | ||
16540 | if (spec->unsol_event) | 16748 | if (spec->unsol_event) |
16541 | alc_inithook(codec); | 16749 | alc_inithook(codec); |
16542 | } | 16750 | } |
@@ -18520,7 +18728,7 @@ static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, | |||
18520 | hda_nid_t dac) | 18728 | hda_nid_t dac) |
18521 | { | 18729 | { |
18522 | int i, num; | 18730 | int i, num; |
18523 | hda_nid_t srcs[4]; | 18731 | hda_nid_t srcs[HDA_MAX_CONNECTIONS]; |
18524 | 18732 | ||
18525 | alc_set_pin_output(codec, nid, pin_type); | 18733 | alc_set_pin_output(codec, nid, pin_type); |
18526 | /* need the manual connection? */ | 18734 | /* need the manual connection? */ |
@@ -18624,8 +18832,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
18624 | 18832 | ||
18625 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 18833 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
18626 | 18834 | ||
18627 | if (spec->autocfg.dig_outs) | 18835 | alc_auto_parse_digital(codec); |
18628 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; | ||
18629 | 18836 | ||
18630 | if (spec->kctls.list) | 18837 | if (spec->kctls.list) |
18631 | add_mixer(spec, spec->kctls.list); | 18838 | add_mixer(spec, spec->kctls.list); |
@@ -18635,7 +18842,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
18635 | 18842 | ||
18636 | add_verb(spec, alc662_init_verbs); | 18843 | add_verb(spec, alc662_init_verbs); |
18637 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || | 18844 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || |
18638 | codec->vendor_id == 0x10ec0665) | 18845 | codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) |
18639 | add_verb(spec, alc663_init_verbs); | 18846 | add_verb(spec, alc663_init_verbs); |
18640 | 18847 | ||
18641 | if (codec->vendor_id == 0x10ec0272) | 18848 | if (codec->vendor_id == 0x10ec0272) |
@@ -18662,6 +18869,7 @@ static void alc662_auto_init(struct hda_codec *codec) | |||
18662 | alc662_auto_init_hp_out(codec); | 18869 | alc662_auto_init_hp_out(codec); |
18663 | alc662_auto_init_analog_input(codec); | 18870 | alc662_auto_init_analog_input(codec); |
18664 | alc662_auto_init_input_src(codec); | 18871 | alc662_auto_init_input_src(codec); |
18872 | alc_auto_init_digital(codec); | ||
18665 | if (spec->unsol_event) | 18873 | if (spec->unsol_event) |
18666 | alc_inithook(codec); | 18874 | alc_inithook(codec); |
18667 | } | 18875 | } |
@@ -18781,6 +18989,333 @@ static int patch_alc888(struct hda_codec *codec) | |||
18781 | } | 18989 | } |
18782 | 18990 | ||
18783 | /* | 18991 | /* |
18992 | * ALC680 support | ||
18993 | */ | ||
18994 | #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID | ||
18995 | #define alc680_modes alc260_modes | ||
18996 | |||
18997 | static hda_nid_t alc680_dac_nids[3] = { | ||
18998 | /* Lout1, Lout2, hp */ | ||
18999 | 0x02, 0x03, 0x04 | ||
19000 | }; | ||
19001 | |||
19002 | static hda_nid_t alc680_adc_nids[3] = { | ||
19003 | /* ADC0-2 */ | ||
19004 | /* DMIC, MIC, Line-in*/ | ||
19005 | 0x07, 0x08, 0x09 | ||
19006 | }; | ||
19007 | |||
19008 | static struct snd_kcontrol_new alc680_base_mixer[] = { | ||
19009 | /* output mixer control */ | ||
19010 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
19011 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
19012 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), | ||
19013 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), | ||
19014 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
19015 | { } | ||
19016 | }; | ||
19017 | |||
19018 | static struct snd_kcontrol_new alc680_capture_mixer[] = { | ||
19019 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | ||
19020 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | ||
19021 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), | ||
19022 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), | ||
19023 | HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), | ||
19024 | HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), | ||
19025 | { } /* end */ | ||
19026 | }; | ||
19027 | |||
19028 | /* | ||
19029 | * generic initialization of ADC, input mixers and output mixers | ||
19030 | */ | ||
19031 | static struct hda_verb alc680_init_verbs[] = { | ||
19032 | /* Unmute DAC0-1 and set vol = 0 */ | ||
19033 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
19034 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
19035 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
19036 | |||
19037 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
19038 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
19039 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | ||
19040 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
19041 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
19042 | |||
19043 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
19044 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
19045 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
19046 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
19047 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
19048 | { } | ||
19049 | }; | ||
19050 | |||
19051 | /* create input playback/capture controls for the given pin */ | ||
19052 | static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | ||
19053 | const char *ctlname, int idx) | ||
19054 | { | ||
19055 | hda_nid_t dac; | ||
19056 | int err; | ||
19057 | |||
19058 | switch (nid) { | ||
19059 | case 0x14: | ||
19060 | dac = 0x02; | ||
19061 | break; | ||
19062 | case 0x15: | ||
19063 | dac = 0x03; | ||
19064 | break; | ||
19065 | case 0x16: | ||
19066 | dac = 0x04; | ||
19067 | break; | ||
19068 | default: | ||
19069 | return 0; | ||
19070 | } | ||
19071 | if (spec->multiout.dac_nids[0] != dac && | ||
19072 | spec->multiout.dac_nids[1] != dac) { | ||
19073 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, | ||
19074 | HDA_COMPOSE_AMP_VAL(dac, 3, idx, | ||
19075 | HDA_OUTPUT)); | ||
19076 | if (err < 0) | ||
19077 | return err; | ||
19078 | |||
19079 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, | ||
19080 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); | ||
19081 | |||
19082 | if (err < 0) | ||
19083 | return err; | ||
19084 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; | ||
19085 | } | ||
19086 | |||
19087 | return 0; | ||
19088 | } | ||
19089 | |||
19090 | /* add playback controls from the parsed DAC table */ | ||
19091 | static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec, | ||
19092 | const struct auto_pin_cfg *cfg) | ||
19093 | { | ||
19094 | hda_nid_t nid; | ||
19095 | int err; | ||
19096 | |||
19097 | spec->multiout.dac_nids = spec->private_dac_nids; | ||
19098 | |||
19099 | nid = cfg->line_out_pins[0]; | ||
19100 | if (nid) { | ||
19101 | const char *name; | ||
19102 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
19103 | name = "Speaker"; | ||
19104 | else | ||
19105 | name = "Front"; | ||
19106 | err = alc680_new_analog_output(spec, nid, name, 0); | ||
19107 | if (err < 0) | ||
19108 | return err; | ||
19109 | } | ||
19110 | |||
19111 | nid = cfg->speaker_pins[0]; | ||
19112 | if (nid) { | ||
19113 | err = alc680_new_analog_output(spec, nid, "Speaker", 0); | ||
19114 | if (err < 0) | ||
19115 | return err; | ||
19116 | } | ||
19117 | nid = cfg->hp_pins[0]; | ||
19118 | if (nid) { | ||
19119 | err = alc680_new_analog_output(spec, nid, "Headphone", 0); | ||
19120 | if (err < 0) | ||
19121 | return err; | ||
19122 | } | ||
19123 | |||
19124 | return 0; | ||
19125 | } | ||
19126 | |||
19127 | static void alc680_auto_set_output_and_unmute(struct hda_codec *codec, | ||
19128 | hda_nid_t nid, int pin_type) | ||
19129 | { | ||
19130 | alc_set_pin_output(codec, nid, pin_type); | ||
19131 | } | ||
19132 | |||
19133 | static void alc680_auto_init_multi_out(struct hda_codec *codec) | ||
19134 | { | ||
19135 | struct alc_spec *spec = codec->spec; | ||
19136 | hda_nid_t nid = spec->autocfg.line_out_pins[0]; | ||
19137 | if (nid) { | ||
19138 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
19139 | alc680_auto_set_output_and_unmute(codec, nid, pin_type); | ||
19140 | } | ||
19141 | } | ||
19142 | |||
19143 | static void alc680_auto_init_hp_out(struct hda_codec *codec) | ||
19144 | { | ||
19145 | struct alc_spec *spec = codec->spec; | ||
19146 | hda_nid_t pin; | ||
19147 | |||
19148 | pin = spec->autocfg.hp_pins[0]; | ||
19149 | if (pin) | ||
19150 | alc680_auto_set_output_and_unmute(codec, pin, PIN_HP); | ||
19151 | pin = spec->autocfg.speaker_pins[0]; | ||
19152 | if (pin) | ||
19153 | alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT); | ||
19154 | } | ||
19155 | |||
19156 | /* pcm configuration: identical with ALC880 */ | ||
19157 | #define alc680_pcm_analog_playback alc880_pcm_analog_playback | ||
19158 | #define alc680_pcm_analog_capture alc880_pcm_analog_capture | ||
19159 | #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture | ||
19160 | #define alc680_pcm_digital_playback alc880_pcm_digital_playback | ||
19161 | |||
19162 | static struct hda_input_mux alc680_capture_source = { | ||
19163 | .num_items = 1, | ||
19164 | .items = { | ||
19165 | { "Mic", 0x0 }, | ||
19166 | }, | ||
19167 | }; | ||
19168 | |||
19169 | /* | ||
19170 | * BIOS auto configuration | ||
19171 | */ | ||
19172 | static int alc680_parse_auto_config(struct hda_codec *codec) | ||
19173 | { | ||
19174 | struct alc_spec *spec = codec->spec; | ||
19175 | int err; | ||
19176 | static hda_nid_t alc680_ignore[] = { 0 }; | ||
19177 | |||
19178 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | ||
19179 | alc680_ignore); | ||
19180 | if (err < 0) | ||
19181 | return err; | ||
19182 | if (!spec->autocfg.line_outs) { | ||
19183 | if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { | ||
19184 | spec->multiout.max_channels = 2; | ||
19185 | spec->no_analog = 1; | ||
19186 | goto dig_only; | ||
19187 | } | ||
19188 | return 0; /* can't find valid BIOS pin config */ | ||
19189 | } | ||
19190 | err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg); | ||
19191 | if (err < 0) | ||
19192 | return err; | ||
19193 | |||
19194 | spec->multiout.max_channels = 2; | ||
19195 | |||
19196 | dig_only: | ||
19197 | /* digital only support output */ | ||
19198 | alc_auto_parse_digital(codec); | ||
19199 | if (spec->kctls.list) | ||
19200 | add_mixer(spec, spec->kctls.list); | ||
19201 | |||
19202 | add_verb(spec, alc680_init_verbs); | ||
19203 | spec->num_mux_defs = 1; | ||
19204 | spec->input_mux = &alc680_capture_source; | ||
19205 | |||
19206 | err = alc_auto_add_mic_boost(codec); | ||
19207 | if (err < 0) | ||
19208 | return err; | ||
19209 | |||
19210 | return 1; | ||
19211 | } | ||
19212 | |||
19213 | #define alc680_auto_init_analog_input alc882_auto_init_analog_input | ||
19214 | |||
19215 | /* init callback for auto-configuration model -- overriding the default init */ | ||
19216 | static void alc680_auto_init(struct hda_codec *codec) | ||
19217 | { | ||
19218 | struct alc_spec *spec = codec->spec; | ||
19219 | alc680_auto_init_multi_out(codec); | ||
19220 | alc680_auto_init_hp_out(codec); | ||
19221 | alc680_auto_init_analog_input(codec); | ||
19222 | alc_auto_init_digital(codec); | ||
19223 | if (spec->unsol_event) | ||
19224 | alc_inithook(codec); | ||
19225 | } | ||
19226 | |||
19227 | /* | ||
19228 | * configuration and preset | ||
19229 | */ | ||
19230 | static const char *alc680_models[ALC680_MODEL_LAST] = { | ||
19231 | [ALC680_BASE] = "base", | ||
19232 | [ALC680_AUTO] = "auto", | ||
19233 | }; | ||
19234 | |||
19235 | static struct snd_pci_quirk alc680_cfg_tbl[] = { | ||
19236 | SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), | ||
19237 | {} | ||
19238 | }; | ||
19239 | |||
19240 | static struct alc_config_preset alc680_presets[] = { | ||
19241 | [ALC680_BASE] = { | ||
19242 | .mixers = { alc680_base_mixer }, | ||
19243 | .cap_mixer = alc680_capture_mixer, | ||
19244 | .init_verbs = { alc680_init_verbs }, | ||
19245 | .num_dacs = ARRAY_SIZE(alc680_dac_nids), | ||
19246 | .dac_nids = alc680_dac_nids, | ||
19247 | .num_adc_nids = ARRAY_SIZE(alc680_adc_nids), | ||
19248 | .adc_nids = alc680_adc_nids, | ||
19249 | .hp_nid = 0x04, | ||
19250 | .dig_out_nid = ALC680_DIGOUT_NID, | ||
19251 | .num_channel_mode = ARRAY_SIZE(alc680_modes), | ||
19252 | .channel_mode = alc680_modes, | ||
19253 | .input_mux = &alc680_capture_source, | ||
19254 | }, | ||
19255 | }; | ||
19256 | |||
19257 | static int patch_alc680(struct hda_codec *codec) | ||
19258 | { | ||
19259 | struct alc_spec *spec; | ||
19260 | int board_config; | ||
19261 | int err; | ||
19262 | |||
19263 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
19264 | if (spec == NULL) | ||
19265 | return -ENOMEM; | ||
19266 | |||
19267 | codec->spec = spec; | ||
19268 | |||
19269 | board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, | ||
19270 | alc680_models, | ||
19271 | alc680_cfg_tbl); | ||
19272 | |||
19273 | if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { | ||
19274 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
19275 | codec->chip_name); | ||
19276 | board_config = ALC680_AUTO; | ||
19277 | } | ||
19278 | |||
19279 | if (board_config == ALC680_AUTO) { | ||
19280 | /* automatic parse from the BIOS config */ | ||
19281 | err = alc680_parse_auto_config(codec); | ||
19282 | if (err < 0) { | ||
19283 | alc_free(codec); | ||
19284 | return err; | ||
19285 | } else if (!err) { | ||
19286 | printk(KERN_INFO | ||
19287 | "hda_codec: Cannot set up configuration " | ||
19288 | "from BIOS. Using base mode...\n"); | ||
19289 | board_config = ALC680_BASE; | ||
19290 | } | ||
19291 | } | ||
19292 | |||
19293 | if (board_config != ALC680_AUTO) | ||
19294 | setup_preset(codec, &alc680_presets[board_config]); | ||
19295 | |||
19296 | spec->stream_analog_playback = &alc680_pcm_analog_playback; | ||
19297 | spec->stream_analog_capture = &alc680_pcm_analog_capture; | ||
19298 | spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture; | ||
19299 | spec->stream_digital_playback = &alc680_pcm_digital_playback; | ||
19300 | |||
19301 | if (!spec->adc_nids) { | ||
19302 | spec->adc_nids = alc680_adc_nids; | ||
19303 | spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids); | ||
19304 | } | ||
19305 | |||
19306 | if (!spec->cap_mixer) | ||
19307 | set_capture_mixer(codec); | ||
19308 | |||
19309 | spec->vmaster_nid = 0x02; | ||
19310 | |||
19311 | codec->patch_ops = alc_patch_ops; | ||
19312 | if (board_config == ALC680_AUTO) | ||
19313 | spec->init_hook = alc680_auto_init; | ||
19314 | |||
19315 | return 0; | ||
19316 | } | ||
19317 | |||
19318 | /* | ||
18784 | * patch entries | 19319 | * patch entries |
18785 | */ | 19320 | */ |
18786 | static struct hda_codec_preset snd_hda_preset_realtek[] = { | 19321 | static struct hda_codec_preset snd_hda_preset_realtek[] = { |
@@ -18804,6 +19339,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
18804 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, | 19339 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, |
18805 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, | 19340 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, |
18806 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, | 19341 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, |
19342 | { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, | ||
18807 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 19343 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
18808 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 19344 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
18809 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, | 19345 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index f1e7babd6920..b8d730c47df1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -202,6 +202,7 @@ struct sigmatel_spec { | |||
202 | unsigned int spdif_mute: 1; | 202 | unsigned int spdif_mute: 1; |
203 | unsigned int check_volume_offset:1; | 203 | unsigned int check_volume_offset:1; |
204 | unsigned int auto_mic:1; | 204 | unsigned int auto_mic:1; |
205 | unsigned int linear_tone_beep:1; | ||
205 | 206 | ||
206 | /* gpio lines */ | 207 | /* gpio lines */ |
207 | unsigned int eapd_mask; | 208 | unsigned int eapd_mask; |
@@ -3802,7 +3803,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3802 | return err; | 3803 | return err; |
3803 | if (codec->beep) { | 3804 | if (codec->beep) { |
3804 | /* IDT/STAC codecs have linear beep tone parameter */ | 3805 | /* IDT/STAC codecs have linear beep tone parameter */ |
3805 | codec->beep->linear_tone = 1; | 3806 | codec->beep->linear_tone = spec->linear_tone_beep; |
3806 | /* if no beep switch is available, make its own one */ | 3807 | /* if no beep switch is available, make its own one */ |
3807 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); | 3808 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); |
3808 | if (!(caps & AC_AMPCAP_MUTE)) { | 3809 | if (!(caps & AC_AMPCAP_MUTE)) { |
@@ -5005,6 +5006,7 @@ static int patch_stac9200(struct hda_codec *codec) | |||
5005 | 5006 | ||
5006 | codec->no_trigger_sense = 1; | 5007 | codec->no_trigger_sense = 1; |
5007 | codec->spec = spec; | 5008 | codec->spec = spec; |
5009 | spec->linear_tone_beep = 1; | ||
5008 | spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); | 5010 | spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); |
5009 | spec->pin_nids = stac9200_pin_nids; | 5011 | spec->pin_nids = stac9200_pin_nids; |
5010 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, | 5012 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, |
@@ -5068,6 +5070,7 @@ static int patch_stac925x(struct hda_codec *codec) | |||
5068 | 5070 | ||
5069 | codec->no_trigger_sense = 1; | 5071 | codec->no_trigger_sense = 1; |
5070 | codec->spec = spec; | 5072 | codec->spec = spec; |
5073 | spec->linear_tone_beep = 1; | ||
5071 | spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); | 5074 | spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); |
5072 | spec->pin_nids = stac925x_pin_nids; | 5075 | spec->pin_nids = stac925x_pin_nids; |
5073 | 5076 | ||
@@ -5153,6 +5156,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec) | |||
5153 | 5156 | ||
5154 | codec->no_trigger_sense = 1; | 5157 | codec->no_trigger_sense = 1; |
5155 | codec->spec = spec; | 5158 | codec->spec = spec; |
5159 | spec->linear_tone_beep = 0; | ||
5156 | codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; | 5160 | codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; |
5157 | spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); | 5161 | spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); |
5158 | spec->pin_nids = stac92hd73xx_pin_nids; | 5162 | spec->pin_nids = stac92hd73xx_pin_nids; |
@@ -5300,6 +5304,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5300 | 5304 | ||
5301 | codec->no_trigger_sense = 1; | 5305 | codec->no_trigger_sense = 1; |
5302 | codec->spec = spec; | 5306 | codec->spec = spec; |
5307 | spec->linear_tone_beep = 1; | ||
5303 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | 5308 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; |
5304 | spec->digbeep_nid = 0x21; | 5309 | spec->digbeep_nid = 0x21; |
5305 | spec->mux_nids = stac92hd83xxx_mux_nids; | 5310 | spec->mux_nids = stac92hd83xxx_mux_nids; |
@@ -5522,6 +5527,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
5522 | 5527 | ||
5523 | codec->no_trigger_sense = 1; | 5528 | codec->no_trigger_sense = 1; |
5524 | codec->spec = spec; | 5529 | codec->spec = spec; |
5530 | spec->linear_tone_beep = 0; | ||
5525 | codec->patch_ops = stac92xx_patch_ops; | 5531 | codec->patch_ops = stac92xx_patch_ops; |
5526 | spec->num_pins = STAC92HD71BXX_NUM_PINS; | 5532 | spec->num_pins = STAC92HD71BXX_NUM_PINS; |
5527 | switch (codec->vendor_id) { | 5533 | switch (codec->vendor_id) { |
@@ -5779,6 +5785,7 @@ static int patch_stac922x(struct hda_codec *codec) | |||
5779 | 5785 | ||
5780 | codec->no_trigger_sense = 1; | 5786 | codec->no_trigger_sense = 1; |
5781 | codec->spec = spec; | 5787 | codec->spec = spec; |
5788 | spec->linear_tone_beep = 1; | ||
5782 | spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); | 5789 | spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); |
5783 | spec->pin_nids = stac922x_pin_nids; | 5790 | spec->pin_nids = stac922x_pin_nids; |
5784 | spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, | 5791 | spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, |
@@ -5883,6 +5890,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5883 | 5890 | ||
5884 | codec->no_trigger_sense = 1; | 5891 | codec->no_trigger_sense = 1; |
5885 | codec->spec = spec; | 5892 | codec->spec = spec; |
5893 | spec->linear_tone_beep = 1; | ||
5886 | codec->slave_dig_outs = stac927x_slave_dig_outs; | 5894 | codec->slave_dig_outs = stac927x_slave_dig_outs; |
5887 | spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); | 5895 | spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); |
5888 | spec->pin_nids = stac927x_pin_nids; | 5896 | spec->pin_nids = stac927x_pin_nids; |
@@ -6018,6 +6026,7 @@ static int patch_stac9205(struct hda_codec *codec) | |||
6018 | 6026 | ||
6019 | codec->no_trigger_sense = 1; | 6027 | codec->no_trigger_sense = 1; |
6020 | codec->spec = spec; | 6028 | codec->spec = spec; |
6029 | spec->linear_tone_beep = 1; | ||
6021 | spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); | 6030 | spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); |
6022 | spec->pin_nids = stac9205_pin_nids; | 6031 | spec->pin_nids = stac9205_pin_nids; |
6023 | spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, | 6032 | spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, |
@@ -6174,6 +6183,7 @@ static int patch_stac9872(struct hda_codec *codec) | |||
6174 | return -ENOMEM; | 6183 | return -ENOMEM; |
6175 | codec->no_trigger_sense = 1; | 6184 | codec->no_trigger_sense = 1; |
6176 | codec->spec = spec; | 6185 | codec->spec = spec; |
6186 | spec->linear_tone_beep = 1; | ||
6177 | spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); | 6187 | spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); |
6178 | spec->pin_nids = stac9872_pin_nids; | 6188 | spec->pin_nids = stac9872_pin_nids; |
6179 | 6189 | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 73453814e098..ae3acb2b42d1 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -552,24 +552,30 @@ static void via_auto_init_hp_out(struct hda_codec *codec) | |||
552 | } | 552 | } |
553 | } | 553 | } |
554 | 554 | ||
555 | static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin); | ||
556 | |||
555 | static void via_auto_init_analog_input(struct hda_codec *codec) | 557 | static void via_auto_init_analog_input(struct hda_codec *codec) |
556 | { | 558 | { |
557 | struct via_spec *spec = codec->spec; | 559 | struct via_spec *spec = codec->spec; |
560 | unsigned int ctl; | ||
558 | int i; | 561 | int i; |
559 | 562 | ||
560 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 563 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
561 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 564 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
565 | if (!nid) | ||
566 | continue; | ||
562 | 567 | ||
568 | if (spec->smart51_enabled && is_smart51_pins(spec, nid)) | ||
569 | ctl = PIN_OUT; | ||
570 | else if (i <= AUTO_PIN_FRONT_MIC) | ||
571 | ctl = PIN_VREF50; | ||
572 | else | ||
573 | ctl = PIN_IN; | ||
563 | snd_hda_codec_write(codec, nid, 0, | 574 | snd_hda_codec_write(codec, nid, 0, |
564 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 575 | AC_VERB_SET_PIN_WIDGET_CONTROL, ctl); |
565 | (i <= AUTO_PIN_FRONT_MIC ? | ||
566 | PIN_VREF50 : PIN_IN)); | ||
567 | |||
568 | } | 576 | } |
569 | } | 577 | } |
570 | 578 | ||
571 | static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin); | ||
572 | |||
573 | static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, | 579 | static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, |
574 | unsigned int *affected_parm) | 580 | unsigned int *affected_parm) |
575 | { | 581 | { |
@@ -658,6 +664,8 @@ static void set_jack_power_state(struct hda_codec *codec) | |||
658 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ | 664 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ |
659 | parm = AC_PWRST_D3; | 665 | parm = AC_PWRST_D3; |
660 | set_pin_power_state(codec, 0x19, &parm); | 666 | set_pin_power_state(codec, 0x19, &parm); |
667 | if (spec->smart51_enabled) | ||
668 | parm = AC_PWRST_D0; | ||
661 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, | 669 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, |
662 | parm); | 670 | parm); |
663 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, | 671 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, |
@@ -667,6 +675,8 @@ static void set_jack_power_state(struct hda_codec *codec) | |||
667 | if (is_8ch) { | 675 | if (is_8ch) { |
668 | parm = AC_PWRST_D3; | 676 | parm = AC_PWRST_D3; |
669 | set_pin_power_state(codec, 0x22, &parm); | 677 | set_pin_power_state(codec, 0x22, &parm); |
678 | if (spec->smart51_enabled) | ||
679 | parm = AC_PWRST_D0; | ||
670 | snd_hda_codec_write(codec, 0x26, 0, | 680 | snd_hda_codec_write(codec, 0x26, 0, |
671 | AC_VERB_SET_POWER_STATE, parm); | 681 | AC_VERB_SET_POWER_STATE, parm); |
672 | snd_hda_codec_write(codec, 0x24, 0, | 682 | snd_hda_codec_write(codec, 0x24, 0, |
@@ -3915,6 +3925,13 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, | |||
3915 | } | 3925 | } |
3916 | } | 3926 | } |
3917 | 3927 | ||
3928 | /* for Smart 5.1, line/mic inputs double as output pins */ | ||
3929 | if (cfg->line_outs == 1) { | ||
3930 | spec->multiout.num_dacs = 3; | ||
3931 | spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11; | ||
3932 | spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24; | ||
3933 | } | ||
3934 | |||
3918 | return 0; | 3935 | return 0; |
3919 | } | 3936 | } |
3920 | 3937 | ||
@@ -3932,7 +3949,8 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, | |||
3932 | for (i = 0; i <= AUTO_SEQ_SIDE; i++) { | 3949 | for (i = 0; i <= AUTO_SEQ_SIDE; i++) { |
3933 | nid = cfg->line_out_pins[i]; | 3950 | nid = cfg->line_out_pins[i]; |
3934 | 3951 | ||
3935 | if (!nid) | 3952 | /* for Smart 5.1, there are always at least six channels */ |
3953 | if (!nid && i > AUTO_SEQ_CENLFE) | ||
3936 | continue; | 3954 | continue; |
3937 | 3955 | ||
3938 | nid_vol = nid_vols[i]; | 3956 | nid_vol = nid_vols[i]; |