aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt4
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt15
-rw-r--r--Documentation/sound/alsa/HD-Audio.txt64
-rw-r--r--sound/pci/hda/Kconfig14
-rw-r--r--sound/pci/hda/hda_beep.c4
-rw-r--r--sound/pci/hda/hda_codec.c65
-rw-r--r--sound/pci/hda/hda_codec.h10
-rw-r--r--sound/pci/hda/hda_generic.c18
-rw-r--r--sound/pci/hda/hda_hwdep.c236
-rw-r--r--sound/pci/hda/hda_intel.c48
-rw-r--r--sound/pci/hda/hda_local.h4
-rw-r--r--sound/pci/hda/hda_proc.c3
-rw-r--r--sound/pci/hda/patch_analog.c131
-rw-r--r--sound/pci/hda/patch_ca0110.c3
-rw-r--r--sound/pci/hda/patch_cmedia.c3
-rw-r--r--sound/pci/hda/patch_conexant.c479
-rw-r--r--sound/pci/hda/patch_intelhdmi.c2
-rw-r--r--sound/pci/hda/patch_realtek.c2393
-rw-r--r--sound/pci/hda/patch_sigmatel.c640
-rw-r--r--sound/pci/hda/patch_via.c3
20 files changed, 2539 insertions, 1600 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 4252697a95d6..f9d11140af91 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -768,6 +768,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
768 bdl_pos_adj - Specifies the DMA IRQ timing delay in samples. 768 bdl_pos_adj - Specifies the DMA IRQ timing delay in samples.
769 Passing -1 will make the driver to choose the appropriate 769 Passing -1 will make the driver to choose the appropriate
770 value based on the controller chip. 770 value based on the controller chip.
771 patch - Specifies the early "patch" files to modify the HD-audio
772 setup before initializing the codecs. This option is
773 available only when CONFIG_SND_HDA_PATCH_LOADER=y is set.
774 See HD-Audio.txt for details.
771 775
772 [Single (global) options] 776 [Single (global) options]
773 single_cmd - Use single immediate commands to communicate with 777 single_cmd - Use single immediate commands to communicate with
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 0d8d23581c44..4c95a6c3f79f 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -114,8 +114,8 @@ ALC662/663/272
114 samsung-nc10 Samsung NC10 mini notebook 114 samsung-nc10 Samsung NC10 mini notebook
115 auto auto-config reading BIOS (default) 115 auto auto-config reading BIOS (default)
116 116
117ALC882/885 117ALC882/883/885/888/889
118========== 118======================
119 3stack-dig 3-jack with SPDIF I/O 119 3stack-dig 3-jack with SPDIF I/O
120 6stack-dig 6-jack digital with SPDIF I/O 120 6stack-dig 6-jack digital with SPDIF I/O
121 arima Arima W820Di1 121 arima Arima W820Di1
@@ -127,12 +127,8 @@ ALC882/885
127 mbp3 Macbook Pro rev3 127 mbp3 Macbook Pro rev3
128 imac24 iMac 24'' with jack detection 128 imac24 iMac 24'' with jack detection
129 w2jc ASUS W2JC 129 w2jc ASUS W2JC
130 auto auto-config reading BIOS (default) 130 3stack-2ch-dig 3-jack with SPDIF I/O (ALC883)
131 131 alc883-6stack-dig 6-jack digital with SPDIF I/O (ALC883)
132ALC883/888
133==========
134 3stack-dig 3-jack with SPDIF I/O
135 6stack-dig 6-jack digital with SPDIF I/O
136 3stack-6ch 3-jack 6-channel 132 3stack-6ch 3-jack 6-channel
137 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O 133 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
138 6stack-dig-demo 6-jack digital for Intel demo board 134 6stack-dig-demo 6-jack digital for Intel demo board
@@ -159,6 +155,8 @@ ALC883/888
159 fujitsu-pi2515 Fujitsu AMILO Pi2515 155 fujitsu-pi2515 Fujitsu AMILO Pi2515
160 fujitsu-xa3530 Fujitsu AMILO XA3530 156 fujitsu-xa3530 Fujitsu AMILO XA3530
161 3stack-6ch-intel Intel DG33* boards 157 3stack-6ch-intel Intel DG33* boards
158 intel-alc889a Intel IbexPeak with ALC889A
159 intel-x58 Intel DX58 with ALC889
162 asus-p5q ASUS P5Q-EM boards 160 asus-p5q ASUS P5Q-EM boards
163 mb31 MacBook 3,1 161 mb31 MacBook 3,1
164 sony-vaio-tt Sony VAIO TT 162 sony-vaio-tt Sony VAIO TT
@@ -240,6 +238,7 @@ AD1986A
240 laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100) 238 laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100)
241 ultra 2-channel with EAPD (Samsung Ultra tablet PC) 239 ultra 2-channel with EAPD (Samsung Ultra tablet PC)
242 samsung 2-channel with EAPD (Samsung R65) 240 samsung 2-channel with EAPD (Samsung R65)
241 samsung-p50 2-channel with HP-automute (Samsung P50)
243 242
244AD1988/AD1988B/AD1989A/AD1989B 243AD1988/AD1988B/AD1989A/AD1989B
245============================== 244==============================
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt
index 71ac995b1915..7b8a5f947d1d 100644
--- a/Documentation/sound/alsa/HD-Audio.txt
+++ b/Documentation/sound/alsa/HD-Audio.txt
@@ -139,6 +139,10 @@ The driver checks PCI SSID and looks through the static configuration
139table until any matching entry is found. If you have a new machine, 139table until any matching entry is found. If you have a new machine,
140you may see a message like below: 140you may see a message like below:
141------------------------------------------------------------------------ 141------------------------------------------------------------------------
142 hda_codec: ALC880: BIOS auto-probing.
143------------------------------------------------------------------------
144Meanwhile, in the earlier versions, you would see a message like:
145------------------------------------------------------------------------
142 hda_codec: Unknown model for ALC880, trying auto-probe from BIOS... 146 hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...
143------------------------------------------------------------------------ 147------------------------------------------------------------------------
144Even if you see such a message, DON'T PANIC. Take a deep breath and 148Even if you see such a message, DON'T PANIC. Take a deep breath and
@@ -403,6 +407,66 @@ re-configure based on that state, run like below:
403------------------------------------------------------------------------ 407------------------------------------------------------------------------
404 408
405 409
410Early Patching
411~~~~~~~~~~~~~~
412When CONFIG_SND_HDA_PATCH_LOADER=y is set, you can pass a "patch" as a
413firmware file for modifying the HD-audio setup before initializing the
414codec. This can work basically like the reconfiguration via sysfs in
415the above, but it does it before the first codec configuration.
416
417A patch file is a plain text file which looks like below:
418
419------------------------------------------------------------------------
420 [codec]
421 0x12345678 0xabcd1234 2
422
423 [model]
424 auto
425
426 [pincfg]
427 0x12 0x411111f0
428
429 [verb]
430 0x20 0x500 0x03
431 0x20 0x400 0xff
432
433 [hint]
434 hp_detect = yes
435------------------------------------------------------------------------
436
437The file needs to have a line `[codec]`. The next line should contain
438three numbers indicating the codec vendor-id (0x12345678 in the
439example), the codec subsystem-id (0xabcd1234) and the address (2) of
440the codec. The rest patch entries are applied to this specified codec
441until another codec entry is given.
442
443The `[model]` line allows to change the model name of the each codec.
444In the example above, it will be changed to model=auto.
445Note that this overrides the module option.
446
447After the `[pincfg]` line, the contents are parsed as the initial
448default pin-configurations just like `user_pin_configs` sysfs above.
449The values can be shown in user_pin_configs sysfs file, too.
450
451Similarly, the lines after `[verb]` are parsed as `init_verbs`
452sysfs entries, and the lines after `[hint]` are parsed as `hints`
453sysfs entries, respectively.
454
455The hd-audio driver reads the file via request_firmware(). Thus,
456a patch file has to be located on the appropriate firmware path,
457typically, /lib/firmware. For example, when you pass the option
458`patch=hda-init.fw`, the file /lib/firmware/hda-init-fw must be
459present.
460
461The patch module option is specific to each card instance, and you
462need to give one file name for each instance, separated by commas.
463For example, if you have two cards, one for an on-board analog and one
464for an HDMI video board, you may pass patch option like below:
465------------------------------------------------------------------------
466 options snd-hda-intel patch=on-board-patch,hdmi-patch
467------------------------------------------------------------------------
468
469
406Power-Saving 470Power-Saving
407~~~~~~~~~~~~ 471~~~~~~~~~~~~
408The power-saving is a kind of auto-suspend of the device. When the 472The power-saving is a kind of auto-suspend of the device. When the
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 04438f1d682d..b8a77f9b0827 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -46,6 +46,20 @@ config SND_HDA_INPUT_JACK
46 Say Y here to enable the jack plugging notification via 46 Say Y here to enable the jack plugging notification via
47 input layer. 47 input layer.
48 48
49config SND_HDA_PATCH_LOADER
50 bool "Support initialization patch loading for HD-audio"
51 depends on EXPERIMENTAL
52 select FW_LOADER
53 select SND_HDA_HWDEP
54 select SND_HDA_RECONFIG
55 help
56 Say Y here to allow the HD-audio driver to load a pseudo
57 firmware file ("patch") for overriding the BIOS setup at
58 start up. The "patch" file can be specified via patch module
59 option, such as patch=hda-init.
60
61 This option turns on hwdep and reconfig features automatically.
62
49config SND_HDA_CODEC_REALTEK 63config SND_HDA_CODEC_REALTEK
50 bool "Build Realtek HD-audio codec support" 64 bool "Build Realtek HD-audio codec support"
51 default y 65 default y
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index b0275a050870..3f51a981e604 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -24,6 +24,7 @@
24#include <linux/workqueue.h> 24#include <linux/workqueue.h>
25#include <sound/core.h> 25#include <sound/core.h>
26#include "hda_beep.h" 26#include "hda_beep.h"
27#include "hda_local.h"
27 28
28enum { 29enum {
29 DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */ 30 DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */
@@ -118,6 +119,9 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
118 struct hda_beep *beep; 119 struct hda_beep *beep;
119 int err; 120 int err;
120 121
122 if (!snd_hda_get_bool_hint(codec, "beep"))
123 return 0; /* disabled explicitly */
124
121 beep = kzalloc(sizeof(*beep), GFP_KERNEL); 125 beep = kzalloc(sizeof(*beep), GFP_KERNEL);
122 if (beep == NULL) 126 if (beep == NULL)
123 return -ENOMEM; 127 return -ENOMEM;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 88480c0c58a0..3a603cde8cc4 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -150,7 +150,14 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
150{ 150{
151 u32 val; 151 u32 val;
152 152
153 val = (u32)(codec->addr & 0x0f) << 28; 153 if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) ||
154 (verb & ~0xfff) || (parm & ~0xffff)) {
155 printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n",
156 codec->addr, direct, nid, verb, parm);
157 return ~0;
158 }
159
160 val = (u32)codec->addr << 28;
154 val |= (u32)direct << 27; 161 val |= (u32)direct << 27;
155 val |= (u32)nid << 20; 162 val |= (u32)nid << 20;
156 val |= verb << 8; 163 val |= verb << 8;
@@ -167,6 +174,9 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
167 struct hda_bus *bus = codec->bus; 174 struct hda_bus *bus = codec->bus;
168 int err; 175 int err;
169 176
177 if (cmd == ~0)
178 return -1;
179
170 if (res) 180 if (res)
171 *res = -1; 181 *res = -1;
172 again: 182 again:
@@ -291,11 +301,20 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
291 unsigned int parm; 301 unsigned int parm;
292 int i, conn_len, conns; 302 int i, conn_len, conns;
293 unsigned int shift, num_elems, mask; 303 unsigned int shift, num_elems, mask;
304 unsigned int wcaps;
294 hda_nid_t prev_nid; 305 hda_nid_t prev_nid;
295 306
296 if (snd_BUG_ON(!conn_list || max_conns <= 0)) 307 if (snd_BUG_ON(!conn_list || max_conns <= 0))
297 return -EINVAL; 308 return -EINVAL;
298 309
310 wcaps = get_wcaps(codec, nid);
311 if (!(wcaps & AC_WCAP_CONN_LIST) &&
312 get_wcaps_type(wcaps) != AC_WID_VOL_KNB) {
313 snd_printk(KERN_WARNING "hda_codec: "
314 "connection list not available for 0x%x\n", nid);
315 return -EINVAL;
316 }
317
299 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); 318 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
300 if (parm & AC_CLIST_LONG) { 319 if (parm & AC_CLIST_LONG) {
301 /* long form */ 320 /* long form */
@@ -316,6 +335,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
316 /* single connection */ 335 /* single connection */
317 parm = snd_hda_codec_read(codec, nid, 0, 336 parm = snd_hda_codec_read(codec, nid, 0,
318 AC_VERB_GET_CONNECT_LIST, 0); 337 AC_VERB_GET_CONNECT_LIST, 0);
338 if (parm == -1 && codec->bus->rirb_error)
339 return -EIO;
319 conn_list[0] = parm & mask; 340 conn_list[0] = parm & mask;
320 return 1; 341 return 1;
321 } 342 }
@@ -327,9 +348,12 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
327 int range_val; 348 int range_val;
328 hda_nid_t val, n; 349 hda_nid_t val, n;
329 350
330 if (i % num_elems == 0) 351 if (i % num_elems == 0) {
331 parm = snd_hda_codec_read(codec, nid, 0, 352 parm = snd_hda_codec_read(codec, nid, 0,
332 AC_VERB_GET_CONNECT_LIST, i); 353 AC_VERB_GET_CONNECT_LIST, i);
354 if (parm == -1 && codec->bus->rirb_error)
355 return -EIO;
356 }
333 range_val = !!(parm & (1 << (shift-1))); /* ranges */ 357 range_val = !!(parm & (1 << (shift-1))); /* ranges */
334 val = parm & mask; 358 val = parm & mask;
335 if (val == 0) { 359 if (val == 0) {
@@ -727,8 +751,7 @@ static int read_pin_defaults(struct hda_codec *codec)
727 for (i = 0; i < codec->num_nodes; i++, nid++) { 751 for (i = 0; i < codec->num_nodes; i++, nid++) {
728 struct hda_pincfg *pin; 752 struct hda_pincfg *pin;
729 unsigned int wcaps = get_wcaps(codec, nid); 753 unsigned int wcaps = get_wcaps(codec, nid);
730 unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> 754 unsigned int wid_type = get_wcaps_type(wcaps);
731 AC_WCAP_TYPE_SHIFT;
732 if (wid_type != AC_WID_PIN) 755 if (wid_type != AC_WID_PIN)
733 continue; 756 continue;
734 pin = snd_array_new(&codec->init_pins); 757 pin = snd_array_new(&codec->init_pins);
@@ -891,7 +914,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
891 * Returns 0 if successful, or a negative error code. 914 * Returns 0 if successful, or a negative error code.
892 */ 915 */
893int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 916int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
894 int do_init, struct hda_codec **codecp) 917 struct hda_codec **codecp)
895{ 918{
896 struct hda_codec *codec; 919 struct hda_codec *codec;
897 char component[31]; 920 char component[31];
@@ -984,11 +1007,6 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
984 codec->afg ? codec->afg : codec->mfg, 1007 codec->afg ? codec->afg : codec->mfg,
985 AC_PWRST_D0); 1008 AC_PWRST_D0);
986 1009
987 if (do_init) {
988 err = snd_hda_codec_configure(codec);
989 if (err < 0)
990 goto error;
991 }
992 snd_hda_codec_proc_new(codec); 1010 snd_hda_codec_proc_new(codec);
993 1011
994 snd_hda_create_hwdep(codec); 1012 snd_hda_create_hwdep(codec);
@@ -1042,6 +1060,7 @@ int snd_hda_codec_configure(struct hda_codec *codec)
1042 err = init_unsol_queue(codec->bus); 1060 err = init_unsol_queue(codec->bus);
1043 return err; 1061 return err;
1044} 1062}
1063EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
1045 1064
1046/** 1065/**
1047 * snd_hda_codec_setup_stream - set up the codec for streaming 1066 * snd_hda_codec_setup_stream - set up the codec for streaming
@@ -2356,16 +2375,20 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2356 hda_nid_t nid; 2375 hda_nid_t nid;
2357 int i; 2376 int i;
2358 2377
2359 snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE, 2378 /* this delay seems necessary to avoid click noise at power-down */
2379 if (power_state == AC_PWRST_D3)
2380 msleep(100);
2381 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
2360 power_state); 2382 power_state);
2361 msleep(10); /* partial workaround for "azx_get_response timeout" */ 2383 /* partial workaround for "azx_get_response timeout" */
2384 if (power_state == AC_PWRST_D0)
2385 msleep(10);
2362 2386
2363 nid = codec->start_nid; 2387 nid = codec->start_nid;
2364 for (i = 0; i < codec->num_nodes; i++, nid++) { 2388 for (i = 0; i < codec->num_nodes; i++, nid++) {
2365 unsigned int wcaps = get_wcaps(codec, nid); 2389 unsigned int wcaps = get_wcaps(codec, nid);
2366 if (wcaps & AC_WCAP_POWER) { 2390 if (wcaps & AC_WCAP_POWER) {
2367 unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> 2391 unsigned int wid_type = get_wcaps_type(wcaps);
2368 AC_WCAP_TYPE_SHIFT;
2369 if (power_state == AC_PWRST_D3 && 2392 if (power_state == AC_PWRST_D3 &&
2370 wid_type == AC_WID_PIN) { 2393 wid_type == AC_WID_PIN) {
2371 unsigned int pincap; 2394 unsigned int pincap;
@@ -2573,7 +2596,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2573 case 20: 2596 case 20:
2574 case 24: 2597 case 24:
2575 case 32: 2598 case 32:
2576 if (maxbps >= 32) 2599 if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
2577 val |= 0x40; 2600 val |= 0x40;
2578 else if (maxbps >= 24) 2601 else if (maxbps >= 24)
2579 val |= 0x30; 2602 val |= 0x30;
@@ -2700,11 +2723,12 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
2700 bps = 20; 2723 bps = 20;
2701 } 2724 }
2702 } 2725 }
2703 else if (streams == AC_SUPFMT_FLOAT32) { 2726 if (streams & AC_SUPFMT_FLOAT32) {
2704 /* should be exclusive */
2705 formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; 2727 formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
2706 bps = 32; 2728 if (!bps)
2707 } else if (streams == AC_SUPFMT_AC3) { 2729 bps = 32;
2730 }
2731 if (streams == AC_SUPFMT_AC3) {
2708 /* should be exclusive */ 2732 /* should be exclusive */
2709 /* temporary hack: we have still no proper support 2733 /* temporary hack: we have still no proper support
2710 * for the direct AC3 stream... 2734 * for the direct AC3 stream...
@@ -3655,8 +3679,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
3655 end_nid = codec->start_nid + codec->num_nodes; 3679 end_nid = codec->start_nid + codec->num_nodes;
3656 for (nid = codec->start_nid; nid < end_nid; nid++) { 3680 for (nid = codec->start_nid; nid < end_nid; nid++) {
3657 unsigned int wid_caps = get_wcaps(codec, nid); 3681 unsigned int wid_caps = get_wcaps(codec, nid);
3658 unsigned int wid_type = 3682 unsigned int wid_type = get_wcaps_type(wid_caps);
3659 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3660 unsigned int def_conf; 3683 unsigned int def_conf;
3661 short assoc, loc; 3684 short assoc, loc;
3662 3685
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index cad79efaabc9..72c997592eed 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -830,7 +830,8 @@ enum {
830int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, 830int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
831 struct hda_bus **busp); 831 struct hda_bus **busp);
832int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 832int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
833 int do_init, struct hda_codec **codecp); 833 struct hda_codec **codecp);
834int snd_hda_codec_configure(struct hda_codec *codec);
834 835
835/* 836/*
836 * low level functions 837 * low level functions
@@ -938,6 +939,13 @@ static inline void snd_hda_power_down(struct hda_codec *codec) {}
938#define snd_hda_codec_needs_resume(codec) 1 939#define snd_hda_codec_needs_resume(codec) 1
939#endif 940#endif
940 941
942#ifdef CONFIG_SND_HDA_PATCH_LOADER
943/*
944 * patch firmware
945 */
946int snd_hda_load_patch(struct hda_bus *bus, const char *patch);
947#endif
948
941/* 949/*
942 * Codec modularization 950 * Codec modularization
943 */ 951 */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 1d5797a96682..b36f6c5a92df 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -121,11 +121,17 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
121 if (node == NULL) 121 if (node == NULL)
122 return -ENOMEM; 122 return -ENOMEM;
123 node->nid = nid; 123 node->nid = nid;
124 nconns = snd_hda_get_connections(codec, nid, conn_list, 124 node->wid_caps = get_wcaps(codec, nid);
125 HDA_MAX_CONNECTIONS); 125 node->type = get_wcaps_type(node->wid_caps);
126 if (nconns < 0) { 126 if (node->wid_caps & AC_WCAP_CONN_LIST) {
127 kfree(node); 127 nconns = snd_hda_get_connections(codec, nid, conn_list,
128 return nconns; 128 HDA_MAX_CONNECTIONS);
129 if (nconns < 0) {
130 kfree(node);
131 return nconns;
132 }
133 } else {
134 nconns = 0;
129 } 135 }
130 if (nconns <= ARRAY_SIZE(node->slist)) 136 if (nconns <= ARRAY_SIZE(node->slist))
131 node->conn_list = node->slist; 137 node->conn_list = node->slist;
@@ -140,8 +146,6 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
140 } 146 }
141 memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t)); 147 memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t));
142 node->nconns = nconns; 148 node->nconns = nconns;
143 node->wid_caps = get_wcaps(codec, nid);
144 node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
145 149
146 if (node->type == AC_WID_PIN) { 150 if (node->type == AC_WID_PIN) {
147 node->pin_caps = snd_hda_query_pin_caps(codec, node->nid); 151 node->pin_caps = snd_hda_query_pin_caps(codec, node->nid);
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 6812fbe80fa4..cc24e6721d74 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -24,6 +24,7 @@
24#include <linux/compat.h> 24#include <linux/compat.h>
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/ctype.h> 26#include <linux/ctype.h>
27#include <linux/firmware.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include "hda_codec.h" 29#include "hda_codec.h"
29#include "hda_local.h" 30#include "hda_local.h"
@@ -312,12 +313,8 @@ static ssize_t init_verbs_show(struct device *dev,
312 return len; 313 return len;
313} 314}
314 315
315static ssize_t init_verbs_store(struct device *dev, 316static int parse_init_verbs(struct hda_codec *codec, const char *buf)
316 struct device_attribute *attr,
317 const char *buf, size_t count)
318{ 317{
319 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
320 struct hda_codec *codec = hwdep->private_data;
321 struct hda_verb *v; 318 struct hda_verb *v;
322 int nid, verb, param; 319 int nid, verb, param;
323 320
@@ -331,6 +328,18 @@ static ssize_t init_verbs_store(struct device *dev,
331 v->nid = nid; 328 v->nid = nid;
332 v->verb = verb; 329 v->verb = verb;
333 v->param = param; 330 v->param = param;
331 return 0;
332}
333
334static ssize_t init_verbs_store(struct device *dev,
335 struct device_attribute *attr,
336 const char *buf, size_t count)
337{
338 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
339 struct hda_codec *codec = hwdep->private_data;
340 int err = parse_init_verbs(codec, buf);
341 if (err < 0)
342 return err;
334 return count; 343 return count;
335} 344}
336 345
@@ -376,19 +385,15 @@ static void remove_trail_spaces(char *str)
376 385
377#define MAX_HINTS 1024 386#define MAX_HINTS 1024
378 387
379static ssize_t hints_store(struct device *dev, 388static int parse_hints(struct hda_codec *codec, const char *buf)
380 struct device_attribute *attr,
381 const char *buf, size_t count)
382{ 389{
383 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
384 struct hda_codec *codec = hwdep->private_data;
385 char *key, *val; 390 char *key, *val;
386 struct hda_hint *hint; 391 struct hda_hint *hint;
387 392
388 while (isspace(*buf)) 393 while (isspace(*buf))
389 buf++; 394 buf++;
390 if (!*buf || *buf == '#' || *buf == '\n') 395 if (!*buf || *buf == '#' || *buf == '\n')
391 return count; 396 return 0;
392 if (*buf == '=') 397 if (*buf == '=')
393 return -EINVAL; 398 return -EINVAL;
394 key = kstrndup_noeol(buf, 1024); 399 key = kstrndup_noeol(buf, 1024);
@@ -411,7 +416,7 @@ static ssize_t hints_store(struct device *dev,
411 kfree(hint->key); 416 kfree(hint->key);
412 hint->key = key; 417 hint->key = key;
413 hint->val = val; 418 hint->val = val;
414 return count; 419 return 0;
415 } 420 }
416 /* allocate a new hint entry */ 421 /* allocate a new hint entry */
417 if (codec->hints.used >= MAX_HINTS) 422 if (codec->hints.used >= MAX_HINTS)
@@ -424,6 +429,18 @@ static ssize_t hints_store(struct device *dev,
424 } 429 }
425 hint->key = key; 430 hint->key = key;
426 hint->val = val; 431 hint->val = val;
432 return 0;
433}
434
435static ssize_t hints_store(struct device *dev,
436 struct device_attribute *attr,
437 const char *buf, size_t count)
438{
439 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
440 struct hda_codec *codec = hwdep->private_data;
441 int err = parse_hints(codec, buf);
442 if (err < 0)
443 return err;
427 return count; 444 return count;
428} 445}
429 446
@@ -469,20 +486,24 @@ static ssize_t driver_pin_configs_show(struct device *dev,
469 486
470#define MAX_PIN_CONFIGS 32 487#define MAX_PIN_CONFIGS 32
471 488
472static ssize_t user_pin_configs_store(struct device *dev, 489static int parse_user_pin_configs(struct hda_codec *codec, const char *buf)
473 struct device_attribute *attr,
474 const char *buf, size_t count)
475{ 490{
476 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
477 struct hda_codec *codec = hwdep->private_data;
478 int nid, cfg; 491 int nid, cfg;
479 int err;
480 492
481 if (sscanf(buf, "%i %i", &nid, &cfg) != 2) 493 if (sscanf(buf, "%i %i", &nid, &cfg) != 2)
482 return -EINVAL; 494 return -EINVAL;
483 if (!nid) 495 if (!nid)
484 return -EINVAL; 496 return -EINVAL;
485 err = snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg); 497 return snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg);
498}
499
500static ssize_t user_pin_configs_store(struct device *dev,
501 struct device_attribute *attr,
502 const char *buf, size_t count)
503{
504 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
505 struct hda_codec *codec = hwdep->private_data;
506 int err = parse_user_pin_configs(codec, buf);
486 if (err < 0) 507 if (err < 0)
487 return err; 508 return err;
488 return count; 509 return count;
@@ -553,3 +574,180 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
553EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint); 574EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint);
554 575
555#endif /* CONFIG_SND_HDA_RECONFIG */ 576#endif /* CONFIG_SND_HDA_RECONFIG */
577
578#ifdef CONFIG_SND_HDA_PATCH_LOADER
579
580/* parser mode */
581enum {
582 LINE_MODE_NONE,
583 LINE_MODE_CODEC,
584 LINE_MODE_MODEL,
585 LINE_MODE_PINCFG,
586 LINE_MODE_VERB,
587 LINE_MODE_HINT,
588 NUM_LINE_MODES,
589};
590
591static inline int strmatch(const char *a, const char *b)
592{
593 return strnicmp(a, b, strlen(b)) == 0;
594}
595
596/* parse the contents after the line "[codec]"
597 * accept only the line with three numbers, and assign the current codec
598 */
599static void parse_codec_mode(char *buf, struct hda_bus *bus,
600 struct hda_codec **codecp)
601{
602 unsigned int vendorid, subid, caddr;
603 struct hda_codec *codec;
604
605 *codecp = NULL;
606 if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) {
607 list_for_each_entry(codec, &bus->codec_list, list) {
608 if (codec->addr == caddr) {
609 *codecp = codec;
610 break;
611 }
612 }
613 }
614}
615
616/* parse the contents after the other command tags, [pincfg], [verb],
617 * [hint] and [model]
618 * just pass to the sysfs helper (only when any codec was specified)
619 */
620static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
621 struct hda_codec **codecp)
622{
623 if (!*codecp)
624 return;
625 parse_user_pin_configs(*codecp, buf);
626}
627
628static void parse_verb_mode(char *buf, struct hda_bus *bus,
629 struct hda_codec **codecp)
630{
631 if (!*codecp)
632 return;
633 parse_init_verbs(*codecp, buf);
634}
635
636static void parse_hint_mode(char *buf, struct hda_bus *bus,
637 struct hda_codec **codecp)
638{
639 if (!*codecp)
640 return;
641 parse_hints(*codecp, buf);
642}
643
644static void parse_model_mode(char *buf, struct hda_bus *bus,
645 struct hda_codec **codecp)
646{
647 if (!*codecp)
648 return;
649 kfree((*codecp)->modelname);
650 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
651}
652
653struct hda_patch_item {
654 const char *tag;
655 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
656};
657
658static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
659 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode },
660 [LINE_MODE_MODEL] = { "[model]", parse_model_mode },
661 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode },
662 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode },
663 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode },
664};
665
666/* check the line starting with '[' -- change the parser mode accodingly */
667static int parse_line_mode(char *buf, struct hda_bus *bus)
668{
669 int i;
670 for (i = 0; i < ARRAY_SIZE(patch_items); i++) {
671 if (!patch_items[i].tag)
672 continue;
673 if (strmatch(buf, patch_items[i].tag))
674 return i;
675 }
676 return LINE_MODE_NONE;
677}
678
679/* copy one line from the buffer in fw, and update the fields in fw
680 * return zero if it reaches to the end of the buffer, or non-zero
681 * if successfully copied a line
682 *
683 * the spaces at the beginning and the end of the line are stripped
684 */
685static int get_line_from_fw(char *buf, int size, struct firmware *fw)
686{
687 int len;
688 const char *p = fw->data;
689 while (isspace(*p) && fw->size) {
690 p++;
691 fw->size--;
692 }
693 if (!fw->size)
694 return 0;
695 if (size < fw->size)
696 size = fw->size;
697
698 for (len = 0; len < fw->size; len++) {
699 if (!*p)
700 break;
701 if (*p == '\n') {
702 p++;
703 len++;
704 break;
705 }
706 if (len < size)
707 *buf++ = *p++;
708 }
709 *buf = 0;
710 fw->size -= len;
711 fw->data = p;
712 remove_trail_spaces(buf);
713 return 1;
714}
715
716/*
717 * load a "patch" firmware file and parse it
718 */
719int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
720{
721 int err;
722 const struct firmware *fw;
723 struct firmware tmp;
724 char buf[128];
725 struct hda_codec *codec;
726 int line_mode;
727 struct device *dev = bus->card->dev;
728
729 if (snd_BUG_ON(!dev))
730 return -ENODEV;
731 err = request_firmware(&fw, patch, dev);
732 if (err < 0) {
733 printk(KERN_ERR "hda-codec: Cannot load the patch '%s'\n",
734 patch);
735 return err;
736 }
737
738 tmp = *fw;
739 line_mode = LINE_MODE_NONE;
740 codec = NULL;
741 while (get_line_from_fw(buf, sizeof(buf) - 1, &tmp)) {
742 if (!*buf || *buf == '#' || *buf == '\n')
743 continue;
744 if (*buf == '[')
745 line_mode = parse_line_mode(buf, bus);
746 else if (patch_items[line_mode].parser)
747 patch_items[line_mode].parser(buf, bus, &codec);
748 }
749 release_firmware(fw);
750 return 0;
751}
752EXPORT_SYMBOL_HDA(snd_hda_load_patch);
753#endif /* CONFIG_SND_HDA_PATCH_LOADER */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 77c1b840ca8b..4db854b43e6b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -61,6 +61,9 @@ static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
61static int probe_only[SNDRV_CARDS]; 61static int probe_only[SNDRV_CARDS];
62static int single_cmd; 62static int single_cmd;
63static int enable_msi; 63static int enable_msi;
64#ifdef CONFIG_SND_HDA_PATCH_LOADER
65static char *patch[SNDRV_CARDS];
66#endif
64 67
65module_param_array(index, int, NULL, 0444); 68module_param_array(index, int, NULL, 0444);
66MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); 69MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -84,6 +87,10 @@ MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
84 "(for debugging only)."); 87 "(for debugging only).");
85module_param(enable_msi, int, 0444); 88module_param(enable_msi, int, 0444);
86MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); 89MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
90#ifdef CONFIG_SND_HDA_PATCH_LOADER
91module_param_array(patch, charp, NULL, 0444);
92MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
93#endif
87 94
88#ifdef CONFIG_SND_HDA_POWER_SAVE 95#ifdef CONFIG_SND_HDA_POWER_SAVE
89static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; 96static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
@@ -1286,8 +1293,7 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1286 [AZX_DRIVER_TERA] = 1, 1293 [AZX_DRIVER_TERA] = 1,
1287}; 1294};
1288 1295
1289static int __devinit azx_codec_create(struct azx *chip, const char *model, 1296static int __devinit azx_codec_create(struct azx *chip, const char *model)
1290 int no_init)
1291{ 1297{
1292 struct hda_bus_template bus_temp; 1298 struct hda_bus_template bus_temp;
1293 int c, codecs, err; 1299 int c, codecs, err;
@@ -1346,7 +1352,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1346 for (c = 0; c < max_slots; c++) { 1352 for (c = 0; c < max_slots; c++) {
1347 if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { 1353 if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
1348 struct hda_codec *codec; 1354 struct hda_codec *codec;
1349 err = snd_hda_codec_new(chip->bus, c, !no_init, &codec); 1355 err = snd_hda_codec_new(chip->bus, c, &codec);
1350 if (err < 0) 1356 if (err < 0)
1351 continue; 1357 continue;
1352 codecs++; 1358 codecs++;
@@ -1356,7 +1362,16 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1356 snd_printk(KERN_ERR SFX "no codecs initialized\n"); 1362 snd_printk(KERN_ERR SFX "no codecs initialized\n");
1357 return -ENXIO; 1363 return -ENXIO;
1358 } 1364 }
1365 return 0;
1366}
1359 1367
1368/* configure each codec instance */
1369static int __devinit azx_codec_configure(struct azx *chip)
1370{
1371 struct hda_codec *codec;
1372 list_for_each_entry(codec, &chip->bus->codec_list, list) {
1373 snd_hda_codec_configure(codec);
1374 }
1360 return 0; 1375 return 0;
1361} 1376}
1362 1377
@@ -2481,15 +2496,32 @@ static int __devinit azx_probe(struct pci_dev *pci,
2481 return err; 2496 return err;
2482 } 2497 }
2483 2498
2499 /* set this here since it's referred in snd_hda_load_patch() */
2500 snd_card_set_dev(card, &pci->dev);
2501
2484 err = azx_create(card, pci, dev, pci_id->driver_data, &chip); 2502 err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
2485 if (err < 0) 2503 if (err < 0)
2486 goto out_free; 2504 goto out_free;
2487 card->private_data = chip; 2505 card->private_data = chip;
2488 2506
2489 /* create codec instances */ 2507 /* create codec instances */
2490 err = azx_codec_create(chip, model[dev], probe_only[dev]); 2508 err = azx_codec_create(chip, model[dev]);
2491 if (err < 0) 2509 if (err < 0)
2492 goto out_free; 2510 goto out_free;
2511#ifdef CONFIG_SND_HDA_PATCH_LOADER
2512 if (patch[dev]) {
2513 snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
2514 patch[dev]);
2515 err = snd_hda_load_patch(chip->bus, patch[dev]);
2516 if (err < 0)
2517 goto out_free;
2518 }
2519#endif
2520 if (!probe_only[dev]) {
2521 err = azx_codec_configure(chip);
2522 if (err < 0)
2523 goto out_free;
2524 }
2493 2525
2494 /* create PCM streams */ 2526 /* create PCM streams */
2495 err = snd_hda_build_pcms(chip->bus); 2527 err = snd_hda_build_pcms(chip->bus);
@@ -2501,8 +2533,6 @@ static int __devinit azx_probe(struct pci_dev *pci,
2501 if (err < 0) 2533 if (err < 0)
2502 goto out_free; 2534 goto out_free;
2503 2535
2504 snd_card_set_dev(card, &pci->dev);
2505
2506 err = snd_card_register(card); 2536 err = snd_card_register(card);
2507 if (err < 0) 2537 if (err < 0)
2508 goto out_free; 2538 goto out_free;
@@ -2604,11 +2634,15 @@ static struct pci_device_id azx_ids[] = {
2604 /* this entry seems still valid -- i.e. without emu20kx chip */ 2634 /* this entry seems still valid -- i.e. without emu20kx chip */
2605 { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, 2635 { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC },
2606#endif 2636#endif
2607 /* AMD Generic, PCI class code and Vendor ID for HD Audio */ 2637 /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
2608 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), 2638 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
2609 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2639 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2610 .class_mask = 0xffffff, 2640 .class_mask = 0xffffff,
2611 .driver_data = AZX_DRIVER_GENERIC }, 2641 .driver_data = AZX_DRIVER_GENERIC },
2642 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID),
2643 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2644 .class_mask = 0xffffff,
2645 .driver_data = AZX_DRIVER_GENERIC },
2612 { 0, } 2646 { 0, }
2613}; 2647};
2614MODULE_DEVICE_TABLE(pci, azx_ids); 2648MODULE_DEVICE_TABLE(pci, azx_ids);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 83349013b4df..fa57cb93b443 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -99,7 +99,6 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
99int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 99int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
100 unsigned int *tlv, const char **slaves); 100 unsigned int *tlv, const char **slaves);
101int snd_hda_codec_reset(struct hda_codec *codec); 101int snd_hda_codec_reset(struct hda_codec *codec);
102int snd_hda_codec_configure(struct hda_codec *codec);
103 102
104/* amp value bits */ 103/* amp value bits */
105#define HDA_AMP_MUTE 0x80 104#define HDA_AMP_MUTE 0x80
@@ -408,6 +407,9 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
408 return codec->wcaps[nid - codec->start_nid]; 407 return codec->wcaps[nid - codec->start_nid];
409} 408}
410 409
410/* get the widget type from widget capability bits */
411#define get_wcaps_type(wcaps) (((wcaps) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT)
412
411u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction); 413u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
412int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 414int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
413 unsigned int caps); 415 unsigned int caps);
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 418c5d1badaa..a721eb08a290 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -508,8 +508,7 @@ static void print_codec_info(struct snd_info_entry *entry,
508 unsigned int wid_caps = 508 unsigned int wid_caps =
509 snd_hda_param_read(codec, nid, 509 snd_hda_param_read(codec, nid,
510 AC_PAR_AUDIO_WIDGET_CAP); 510 AC_PAR_AUDIO_WIDGET_CAP);
511 unsigned int wid_type = 511 unsigned int wid_type = get_wcaps_type(wid_caps);
512 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
513 hda_nid_t conn[HDA_MAX_CONNECTIONS]; 512 hda_nid_t conn[HDA_MAX_CONNECTIONS];
514 int conn_len = 0; 513 int conn_len = 0;
515 514
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index e8e6a43865c2..ab3bcb78ace9 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -72,6 +72,7 @@ struct ad198x_spec {
72 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 72 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
73 73
74 unsigned int jack_present :1; 74 unsigned int jack_present :1;
75 unsigned int inv_jack_detect:1;
75 76
76#ifdef CONFIG_SND_HDA_POWER_SAVE 77#ifdef CONFIG_SND_HDA_POWER_SAVE
77 struct hda_loopback_check loopback; 78 struct hda_loopback_check loopback;
@@ -669,39 +670,13 @@ static struct hda_input_mux ad1986a_automic_capture_source = {
669 }, 670 },
670}; 671};
671 672
672static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { 673static struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = {
673 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 674 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
674 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), 675 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
675 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
676 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
677 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
678 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
679 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
680 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
681 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
682 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
683 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
684 {
685 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
686 .name = "Capture Source",
687 .info = ad198x_mux_enum_info,
688 .get = ad198x_mux_enum_get,
689 .put = ad198x_mux_enum_put,
690 },
691 {
692 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
693 .name = "External Amplifier",
694 .info = ad198x_eapd_info,
695 .get = ad198x_eapd_get,
696 .put = ad198x_eapd_put,
697 .private_value = 0x1b | (1 << 8), /* port-D, inversed */
698 },
699 { } /* end */ 676 { } /* end */
700}; 677};
701 678
702static struct snd_kcontrol_new ad1986a_samsung_mixers[] = { 679static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
703 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
704 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
705 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 680 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
706 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 681 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 682 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
@@ -727,6 +702,12 @@ static struct snd_kcontrol_new ad1986a_samsung_mixers[] = {
727 { } /* end */ 702 { } /* end */
728}; 703};
729 704
705static struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = {
706 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
707 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
708 { } /* end */
709};
710
730/* re-connect the mic boost input according to the jack sensing */ 711/* re-connect the mic boost input according to the jack sensing */
731static void ad1986a_automic(struct hda_codec *codec) 712static void ad1986a_automic(struct hda_codec *codec)
732{ 713{
@@ -776,8 +757,9 @@ static void ad1986a_hp_automute(struct hda_codec *codec)
776 unsigned int present; 757 unsigned int present;
777 758
778 present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0); 759 present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0);
779 /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */ 760 spec->jack_present = !!(present & 0x80000000);
780 spec->jack_present = !(present & 0x80000000); 761 if (spec->inv_jack_detect)
762 spec->jack_present = !spec->jack_present;
781 ad1986a_update_hp(codec); 763 ad1986a_update_hp(codec);
782} 764}
783 765
@@ -816,7 +798,7 @@ static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
816 return change; 798 return change;
817} 799}
818 800
819static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = { 801static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
820 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 802 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
821 { 803 {
822 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 804 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -826,33 +808,10 @@ static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = {
826 .put = ad1986a_hp_master_sw_put, 808 .put = ad1986a_hp_master_sw_put,
827 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 809 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
828 }, 810 },
829 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
830 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
831 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT),
832 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT),
833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
834 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
835 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
836 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
837 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
838 {
839 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
840 .name = "Capture Source",
841 .info = ad198x_mux_enum_info,
842 .get = ad198x_mux_enum_get,
843 .put = ad198x_mux_enum_put,
844 },
845 {
846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
847 .name = "External Amplifier",
848 .info = ad198x_eapd_info,
849 .get = ad198x_eapd_get,
850 .put = ad198x_eapd_put,
851 .private_value = 0x1b | (1 << 8), /* port-D, inversed */
852 },
853 { } /* end */ 811 { } /* end */
854}; 812};
855 813
814
856/* 815/*
857 * initialization verbs 816 * initialization verbs
858 */ 817 */
@@ -981,6 +940,27 @@ static struct hda_verb ad1986a_hp_init_verbs[] = {
981 {} 940 {}
982}; 941};
983 942
943static void ad1986a_samsung_p50_unsol_event(struct hda_codec *codec,
944 unsigned int res)
945{
946 switch (res >> 26) {
947 case AD1986A_HP_EVENT:
948 ad1986a_hp_automute(codec);
949 break;
950 case AD1986A_MIC_EVENT:
951 ad1986a_automic(codec);
952 break;
953 }
954}
955
956static int ad1986a_samsung_p50_init(struct hda_codec *codec)
957{
958 ad198x_init(codec);
959 ad1986a_hp_automute(codec);
960 ad1986a_automic(codec);
961 return 0;
962}
963
984 964
985/* models */ 965/* models */
986enum { 966enum {
@@ -991,6 +971,7 @@ enum {
991 AD1986A_LAPTOP_AUTOMUTE, 971 AD1986A_LAPTOP_AUTOMUTE,
992 AD1986A_ULTRA, 972 AD1986A_ULTRA,
993 AD1986A_SAMSUNG, 973 AD1986A_SAMSUNG,
974 AD1986A_SAMSUNG_P50,
994 AD1986A_MODELS 975 AD1986A_MODELS
995}; 976};
996 977
@@ -1002,6 +983,7 @@ static const char *ad1986a_models[AD1986A_MODELS] = {
1002 [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute", 983 [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
1003 [AD1986A_ULTRA] = "ultra", 984 [AD1986A_ULTRA] = "ultra",
1004 [AD1986A_SAMSUNG] = "samsung", 985 [AD1986A_SAMSUNG] = "samsung",
986 [AD1986A_SAMSUNG_P50] = "samsung-p50",
1005}; 987};
1006 988
1007static struct snd_pci_quirk ad1986a_cfg_tbl[] = { 989static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
@@ -1024,6 +1006,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1024 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), 1006 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD),
1025 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), 1007 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
1026 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), 1008 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
1009 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
1027 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), 1010 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
1028 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG), 1011 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG),
1029 SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK), 1012 SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
@@ -1111,7 +1094,10 @@ static int patch_ad1986a(struct hda_codec *codec)
1111 spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 1094 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1112 break; 1095 break;
1113 case AD1986A_LAPTOP_EAPD: 1096 case AD1986A_LAPTOP_EAPD:
1114 spec->mixers[0] = ad1986a_laptop_eapd_mixers; 1097 spec->num_mixers = 3;
1098 spec->mixers[0] = ad1986a_laptop_master_mixers;
1099 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1100 spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1115 spec->num_init_verbs = 2; 1101 spec->num_init_verbs = 2;
1116 spec->init_verbs[1] = ad1986a_eapd_init_verbs; 1102 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1117 spec->multiout.max_channels = 2; 1103 spec->multiout.max_channels = 2;
@@ -1122,7 +1108,9 @@ static int patch_ad1986a(struct hda_codec *codec)
1122 spec->input_mux = &ad1986a_laptop_eapd_capture_source; 1108 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1123 break; 1109 break;
1124 case AD1986A_SAMSUNG: 1110 case AD1986A_SAMSUNG:
1125 spec->mixers[0] = ad1986a_samsung_mixers; 1111 spec->num_mixers = 2;
1112 spec->mixers[0] = ad1986a_laptop_master_mixers;
1113 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1126 spec->num_init_verbs = 3; 1114 spec->num_init_verbs = 3;
1127 spec->init_verbs[1] = ad1986a_eapd_init_verbs; 1115 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1128 spec->init_verbs[2] = ad1986a_automic_verbs; 1116 spec->init_verbs[2] = ad1986a_automic_verbs;
@@ -1135,8 +1123,28 @@ static int patch_ad1986a(struct hda_codec *codec)
1135 codec->patch_ops.unsol_event = ad1986a_automic_unsol_event; 1123 codec->patch_ops.unsol_event = ad1986a_automic_unsol_event;
1136 codec->patch_ops.init = ad1986a_automic_init; 1124 codec->patch_ops.init = ad1986a_automic_init;
1137 break; 1125 break;
1126 case AD1986A_SAMSUNG_P50:
1127 spec->num_mixers = 2;
1128 spec->mixers[0] = ad1986a_automute_master_mixers;
1129 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1130 spec->num_init_verbs = 4;
1131 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1132 spec->init_verbs[2] = ad1986a_automic_verbs;
1133 spec->init_verbs[3] = ad1986a_hp_init_verbs;
1134 spec->multiout.max_channels = 2;
1135 spec->multiout.num_dacs = 1;
1136 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1137 if (!is_jack_available(codec, 0x25))
1138 spec->multiout.dig_out_nid = 0;
1139 spec->input_mux = &ad1986a_automic_capture_source;
1140 codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event;
1141 codec->patch_ops.init = ad1986a_samsung_p50_init;
1142 break;
1138 case AD1986A_LAPTOP_AUTOMUTE: 1143 case AD1986A_LAPTOP_AUTOMUTE:
1139 spec->mixers[0] = ad1986a_laptop_automute_mixers; 1144 spec->num_mixers = 3;
1145 spec->mixers[0] = ad1986a_automute_master_mixers;
1146 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1147 spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1140 spec->num_init_verbs = 3; 1148 spec->num_init_verbs = 3;
1141 spec->init_verbs[1] = ad1986a_eapd_init_verbs; 1149 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1142 spec->init_verbs[2] = ad1986a_hp_init_verbs; 1150 spec->init_verbs[2] = ad1986a_hp_init_verbs;
@@ -1148,6 +1156,10 @@ static int patch_ad1986a(struct hda_codec *codec)
1148 spec->input_mux = &ad1986a_laptop_eapd_capture_source; 1156 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1149 codec->patch_ops.unsol_event = ad1986a_hp_unsol_event; 1157 codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
1150 codec->patch_ops.init = ad1986a_hp_init; 1158 codec->patch_ops.init = ad1986a_hp_init;
1159 /* Lenovo N100 seems to report the reversed bit
1160 * for HP jack-sensing
1161 */
1162 spec->inv_jack_detect = 1;
1151 break; 1163 break;
1152 case AD1986A_ULTRA: 1164 case AD1986A_ULTRA:
1153 spec->mixers[0] = ad1986a_laptop_eapd_mixers; 1165 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
@@ -2970,7 +2982,8 @@ static int patch_ad1988(struct hda_codec *codec)
2970 board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST, 2982 board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
2971 ad1988_models, ad1988_cfg_tbl); 2983 ad1988_models, ad1988_cfg_tbl);
2972 if (board_config < 0) { 2984 if (board_config < 0) {
2973 printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n"); 2985 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
2986 codec->chip_name);
2974 board_config = AD1988_AUTO; 2987 board_config = AD1988_AUTO;
2975 } 2988 }
2976 2989
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index 019ca7cb56d7..d08353d3bb7f 100644
--- a/sound/pci/hda/patch_ca0110.c
+++ b/sound/pci/hda/patch_ca0110.c
@@ -459,8 +459,7 @@ static void parse_input(struct hda_codec *codec)
459 nid = codec->start_nid; 459 nid = codec->start_nid;
460 for (i = 0; i < codec->num_nodes; i++, nid++) { 460 for (i = 0; i < codec->num_nodes; i++, nid++) {
461 unsigned int wcaps = get_wcaps(codec, nid); 461 unsigned int wcaps = get_wcaps(codec, nid);
462 unsigned int type = (wcaps & AC_WCAP_TYPE) >> 462 unsigned int type = get_wcaps_type(wcaps);
463 AC_WCAP_TYPE_SHIFT;
464 if (type != AC_WID_AUD_IN) 463 if (type != AC_WID_AUD_IN)
465 continue; 464 continue;
466 if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) 465 if (snd_hda_get_connections(codec, nid, &pin, 1) != 1)
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index c921264bbd71..780e1a72114a 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -635,7 +635,8 @@ static int patch_cmi9880(struct hda_codec *codec)
635 cmi9880_models, 635 cmi9880_models,
636 cmi9880_cfg_tbl); 636 cmi9880_cfg_tbl);
637 if (spec->board_config < 0) { 637 if (spec->board_config < 0) {
638 snd_printdd(KERN_INFO "hda_codec: Unknown model for CMI9880\n"); 638 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
639 codec->chip_name);
639 spec->board_config = CMI_AUTO; /* try everything */ 640 spec->board_config = CMI_AUTO; /* try everything */
640 } 641 }
641 642
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index ac868c59f9e3..9d899eda44d7 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -108,6 +108,8 @@ struct conexant_spec {
108 struct hda_input_mux private_imux; 108 struct hda_input_mux private_imux;
109 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 109 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
110 110
111 unsigned int dell_automute;
112 unsigned int port_d_mode;
111}; 113};
112 114
113static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 115static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -1908,6 +1910,480 @@ static int patch_cxt5051(struct hda_codec *codec)
1908 return 0; 1910 return 0;
1909} 1911}
1910 1912
1913/* Conexant 5066 specific */
1914
1915static hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
1916static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
1917static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
1918#define CXT5066_SPDIF_OUT 0x21
1919
1920static struct hda_channel_mode cxt5066_modes[1] = {
1921 { 2, NULL },
1922};
1923
1924static void cxt5066_update_speaker(struct hda_codec *codec)
1925{
1926 struct conexant_spec *spec = codec->spec;
1927 unsigned int pinctl;
1928
1929 snd_printdd("CXT5066: update speaker, hp_present=%d\n",
1930 spec->hp_present);
1931
1932 /* Port A (HP) */
1933 pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
1934 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1935 pinctl);
1936
1937 /* Port D (HP/LO) */
1938 pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
1939 ? spec->port_d_mode : 0;
1940 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1941 pinctl);
1942
1943 /* CLASS_D AMP */
1944 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1945 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1946 pinctl);
1947
1948 if (spec->dell_automute) {
1949 /* DELL AIO Port Rule: PortA > PortD > IntSpk */
1950 pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
1951 ? PIN_OUT : 0;
1952 snd_hda_codec_write(codec, 0x1c, 0,
1953 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
1954 }
1955}
1956
1957/* turn on/off EAPD (+ mute HP) as a master switch */
1958static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1959 struct snd_ctl_elem_value *ucontrol)
1960{
1961 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1962
1963 if (!cxt_eapd_put(kcontrol, ucontrol))
1964 return 0;
1965
1966 cxt5066_update_speaker(codec);
1967 return 1;
1968}
1969
1970/* toggle input of built-in and mic jack appropriately */
1971static void cxt5066_automic(struct hda_codec *codec)
1972{
1973 static struct hda_verb ext_mic_present[] = {
1974 /* enable external mic, port B */
1975 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1976
1977 /* switch to external mic input */
1978 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
1979
1980 /* disable internal mic, port C */
1981 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1982 {}
1983 };
1984 static struct hda_verb ext_mic_absent[] = {
1985 /* enable internal mic, port C */
1986 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1987
1988 /* switch to internal mic input */
1989 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
1990
1991 /* disable external mic, port B */
1992 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1993 {}
1994 };
1995 unsigned int present;
1996
1997 present = snd_hda_codec_read(codec, 0x1a, 0,
1998 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1999 if (present) {
2000 snd_printdd("CXT5066: external microphone detected\n");
2001 snd_hda_sequence_write(codec, ext_mic_present);
2002 } else {
2003 snd_printdd("CXT5066: external microphone absent\n");
2004 snd_hda_sequence_write(codec, ext_mic_absent);
2005 }
2006}
2007
2008/* mute internal speaker if HP is plugged */
2009static void cxt5066_hp_automute(struct hda_codec *codec)
2010{
2011 struct conexant_spec *spec = codec->spec;
2012 unsigned int portA, portD;
2013
2014 /* Port A */
2015 portA = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0)
2016 & AC_PINSENSE_PRESENCE;
2017
2018 /* Port D */
2019 portD = (snd_hda_codec_read(codec, 0x1c, 0, AC_VERB_GET_PIN_SENSE, 0)
2020 & AC_PINSENSE_PRESENCE) << 1;
2021
2022 spec->hp_present = !!(portA | portD);
2023 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2024 portA, portD, spec->hp_present);
2025 cxt5066_update_speaker(codec);
2026}
2027
2028/* unsolicited event for jack sensing */
2029static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
2030{
2031 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2032 switch (res >> 26) {
2033 case CONEXANT_HP_EVENT:
2034 cxt5066_hp_automute(codec);
2035 break;
2036 case CONEXANT_MIC_EVENT:
2037 cxt5066_automic(codec);
2038 break;
2039 }
2040}
2041
2042static const struct hda_input_mux cxt5066_analog_mic_boost = {
2043 .num_items = 5,
2044 .items = {
2045 { "0dB", 0 },
2046 { "10dB", 1 },
2047 { "20dB", 2 },
2048 { "30dB", 3 },
2049 { "40dB", 4 },
2050 },
2051};
2052
2053static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2054 struct snd_ctl_elem_info *uinfo)
2055{
2056 return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo);
2057}
2058
2059static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2060 struct snd_ctl_elem_value *ucontrol)
2061{
2062 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2063 int val;
2064
2065 val = snd_hda_codec_read(codec, 0x17, 0,
2066 AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_OUTPUT);
2067
2068 ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN;
2069 return 0;
2070}
2071
2072static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2073 struct snd_ctl_elem_value *ucontrol)
2074{
2075 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2076 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2077 unsigned int idx;
2078
2079 if (!imux->num_items)
2080 return 0;
2081 idx = ucontrol->value.enumerated.item[0];
2082 if (idx >= imux->num_items)
2083 idx = imux->num_items - 1;
2084
2085 snd_hda_codec_write_cache(codec, 0x17, 0,
2086 AC_VERB_SET_AMP_GAIN_MUTE,
2087 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2088 imux->items[idx].index);
2089
2090 return 1;
2091}
2092
2093static struct hda_input_mux cxt5066_capture_source = {
2094 .num_items = 4,
2095 .items = {
2096 { "Mic B", 0 },
2097 { "Mic C", 1 },
2098 { "Mic E", 2 },
2099 { "Mic F", 3 },
2100 },
2101};
2102
2103static struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2104 .ops = &snd_hda_bind_vol,
2105 .values = {
2106 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2107 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2108 0
2109 },
2110};
2111
2112static struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2113 .ops = &snd_hda_bind_sw,
2114 .values = {
2115 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2116 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2117 0
2118 },
2119};
2120
2121static struct snd_kcontrol_new cxt5066_mixer_master[] = {
2122 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2123 {}
2124};
2125
2126static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2127 {
2128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2129 .name = "Master Playback Volume",
2130 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2131 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2132 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2133 .info = snd_hda_mixer_amp_volume_info,
2134 .get = snd_hda_mixer_amp_volume_get,
2135 .put = snd_hda_mixer_amp_volume_put,
2136 .tlv = { .c = snd_hda_mixer_amp_tlv },
2137 /* offset by 28 volume steps to limit minimum gain to -46dB */
2138 .private_value =
2139 HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
2140 },
2141 {}
2142};
2143
2144static struct snd_kcontrol_new cxt5066_mixers[] = {
2145 {
2146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2147 .name = "Master Playback Switch",
2148 .info = cxt_eapd_info,
2149 .get = cxt_eapd_get,
2150 .put = cxt5066_hp_master_sw_put,
2151 .private_value = 0x1d,
2152 },
2153
2154 {
2155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2156 .name = "Analog Mic Boost Capture Enum",
2157 .info = cxt5066_mic_boost_mux_enum_info,
2158 .get = cxt5066_mic_boost_mux_enum_get,
2159 .put = cxt5066_mic_boost_mux_enum_put,
2160 },
2161
2162 HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
2163 HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others),
2164 {}
2165};
2166
2167static struct hda_verb cxt5066_init_verbs[] = {
2168 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2169 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2170 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2171 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2172
2173 /* Speakers */
2174 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2175 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2176
2177 /* HP, Amp */
2178 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2179 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2180
2181 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2182 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2183
2184 /* DAC1 */
2185 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2186
2187 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2188 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2189 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2190 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2191 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2192 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2193
2194 /* no digital microphone support yet */
2195 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2196
2197 /* Audio input selector */
2198 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2199
2200 /* SPDIF route: PCM */
2201 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2202 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2203
2204 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2205 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2206
2207 /* EAPD */
2208 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2209
2210 /* not handling these yet */
2211 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2212 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2213 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2214 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2215 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2216 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2217 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2218 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2219 { } /* end */
2220};
2221
2222static struct hda_verb cxt5066_init_verbs_olpc[] = {
2223 /* Port A: headphones */
2224 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2225 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2226
2227 /* Port B: external microphone */
2228 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2229
2230 /* Port C: internal microphone */
2231 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2232
2233 /* Port D: unused */
2234 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2235
2236 /* Port E: unused, but has primary EAPD */
2237 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2238 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2239
2240 /* Port F: unused */
2241 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2242
2243 /* Port G: internal speakers */
2244 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2245 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2246
2247 /* DAC1 */
2248 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2249
2250 /* DAC2: unused */
2251 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2252
2253 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2254 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2255 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2256 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2257 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2258 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2259 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2260 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2261 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2262 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2263 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2264 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2265
2266 /* Disable digital microphone port */
2267 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2268
2269 /* Audio input selectors */
2270 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2271 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2272
2273 /* Disable SPDIF */
2274 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2275 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2276
2277 /* enable unsolicited events for Port A and B */
2278 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2279 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2280 { } /* end */
2281};
2282
2283static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2284 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2285 { } /* end */
2286};
2287
2288/* initialize jack-sensing, too */
2289static int cxt5066_init(struct hda_codec *codec)
2290{
2291 snd_printdd("CXT5066: init\n");
2292 conexant_init(codec);
2293 if (codec->patch_ops.unsol_event) {
2294 cxt5066_hp_automute(codec);
2295 cxt5066_automic(codec);
2296 }
2297 return 0;
2298}
2299
2300enum {
2301 CXT5066_LAPTOP, /* Laptops w/ EAPD support */
2302 CXT5066_DELL_LAPTOP, /* Dell Laptop */
2303 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */
2304 CXT5066_MODELS
2305};
2306
2307static const char *cxt5066_models[CXT5066_MODELS] = {
2308 [CXT5066_LAPTOP] = "laptop",
2309 [CXT5066_DELL_LAPTOP] = "dell-laptop",
2310 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
2311};
2312
2313static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2314 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
2315 CXT5066_LAPTOP),
2316 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
2317 CXT5066_DELL_LAPTOP),
2318 {}
2319};
2320
2321static int patch_cxt5066(struct hda_codec *codec)
2322{
2323 struct conexant_spec *spec;
2324 int board_config;
2325
2326 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2327 if (!spec)
2328 return -ENOMEM;
2329 codec->spec = spec;
2330
2331 codec->patch_ops = conexant_patch_ops;
2332 codec->patch_ops.init = cxt5066_init;
2333
2334 spec->dell_automute = 0;
2335 spec->multiout.max_channels = 2;
2336 spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
2337 spec->multiout.dac_nids = cxt5066_dac_nids;
2338 spec->multiout.dig_out_nid = CXT5066_SPDIF_OUT;
2339 spec->num_adc_nids = 1;
2340 spec->adc_nids = cxt5066_adc_nids;
2341 spec->capsrc_nids = cxt5066_capsrc_nids;
2342 spec->input_mux = &cxt5066_capture_source;
2343
2344 spec->port_d_mode = PIN_HP;
2345
2346 spec->num_init_verbs = 1;
2347 spec->init_verbs[0] = cxt5066_init_verbs;
2348 spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes);
2349 spec->channel_mode = cxt5066_modes;
2350 spec->cur_adc = 0;
2351 spec->cur_adc_idx = 0;
2352
2353 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
2354 cxt5066_models, cxt5066_cfg_tbl);
2355 switch (board_config) {
2356 default:
2357 case CXT5066_LAPTOP:
2358 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2359 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2360 break;
2361 case CXT5066_DELL_LAPTOP:
2362 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2363 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2364
2365 spec->port_d_mode = PIN_OUT;
2366 spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo;
2367 spec->num_init_verbs++;
2368 spec->dell_automute = 1;
2369 break;
2370 case CXT5066_OLPC_XO_1_5:
2371 codec->patch_ops.unsol_event = cxt5066_unsol_event;
2372 spec->init_verbs[0] = cxt5066_init_verbs_olpc;
2373 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2374 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2375 spec->port_d_mode = 0;
2376
2377 /* no S/PDIF out */
2378 spec->multiout.dig_out_nid = 0;
2379
2380 /* input source automatically selected */
2381 spec->input_mux = NULL;
2382 break;
2383 }
2384
2385 return 0;
2386}
1911 2387
1912/* 2388/*
1913 */ 2389 */
@@ -1919,12 +2395,15 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = {
1919 .patch = patch_cxt5047 }, 2395 .patch = patch_cxt5047 },
1920 { .id = 0x14f15051, .name = "CX20561 (Hermosa)", 2396 { .id = 0x14f15051, .name = "CX20561 (Hermosa)",
1921 .patch = patch_cxt5051 }, 2397 .patch = patch_cxt5051 },
2398 { .id = 0x14f15066, .name = "CX20582 (Pebble)",
2399 .patch = patch_cxt5066 },
1922 {} /* terminator */ 2400 {} /* terminator */
1923}; 2401};
1924 2402
1925MODULE_ALIAS("snd-hda-codec-id:14f15045"); 2403MODULE_ALIAS("snd-hda-codec-id:14f15045");
1926MODULE_ALIAS("snd-hda-codec-id:14f15047"); 2404MODULE_ALIAS("snd-hda-codec-id:14f15047");
1927MODULE_ALIAS("snd-hda-codec-id:14f15051"); 2405MODULE_ALIAS("snd-hda-codec-id:14f15051");
2406MODULE_ALIAS("snd-hda-codec-id:14f15066");
1928 2407
1929MODULE_LICENSE("GPL"); 2408MODULE_LICENSE("GPL");
1930MODULE_DESCRIPTION("Conexant HD-audio codec"); 2409MODULE_DESCRIPTION("Conexant HD-audio codec");
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index fcc77fec4487..032850eba369 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -685,6 +685,7 @@ static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
685 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, 685 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
686 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, 686 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
687 { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, 687 { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi },
688 { .id = 0x80860054, .name = "G45 DEVIBX", .patch = patch_intel_hdmi },
688 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, 689 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
689 {} /* terminator */ 690 {} /* terminator */
690}; 691};
@@ -694,6 +695,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862801");
694MODULE_ALIAS("snd-hda-codec-id:80862802"); 695MODULE_ALIAS("snd-hda-codec-id:80862802");
695MODULE_ALIAS("snd-hda-codec-id:80862803"); 696MODULE_ALIAS("snd-hda-codec-id:80862803");
696MODULE_ALIAS("snd-hda-codec-id:80862804"); 697MODULE_ALIAS("snd-hda-codec-id:80862804");
698MODULE_ALIAS("snd-hda-codec-id:80860054");
697MODULE_ALIAS("snd-hda-codec-id:10951392"); 699MODULE_ALIAS("snd-hda-codec-id:10951392");
698 700
699MODULE_LICENSE("GPL"); 701MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 8c8b273116fb..587d94f869be 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -208,12 +208,6 @@ enum {
208 ALC885_MBP3, 208 ALC885_MBP3,
209 ALC885_MB5, 209 ALC885_MB5,
210 ALC885_IMAC24, 210 ALC885_IMAC24,
211 ALC882_AUTO,
212 ALC882_MODEL_LAST,
213};
214
215/* ALC883 models */
216enum {
217 ALC883_3ST_2ch_DIG, 211 ALC883_3ST_2ch_DIG,
218 ALC883_3ST_6ch_DIG, 212 ALC883_3ST_6ch_DIG,
219 ALC883_3ST_6ch, 213 ALC883_3ST_6ch,
@@ -241,13 +235,15 @@ enum {
241 ALC883_FUJITSU_PI2515, 235 ALC883_FUJITSU_PI2515,
242 ALC888_FUJITSU_XA3530, 236 ALC888_FUJITSU_XA3530,
243 ALC883_3ST_6ch_INTEL, 237 ALC883_3ST_6ch_INTEL,
238 ALC889A_INTEL,
239 ALC889_INTEL,
244 ALC888_ASUS_M90V, 240 ALC888_ASUS_M90V,
245 ALC888_ASUS_EEE1601, 241 ALC888_ASUS_EEE1601,
246 ALC889A_MB31, 242 ALC889A_MB31,
247 ALC1200_ASUS_P5Q, 243 ALC1200_ASUS_P5Q,
248 ALC883_SONY_VAIO_TT, 244 ALC883_SONY_VAIO_TT,
249 ALC883_AUTO, 245 ALC882_AUTO,
250 ALC883_MODEL_LAST, 246 ALC882_MODEL_LAST,
251}; 247};
252 248
253/* for GPIO Poll */ 249/* for GPIO Poll */
@@ -320,6 +316,8 @@ struct alc_spec {
320 struct snd_array kctls; 316 struct snd_array kctls;
321 struct hda_input_mux private_imux[3]; 317 struct hda_input_mux private_imux[3];
322 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 318 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
319 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
320 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
323 321
324 /* hooks */ 322 /* hooks */
325 void (*init_hook)(struct hda_codec *codec); 323 void (*init_hook)(struct hda_codec *codec);
@@ -417,7 +415,7 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
417 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 415 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
418 imux = &spec->input_mux[mux_idx]; 416 imux = &spec->input_mux[mux_idx];
419 417
420 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 418 type = get_wcaps_type(get_wcaps(codec, nid));
421 if (type == AC_WID_AUD_MIX) { 419 if (type == AC_WID_AUD_MIX) {
422 /* Matrix-mixer style (e.g. ALC882) */ 420 /* Matrix-mixer style (e.g. ALC882) */
423 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 421 unsigned int *cur_val = &spec->cur_mux[adc_idx];
@@ -1031,6 +1029,16 @@ static void alc888_coef_init(struct hda_codec *codec)
1031 AC_VERB_SET_PROC_COEF, 0x3030); 1029 AC_VERB_SET_PROC_COEF, 0x3030);
1032} 1030}
1033 1031
1032static void alc889_coef_init(struct hda_codec *codec)
1033{
1034 unsigned int tmp;
1035
1036 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1037 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1038 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1039 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1040}
1041
1034static void alc_auto_init_amp(struct hda_codec *codec, int type) 1042static void alc_auto_init_amp(struct hda_codec *codec, int type)
1035{ 1043{
1036 unsigned int tmp; 1044 unsigned int tmp;
@@ -1088,15 +1096,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1088 case 0x10ec0885: 1096 case 0x10ec0885:
1089 case 0x10ec0887: 1097 case 0x10ec0887:
1090 case 0x10ec0889: 1098 case 0x10ec0889:
1091 snd_hda_codec_write(codec, 0x20, 0, 1099 alc889_coef_init(codec);
1092 AC_VERB_SET_COEF_INDEX, 7);
1093 tmp = snd_hda_codec_read(codec, 0x20, 0,
1094 AC_VERB_GET_PROC_COEF, 0);
1095 snd_hda_codec_write(codec, 0x20, 0,
1096 AC_VERB_SET_COEF_INDEX, 7);
1097 snd_hda_codec_write(codec, 0x20, 0,
1098 AC_VERB_SET_PROC_COEF,
1099 tmp | 0x2010);
1100 break; 1100 break;
1101 case 0x10ec0888: 1101 case 0x10ec0888:
1102 alc888_coef_init(codec); 1102 alc888_coef_init(codec);
@@ -1436,6 +1436,25 @@ static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1436 alc_automute_amp(codec); 1436 alc_automute_amp(codec);
1437} 1437}
1438 1438
1439static void alc889_automute_init(struct hda_codec *codec)
1440{
1441 struct alc_spec *spec = codec->spec;
1442
1443 spec->autocfg.hp_pins[0] = 0x15;
1444 spec->autocfg.speaker_pins[0] = 0x14;
1445 spec->autocfg.speaker_pins[1] = 0x16;
1446 spec->autocfg.speaker_pins[2] = 0x17;
1447 spec->autocfg.speaker_pins[3] = 0x19;
1448 spec->autocfg.speaker_pins[4] = 0x1a;
1449 alc_automute_amp(codec);
1450}
1451
1452static void alc889_intel_init_hook(struct hda_codec *codec)
1453{
1454 alc889_coef_init(codec);
1455 alc889_automute_init(codec);
1456}
1457
1439static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec) 1458static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1440{ 1459{
1441 struct alc_spec *spec = codec->spec; 1460 struct alc_spec *spec = codec->spec;
@@ -4505,12 +4524,6 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4505 &dig_nid, 1); 4524 &dig_nid, 1);
4506 if (err < 0) 4525 if (err < 0)
4507 continue; 4526 continue;
4508 if (dig_nid > 0x7f) {
4509 printk(KERN_ERR "alc880_auto: invalid dig_nid "
4510 "connection 0x%x for NID 0x%x\n", dig_nid,
4511 spec->autocfg.dig_out_pins[i]);
4512 continue;
4513 }
4514 if (!i) 4527 if (!i)
4515 spec->multiout.dig_out_nid = dig_nid; 4528 spec->multiout.dig_out_nid = dig_nid;
4516 else { 4529 else {
@@ -4590,8 +4603,8 @@ static int patch_alc880(struct hda_codec *codec)
4590 alc880_models, 4603 alc880_models,
4591 alc880_cfg_tbl); 4604 alc880_cfg_tbl);
4592 if (board_config < 0) { 4605 if (board_config < 0) {
4593 printk(KERN_INFO "hda_codec: Unknown model for %s, " 4606 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4594 "trying auto-probe from BIOS...\n", codec->chip_name); 4607 codec->chip_name);
4595 board_config = ALC880_AUTO; 4608 board_config = ALC880_AUTO;
4596 } 4609 }
4597 4610
@@ -4629,7 +4642,7 @@ static int patch_alc880(struct hda_codec *codec)
4629 /* check whether NID 0x07 is valid */ 4642 /* check whether NID 0x07 is valid */
4630 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 4643 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4631 /* get type */ 4644 /* get type */
4632 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 4645 wcap = get_wcaps_type(wcap);
4633 if (wcap != AC_WID_AUD_IN) { 4646 if (wcap != AC_WID_AUD_IN) {
4634 spec->adc_nids = alc880_adc_nids_alt; 4647 spec->adc_nids = alc880_adc_nids_alt;
4635 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 4648 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
@@ -6234,8 +6247,7 @@ static int patch_alc260(struct hda_codec *codec)
6234 alc260_models, 6247 alc260_models,
6235 alc260_cfg_tbl); 6248 alc260_cfg_tbl);
6236 if (board_config < 0) { 6249 if (board_config < 0) {
6237 snd_printd(KERN_INFO "hda_codec: Unknown model for %s, " 6250 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6238 "trying auto-probe from BIOS...\n",
6239 codec->chip_name); 6251 codec->chip_name);
6240 board_config = ALC260_AUTO; 6252 board_config = ALC260_AUTO;
6241 } 6253 }
@@ -6272,7 +6284,7 @@ static int patch_alc260(struct hda_codec *codec)
6272 if (!spec->adc_nids && spec->input_mux) { 6284 if (!spec->adc_nids && spec->input_mux) {
6273 /* check whether NID 0x04 is valid */ 6285 /* check whether NID 0x04 is valid */
6274 unsigned int wcap = get_wcaps(codec, 0x04); 6286 unsigned int wcap = get_wcaps(codec, 0x04);
6275 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 6287 wcap = get_wcaps_type(wcap);
6276 /* get type */ 6288 /* get type */
6277 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 6289 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6278 spec->adc_nids = alc260_adc_nids_alt; 6290 spec->adc_nids = alc260_adc_nids_alt;
@@ -6301,7 +6313,7 @@ static int patch_alc260(struct hda_codec *codec)
6301 6313
6302 6314
6303/* 6315/*
6304 * ALC882 support 6316 * ALC882/883/885/888/889 support
6305 * 6317 *
6306 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 6318 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6307 * configuration. Each pin widget can choose any input DACs and a mixer. 6319 * configuration. Each pin widget can choose any input DACs and a mixer.
@@ -6313,22 +6325,35 @@ static int patch_alc260(struct hda_codec *codec)
6313 */ 6325 */
6314#define ALC882_DIGOUT_NID 0x06 6326#define ALC882_DIGOUT_NID 0x06
6315#define ALC882_DIGIN_NID 0x0a 6327#define ALC882_DIGIN_NID 0x0a
6328#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6329#define ALC883_DIGIN_NID ALC882_DIGIN_NID
6330#define ALC1200_DIGOUT_NID 0x10
6331
6316 6332
6317static struct hda_channel_mode alc882_ch_modes[1] = { 6333static struct hda_channel_mode alc882_ch_modes[1] = {
6318 { 8, NULL } 6334 { 8, NULL }
6319}; 6335};
6320 6336
6337/* DACs */
6321static hda_nid_t alc882_dac_nids[4] = { 6338static hda_nid_t alc882_dac_nids[4] = {
6322 /* front, rear, clfe, rear_surr */ 6339 /* front, rear, clfe, rear_surr */
6323 0x02, 0x03, 0x04, 0x05 6340 0x02, 0x03, 0x04, 0x05
6324}; 6341};
6342#define alc883_dac_nids alc882_dac_nids
6325 6343
6326/* identical with ALC880 */ 6344/* ADCs */
6327#define alc882_adc_nids alc880_adc_nids 6345#define alc882_adc_nids alc880_adc_nids
6328#define alc882_adc_nids_alt alc880_adc_nids_alt 6346#define alc882_adc_nids_alt alc880_adc_nids_alt
6347#define alc883_adc_nids alc882_adc_nids_alt
6348static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6349static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6350#define alc889_adc_nids alc880_adc_nids
6329 6351
6330static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 6352static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6331static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 6353static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6354#define alc883_capsrc_nids alc882_capsrc_nids_alt
6355static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6356#define alc889_capsrc_nids alc882_capsrc_nids
6332 6357
6333/* input MUX */ 6358/* input MUX */
6334/* FIXME: should be a matrix-type input source selection */ 6359/* FIXME: should be a matrix-type input source selection */
@@ -6343,6 +6368,17 @@ static struct hda_input_mux alc882_capture_source = {
6343 }, 6368 },
6344}; 6369};
6345 6370
6371#define alc883_capture_source alc882_capture_source
6372
6373static struct hda_input_mux alc889_capture_source = {
6374 .num_items = 3,
6375 .items = {
6376 { "Front Mic", 0x0 },
6377 { "Mic", 0x3 },
6378 { "Line", 0x2 },
6379 },
6380};
6381
6346static struct hda_input_mux mb5_capture_source = { 6382static struct hda_input_mux mb5_capture_source = {
6347 .num_items = 3, 6383 .num_items = 3,
6348 .items = { 6384 .items = {
@@ -6352,6 +6388,77 @@ static struct hda_input_mux mb5_capture_source = {
6352 }, 6388 },
6353}; 6389};
6354 6390
6391static struct hda_input_mux alc883_3stack_6ch_intel = {
6392 .num_items = 4,
6393 .items = {
6394 { "Mic", 0x1 },
6395 { "Front Mic", 0x0 },
6396 { "Line", 0x2 },
6397 { "CD", 0x4 },
6398 },
6399};
6400
6401static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6402 .num_items = 2,
6403 .items = {
6404 { "Mic", 0x1 },
6405 { "Line", 0x2 },
6406 },
6407};
6408
6409static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6410 .num_items = 4,
6411 .items = {
6412 { "Mic", 0x0 },
6413 { "iMic", 0x1 },
6414 { "Line", 0x2 },
6415 { "CD", 0x4 },
6416 },
6417};
6418
6419static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6420 .num_items = 2,
6421 .items = {
6422 { "Mic", 0x0 },
6423 { "Int Mic", 0x1 },
6424 },
6425};
6426
6427static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6428 .num_items = 3,
6429 .items = {
6430 { "Mic", 0x0 },
6431 { "Front Mic", 0x1 },
6432 { "Line", 0x4 },
6433 },
6434};
6435
6436static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6437 .num_items = 2,
6438 .items = {
6439 { "Mic", 0x0 },
6440 { "Line", 0x2 },
6441 },
6442};
6443
6444static struct hda_input_mux alc889A_mb31_capture_source = {
6445 .num_items = 2,
6446 .items = {
6447 { "Mic", 0x0 },
6448 /* Front Mic (0x01) unused */
6449 { "Line", 0x2 },
6450 /* Line 2 (0x03) unused */
6451 /* CD (0x04) unsused? */
6452 },
6453};
6454
6455/*
6456 * 2ch mode
6457 */
6458static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6459 { 2, NULL }
6460};
6461
6355/* 6462/*
6356 * 2ch mode 6463 * 2ch mode
6357 */ 6464 */
@@ -6364,6 +6471,18 @@ static struct hda_verb alc882_3ST_ch2_init[] = {
6364}; 6471};
6365 6472
6366/* 6473/*
6474 * 4ch mode
6475 */
6476static struct hda_verb alc882_3ST_ch4_init[] = {
6477 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6478 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6479 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6480 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6481 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6482 { } /* end */
6483};
6484
6485/*
6367 * 6ch mode 6486 * 6ch mode
6368 */ 6487 */
6369static struct hda_verb alc882_3ST_ch6_init[] = { 6488static struct hda_verb alc882_3ST_ch6_init[] = {
@@ -6376,11 +6495,14 @@ static struct hda_verb alc882_3ST_ch6_init[] = {
6376 { } /* end */ 6495 { } /* end */
6377}; 6496};
6378 6497
6379static struct hda_channel_mode alc882_3ST_6ch_modes[2] = { 6498static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
6380 { 2, alc882_3ST_ch2_init }, 6499 { 2, alc882_3ST_ch2_init },
6500 { 4, alc882_3ST_ch4_init },
6381 { 6, alc882_3ST_ch6_init }, 6501 { 6, alc882_3ST_ch6_init },
6382}; 6502};
6383 6503
6504#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
6505
6384/* 6506/*
6385 * 6ch mode 6507 * 6ch mode
6386 */ 6508 */
@@ -6468,6 +6590,189 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6468 { 6, alc885_mb5_ch6_init }, 6590 { 6, alc885_mb5_ch6_init },
6469}; 6591};
6470 6592
6593
6594/*
6595 * 2ch mode
6596 */
6597static struct hda_verb alc883_4ST_ch2_init[] = {
6598 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6599 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6600 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6601 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6602 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6603 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6604 { } /* end */
6605};
6606
6607/*
6608 * 4ch mode
6609 */
6610static struct hda_verb alc883_4ST_ch4_init[] = {
6611 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6612 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6613 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6614 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6615 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6616 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6617 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6618 { } /* end */
6619};
6620
6621/*
6622 * 6ch mode
6623 */
6624static struct hda_verb alc883_4ST_ch6_init[] = {
6625 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6626 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6627 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6628 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6629 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6630 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6631 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6632 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6633 { } /* end */
6634};
6635
6636/*
6637 * 8ch mode
6638 */
6639static struct hda_verb alc883_4ST_ch8_init[] = {
6640 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6641 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6642 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6643 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6644 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6645 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6646 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6647 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6648 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6649 { } /* end */
6650};
6651
6652static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6653 { 2, alc883_4ST_ch2_init },
6654 { 4, alc883_4ST_ch4_init },
6655 { 6, alc883_4ST_ch6_init },
6656 { 8, alc883_4ST_ch8_init },
6657};
6658
6659
6660/*
6661 * 2ch mode
6662 */
6663static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6664 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6665 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6666 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6667 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6668 { } /* end */
6669};
6670
6671/*
6672 * 4ch mode
6673 */
6674static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6675 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6676 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6677 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6678 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6679 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6680 { } /* end */
6681};
6682
6683/*
6684 * 6ch mode
6685 */
6686static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6687 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6688 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6689 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6690 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6691 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6692 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6693 { } /* end */
6694};
6695
6696static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6697 { 2, alc883_3ST_ch2_intel_init },
6698 { 4, alc883_3ST_ch4_intel_init },
6699 { 6, alc883_3ST_ch6_intel_init },
6700};
6701
6702/*
6703 * 2ch mode
6704 */
6705static struct hda_verb alc889_ch2_intel_init[] = {
6706 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6707 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
6708 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
6709 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
6710 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6711 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6712 { } /* end */
6713};
6714
6715/*
6716 * 6ch mode
6717 */
6718static struct hda_verb alc889_ch6_intel_init[] = {
6719 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6720 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6721 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6722 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6723 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6724 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6725 { } /* end */
6726};
6727
6728/*
6729 * 8ch mode
6730 */
6731static struct hda_verb alc889_ch8_intel_init[] = {
6732 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6733 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6734 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6735 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6736 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
6737 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6738 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6739 { } /* end */
6740};
6741
6742static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
6743 { 2, alc889_ch2_intel_init },
6744 { 6, alc889_ch6_intel_init },
6745 { 8, alc889_ch8_intel_init },
6746};
6747
6748/*
6749 * 6ch mode
6750 */
6751static struct hda_verb alc883_sixstack_ch6_init[] = {
6752 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6753 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6754 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6755 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6756 { } /* end */
6757};
6758
6759/*
6760 * 8ch mode
6761 */
6762static struct hda_verb alc883_sixstack_ch8_init[] = {
6763 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6764 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6765 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6766 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6767 { } /* end */
6768};
6769
6770static struct hda_channel_mode alc883_sixstack_modes[2] = {
6771 { 6, alc883_sixstack_ch6_init },
6772 { 8, alc883_sixstack_ch8_init },
6773};
6774
6775
6471/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 6776/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6472 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 6777 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6473 */ 6778 */
@@ -6603,7 +6908,7 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6603 { } /* end */ 6908 { } /* end */
6604}; 6909};
6605 6910
6606static struct hda_verb alc882_init_verbs[] = { 6911static struct hda_verb alc882_base_init_verbs[] = {
6607 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 6912 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6608 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6913 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6609 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6914 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -6621,6 +6926,13 @@ static struct hda_verb alc882_init_verbs[] = {
6621 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6926 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6622 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6927 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6623 6928
6929 /* mute analog input loopbacks */
6930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6933 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6934 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6935
6624 /* Front Pin: output 0 (0x0c) */ 6936 /* Front Pin: output 0 (0x0c) */
6625 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6937 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6626 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6938 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -6655,11 +6967,6 @@ static struct hda_verb alc882_init_verbs[] = {
6655 6967
6656 /* FIXME: use matrix-type input source selection */ 6968 /* FIXME: use matrix-type input source selection */
6657 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 6969 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6658 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6659 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6660 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6661 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6662 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6663 /* Input mixer2 */ 6970 /* Input mixer2 */
6664 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6971 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6665 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6972 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
@@ -6670,9 +6977,6 @@ static struct hda_verb alc882_init_verbs[] = {
6670 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6977 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6671 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6978 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6672 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6673 /* ADC1: mute amp left and right */
6674 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6675 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6676 /* ADC2: mute amp left and right */ 6980 /* ADC2: mute amp left and right */
6677 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6981 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6678 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 6982 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -6683,6 +6987,18 @@ static struct hda_verb alc882_init_verbs[] = {
6683 { } 6987 { }
6684}; 6988};
6685 6989
6990static struct hda_verb alc882_adc1_init_verbs[] = {
6991 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6996 /* ADC1: mute amp left and right */
6997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6998 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6999 { }
7000};
7001
6686static struct hda_verb alc882_eapd_verbs[] = { 7002static struct hda_verb alc882_eapd_verbs[] = {
6687 /* change to EAPD mode */ 7003 /* change to EAPD mode */
6688 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7004 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
@@ -6690,6 +7006,110 @@ static struct hda_verb alc882_eapd_verbs[] = {
6690 { } 7006 { }
6691}; 7007};
6692 7008
7009static struct hda_verb alc889_eapd_verbs[] = {
7010 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7011 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7012 { }
7013};
7014
7015static struct hda_verb alc_hp15_unsol_verbs[] = {
7016 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7018 {}
7019};
7020
7021static struct hda_verb alc885_init_verbs[] = {
7022 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7026 /* Rear mixer */
7027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7028 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7030 /* CLFE mixer */
7031 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7032 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7034 /* Side mixer */
7035 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7036 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7037 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7038
7039 /* mute analog input loopbacks */
7040 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7041 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7042 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7043
7044 /* Front HP Pin: output 0 (0x0c) */
7045 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7046 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7047 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7048 /* Front Pin: output 0 (0x0c) */
7049 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7050 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7051 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7052 /* Rear Pin: output 1 (0x0d) */
7053 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7054 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7055 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7056 /* CLFE Pin: output 2 (0x0e) */
7057 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7058 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7059 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7060 /* Side Pin: output 3 (0x0f) */
7061 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7062 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7063 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7064 /* Mic (rear) pin: input vref at 80% */
7065 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7066 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7067 /* Front Mic pin: input vref at 80% */
7068 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7069 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7070 /* Line In pin: input */
7071 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7072 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7073
7074 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7075 /* Input mixer1 */
7076 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7079 /* Input mixer2 */
7080 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7081 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7082 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7083 /* Input mixer3 */
7084 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7087 /* ADC2: mute amp left and right */
7088 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7089 /* ADC3: mute amp left and right */
7090 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7091
7092 { }
7093};
7094
7095static struct hda_verb alc885_init_input_verbs[] = {
7096 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7097 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7098 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7099 { }
7100};
7101
7102
7103/* Unmute Selector 24h and set the default input to front mic */
7104static struct hda_verb alc889_init_input_verbs[] = {
7105 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7106 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7107 { }
7108};
7109
7110
7111#define alc883_init_verbs alc882_base_init_verbs
7112
6693/* Mac Pro test */ 7113/* Mac Pro test */
6694static struct snd_kcontrol_new alc882_macpro_mixer[] = { 7114static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6695 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7115 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -7037,12 +7457,10 @@ static void alc885_imac24_init_hook(struct hda_codec *codec)
7037/* 7457/*
7038 * generic initialization of ADC, input mixers and output mixers 7458 * generic initialization of ADC, input mixers and output mixers
7039 */ 7459 */
7040static struct hda_verb alc882_auto_init_verbs[] = { 7460static struct hda_verb alc883_auto_init_verbs[] = {
7041 /* 7461 /*
7042 * Unmute ADC0-2 and set the default input to mic-in 7462 * Unmute ADC0-2 and set the default input to mic-in
7043 */ 7463 */
7044 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7045 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7464 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7465 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7048 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7466 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -7083,11 +7501,6 @@ static struct hda_verb alc882_auto_init_verbs[] = {
7083 7501
7084 /* FIXME: use matrix-type input source selection */ 7502 /* FIXME: use matrix-type input source selection */
7085 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7503 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7086 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7087 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7088 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7089 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7090 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7091 /* Input mixer2 */ 7504 /* Input mixer2 */
7092 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7505 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7093 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7506 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
@@ -7102,820 +7515,6 @@ static struct hda_verb alc882_auto_init_verbs[] = {
7102 { } 7515 { }
7103}; 7516};
7104 7517
7105#ifdef CONFIG_SND_HDA_POWER_SAVE
7106#define alc882_loopbacks alc880_loopbacks
7107#endif
7108
7109/* pcm configuration: identical with ALC880 */
7110#define alc882_pcm_analog_playback alc880_pcm_analog_playback
7111#define alc882_pcm_analog_capture alc880_pcm_analog_capture
7112#define alc882_pcm_digital_playback alc880_pcm_digital_playback
7113#define alc882_pcm_digital_capture alc880_pcm_digital_capture
7114
7115/*
7116 * configuration and preset
7117 */
7118static const char *alc882_models[ALC882_MODEL_LAST] = {
7119 [ALC882_3ST_DIG] = "3stack-dig",
7120 [ALC882_6ST_DIG] = "6stack-dig",
7121 [ALC882_ARIMA] = "arima",
7122 [ALC882_W2JC] = "w2jc",
7123 [ALC882_TARGA] = "targa",
7124 [ALC882_ASUS_A7J] = "asus-a7j",
7125 [ALC882_ASUS_A7M] = "asus-a7m",
7126 [ALC885_MACPRO] = "macpro",
7127 [ALC885_MB5] = "mb5",
7128 [ALC885_MBP3] = "mbp3",
7129 [ALC885_IMAC24] = "imac24",
7130 [ALC882_AUTO] = "auto",
7131};
7132
7133static struct snd_pci_quirk alc882_cfg_tbl[] = {
7134 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
7135 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
7136 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
7137 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
7138 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
7139 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7140 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
7141 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
7142 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
7143 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
7144 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
7145 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
7146 {}
7147};
7148
7149static struct alc_config_preset alc882_presets[] = {
7150 [ALC882_3ST_DIG] = {
7151 .mixers = { alc882_base_mixer },
7152 .init_verbs = { alc882_init_verbs },
7153 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7154 .dac_nids = alc882_dac_nids,
7155 .dig_out_nid = ALC882_DIGOUT_NID,
7156 .dig_in_nid = ALC882_DIGIN_NID,
7157 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7158 .channel_mode = alc882_ch_modes,
7159 .need_dac_fix = 1,
7160 .input_mux = &alc882_capture_source,
7161 },
7162 [ALC882_6ST_DIG] = {
7163 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7164 .init_verbs = { alc882_init_verbs },
7165 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7166 .dac_nids = alc882_dac_nids,
7167 .dig_out_nid = ALC882_DIGOUT_NID,
7168 .dig_in_nid = ALC882_DIGIN_NID,
7169 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7170 .channel_mode = alc882_sixstack_modes,
7171 .input_mux = &alc882_capture_source,
7172 },
7173 [ALC882_ARIMA] = {
7174 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7175 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
7176 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7177 .dac_nids = alc882_dac_nids,
7178 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7179 .channel_mode = alc882_sixstack_modes,
7180 .input_mux = &alc882_capture_source,
7181 },
7182 [ALC882_W2JC] = {
7183 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
7184 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7185 alc880_gpio1_init_verbs },
7186 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7187 .dac_nids = alc882_dac_nids,
7188 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7189 .channel_mode = alc880_threestack_modes,
7190 .need_dac_fix = 1,
7191 .input_mux = &alc882_capture_source,
7192 .dig_out_nid = ALC882_DIGOUT_NID,
7193 },
7194 [ALC885_MBP3] = {
7195 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
7196 .init_verbs = { alc885_mbp3_init_verbs,
7197 alc880_gpio1_init_verbs },
7198 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7199 .dac_nids = alc882_dac_nids,
7200 .channel_mode = alc885_mbp_6ch_modes,
7201 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
7202 .input_mux = &alc882_capture_source,
7203 .dig_out_nid = ALC882_DIGOUT_NID,
7204 .dig_in_nid = ALC882_DIGIN_NID,
7205 .unsol_event = alc_automute_amp_unsol_event,
7206 .init_hook = alc885_mbp3_init_hook,
7207 },
7208 [ALC885_MB5] = {
7209 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
7210 .init_verbs = { alc885_mb5_init_verbs,
7211 alc880_gpio1_init_verbs },
7212 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7213 .dac_nids = alc882_dac_nids,
7214 .channel_mode = alc885_mb5_6ch_modes,
7215 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
7216 .input_mux = &mb5_capture_source,
7217 .dig_out_nid = ALC882_DIGOUT_NID,
7218 .dig_in_nid = ALC882_DIGIN_NID,
7219 },
7220 [ALC885_MACPRO] = {
7221 .mixers = { alc882_macpro_mixer },
7222 .init_verbs = { alc882_macpro_init_verbs },
7223 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7224 .dac_nids = alc882_dac_nids,
7225 .dig_out_nid = ALC882_DIGOUT_NID,
7226 .dig_in_nid = ALC882_DIGIN_NID,
7227 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7228 .channel_mode = alc882_ch_modes,
7229 .input_mux = &alc882_capture_source,
7230 .init_hook = alc885_macpro_init_hook,
7231 },
7232 [ALC885_IMAC24] = {
7233 .mixers = { alc885_imac24_mixer },
7234 .init_verbs = { alc885_imac24_init_verbs },
7235 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7236 .dac_nids = alc882_dac_nids,
7237 .dig_out_nid = ALC882_DIGOUT_NID,
7238 .dig_in_nid = ALC882_DIGIN_NID,
7239 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7240 .channel_mode = alc882_ch_modes,
7241 .input_mux = &alc882_capture_source,
7242 .unsol_event = alc_automute_amp_unsol_event,
7243 .init_hook = alc885_imac24_init_hook,
7244 },
7245 [ALC882_TARGA] = {
7246 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
7247 .init_verbs = { alc882_init_verbs, alc880_gpio3_init_verbs,
7248 alc882_targa_verbs},
7249 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7250 .dac_nids = alc882_dac_nids,
7251 .dig_out_nid = ALC882_DIGOUT_NID,
7252 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7253 .adc_nids = alc882_adc_nids,
7254 .capsrc_nids = alc882_capsrc_nids,
7255 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7256 .channel_mode = alc882_3ST_6ch_modes,
7257 .need_dac_fix = 1,
7258 .input_mux = &alc882_capture_source,
7259 .unsol_event = alc882_targa_unsol_event,
7260 .init_hook = alc882_targa_init_hook,
7261 },
7262 [ALC882_ASUS_A7J] = {
7263 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
7264 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7265 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7266 .dac_nids = alc882_dac_nids,
7267 .dig_out_nid = ALC882_DIGOUT_NID,
7268 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7269 .adc_nids = alc882_adc_nids,
7270 .capsrc_nids = alc882_capsrc_nids,
7271 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7272 .channel_mode = alc882_3ST_6ch_modes,
7273 .need_dac_fix = 1,
7274 .input_mux = &alc882_capture_source,
7275 },
7276 [ALC882_ASUS_A7M] = {
7277 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7278 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7279 alc880_gpio1_init_verbs,
7280 alc882_asus_a7m_verbs },
7281 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7282 .dac_nids = alc882_dac_nids,
7283 .dig_out_nid = ALC882_DIGOUT_NID,
7284 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7285 .channel_mode = alc880_threestack_modes,
7286 .need_dac_fix = 1,
7287 .input_mux = &alc882_capture_source,
7288 },
7289};
7290
7291
7292/*
7293 * Pin config fixes
7294 */
7295enum {
7296 PINFIX_ABIT_AW9D_MAX
7297};
7298
7299static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7300 { 0x15, 0x01080104 }, /* side */
7301 { 0x16, 0x01011012 }, /* rear */
7302 { 0x17, 0x01016011 }, /* clfe */
7303 { }
7304};
7305
7306static const struct alc_pincfg *alc882_pin_fixes[] = {
7307 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7308};
7309
7310static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7311 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7312 {}
7313};
7314
7315/*
7316 * BIOS auto configuration
7317 */
7318static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7319 hda_nid_t nid, int pin_type,
7320 int dac_idx)
7321{
7322 /* set as output */
7323 struct alc_spec *spec = codec->spec;
7324 int idx;
7325
7326 alc_set_pin_output(codec, nid, pin_type);
7327 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7328 idx = 4;
7329 else
7330 idx = spec->multiout.dac_nids[dac_idx] - 2;
7331 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7332
7333}
7334
7335static void alc882_auto_init_multi_out(struct hda_codec *codec)
7336{
7337 struct alc_spec *spec = codec->spec;
7338 int i;
7339
7340 for (i = 0; i <= HDA_SIDE; i++) {
7341 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7342 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7343 if (nid)
7344 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7345 i);
7346 }
7347}
7348
7349static void alc882_auto_init_hp_out(struct hda_codec *codec)
7350{
7351 struct alc_spec *spec = codec->spec;
7352 hda_nid_t pin;
7353
7354 pin = spec->autocfg.hp_pins[0];
7355 if (pin) /* connect to front */
7356 /* use dac 0 */
7357 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7358 pin = spec->autocfg.speaker_pins[0];
7359 if (pin)
7360 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7361}
7362
7363#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7364#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7365
7366static void alc882_auto_init_analog_input(struct hda_codec *codec)
7367{
7368 struct alc_spec *spec = codec->spec;
7369 int i;
7370
7371 for (i = 0; i < AUTO_PIN_LAST; i++) {
7372 hda_nid_t nid = spec->autocfg.input_pins[i];
7373 if (!nid)
7374 continue;
7375 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7376 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7377 snd_hda_codec_write(codec, nid, 0,
7378 AC_VERB_SET_AMP_GAIN_MUTE,
7379 AMP_OUT_MUTE);
7380 }
7381}
7382
7383static void alc882_auto_init_input_src(struct hda_codec *codec)
7384{
7385 struct alc_spec *spec = codec->spec;
7386 int c;
7387
7388 for (c = 0; c < spec->num_adc_nids; c++) {
7389 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7390 hda_nid_t nid = spec->capsrc_nids[c];
7391 unsigned int mux_idx;
7392 const struct hda_input_mux *imux;
7393 int conns, mute, idx, item;
7394
7395 conns = snd_hda_get_connections(codec, nid, conn_list,
7396 ARRAY_SIZE(conn_list));
7397 if (conns < 0)
7398 continue;
7399 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7400 imux = &spec->input_mux[mux_idx];
7401 for (idx = 0; idx < conns; idx++) {
7402 /* if the current connection is the selected one,
7403 * unmute it as default - otherwise mute it
7404 */
7405 mute = AMP_IN_MUTE(idx);
7406 for (item = 0; item < imux->num_items; item++) {
7407 if (imux->items[item].index == idx) {
7408 if (spec->cur_mux[c] == item)
7409 mute = AMP_IN_UNMUTE(idx);
7410 break;
7411 }
7412 }
7413 /* check if we have a selector or mixer
7414 * we could check for the widget type instead, but
7415 * just check for Amp-In presence (in case of mixer
7416 * without amp-in there is something wrong, this
7417 * function shouldn't be used or capsrc nid is wrong)
7418 */
7419 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7420 snd_hda_codec_write(codec, nid, 0,
7421 AC_VERB_SET_AMP_GAIN_MUTE,
7422 mute);
7423 else if (mute != AMP_IN_MUTE(idx))
7424 snd_hda_codec_write(codec, nid, 0,
7425 AC_VERB_SET_CONNECT_SEL,
7426 idx);
7427 }
7428 }
7429}
7430
7431/* add mic boosts if needed */
7432static int alc_auto_add_mic_boost(struct hda_codec *codec)
7433{
7434 struct alc_spec *spec = codec->spec;
7435 int err;
7436 hda_nid_t nid;
7437
7438 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7439 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7440 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7441 "Mic Boost",
7442 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7443 if (err < 0)
7444 return err;
7445 }
7446 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7447 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7448 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7449 "Front Mic Boost",
7450 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7451 if (err < 0)
7452 return err;
7453 }
7454 return 0;
7455}
7456
7457/* almost identical with ALC880 parser... */
7458static int alc882_parse_auto_config(struct hda_codec *codec)
7459{
7460 struct alc_spec *spec = codec->spec;
7461 int err = alc880_parse_auto_config(codec);
7462
7463 if (err < 0)
7464 return err;
7465 else if (!err)
7466 return 0; /* no config found */
7467
7468 err = alc_auto_add_mic_boost(codec);
7469 if (err < 0)
7470 return err;
7471
7472 /* hack - override the init verbs */
7473 spec->init_verbs[0] = alc882_auto_init_verbs;
7474
7475 return 1; /* config found */
7476}
7477
7478/* additional initialization for auto-configuration model */
7479static void alc882_auto_init(struct hda_codec *codec)
7480{
7481 struct alc_spec *spec = codec->spec;
7482 alc882_auto_init_multi_out(codec);
7483 alc882_auto_init_hp_out(codec);
7484 alc882_auto_init_analog_input(codec);
7485 alc882_auto_init_input_src(codec);
7486 if (spec->unsol_event)
7487 alc_inithook(codec);
7488}
7489
7490static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7491
7492static int patch_alc882(struct hda_codec *codec)
7493{
7494 struct alc_spec *spec;
7495 int err, board_config;
7496
7497 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7498 if (spec == NULL)
7499 return -ENOMEM;
7500
7501 codec->spec = spec;
7502
7503 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7504 alc882_models,
7505 alc882_cfg_tbl);
7506
7507 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7508 /* Pick up systems that don't supply PCI SSID */
7509 switch (codec->subsystem_id) {
7510 case 0x106b0c00: /* Mac Pro */
7511 board_config = ALC885_MACPRO;
7512 break;
7513 case 0x106b1000: /* iMac 24 */
7514 case 0x106b2800: /* AppleTV */
7515 case 0x106b3e00: /* iMac 24 Aluminium */
7516 board_config = ALC885_IMAC24;
7517 break;
7518 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7519 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7520 case 0x106b00a4: /* MacbookPro4,1 */
7521 case 0x106b2c00: /* Macbook Pro rev3 */
7522 /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
7523 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7524 board_config = ALC885_MBP3;
7525 break;
7526 case 0x106b3f00: /* Macbook 5,1 */
7527 case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
7528 * seems not working, so apparently
7529 * no perfect solution yet
7530 */
7531 board_config = ALC885_MB5;
7532 break;
7533 default:
7534 /* ALC889A is handled better as ALC888-compatible */
7535 if (codec->revision_id == 0x100101 ||
7536 codec->revision_id == 0x100103) {
7537 alc_free(codec);
7538 return patch_alc883(codec);
7539 }
7540 printk(KERN_INFO "hda_codec: Unknown model for %s, "
7541 "trying auto-probe from BIOS...\n",
7542 codec->chip_name);
7543 board_config = ALC882_AUTO;
7544 }
7545 }
7546
7547 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7548
7549 if (board_config == ALC882_AUTO) {
7550 /* automatic parse from the BIOS config */
7551 err = alc882_parse_auto_config(codec);
7552 if (err < 0) {
7553 alc_free(codec);
7554 return err;
7555 } else if (!err) {
7556 printk(KERN_INFO
7557 "hda_codec: Cannot set up configuration "
7558 "from BIOS. Using base mode...\n");
7559 board_config = ALC882_3ST_DIG;
7560 }
7561 }
7562
7563 err = snd_hda_attach_beep_device(codec, 0x1);
7564 if (err < 0) {
7565 alc_free(codec);
7566 return err;
7567 }
7568
7569 if (board_config != ALC882_AUTO)
7570 setup_preset(spec, &alc882_presets[board_config]);
7571
7572 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7573 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7574 /* FIXME: setup DAC5 */
7575 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7576 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7577
7578 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7579 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7580
7581 if (!spec->adc_nids && spec->input_mux) {
7582 /* check whether NID 0x07 is valid */
7583 unsigned int wcap = get_wcaps(codec, 0x07);
7584 /* get type */
7585 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7586 if (wcap != AC_WID_AUD_IN) {
7587 spec->adc_nids = alc882_adc_nids_alt;
7588 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7589 spec->capsrc_nids = alc882_capsrc_nids_alt;
7590 } else {
7591 spec->adc_nids = alc882_adc_nids;
7592 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7593 spec->capsrc_nids = alc882_capsrc_nids;
7594 }
7595 }
7596 set_capture_mixer(spec);
7597 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7598
7599 spec->vmaster_nid = 0x0c;
7600
7601 codec->patch_ops = alc_patch_ops;
7602 if (board_config == ALC882_AUTO)
7603 spec->init_hook = alc882_auto_init;
7604#ifdef CONFIG_SND_HDA_POWER_SAVE
7605 if (!spec->loopback.amplist)
7606 spec->loopback.amplist = alc882_loopbacks;
7607#endif
7608 codec->proc_widget_hook = print_realtek_coef;
7609
7610 return 0;
7611}
7612
7613/*
7614 * ALC883 support
7615 *
7616 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7617 * configuration. Each pin widget can choose any input DACs and a mixer.
7618 * Each ADC is connected from a mixer of all inputs. This makes possible
7619 * 6-channel independent captures.
7620 *
7621 * In addition, an independent DAC for the multi-playback (not used in this
7622 * driver yet).
7623 */
7624#define ALC883_DIGOUT_NID 0x06
7625#define ALC883_DIGIN_NID 0x0a
7626
7627#define ALC1200_DIGOUT_NID 0x10
7628
7629static hda_nid_t alc883_dac_nids[4] = {
7630 /* front, rear, clfe, rear_surr */
7631 0x02, 0x03, 0x04, 0x05
7632};
7633
7634static hda_nid_t alc883_adc_nids[2] = {
7635 /* ADC1-2 */
7636 0x08, 0x09,
7637};
7638
7639static hda_nid_t alc883_adc_nids_alt[1] = {
7640 /* ADC1 */
7641 0x08,
7642};
7643
7644static hda_nid_t alc883_adc_nids_rev[2] = {
7645 /* ADC2-1 */
7646 0x09, 0x08
7647};
7648
7649#define alc889_adc_nids alc880_adc_nids
7650
7651static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7652
7653static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7654
7655#define alc889_capsrc_nids alc882_capsrc_nids
7656
7657/* input MUX */
7658/* FIXME: should be a matrix-type input source selection */
7659
7660static struct hda_input_mux alc883_capture_source = {
7661 .num_items = 4,
7662 .items = {
7663 { "Mic", 0x0 },
7664 { "Front Mic", 0x1 },
7665 { "Line", 0x2 },
7666 { "CD", 0x4 },
7667 },
7668};
7669
7670static struct hda_input_mux alc883_3stack_6ch_intel = {
7671 .num_items = 4,
7672 .items = {
7673 { "Mic", 0x1 },
7674 { "Front Mic", 0x0 },
7675 { "Line", 0x2 },
7676 { "CD", 0x4 },
7677 },
7678};
7679
7680static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7681 .num_items = 2,
7682 .items = {
7683 { "Mic", 0x1 },
7684 { "Line", 0x2 },
7685 },
7686};
7687
7688static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7689 .num_items = 4,
7690 .items = {
7691 { "Mic", 0x0 },
7692 { "iMic", 0x1 },
7693 { "Line", 0x2 },
7694 { "CD", 0x4 },
7695 },
7696};
7697
7698static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7699 .num_items = 2,
7700 .items = {
7701 { "Mic", 0x0 },
7702 { "Int Mic", 0x1 },
7703 },
7704};
7705
7706static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7707 .num_items = 3,
7708 .items = {
7709 { "Mic", 0x0 },
7710 { "Front Mic", 0x1 },
7711 { "Line", 0x4 },
7712 },
7713};
7714
7715static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7716 .num_items = 2,
7717 .items = {
7718 { "Mic", 0x0 },
7719 { "Line", 0x2 },
7720 },
7721};
7722
7723static struct hda_input_mux alc889A_mb31_capture_source = {
7724 .num_items = 2,
7725 .items = {
7726 { "Mic", 0x0 },
7727 /* Front Mic (0x01) unused */
7728 { "Line", 0x2 },
7729 /* Line 2 (0x03) unused */
7730 /* CD (0x04) unsused? */
7731 },
7732};
7733
7734/*
7735 * 2ch mode
7736 */
7737static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7738 { 2, NULL }
7739};
7740
7741/*
7742 * 2ch mode
7743 */
7744static struct hda_verb alc883_3ST_ch2_init[] = {
7745 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7746 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7747 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7748 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7749 { } /* end */
7750};
7751
7752/*
7753 * 4ch mode
7754 */
7755static struct hda_verb alc883_3ST_ch4_init[] = {
7756 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7757 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7758 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7759 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7760 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7761 { } /* end */
7762};
7763
7764/*
7765 * 6ch mode
7766 */
7767static struct hda_verb alc883_3ST_ch6_init[] = {
7768 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7769 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7770 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7771 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7772 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7773 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7774 { } /* end */
7775};
7776
7777static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7778 { 2, alc883_3ST_ch2_init },
7779 { 4, alc883_3ST_ch4_init },
7780 { 6, alc883_3ST_ch6_init },
7781};
7782
7783
7784/*
7785 * 2ch mode
7786 */
7787static struct hda_verb alc883_4ST_ch2_init[] = {
7788 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7789 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7790 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7791 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7792 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7793 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7794 { } /* end */
7795};
7796
7797/*
7798 * 4ch mode
7799 */
7800static struct hda_verb alc883_4ST_ch4_init[] = {
7801 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7802 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7803 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7804 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7805 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7806 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7807 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7808 { } /* end */
7809};
7810
7811/*
7812 * 6ch mode
7813 */
7814static struct hda_verb alc883_4ST_ch6_init[] = {
7815 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7816 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7817 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7818 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7819 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7820 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7821 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7822 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7823 { } /* end */
7824};
7825
7826/*
7827 * 8ch mode
7828 */
7829static struct hda_verb alc883_4ST_ch8_init[] = {
7830 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7831 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7832 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7833 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7834 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7835 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7836 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7837 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7838 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7839 { } /* end */
7840};
7841
7842static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7843 { 2, alc883_4ST_ch2_init },
7844 { 4, alc883_4ST_ch4_init },
7845 { 6, alc883_4ST_ch6_init },
7846 { 8, alc883_4ST_ch8_init },
7847};
7848
7849
7850/*
7851 * 2ch mode
7852 */
7853static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7854 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7855 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7856 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7857 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7858 { } /* end */
7859};
7860
7861/*
7862 * 4ch mode
7863 */
7864static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7865 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7866 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7867 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7868 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7869 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7870 { } /* end */
7871};
7872
7873/*
7874 * 6ch mode
7875 */
7876static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7877 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7878 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7879 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7880 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7881 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7882 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7883 { } /* end */
7884};
7885
7886static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7887 { 2, alc883_3ST_ch2_intel_init },
7888 { 4, alc883_3ST_ch4_intel_init },
7889 { 6, alc883_3ST_ch6_intel_init },
7890};
7891
7892/*
7893 * 6ch mode
7894 */
7895static struct hda_verb alc883_sixstack_ch6_init[] = {
7896 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7897 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7898 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7899 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7900 { } /* end */
7901};
7902
7903/*
7904 * 8ch mode
7905 */
7906static struct hda_verb alc883_sixstack_ch8_init[] = {
7907 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7908 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7909 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7910 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7911 { } /* end */
7912};
7913
7914static struct hda_channel_mode alc883_sixstack_modes[2] = {
7915 { 6, alc883_sixstack_ch6_init },
7916 { 8, alc883_sixstack_ch8_init },
7917};
7918
7919/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 7518/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7920static struct hda_verb alc889A_mb31_ch2_init[] = { 7519static struct hda_verb alc889A_mb31_ch2_init[] = {
7921 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 7520 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
@@ -7966,34 +7565,7 @@ static struct hda_verb alc883_medion_eapd_verbs[] = {
7966 { } 7565 { }
7967}; 7566};
7968 7567
7969/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 7568#define alc883_base_mixer alc882_base_mixer
7970 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7971 */
7972
7973static struct snd_kcontrol_new alc883_base_mixer[] = {
7974 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7975 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7976 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7977 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7978 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7979 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7980 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7981 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7982 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7983 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7984 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7985 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7986 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7988 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7990 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7992 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7993 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7994 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7995 { } /* end */
7996};
7997 7569
7998static struct snd_kcontrol_new alc883_mitac_mixer[] = { 7570static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7999 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7571 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -8104,6 +7676,30 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8104 { } /* end */ 7676 { } /* end */
8105}; 7677};
8106 7678
7679static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
7680 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7681 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7682 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7683 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7684 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7685 HDA_OUTPUT),
7686 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7687 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7688 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7689 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7690 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
7691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7692 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7693 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7694 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
7695 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
7696 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
7697 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7698 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7699 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7700 { } /* end */
7701};
7702
8107static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 7703static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8108 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7704 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8109 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7705 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -8344,84 +7940,6 @@ static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8344 { } /* end */ 7940 { } /* end */
8345}; 7941};
8346 7942
8347static struct hda_verb alc883_init_verbs[] = {
8348 /* ADC1: mute amp left and right */
8349 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8350 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8351 /* ADC2: mute amp left and right */
8352 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8353 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8354 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8356 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8357 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8358 /* Rear mixer */
8359 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8360 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8361 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8362 /* CLFE mixer */
8363 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8364 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8365 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8366 /* Side mixer */
8367 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8368 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8369 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8370
8371 /* mute analog input loopbacks */
8372 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8373 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8374 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8375 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8376 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8377
8378 /* Front Pin: output 0 (0x0c) */
8379 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8380 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8381 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8382 /* Rear Pin: output 1 (0x0d) */
8383 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8384 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8386 /* CLFE Pin: output 2 (0x0e) */
8387 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8388 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8389 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8390 /* Side Pin: output 3 (0x0f) */
8391 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8392 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8393 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8394 /* Mic (rear) pin: input vref at 80% */
8395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8397 /* Front Mic pin: input vref at 80% */
8398 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8399 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8400 /* Line In pin: input */
8401 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8402 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8403 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8404 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8405 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8406 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8407 /* CD pin widget for input */
8408 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8409
8410 /* FIXME: use matrix-type input source selection */
8411 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8412 /* Input mixer2 */
8413 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8414 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8415 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8416 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8417 /* Input mixer3 */
8418 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8419 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8420 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8421 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8422 { }
8423};
8424
8425/* toggle speaker-output according to the hp-jack state */ 7943/* toggle speaker-output according to the hp-jack state */
8426static void alc883_mitac_init_hook(struct hda_codec *codec) 7944static void alc883_mitac_init_hook(struct hda_codec *codec)
8427{ 7945{
@@ -8854,69 +8372,6 @@ static void alc883_vaiott_init_hook(struct hda_codec *codec)
8854 alc_automute_amp(codec); 8372 alc_automute_amp(codec);
8855} 8373}
8856 8374
8857/*
8858 * generic initialization of ADC, input mixers and output mixers
8859 */
8860static struct hda_verb alc883_auto_init_verbs[] = {
8861 /*
8862 * Unmute ADC0-2 and set the default input to mic-in
8863 */
8864 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8865 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8866 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8867 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8868
8869 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8870 * mixer widget
8871 * Note: PASD motherboards uses the Line In 2 as the input for
8872 * front panel mic (mic 2)
8873 */
8874 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8875 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8876 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8877 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8878 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8879 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8880
8881 /*
8882 * Set up output mixers (0x0c - 0x0f)
8883 */
8884 /* set vol=0 to output mixers */
8885 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8886 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8887 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8888 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8889 /* set up input amps for analog loopback */
8890 /* Amp Indices: DAC = 0, mixer = 1 */
8891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8892 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8893 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8894 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8895 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8896 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8897 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8898 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8899 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8900 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8901
8902 /* FIXME: use matrix-type input source selection */
8903 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8904 /* Input mixer1 */
8905 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8906 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8907 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8908 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8909 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8910 /* Input mixer2 */
8911 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8912 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8914 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8916
8917 { }
8918};
8919
8920static struct hda_verb alc888_asus_m90v_verbs[] = { 8375static struct hda_verb alc888_asus_m90v_verbs[] = {
8921 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8376 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8922 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8377 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -9027,25 +8482,44 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9027 alc889A_mb31_automute(codec); 8482 alc889A_mb31_automute(codec);
9028} 8483}
9029 8484
8485
9030#ifdef CONFIG_SND_HDA_POWER_SAVE 8486#ifdef CONFIG_SND_HDA_POWER_SAVE
9031#define alc883_loopbacks alc880_loopbacks 8487#define alc882_loopbacks alc880_loopbacks
9032#endif 8488#endif
9033 8489
9034/* pcm configuration: identical with ALC880 */ 8490/* pcm configuration: identical with ALC880 */
9035#define alc883_pcm_analog_playback alc880_pcm_analog_playback 8491#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9036#define alc883_pcm_analog_capture alc880_pcm_analog_capture 8492#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9037#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 8493#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9038#define alc883_pcm_digital_playback alc880_pcm_digital_playback 8494#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9039#define alc883_pcm_digital_capture alc880_pcm_digital_capture 8495
8496static hda_nid_t alc883_slave_dig_outs[] = {
8497 ALC1200_DIGOUT_NID, 0,
8498};
8499
8500static hda_nid_t alc1200_slave_dig_outs[] = {
8501 ALC883_DIGOUT_NID, 0,
8502};
9040 8503
9041/* 8504/*
9042 * configuration and preset 8505 * configuration and preset
9043 */ 8506 */
9044static const char *alc883_models[ALC883_MODEL_LAST] = { 8507static const char *alc882_models[ALC882_MODEL_LAST] = {
9045 [ALC883_3ST_2ch_DIG] = "3stack-dig", 8508 [ALC882_3ST_DIG] = "3stack-dig",
8509 [ALC882_6ST_DIG] = "6stack-dig",
8510 [ALC882_ARIMA] = "arima",
8511 [ALC882_W2JC] = "w2jc",
8512 [ALC882_TARGA] = "targa",
8513 [ALC882_ASUS_A7J] = "asus-a7j",
8514 [ALC882_ASUS_A7M] = "asus-a7m",
8515 [ALC885_MACPRO] = "macpro",
8516 [ALC885_MB5] = "mb5",
8517 [ALC885_MBP3] = "mbp3",
8518 [ALC885_IMAC24] = "imac24",
8519 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9046 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 8520 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9047 [ALC883_3ST_6ch] = "3stack-6ch", 8521 [ALC883_3ST_6ch] = "3stack-6ch",
9048 [ALC883_6ST_DIG] = "6stack-dig", 8522 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9049 [ALC883_TARGA_DIG] = "targa-dig", 8523 [ALC883_TARGA_DIG] = "targa-dig",
9050 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 8524 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9051 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", 8525 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
@@ -9069,14 +8543,17 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
9069 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 8543 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9070 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", 8544 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9071 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 8545 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8546 [ALC889A_INTEL] = "intel-alc889a",
8547 [ALC889_INTEL] = "intel-x58",
9072 [ALC1200_ASUS_P5Q] = "asus-p5q", 8548 [ALC1200_ASUS_P5Q] = "asus-p5q",
9073 [ALC889A_MB31] = "mb31", 8549 [ALC889A_MB31] = "mb31",
9074 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", 8550 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9075 [ALC883_AUTO] = "auto", 8551 [ALC882_AUTO] = "auto",
9076}; 8552};
9077 8553
9078static struct snd_pci_quirk alc883_cfg_tbl[] = { 8554static struct snd_pci_quirk alc882_cfg_tbl[] = {
9079 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), 8555 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8556
9080 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 8557 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9081 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), 8558 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9082 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), 8559 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
@@ -9091,8 +8568,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9091 ALC888_ACER_ASPIRE_8930G), 8568 ALC888_ACER_ASPIRE_8930G),
9092 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 8569 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9093 ALC888_ACER_ASPIRE_8930G), 8570 ALC888_ACER_ASPIRE_8930G),
9094 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), 8571 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9095 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), 8572 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9096 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 8573 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9097 ALC888_ACER_ASPIRE_6530G), 8574 ALC888_ACER_ASPIRE_6530G),
9098 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 8575 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
@@ -9101,30 +8578,44 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9101 * model=auto should work fine now 8578 * model=auto should work fine now
9102 */ 8579 */
9103 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ 8580 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8581
9104 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 8582 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8583
9105 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 8584 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9106 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 8585 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9107 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 8586 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9108 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 8587 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9109 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), 8588 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9110 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), 8589 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8590
8591 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
8592 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
8593 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9111 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 8594 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8595 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
8596 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
8597 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9112 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 8598 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9113 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), 8599 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9114 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 8600 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9115 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 8601 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8602
8603 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9116 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 8604 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9117 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 8605 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9118 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), 8606 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9119 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 8607 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9120 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 8608 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9121 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 8609 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9122 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 8610 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9123 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), 8611 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
8612
9124 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 8613 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9125 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 8614 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9126 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 8615 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8616 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9127 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG), 8617 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8618 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9128 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 8619 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9129 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 8620 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9130 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 8621 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
@@ -9133,6 +8624,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9133 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 8624 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9134 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 8625 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9135 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 8626 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8627 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9136 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 8628 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9137 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 8629 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9138 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 8630 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
@@ -9146,11 +8638,14 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9146 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 8638 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9147 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), 8639 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9148 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 8640 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8641 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
8642
9149 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 8643 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9150 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 8644 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9151 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 8645 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9152 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), 8646 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9153 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 8647 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8648 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9154 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 8649 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9155 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", 8650 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9156 ALC883_FUJITSU_PI2515), 8651 ALC883_FUJITSU_PI2515),
@@ -9165,24 +8660,182 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9165 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 8660 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9166 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 8661 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9167 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 8662 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8663
9168 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 8664 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9169 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 8665 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9170 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 8666 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9171 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), 8667 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
8668 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
8669 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9172 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 8670 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9173 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9174 {}
9175};
9176 8671
9177static hda_nid_t alc883_slave_dig_outs[] = { 8672 {}
9178 ALC1200_DIGOUT_NID, 0,
9179}; 8673};
9180 8674
9181static hda_nid_t alc1200_slave_dig_outs[] = { 8675/* codec SSID table for Intel Mac */
9182 ALC883_DIGOUT_NID, 0, 8676static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8677 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
8678 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
8679 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
8680 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
8681 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
8682 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
8683 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
8684 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8685 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8686 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
8687 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8688 /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently
8689 * no perfect solution yet
8690 */
8691 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8692 {} /* terminator */
9183}; 8693};
9184 8694
9185static struct alc_config_preset alc883_presets[] = { 8695static struct alc_config_preset alc882_presets[] = {
8696 [ALC882_3ST_DIG] = {
8697 .mixers = { alc882_base_mixer },
8698 .init_verbs = { alc882_base_init_verbs,
8699 alc882_adc1_init_verbs },
8700 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8701 .dac_nids = alc882_dac_nids,
8702 .dig_out_nid = ALC882_DIGOUT_NID,
8703 .dig_in_nid = ALC882_DIGIN_NID,
8704 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8705 .channel_mode = alc882_ch_modes,
8706 .need_dac_fix = 1,
8707 .input_mux = &alc882_capture_source,
8708 },
8709 [ALC882_6ST_DIG] = {
8710 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8711 .init_verbs = { alc882_base_init_verbs,
8712 alc882_adc1_init_verbs },
8713 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8714 .dac_nids = alc882_dac_nids,
8715 .dig_out_nid = ALC882_DIGOUT_NID,
8716 .dig_in_nid = ALC882_DIGIN_NID,
8717 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8718 .channel_mode = alc882_sixstack_modes,
8719 .input_mux = &alc882_capture_source,
8720 },
8721 [ALC882_ARIMA] = {
8722 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8723 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8724 alc882_eapd_verbs },
8725 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8726 .dac_nids = alc882_dac_nids,
8727 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8728 .channel_mode = alc882_sixstack_modes,
8729 .input_mux = &alc882_capture_source,
8730 },
8731 [ALC882_W2JC] = {
8732 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8733 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8734 alc882_eapd_verbs, alc880_gpio1_init_verbs },
8735 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8736 .dac_nids = alc882_dac_nids,
8737 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8738 .channel_mode = alc880_threestack_modes,
8739 .need_dac_fix = 1,
8740 .input_mux = &alc882_capture_source,
8741 .dig_out_nid = ALC882_DIGOUT_NID,
8742 },
8743 [ALC885_MBP3] = {
8744 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
8745 .init_verbs = { alc885_mbp3_init_verbs,
8746 alc880_gpio1_init_verbs },
8747 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8748 .dac_nids = alc882_dac_nids,
8749 .channel_mode = alc885_mbp_6ch_modes,
8750 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
8751 .input_mux = &alc882_capture_source,
8752 .dig_out_nid = ALC882_DIGOUT_NID,
8753 .dig_in_nid = ALC882_DIGIN_NID,
8754 .unsol_event = alc_automute_amp_unsol_event,
8755 .init_hook = alc885_mbp3_init_hook,
8756 },
8757 [ALC885_MB5] = {
8758 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
8759 .init_verbs = { alc885_mb5_init_verbs,
8760 alc880_gpio1_init_verbs },
8761 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8762 .dac_nids = alc882_dac_nids,
8763 .channel_mode = alc885_mb5_6ch_modes,
8764 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
8765 .input_mux = &mb5_capture_source,
8766 .dig_out_nid = ALC882_DIGOUT_NID,
8767 .dig_in_nid = ALC882_DIGIN_NID,
8768 },
8769 [ALC885_MACPRO] = {
8770 .mixers = { alc882_macpro_mixer },
8771 .init_verbs = { alc882_macpro_init_verbs },
8772 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8773 .dac_nids = alc882_dac_nids,
8774 .dig_out_nid = ALC882_DIGOUT_NID,
8775 .dig_in_nid = ALC882_DIGIN_NID,
8776 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8777 .channel_mode = alc882_ch_modes,
8778 .input_mux = &alc882_capture_source,
8779 .init_hook = alc885_macpro_init_hook,
8780 },
8781 [ALC885_IMAC24] = {
8782 .mixers = { alc885_imac24_mixer },
8783 .init_verbs = { alc885_imac24_init_verbs },
8784 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8785 .dac_nids = alc882_dac_nids,
8786 .dig_out_nid = ALC882_DIGOUT_NID,
8787 .dig_in_nid = ALC882_DIGIN_NID,
8788 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8789 .channel_mode = alc882_ch_modes,
8790 .input_mux = &alc882_capture_source,
8791 .unsol_event = alc_automute_amp_unsol_event,
8792 .init_hook = alc885_imac24_init_hook,
8793 },
8794 [ALC882_TARGA] = {
8795 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8796 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8797 alc880_gpio3_init_verbs, alc882_targa_verbs},
8798 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8799 .dac_nids = alc882_dac_nids,
8800 .dig_out_nid = ALC882_DIGOUT_NID,
8801 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8802 .adc_nids = alc882_adc_nids,
8803 .capsrc_nids = alc882_capsrc_nids,
8804 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8805 .channel_mode = alc882_3ST_6ch_modes,
8806 .need_dac_fix = 1,
8807 .input_mux = &alc882_capture_source,
8808 .unsol_event = alc882_targa_unsol_event,
8809 .init_hook = alc882_targa_init_hook,
8810 },
8811 [ALC882_ASUS_A7J] = {
8812 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8813 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8814 alc882_asus_a7j_verbs},
8815 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8816 .dac_nids = alc882_dac_nids,
8817 .dig_out_nid = ALC882_DIGOUT_NID,
8818 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8819 .adc_nids = alc882_adc_nids,
8820 .capsrc_nids = alc882_capsrc_nids,
8821 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8822 .channel_mode = alc882_3ST_6ch_modes,
8823 .need_dac_fix = 1,
8824 .input_mux = &alc882_capture_source,
8825 },
8826 [ALC882_ASUS_A7M] = {
8827 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8828 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8829 alc882_eapd_verbs, alc880_gpio1_init_verbs,
8830 alc882_asus_a7m_verbs },
8831 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8832 .dac_nids = alc882_dac_nids,
8833 .dig_out_nid = ALC882_DIGOUT_NID,
8834 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8835 .channel_mode = alc880_threestack_modes,
8836 .need_dac_fix = 1,
8837 .input_mux = &alc882_capture_source,
8838 },
9186 [ALC883_3ST_2ch_DIG] = { 8839 [ALC883_3ST_2ch_DIG] = {
9187 .mixers = { alc883_3ST_2ch_mixer }, 8840 .mixers = { alc883_3ST_2ch_mixer },
9188 .init_verbs = { alc883_init_verbs }, 8841 .init_verbs = { alc883_init_verbs },
@@ -9229,6 +8882,44 @@ static struct alc_config_preset alc883_presets[] = {
9229 .need_dac_fix = 1, 8882 .need_dac_fix = 1,
9230 .input_mux = &alc883_3stack_6ch_intel, 8883 .input_mux = &alc883_3stack_6ch_intel,
9231 }, 8884 },
8885 [ALC889A_INTEL] = {
8886 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
8887 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
8888 alc_hp15_unsol_verbs },
8889 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8890 .dac_nids = alc883_dac_nids,
8891 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
8892 .adc_nids = alc889_adc_nids,
8893 .dig_out_nid = ALC883_DIGOUT_NID,
8894 .dig_in_nid = ALC883_DIGIN_NID,
8895 .slave_dig_outs = alc883_slave_dig_outs,
8896 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
8897 .channel_mode = alc889_8ch_intel_modes,
8898 .capsrc_nids = alc889_capsrc_nids,
8899 .input_mux = &alc889_capture_source,
8900 .init_hook = alc889_automute_init,
8901 .unsol_event = alc_automute_amp_unsol_event,
8902 .need_dac_fix = 1,
8903 },
8904 [ALC889_INTEL] = {
8905 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
8906 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
8907 alc889_eapd_verbs, alc_hp15_unsol_verbs},
8908 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8909 .dac_nids = alc883_dac_nids,
8910 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
8911 .adc_nids = alc889_adc_nids,
8912 .dig_out_nid = ALC883_DIGOUT_NID,
8913 .dig_in_nid = ALC883_DIGIN_NID,
8914 .slave_dig_outs = alc883_slave_dig_outs,
8915 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
8916 .channel_mode = alc889_8ch_intel_modes,
8917 .capsrc_nids = alc889_capsrc_nids,
8918 .input_mux = &alc889_capture_source,
8919 .init_hook = alc889_intel_init_hook,
8920 .unsol_event = alc_automute_amp_unsol_event,
8921 .need_dac_fix = 1,
8922 },
9232 [ALC883_6ST_DIG] = { 8923 [ALC883_6ST_DIG] = {
9233 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 8924 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9234 .init_verbs = { alc883_init_verbs }, 8925 .init_verbs = { alc883_init_verbs },
@@ -9619,9 +9310,32 @@ static struct alc_config_preset alc883_presets[] = {
9619 9310
9620 9311
9621/* 9312/*
9313 * Pin config fixes
9314 */
9315enum {
9316 PINFIX_ABIT_AW9D_MAX
9317};
9318
9319static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9320 { 0x15, 0x01080104 }, /* side */
9321 { 0x16, 0x01011012 }, /* rear */
9322 { 0x17, 0x01016011 }, /* clfe */
9323 { }
9324};
9325
9326static const struct alc_pincfg *alc882_pin_fixes[] = {
9327 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
9328};
9329
9330static struct snd_pci_quirk alc882_pinfix_tbl[] = {
9331 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9332 {}
9333};
9334
9335/*
9622 * BIOS auto configuration 9336 * BIOS auto configuration
9623 */ 9337 */
9624static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, 9338static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9625 hda_nid_t nid, int pin_type, 9339 hda_nid_t nid, int pin_type,
9626 int dac_idx) 9340 int dac_idx)
9627{ 9341{
@@ -9638,7 +9352,7 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9638 9352
9639} 9353}
9640 9354
9641static void alc883_auto_init_multi_out(struct hda_codec *codec) 9355static void alc882_auto_init_multi_out(struct hda_codec *codec)
9642{ 9356{
9643 struct alc_spec *spec = codec->spec; 9357 struct alc_spec *spec = codec->spec;
9644 int i; 9358 int i;
@@ -9647,12 +9361,12 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec)
9647 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 9361 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9648 int pin_type = get_pin_type(spec->autocfg.line_out_type); 9362 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9649 if (nid) 9363 if (nid)
9650 alc883_auto_set_output_and_unmute(codec, nid, pin_type, 9364 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
9651 i); 9365 i);
9652 } 9366 }
9653} 9367}
9654 9368
9655static void alc883_auto_init_hp_out(struct hda_codec *codec) 9369static void alc882_auto_init_hp_out(struct hda_codec *codec)
9656{ 9370{
9657 struct alc_spec *spec = codec->spec; 9371 struct alc_spec *spec = codec->spec;
9658 hda_nid_t pin; 9372 hda_nid_t pin;
@@ -9660,42 +9374,111 @@ static void alc883_auto_init_hp_out(struct hda_codec *codec)
9660 pin = spec->autocfg.hp_pins[0]; 9374 pin = spec->autocfg.hp_pins[0];
9661 if (pin) /* connect to front */ 9375 if (pin) /* connect to front */
9662 /* use dac 0 */ 9376 /* use dac 0 */
9663 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 9377 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9664 pin = spec->autocfg.speaker_pins[0]; 9378 pin = spec->autocfg.speaker_pins[0];
9665 if (pin) 9379 if (pin)
9666 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 9380 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9667} 9381}
9668 9382
9669#define alc883_is_input_pin(nid) alc880_is_input_pin(nid) 9383static void alc882_auto_init_analog_input(struct hda_codec *codec)
9670#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9671
9672static void alc883_auto_init_analog_input(struct hda_codec *codec)
9673{ 9384{
9674 struct alc_spec *spec = codec->spec; 9385 struct alc_spec *spec = codec->spec;
9675 int i; 9386 int i;
9676 9387
9677 for (i = 0; i < AUTO_PIN_LAST; i++) { 9388 for (i = 0; i < AUTO_PIN_LAST; i++) {
9678 hda_nid_t nid = spec->autocfg.input_pins[i]; 9389 hda_nid_t nid = spec->autocfg.input_pins[i];
9679 if (alc883_is_input_pin(nid)) { 9390 if (!nid)
9680 alc_set_input_pin(codec, nid, i); 9391 continue;
9681 if (nid != ALC883_PIN_CD_NID && 9392 alc_set_input_pin(codec, nid, i);
9682 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 9393 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9394 snd_hda_codec_write(codec, nid, 0,
9395 AC_VERB_SET_AMP_GAIN_MUTE,
9396 AMP_OUT_MUTE);
9397 }
9398}
9399
9400static void alc882_auto_init_input_src(struct hda_codec *codec)
9401{
9402 struct alc_spec *spec = codec->spec;
9403 int c;
9404
9405 for (c = 0; c < spec->num_adc_nids; c++) {
9406 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9407 hda_nid_t nid = spec->capsrc_nids[c];
9408 unsigned int mux_idx;
9409 const struct hda_input_mux *imux;
9410 int conns, mute, idx, item;
9411
9412 conns = snd_hda_get_connections(codec, nid, conn_list,
9413 ARRAY_SIZE(conn_list));
9414 if (conns < 0)
9415 continue;
9416 mux_idx = c >= spec->num_mux_defs ? 0 : c;
9417 imux = &spec->input_mux[mux_idx];
9418 for (idx = 0; idx < conns; idx++) {
9419 /* if the current connection is the selected one,
9420 * unmute it as default - otherwise mute it
9421 */
9422 mute = AMP_IN_MUTE(idx);
9423 for (item = 0; item < imux->num_items; item++) {
9424 if (imux->items[item].index == idx) {
9425 if (spec->cur_mux[c] == item)
9426 mute = AMP_IN_UNMUTE(idx);
9427 break;
9428 }
9429 }
9430 /* check if we have a selector or mixer
9431 * we could check for the widget type instead, but
9432 * just check for Amp-In presence (in case of mixer
9433 * without amp-in there is something wrong, this
9434 * function shouldn't be used or capsrc nid is wrong)
9435 */
9436 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9683 snd_hda_codec_write(codec, nid, 0, 9437 snd_hda_codec_write(codec, nid, 0,
9684 AC_VERB_SET_AMP_GAIN_MUTE, 9438 AC_VERB_SET_AMP_GAIN_MUTE,
9685 AMP_OUT_MUTE); 9439 mute);
9440 else if (mute != AMP_IN_MUTE(idx))
9441 snd_hda_codec_write(codec, nid, 0,
9442 AC_VERB_SET_CONNECT_SEL,
9443 idx);
9686 } 9444 }
9687 } 9445 }
9688} 9446}
9689 9447
9690#define alc883_auto_init_input_src alc882_auto_init_input_src 9448/* add mic boosts if needed */
9449static int alc_auto_add_mic_boost(struct hda_codec *codec)
9450{
9451 struct alc_spec *spec = codec->spec;
9452 int err;
9453 hda_nid_t nid;
9454
9455 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9456 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9457 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9458 "Mic Boost",
9459 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9460 if (err < 0)
9461 return err;
9462 }
9463 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9464 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9465 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9466 "Front Mic Boost",
9467 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9468 if (err < 0)
9469 return err;
9470 }
9471 return 0;
9472}
9691 9473
9692/* almost identical with ALC880 parser... */ 9474/* almost identical with ALC880 parser... */
9693static int alc883_parse_auto_config(struct hda_codec *codec) 9475static int alc882_parse_auto_config(struct hda_codec *codec)
9694{ 9476{
9695 struct alc_spec *spec = codec->spec; 9477 struct alc_spec *spec = codec->spec;
9696 int err = alc880_parse_auto_config(codec); 9478 struct auto_pin_cfg *autocfg = &spec->autocfg;
9697 struct auto_pin_cfg *cfg = &spec->autocfg; 9479 unsigned int wcap;
9698 int i; 9480 int i;
9481 int err = alc880_parse_auto_config(codec);
9699 9482
9700 if (err < 0) 9483 if (err < 0)
9701 return err; 9484 return err;
@@ -9708,43 +9491,45 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
9708 9491
9709 /* hack - override the init verbs */ 9492 /* hack - override the init verbs */
9710 spec->init_verbs[0] = alc883_auto_init_verbs; 9493 spec->init_verbs[0] = alc883_auto_init_verbs;
9494 /* if ADC 0x07 is available, initialize it, too */
9495 wcap = get_wcaps(codec, 0x07);
9496 wcap = get_wcaps_type(wcap);
9497 if (wcap == AC_WID_AUD_IN)
9498 add_verb(spec, alc882_adc1_init_verbs);
9711 9499
9712 /* setup input_mux for ALC889 */ 9500 /* digital-mic input pin is excluded in alc880_auto_create..()
9713 if (codec->vendor_id == 0x10ec0889) { 9501 * because it's under 0x18
9714 /* digital-mic input pin is excluded in alc880_auto_create..() 9502 */
9715 * because it's under 0x18 9503 if (autocfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9716 */ 9504 autocfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9717 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || 9505 struct hda_input_mux *imux = &spec->private_imux[0];
9718 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { 9506 for (i = 1; i < 3; i++)
9719 struct hda_input_mux *imux = &spec->private_imux[0]; 9507 memcpy(&spec->private_imux[i],
9720 for (i = 1; i < 3; i++) 9508 &spec->private_imux[0],
9721 memcpy(&spec->private_imux[i], 9509 sizeof(spec->private_imux[0]));
9722 &spec->private_imux[0], 9510 imux->items[imux->num_items].label = "Int DMic";
9723 sizeof(spec->private_imux[0])); 9511 imux->items[imux->num_items].index = 0x0b;
9724 imux->items[imux->num_items].label = "Int DMic"; 9512 imux->num_items++;
9725 imux->items[imux->num_items].index = 0x0b; 9513 spec->num_mux_defs = 3;
9726 imux->num_items++; 9514 spec->input_mux = spec->private_imux;
9727 spec->num_mux_defs = 3;
9728 spec->input_mux = spec->private_imux;
9729 }
9730 } 9515 }
9731 9516
9732 return 1; /* config found */ 9517 return 1; /* config found */
9733} 9518}
9734 9519
9735/* additional initialization for auto-configuration model */ 9520/* additional initialization for auto-configuration model */
9736static void alc883_auto_init(struct hda_codec *codec) 9521static void alc882_auto_init(struct hda_codec *codec)
9737{ 9522{
9738 struct alc_spec *spec = codec->spec; 9523 struct alc_spec *spec = codec->spec;
9739 alc883_auto_init_multi_out(codec); 9524 alc882_auto_init_multi_out(codec);
9740 alc883_auto_init_hp_out(codec); 9525 alc882_auto_init_hp_out(codec);
9741 alc883_auto_init_analog_input(codec); 9526 alc882_auto_init_analog_input(codec);
9742 alc883_auto_init_input_src(codec); 9527 alc882_auto_init_input_src(codec);
9743 if (spec->unsol_event) 9528 if (spec->unsol_event)
9744 alc_inithook(codec); 9529 alc_inithook(codec);
9745} 9530}
9746 9531
9747static int patch_alc883(struct hda_codec *codec) 9532static int patch_alc882(struct hda_codec *codec)
9748{ 9533{
9749 struct alc_spec *spec; 9534 struct alc_spec *spec;
9750 int err, board_config; 9535 int err, board_config;
@@ -9755,28 +9540,35 @@ static int patch_alc883(struct hda_codec *codec)
9755 9540
9756 codec->spec = spec; 9541 codec->spec = spec;
9757 9542
9758 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 9543 switch (codec->vendor_id) {
9544 case 0x10ec0882:
9545 case 0x10ec0885:
9546 break;
9547 default:
9548 /* ALC883 and variants */
9549 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9550 break;
9551 }
9759 9552
9760 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, 9553 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
9761 alc883_models, 9554 alc882_models,
9762 alc883_cfg_tbl); 9555 alc882_cfg_tbl);
9763 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { 9556
9764 /* Pick up systems that don't supply PCI SSID */ 9557 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
9765 switch (codec->subsystem_id) { 9558 board_config = snd_hda_check_board_codec_sid_config(codec,
9766 case 0x106b3600: /* Macbook 3.1 */ 9559 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
9767 board_config = ALC889A_MB31; 9560
9768 break; 9561 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9769 default: 9562 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
9770 printk(KERN_INFO 9563 codec->chip_name);
9771 "hda_codec: Unknown model for %s, trying " 9564 board_config = ALC882_AUTO;
9772 "auto-probe from BIOS...\n", codec->chip_name);
9773 board_config = ALC883_AUTO;
9774 }
9775 } 9565 }
9776 9566
9777 if (board_config == ALC883_AUTO) { 9567 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
9568
9569 if (board_config == ALC882_AUTO) {
9778 /* automatic parse from the BIOS config */ 9570 /* automatic parse from the BIOS config */
9779 err = alc883_parse_auto_config(codec); 9571 err = alc882_parse_auto_config(codec);
9780 if (err < 0) { 9572 if (err < 0) {
9781 alc_free(codec); 9573 alc_free(codec);
9782 return err; 9574 return err;
@@ -9784,7 +9576,7 @@ static int patch_alc883(struct hda_codec *codec)
9784 printk(KERN_INFO 9576 printk(KERN_INFO
9785 "hda_codec: Cannot set up configuration " 9577 "hda_codec: Cannot set up configuration "
9786 "from BIOS. Using base mode...\n"); 9578 "from BIOS. Using base mode...\n");
9787 board_config = ALC883_3ST_2ch_DIG; 9579 board_config = ALC882_3ST_DIG;
9788 } 9580 }
9789 } 9581 }
9790 9582
@@ -9794,63 +9586,61 @@ static int patch_alc883(struct hda_codec *codec)
9794 return err; 9586 return err;
9795 } 9587 }
9796 9588
9797 if (board_config != ALC883_AUTO) 9589 if (board_config != ALC882_AUTO)
9798 setup_preset(spec, &alc883_presets[board_config]); 9590 setup_preset(spec, &alc882_presets[board_config]);
9799 9591
9800 switch (codec->vendor_id) { 9592 spec->stream_analog_playback = &alc882_pcm_analog_playback;
9801 case 0x10ec0888: 9593 spec->stream_analog_capture = &alc882_pcm_analog_capture;
9802 if (!spec->num_adc_nids) { 9594 /* FIXME: setup DAC5 */
9803 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9595 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
9804 spec->adc_nids = alc883_adc_nids; 9596 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
9805 } 9597
9806 if (!spec->capsrc_nids) 9598 spec->stream_digital_playback = &alc882_pcm_digital_playback;
9807 spec->capsrc_nids = alc883_capsrc_nids; 9599 spec->stream_digital_capture = &alc882_pcm_digital_capture;
9600
9601 if (codec->vendor_id == 0x10ec0888)
9808 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ 9602 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9809 break; 9603
9810 case 0x10ec0889: 9604 if (!spec->adc_nids && spec->input_mux) {
9811 if (!spec->num_adc_nids) { 9605 int i;
9812 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids); 9606 spec->num_adc_nids = 0;
9813 spec->adc_nids = alc889_adc_nids; 9607 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
9814 } 9608 hda_nid_t cap;
9815 if (!spec->capsrc_nids) 9609 hda_nid_t nid = alc882_adc_nids[i];
9816 spec->capsrc_nids = alc889_capsrc_nids; 9610 unsigned int wcap = get_wcaps(codec, nid);
9817 break; 9611 /* get type */
9818 default: 9612 wcap = get_wcaps_type(wcap);
9819 if (!spec->num_adc_nids) { 9613 if (wcap != AC_WID_AUD_IN)
9820 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9614 continue;
9821 spec->adc_nids = alc883_adc_nids; 9615 spec->private_adc_nids[spec->num_adc_nids] = nid;
9616 err = snd_hda_get_connections(codec, nid, &cap, 1);
9617 if (err < 0)
9618 continue;
9619 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9620 spec->num_adc_nids++;
9822 } 9621 }
9823 if (!spec->capsrc_nids) 9622 spec->adc_nids = spec->private_adc_nids;
9824 spec->capsrc_nids = alc883_capsrc_nids; 9623 spec->capsrc_nids = spec->private_capsrc_nids;
9825 break;
9826 } 9624 }
9827 9625
9828 spec->stream_analog_playback = &alc883_pcm_analog_playback; 9626 set_capture_mixer(spec);
9829 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9830 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9831
9832 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9833 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9834
9835 if (!spec->cap_mixer)
9836 set_capture_mixer(spec);
9837 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 9627 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9838 9628
9839 spec->vmaster_nid = 0x0c; 9629 spec->vmaster_nid = 0x0c;
9840 9630
9841 codec->patch_ops = alc_patch_ops; 9631 codec->patch_ops = alc_patch_ops;
9842 if (board_config == ALC883_AUTO) 9632 if (board_config == ALC882_AUTO)
9843 spec->init_hook = alc883_auto_init; 9633 spec->init_hook = alc882_auto_init;
9844
9845#ifdef CONFIG_SND_HDA_POWER_SAVE 9634#ifdef CONFIG_SND_HDA_POWER_SAVE
9846 if (!spec->loopback.amplist) 9635 if (!spec->loopback.amplist)
9847 spec->loopback.amplist = alc883_loopbacks; 9636 spec->loopback.amplist = alc882_loopbacks;
9848#endif 9637#endif
9849 codec->proc_widget_hook = print_realtek_coef; 9638 codec->proc_widget_hook = print_realtek_coef;
9850 9639
9851 return 0; 9640 return 0;
9852} 9641}
9853 9642
9643
9854/* 9644/*
9855 * ALC262 support 9645 * ALC262 support
9856 */ 9646 */
@@ -10359,12 +10149,6 @@ static struct hda_verb alc262_eapd_verbs[] = {
10359 { } 10149 { }
10360}; 10150};
10361 10151
10362static struct hda_verb alc262_hippo_unsol_verbs[] = {
10363 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10365 {}
10366};
10367
10368static struct hda_verb alc262_hippo1_unsol_verbs[] = { 10152static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10369 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 10153 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10370 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 10154 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -11406,7 +11190,7 @@ static struct alc_config_preset alc262_presets[] = {
11406 }, 11190 },
11407 [ALC262_HIPPO] = { 11191 [ALC262_HIPPO] = {
11408 .mixers = { alc262_hippo_mixer }, 11192 .mixers = { alc262_hippo_mixer },
11409 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, 11193 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
11410 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11194 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11411 .dac_nids = alc262_dac_nids, 11195 .dac_nids = alc262_dac_nids,
11412 .hp_nid = 0x03, 11196 .hp_nid = 0x03,
@@ -11526,7 +11310,8 @@ static struct alc_config_preset alc262_presets[] = {
11526 }, 11310 },
11527 [ALC262_BENQ_T31] = { 11311 [ALC262_BENQ_T31] = {
11528 .mixers = { alc262_benq_t31_mixer }, 11312 .mixers = { alc262_benq_t31_mixer },
11529 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, 11313 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
11314 alc_hp15_unsol_verbs },
11530 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11315 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11531 .dac_nids = alc262_dac_nids, 11316 .dac_nids = alc262_dac_nids,
11532 .hp_nid = 0x03, 11317 .hp_nid = 0x03,
@@ -11648,8 +11433,8 @@ static int patch_alc262(struct hda_codec *codec)
11648 alc262_cfg_tbl); 11433 alc262_cfg_tbl);
11649 11434
11650 if (board_config < 0) { 11435 if (board_config < 0) {
11651 printk(KERN_INFO "hda_codec: Unknown model for %s, " 11436 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11652 "trying auto-probe from BIOS...\n", codec->chip_name); 11437 codec->chip_name);
11653 board_config = ALC262_AUTO; 11438 board_config = ALC262_AUTO;
11654 } 11439 }
11655 11440
@@ -11702,7 +11487,7 @@ static int patch_alc262(struct hda_codec *codec)
11702 unsigned int wcap = get_wcaps(codec, 0x07); 11487 unsigned int wcap = get_wcaps(codec, 0x07);
11703 11488
11704 /* get type */ 11489 /* get type */
11705 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 11490 wcap = get_wcaps_type(wcap);
11706 if (wcap != AC_WID_AUD_IN) { 11491 if (wcap != AC_WID_AUD_IN) {
11707 spec->adc_nids = alc262_adc_nids_alt; 11492 spec->adc_nids = alc262_adc_nids_alt;
11708 spec->num_adc_nids = 11493 spec->num_adc_nids =
@@ -12269,26 +12054,38 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12269 const char *ctlname, int idx) 12054 const char *ctlname, int idx)
12270{ 12055{
12271 char name[32]; 12056 char name[32];
12057 hda_nid_t dac;
12272 int err; 12058 int err;
12273 12059
12274 sprintf(name, "%s Playback Volume", ctlname); 12060 sprintf(name, "%s Playback Volume", ctlname);
12275 if (nid == 0x14) { 12061 switch (nid) {
12276 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 12062 case 0x14:
12277 HDA_COMPOSE_AMP_VAL(0x02, 3, idx, 12063 case 0x16:
12278 HDA_OUTPUT)); 12064 dac = 0x02;
12279 if (err < 0) 12065 break;
12280 return err; 12066 case 0x15:
12281 } else if (nid == 0x15) { 12067 dac = 0x03;
12068 break;
12069 default:
12070 return 0;
12071 }
12072 if (spec->multiout.dac_nids[0] != dac &&
12073 spec->multiout.dac_nids[1] != dac) {
12282 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 12074 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12283 HDA_COMPOSE_AMP_VAL(0x03, 3, idx, 12075 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
12284 HDA_OUTPUT)); 12076 HDA_OUTPUT));
12285 if (err < 0) 12077 if (err < 0)
12286 return err; 12078 return err;
12287 } else 12079 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12288 return -1; 12080 }
12081
12289 sprintf(name, "%s Playback Switch", ctlname); 12082 sprintf(name, "%s Playback Switch", ctlname);
12290 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 12083 if (nid != 0x16)
12084 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12291 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 12085 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
12086 else /* mono */
12087 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12088 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
12292 if (err < 0) 12089 if (err < 0)
12293 return err; 12090 return err;
12294 return 0; 12091 return 0;
@@ -12301,14 +12098,19 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12301 hda_nid_t nid; 12098 hda_nid_t nid;
12302 int err; 12099 int err;
12303 12100
12304 spec->multiout.num_dacs = 2; /* only use one dac */
12305 spec->multiout.dac_nids = spec->private_dac_nids; 12101 spec->multiout.dac_nids = spec->private_dac_nids;
12306 spec->multiout.dac_nids[0] = 2;
12307 spec->multiout.dac_nids[1] = 3;
12308 12102
12309 nid = cfg->line_out_pins[0]; 12103 nid = cfg->line_out_pins[0];
12310 if (nid) 12104 if (nid) {
12311 alc268_new_analog_output(spec, nid, "Front", 0); 12105 const char *name;
12106 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12107 name = "Speaker";
12108 else
12109 name = "Front";
12110 err = alc268_new_analog_output(spec, nid, name, 0);
12111 if (err < 0)
12112 return err;
12113 }
12312 12114
12313 nid = cfg->speaker_pins[0]; 12115 nid = cfg->speaker_pins[0];
12314 if (nid == 0x1d) { 12116 if (nid == 0x1d) {
@@ -12317,16 +12119,23 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12317 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 12119 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12318 if (err < 0) 12120 if (err < 0)
12319 return err; 12121 return err;
12122 } else {
12123 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12124 if (err < 0)
12125 return err;
12320 } 12126 }
12321 nid = cfg->hp_pins[0]; 12127 nid = cfg->hp_pins[0];
12322 if (nid) 12128 if (nid) {
12323 alc268_new_analog_output(spec, nid, "Headphone", 0); 12129 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12130 if (err < 0)
12131 return err;
12132 }
12324 12133
12325 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 12134 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12326 if (nid == 0x16) { 12135 if (nid == 0x16) {
12327 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 12136 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12328 "Mono Playback Switch", 12137 "Mono Playback Switch",
12329 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); 12138 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
12330 if (err < 0) 12139 if (err < 0)
12331 return err; 12140 return err;
12332 } 12141 }
@@ -12697,8 +12506,8 @@ static int patch_alc268(struct hda_codec *codec)
12697 alc268_cfg_tbl); 12506 alc268_cfg_tbl);
12698 12507
12699 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 12508 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12700 printk(KERN_INFO "hda_codec: Unknown model for %s, " 12509 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12701 "trying auto-probe from BIOS...\n", codec->chip_name); 12510 codec->chip_name);
12702 board_config = ALC268_AUTO; 12511 board_config = ALC268_AUTO;
12703 } 12512 }
12704 12513
@@ -12754,7 +12563,7 @@ static int patch_alc268(struct hda_codec *codec)
12754 int i; 12563 int i;
12755 12564
12756 /* get type */ 12565 /* get type */
12757 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 12566 wcap = get_wcaps_type(wcap);
12758 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 12567 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12759 spec->adc_nids = alc268_adc_nids_alt; 12568 spec->adc_nids = alc268_adc_nids_alt;
12760 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 12569 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
@@ -13515,8 +13324,8 @@ static int patch_alc269(struct hda_codec *codec)
13515 alc269_cfg_tbl); 13324 alc269_cfg_tbl);
13516 13325
13517 if (board_config < 0) { 13326 if (board_config < 0) {
13518 printk(KERN_INFO "hda_codec: Unknown model for %s, " 13327 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13519 "trying auto-probe from BIOS...\n", codec->chip_name); 13328 codec->chip_name);
13520 board_config = ALC269_AUTO; 13329 board_config = ALC269_AUTO;
13521 } 13330 }
13522 13331
@@ -14108,23 +13917,23 @@ static struct hda_verb alc861_auto_init_verbs[] = {
14108 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14109 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 13918 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14110 13919
14111 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13920 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14112 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13921 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14113 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13922 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14114 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13923 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14115 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13924 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14116 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13925 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14117 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13926 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14118 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 13927 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14119 13928
14120 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13929 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14121 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13930 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14122 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13931 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14123 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 13932 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14124 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13933 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14125 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13934 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14126 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 13935 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14127 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 13936 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14128 13937
14129 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 13938 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
14130 13939
@@ -14196,64 +14005,96 @@ static struct hda_input_mux alc861_capture_source = {
14196 }, 14005 },
14197}; 14006};
14198 14007
14008static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
14009{
14010 struct alc_spec *spec = codec->spec;
14011 hda_nid_t mix, srcs[5];
14012 int i, j, num;
14013
14014 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
14015 return 0;
14016 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14017 if (num < 0)
14018 return 0;
14019 for (i = 0; i < num; i++) {
14020 unsigned int type;
14021 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
14022 if (type != AC_WID_AUD_OUT)
14023 continue;
14024 for (j = 0; j < spec->multiout.num_dacs; j++)
14025 if (spec->multiout.dac_nids[j] == srcs[i])
14026 break;
14027 if (j >= spec->multiout.num_dacs)
14028 return srcs[i];
14029 }
14030 return 0;
14031}
14032
14199/* fill in the dac_nids table from the parsed pin configuration */ 14033/* fill in the dac_nids table from the parsed pin configuration */
14200static int alc861_auto_fill_dac_nids(struct alc_spec *spec, 14034static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
14201 const struct auto_pin_cfg *cfg) 14035 const struct auto_pin_cfg *cfg)
14202{ 14036{
14037 struct alc_spec *spec = codec->spec;
14203 int i; 14038 int i;
14204 hda_nid_t nid; 14039 hda_nid_t nid, dac;
14205 14040
14206 spec->multiout.dac_nids = spec->private_dac_nids; 14041 spec->multiout.dac_nids = spec->private_dac_nids;
14207 for (i = 0; i < cfg->line_outs; i++) { 14042 for (i = 0; i < cfg->line_outs; i++) {
14208 nid = cfg->line_out_pins[i]; 14043 nid = cfg->line_out_pins[i];
14209 if (nid) { 14044 dac = alc861_look_for_dac(codec, nid);
14210 if (i >= ARRAY_SIZE(alc861_dac_nids)) 14045 if (!dac)
14211 continue; 14046 continue;
14212 spec->multiout.dac_nids[i] = alc861_dac_nids[i]; 14047 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
14213 }
14214 } 14048 }
14215 spec->multiout.num_dacs = cfg->line_outs;
14216 return 0; 14049 return 0;
14217} 14050}
14218 14051
14052static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
14053 hda_nid_t nid, unsigned int chs)
14054{
14055 char name[32];
14056 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
14057 return add_control(codec->spec, ALC_CTL_WIDGET_MUTE, name,
14058 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
14059}
14060
14219/* add playback controls from the parsed DAC table */ 14061/* add playback controls from the parsed DAC table */
14220static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, 14062static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
14221 const struct auto_pin_cfg *cfg) 14063 const struct auto_pin_cfg *cfg)
14222{ 14064{
14223 char name[32]; 14065 struct alc_spec *spec = codec->spec;
14224 static const char *chname[4] = { 14066 static const char *chname[4] = {
14225 "Front", "Surround", NULL /*CLFE*/, "Side" 14067 "Front", "Surround", NULL /*CLFE*/, "Side"
14226 }; 14068 };
14227 hda_nid_t nid; 14069 hda_nid_t nid;
14228 int i, idx, err; 14070 int i, err;
14071
14072 if (cfg->line_outs == 1) {
14073 const char *pfx = NULL;
14074 if (!cfg->hp_outs)
14075 pfx = "Master";
14076 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
14077 pfx = "Speaker";
14078 if (pfx) {
14079 nid = spec->multiout.dac_nids[0];
14080 return alc861_create_out_sw(codec, pfx, nid, 3);
14081 }
14082 }
14229 14083
14230 for (i = 0; i < cfg->line_outs; i++) { 14084 for (i = 0; i < cfg->line_outs; i++) {
14231 nid = spec->multiout.dac_nids[i]; 14085 nid = spec->multiout.dac_nids[i];
14232 if (!nid) 14086 if (!nid)
14233 continue; 14087 continue;
14234 if (nid == 0x05) { 14088 if (i == 2) {
14235 /* Center/LFE */ 14089 /* Center/LFE */
14236 err = add_control(spec, ALC_CTL_BIND_MUTE, 14090 err = alc861_create_out_sw(codec, "Center", nid, 1);
14237 "Center Playback Switch",
14238 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
14239 HDA_OUTPUT));
14240 if (err < 0) 14091 if (err < 0)
14241 return err; 14092 return err;
14242 err = add_control(spec, ALC_CTL_BIND_MUTE, 14093 err = alc861_create_out_sw(codec, "LFE", nid, 2);
14243 "LFE Playback Switch",
14244 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
14245 HDA_OUTPUT));
14246 if (err < 0) 14094 if (err < 0)
14247 return err; 14095 return err;
14248 } else { 14096 } else {
14249 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; 14097 err = alc861_create_out_sw(codec, chname[i], nid, 3);
14250 idx++)
14251 if (nid == alc861_dac_nids[idx])
14252 break;
14253 sprintf(name, "%s Playback Switch", chname[idx]);
14254 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14255 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
14256 HDA_OUTPUT));
14257 if (err < 0) 14098 if (err < 0)
14258 return err; 14099 return err;
14259 } 14100 }
@@ -14261,8 +14102,9 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
14261 return 0; 14102 return 0;
14262} 14103}
14263 14104
14264static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) 14105static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
14265{ 14106{
14107 struct alc_spec *spec = codec->spec;
14266 int err; 14108 int err;
14267 hda_nid_t nid; 14109 hda_nid_t nid;
14268 14110
@@ -14270,21 +14112,22 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
14270 return 0; 14112 return 0;
14271 14113
14272 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 14114 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
14273 nid = 0x03; 14115 nid = alc861_look_for_dac(codec, pin);
14274 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 14116 if (nid) {
14275 "Headphone Playback Switch", 14117 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
14276 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 14118 if (err < 0)
14277 if (err < 0) 14119 return err;
14278 return err; 14120 spec->multiout.hp_nid = nid;
14279 spec->multiout.hp_nid = nid; 14121 }
14280 } 14122 }
14281 return 0; 14123 return 0;
14282} 14124}
14283 14125
14284/* create playback/capture controls for input pins */ 14126/* create playback/capture controls for input pins */
14285static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, 14127static int alc861_auto_create_analog_input_ctls(struct hda_codec *codec,
14286 const struct auto_pin_cfg *cfg) 14128 const struct auto_pin_cfg *cfg)
14287{ 14129{
14130 struct alc_spec *spec = codec->spec;
14288 struct hda_input_mux *imux = &spec->private_imux[0]; 14131 struct hda_input_mux *imux = &spec->private_imux[0];
14289 int i, err, idx, idx1; 14132 int i, err, idx, idx1;
14290 14133
@@ -14328,12 +14171,29 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
14328 14171
14329static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 14172static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14330 hda_nid_t nid, 14173 hda_nid_t nid,
14331 int pin_type, int dac_idx) 14174 int pin_type, hda_nid_t dac)
14332{ 14175{
14176 hda_nid_t mix, srcs[5];
14177 int i, num;
14178
14333 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 14179 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14334 pin_type); 14180 pin_type);
14335 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, 14181 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14336 AMP_OUT_UNMUTE); 14182 AMP_OUT_UNMUTE);
14183 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
14184 return;
14185 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14186 if (num < 0)
14187 return;
14188 for (i = 0; i < num; i++) {
14189 unsigned int mute;
14190 if (srcs[i] == dac || srcs[i] == 0x15)
14191 mute = AMP_IN_UNMUTE(i);
14192 else
14193 mute = AMP_IN_MUTE(i);
14194 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14195 mute);
14196 }
14337} 14197}
14338 14198
14339static void alc861_auto_init_multi_out(struct hda_codec *codec) 14199static void alc861_auto_init_multi_out(struct hda_codec *codec)
@@ -14356,12 +14216,13 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec)
14356 hda_nid_t pin; 14216 hda_nid_t pin;
14357 14217
14358 pin = spec->autocfg.hp_pins[0]; 14218 pin = spec->autocfg.hp_pins[0];
14359 if (pin) /* connect to front */ 14219 if (pin)
14360 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, 14220 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
14361 spec->multiout.dac_nids[0]); 14221 spec->multiout.hp_nid);
14362 pin = spec->autocfg.speaker_pins[0]; 14222 pin = spec->autocfg.speaker_pins[0];
14363 if (pin) 14223 if (pin)
14364 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 14224 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT,
14225 spec->multiout.dac_nids[0]);
14365} 14226}
14366 14227
14367static void alc861_auto_init_analog_input(struct hda_codec *codec) 14228static void alc861_auto_init_analog_input(struct hda_codec *codec)
@@ -14393,16 +14254,16 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
14393 if (!spec->autocfg.line_outs) 14254 if (!spec->autocfg.line_outs)
14394 return 0; /* can't find valid BIOS pin config */ 14255 return 0; /* can't find valid BIOS pin config */
14395 14256
14396 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); 14257 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
14397 if (err < 0) 14258 if (err < 0)
14398 return err; 14259 return err;
14399 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); 14260 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
14400 if (err < 0) 14261 if (err < 0)
14401 return err; 14262 return err;
14402 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 14263 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
14403 if (err < 0) 14264 if (err < 0)
14404 return err; 14265 return err;
14405 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); 14266 err = alc861_auto_create_analog_input_ctls(codec, &spec->autocfg);
14406 if (err < 0) 14267 if (err < 0)
14407 return err; 14268 return err;
14408 14269
@@ -14614,8 +14475,8 @@ static int patch_alc861(struct hda_codec *codec)
14614 alc861_cfg_tbl); 14475 alc861_cfg_tbl);
14615 14476
14616 if (board_config < 0) { 14477 if (board_config < 0) {
14617 printk(KERN_INFO "hda_codec: Unknown model for %s, " 14478 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14618 "trying auto-probe from BIOS...\n", codec->chip_name); 14479 codec->chip_name);
14619 board_config = ALC861_AUTO; 14480 board_config = ALC861_AUTO;
14620 } 14481 }
14621 14482
@@ -15538,8 +15399,8 @@ static int patch_alc861vd(struct hda_codec *codec)
15538 alc861vd_cfg_tbl); 15399 alc861vd_cfg_tbl);
15539 15400
15540 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 15401 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15541 printk(KERN_INFO "hda_codec: Unknown model for %s, " 15402 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15542 "trying auto-probe from BIOS...\n", codec->chip_name); 15403 codec->chip_name);
15543 board_config = ALC861VD_AUTO; 15404 board_config = ALC861VD_AUTO;
15544 } 15405 }
15545 15406
@@ -17462,8 +17323,8 @@ static int patch_alc662(struct hda_codec *codec)
17462 alc662_models, 17323 alc662_models,
17463 alc662_cfg_tbl); 17324 alc662_cfg_tbl);
17464 if (board_config < 0) { 17325 if (board_config < 0) {
17465 printk(KERN_INFO "hda_codec: Unknown model for %s, " 17326 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17466 "trying auto-probe from BIOS...\n", codec->chip_name); 17327 codec->chip_name);
17467 board_config = ALC662_AUTO; 17328 board_config = ALC662_AUTO;
17468 } 17329 }
17469 17330
@@ -17537,23 +17398,23 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
17537 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 17398 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17538 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 17399 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17539 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 17400 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17540 .patch = patch_alc883 }, 17401 .patch = patch_alc882 },
17541 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 17402 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17542 .patch = patch_alc662 }, 17403 .patch = patch_alc662 },
17543 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 17404 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17544 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 17405 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17545 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 17406 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17546 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 17407 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
17547 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 17408 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17548 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 17409 .patch = patch_alc882 },
17549 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 17410 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17550 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 17411 .patch = patch_alc882 },
17551 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 17412 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17552 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 }, 17413 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
17553 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 17414 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17554 .patch = patch_alc883 }, 17415 .patch = patch_alc882 },
17555 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 17416 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
17556 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, 17417 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
17557 {} /* terminator */ 17418 {} /* terminator */
17558}; 17419};
17559 17420
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 5383d8cff88b..e5fbec37ffdd 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -40,6 +40,8 @@ enum {
40 STAC_INSERT_EVENT, 40 STAC_INSERT_EVENT,
41 STAC_PWR_EVENT, 41 STAC_PWR_EVENT,
42 STAC_HP_EVENT, 42 STAC_HP_EVENT,
43 STAC_LO_EVENT,
44 STAC_MIC_EVENT,
43}; 45};
44 46
45enum { 47enum {
@@ -176,6 +178,12 @@ struct sigmatel_jack {
176 struct snd_jack *jack; 178 struct snd_jack *jack;
177}; 179};
178 180
181struct sigmatel_mic_route {
182 hda_nid_t pin;
183 unsigned char mux_idx;
184 unsigned char dmux_idx;
185};
186
179struct sigmatel_spec { 187struct sigmatel_spec {
180 struct snd_kcontrol_new *mixers[4]; 188 struct snd_kcontrol_new *mixers[4];
181 unsigned int num_mixers; 189 unsigned int num_mixers;
@@ -187,6 +195,7 @@ struct sigmatel_spec {
187 unsigned int hp_detect: 1; 195 unsigned int hp_detect: 1;
188 unsigned int spdif_mute: 1; 196 unsigned int spdif_mute: 1;
189 unsigned int check_volume_offset:1; 197 unsigned int check_volume_offset:1;
198 unsigned int auto_mic:1;
190 199
191 /* gpio lines */ 200 /* gpio lines */
192 unsigned int eapd_mask; 201 unsigned int eapd_mask;
@@ -238,6 +247,14 @@ struct sigmatel_spec {
238 unsigned int num_dmuxes; 247 unsigned int num_dmuxes;
239 hda_nid_t *smux_nids; 248 hda_nid_t *smux_nids;
240 unsigned int num_smuxes; 249 unsigned int num_smuxes;
250
251 unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */
252 unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */
253 unsigned int num_caps; /* number of capture volume/switch elements */
254
255 struct sigmatel_mic_route ext_mic;
256 struct sigmatel_mic_route int_mic;
257
241 const char **spdif_labels; 258 const char **spdif_labels;
242 259
243 hda_nid_t dig_in_nid; 260 hda_nid_t dig_in_nid;
@@ -334,6 +351,13 @@ static hda_nid_t stac92hd73xx_smux_nids[2] = {
334 0x22, 0x23, 351 0x22, 0x23,
335}; 352};
336 353
354#define STAC92HD73XX_NUM_CAPS 2
355static unsigned long stac92hd73xx_capvols[] = {
356 HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT),
357 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
358};
359#define stac92hd73xx_capsws stac92hd73xx_capvols
360
337#define STAC92HD83XXX_NUM_DMICS 2 361#define STAC92HD83XXX_NUM_DMICS 2
338static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { 362static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
339 0x11, 0x12, 0 363 0x11, 0x12, 0
@@ -365,6 +389,13 @@ static hda_nid_t stac92hd83xxx_amp_nids[1] = {
365 0xc, 389 0xc,
366}; 390};
367 391
392#define STAC92HD83XXX_NUM_CAPS 2
393static unsigned long stac92hd83xxx_capvols[] = {
394 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
395 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_OUTPUT),
396};
397#define stac92hd83xxx_capsws stac92hd83xxx_capvols
398
368static hda_nid_t stac92hd71bxx_pwr_nids[3] = { 399static hda_nid_t stac92hd71bxx_pwr_nids[3] = {
369 0x0a, 0x0d, 0x0f 400 0x0a, 0x0d, 0x0f
370}; 401};
@@ -394,6 +425,13 @@ static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = {
394 0x22, 0 425 0x22, 0
395}; 426};
396 427
428#define STAC92HD71BXX_NUM_CAPS 2
429static unsigned long stac92hd71bxx_capvols[] = {
430 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
431 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
432};
433#define stac92hd71bxx_capsws stac92hd71bxx_capvols
434
397static hda_nid_t stac925x_adc_nids[1] = { 435static hda_nid_t stac925x_adc_nids[1] = {
398 0x03, 436 0x03,
399}; 437};
@@ -415,6 +453,13 @@ static hda_nid_t stac925x_dmux_nids[1] = {
415 0x14, 453 0x14,
416}; 454};
417 455
456static unsigned long stac925x_capvols[] = {
457 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
458};
459static unsigned long stac925x_capsws[] = {
460 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
461};
462
418static hda_nid_t stac922x_adc_nids[2] = { 463static hda_nid_t stac922x_adc_nids[2] = {
419 0x06, 0x07, 464 0x06, 0x07,
420}; 465};
@@ -423,6 +468,13 @@ static hda_nid_t stac922x_mux_nids[2] = {
423 0x12, 0x13, 468 0x12, 0x13,
424}; 469};
425 470
471#define STAC922X_NUM_CAPS 2
472static unsigned long stac922x_capvols[] = {
473 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT),
474 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
475};
476#define stac922x_capsws stac922x_capvols
477
426static hda_nid_t stac927x_slave_dig_outs[2] = { 478static hda_nid_t stac927x_slave_dig_outs[2] = {
427 0x1f, 0, 479 0x1f, 0,
428}; 480};
@@ -452,6 +504,18 @@ static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
452 0x13, 0x14, 0 504 0x13, 0x14, 0
453}; 505};
454 506
507#define STAC927X_NUM_CAPS 3
508static unsigned long stac927x_capvols[] = {
509 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
510 HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT),
511 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT),
512};
513static unsigned long stac927x_capsws[] = {
514 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
515 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
516 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
517};
518
455static const char *stac927x_spdif_labels[5] = { 519static const char *stac927x_spdif_labels[5] = {
456 "Digital Playback", "ADAT", "Analog Mux 1", 520 "Digital Playback", "ADAT", "Analog Mux 1",
457 "Analog Mux 2", "Analog Mux 3" 521 "Analog Mux 2", "Analog Mux 3"
@@ -478,6 +542,16 @@ static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
478 0x17, 0x18, 0 542 0x17, 0x18, 0
479}; 543};
480 544
545#define STAC9205_NUM_CAPS 2
546static unsigned long stac9205_capvols[] = {
547 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT),
548 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT),
549};
550static unsigned long stac9205_capsws[] = {
551 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
552 HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT),
553};
554
481static hda_nid_t stac9200_pin_nids[8] = { 555static hda_nid_t stac9200_pin_nids[8] = {
482 0x08, 0x09, 0x0d, 0x0e, 556 0x08, 0x09, 0x0d, 0x0e,
483 0x0f, 0x10, 0x11, 0x12, 557 0x0f, 0x10, 0x11, 0x12,
@@ -924,19 +998,6 @@ static struct hda_verb stac92hd71bxx_core_init[] = {
924 {} 998 {}
925}; 999};
926 1000
927#define HD_DISABLE_PORTF 1
928static struct hda_verb stac92hd71bxx_analog_core_init[] = {
929 /* start of config #1 */
930
931 /* connect port 0f to audio mixer */
932 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
933 /* start of config #2 */
934
935 /* set master volume and direct control */
936 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
937 {}
938};
939
940static struct hda_verb stac92hd71bxx_unmute_core_init[] = { 1001static struct hda_verb stac92hd71bxx_unmute_core_init[] = {
941 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ 1002 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
942 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1003 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -1069,12 +1130,6 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
1069 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), 1130 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
1070 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), 1131 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
1071 1132
1072 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
1073 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
1074
1075 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
1076 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
1077
1078 { } /* end */ 1133 { } /* end */
1079}; 1134};
1080 1135
@@ -1094,12 +1149,6 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = {
1094}; 1149};
1095 1150
1096static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { 1151static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = {
1097 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
1098 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
1099
1100 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
1101 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
1102
1103 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), 1152 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
1104 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), 1153 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
1105 1154
@@ -1118,12 +1167,6 @@ static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = {
1118}; 1167};
1119 1168
1120static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { 1169static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
1121 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
1122 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
1123
1124 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
1125 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
1126
1127 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), 1170 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
1128 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), 1171 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
1129 1172
@@ -1143,12 +1186,6 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
1143 1186
1144 1187
1145static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { 1188static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
1146 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT),
1147 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT),
1148
1149 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT),
1150 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT),
1151
1152 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT), 1189 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT),
1153 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT), 1190 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT),
1154 1191
@@ -1169,17 +1206,6 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
1169}; 1206};
1170 1207
1171static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { 1208static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
1172 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
1173 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
1174
1175 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
1176 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
1177 /* analog pc-beep replaced with digital beep support */
1178 /*
1179 HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT),
1180 HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT),
1181 */
1182
1183 HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT), 1209 HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT),
1184 HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT), 1210 HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT),
1185 1211
@@ -1198,29 +1224,9 @@ static struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
1198 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) 1224 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2)
1199}; 1225};
1200 1226
1201static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
1202 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
1203 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
1204
1205 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
1206 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
1207 { } /* end */
1208};
1209
1210static struct snd_kcontrol_new stac925x_mixer[] = { 1227static struct snd_kcontrol_new stac925x_mixer[] = {
1211 HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), 1228 HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT),
1212 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), 1229 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT),
1213 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
1214 HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT),
1215 { } /* end */
1216};
1217
1218static struct snd_kcontrol_new stac9205_mixer[] = {
1219 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
1220 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
1221
1222 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
1223 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
1224 { } /* end */ 1230 { } /* end */
1225}; 1231};
1226 1232
@@ -1229,29 +1235,6 @@ static struct snd_kcontrol_new stac9205_loopback[] = {
1229 {} 1235 {}
1230}; 1236};
1231 1237
1232/* This needs to be generated dynamically based on sequence */
1233static struct snd_kcontrol_new stac922x_mixer[] = {
1234 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
1235 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
1236
1237 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
1238 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
1239 { } /* end */
1240};
1241
1242
1243static struct snd_kcontrol_new stac927x_mixer[] = {
1244 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
1245 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
1246
1247 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
1248 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
1249
1250 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
1251 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
1252 { } /* end */
1253};
1254
1255static struct snd_kcontrol_new stac927x_loopback[] = { 1238static struct snd_kcontrol_new stac927x_loopback[] = {
1256 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), 1239 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
1257 {} 1240 {}
@@ -1309,16 +1292,18 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1309 int err; 1292 int err;
1310 int i; 1293 int i;
1311 1294
1312 err = snd_hda_add_new_ctls(codec, spec->mixer); 1295 if (spec->mixer) {
1313 if (err < 0) 1296 err = snd_hda_add_new_ctls(codec, spec->mixer);
1314 return err; 1297 if (err < 0)
1298 return err;
1299 }
1315 1300
1316 for (i = 0; i < spec->num_mixers; i++) { 1301 for (i = 0; i < spec->num_mixers; i++) {
1317 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1302 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1318 if (err < 0) 1303 if (err < 0)
1319 return err; 1304 return err;
1320 } 1305 }
1321 if (spec->num_dmuxes > 0) { 1306 if (!spec->auto_mic && spec->num_dmuxes > 0) {
1322 stac_dmux_mixer.count = spec->num_dmuxes; 1307 stac_dmux_mixer.count = spec->num_dmuxes;
1323 err = snd_hda_ctl_add(codec, 1308 err = snd_hda_ctl_add(codec,
1324 snd_ctl_new1(&stac_dmux_mixer, codec)); 1309 snd_ctl_new1(&stac_dmux_mixer, codec));
@@ -2636,8 +2621,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
2636 return 0; 2621 return 0;
2637} 2622}
2638 2623
2639static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, 2624static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid);
2640 unsigned char type);
2641 2625
2642static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, 2626static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2643 struct snd_ctl_elem_value *ucontrol) 2627 struct snd_ctl_elem_value *ucontrol)
@@ -2651,7 +2635,7 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2651 /* check to be sure that the ports are upto date with 2635 /* check to be sure that the ports are upto date with
2652 * switch changes 2636 * switch changes
2653 */ 2637 */
2654 stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); 2638 stac_issue_unsol_event(codec, nid);
2655 2639
2656 return 1; 2640 return 1;
2657} 2641}
@@ -2784,7 +2768,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
2784 * appropriately according to the pin direction 2768 * appropriately according to the pin direction
2785 */ 2769 */
2786 if (spec->hp_detect) 2770 if (spec->hp_detect)
2787 stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); 2771 stac_issue_unsol_event(codec, nid);
2788 2772
2789 return 1; 2773 return 1;
2790} 2774}
@@ -2967,6 +2951,8 @@ static int stac92xx_add_input_source(struct sigmatel_spec *spec)
2967 struct snd_kcontrol_new *knew; 2951 struct snd_kcontrol_new *knew;
2968 struct hda_input_mux *imux = &spec->private_imux; 2952 struct hda_input_mux *imux = &spec->private_imux;
2969 2953
2954 if (spec->auto_mic)
2955 return 0; /* no need for input source */
2970 if (!spec->num_adcs || imux->num_items <= 1) 2956 if (!spec->num_adcs || imux->num_items <= 1)
2971 return 0; /* no need for input source control */ 2957 return 0; /* no need for input source control */
2972 knew = stac_control_new(spec, &stac_input_src_temp, 2958 knew = stac_control_new(spec, &stac_input_src_temp,
@@ -3060,7 +3046,7 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
3060 HDA_MAX_CONNECTIONS); 3046 HDA_MAX_CONNECTIONS);
3061 for (j = 0; j < conn_len; j++) { 3047 for (j = 0; j < conn_len; j++) {
3062 wcaps = get_wcaps(codec, conn[j]); 3048 wcaps = get_wcaps(codec, conn[j]);
3063 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 3049 wtype = get_wcaps_type(wcaps);
3064 /* we check only analog outputs */ 3050 /* we check only analog outputs */
3065 if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) 3051 if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
3066 continue; 3052 continue;
@@ -3319,6 +3305,21 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
3319 return 0; 3305 return 0;
3320} 3306}
3321 3307
3308static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol,
3309 unsigned long sw, int idx)
3310{
3311 int err;
3312 err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx,
3313 "Capture Volume", vol);
3314 if (err < 0)
3315 return err;
3316 err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_MUTE, idx,
3317 "Capture Switch", sw);
3318 if (err < 0)
3319 return err;
3320 return 0;
3321}
3322
3322/* add playback controls from the parsed DAC table */ 3323/* add playback controls from the parsed DAC table */
3323static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, 3324static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
3324 const struct auto_pin_cfg *cfg) 3325 const struct auto_pin_cfg *cfg)
@@ -3392,7 +3393,7 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
3392 spec->mono_nid, 3393 spec->mono_nid,
3393 con_lst, 3394 con_lst,
3394 HDA_MAX_NUM_INPUTS); 3395 HDA_MAX_NUM_INPUTS);
3395 if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) 3396 if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels))
3396 return -EINVAL; 3397 return -EINVAL;
3397 3398
3398 for (i = 0; i < num_cons; i++) { 3399 for (i = 0; i < num_cons; i++) {
@@ -3538,7 +3539,7 @@ static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
3538 spec->smux_nids[0], 3539 spec->smux_nids[0],
3539 con_lst, 3540 con_lst,
3540 HDA_MAX_NUM_INPUTS); 3541 HDA_MAX_NUM_INPUTS);
3541 if (!num_cons) 3542 if (num_cons <= 0)
3542 return -EINVAL; 3543 return -EINVAL;
3543 3544
3544 if (!labels) 3545 if (!labels)
@@ -3559,14 +3560,26 @@ static const char *stac92xx_dmic_labels[5] = {
3559 "Digital Mic 3", "Digital Mic 4" 3560 "Digital Mic 3", "Digital Mic 4"
3560}; 3561};
3561 3562
3563static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3564 hda_nid_t nid)
3565{
3566 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3567 int i, nums;
3568
3569 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3570 for (i = 0; i < nums; i++)
3571 if (conn[i] == nid)
3572 return i;
3573 return -1;
3574}
3575
3562/* create playback/capture controls for input pins on dmic capable codecs */ 3576/* create playback/capture controls for input pins on dmic capable codecs */
3563static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, 3577static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3564 const struct auto_pin_cfg *cfg) 3578 const struct auto_pin_cfg *cfg)
3565{ 3579{
3566 struct sigmatel_spec *spec = codec->spec; 3580 struct sigmatel_spec *spec = codec->spec;
3567 struct hda_input_mux *dimux = &spec->private_dimux; 3581 struct hda_input_mux *dimux = &spec->private_dimux;
3568 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; 3582 int err, i;
3569 int err, i, j;
3570 char name[32]; 3583 char name[32];
3571 3584
3572 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; 3585 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
@@ -3576,7 +3589,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3576 for (i = 0; i < spec->num_dmics; i++) { 3589 for (i = 0; i < spec->num_dmics; i++) {
3577 hda_nid_t nid; 3590 hda_nid_t nid;
3578 int index; 3591 int index;
3579 int num_cons;
3580 unsigned int wcaps; 3592 unsigned int wcaps;
3581 unsigned int def_conf; 3593 unsigned int def_conf;
3582 3594
@@ -3585,17 +3597,10 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3585 continue; 3597 continue;
3586 3598
3587 nid = spec->dmic_nids[i]; 3599 nid = spec->dmic_nids[i];
3588 num_cons = snd_hda_get_connections(codec, 3600 index = get_connection_index(codec, spec->dmux_nids[0], nid);
3589 spec->dmux_nids[0], 3601 if (index < 0)
3590 con_lst, 3602 continue;
3591 HDA_MAX_NUM_INPUTS); 3603
3592 for (j = 0; j < num_cons; j++)
3593 if (con_lst[j] == nid) {
3594 index = j;
3595 goto found;
3596 }
3597 continue;
3598found:
3599 wcaps = get_wcaps(codec, nid) & 3604 wcaps = get_wcaps(codec, nid) &
3600 (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); 3605 (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);
3601 3606
@@ -3622,6 +3627,88 @@ found:
3622 return 0; 3627 return 0;
3623} 3628}
3624 3629
3630static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid,
3631 hda_nid_t *fixed, hda_nid_t *ext)
3632{
3633 unsigned int cfg;
3634
3635 if (!nid)
3636 return 0;
3637 cfg = snd_hda_codec_get_pincfg(codec, nid);
3638 switch (get_defcfg_connect(cfg)) {
3639 case AC_JACK_PORT_FIXED:
3640 if (*fixed)
3641 return 1; /* already occupied */
3642 *fixed = nid;
3643 break;
3644 case AC_JACK_PORT_COMPLEX:
3645 if (*ext)
3646 return 1; /* already occupied */
3647 *ext = nid;
3648 break;
3649 }
3650 return 0;
3651}
3652
3653static int set_mic_route(struct hda_codec *codec,
3654 struct sigmatel_mic_route *mic,
3655 hda_nid_t pin)
3656{
3657 struct sigmatel_spec *spec = codec->spec;
3658 struct auto_pin_cfg *cfg = &spec->autocfg;
3659 int i;
3660
3661 mic->pin = pin;
3662 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++)
3663 if (pin == cfg->input_pins[i])
3664 break;
3665 if (i <= AUTO_PIN_FRONT_MIC) {
3666 /* analog pin */
3667 mic->dmux_idx = 0;
3668 i = get_connection_index(codec, spec->mux_nids[0], pin);
3669 if (i < 0)
3670 return -1;
3671 mic->mux_idx = i;
3672 } else {
3673 /* digital pin */
3674 mic->mux_idx = 0;
3675 i = get_connection_index(codec, spec->dmux_nids[0], pin);
3676 if (i < 0)
3677 return -1;
3678 mic->dmux_idx = i;
3679 }
3680 return 0;
3681}
3682
3683/* return non-zero if the device is for automatic mic switch */
3684static int stac_check_auto_mic(struct hda_codec *codec)
3685{
3686 struct sigmatel_spec *spec = codec->spec;
3687 struct auto_pin_cfg *cfg = &spec->autocfg;
3688 hda_nid_t fixed, ext;
3689 int i;
3690
3691 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) {
3692 if (cfg->input_pins[i])
3693 return 0; /* must be exclusively mics */
3694 }
3695 fixed = ext = 0;
3696 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++)
3697 if (check_mic_pin(codec, cfg->input_pins[i], &fixed, &ext))
3698 return 0;
3699 for (i = 0; i < spec->num_dmics; i++)
3700 if (check_mic_pin(codec, spec->dmic_nids[i], &fixed, &ext))
3701 return 0;
3702 if (!fixed || !ext)
3703 return 0;
3704 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
3705 return 0; /* no unsol support */
3706 if (set_mic_route(codec, &spec->ext_mic, ext) ||
3707 set_mic_route(codec, &spec->int_mic, fixed))
3708 return 0; /* something is wrong */
3709 return 1;
3710}
3711
3625/* create playback/capture controls for input pins */ 3712/* create playback/capture controls for input pins */
3626static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) 3713static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
3627{ 3714{
@@ -3705,7 +3792,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3705{ 3792{
3706 struct sigmatel_spec *spec = codec->spec; 3793 struct sigmatel_spec *spec = codec->spec;
3707 int hp_swap = 0; 3794 int hp_swap = 0;
3708 int err; 3795 int i, err;
3709 3796
3710 if ((err = snd_hda_parse_pin_def_config(codec, 3797 if ((err = snd_hda_parse_pin_def_config(codec,
3711 &spec->autocfg, 3798 &spec->autocfg,
@@ -3745,11 +3832,10 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3745 if (snd_hda_get_connections(codec, 3832 if (snd_hda_get_connections(codec,
3746 spec->autocfg.mono_out_pin, conn_list, 1) && 3833 spec->autocfg.mono_out_pin, conn_list, 1) &&
3747 snd_hda_get_connections(codec, conn_list[0], 3834 snd_hda_get_connections(codec, conn_list[0],
3748 conn_list, 1)) { 3835 conn_list, 1) > 0) {
3749 3836
3750 int wcaps = get_wcaps(codec, conn_list[0]); 3837 int wcaps = get_wcaps(codec, conn_list[0]);
3751 int wid_type = (wcaps & AC_WCAP_TYPE) 3838 int wid_type = get_wcaps_type(wcaps);
3752 >> AC_WCAP_TYPE_SHIFT;
3753 /* LR swap check, some stac925x have a mux that 3839 /* LR swap check, some stac925x have a mux that
3754 * changes the DACs output path instead of the 3840 * changes the DACs output path instead of the
3755 * mono-mux path. 3841 * mono-mux path.
@@ -3840,6 +3926,21 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3840 spec->autocfg.line_outs = 0; 3926 spec->autocfg.line_outs = 0;
3841 } 3927 }
3842 3928
3929 if (stac_check_auto_mic(codec)) {
3930 spec->auto_mic = 1;
3931 /* only one capture for auto-mic */
3932 spec->num_adcs = 1;
3933 spec->num_caps = 1;
3934 spec->num_muxes = 1;
3935 }
3936
3937 for (i = 0; i < spec->num_caps; i++) {
3938 err = stac92xx_add_capvol_ctls(codec, spec->capvols[i],
3939 spec->capsws[i], i);
3940 if (err < 0)
3941 return err;
3942 }
3943
3843 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); 3944 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
3844 if (err < 0) 3945 if (err < 0)
3845 return err; 3946 return err;
@@ -4102,14 +4203,14 @@ static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
4102} 4203}
4103 4204
4104static struct sigmatel_event *stac_get_event(struct hda_codec *codec, 4205static struct sigmatel_event *stac_get_event(struct hda_codec *codec,
4105 hda_nid_t nid, unsigned char type) 4206 hda_nid_t nid)
4106{ 4207{
4107 struct sigmatel_spec *spec = codec->spec; 4208 struct sigmatel_spec *spec = codec->spec;
4108 struct sigmatel_event *event = spec->events.list; 4209 struct sigmatel_event *event = spec->events.list;
4109 int i; 4210 int i;
4110 4211
4111 for (i = 0; i < spec->events.used; i++, event++) { 4212 for (i = 0; i < spec->events.used; i++, event++) {
4112 if (event->nid == nid && event->type == type) 4213 if (event->nid == nid)
4113 return event; 4214 return event;
4114 } 4215 }
4115 return NULL; 4216 return NULL;
@@ -4129,24 +4230,32 @@ static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec,
4129 return NULL; 4230 return NULL;
4130} 4231}
4131 4232
4132static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, 4233/* check if given nid is a valid pin and no other events are assigned
4133 unsigned int type) 4234 * to it. If OK, assign the event, set the unsol flag, and returns 1.
4235 * Otherwise, returns zero.
4236 */
4237static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
4238 unsigned int type)
4134{ 4239{
4135 struct sigmatel_event *event; 4240 struct sigmatel_event *event;
4136 int tag; 4241 int tag;
4137 4242
4138 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) 4243 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
4139 return; 4244 return 0;
4140 event = stac_get_event(codec, nid, type); 4245 event = stac_get_event(codec, nid);
4141 if (event) 4246 if (event) {
4247 if (event->type != type)
4248 return 0;
4142 tag = event->tag; 4249 tag = event->tag;
4143 else 4250 } else {
4144 tag = stac_add_event(codec->spec, nid, type, 0); 4251 tag = stac_add_event(codec->spec, nid, type, 0);
4145 if (tag < 0) 4252 if (tag < 0)
4146 return; 4253 return 0;
4254 }
4147 snd_hda_codec_write_cache(codec, nid, 0, 4255 snd_hda_codec_write_cache(codec, nid, 0,
4148 AC_VERB_SET_UNSOLICITED_ENABLE, 4256 AC_VERB_SET_UNSOLICITED_ENABLE,
4149 AC_USRSP_EN | tag); 4257 AC_USRSP_EN | tag);
4258 return 1;
4150} 4259}
4151 4260
4152static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) 4261static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
@@ -4239,20 +4348,34 @@ static int stac92xx_init(struct hda_codec *codec)
4239 hda_nid_t nid = cfg->hp_pins[i]; 4348 hda_nid_t nid = cfg->hp_pins[i];
4240 enable_pin_detect(codec, nid, STAC_HP_EVENT); 4349 enable_pin_detect(codec, nid, STAC_HP_EVENT);
4241 } 4350 }
4351 if (cfg->line_out_type == AUTO_PIN_LINE_OUT) {
4352 /* enable pin-detect for line-outs as well */
4353 for (i = 0; i < cfg->hp_outs; i++) {
4354 hda_nid_t nid = cfg->hp_pins[i];
4355 enable_pin_detect(codec, nid, STAC_LO_EVENT);
4356 }
4357 }
4358
4242 /* force to enable the first line-out; the others are set up 4359 /* force to enable the first line-out; the others are set up
4243 * in unsol_event 4360 * in unsol_event
4244 */ 4361 */
4245 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], 4362 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
4246 AC_PINCTL_OUT_EN); 4363 AC_PINCTL_OUT_EN);
4247 /* fake event to set up pins */ 4364 /* fake event to set up pins */
4248 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], 4365 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
4249 STAC_HP_EVENT);
4250 } else { 4366 } else {
4251 stac92xx_auto_init_multi_out(codec); 4367 stac92xx_auto_init_multi_out(codec);
4252 stac92xx_auto_init_hp_out(codec); 4368 stac92xx_auto_init_hp_out(codec);
4253 for (i = 0; i < cfg->hp_outs; i++) 4369 for (i = 0; i < cfg->hp_outs; i++)
4254 stac_toggle_power_map(codec, cfg->hp_pins[i], 1); 4370 stac_toggle_power_map(codec, cfg->hp_pins[i], 1);
4255 } 4371 }
4372 if (spec->auto_mic) {
4373 /* initialize connection to analog input */
4374 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
4375 AC_VERB_SET_CONNECT_SEL, 0);
4376 if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT))
4377 stac_issue_unsol_event(codec, spec->ext_mic.pin);
4378 }
4256 for (i = 0; i < AUTO_PIN_LAST; i++) { 4379 for (i = 0; i < AUTO_PIN_LAST; i++) {
4257 hda_nid_t nid = cfg->input_pins[i]; 4380 hda_nid_t nid = cfg->input_pins[i];
4258 if (nid) { 4381 if (nid) {
@@ -4279,10 +4402,9 @@ static int stac92xx_init(struct hda_codec *codec)
4279 } 4402 }
4280 conf = snd_hda_codec_get_pincfg(codec, nid); 4403 conf = snd_hda_codec_get_pincfg(codec, nid);
4281 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { 4404 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
4282 enable_pin_detect(codec, nid, 4405 if (enable_pin_detect(codec, nid,
4283 STAC_INSERT_EVENT); 4406 STAC_INSERT_EVENT))
4284 stac_issue_unsol_event(codec, nid, 4407 stac_issue_unsol_event(codec, nid);
4285 STAC_INSERT_EVENT);
4286 } 4408 }
4287 } 4409 }
4288 } 4410 }
@@ -4327,10 +4449,8 @@ static int stac92xx_init(struct hda_codec *codec)
4327 stac_toggle_power_map(codec, nid, 1); 4449 stac_toggle_power_map(codec, nid, 1);
4328 continue; 4450 continue;
4329 } 4451 }
4330 if (!stac_get_event(codec, nid, STAC_INSERT_EVENT)) { 4452 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT))
4331 enable_pin_detect(codec, nid, STAC_PWR_EVENT); 4453 stac_issue_unsol_event(codec, nid);
4332 stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT);
4333 }
4334 } 4454 }
4335 if (spec->dac_list) 4455 if (spec->dac_list)
4336 stac92xx_power_down(codec); 4456 stac92xx_power_down(codec);
@@ -4434,6 +4554,48 @@ static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
4434 return 0; 4554 return 0;
4435} 4555}
4436 4556
4557static void stac92xx_line_out_detect(struct hda_codec *codec,
4558 int presence)
4559{
4560 struct sigmatel_spec *spec = codec->spec;
4561 struct auto_pin_cfg *cfg = &spec->autocfg;
4562 int i;
4563
4564 for (i = 0; i < cfg->line_outs; i++) {
4565 if (presence)
4566 break;
4567 presence = get_pin_presence(codec, cfg->line_out_pins[i]);
4568 if (presence) {
4569 unsigned int pinctl;
4570 pinctl = snd_hda_codec_read(codec,
4571 cfg->line_out_pins[i], 0,
4572 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4573 if (pinctl & AC_PINCTL_IN_EN)
4574 presence = 0; /* mic- or line-input */
4575 }
4576 }
4577
4578 if (presence) {
4579 /* disable speakers */
4580 for (i = 0; i < cfg->speaker_outs; i++)
4581 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
4582 AC_PINCTL_OUT_EN);
4583 if (spec->eapd_mask && spec->eapd_switch)
4584 stac_gpio_set(codec, spec->gpio_mask,
4585 spec->gpio_dir, spec->gpio_data &
4586 ~spec->eapd_mask);
4587 } else {
4588 /* enable speakers */
4589 for (i = 0; i < cfg->speaker_outs; i++)
4590 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
4591 AC_PINCTL_OUT_EN);
4592 if (spec->eapd_mask && spec->eapd_switch)
4593 stac_gpio_set(codec, spec->gpio_mask,
4594 spec->gpio_dir, spec->gpio_data |
4595 spec->eapd_mask);
4596 }
4597}
4598
4437/* return non-zero if the hp-pin of the given array index isn't 4599/* return non-zero if the hp-pin of the given array index isn't
4438 * a jack-detection target 4600 * a jack-detection target
4439 */ 4601 */
@@ -4486,13 +4648,6 @@ static void stac92xx_hp_detect(struct hda_codec *codec)
4486 for (i = 0; i < cfg->line_outs; i++) 4648 for (i = 0; i < cfg->line_outs; i++)
4487 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], 4649 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
4488 AC_PINCTL_OUT_EN); 4650 AC_PINCTL_OUT_EN);
4489 for (i = 0; i < cfg->speaker_outs; i++)
4490 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
4491 AC_PINCTL_OUT_EN);
4492 if (spec->eapd_mask && spec->eapd_switch)
4493 stac_gpio_set(codec, spec->gpio_mask,
4494 spec->gpio_dir, spec->gpio_data &
4495 ~spec->eapd_mask);
4496 } else { 4651 } else {
4497 /* enable lineouts */ 4652 /* enable lineouts */
4498 if (spec->hp_switch) 4653 if (spec->hp_switch)
@@ -4501,14 +4656,8 @@ static void stac92xx_hp_detect(struct hda_codec *codec)
4501 for (i = 0; i < cfg->line_outs; i++) 4656 for (i = 0; i < cfg->line_outs; i++)
4502 stac92xx_set_pinctl(codec, cfg->line_out_pins[i], 4657 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
4503 AC_PINCTL_OUT_EN); 4658 AC_PINCTL_OUT_EN);
4504 for (i = 0; i < cfg->speaker_outs; i++)
4505 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
4506 AC_PINCTL_OUT_EN);
4507 if (spec->eapd_mask && spec->eapd_switch)
4508 stac_gpio_set(codec, spec->gpio_mask,
4509 spec->gpio_dir, spec->gpio_data |
4510 spec->eapd_mask);
4511 } 4659 }
4660 stac92xx_line_out_detect(codec, presence);
4512 /* toggle hp outs */ 4661 /* toggle hp outs */
4513 for (i = 0; i < cfg->hp_outs; i++) { 4662 for (i = 0; i < cfg->hp_outs; i++) {
4514 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; 4663 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
@@ -4593,10 +4742,28 @@ static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
4593 } 4742 }
4594} 4743}
4595 4744
4596static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, 4745static void stac92xx_mic_detect(struct hda_codec *codec)
4597 unsigned char type) 4746{
4747 struct sigmatel_spec *spec = codec->spec;
4748 struct sigmatel_mic_route *mic;
4749
4750 if (get_pin_presence(codec, spec->ext_mic.pin))
4751 mic = &spec->ext_mic;
4752 else
4753 mic = &spec->int_mic;
4754 if (mic->dmux_idx)
4755 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
4756 AC_VERB_SET_CONNECT_SEL,
4757 mic->dmux_idx);
4758 else
4759 snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0,
4760 AC_VERB_SET_CONNECT_SEL,
4761 mic->mux_idx);
4762}
4763
4764static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid)
4598{ 4765{
4599 struct sigmatel_event *event = stac_get_event(codec, nid, type); 4766 struct sigmatel_event *event = stac_get_event(codec, nid);
4600 if (!event) 4767 if (!event)
4601 return; 4768 return;
4602 codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26); 4769 codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26);
@@ -4616,7 +4783,19 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4616 switch (event->type) { 4783 switch (event->type) {
4617 case STAC_HP_EVENT: 4784 case STAC_HP_EVENT:
4618 stac92xx_hp_detect(codec); 4785 stac92xx_hp_detect(codec);
4619 /* fallthru */ 4786 break;
4787 case STAC_LO_EVENT:
4788 stac92xx_line_out_detect(codec, 0);
4789 break;
4790 case STAC_MIC_EVENT:
4791 stac92xx_mic_detect(codec);
4792 break;
4793 }
4794
4795 switch (event->type) {
4796 case STAC_HP_EVENT:
4797 case STAC_LO_EVENT:
4798 case STAC_MIC_EVENT:
4620 case STAC_INSERT_EVENT: 4799 case STAC_INSERT_EVENT:
4621 case STAC_PWR_EVENT: 4800 case STAC_PWR_EVENT:
4622 if (spec->num_pwrs > 0) 4801 if (spec->num_pwrs > 0)
@@ -4707,8 +4886,7 @@ static int stac92xx_resume(struct hda_codec *codec)
4707 snd_hda_codec_resume_cache(codec); 4886 snd_hda_codec_resume_cache(codec);
4708 /* fake event to set up pins again to override cached values */ 4887 /* fake event to set up pins again to override cached values */
4709 if (spec->hp_detect) 4888 if (spec->hp_detect)
4710 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], 4889 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
4711 STAC_HP_EVENT);
4712 return 0; 4890 return 0;
4713} 4891}
4714 4892
@@ -4748,6 +4926,19 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4748static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 4926static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
4749{ 4927{
4750 struct sigmatel_spec *spec = codec->spec; 4928 struct sigmatel_spec *spec = codec->spec;
4929 int i;
4930 hda_nid_t nid;
4931
4932 /* reset each pin before powering down DAC/ADC to avoid click noise */
4933 nid = codec->start_nid;
4934 for (i = 0; i < codec->num_nodes; i++, nid++) {
4935 unsigned int wcaps = get_wcaps(codec, nid);
4936 unsigned int wid_type = get_wcaps_type(wcaps);
4937 if (wid_type == AC_WID_PIN)
4938 snd_hda_codec_read(codec, nid, 0,
4939 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
4940 }
4941
4751 if (spec->eapd_mask) 4942 if (spec->eapd_mask)
4752 stac_gpio_set(codec, spec->gpio_mask, 4943 stac_gpio_set(codec, spec->gpio_mask,
4753 spec->gpio_dir, spec->gpio_data & 4944 spec->gpio_dir, spec->gpio_data &
@@ -4784,7 +4975,8 @@ static int patch_stac9200(struct hda_codec *codec)
4784 stac9200_models, 4975 stac9200_models,
4785 stac9200_cfg_tbl); 4976 stac9200_cfg_tbl);
4786 if (spec->board_config < 0) 4977 if (spec->board_config < 0)
4787 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); 4978 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4979 codec->chip_name);
4788 else 4980 else
4789 stac92xx_set_config_regs(codec, 4981 stac92xx_set_config_regs(codec,
4790 stac9200_brd_tbl[spec->board_config]); 4982 stac9200_brd_tbl[spec->board_config]);
@@ -4856,8 +5048,8 @@ static int patch_stac925x(struct hda_codec *codec)
4856 stac925x_cfg_tbl); 5048 stac925x_cfg_tbl);
4857 again: 5049 again:
4858 if (spec->board_config < 0) 5050 if (spec->board_config < 0)
4859 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," 5051 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4860 "using BIOS defaults\n"); 5052 codec->chip_name);
4861 else 5053 else
4862 stac92xx_set_config_regs(codec, 5054 stac92xx_set_config_regs(codec,
4863 stac925x_brd_tbl[spec->board_config]); 5055 stac925x_brd_tbl[spec->board_config]);
@@ -4887,6 +5079,9 @@ static int patch_stac925x(struct hda_codec *codec)
4887 5079
4888 spec->init = stac925x_core_init; 5080 spec->init = stac925x_core_init;
4889 spec->mixer = stac925x_mixer; 5081 spec->mixer = stac925x_mixer;
5082 spec->num_caps = 1;
5083 spec->capvols = stac925x_capvols;
5084 spec->capsws = stac925x_capsws;
4890 5085
4891 err = stac92xx_parse_auto_config(codec, 0x8, 0x7); 5086 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
4892 if (!err) { 5087 if (!err) {
@@ -4939,8 +5134,8 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
4939 stac92hd73xx_cfg_tbl); 5134 stac92hd73xx_cfg_tbl);
4940again: 5135again:
4941 if (spec->board_config < 0) 5136 if (spec->board_config < 0)
4942 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 5137 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4943 " STAC92HD73XX, using BIOS defaults\n"); 5138 codec->chip_name);
4944 else 5139 else
4945 stac92xx_set_config_regs(codec, 5140 stac92xx_set_config_regs(codec,
4946 stac92hd73xx_brd_tbl[spec->board_config]); 5141 stac92hd73xx_brd_tbl[spec->board_config]);
@@ -4990,6 +5185,10 @@ again:
4990 memcpy(&spec->private_dimux, &stac92hd73xx_dmux, 5185 memcpy(&spec->private_dimux, &stac92hd73xx_dmux,
4991 sizeof(stac92hd73xx_dmux)); 5186 sizeof(stac92hd73xx_dmux));
4992 5187
5188 spec->num_caps = STAC92HD73XX_NUM_CAPS;
5189 spec->capvols = stac92hd73xx_capvols;
5190 spec->capsws = stac92hd73xx_capsws;
5191
4993 switch (spec->board_config) { 5192 switch (spec->board_config) {
4994 case STAC_DELL_EQ: 5193 case STAC_DELL_EQ:
4995 spec->init = dell_eq_core_init; 5194 spec->init = dell_eq_core_init;
@@ -5109,14 +5308,18 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5109 spec->num_dmics = STAC92HD83XXX_NUM_DMICS; 5308 spec->num_dmics = STAC92HD83XXX_NUM_DMICS;
5110 spec->dinput_mux = &stac92hd83xxx_dmux; 5309 spec->dinput_mux = &stac92hd83xxx_dmux;
5111 spec->pin_nids = stac92hd83xxx_pin_nids; 5310 spec->pin_nids = stac92hd83xxx_pin_nids;
5311 spec->num_caps = STAC92HD83XXX_NUM_CAPS;
5312 spec->capvols = stac92hd83xxx_capvols;
5313 spec->capsws = stac92hd83xxx_capsws;
5314
5112 spec->board_config = snd_hda_check_board_config(codec, 5315 spec->board_config = snd_hda_check_board_config(codec,
5113 STAC_92HD83XXX_MODELS, 5316 STAC_92HD83XXX_MODELS,
5114 stac92hd83xxx_models, 5317 stac92hd83xxx_models,
5115 stac92hd83xxx_cfg_tbl); 5318 stac92hd83xxx_cfg_tbl);
5116again: 5319again:
5117 if (spec->board_config < 0) 5320 if (spec->board_config < 0)
5118 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 5321 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5119 " STAC92HD83XXX, using BIOS defaults\n"); 5322 codec->chip_name);
5120 else 5323 else
5121 stac92xx_set_config_regs(codec, 5324 stac92xx_set_config_regs(codec,
5122 stac92hd83xxx_brd_tbl[spec->board_config]); 5325 stac92hd83xxx_brd_tbl[spec->board_config]);
@@ -5158,6 +5361,8 @@ again:
5158 5361
5159 num_dacs = snd_hda_get_connections(codec, nid, 5362 num_dacs = snd_hda_get_connections(codec, nid,
5160 conn, STAC92HD83_DAC_COUNT + 1) - 1; 5363 conn, STAC92HD83_DAC_COUNT + 1) - 1;
5364 if (num_dacs < 0)
5365 num_dacs = STAC92HD83_DAC_COUNT;
5161 5366
5162 /* set port X to select the last DAC 5367 /* set port X to select the last DAC
5163 */ 5368 */
@@ -5279,8 +5484,8 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
5279 stac92hd71bxx_cfg_tbl); 5484 stac92hd71bxx_cfg_tbl);
5280again: 5485again:
5281 if (spec->board_config < 0) 5486 if (spec->board_config < 0)
5282 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 5487 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5283 " STAC92HD71BXX, using BIOS defaults\n"); 5488 codec->chip_name);
5284 else 5489 else
5285 stac92xx_set_config_regs(codec, 5490 stac92xx_set_config_regs(codec,
5286 stac92hd71bxx_brd_tbl[spec->board_config]); 5491 stac92hd71bxx_brd_tbl[spec->board_config]);
@@ -5295,6 +5500,10 @@ again:
5295 spec->dmic_nids = stac92hd71bxx_dmic_nids; 5500 spec->dmic_nids = stac92hd71bxx_dmic_nids;
5296 spec->dmux_nids = stac92hd71bxx_dmux_nids; 5501 spec->dmux_nids = stac92hd71bxx_dmux_nids;
5297 5502
5503 spec->num_caps = STAC92HD71BXX_NUM_CAPS;
5504 spec->capvols = stac92hd71bxx_capvols;
5505 spec->capsws = stac92hd71bxx_capsws;
5506
5298 switch (codec->vendor_id) { 5507 switch (codec->vendor_id) {
5299 case 0x111d76b6: /* 4 Port without Analog Mixer */ 5508 case 0x111d76b6: /* 4 Port without Analog Mixer */
5300 case 0x111d76b7: 5509 case 0x111d76b7:
@@ -5304,7 +5513,6 @@ again:
5304 case 0x111d76b5: 5513 case 0x111d76b5:
5305 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_nomixer, 5514 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_nomixer,
5306 sizeof(stac92hd71bxx_dmux_nomixer)); 5515 sizeof(stac92hd71bxx_dmux_nomixer));
5307 spec->mixer = stac92hd71bxx_mixer;
5308 spec->init = stac92hd71bxx_core_init; 5516 spec->init = stac92hd71bxx_core_init;
5309 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 5517 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
5310 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5518 spec->num_dmics = stac92hd71bxx_connected_ports(codec,
@@ -5317,8 +5525,6 @@ again:
5317 } 5525 }
5318 break; 5526 break;
5319 case 0x111d7608: /* 5 Port with Analog Mixer */ 5527 case 0x111d7608: /* 5 Port with Analog Mixer */
5320 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer,
5321 sizeof(stac92hd71bxx_dmux_amixer));
5322 spec->private_dimux.num_items--; 5528 spec->private_dimux.num_items--;
5323 switch (spec->board_config) { 5529 switch (spec->board_config) {
5324 case STAC_HP_M4: 5530 case STAC_HP_M4:
@@ -5341,11 +5547,17 @@ again:
5341 5547
5342 /* no output amps */ 5548 /* no output amps */
5343 spec->num_pwrs = 0; 5549 spec->num_pwrs = 0;
5344 spec->mixer = stac92hd71bxx_analog_mixer; 5550 if (snd_hda_get_bool_hint(codec, "analog_mixer") == 1) {
5345 spec->dinput_mux = &spec->private_dimux; 5551 spec->mixer = stac92hd71bxx_analog_mixer;
5346 5552 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer,
5553 sizeof(stac92hd71bxx_dmux_amixer));
5554 } else {
5555 memcpy(&spec->private_dimux,
5556 &stac92hd71bxx_dmux_nomixer,
5557 sizeof(stac92hd71bxx_dmux_nomixer));
5558 }
5347 /* disable VSW */ 5559 /* disable VSW */
5348 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; 5560 spec->init = stac92hd71bxx_core_init;
5349 unmute_init++; 5561 unmute_init++;
5350 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); 5562 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
5351 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); 5563 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
@@ -5353,8 +5565,11 @@ again:
5353 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5565 spec->num_dmics = stac92hd71bxx_connected_ports(codec,
5354 stac92hd71bxx_dmic_nids, 5566 stac92hd71bxx_dmic_nids,
5355 STAC92HD71BXX_NUM_DMICS - 1); 5567 STAC92HD71BXX_NUM_DMICS - 1);
5356 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); 5568 if (spec->num_dmics) {
5357 ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2; 5569 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
5570 spec->dinput_mux = &spec->private_dimux;
5571 ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2;
5572 }
5358 break; 5573 break;
5359 case 0x111d7603: /* 6 Port with Analog Mixer */ 5574 case 0x111d7603: /* 6 Port with Analog Mixer */
5360 if ((codec->revision_id & 0xf) == 1) 5575 if ((codec->revision_id & 0xf) == 1)
@@ -5364,17 +5579,25 @@ again:
5364 spec->num_pwrs = 0; 5579 spec->num_pwrs = 0;
5365 /* fallthru */ 5580 /* fallthru */
5366 default: 5581 default:
5367 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, 5582 if (snd_hda_get_bool_hint(codec, "analog_mixer") == 1) {
5368 sizeof(stac92hd71bxx_dmux_amixer)); 5583 spec->mixer = stac92hd71bxx_analog_mixer;
5369 spec->dinput_mux = &spec->private_dimux; 5584 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer,
5370 spec->mixer = stac92hd71bxx_analog_mixer; 5585 sizeof(stac92hd71bxx_dmux_amixer));
5371 spec->init = stac92hd71bxx_analog_core_init; 5586 } else {
5587 memcpy(&spec->private_dimux,
5588 &stac92hd71bxx_dmux_nomixer,
5589 sizeof(stac92hd71bxx_dmux_nomixer));
5590 }
5591 spec->init = stac92hd71bxx_core_init;
5372 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 5592 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
5373 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5593 spec->num_dmics = stac92hd71bxx_connected_ports(codec,
5374 stac92hd71bxx_dmic_nids, 5594 stac92hd71bxx_dmic_nids,
5375 STAC92HD71BXX_NUM_DMICS); 5595 STAC92HD71BXX_NUM_DMICS);
5376 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); 5596 if (spec->num_dmics) {
5377 ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; 5597 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
5598 spec->dinput_mux = &spec->private_dimux;
5599 ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1;
5600 }
5378 } 5601 }
5379 5602
5380 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) 5603 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
@@ -5535,8 +5758,8 @@ static int patch_stac922x(struct hda_codec *codec)
5535 5758
5536 again: 5759 again:
5537 if (spec->board_config < 0) 5760 if (spec->board_config < 0)
5538 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " 5761 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5539 "using BIOS defaults\n"); 5762 codec->chip_name);
5540 else 5763 else
5541 stac92xx_set_config_regs(codec, 5764 stac92xx_set_config_regs(codec,
5542 stac922x_brd_tbl[spec->board_config]); 5765 stac922x_brd_tbl[spec->board_config]);
@@ -5549,7 +5772,10 @@ static int patch_stac922x(struct hda_codec *codec)
5549 spec->num_pwrs = 0; 5772 spec->num_pwrs = 0;
5550 5773
5551 spec->init = stac922x_core_init; 5774 spec->init = stac922x_core_init;
5552 spec->mixer = stac922x_mixer; 5775
5776 spec->num_caps = STAC922X_NUM_CAPS;
5777 spec->capvols = stac922x_capvols;
5778 spec->capsws = stac922x_capsws;
5553 5779
5554 spec->multiout.dac_nids = spec->dac_nids; 5780 spec->multiout.dac_nids = spec->dac_nids;
5555 5781
@@ -5598,8 +5824,8 @@ static int patch_stac927x(struct hda_codec *codec)
5598 stac927x_cfg_tbl); 5824 stac927x_cfg_tbl);
5599 again: 5825 again:
5600 if (spec->board_config < 0) 5826 if (spec->board_config < 0)
5601 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 5827 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5602 "STAC927x, using BIOS defaults\n"); 5828 codec->chip_name);
5603 else 5829 else
5604 stac92xx_set_config_regs(codec, 5830 stac92xx_set_config_regs(codec,
5605 stac927x_brd_tbl[spec->board_config]); 5831 stac927x_brd_tbl[spec->board_config]);
@@ -5624,7 +5850,6 @@ static int patch_stac927x(struct hda_codec *codec)
5624 spec->num_dmics = 0; 5850 spec->num_dmics = 0;
5625 5851
5626 spec->init = d965_core_init; 5852 spec->init = d965_core_init;
5627 spec->mixer = stac927x_mixer;
5628 break; 5853 break;
5629 case STAC_DELL_BIOS: 5854 case STAC_DELL_BIOS:
5630 switch (codec->subsystem_id) { 5855 switch (codec->subsystem_id) {
@@ -5649,7 +5874,6 @@ static int patch_stac927x(struct hda_codec *codec)
5649 spec->num_dmics = STAC927X_NUM_DMICS; 5874 spec->num_dmics = STAC927X_NUM_DMICS;
5650 5875
5651 spec->init = d965_core_init; 5876 spec->init = d965_core_init;
5652 spec->mixer = stac927x_mixer;
5653 spec->dmux_nids = stac927x_dmux_nids; 5877 spec->dmux_nids = stac927x_dmux_nids;
5654 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); 5878 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
5655 break; 5879 break;
@@ -5662,9 +5886,12 @@ static int patch_stac927x(struct hda_codec *codec)
5662 spec->num_dmics = 0; 5886 spec->num_dmics = 0;
5663 5887
5664 spec->init = stac927x_core_init; 5888 spec->init = stac927x_core_init;
5665 spec->mixer = stac927x_mixer;
5666 } 5889 }
5667 5890
5891 spec->num_caps = STAC927X_NUM_CAPS;
5892 spec->capvols = stac927x_capvols;
5893 spec->capsws = stac927x_capsws;
5894
5668 spec->num_pwrs = 0; 5895 spec->num_pwrs = 0;
5669 spec->aloopback_ctl = stac927x_loopback; 5896 spec->aloopback_ctl = stac927x_loopback;
5670 spec->aloopback_mask = 0x40; 5897 spec->aloopback_mask = 0x40;
@@ -5726,7 +5953,8 @@ static int patch_stac9205(struct hda_codec *codec)
5726 stac9205_cfg_tbl); 5953 stac9205_cfg_tbl);
5727 again: 5954 again:
5728 if (spec->board_config < 0) 5955 if (spec->board_config < 0)
5729 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); 5956 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5957 codec->chip_name);
5730 else 5958 else
5731 stac92xx_set_config_regs(codec, 5959 stac92xx_set_config_regs(codec,
5732 stac9205_brd_tbl[spec->board_config]); 5960 stac9205_brd_tbl[spec->board_config]);
@@ -5745,9 +5973,12 @@ static int patch_stac9205(struct hda_codec *codec)
5745 spec->num_pwrs = 0; 5973 spec->num_pwrs = 0;
5746 5974
5747 spec->init = stac9205_core_init; 5975 spec->init = stac9205_core_init;
5748 spec->mixer = stac9205_mixer;
5749 spec->aloopback_ctl = stac9205_loopback; 5976 spec->aloopback_ctl = stac9205_loopback;
5750 5977
5978 spec->num_caps = STAC9205_NUM_CAPS;
5979 spec->capvols = stac9205_capvols;
5980 spec->capsws = stac9205_capsws;
5981
5751 spec->aloopback_mask = 0x40; 5982 spec->aloopback_mask = 0x40;
5752 spec->aloopback_shift = 0; 5983 spec->aloopback_shift = 0;
5753 /* Turn on/off EAPD per HP plugging */ 5984 /* Turn on/off EAPD per HP plugging */
@@ -5822,12 +6053,6 @@ static struct hda_verb stac9872_core_init[] = {
5822 {} 6053 {}
5823}; 6054};
5824 6055
5825static struct snd_kcontrol_new stac9872_mixer[] = {
5826 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
5827 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
5828 { } /* end */
5829};
5830
5831static hda_nid_t stac9872_pin_nids[] = { 6056static hda_nid_t stac9872_pin_nids[] = {
5832 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 6057 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
5833 0x11, 0x13, 0x14, 6058 0x11, 0x13, 0x14,
@@ -5841,6 +6066,11 @@ static hda_nid_t stac9872_mux_nids[] = {
5841 0x15 6066 0x15
5842}; 6067};
5843 6068
6069static unsigned long stac9872_capvols[] = {
6070 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
6071};
6072#define stac9872_capsws stac9872_capvols
6073
5844static unsigned int stac9872_vaio_pin_configs[9] = { 6074static unsigned int stac9872_vaio_pin_configs[9] = {
5845 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, 6075 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030,
5846 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, 6076 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0,
@@ -5878,8 +6108,8 @@ static int patch_stac9872(struct hda_codec *codec)
5878 stac9872_models, 6108 stac9872_models,
5879 stac9872_cfg_tbl); 6109 stac9872_cfg_tbl);
5880 if (spec->board_config < 0) 6110 if (spec->board_config < 0)
5881 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9872, " 6111 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5882 "using BIOS defaults\n"); 6112 codec->chip_name);
5883 else 6113 else
5884 stac92xx_set_config_regs(codec, 6114 stac92xx_set_config_regs(codec,
5885 stac9872_brd_tbl[spec->board_config]); 6115 stac9872_brd_tbl[spec->board_config]);
@@ -5889,8 +6119,10 @@ static int patch_stac9872(struct hda_codec *codec)
5889 spec->adc_nids = stac9872_adc_nids; 6119 spec->adc_nids = stac9872_adc_nids;
5890 spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids); 6120 spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids);
5891 spec->mux_nids = stac9872_mux_nids; 6121 spec->mux_nids = stac9872_mux_nids;
5892 spec->mixer = stac9872_mixer;
5893 spec->init = stac9872_core_init; 6122 spec->init = stac9872_core_init;
6123 spec->num_caps = 1;
6124 spec->capvols = stac9872_capvols;
6125 spec->capsws = stac9872_capsws;
5894 6126
5895 err = stac92xx_parse_auto_config(codec, 0x10, 0x12); 6127 err = stac92xx_parse_auto_config(codec, 0x10, 0x12);
5896 if (err < 0) { 6128 if (err < 0) {
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 9008b4b013aa..ab90abb04ccd 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1339,8 +1339,7 @@ static int get_mux_nids(struct hda_codec *codec)
1339 for (i = 0; i < spec->num_adc_nids; i++) { 1339 for (i = 0; i < spec->num_adc_nids; i++) {
1340 nid = spec->adc_nids[i]; 1340 nid = spec->adc_nids[i];
1341 while (nid) { 1341 while (nid) {
1342 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) 1342 type = get_wcaps_type(get_wcaps(codec, nid));
1343 >> AC_WCAP_TYPE_SHIFT;
1344 if (type == AC_WID_PIN) 1343 if (type == AC_WID_PIN)
1345 break; 1344 break;
1346 n = snd_hda_get_connections(codec, nid, conn, 1345 n = snd_hda_get_connections(codec, nid, conn,