diff options
-rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 4 | ||||
-rw-r--r-- | Documentation/sound/alsa/HD-Audio-Models.txt | 15 | ||||
-rw-r--r-- | Documentation/sound/alsa/HD-Audio.txt | 64 | ||||
-rw-r--r-- | sound/pci/hda/Kconfig | 14 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 65 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 10 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.c | 18 | ||||
-rw-r--r-- | sound/pci/hda/hda_hwdep.c | 236 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 48 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_proc.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 131 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0110.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 479 | ||||
-rw-r--r-- | sound/pci/hda/patch_intelhdmi.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 2393 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 640 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 3 |
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 | ||
117 | ALC882/885 | 117 | ALC882/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) | |
132 | ALC883/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 | ||
244 | AD1988/AD1988B/AD1989A/AD1989B | 243 | AD1988/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 | |||
139 | table until any matching entry is found. If you have a new machine, | 139 | table until any matching entry is found. If you have a new machine, |
140 | you may see a message like below: | 140 | you may see a message like below: |
141 | ------------------------------------------------------------------------ | 141 | ------------------------------------------------------------------------ |
142 | hda_codec: ALC880: BIOS auto-probing. | ||
143 | ------------------------------------------------------------------------ | ||
144 | Meanwhile, 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 | ------------------------------------------------------------------------ |
144 | Even if you see such a message, DON'T PANIC. Take a deep breath and | 148 | Even 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 | ||
410 | Early Patching | ||
411 | ~~~~~~~~~~~~~~ | ||
412 | When CONFIG_SND_HDA_PATCH_LOADER=y is set, you can pass a "patch" as a | ||
413 | firmware file for modifying the HD-audio setup before initializing the | ||
414 | codec. This can work basically like the reconfiguration via sysfs in | ||
415 | the above, but it does it before the first codec configuration. | ||
416 | |||
417 | A 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 | |||
437 | The file needs to have a line `[codec]`. The next line should contain | ||
438 | three numbers indicating the codec vendor-id (0x12345678 in the | ||
439 | example), the codec subsystem-id (0xabcd1234) and the address (2) of | ||
440 | the codec. The rest patch entries are applied to this specified codec | ||
441 | until another codec entry is given. | ||
442 | |||
443 | The `[model]` line allows to change the model name of the each codec. | ||
444 | In the example above, it will be changed to model=auto. | ||
445 | Note that this overrides the module option. | ||
446 | |||
447 | After the `[pincfg]` line, the contents are parsed as the initial | ||
448 | default pin-configurations just like `user_pin_configs` sysfs above. | ||
449 | The values can be shown in user_pin_configs sysfs file, too. | ||
450 | |||
451 | Similarly, the lines after `[verb]` are parsed as `init_verbs` | ||
452 | sysfs entries, and the lines after `[hint]` are parsed as `hints` | ||
453 | sysfs entries, respectively. | ||
454 | |||
455 | The hd-audio driver reads the file via request_firmware(). Thus, | ||
456 | a patch file has to be located on the appropriate firmware path, | ||
457 | typically, /lib/firmware. For example, when you pass the option | ||
458 | `patch=hda-init.fw`, the file /lib/firmware/hda-init-fw must be | ||
459 | present. | ||
460 | |||
461 | The patch module option is specific to each card instance, and you | ||
462 | need to give one file name for each instance, separated by commas. | ||
463 | For example, if you have two cards, one for an on-board analog and one | ||
464 | for 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 | |||
406 | Power-Saving | 470 | Power-Saving |
407 | ~~~~~~~~~~~~ | 471 | ~~~~~~~~~~~~ |
408 | The power-saving is a kind of auto-suspend of the device. When the | 472 | The 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 | ||
49 | config 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 | |||
49 | config SND_HDA_CODEC_REALTEK | 63 | config 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 | ||
28 | enum { | 29 | enum { |
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 | */ |
893 | int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | 916 | int /*__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 | } |
1063 | EXPORT_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 { | |||
830 | int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, | 830 | int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, |
831 | struct hda_bus **busp); | 831 | struct hda_bus **busp); |
832 | int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | 832 | int 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); |
834 | int 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 | */ | ||
946 | int 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 | ||
315 | static ssize_t init_verbs_store(struct device *dev, | 316 | static 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 | |||
334 | static 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 | ||
379 | static ssize_t hints_store(struct device *dev, | 388 | static 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 | |||
435 | static 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 | ||
472 | static ssize_t user_pin_configs_store(struct device *dev, | 489 | static 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 | |||
500 | static 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) | |||
553 | EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint); | 574 | EXPORT_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 */ | ||
581 | enum { | ||
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 | |||
591 | static 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 | */ | ||
599 | static 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 | */ | ||
620 | static 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 | |||
628 | static 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 | |||
636 | static 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 | |||
644 | static 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 | |||
653 | struct hda_patch_item { | ||
654 | const char *tag; | ||
655 | void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc); | ||
656 | }; | ||
657 | |||
658 | static 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 */ | ||
667 | static 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 | */ | ||
685 | static 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 | */ | ||
719 | int 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 | } | ||
752 | EXPORT_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}; | |||
61 | static int probe_only[SNDRV_CARDS]; | 61 | static int probe_only[SNDRV_CARDS]; |
62 | static int single_cmd; | 62 | static int single_cmd; |
63 | static int enable_msi; | 63 | static int enable_msi; |
64 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | ||
65 | static char *patch[SNDRV_CARDS]; | ||
66 | #endif | ||
64 | 67 | ||
65 | module_param_array(index, int, NULL, 0444); | 68 | module_param_array(index, int, NULL, 0444); |
66 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); | 69 | MODULE_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)."); |
85 | module_param(enable_msi, int, 0444); | 88 | module_param(enable_msi, int, 0444); |
86 | MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); | 89 | MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); |
90 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | ||
91 | module_param_array(patch, charp, NULL, 0444); | ||
92 | MODULE_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 |
89 | static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; | 96 | static 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 | ||
1289 | static int __devinit azx_codec_create(struct azx *chip, const char *model, | 1296 | static 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 */ | ||
1369 | static 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 | }; |
2614 | MODULE_DEVICE_TABLE(pci, azx_ids); | 2648 | MODULE_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, | |||
99 | int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | 99 | int snd_hda_add_vmaster(struct hda_codec *codec, char *name, |
100 | unsigned int *tlv, const char **slaves); | 100 | unsigned int *tlv, const char **slaves); |
101 | int snd_hda_codec_reset(struct hda_codec *codec); | 101 | int snd_hda_codec_reset(struct hda_codec *codec); |
102 | int 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 | |||
411 | u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction); | 413 | u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction); |
412 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | 414 | int 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 | ||
672 | static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { | 673 | static 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 | ||
702 | static struct snd_kcontrol_new ad1986a_samsung_mixers[] = { | 679 | static 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 | ||
705 | static 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 */ |
731 | static void ad1986a_automic(struct hda_codec *codec) | 712 | static 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 | ||
819 | static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = { | 801 | static 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 | ||
943 | static 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 | |||
956 | static 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 */ |
986 | enum { | 966 | enum { |
@@ -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 | ||
1007 | static struct snd_pci_quirk ad1986a_cfg_tbl[] = { | 989 | static 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 | ||
113 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, | 115 | static 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 | |||
1915 | static hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; | ||
1916 | static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; | ||
1917 | static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; | ||
1918 | #define CXT5066_SPDIF_OUT 0x21 | ||
1919 | |||
1920 | static struct hda_channel_mode cxt5066_modes[1] = { | ||
1921 | { 2, NULL }, | ||
1922 | }; | ||
1923 | |||
1924 | static 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 */ | ||
1958 | static 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 */ | ||
1971 | static 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 */ | ||
2009 | static 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 */ | ||
2029 | static 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 | |||
2042 | static 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 | |||
2053 | static 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 | |||
2059 | static 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 | |||
2072 | static 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 | |||
2093 | static 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 | |||
2103 | static 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 | |||
2112 | static 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 | |||
2121 | static struct snd_kcontrol_new cxt5066_mixer_master[] = { | ||
2122 | HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), | ||
2123 | {} | ||
2124 | }; | ||
2125 | |||
2126 | static 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 | |||
2144 | static 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 | |||
2167 | static 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 | |||
2222 | static 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 | |||
2283 | static 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 */ | ||
2289 | static 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 | |||
2300 | enum { | ||
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 | |||
2307 | static 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 | |||
2313 | static 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 | |||
2321 | static 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 | ||
1925 | MODULE_ALIAS("snd-hda-codec-id:14f15045"); | 2403 | MODULE_ALIAS("snd-hda-codec-id:14f15045"); |
1926 | MODULE_ALIAS("snd-hda-codec-id:14f15047"); | 2404 | MODULE_ALIAS("snd-hda-codec-id:14f15047"); |
1927 | MODULE_ALIAS("snd-hda-codec-id:14f15051"); | 2405 | MODULE_ALIAS("snd-hda-codec-id:14f15051"); |
2406 | MODULE_ALIAS("snd-hda-codec-id:14f15066"); | ||
1928 | 2407 | ||
1929 | MODULE_LICENSE("GPL"); | 2408 | MODULE_LICENSE("GPL"); |
1930 | MODULE_DESCRIPTION("Conexant HD-audio codec"); | 2409 | MODULE_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"); | |||
694 | MODULE_ALIAS("snd-hda-codec-id:80862802"); | 695 | MODULE_ALIAS("snd-hda-codec-id:80862802"); |
695 | MODULE_ALIAS("snd-hda-codec-id:80862803"); | 696 | MODULE_ALIAS("snd-hda-codec-id:80862803"); |
696 | MODULE_ALIAS("snd-hda-codec-id:80862804"); | 697 | MODULE_ALIAS("snd-hda-codec-id:80862804"); |
698 | MODULE_ALIAS("snd-hda-codec-id:80860054"); | ||
697 | MODULE_ALIAS("snd-hda-codec-id:10951392"); | 699 | MODULE_ALIAS("snd-hda-codec-id:10951392"); |
698 | 700 | ||
699 | MODULE_LICENSE("GPL"); | 701 | MODULE_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 */ | ||
216 | enum { | ||
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 | ||
1032 | static 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 | |||
1034 | static void alc_auto_init_amp(struct hda_codec *codec, int type) | 1042 | static 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 | ||
1439 | static 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 | |||
1452 | static void alc889_intel_init_hook(struct hda_codec *codec) | ||
1453 | { | ||
1454 | alc889_coef_init(codec); | ||
1455 | alc889_automute_init(codec); | ||
1456 | } | ||
1457 | |||
1439 | static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec) | 1458 | static 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 | ||
6317 | static struct hda_channel_mode alc882_ch_modes[1] = { | 6333 | static struct hda_channel_mode alc882_ch_modes[1] = { |
6318 | { 8, NULL } | 6334 | { 8, NULL } |
6319 | }; | 6335 | }; |
6320 | 6336 | ||
6337 | /* DACs */ | ||
6321 | static hda_nid_t alc882_dac_nids[4] = { | 6338 | static 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 | ||
6348 | static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; | ||
6349 | static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; | ||
6350 | #define alc889_adc_nids alc880_adc_nids | ||
6329 | 6351 | ||
6330 | static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; | 6352 | static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; |
6331 | static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; | 6353 | static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; |
6354 | #define alc883_capsrc_nids alc882_capsrc_nids_alt | ||
6355 | static 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 | |||
6373 | static 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 | |||
6346 | static struct hda_input_mux mb5_capture_source = { | 6382 | static 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 | ||
6391 | static 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 | |||
6401 | static struct hda_input_mux alc883_lenovo_101e_capture_source = { | ||
6402 | .num_items = 2, | ||
6403 | .items = { | ||
6404 | { "Mic", 0x1 }, | ||
6405 | { "Line", 0x2 }, | ||
6406 | }, | ||
6407 | }; | ||
6408 | |||
6409 | static 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 | |||
6419 | static 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 | |||
6427 | static 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 | |||
6436 | static struct hda_input_mux alc883_asus_eee1601_capture_source = { | ||
6437 | .num_items = 2, | ||
6438 | .items = { | ||
6439 | { "Mic", 0x0 }, | ||
6440 | { "Line", 0x2 }, | ||
6441 | }, | ||
6442 | }; | ||
6443 | |||
6444 | static 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 | */ | ||
6458 | static 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 | */ | ||
6476 | static 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 | */ |
6369 | static struct hda_verb alc882_3ST_ch6_init[] = { | 6488 | static 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 | ||
6379 | static struct hda_channel_mode alc882_3ST_6ch_modes[2] = { | 6498 | static 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 | */ | ||
6597 | static 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 | */ | ||
6610 | static 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 | */ | ||
6624 | static 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 | */ | ||
6639 | static 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 | |||
6652 | static 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 | */ | ||
6663 | static 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 | */ | ||
6674 | static 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 | */ | ||
6686 | static 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 | |||
6696 | static 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 | */ | ||
6705 | static 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 | */ | ||
6718 | static 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 | */ | ||
6731 | static 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 | |||
6742 | static 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 | */ | ||
6751 | static 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 | */ | ||
6762 | static 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 | |||
6770 | static 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 | ||
6606 | static struct hda_verb alc882_init_verbs[] = { | 6911 | static 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 | ||
6990 | static 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 | |||
6686 | static struct hda_verb alc882_eapd_verbs[] = { | 7002 | static 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 | ||
7009 | static 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 | |||
7015 | static 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 | |||
7021 | static 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 | |||
7095 | static 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 */ | ||
7104 | static 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 */ |
6694 | static struct snd_kcontrol_new alc882_macpro_mixer[] = { | 7114 | static 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 | */ |
7040 | static struct hda_verb alc882_auto_init_verbs[] = { | 7460 | static 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 | */ | ||
7118 | static 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 | |||
7133 | static 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 | |||
7149 | static 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 | */ | ||
7295 | enum { | ||
7296 | PINFIX_ABIT_AW9D_MAX | ||
7297 | }; | ||
7298 | |||
7299 | static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { | ||
7300 | { 0x15, 0x01080104 }, /* side */ | ||
7301 | { 0x16, 0x01011012 }, /* rear */ | ||
7302 | { 0x17, 0x01016011 }, /* clfe */ | ||
7303 | { } | ||
7304 | }; | ||
7305 | |||
7306 | static const struct alc_pincfg *alc882_pin_fixes[] = { | ||
7307 | [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, | ||
7308 | }; | ||
7309 | |||
7310 | static 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 | */ | ||
7318 | static 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 | |||
7335 | static 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 | |||
7349 | static 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 | |||
7366 | static 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 | |||
7383 | static 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 */ | ||
7432 | static 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... */ | ||
7458 | static 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 */ | ||
7479 | static 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 | |||
7490 | static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */ | ||
7491 | |||
7492 | static 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 | |||
7629 | static hda_nid_t alc883_dac_nids[4] = { | ||
7630 | /* front, rear, clfe, rear_surr */ | ||
7631 | 0x02, 0x03, 0x04, 0x05 | ||
7632 | }; | ||
7633 | |||
7634 | static hda_nid_t alc883_adc_nids[2] = { | ||
7635 | /* ADC1-2 */ | ||
7636 | 0x08, 0x09, | ||
7637 | }; | ||
7638 | |||
7639 | static hda_nid_t alc883_adc_nids_alt[1] = { | ||
7640 | /* ADC1 */ | ||
7641 | 0x08, | ||
7642 | }; | ||
7643 | |||
7644 | static 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 | |||
7651 | static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 }; | ||
7652 | |||
7653 | static 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 | |||
7660 | static 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 | |||
7670 | static 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 | |||
7680 | static struct hda_input_mux alc883_lenovo_101e_capture_source = { | ||
7681 | .num_items = 2, | ||
7682 | .items = { | ||
7683 | { "Mic", 0x1 }, | ||
7684 | { "Line", 0x2 }, | ||
7685 | }, | ||
7686 | }; | ||
7687 | |||
7688 | static 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 | |||
7698 | static 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 | |||
7706 | static 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 | |||
7715 | static struct hda_input_mux alc883_asus_eee1601_capture_source = { | ||
7716 | .num_items = 2, | ||
7717 | .items = { | ||
7718 | { "Mic", 0x0 }, | ||
7719 | { "Line", 0x2 }, | ||
7720 | }, | ||
7721 | }; | ||
7722 | |||
7723 | static 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 | */ | ||
7737 | static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { | ||
7738 | { 2, NULL } | ||
7739 | }; | ||
7740 | |||
7741 | /* | ||
7742 | * 2ch mode | ||
7743 | */ | ||
7744 | static 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 | */ | ||
7755 | static 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 | */ | ||
7767 | static 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 | |||
7777 | static 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 | */ | ||
7787 | static 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 | */ | ||
7800 | static 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 | */ | ||
7814 | static 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 | */ | ||
7829 | static 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 | |||
7842 | static 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 | */ | ||
7853 | static 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 | */ | ||
7864 | static 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 | */ | ||
7876 | static 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 | |||
7886 | static 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 | */ | ||
7895 | static 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 | */ | ||
7906 | static 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 | |||
7914 | static 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) */ |
7920 | static struct hda_verb alc889A_mb31_ch2_init[] = { | 7519 | static 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 | |||
7973 | static 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 | ||
7998 | static struct snd_kcontrol_new alc883_mitac_mixer[] = { | 7570 | static 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 | ||
7679 | static 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 | |||
8107 | static struct snd_kcontrol_new alc883_fivestack_mixer[] = { | 7703 | static 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 | ||
8347 | static 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 */ |
8426 | static void alc883_mitac_init_hook(struct hda_codec *codec) | 7944 | static 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 | */ | ||
8860 | static 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 | |||
8920 | static struct hda_verb alc888_asus_m90v_verbs[] = { | 8375 | static 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 | |
8496 | static hda_nid_t alc883_slave_dig_outs[] = { | ||
8497 | ALC1200_DIGOUT_NID, 0, | ||
8498 | }; | ||
8499 | |||
8500 | static 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 | */ |
9044 | static const char *alc883_models[ALC883_MODEL_LAST] = { | 8507 | static 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 | ||
9078 | static struct snd_pci_quirk alc883_cfg_tbl[] = { | 8554 | static 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 | ||
9177 | static hda_nid_t alc883_slave_dig_outs[] = { | 8672 | {} |
9178 | ALC1200_DIGOUT_NID, 0, | ||
9179 | }; | 8673 | }; |
9180 | 8674 | ||
9181 | static hda_nid_t alc1200_slave_dig_outs[] = { | 8675 | /* codec SSID table for Intel Mac */ |
9182 | ALC883_DIGOUT_NID, 0, | 8676 | static 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 | ||
9185 | static struct alc_config_preset alc883_presets[] = { | 8695 | static 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 | */ | ||
9315 | enum { | ||
9316 | PINFIX_ABIT_AW9D_MAX | ||
9317 | }; | ||
9318 | |||
9319 | static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { | ||
9320 | { 0x15, 0x01080104 }, /* side */ | ||
9321 | { 0x16, 0x01011012 }, /* rear */ | ||
9322 | { 0x17, 0x01016011 }, /* clfe */ | ||
9323 | { } | ||
9324 | }; | ||
9325 | |||
9326 | static const struct alc_pincfg *alc882_pin_fixes[] = { | ||
9327 | [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, | ||
9328 | }; | ||
9329 | |||
9330 | static 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 | */ |
9624 | static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, | 9338 | static 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 | ||
9641 | static void alc883_auto_init_multi_out(struct hda_codec *codec) | 9355 | static 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 | ||
9655 | static void alc883_auto_init_hp_out(struct hda_codec *codec) | 9369 | static 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) | 9383 | static void alc882_auto_init_analog_input(struct hda_codec *codec) |
9670 | #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID | ||
9671 | |||
9672 | static 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 | |||
9400 | static 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 */ |
9449 | static 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... */ |
9693 | static int alc883_parse_auto_config(struct hda_codec *codec) | 9475 | static 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 */ |
9736 | static void alc883_auto_init(struct hda_codec *codec) | 9521 | static 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 | ||
9747 | static int patch_alc883(struct hda_codec *codec) | 9532 | static 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 | ||
10362 | static 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 | |||
10368 | static struct hda_verb alc262_hippo1_unsol_verbs[] = { | 10152 | static 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 | ||
14008 | static 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 */ |
14200 | static int alc861_auto_fill_dac_nids(struct alc_spec *spec, | 14034 | static 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 | ||
14052 | static 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 */ |
14220 | static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, | 14062 | static 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 | ||
14264 | static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) | 14105 | static 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 */ |
14285 | static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, | 14127 | static 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 | ||
14329 | static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, | 14172 | static 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 | ||
14339 | static void alc861_auto_init_multi_out(struct hda_codec *codec) | 14199 | static 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 | ||
14367 | static void alc861_auto_init_analog_input(struct hda_codec *codec) | 14228 | static 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 | ||
45 | enum { | 47 | enum { |
@@ -176,6 +178,12 @@ struct sigmatel_jack { | |||
176 | struct snd_jack *jack; | 178 | struct snd_jack *jack; |
177 | }; | 179 | }; |
178 | 180 | ||
181 | struct sigmatel_mic_route { | ||
182 | hda_nid_t pin; | ||
183 | unsigned char mux_idx; | ||
184 | unsigned char dmux_idx; | ||
185 | }; | ||
186 | |||
179 | struct sigmatel_spec { | 187 | struct 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 | ||
355 | static 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 |
338 | static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { | 362 | static 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 | ||
393 | static 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 | |||
368 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { | 399 | static 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 | ||
429 | static 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 | |||
397 | static hda_nid_t stac925x_adc_nids[1] = { | 435 | static 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 | ||
456 | static unsigned long stac925x_capvols[] = { | ||
457 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), | ||
458 | }; | ||
459 | static unsigned long stac925x_capsws[] = { | ||
460 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
461 | }; | ||
462 | |||
418 | static hda_nid_t stac922x_adc_nids[2] = { | 463 | static 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 | ||
472 | static 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 | |||
426 | static hda_nid_t stac927x_slave_dig_outs[2] = { | 478 | static 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 | ||
508 | static 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 | }; | ||
513 | static 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 | |||
455 | static const char *stac927x_spdif_labels[5] = { | 519 | static 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 | ||
546 | static 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 | }; | ||
550 | static 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 | |||
481 | static hda_nid_t stac9200_pin_nids[8] = { | 555 | static 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 | ||
928 | static 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 | |||
940 | static struct hda_verb stac92hd71bxx_unmute_core_init[] = { | 1001 | static 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 | ||
1096 | static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { | 1151 | static 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 | ||
1120 | static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { | 1169 | static 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 | ||
1145 | static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | 1188 | static 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 | ||
1171 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | 1208 | static 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 | ||
1201 | static 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 | |||
1210 | static struct snd_kcontrol_new stac925x_mixer[] = { | 1227 | static 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 | |||
1218 | static 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 */ | ||
1233 | static 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 | |||
1243 | static 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 | |||
1255 | static struct snd_kcontrol_new stac927x_loopback[] = { | 1238 | static 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 | ||
2639 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, | 2624 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid); |
2640 | unsigned char type); | ||
2641 | 2625 | ||
2642 | static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, | 2626 | static 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 | ||
3308 | static 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 */ |
3323 | static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | 3324 | static 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 | ||
3563 | static 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 */ |
3563 | static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | 3577 | static 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; | ||
3598 | found: | ||
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 | ||
3630 | static 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 | |||
3653 | static 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 */ | ||
3684 | static 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 */ |
3626 | static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) | 3713 | static 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 | ||
4104 | static struct sigmatel_event *stac_get_event(struct hda_codec *codec, | 4205 | static 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 | ||
4132 | static 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 | */ | ||
4237 | static 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 | ||
4152 | static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) | 4261 | static 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 | ||
4557 | static 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 | ||
4596 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, | 4745 | static 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 | |||
4764 | static 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, | |||
4748 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | 4926 | static 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); |
4940 | again: | 5135 | again: |
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); |
5116 | again: | 5319 | again: |
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); |
5280 | again: | 5485 | again: |
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 | ||
5825 | static 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 | |||
5831 | static hda_nid_t stac9872_pin_nids[] = { | 6056 | static 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 | ||
6069 | static unsigned long stac9872_capvols[] = { | ||
6070 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), | ||
6071 | }; | ||
6072 | #define stac9872_capsws stac9872_capvols | ||
6073 | |||
5844 | static unsigned int stac9872_vaio_pin_configs[9] = { | 6074 | static 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, |