diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/Kconfig | 27 | ||||
-rw-r--r-- | sound/pci/hda/Makefile | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 66 | ||||
-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 | 74 | ||||
-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_cirrus.c | 1194 | ||||
-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 | 104 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 3468 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 886 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 3 |
19 files changed, 4392 insertions, 2325 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 04438f1d682..55545e0818b 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 |
@@ -134,6 +148,19 @@ config SND_HDA_ELD | |||
134 | def_bool y | 148 | def_bool y |
135 | depends on SND_HDA_CODEC_INTELHDMI | 149 | depends on SND_HDA_CODEC_INTELHDMI |
136 | 150 | ||
151 | config SND_HDA_CODEC_CIRRUS | ||
152 | bool "Build Cirrus Logic codec support" | ||
153 | depends on SND_HDA_INTEL | ||
154 | default y | ||
155 | help | ||
156 | Say Y here to include Cirrus Logic codec support in | ||
157 | snd-hda-intel driver, such as CS4206. | ||
158 | |||
159 | When the HD-audio driver is built as a module, the codec | ||
160 | support code is also built as another module, | ||
161 | snd-hda-codec-cirrus. | ||
162 | This module is automatically loaded at probing. | ||
163 | |||
137 | config SND_HDA_CODEC_CONEXANT | 164 | config SND_HDA_CODEC_CONEXANT |
138 | bool "Build Conexant HD-audio codec support" | 165 | bool "Build Conexant HD-audio codec support" |
139 | default y | 166 | default y |
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index e3081d4586c..315a1c4f899 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile | |||
@@ -13,6 +13,7 @@ snd-hda-codec-analog-objs := patch_analog.o | |||
13 | snd-hda-codec-idt-objs := patch_sigmatel.o | 13 | snd-hda-codec-idt-objs := patch_sigmatel.o |
14 | snd-hda-codec-si3054-objs := patch_si3054.o | 14 | snd-hda-codec-si3054-objs := patch_si3054.o |
15 | snd-hda-codec-atihdmi-objs := patch_atihdmi.o | 15 | snd-hda-codec-atihdmi-objs := patch_atihdmi.o |
16 | snd-hda-codec-cirrus-objs := patch_cirrus.o | ||
16 | snd-hda-codec-ca0110-objs := patch_ca0110.o | 17 | snd-hda-codec-ca0110-objs := patch_ca0110.o |
17 | snd-hda-codec-conexant-objs := patch_conexant.o | 18 | snd-hda-codec-conexant-objs := patch_conexant.o |
18 | snd-hda-codec-via-objs := patch_via.o | 19 | snd-hda-codec-via-objs := patch_via.o |
@@ -41,6 +42,9 @@ endif | |||
41 | ifdef CONFIG_SND_HDA_CODEC_ATIHDMI | 42 | ifdef CONFIG_SND_HDA_CODEC_ATIHDMI |
42 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o | 43 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o |
43 | endif | 44 | endif |
45 | ifdef CONFIG_SND_HDA_CODEC_CIRRUS | ||
46 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cirrus.o | ||
47 | endif | ||
44 | ifdef CONFIG_SND_HDA_CODEC_CA0110 | 48 | ifdef CONFIG_SND_HDA_CODEC_CA0110 |
45 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o | 49 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o |
46 | endif | 50 | endif |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index b0275a05087..3f51a981e60 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 c7df01b72ca..24401d5d351 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -44,6 +44,7 @@ struct hda_vendor_id { | |||
44 | /* codec vendor labels */ | 44 | /* codec vendor labels */ |
45 | static struct hda_vendor_id hda_vendor_ids[] = { | 45 | static struct hda_vendor_id hda_vendor_ids[] = { |
46 | { 0x1002, "ATI" }, | 46 | { 0x1002, "ATI" }, |
47 | { 0x1013, "Cirrus Logic" }, | ||
47 | { 0x1057, "Motorola" }, | 48 | { 0x1057, "Motorola" }, |
48 | { 0x1095, "Silicon Image" }, | 49 | { 0x1095, "Silicon Image" }, |
49 | { 0x10de, "Nvidia" }, | 50 | { 0x10de, "Nvidia" }, |
@@ -150,7 +151,14 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | |||
150 | { | 151 | { |
151 | u32 val; | 152 | u32 val; |
152 | 153 | ||
153 | val = (u32)(codec->addr & 0x0f) << 28; | 154 | if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) || |
155 | (verb & ~0xfff) || (parm & ~0xffff)) { | ||
156 | printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n", | ||
157 | codec->addr, direct, nid, verb, parm); | ||
158 | return ~0; | ||
159 | } | ||
160 | |||
161 | val = (u32)codec->addr << 28; | ||
154 | val |= (u32)direct << 27; | 162 | val |= (u32)direct << 27; |
155 | val |= (u32)nid << 20; | 163 | val |= (u32)nid << 20; |
156 | val |= verb << 8; | 164 | val |= verb << 8; |
@@ -167,6 +175,9 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, | |||
167 | struct hda_bus *bus = codec->bus; | 175 | struct hda_bus *bus = codec->bus; |
168 | int err; | 176 | int err; |
169 | 177 | ||
178 | if (cmd == ~0) | ||
179 | return -1; | ||
180 | |||
170 | if (res) | 181 | if (res) |
171 | *res = -1; | 182 | *res = -1; |
172 | again: | 183 | again: |
@@ -291,11 +302,20 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
291 | unsigned int parm; | 302 | unsigned int parm; |
292 | int i, conn_len, conns; | 303 | int i, conn_len, conns; |
293 | unsigned int shift, num_elems, mask; | 304 | unsigned int shift, num_elems, mask; |
305 | unsigned int wcaps; | ||
294 | hda_nid_t prev_nid; | 306 | hda_nid_t prev_nid; |
295 | 307 | ||
296 | if (snd_BUG_ON(!conn_list || max_conns <= 0)) | 308 | if (snd_BUG_ON(!conn_list || max_conns <= 0)) |
297 | return -EINVAL; | 309 | return -EINVAL; |
298 | 310 | ||
311 | wcaps = get_wcaps(codec, nid); | ||
312 | if (!(wcaps & AC_WCAP_CONN_LIST) && | ||
313 | get_wcaps_type(wcaps) != AC_WID_VOL_KNB) { | ||
314 | snd_printk(KERN_WARNING "hda_codec: " | ||
315 | "connection list not available for 0x%x\n", nid); | ||
316 | return -EINVAL; | ||
317 | } | ||
318 | |||
299 | parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); | 319 | parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); |
300 | if (parm & AC_CLIST_LONG) { | 320 | if (parm & AC_CLIST_LONG) { |
301 | /* long form */ | 321 | /* long form */ |
@@ -316,6 +336,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
316 | /* single connection */ | 336 | /* single connection */ |
317 | parm = snd_hda_codec_read(codec, nid, 0, | 337 | parm = snd_hda_codec_read(codec, nid, 0, |
318 | AC_VERB_GET_CONNECT_LIST, 0); | 338 | AC_VERB_GET_CONNECT_LIST, 0); |
339 | if (parm == -1 && codec->bus->rirb_error) | ||
340 | return -EIO; | ||
319 | conn_list[0] = parm & mask; | 341 | conn_list[0] = parm & mask; |
320 | return 1; | 342 | return 1; |
321 | } | 343 | } |
@@ -327,9 +349,12 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
327 | int range_val; | 349 | int range_val; |
328 | hda_nid_t val, n; | 350 | hda_nid_t val, n; |
329 | 351 | ||
330 | if (i % num_elems == 0) | 352 | if (i % num_elems == 0) { |
331 | parm = snd_hda_codec_read(codec, nid, 0, | 353 | parm = snd_hda_codec_read(codec, nid, 0, |
332 | AC_VERB_GET_CONNECT_LIST, i); | 354 | AC_VERB_GET_CONNECT_LIST, i); |
355 | if (parm == -1 && codec->bus->rirb_error) | ||
356 | return -EIO; | ||
357 | } | ||
333 | range_val = !!(parm & (1 << (shift-1))); /* ranges */ | 358 | range_val = !!(parm & (1 << (shift-1))); /* ranges */ |
334 | val = parm & mask; | 359 | val = parm & mask; |
335 | if (val == 0) { | 360 | if (val == 0) { |
@@ -727,8 +752,7 @@ static int read_pin_defaults(struct hda_codec *codec) | |||
727 | for (i = 0; i < codec->num_nodes; i++, nid++) { | 752 | for (i = 0; i < codec->num_nodes; i++, nid++) { |
728 | struct hda_pincfg *pin; | 753 | struct hda_pincfg *pin; |
729 | unsigned int wcaps = get_wcaps(codec, nid); | 754 | unsigned int wcaps = get_wcaps(codec, nid); |
730 | unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> | 755 | unsigned int wid_type = get_wcaps_type(wcaps); |
731 | AC_WCAP_TYPE_SHIFT; | ||
732 | if (wid_type != AC_WID_PIN) | 756 | if (wid_type != AC_WID_PIN) |
733 | continue; | 757 | continue; |
734 | pin = snd_array_new(&codec->init_pins); | 758 | pin = snd_array_new(&codec->init_pins); |
@@ -891,7 +915,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. | 915 | * Returns 0 if successful, or a negative error code. |
892 | */ | 916 | */ |
893 | int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | 917 | int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, |
894 | int do_init, struct hda_codec **codecp) | 918 | struct hda_codec **codecp) |
895 | { | 919 | { |
896 | struct hda_codec *codec; | 920 | struct hda_codec *codec; |
897 | char component[31]; | 921 | char component[31]; |
@@ -984,11 +1008,6 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr | |||
984 | codec->afg ? codec->afg : codec->mfg, | 1008 | codec->afg ? codec->afg : codec->mfg, |
985 | AC_PWRST_D0); | 1009 | AC_PWRST_D0); |
986 | 1010 | ||
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); | 1011 | snd_hda_codec_proc_new(codec); |
993 | 1012 | ||
994 | snd_hda_create_hwdep(codec); | 1013 | snd_hda_create_hwdep(codec); |
@@ -1042,6 +1061,7 @@ int snd_hda_codec_configure(struct hda_codec *codec) | |||
1042 | err = init_unsol_queue(codec->bus); | 1061 | err = init_unsol_queue(codec->bus); |
1043 | return err; | 1062 | return err; |
1044 | } | 1063 | } |
1064 | EXPORT_SYMBOL_HDA(snd_hda_codec_configure); | ||
1045 | 1065 | ||
1046 | /** | 1066 | /** |
1047 | * snd_hda_codec_setup_stream - set up the codec for streaming | 1067 | * snd_hda_codec_setup_stream - set up the codec for streaming |
@@ -2356,16 +2376,20 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
2356 | hda_nid_t nid; | 2376 | hda_nid_t nid; |
2357 | int i; | 2377 | int i; |
2358 | 2378 | ||
2359 | snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE, | 2379 | /* this delay seems necessary to avoid click noise at power-down */ |
2380 | if (power_state == AC_PWRST_D3) | ||
2381 | msleep(100); | ||
2382 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, | ||
2360 | power_state); | 2383 | power_state); |
2361 | msleep(10); /* partial workaround for "azx_get_response timeout" */ | 2384 | /* partial workaround for "azx_get_response timeout" */ |
2385 | if (power_state == AC_PWRST_D0) | ||
2386 | msleep(10); | ||
2362 | 2387 | ||
2363 | nid = codec->start_nid; | 2388 | nid = codec->start_nid; |
2364 | for (i = 0; i < codec->num_nodes; i++, nid++) { | 2389 | for (i = 0; i < codec->num_nodes; i++, nid++) { |
2365 | unsigned int wcaps = get_wcaps(codec, nid); | 2390 | unsigned int wcaps = get_wcaps(codec, nid); |
2366 | if (wcaps & AC_WCAP_POWER) { | 2391 | if (wcaps & AC_WCAP_POWER) { |
2367 | unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> | 2392 | unsigned int wid_type = get_wcaps_type(wcaps); |
2368 | AC_WCAP_TYPE_SHIFT; | ||
2369 | if (power_state == AC_PWRST_D3 && | 2393 | if (power_state == AC_PWRST_D3 && |
2370 | wid_type == AC_WID_PIN) { | 2394 | wid_type == AC_WID_PIN) { |
2371 | unsigned int pincap; | 2395 | unsigned int pincap; |
@@ -2573,7 +2597,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
2573 | case 20: | 2597 | case 20: |
2574 | case 24: | 2598 | case 24: |
2575 | case 32: | 2599 | case 32: |
2576 | if (maxbps >= 32) | 2600 | if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE) |
2577 | val |= 0x40; | 2601 | val |= 0x40; |
2578 | else if (maxbps >= 24) | 2602 | else if (maxbps >= 24) |
2579 | val |= 0x30; | 2603 | val |= 0x30; |
@@ -2700,11 +2724,12 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
2700 | bps = 20; | 2724 | bps = 20; |
2701 | } | 2725 | } |
2702 | } | 2726 | } |
2703 | else if (streams == AC_SUPFMT_FLOAT32) { | 2727 | if (streams & AC_SUPFMT_FLOAT32) { |
2704 | /* should be exclusive */ | ||
2705 | formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; | 2728 | formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; |
2706 | bps = 32; | 2729 | if (!bps) |
2707 | } else if (streams == AC_SUPFMT_AC3) { | 2730 | bps = 32; |
2731 | } | ||
2732 | if (streams == AC_SUPFMT_AC3) { | ||
2708 | /* should be exclusive */ | 2733 | /* should be exclusive */ |
2709 | /* temporary hack: we have still no proper support | 2734 | /* temporary hack: we have still no proper support |
2710 | * for the direct AC3 stream... | 2735 | * for the direct AC3 stream... |
@@ -3655,8 +3680,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
3655 | end_nid = codec->start_nid + codec->num_nodes; | 3680 | end_nid = codec->start_nid + codec->num_nodes; |
3656 | for (nid = codec->start_nid; nid < end_nid; nid++) { | 3681 | for (nid = codec->start_nid; nid < end_nid; nid++) { |
3657 | unsigned int wid_caps = get_wcaps(codec, nid); | 3682 | unsigned int wid_caps = get_wcaps(codec, nid); |
3658 | unsigned int wid_type = | 3683 | unsigned int wid_type = get_wcaps_type(wid_caps); |
3659 | (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
3660 | unsigned int def_conf; | 3684 | unsigned int def_conf; |
3661 | short assoc, loc; | 3685 | short assoc, loc; |
3662 | 3686 | ||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 1b75f28ed09..99552fb5f75 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 1d5797a9668..b36f6c5a92d 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 6812fbe80fa..cc24e6721d7 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 175f07a381b..20a66f85f0a 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; |
@@ -1331,8 +1338,7 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = { | |||
1331 | [AZX_DRIVER_TERA] = 1, | 1338 | [AZX_DRIVER_TERA] = 1, |
1332 | }; | 1339 | }; |
1333 | 1340 | ||
1334 | static int __devinit azx_codec_create(struct azx *chip, const char *model, | 1341 | static int __devinit azx_codec_create(struct azx *chip, const char *model) |
1335 | int no_init) | ||
1336 | { | 1342 | { |
1337 | struct hda_bus_template bus_temp; | 1343 | struct hda_bus_template bus_temp; |
1338 | int c, codecs, err; | 1344 | int c, codecs, err; |
@@ -1391,7 +1397,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, | |||
1391 | for (c = 0; c < max_slots; c++) { | 1397 | for (c = 0; c < max_slots; c++) { |
1392 | if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { | 1398 | if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { |
1393 | struct hda_codec *codec; | 1399 | struct hda_codec *codec; |
1394 | err = snd_hda_codec_new(chip->bus, c, !no_init, &codec); | 1400 | err = snd_hda_codec_new(chip->bus, c, &codec); |
1395 | if (err < 0) | 1401 | if (err < 0) |
1396 | continue; | 1402 | continue; |
1397 | codecs++; | 1403 | codecs++; |
@@ -1401,7 +1407,16 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, | |||
1401 | snd_printk(KERN_ERR SFX "no codecs initialized\n"); | 1407 | snd_printk(KERN_ERR SFX "no codecs initialized\n"); |
1402 | return -ENXIO; | 1408 | return -ENXIO; |
1403 | } | 1409 | } |
1410 | return 0; | ||
1411 | } | ||
1404 | 1412 | ||
1413 | /* configure each codec instance */ | ||
1414 | static int __devinit azx_codec_configure(struct azx *chip) | ||
1415 | { | ||
1416 | struct hda_codec *codec; | ||
1417 | list_for_each_entry(codec, &chip->bus->codec_list, list) { | ||
1418 | snd_hda_codec_configure(codec); | ||
1419 | } | ||
1405 | return 0; | 1420 | return 0; |
1406 | } | 1421 | } |
1407 | 1422 | ||
@@ -2284,6 +2299,30 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) | |||
2284 | } | 2299 | } |
2285 | } | 2300 | } |
2286 | 2301 | ||
2302 | /* | ||
2303 | * white-list for enable_msi | ||
2304 | */ | ||
2305 | static struct snd_pci_quirk msi_white_list[] __devinitdata = { | ||
2306 | SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1), | ||
2307 | {} | ||
2308 | }; | ||
2309 | |||
2310 | static void __devinit check_msi(struct azx *chip) | ||
2311 | { | ||
2312 | const struct snd_pci_quirk *q; | ||
2313 | |||
2314 | chip->msi = enable_msi; | ||
2315 | if (chip->msi) | ||
2316 | return; | ||
2317 | q = snd_pci_quirk_lookup(chip->pci, msi_white_list); | ||
2318 | if (q) { | ||
2319 | printk(KERN_INFO | ||
2320 | "hda_intel: msi for device %04x:%04x set to %d\n", | ||
2321 | q->subvendor, q->subdevice, q->value); | ||
2322 | chip->msi = q->value; | ||
2323 | } | ||
2324 | } | ||
2325 | |||
2287 | 2326 | ||
2288 | /* | 2327 | /* |
2289 | * constructor | 2328 | * constructor |
@@ -2318,7 +2357,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2318 | chip->pci = pci; | 2357 | chip->pci = pci; |
2319 | chip->irq = -1; | 2358 | chip->irq = -1; |
2320 | chip->driver_type = driver_type; | 2359 | chip->driver_type = driver_type; |
2321 | chip->msi = enable_msi; | 2360 | check_msi(chip); |
2322 | chip->dev_index = dev; | 2361 | chip->dev_index = dev; |
2323 | INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); | 2362 | INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); |
2324 | 2363 | ||
@@ -2526,15 +2565,32 @@ static int __devinit azx_probe(struct pci_dev *pci, | |||
2526 | return err; | 2565 | return err; |
2527 | } | 2566 | } |
2528 | 2567 | ||
2568 | /* set this here since it's referred in snd_hda_load_patch() */ | ||
2569 | snd_card_set_dev(card, &pci->dev); | ||
2570 | |||
2529 | err = azx_create(card, pci, dev, pci_id->driver_data, &chip); | 2571 | err = azx_create(card, pci, dev, pci_id->driver_data, &chip); |
2530 | if (err < 0) | 2572 | if (err < 0) |
2531 | goto out_free; | 2573 | goto out_free; |
2532 | card->private_data = chip; | 2574 | card->private_data = chip; |
2533 | 2575 | ||
2534 | /* create codec instances */ | 2576 | /* create codec instances */ |
2535 | err = azx_codec_create(chip, model[dev], probe_only[dev]); | 2577 | err = azx_codec_create(chip, model[dev]); |
2536 | if (err < 0) | 2578 | if (err < 0) |
2537 | goto out_free; | 2579 | goto out_free; |
2580 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | ||
2581 | if (patch[dev]) { | ||
2582 | snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n", | ||
2583 | patch[dev]); | ||
2584 | err = snd_hda_load_patch(chip->bus, patch[dev]); | ||
2585 | if (err < 0) | ||
2586 | goto out_free; | ||
2587 | } | ||
2588 | #endif | ||
2589 | if (!probe_only[dev]) { | ||
2590 | err = azx_codec_configure(chip); | ||
2591 | if (err < 0) | ||
2592 | goto out_free; | ||
2593 | } | ||
2538 | 2594 | ||
2539 | /* create PCM streams */ | 2595 | /* create PCM streams */ |
2540 | err = snd_hda_build_pcms(chip->bus); | 2596 | err = snd_hda_build_pcms(chip->bus); |
@@ -2546,8 +2602,6 @@ static int __devinit azx_probe(struct pci_dev *pci, | |||
2546 | if (err < 0) | 2602 | if (err < 0) |
2547 | goto out_free; | 2603 | goto out_free; |
2548 | 2604 | ||
2549 | snd_card_set_dev(card, &pci->dev); | ||
2550 | |||
2551 | err = snd_card_register(card); | 2605 | err = snd_card_register(card); |
2552 | if (err < 0) | 2606 | if (err < 0) |
2553 | goto out_free; | 2607 | goto out_free; |
@@ -2649,11 +2703,15 @@ static struct pci_device_id azx_ids[] = { | |||
2649 | /* this entry seems still valid -- i.e. without emu20kx chip */ | 2703 | /* this entry seems still valid -- i.e. without emu20kx chip */ |
2650 | { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, | 2704 | { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, |
2651 | #endif | 2705 | #endif |
2652 | /* AMD Generic, PCI class code and Vendor ID for HD Audio */ | 2706 | /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */ |
2653 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), | 2707 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), |
2654 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2708 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
2655 | .class_mask = 0xffffff, | 2709 | .class_mask = 0xffffff, |
2656 | .driver_data = AZX_DRIVER_GENERIC }, | 2710 | .driver_data = AZX_DRIVER_GENERIC }, |
2711 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID), | ||
2712 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | ||
2713 | .class_mask = 0xffffff, | ||
2714 | .driver_data = AZX_DRIVER_GENERIC }, | ||
2657 | { 0, } | 2715 | { 0, } |
2658 | }; | 2716 | }; |
2659 | MODULE_DEVICE_TABLE(pci, azx_ids); | 2717 | MODULE_DEVICE_TABLE(pci, azx_ids); |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 83349013b4d..fa57cb93b44 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 418c5d1bada..a721eb08a29 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 f2bb4803417..41ec0f865ee 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 019ca7cb56d..d08353d3bb7 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_cirrus.c b/sound/pci/hda/patch_cirrus.c new file mode 100644 index 00000000000..8ba306856d3 --- /dev/null +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -0,0 +1,1194 @@ | |||
1 | /* | ||
2 | * HD audio interface patch for Cirrus Logic CS420x chip | ||
3 | * | ||
4 | * Copyright (c) 2009 Takashi Iwai <tiwai@suse.de> | ||
5 | * | ||
6 | * This driver is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This driver is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/init.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <sound/core.h> | ||
26 | #include "hda_codec.h" | ||
27 | #include "hda_local.h" | ||
28 | |||
29 | /* | ||
30 | */ | ||
31 | |||
32 | struct cs_spec { | ||
33 | int board_config; | ||
34 | struct auto_pin_cfg autocfg; | ||
35 | struct hda_multi_out multiout; | ||
36 | struct snd_kcontrol *vmaster_sw; | ||
37 | struct snd_kcontrol *vmaster_vol; | ||
38 | |||
39 | hda_nid_t dac_nid[AUTO_CFG_MAX_OUTS]; | ||
40 | hda_nid_t slave_dig_outs[2]; | ||
41 | |||
42 | unsigned int input_idx[AUTO_PIN_LAST]; | ||
43 | unsigned int capsrc_idx[AUTO_PIN_LAST]; | ||
44 | hda_nid_t adc_nid[AUTO_PIN_LAST]; | ||
45 | unsigned int adc_idx[AUTO_PIN_LAST]; | ||
46 | unsigned int num_inputs; | ||
47 | unsigned int cur_input; | ||
48 | unsigned int automic_idx; | ||
49 | hda_nid_t cur_adc; | ||
50 | unsigned int cur_adc_stream_tag; | ||
51 | unsigned int cur_adc_format; | ||
52 | hda_nid_t dig_in; | ||
53 | |||
54 | struct hda_bind_ctls *capture_bind[2]; | ||
55 | |||
56 | unsigned int gpio_mask; | ||
57 | unsigned int gpio_dir; | ||
58 | unsigned int gpio_data; | ||
59 | |||
60 | struct hda_pcm pcm_rec[2]; /* PCM information */ | ||
61 | |||
62 | unsigned int hp_detect:1; | ||
63 | unsigned int mic_detect:1; | ||
64 | }; | ||
65 | |||
66 | /* available models */ | ||
67 | enum { | ||
68 | CS420X_MBP55, | ||
69 | CS420X_AUTO, | ||
70 | CS420X_MODELS | ||
71 | }; | ||
72 | |||
73 | /* Vendor-specific processing widget */ | ||
74 | #define CS420X_VENDOR_NID 0x11 | ||
75 | #define CS_DIG_OUT1_PIN_NID 0x10 | ||
76 | #define CS_DIG_OUT2_PIN_NID 0x15 | ||
77 | #define CS_DMIC1_PIN_NID 0x12 | ||
78 | #define CS_DMIC2_PIN_NID 0x0e | ||
79 | |||
80 | /* coef indices */ | ||
81 | #define IDX_SPDIF_STAT 0x0000 | ||
82 | #define IDX_SPDIF_CTL 0x0001 | ||
83 | #define IDX_ADC_CFG 0x0002 | ||
84 | /* SZC bitmask, 4 modes below: | ||
85 | * 0 = immediate, | ||
86 | * 1 = digital immediate, analog zero-cross | ||
87 | * 2 = digtail & analog soft-ramp | ||
88 | * 3 = digital soft-ramp, analog zero-cross | ||
89 | */ | ||
90 | #define CS_COEF_ADC_SZC_MASK (3 << 0) | ||
91 | #define CS_COEF_ADC_MIC_SZC_MODE (3 << 0) /* SZC setup for mic */ | ||
92 | #define CS_COEF_ADC_LI_SZC_MODE (3 << 0) /* SZC setup for line-in */ | ||
93 | /* PGA mode: 0 = differential, 1 = signle-ended */ | ||
94 | #define CS_COEF_ADC_MIC_PGA_MODE (1 << 5) /* PGA setup for mic */ | ||
95 | #define CS_COEF_ADC_LI_PGA_MODE (1 << 6) /* PGA setup for line-in */ | ||
96 | #define IDX_DAC_CFG 0x0003 | ||
97 | /* SZC bitmask, 4 modes below: | ||
98 | * 0 = Immediate | ||
99 | * 1 = zero-cross | ||
100 | * 2 = soft-ramp | ||
101 | * 3 = soft-ramp on zero-cross | ||
102 | */ | ||
103 | #define CS_COEF_DAC_HP_SZC_MODE (3 << 0) /* nid 0x02 */ | ||
104 | #define CS_COEF_DAC_LO_SZC_MODE (3 << 2) /* nid 0x03 */ | ||
105 | #define CS_COEF_DAC_SPK_SZC_MODE (3 << 4) /* nid 0x04 */ | ||
106 | |||
107 | #define IDX_BEEP_CFG 0x0004 | ||
108 | /* 0x0008 - test reg key */ | ||
109 | /* 0x0009 - 0x0014 -> 12 test regs */ | ||
110 | /* 0x0015 - visibility reg */ | ||
111 | |||
112 | |||
113 | static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx) | ||
114 | { | ||
115 | snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, | ||
116 | AC_VERB_SET_COEF_INDEX, idx); | ||
117 | return snd_hda_codec_read(codec, CS420X_VENDOR_NID, 0, | ||
118 | AC_VERB_GET_PROC_COEF, 0); | ||
119 | } | ||
120 | |||
121 | static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx, | ||
122 | unsigned int coef) | ||
123 | { | ||
124 | snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, | ||
125 | AC_VERB_SET_COEF_INDEX, idx); | ||
126 | snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, | ||
127 | AC_VERB_SET_PROC_COEF, coef); | ||
128 | } | ||
129 | |||
130 | |||
131 | #define HP_EVENT 1 | ||
132 | #define MIC_EVENT 2 | ||
133 | |||
134 | /* | ||
135 | * PCM callbacks | ||
136 | */ | ||
137 | static int cs_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
138 | struct hda_codec *codec, | ||
139 | struct snd_pcm_substream *substream) | ||
140 | { | ||
141 | struct cs_spec *spec = codec->spec; | ||
142 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
143 | hinfo); | ||
144 | } | ||
145 | |||
146 | static int cs_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
147 | struct hda_codec *codec, | ||
148 | unsigned int stream_tag, | ||
149 | unsigned int format, | ||
150 | struct snd_pcm_substream *substream) | ||
151 | { | ||
152 | struct cs_spec *spec = codec->spec; | ||
153 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | ||
154 | stream_tag, format, substream); | ||
155 | } | ||
156 | |||
157 | static int cs_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
158 | struct hda_codec *codec, | ||
159 | struct snd_pcm_substream *substream) | ||
160 | { | ||
161 | struct cs_spec *spec = codec->spec; | ||
162 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Digital out | ||
167 | */ | ||
168 | static int cs_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
169 | struct hda_codec *codec, | ||
170 | struct snd_pcm_substream *substream) | ||
171 | { | ||
172 | struct cs_spec *spec = codec->spec; | ||
173 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | ||
174 | } | ||
175 | |||
176 | static int cs_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
177 | struct hda_codec *codec, | ||
178 | struct snd_pcm_substream *substream) | ||
179 | { | ||
180 | struct cs_spec *spec = codec->spec; | ||
181 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | ||
182 | } | ||
183 | |||
184 | static int cs_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
185 | struct hda_codec *codec, | ||
186 | unsigned int stream_tag, | ||
187 | unsigned int format, | ||
188 | struct snd_pcm_substream *substream) | ||
189 | { | ||
190 | struct cs_spec *spec = codec->spec; | ||
191 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
192 | format, substream); | ||
193 | } | ||
194 | |||
195 | static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
196 | struct hda_codec *codec, | ||
197 | struct snd_pcm_substream *substream) | ||
198 | { | ||
199 | struct cs_spec *spec = codec->spec; | ||
200 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * Analog capture | ||
205 | */ | ||
206 | static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
207 | struct hda_codec *codec, | ||
208 | unsigned int stream_tag, | ||
209 | unsigned int format, | ||
210 | struct snd_pcm_substream *substream) | ||
211 | { | ||
212 | struct cs_spec *spec = codec->spec; | ||
213 | spec->cur_adc = spec->adc_nid[spec->cur_input]; | ||
214 | spec->cur_adc_stream_tag = stream_tag; | ||
215 | spec->cur_adc_format = format; | ||
216 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static int cs_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
221 | struct hda_codec *codec, | ||
222 | struct snd_pcm_substream *substream) | ||
223 | { | ||
224 | struct cs_spec *spec = codec->spec; | ||
225 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
226 | spec->cur_adc = 0; | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | /* | ||
231 | */ | ||
232 | static struct hda_pcm_stream cs_pcm_analog_playback = { | ||
233 | .substreams = 1, | ||
234 | .channels_min = 2, | ||
235 | .channels_max = 2, | ||
236 | .ops = { | ||
237 | .open = cs_playback_pcm_open, | ||
238 | .prepare = cs_playback_pcm_prepare, | ||
239 | .cleanup = cs_playback_pcm_cleanup | ||
240 | }, | ||
241 | }; | ||
242 | |||
243 | static struct hda_pcm_stream cs_pcm_analog_capture = { | ||
244 | .substreams = 1, | ||
245 | .channels_min = 2, | ||
246 | .channels_max = 2, | ||
247 | .ops = { | ||
248 | .prepare = cs_capture_pcm_prepare, | ||
249 | .cleanup = cs_capture_pcm_cleanup | ||
250 | }, | ||
251 | }; | ||
252 | |||
253 | static struct hda_pcm_stream cs_pcm_digital_playback = { | ||
254 | .substreams = 1, | ||
255 | .channels_min = 2, | ||
256 | .channels_max = 2, | ||
257 | .ops = { | ||
258 | .open = cs_dig_playback_pcm_open, | ||
259 | .close = cs_dig_playback_pcm_close, | ||
260 | .prepare = cs_dig_playback_pcm_prepare, | ||
261 | .cleanup = cs_dig_playback_pcm_cleanup | ||
262 | }, | ||
263 | }; | ||
264 | |||
265 | static struct hda_pcm_stream cs_pcm_digital_capture = { | ||
266 | .substreams = 1, | ||
267 | .channels_min = 2, | ||
268 | .channels_max = 2, | ||
269 | }; | ||
270 | |||
271 | static int cs_build_pcms(struct hda_codec *codec) | ||
272 | { | ||
273 | struct cs_spec *spec = codec->spec; | ||
274 | struct hda_pcm *info = spec->pcm_rec; | ||
275 | |||
276 | codec->pcm_info = info; | ||
277 | codec->num_pcms = 0; | ||
278 | |||
279 | info->name = "Cirrus Analog"; | ||
280 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cs_pcm_analog_playback; | ||
281 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dac_nid[0]; | ||
282 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | ||
283 | spec->multiout.max_channels; | ||
284 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture; | ||
285 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | ||
286 | spec->adc_nid[spec->cur_input]; | ||
287 | codec->num_pcms++; | ||
288 | |||
289 | if (!spec->multiout.dig_out_nid && !spec->dig_in) | ||
290 | return 0; | ||
291 | |||
292 | info++; | ||
293 | info->name = "Cirrus Digital"; | ||
294 | info->pcm_type = spec->autocfg.dig_out_type[0]; | ||
295 | if (!info->pcm_type) | ||
296 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | ||
297 | if (spec->multiout.dig_out_nid) { | ||
298 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | ||
299 | cs_pcm_digital_playback; | ||
300 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | ||
301 | spec->multiout.dig_out_nid; | ||
302 | } | ||
303 | if (spec->dig_in) { | ||
304 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
305 | cs_pcm_digital_capture; | ||
306 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in; | ||
307 | } | ||
308 | codec->num_pcms++; | ||
309 | |||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * parse codec topology | ||
315 | */ | ||
316 | |||
317 | static hda_nid_t get_dac(struct hda_codec *codec, hda_nid_t pin) | ||
318 | { | ||
319 | hda_nid_t dac; | ||
320 | if (!pin) | ||
321 | return 0; | ||
322 | if (snd_hda_get_connections(codec, pin, &dac, 1) != 1) | ||
323 | return 0; | ||
324 | return dac; | ||
325 | } | ||
326 | |||
327 | static int is_ext_mic(struct hda_codec *codec, unsigned int idx) | ||
328 | { | ||
329 | struct cs_spec *spec = codec->spec; | ||
330 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
331 | hda_nid_t pin = cfg->input_pins[idx]; | ||
332 | unsigned int val = snd_hda_query_pin_caps(codec, pin); | ||
333 | if (!(val & AC_PINCAP_PRES_DETECT)) | ||
334 | return 0; | ||
335 | val = snd_hda_codec_get_pincfg(codec, pin); | ||
336 | return (get_defcfg_connect(val) == AC_JACK_PORT_COMPLEX); | ||
337 | } | ||
338 | |||
339 | static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, | ||
340 | unsigned int *idxp) | ||
341 | { | ||
342 | int i; | ||
343 | hda_nid_t nid; | ||
344 | |||
345 | nid = codec->start_nid; | ||
346 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
347 | hda_nid_t pins[2]; | ||
348 | unsigned int type; | ||
349 | int j, nums; | ||
350 | type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) | ||
351 | >> AC_WCAP_TYPE_SHIFT; | ||
352 | if (type != AC_WID_AUD_IN) | ||
353 | continue; | ||
354 | nums = snd_hda_get_connections(codec, nid, pins, | ||
355 | ARRAY_SIZE(pins)); | ||
356 | if (nums <= 0) | ||
357 | continue; | ||
358 | for (j = 0; j < nums; j++) { | ||
359 | if (pins[j] == pin) { | ||
360 | *idxp = j; | ||
361 | return nid; | ||
362 | } | ||
363 | } | ||
364 | } | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static int is_active_pin(struct hda_codec *codec, hda_nid_t nid) | ||
369 | { | ||
370 | unsigned int val; | ||
371 | val = snd_hda_codec_get_pincfg(codec, nid); | ||
372 | return (get_defcfg_connect(val) != AC_JACK_PORT_NONE); | ||
373 | } | ||
374 | |||
375 | static int parse_output(struct hda_codec *codec) | ||
376 | { | ||
377 | struct cs_spec *spec = codec->spec; | ||
378 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
379 | int i, extra_nids; | ||
380 | hda_nid_t dac; | ||
381 | |||
382 | for (i = 0; i < cfg->line_outs; i++) { | ||
383 | dac = get_dac(codec, cfg->line_out_pins[i]); | ||
384 | if (!dac) | ||
385 | break; | ||
386 | spec->dac_nid[i] = dac; | ||
387 | } | ||
388 | spec->multiout.num_dacs = i; | ||
389 | spec->multiout.dac_nids = spec->dac_nid; | ||
390 | spec->multiout.max_channels = i * 2; | ||
391 | |||
392 | /* add HP and speakers */ | ||
393 | extra_nids = 0; | ||
394 | for (i = 0; i < cfg->hp_outs; i++) { | ||
395 | dac = get_dac(codec, cfg->hp_pins[i]); | ||
396 | if (!dac) | ||
397 | break; | ||
398 | if (!i) | ||
399 | spec->multiout.hp_nid = dac; | ||
400 | else | ||
401 | spec->multiout.extra_out_nid[extra_nids++] = dac; | ||
402 | } | ||
403 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
404 | dac = get_dac(codec, cfg->speaker_pins[i]); | ||
405 | if (!dac) | ||
406 | break; | ||
407 | spec->multiout.extra_out_nid[extra_nids++] = dac; | ||
408 | } | ||
409 | |||
410 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | ||
411 | cfg->speaker_outs = cfg->line_outs; | ||
412 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
413 | sizeof(cfg->speaker_pins)); | ||
414 | cfg->line_outs = 0; | ||
415 | } | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | static int parse_input(struct hda_codec *codec) | ||
421 | { | ||
422 | struct cs_spec *spec = codec->spec; | ||
423 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
424 | int i; | ||
425 | |||
426 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
427 | hda_nid_t pin = cfg->input_pins[i]; | ||
428 | if (!pin) | ||
429 | continue; | ||
430 | spec->input_idx[spec->num_inputs] = i; | ||
431 | spec->capsrc_idx[i] = spec->num_inputs++; | ||
432 | spec->cur_input = i; | ||
433 | spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]); | ||
434 | } | ||
435 | if (!spec->num_inputs) | ||
436 | return 0; | ||
437 | |||
438 | /* check whether the automatic mic switch is available */ | ||
439 | if (spec->num_inputs == 2 && | ||
440 | spec->adc_nid[AUTO_PIN_MIC] && spec->adc_nid[AUTO_PIN_FRONT_MIC]) { | ||
441 | if (is_ext_mic(codec, cfg->input_pins[AUTO_PIN_FRONT_MIC])) { | ||
442 | if (!is_ext_mic(codec, cfg->input_pins[AUTO_PIN_MIC])) { | ||
443 | spec->mic_detect = 1; | ||
444 | spec->automic_idx = AUTO_PIN_FRONT_MIC; | ||
445 | } | ||
446 | } else { | ||
447 | if (is_ext_mic(codec, cfg->input_pins[AUTO_PIN_MIC])) { | ||
448 | spec->mic_detect = 1; | ||
449 | spec->automic_idx = AUTO_PIN_MIC; | ||
450 | } | ||
451 | } | ||
452 | } | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | |||
457 | static int parse_digital_output(struct hda_codec *codec) | ||
458 | { | ||
459 | struct cs_spec *spec = codec->spec; | ||
460 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
461 | hda_nid_t nid; | ||
462 | |||
463 | if (!cfg->dig_outs) | ||
464 | return 0; | ||
465 | if (snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) < 1) | ||
466 | return 0; | ||
467 | spec->multiout.dig_out_nid = nid; | ||
468 | spec->multiout.share_spdif = 1; | ||
469 | if (cfg->dig_outs > 1 && | ||
470 | snd_hda_get_connections(codec, cfg->dig_out_pins[1], &nid, 1) > 0) { | ||
471 | spec->slave_dig_outs[0] = nid; | ||
472 | codec->slave_dig_outs = spec->slave_dig_outs; | ||
473 | } | ||
474 | return 0; | ||
475 | } | ||
476 | |||
477 | static int parse_digital_input(struct hda_codec *codec) | ||
478 | { | ||
479 | struct cs_spec *spec = codec->spec; | ||
480 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
481 | int idx; | ||
482 | |||
483 | if (cfg->dig_in_pin) | ||
484 | spec->dig_in = get_adc(codec, cfg->dig_in_pin, &idx); | ||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | /* | ||
489 | * create mixer controls | ||
490 | */ | ||
491 | |||
492 | static const char *dir_sfx[2] = { "Playback", "Capture" }; | ||
493 | |||
494 | static int add_mute(struct hda_codec *codec, const char *name, int index, | ||
495 | unsigned int pval, int dir, struct snd_kcontrol **kctlp) | ||
496 | { | ||
497 | char tmp[44]; | ||
498 | struct snd_kcontrol_new knew = | ||
499 | HDA_CODEC_MUTE_IDX(tmp, index, 0, 0, HDA_OUTPUT); | ||
500 | knew.private_value = pval; | ||
501 | snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); | ||
502 | *kctlp = snd_ctl_new1(&knew, codec); | ||
503 | return snd_hda_ctl_add(codec, *kctlp); | ||
504 | } | ||
505 | |||
506 | static int add_volume(struct hda_codec *codec, const char *name, | ||
507 | int index, unsigned int pval, int dir, | ||
508 | struct snd_kcontrol **kctlp) | ||
509 | { | ||
510 | char tmp[32]; | ||
511 | struct snd_kcontrol_new knew = | ||
512 | HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT); | ||
513 | knew.private_value = pval; | ||
514 | snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]); | ||
515 | *kctlp = snd_ctl_new1(&knew, codec); | ||
516 | return snd_hda_ctl_add(codec, *kctlp); | ||
517 | } | ||
518 | |||
519 | static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) | ||
520 | { | ||
521 | unsigned int caps; | ||
522 | |||
523 | /* set the upper-limit for mixer amp to 0dB */ | ||
524 | caps = query_amp_caps(codec, dac, HDA_OUTPUT); | ||
525 | caps &= ~(0x7f << AC_AMPCAP_NUM_STEPS_SHIFT); | ||
526 | caps |= ((caps >> AC_AMPCAP_OFFSET_SHIFT) & 0x7f) | ||
527 | << AC_AMPCAP_NUM_STEPS_SHIFT; | ||
528 | snd_hda_override_amp_caps(codec, dac, HDA_OUTPUT, caps); | ||
529 | } | ||
530 | |||
531 | static int add_vmaster(struct hda_codec *codec, hda_nid_t dac) | ||
532 | { | ||
533 | struct cs_spec *spec = codec->spec; | ||
534 | unsigned int tlv[4]; | ||
535 | int err; | ||
536 | |||
537 | spec->vmaster_sw = | ||
538 | snd_ctl_make_virtual_master("Master Playback Switch", NULL); | ||
539 | err = snd_hda_ctl_add(codec, spec->vmaster_sw); | ||
540 | if (err < 0) | ||
541 | return err; | ||
542 | |||
543 | snd_hda_set_vmaster_tlv(codec, dac, HDA_OUTPUT, tlv); | ||
544 | spec->vmaster_vol = | ||
545 | snd_ctl_make_virtual_master("Master Playback Volume", tlv); | ||
546 | err = snd_hda_ctl_add(codec, spec->vmaster_vol); | ||
547 | if (err < 0) | ||
548 | return err; | ||
549 | return 0; | ||
550 | } | ||
551 | |||
552 | static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx, | ||
553 | int num_ctls, int type) | ||
554 | { | ||
555 | struct cs_spec *spec = codec->spec; | ||
556 | const char *name; | ||
557 | int err, index; | ||
558 | struct snd_kcontrol *kctl; | ||
559 | static char *speakers[] = { | ||
560 | "Front Speaker", "Surround Speaker", "Bass Speaker" | ||
561 | }; | ||
562 | static char *line_outs[] = { | ||
563 | "Front Line-Out", "Surround Line-Out", "Bass Line-Out" | ||
564 | }; | ||
565 | |||
566 | fix_volume_caps(codec, dac); | ||
567 | if (!spec->vmaster_sw) { | ||
568 | err = add_vmaster(codec, dac); | ||
569 | if (err < 0) | ||
570 | return err; | ||
571 | } | ||
572 | |||
573 | index = 0; | ||
574 | switch (type) { | ||
575 | case AUTO_PIN_HP_OUT: | ||
576 | name = "Headphone"; | ||
577 | index = idx; | ||
578 | break; | ||
579 | case AUTO_PIN_SPEAKER_OUT: | ||
580 | if (num_ctls > 1) | ||
581 | name = speakers[idx]; | ||
582 | else | ||
583 | name = "Speaker"; | ||
584 | break; | ||
585 | default: | ||
586 | if (num_ctls > 1) | ||
587 | name = line_outs[idx]; | ||
588 | else | ||
589 | name = "Line-Out"; | ||
590 | break; | ||
591 | } | ||
592 | |||
593 | err = add_mute(codec, name, index, | ||
594 | HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl); | ||
595 | if (err < 0) | ||
596 | return err; | ||
597 | err = snd_ctl_add_slave(spec->vmaster_sw, kctl); | ||
598 | if (err < 0) | ||
599 | return err; | ||
600 | |||
601 | err = add_volume(codec, name, index, | ||
602 | HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl); | ||
603 | if (err < 0) | ||
604 | return err; | ||
605 | err = snd_ctl_add_slave(spec->vmaster_vol, kctl); | ||
606 | if (err < 0) | ||
607 | return err; | ||
608 | |||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | static int build_output(struct hda_codec *codec) | ||
613 | { | ||
614 | struct cs_spec *spec = codec->spec; | ||
615 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
616 | int i, err; | ||
617 | |||
618 | for (i = 0; i < cfg->line_outs; i++) { | ||
619 | err = add_output(codec, get_dac(codec, cfg->line_out_pins[i]), | ||
620 | i, cfg->line_outs, cfg->line_out_type); | ||
621 | if (err < 0) | ||
622 | return err; | ||
623 | } | ||
624 | for (i = 0; i < cfg->hp_outs; i++) { | ||
625 | err = add_output(codec, get_dac(codec, cfg->hp_pins[i]), | ||
626 | i, cfg->hp_outs, AUTO_PIN_HP_OUT); | ||
627 | if (err < 0) | ||
628 | return err; | ||
629 | } | ||
630 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
631 | err = add_output(codec, get_dac(codec, cfg->speaker_pins[i]), | ||
632 | i, cfg->speaker_outs, AUTO_PIN_SPEAKER_OUT); | ||
633 | if (err < 0) | ||
634 | return err; | ||
635 | } | ||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | /* | ||
640 | */ | ||
641 | |||
642 | static struct snd_kcontrol_new cs_capture_ctls[] = { | ||
643 | HDA_BIND_SW("Capture Switch", 0), | ||
644 | HDA_BIND_VOL("Capture Volume", 0), | ||
645 | }; | ||
646 | |||
647 | static int change_cur_input(struct hda_codec *codec, unsigned int idx, | ||
648 | int force) | ||
649 | { | ||
650 | struct cs_spec *spec = codec->spec; | ||
651 | |||
652 | if (spec->cur_input == idx && !force) | ||
653 | return 0; | ||
654 | if (spec->cur_adc && spec->cur_adc != spec->adc_nid[idx]) { | ||
655 | /* stream is running, let's swap the current ADC */ | ||
656 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
657 | spec->cur_adc = spec->adc_nid[idx]; | ||
658 | snd_hda_codec_setup_stream(codec, spec->cur_adc, | ||
659 | spec->cur_adc_stream_tag, 0, | ||
660 | spec->cur_adc_format); | ||
661 | } | ||
662 | snd_hda_codec_write(codec, spec->cur_adc, 0, | ||
663 | AC_VERB_SET_CONNECT_SEL, | ||
664 | spec->adc_idx[idx]); | ||
665 | spec->cur_input = idx; | ||
666 | return 1; | ||
667 | } | ||
668 | |||
669 | static int cs_capture_source_info(struct snd_kcontrol *kcontrol, | ||
670 | struct snd_ctl_elem_info *uinfo) | ||
671 | { | ||
672 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
673 | struct cs_spec *spec = codec->spec; | ||
674 | unsigned int idx; | ||
675 | |||
676 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
677 | uinfo->count = 1; | ||
678 | uinfo->value.enumerated.items = spec->num_inputs; | ||
679 | if (uinfo->value.enumerated.item >= spec->num_inputs) | ||
680 | uinfo->value.enumerated.item = spec->num_inputs - 1; | ||
681 | idx = spec->input_idx[uinfo->value.enumerated.item]; | ||
682 | strcpy(uinfo->value.enumerated.name, auto_pin_cfg_labels[idx]); | ||
683 | return 0; | ||
684 | } | ||
685 | |||
686 | static int cs_capture_source_get(struct snd_kcontrol *kcontrol, | ||
687 | struct snd_ctl_elem_value *ucontrol) | ||
688 | { | ||
689 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
690 | struct cs_spec *spec = codec->spec; | ||
691 | ucontrol->value.enumerated.item[0] = spec->capsrc_idx[spec->cur_input]; | ||
692 | return 0; | ||
693 | } | ||
694 | |||
695 | static int cs_capture_source_put(struct snd_kcontrol *kcontrol, | ||
696 | struct snd_ctl_elem_value *ucontrol) | ||
697 | { | ||
698 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
699 | struct cs_spec *spec = codec->spec; | ||
700 | unsigned int idx = ucontrol->value.enumerated.item[0]; | ||
701 | |||
702 | if (idx >= spec->num_inputs) | ||
703 | return -EINVAL; | ||
704 | idx = spec->input_idx[idx]; | ||
705 | return change_cur_input(codec, idx, 0); | ||
706 | } | ||
707 | |||
708 | static struct snd_kcontrol_new cs_capture_source = { | ||
709 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
710 | .name = "Capture Source", | ||
711 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
712 | .info = cs_capture_source_info, | ||
713 | .get = cs_capture_source_get, | ||
714 | .put = cs_capture_source_put, | ||
715 | }; | ||
716 | |||
717 | static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec, | ||
718 | struct hda_ctl_ops *ops) | ||
719 | { | ||
720 | struct cs_spec *spec = codec->spec; | ||
721 | struct hda_bind_ctls *bind; | ||
722 | int i, n; | ||
723 | |||
724 | bind = kzalloc(sizeof(*bind) + sizeof(long) * (spec->num_inputs + 1), | ||
725 | GFP_KERNEL); | ||
726 | if (!bind) | ||
727 | return NULL; | ||
728 | bind->ops = ops; | ||
729 | n = 0; | ||
730 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
731 | if (!spec->adc_nid[i]) | ||
732 | continue; | ||
733 | bind->values[n++] = | ||
734 | HDA_COMPOSE_AMP_VAL(spec->adc_nid[i], 3, | ||
735 | spec->adc_idx[i], HDA_INPUT); | ||
736 | } | ||
737 | return bind; | ||
738 | } | ||
739 | |||
740 | static int build_input(struct hda_codec *codec) | ||
741 | { | ||
742 | struct cs_spec *spec = codec->spec; | ||
743 | int i, err; | ||
744 | |||
745 | if (!spec->num_inputs) | ||
746 | return 0; | ||
747 | |||
748 | /* make bind-capture */ | ||
749 | spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw); | ||
750 | spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); | ||
751 | for (i = 0; i < 2; i++) { | ||
752 | struct snd_kcontrol *kctl; | ||
753 | if (!spec->capture_bind[i]) | ||
754 | return -ENOMEM; | ||
755 | kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); | ||
756 | if (!kctl) | ||
757 | return -ENOMEM; | ||
758 | kctl->private_value = (long)spec->capture_bind[i]; | ||
759 | err = snd_hda_ctl_add(codec, kctl); | ||
760 | if (err < 0) | ||
761 | return err; | ||
762 | } | ||
763 | |||
764 | if (spec->num_inputs > 1 && !spec->mic_detect) { | ||
765 | err = snd_hda_ctl_add(codec, | ||
766 | snd_ctl_new1(&cs_capture_source, codec)); | ||
767 | if (err < 0) | ||
768 | return err; | ||
769 | } | ||
770 | |||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | /* | ||
775 | */ | ||
776 | |||
777 | static int build_digital_output(struct hda_codec *codec) | ||
778 | { | ||
779 | struct cs_spec *spec = codec->spec; | ||
780 | int err; | ||
781 | |||
782 | if (!spec->multiout.dig_out_nid) | ||
783 | return 0; | ||
784 | |||
785 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); | ||
786 | if (err < 0) | ||
787 | return err; | ||
788 | err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); | ||
789 | if (err < 0) | ||
790 | return err; | ||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | static int build_digital_input(struct hda_codec *codec) | ||
795 | { | ||
796 | struct cs_spec *spec = codec->spec; | ||
797 | if (spec->dig_in) | ||
798 | return snd_hda_create_spdif_in_ctls(codec, spec->dig_in); | ||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | /* | ||
803 | * auto-mute and auto-mic switching | ||
804 | */ | ||
805 | |||
806 | static void cs_automute(struct hda_codec *codec) | ||
807 | { | ||
808 | struct cs_spec *spec = codec->spec; | ||
809 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
810 | unsigned int caps, present, hp_present; | ||
811 | hda_nid_t nid; | ||
812 | int i; | ||
813 | |||
814 | hp_present = 0; | ||
815 | for (i = 0; i < cfg->hp_outs; i++) { | ||
816 | nid = cfg->hp_pins[i]; | ||
817 | caps = snd_hda_query_pin_caps(codec, nid); | ||
818 | if (!(caps & AC_PINCAP_PRES_DETECT)) | ||
819 | continue; | ||
820 | if (caps & AC_PINCAP_TRIG_REQ) | ||
821 | snd_hda_codec_read(codec, nid, 0, | ||
822 | AC_VERB_SET_PIN_SENSE, 0); | ||
823 | present = snd_hda_codec_read(codec, nid, 0, | ||
824 | AC_VERB_GET_PIN_SENSE, 0); | ||
825 | hp_present |= (present & AC_PINSENSE_PRESENCE) != 0; | ||
826 | if (hp_present) | ||
827 | break; | ||
828 | } | ||
829 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
830 | nid = cfg->speaker_pins[i]; | ||
831 | snd_hda_codec_write(codec, nid, 0, | ||
832 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
833 | hp_present ? 0 : PIN_OUT); | ||
834 | } | ||
835 | if (spec->board_config == CS420X_MBP55) { | ||
836 | unsigned int gpio = hp_present ? 0x02 : 0x08; | ||
837 | snd_hda_codec_write(codec, 0x01, 0, | ||
838 | AC_VERB_SET_GPIO_DATA, gpio); | ||
839 | } | ||
840 | } | ||
841 | |||
842 | static void cs_automic(struct hda_codec *codec) | ||
843 | { | ||
844 | struct cs_spec *spec = codec->spec; | ||
845 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
846 | hda_nid_t nid; | ||
847 | unsigned int caps, present; | ||
848 | |||
849 | nid = cfg->input_pins[spec->automic_idx]; | ||
850 | caps = snd_hda_query_pin_caps(codec, nid); | ||
851 | if (caps & AC_PINCAP_TRIG_REQ) | ||
852 | snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
853 | present = snd_hda_codec_read(codec, nid, 0, | ||
854 | AC_VERB_GET_PIN_SENSE, 0); | ||
855 | if (present & AC_PINSENSE_PRESENCE) | ||
856 | change_cur_input(codec, spec->automic_idx, 0); | ||
857 | else { | ||
858 | unsigned int imic = (spec->automic_idx == AUTO_PIN_MIC) ? | ||
859 | AUTO_PIN_FRONT_MIC : AUTO_PIN_MIC; | ||
860 | change_cur_input(codec, imic, 0); | ||
861 | } | ||
862 | } | ||
863 | |||
864 | /* | ||
865 | */ | ||
866 | |||
867 | static void init_output(struct hda_codec *codec) | ||
868 | { | ||
869 | struct cs_spec *spec = codec->spec; | ||
870 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
871 | int i; | ||
872 | |||
873 | /* mute first */ | ||
874 | for (i = 0; i < spec->multiout.num_dacs; i++) | ||
875 | snd_hda_codec_write(codec, spec->multiout.dac_nids[i], 0, | ||
876 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
877 | if (spec->multiout.hp_nid) | ||
878 | snd_hda_codec_write(codec, spec->multiout.hp_nid, 0, | ||
879 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
880 | for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) { | ||
881 | if (!spec->multiout.extra_out_nid[i]) | ||
882 | break; | ||
883 | snd_hda_codec_write(codec, spec->multiout.extra_out_nid[i], 0, | ||
884 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
885 | } | ||
886 | |||
887 | /* set appropriate pin controls */ | ||
888 | for (i = 0; i < cfg->line_outs; i++) | ||
889 | snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, | ||
890 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
891 | for (i = 0; i < cfg->hp_outs; i++) { | ||
892 | hda_nid_t nid = cfg->hp_pins[i]; | ||
893 | snd_hda_codec_write(codec, nid, 0, | ||
894 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); | ||
895 | if (!cfg->speaker_outs) | ||
896 | continue; | ||
897 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { | ||
898 | snd_hda_codec_write(codec, nid, 0, | ||
899 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
900 | AC_USRSP_EN | HP_EVENT); | ||
901 | spec->hp_detect = 1; | ||
902 | } | ||
903 | } | ||
904 | for (i = 0; i < cfg->speaker_outs; i++) | ||
905 | snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, | ||
906 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
907 | if (spec->hp_detect) | ||
908 | cs_automute(codec); | ||
909 | } | ||
910 | |||
911 | static void init_input(struct hda_codec *codec) | ||
912 | { | ||
913 | struct cs_spec *spec = codec->spec; | ||
914 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
915 | unsigned int coef; | ||
916 | int i; | ||
917 | |||
918 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
919 | unsigned int ctl; | ||
920 | hda_nid_t pin = cfg->input_pins[i]; | ||
921 | if (!pin || !spec->adc_nid[i]) | ||
922 | continue; | ||
923 | /* set appropriate pin control and mute first */ | ||
924 | ctl = PIN_IN; | ||
925 | if (i <= AUTO_PIN_FRONT_MIC) { | ||
926 | unsigned int caps = snd_hda_query_pin_caps(codec, pin); | ||
927 | caps >>= AC_PINCAP_VREF_SHIFT; | ||
928 | if (caps & AC_PINCAP_VREF_80) | ||
929 | ctl = PIN_VREF80; | ||
930 | } | ||
931 | snd_hda_codec_write(codec, pin, 0, | ||
932 | AC_VERB_SET_PIN_WIDGET_CONTROL, ctl); | ||
933 | snd_hda_codec_write(codec, spec->adc_nid[i], 0, | ||
934 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
935 | AMP_IN_MUTE(spec->adc_idx[i])); | ||
936 | if (spec->mic_detect && spec->automic_idx == i) | ||
937 | snd_hda_codec_write(codec, pin, 0, | ||
938 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
939 | AC_USRSP_EN | MIC_EVENT); | ||
940 | } | ||
941 | change_cur_input(codec, spec->cur_input, 1); | ||
942 | if (spec->mic_detect) | ||
943 | cs_automic(codec); | ||
944 | |||
945 | coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ | ||
946 | if (is_active_pin(codec, CS_DMIC2_PIN_NID)) | ||
947 | coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */ | ||
948 | if (is_active_pin(codec, CS_DMIC1_PIN_NID)) | ||
949 | coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0 | ||
950 | * No effect if SPDIF_OUT2 is slected in | ||
951 | * IDX_SPDIF_CTL. | ||
952 | */ | ||
953 | cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); | ||
954 | } | ||
955 | |||
956 | static struct hda_verb cs_coef_init_verbs[] = { | ||
957 | {0x11, AC_VERB_SET_PROC_STATE, 1}, | ||
958 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, | ||
959 | {0x11, AC_VERB_SET_PROC_COEF, | ||
960 | (0x002a /* DAC1/2/3 SZCMode Soft Ramp */ | ||
961 | | 0x0040 /* Mute DACs on FIFO error */ | ||
962 | | 0x1000 /* Enable DACs High Pass Filter */ | ||
963 | | 0x0400 /* Disable Coefficient Auto increment */ | ||
964 | )}, | ||
965 | /* Beep */ | ||
966 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, | ||
967 | {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ | ||
968 | |||
969 | {} /* terminator */ | ||
970 | }; | ||
971 | |||
972 | /* SPDIF setup */ | ||
973 | static void init_digital(struct hda_codec *codec) | ||
974 | { | ||
975 | unsigned int coef; | ||
976 | |||
977 | coef = 0x0002; /* SRC_MUTE soft-mute on SPDIF (if no lock) */ | ||
978 | coef |= 0x0008; /* Replace with mute on error */ | ||
979 | if (is_active_pin(codec, CS_DIG_OUT2_PIN_NID)) | ||
980 | coef |= 0x4000; /* RX to TX1 or TX2 Loopthru / SPDIF2 | ||
981 | * SPDIF_OUT2 is shared with GPIO1 and | ||
982 | * DMIC_SDA2. | ||
983 | */ | ||
984 | cs_vendor_coef_set(codec, IDX_SPDIF_CTL, coef); | ||
985 | } | ||
986 | |||
987 | static int cs_init(struct hda_codec *codec) | ||
988 | { | ||
989 | struct cs_spec *spec = codec->spec; | ||
990 | |||
991 | snd_hda_sequence_write(codec, cs_coef_init_verbs); | ||
992 | |||
993 | if (spec->gpio_mask) { | ||
994 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, | ||
995 | spec->gpio_mask); | ||
996 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, | ||
997 | spec->gpio_dir); | ||
998 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
999 | spec->gpio_data); | ||
1000 | } | ||
1001 | |||
1002 | init_output(codec); | ||
1003 | init_input(codec); | ||
1004 | init_digital(codec); | ||
1005 | return 0; | ||
1006 | } | ||
1007 | |||
1008 | static int cs_build_controls(struct hda_codec *codec) | ||
1009 | { | ||
1010 | int err; | ||
1011 | |||
1012 | err = build_output(codec); | ||
1013 | if (err < 0) | ||
1014 | return err; | ||
1015 | err = build_input(codec); | ||
1016 | if (err < 0) | ||
1017 | return err; | ||
1018 | err = build_digital_output(codec); | ||
1019 | if (err < 0) | ||
1020 | return err; | ||
1021 | err = build_digital_input(codec); | ||
1022 | if (err < 0) | ||
1023 | return err; | ||
1024 | return cs_init(codec); | ||
1025 | } | ||
1026 | |||
1027 | static void cs_free(struct hda_codec *codec) | ||
1028 | { | ||
1029 | struct cs_spec *spec = codec->spec; | ||
1030 | kfree(spec->capture_bind[0]); | ||
1031 | kfree(spec->capture_bind[1]); | ||
1032 | kfree(codec->spec); | ||
1033 | } | ||
1034 | |||
1035 | static void cs_unsol_event(struct hda_codec *codec, unsigned int res) | ||
1036 | { | ||
1037 | switch ((res >> 26) & 0x7f) { | ||
1038 | case HP_EVENT: | ||
1039 | cs_automute(codec); | ||
1040 | break; | ||
1041 | case MIC_EVENT: | ||
1042 | cs_automic(codec); | ||
1043 | break; | ||
1044 | } | ||
1045 | } | ||
1046 | |||
1047 | static struct hda_codec_ops cs_patch_ops = { | ||
1048 | .build_controls = cs_build_controls, | ||
1049 | .build_pcms = cs_build_pcms, | ||
1050 | .init = cs_init, | ||
1051 | .free = cs_free, | ||
1052 | .unsol_event = cs_unsol_event, | ||
1053 | }; | ||
1054 | |||
1055 | static int cs_parse_auto_config(struct hda_codec *codec) | ||
1056 | { | ||
1057 | struct cs_spec *spec = codec->spec; | ||
1058 | int err; | ||
1059 | |||
1060 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); | ||
1061 | if (err < 0) | ||
1062 | return err; | ||
1063 | |||
1064 | err = parse_output(codec); | ||
1065 | if (err < 0) | ||
1066 | return err; | ||
1067 | err = parse_input(codec); | ||
1068 | if (err < 0) | ||
1069 | return err; | ||
1070 | err = parse_digital_output(codec); | ||
1071 | if (err < 0) | ||
1072 | return err; | ||
1073 | err = parse_digital_input(codec); | ||
1074 | if (err < 0) | ||
1075 | return err; | ||
1076 | return 0; | ||
1077 | } | ||
1078 | |||
1079 | static const char *cs420x_models[CS420X_MODELS] = { | ||
1080 | [CS420X_MBP55] = "mbp55", | ||
1081 | [CS420X_AUTO] = "auto", | ||
1082 | }; | ||
1083 | |||
1084 | |||
1085 | static struct snd_pci_quirk cs420x_cfg_tbl[] = { | ||
1086 | SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), | ||
1087 | {} /* terminator */ | ||
1088 | }; | ||
1089 | |||
1090 | struct cs_pincfg { | ||
1091 | hda_nid_t nid; | ||
1092 | u32 val; | ||
1093 | }; | ||
1094 | |||
1095 | static struct cs_pincfg mbp55_pincfgs[] = { | ||
1096 | { 0x09, 0x012b4030 }, | ||
1097 | { 0x0a, 0x90100121 }, | ||
1098 | { 0x0b, 0x90100120 }, | ||
1099 | { 0x0c, 0x400000f0 }, | ||
1100 | { 0x0d, 0x90a00110 }, | ||
1101 | { 0x0e, 0x400000f0 }, | ||
1102 | { 0x0f, 0x400000f0 }, | ||
1103 | { 0x10, 0x014be040 }, | ||
1104 | { 0x12, 0x400000f0 }, | ||
1105 | { 0x15, 0x400000f0 }, | ||
1106 | {} /* terminator */ | ||
1107 | }; | ||
1108 | |||
1109 | static struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = { | ||
1110 | [CS420X_MBP55] = mbp55_pincfgs, | ||
1111 | }; | ||
1112 | |||
1113 | static void fix_pincfg(struct hda_codec *codec, int model) | ||
1114 | { | ||
1115 | const struct cs_pincfg *cfg = cs_pincfgs[model]; | ||
1116 | if (!cfg) | ||
1117 | return; | ||
1118 | for (; cfg->nid; cfg++) | ||
1119 | snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); | ||
1120 | } | ||
1121 | |||
1122 | |||
1123 | static int patch_cs420x(struct hda_codec *codec) | ||
1124 | { | ||
1125 | struct cs_spec *spec; | ||
1126 | int err; | ||
1127 | |||
1128 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
1129 | if (!spec) | ||
1130 | return -ENOMEM; | ||
1131 | codec->spec = spec; | ||
1132 | |||
1133 | spec->board_config = | ||
1134 | snd_hda_check_board_config(codec, CS420X_MODELS, | ||
1135 | cs420x_models, cs420x_cfg_tbl); | ||
1136 | if (spec->board_config >= 0) | ||
1137 | fix_pincfg(codec, spec->board_config); | ||
1138 | |||
1139 | switch (spec->board_config) { | ||
1140 | case CS420X_MBP55: | ||
1141 | /* GPIO1 = headphones */ | ||
1142 | /* GPIO3 = speakers */ | ||
1143 | spec->gpio_mask = 0x0a; | ||
1144 | spec->gpio_dir = 0x0a; | ||
1145 | break; | ||
1146 | } | ||
1147 | |||
1148 | err = cs_parse_auto_config(codec); | ||
1149 | if (err < 0) | ||
1150 | goto error; | ||
1151 | |||
1152 | codec->patch_ops = cs_patch_ops; | ||
1153 | |||
1154 | return 0; | ||
1155 | |||
1156 | error: | ||
1157 | kfree(codec->spec); | ||
1158 | codec->spec = NULL; | ||
1159 | return err; | ||
1160 | } | ||
1161 | |||
1162 | |||
1163 | /* | ||
1164 | * patch entries | ||
1165 | */ | ||
1166 | static struct hda_codec_preset snd_hda_preset_cirrus[] = { | ||
1167 | { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, | ||
1168 | { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, | ||
1169 | {} /* terminator */ | ||
1170 | }; | ||
1171 | |||
1172 | MODULE_ALIAS("snd-hda-codec-id:10134206"); | ||
1173 | MODULE_ALIAS("snd-hda-codec-id:10134207"); | ||
1174 | |||
1175 | MODULE_LICENSE("GPL"); | ||
1176 | MODULE_DESCRIPTION("Cirrus Logic HD-audio codec"); | ||
1177 | |||
1178 | static struct hda_codec_preset_list cirrus_list = { | ||
1179 | .preset = snd_hda_preset_cirrus, | ||
1180 | .owner = THIS_MODULE, | ||
1181 | }; | ||
1182 | |||
1183 | static int __init patch_cirrus_init(void) | ||
1184 | { | ||
1185 | return snd_hda_add_codec_preset(&cirrus_list); | ||
1186 | } | ||
1187 | |||
1188 | static void __exit patch_cirrus_exit(void) | ||
1189 | { | ||
1190 | snd_hda_delete_codec_preset(&cirrus_list); | ||
1191 | } | ||
1192 | |||
1193 | module_init(patch_cirrus_init) | ||
1194 | module_exit(patch_cirrus_exit) | ||
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index c921264bbd7..780e1a72114 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 ac868c59f9e..9d899eda44d 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 fcc77fec448..01a18ed475a 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
@@ -33,8 +33,8 @@ | |||
33 | #include "hda_codec.h" | 33 | #include "hda_codec.h" |
34 | #include "hda_local.h" | 34 | #include "hda_local.h" |
35 | 35 | ||
36 | #define CVT_NID 0x02 /* audio converter */ | 36 | static hda_nid_t cvt_nid; /* audio converter */ |
37 | #define PIN_NID 0x03 /* HDMI output pin */ | 37 | static hda_nid_t pin_nid; /* HDMI output pin */ |
38 | 38 | ||
39 | #define INTEL_HDMI_EVENT_TAG 0x08 | 39 | #define INTEL_HDMI_EVENT_TAG 0x08 |
40 | 40 | ||
@@ -44,30 +44,6 @@ struct intel_hdmi_spec { | |||
44 | struct hdmi_eld sink_eld; | 44 | struct hdmi_eld sink_eld; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static struct hda_verb pinout_enable_verb[] = { | ||
48 | {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
49 | {} /* terminator */ | ||
50 | }; | ||
51 | |||
52 | static struct hda_verb unsolicited_response_verb[] = { | ||
53 | {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | | ||
54 | INTEL_HDMI_EVENT_TAG}, | ||
55 | {} | ||
56 | }; | ||
57 | |||
58 | static struct hda_verb def_chan_map[] = { | ||
59 | {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x00}, | ||
60 | {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x11}, | ||
61 | {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x22}, | ||
62 | {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x33}, | ||
63 | {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x44}, | ||
64 | {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x55}, | ||
65 | {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x66}, | ||
66 | {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x77}, | ||
67 | {} | ||
68 | }; | ||
69 | |||
70 | |||
71 | struct hdmi_audio_infoframe { | 47 | struct hdmi_audio_infoframe { |
72 | u8 type; /* 0x84 */ | 48 | u8 type; /* 0x84 */ |
73 | u8 ver; /* 0x01 */ | 49 | u8 ver; /* 0x01 */ |
@@ -244,11 +220,12 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid, | |||
244 | static void hdmi_enable_output(struct hda_codec *codec) | 220 | static void hdmi_enable_output(struct hda_codec *codec) |
245 | { | 221 | { |
246 | /* Unmute */ | 222 | /* Unmute */ |
247 | if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) | 223 | if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP) |
248 | snd_hda_codec_write(codec, PIN_NID, 0, | 224 | snd_hda_codec_write(codec, pin_nid, 0, |
249 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 225 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); |
250 | /* Enable pin out */ | 226 | /* Enable pin out */ |
251 | snd_hda_sequence_write(codec, pinout_enable_verb); | 227 | snd_hda_codec_write(codec, pin_nid, 0, |
228 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
252 | } | 229 | } |
253 | 230 | ||
254 | /* | 231 | /* |
@@ -256,8 +233,8 @@ static void hdmi_enable_output(struct hda_codec *codec) | |||
256 | */ | 233 | */ |
257 | static void hdmi_start_infoframe_trans(struct hda_codec *codec) | 234 | static void hdmi_start_infoframe_trans(struct hda_codec *codec) |
258 | { | 235 | { |
259 | hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); | 236 | hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0); |
260 | snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, | 237 | snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT, |
261 | AC_DIPXMIT_BEST); | 238 | AC_DIPXMIT_BEST); |
262 | } | 239 | } |
263 | 240 | ||
@@ -266,20 +243,20 @@ static void hdmi_start_infoframe_trans(struct hda_codec *codec) | |||
266 | */ | 243 | */ |
267 | static void hdmi_stop_infoframe_trans(struct hda_codec *codec) | 244 | static void hdmi_stop_infoframe_trans(struct hda_codec *codec) |
268 | { | 245 | { |
269 | hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); | 246 | hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0); |
270 | snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, | 247 | snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT, |
271 | AC_DIPXMIT_DISABLE); | 248 | AC_DIPXMIT_DISABLE); |
272 | } | 249 | } |
273 | 250 | ||
274 | static int hdmi_get_channel_count(struct hda_codec *codec) | 251 | static int hdmi_get_channel_count(struct hda_codec *codec) |
275 | { | 252 | { |
276 | return 1 + snd_hda_codec_read(codec, CVT_NID, 0, | 253 | return 1 + snd_hda_codec_read(codec, cvt_nid, 0, |
277 | AC_VERB_GET_CVT_CHAN_COUNT, 0); | 254 | AC_VERB_GET_CVT_CHAN_COUNT, 0); |
278 | } | 255 | } |
279 | 256 | ||
280 | static void hdmi_set_channel_count(struct hda_codec *codec, int chs) | 257 | static void hdmi_set_channel_count(struct hda_codec *codec, int chs) |
281 | { | 258 | { |
282 | snd_hda_codec_write(codec, CVT_NID, 0, | 259 | snd_hda_codec_write(codec, cvt_nid, 0, |
283 | AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); | 260 | AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); |
284 | 261 | ||
285 | if (chs != hdmi_get_channel_count(codec)) | 262 | if (chs != hdmi_get_channel_count(codec)) |
@@ -294,7 +271,7 @@ static void hdmi_debug_channel_mapping(struct hda_codec *codec) | |||
294 | int slot; | 271 | int slot; |
295 | 272 | ||
296 | for (i = 0; i < 8; i++) { | 273 | for (i = 0; i < 8; i++) { |
297 | slot = snd_hda_codec_read(codec, CVT_NID, 0, | 274 | slot = snd_hda_codec_read(codec, cvt_nid, 0, |
298 | AC_VERB_GET_HDMI_CHAN_SLOT, i); | 275 | AC_VERB_GET_HDMI_CHAN_SLOT, i); |
299 | printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n", | 276 | printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n", |
300 | slot >> 4, slot & 0x7); | 277 | slot >> 4, slot & 0x7); |
@@ -307,7 +284,7 @@ static void hdmi_parse_eld(struct hda_codec *codec) | |||
307 | struct intel_hdmi_spec *spec = codec->spec; | 284 | struct intel_hdmi_spec *spec = codec->spec; |
308 | struct hdmi_eld *eld = &spec->sink_eld; | 285 | struct hdmi_eld *eld = &spec->sink_eld; |
309 | 286 | ||
310 | if (!snd_hdmi_get_eld(eld, codec, PIN_NID)) | 287 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) |
311 | snd_hdmi_show_eld(eld); | 288 | snd_hdmi_show_eld(eld); |
312 | } | 289 | } |
313 | 290 | ||
@@ -322,11 +299,11 @@ static void hdmi_debug_dip_size(struct hda_codec *codec) | |||
322 | int i; | 299 | int i; |
323 | int size; | 300 | int size; |
324 | 301 | ||
325 | size = snd_hdmi_get_eld_size(codec, PIN_NID); | 302 | size = snd_hdmi_get_eld_size(codec, pin_nid); |
326 | printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size); | 303 | printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size); |
327 | 304 | ||
328 | for (i = 0; i < 8; i++) { | 305 | for (i = 0; i < 8; i++) { |
329 | size = snd_hda_codec_read(codec, PIN_NID, 0, | 306 | size = snd_hda_codec_read(codec, pin_nid, 0, |
330 | AC_VERB_GET_HDMI_DIP_SIZE, i); | 307 | AC_VERB_GET_HDMI_DIP_SIZE, i); |
331 | printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size); | 308 | printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size); |
332 | } | 309 | } |
@@ -340,15 +317,15 @@ static void hdmi_clear_dip_buffers(struct hda_codec *codec) | |||
340 | int size; | 317 | int size; |
341 | int pi, bi; | 318 | int pi, bi; |
342 | for (i = 0; i < 8; i++) { | 319 | for (i = 0; i < 8; i++) { |
343 | size = snd_hda_codec_read(codec, PIN_NID, 0, | 320 | size = snd_hda_codec_read(codec, pin_nid, 0, |
344 | AC_VERB_GET_HDMI_DIP_SIZE, i); | 321 | AC_VERB_GET_HDMI_DIP_SIZE, i); |
345 | if (size == 0) | 322 | if (size == 0) |
346 | continue; | 323 | continue; |
347 | 324 | ||
348 | hdmi_set_dip_index(codec, PIN_NID, i, 0x0); | 325 | hdmi_set_dip_index(codec, pin_nid, i, 0x0); |
349 | for (j = 1; j < 1000; j++) { | 326 | for (j = 1; j < 1000; j++) { |
350 | hdmi_write_dip_byte(codec, PIN_NID, 0x0); | 327 | hdmi_write_dip_byte(codec, pin_nid, 0x0); |
351 | hdmi_get_dip_index(codec, PIN_NID, &pi, &bi); | 328 | hdmi_get_dip_index(codec, pin_nid, &pi, &bi); |
352 | if (pi != i) | 329 | if (pi != i) |
353 | snd_printd(KERN_INFO "dip index %d: %d != %d\n", | 330 | snd_printd(KERN_INFO "dip index %d: %d != %d\n", |
354 | bi, pi, i); | 331 | bi, pi, i); |
@@ -376,9 +353,9 @@ static void hdmi_fill_audio_infoframe(struct hda_codec *codec, | |||
376 | sum += params[i]; | 353 | sum += params[i]; |
377 | ai->checksum = - sum; | 354 | ai->checksum = - sum; |
378 | 355 | ||
379 | hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); | 356 | hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0); |
380 | for (i = 0; i < sizeof(ai); i++) | 357 | for (i = 0; i < sizeof(ai); i++) |
381 | hdmi_write_dip_byte(codec, PIN_NID, params[i]); | 358 | hdmi_write_dip_byte(codec, pin_nid, params[i]); |
382 | } | 359 | } |
383 | 360 | ||
384 | /* | 361 | /* |
@@ -465,6 +442,8 @@ static int hdmi_setup_channel_allocation(struct hda_codec *codec, | |||
465 | static void hdmi_setup_channel_mapping(struct hda_codec *codec, | 442 | static void hdmi_setup_channel_mapping(struct hda_codec *codec, |
466 | struct hdmi_audio_infoframe *ai) | 443 | struct hdmi_audio_infoframe *ai) |
467 | { | 444 | { |
445 | int i; | ||
446 | |||
468 | if (!ai->CA) | 447 | if (!ai->CA) |
469 | return; | 448 | return; |
470 | 449 | ||
@@ -473,7 +452,11 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec, | |||
473 | * ALSA sequence is front/surr/clfe/side? | 452 | * ALSA sequence is front/surr/clfe/side? |
474 | */ | 453 | */ |
475 | 454 | ||
476 | snd_hda_sequence_write(codec, def_chan_map); | 455 | for (i = 0; i < 8; i++) |
456 | snd_hda_codec_write(codec, cvt_nid, 0, | ||
457 | AC_VERB_SET_HDMI_CHAN_SLOT, | ||
458 | (i << 4) | i); | ||
459 | |||
477 | hdmi_debug_channel_mapping(codec); | 460 | hdmi_debug_channel_mapping(codec); |
478 | } | 461 | } |
479 | 462 | ||
@@ -597,7 +580,6 @@ static struct hda_pcm_stream intel_hdmi_pcm_playback = { | |||
597 | .substreams = 1, | 580 | .substreams = 1, |
598 | .channels_min = 2, | 581 | .channels_min = 2, |
599 | .channels_max = 8, | 582 | .channels_max = 8, |
600 | .nid = CVT_NID, /* NID to query formats and rates and setup streams */ | ||
601 | .ops = { | 583 | .ops = { |
602 | .open = intel_hdmi_playback_pcm_open, | 584 | .open = intel_hdmi_playback_pcm_open, |
603 | .close = intel_hdmi_playback_pcm_close, | 585 | .close = intel_hdmi_playback_pcm_close, |
@@ -613,6 +595,9 @@ static int intel_hdmi_build_pcms(struct hda_codec *codec) | |||
613 | codec->num_pcms = 1; | 595 | codec->num_pcms = 1; |
614 | codec->pcm_info = info; | 596 | codec->pcm_info = info; |
615 | 597 | ||
598 | /* NID to query formats and rates and setup streams */ | ||
599 | intel_hdmi_pcm_playback.nid = cvt_nid; | ||
600 | |||
616 | info->name = "INTEL HDMI"; | 601 | info->name = "INTEL HDMI"; |
617 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 602 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
618 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback; | 603 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback; |
@@ -636,8 +621,9 @@ static int intel_hdmi_init(struct hda_codec *codec) | |||
636 | { | 621 | { |
637 | hdmi_enable_output(codec); | 622 | hdmi_enable_output(codec); |
638 | 623 | ||
639 | snd_hda_sequence_write(codec, unsolicited_response_verb); | 624 | snd_hda_codec_write(codec, pin_nid, 0, |
640 | 625 | AC_VERB_SET_UNSOLICITED_ENABLE, | |
626 | AC_USRSP_EN | INTEL_HDMI_EVENT_TAG); | ||
641 | return 0; | 627 | return 0; |
642 | } | 628 | } |
643 | 629 | ||
@@ -657,7 +643,7 @@ static struct hda_codec_ops intel_hdmi_patch_ops = { | |||
657 | .unsol_event = intel_hdmi_unsol_event, | 643 | .unsol_event = intel_hdmi_unsol_event, |
658 | }; | 644 | }; |
659 | 645 | ||
660 | static int patch_intel_hdmi(struct hda_codec *codec) | 646 | static int do_patch_intel_hdmi(struct hda_codec *codec) |
661 | { | 647 | { |
662 | struct intel_hdmi_spec *spec; | 648 | struct intel_hdmi_spec *spec; |
663 | 649 | ||
@@ -667,7 +653,7 @@ static int patch_intel_hdmi(struct hda_codec *codec) | |||
667 | 653 | ||
668 | spec->multiout.num_dacs = 0; /* no analog */ | 654 | spec->multiout.num_dacs = 0; /* no analog */ |
669 | spec->multiout.max_channels = 8; | 655 | spec->multiout.max_channels = 8; |
670 | spec->multiout.dig_out_nid = CVT_NID; | 656 | spec->multiout.dig_out_nid = cvt_nid; |
671 | 657 | ||
672 | codec->spec = spec; | 658 | codec->spec = spec; |
673 | codec->patch_ops = intel_hdmi_patch_ops; | 659 | codec->patch_ops = intel_hdmi_patch_ops; |
@@ -679,12 +665,27 @@ static int patch_intel_hdmi(struct hda_codec *codec) | |||
679 | return 0; | 665 | return 0; |
680 | } | 666 | } |
681 | 667 | ||
668 | static int patch_intel_hdmi(struct hda_codec *codec) | ||
669 | { | ||
670 | cvt_nid = 0x02; | ||
671 | pin_nid = 0x03; | ||
672 | return do_patch_intel_hdmi(codec); | ||
673 | } | ||
674 | |||
675 | static int patch_intel_hdmi_ibexpeak(struct hda_codec *codec) | ||
676 | { | ||
677 | cvt_nid = 0x02; | ||
678 | pin_nid = 0x04; | ||
679 | return do_patch_intel_hdmi(codec); | ||
680 | } | ||
681 | |||
682 | static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { | 682 | static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { |
683 | { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi }, | 683 | { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi }, |
684 | { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, | 684 | { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, |
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 = "Q57 DEVIBX", .patch = patch_intel_hdmi_ibexpeak }, | ||
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 fea976793ae..efb92c83c7a 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 */ |
@@ -262,6 +258,14 @@ enum { | |||
262 | ALC_INIT_GPIO3, | 258 | ALC_INIT_GPIO3, |
263 | }; | 259 | }; |
264 | 260 | ||
261 | struct alc_mic_route { | ||
262 | hda_nid_t pin; | ||
263 | unsigned char mux_idx; | ||
264 | unsigned char amix_idx; | ||
265 | }; | ||
266 | |||
267 | #define MUX_IDX_UNDEF ((unsigned char)-1) | ||
268 | |||
265 | struct alc_spec { | 269 | struct alc_spec { |
266 | /* codec parameterization */ | 270 | /* codec parameterization */ |
267 | struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ | 271 | struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ |
@@ -304,6 +308,8 @@ struct alc_spec { | |||
304 | unsigned int num_mux_defs; | 308 | unsigned int num_mux_defs; |
305 | const struct hda_input_mux *input_mux; | 309 | const struct hda_input_mux *input_mux; |
306 | unsigned int cur_mux[3]; | 310 | unsigned int cur_mux[3]; |
311 | struct alc_mic_route ext_mic; | ||
312 | struct alc_mic_route int_mic; | ||
307 | 313 | ||
308 | /* channel model */ | 314 | /* channel model */ |
309 | const struct hda_channel_mode *channel_mode; | 315 | const struct hda_channel_mode *channel_mode; |
@@ -320,6 +326,8 @@ struct alc_spec { | |||
320 | struct snd_array kctls; | 326 | struct snd_array kctls; |
321 | struct hda_input_mux private_imux[3]; | 327 | struct hda_input_mux private_imux[3]; |
322 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | 328 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; |
329 | hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; | ||
330 | hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; | ||
323 | 331 | ||
324 | /* hooks */ | 332 | /* hooks */ |
325 | void (*init_hook)(struct hda_codec *codec); | 333 | void (*init_hook)(struct hda_codec *codec); |
@@ -329,6 +337,7 @@ struct alc_spec { | |||
329 | unsigned int sense_updated: 1; | 337 | unsigned int sense_updated: 1; |
330 | unsigned int jack_present: 1; | 338 | unsigned int jack_present: 1; |
331 | unsigned int master_sw: 1; | 339 | unsigned int master_sw: 1; |
340 | unsigned int auto_mic:1; | ||
332 | 341 | ||
333 | /* other flags */ | 342 | /* other flags */ |
334 | unsigned int no_analog :1; /* digital I/O only */ | 343 | unsigned int no_analog :1; /* digital I/O only */ |
@@ -370,6 +379,7 @@ struct alc_config_preset { | |||
370 | unsigned int num_mux_defs; | 379 | unsigned int num_mux_defs; |
371 | const struct hda_input_mux *input_mux; | 380 | const struct hda_input_mux *input_mux; |
372 | void (*unsol_event)(struct hda_codec *, unsigned int); | 381 | void (*unsol_event)(struct hda_codec *, unsigned int); |
382 | void (*setup)(struct hda_codec *); | ||
373 | void (*init_hook)(struct hda_codec *); | 383 | void (*init_hook)(struct hda_codec *); |
374 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 384 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
375 | struct hda_amp_list *loopbacks; | 385 | struct hda_amp_list *loopbacks; |
@@ -417,7 +427,7 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
417 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 427 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; |
418 | imux = &spec->input_mux[mux_idx]; | 428 | imux = &spec->input_mux[mux_idx]; |
419 | 429 | ||
420 | type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 430 | type = get_wcaps_type(get_wcaps(codec, nid)); |
421 | if (type == AC_WID_AUD_MIX) { | 431 | if (type == AC_WID_AUD_MIX) { |
422 | /* Matrix-mixer style (e.g. ALC882) */ | 432 | /* Matrix-mixer style (e.g. ALC882) */ |
423 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; | 433 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; |
@@ -842,9 +852,10 @@ static void print_realtek_coef(struct snd_info_buffer *buffer, | |||
842 | /* | 852 | /* |
843 | * set up from the preset table | 853 | * set up from the preset table |
844 | */ | 854 | */ |
845 | static void setup_preset(struct alc_spec *spec, | 855 | static void setup_preset(struct hda_codec *codec, |
846 | const struct alc_config_preset *preset) | 856 | const struct alc_config_preset *preset) |
847 | { | 857 | { |
858 | struct alc_spec *spec = codec->spec; | ||
848 | int i; | 859 | int i; |
849 | 860 | ||
850 | for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) | 861 | for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) |
@@ -886,6 +897,9 @@ static void setup_preset(struct alc_spec *spec, | |||
886 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 897 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
887 | spec->loopback.amplist = preset->loopbacks; | 898 | spec->loopback.amplist = preset->loopbacks; |
888 | #endif | 899 | #endif |
900 | |||
901 | if (preset->setup) | ||
902 | preset->setup(codec); | ||
889 | } | 903 | } |
890 | 904 | ||
891 | /* Enable GPIO mask and set output */ | 905 | /* Enable GPIO mask and set output */ |
@@ -965,30 +979,64 @@ static void alc_automute_pin(struct hda_codec *codec) | |||
965 | } | 979 | } |
966 | } | 980 | } |
967 | 981 | ||
968 | #if 0 /* it's broken in some cases -- temporarily disabled */ | 982 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, |
983 | hda_nid_t nid) | ||
984 | { | ||
985 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
986 | int i, nums; | ||
987 | |||
988 | nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); | ||
989 | for (i = 0; i < nums; i++) | ||
990 | if (conn[i] == nid) | ||
991 | return i; | ||
992 | return -1; | ||
993 | } | ||
994 | |||
969 | static void alc_mic_automute(struct hda_codec *codec) | 995 | static void alc_mic_automute(struct hda_codec *codec) |
970 | { | 996 | { |
971 | struct alc_spec *spec = codec->spec; | 997 | struct alc_spec *spec = codec->spec; |
972 | unsigned int present; | 998 | struct alc_mic_route *dead, *alive; |
973 | unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; | 999 | unsigned int present, type; |
974 | unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; | 1000 | hda_nid_t cap_nid; |
975 | unsigned int mix_nid = spec->capsrc_nids[0]; | 1001 | |
976 | unsigned int capsrc_idx_mic, capsrc_idx_fmic; | 1002 | if (!spec->auto_mic) |
977 | 1003 | return; | |
978 | capsrc_idx_mic = mic_nid - 0x18; | 1004 | if (!spec->int_mic.pin || !spec->ext_mic.pin) |
979 | capsrc_idx_fmic = fmic_nid - 0x18; | 1005 | return; |
980 | present = snd_hda_codec_read(codec, mic_nid, 0, | 1006 | if (snd_BUG_ON(!spec->adc_nids)) |
981 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1007 | return; |
982 | snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 1008 | |
983 | 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80)); | 1009 | cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; |
984 | snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 1010 | |
985 | 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0)); | 1011 | present = snd_hda_codec_read(codec, spec->ext_mic.pin, 0, |
986 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic, | 1012 | AC_VERB_GET_PIN_SENSE, 0); |
987 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 1013 | present &= AC_PINSENSE_PRESENCE; |
1014 | if (present) { | ||
1015 | alive = &spec->ext_mic; | ||
1016 | dead = &spec->int_mic; | ||
1017 | } else { | ||
1018 | alive = &spec->int_mic; | ||
1019 | dead = &spec->ext_mic; | ||
1020 | } | ||
1021 | |||
1022 | type = get_wcaps_type(get_wcaps(codec, cap_nid)); | ||
1023 | if (type == AC_WID_AUD_MIX) { | ||
1024 | /* Matrix-mixer style (e.g. ALC882) */ | ||
1025 | snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, | ||
1026 | alive->mux_idx, | ||
1027 | HDA_AMP_MUTE, 0); | ||
1028 | snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, | ||
1029 | dead->mux_idx, | ||
1030 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
1031 | } else { | ||
1032 | /* MUX style (e.g. ALC880) */ | ||
1033 | snd_hda_codec_write_cache(codec, cap_nid, 0, | ||
1034 | AC_VERB_SET_CONNECT_SEL, | ||
1035 | alive->mux_idx); | ||
1036 | } | ||
1037 | |||
1038 | /* FIXME: analog mixer */ | ||
988 | } | 1039 | } |
989 | #else | ||
990 | #define alc_mic_automute(codec) do {} while(0) /* NOP */ | ||
991 | #endif /* disabled */ | ||
992 | 1040 | ||
993 | /* unsolicited event for HP jack sensing */ | 1041 | /* unsolicited event for HP jack sensing */ |
994 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | 1042 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -1031,6 +1079,16 @@ static void alc888_coef_init(struct hda_codec *codec) | |||
1031 | AC_VERB_SET_PROC_COEF, 0x3030); | 1079 | AC_VERB_SET_PROC_COEF, 0x3030); |
1032 | } | 1080 | } |
1033 | 1081 | ||
1082 | static void alc889_coef_init(struct hda_codec *codec) | ||
1083 | { | ||
1084 | unsigned int tmp; | ||
1085 | |||
1086 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | ||
1087 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); | ||
1088 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | ||
1089 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); | ||
1090 | } | ||
1091 | |||
1034 | static void alc_auto_init_amp(struct hda_codec *codec, int type) | 1092 | static void alc_auto_init_amp(struct hda_codec *codec, int type) |
1035 | { | 1093 | { |
1036 | unsigned int tmp; | 1094 | unsigned int tmp; |
@@ -1088,15 +1146,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) | |||
1088 | case 0x10ec0885: | 1146 | case 0x10ec0885: |
1089 | case 0x10ec0887: | 1147 | case 0x10ec0887: |
1090 | case 0x10ec0889: | 1148 | case 0x10ec0889: |
1091 | snd_hda_codec_write(codec, 0x20, 0, | 1149 | 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; | 1150 | break; |
1101 | case 0x10ec0888: | 1151 | case 0x10ec0888: |
1102 | alc888_coef_init(codec); | 1152 | alc888_coef_init(codec); |
@@ -1142,6 +1192,55 @@ static void alc_init_auto_hp(struct hda_codec *codec) | |||
1142 | spec->unsol_event = alc_sku_unsol_event; | 1192 | spec->unsol_event = alc_sku_unsol_event; |
1143 | } | 1193 | } |
1144 | 1194 | ||
1195 | static void alc_init_auto_mic(struct hda_codec *codec) | ||
1196 | { | ||
1197 | struct alc_spec *spec = codec->spec; | ||
1198 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1199 | hda_nid_t fixed, ext; | ||
1200 | int i; | ||
1201 | |||
1202 | /* there must be only two mic inputs exclusively */ | ||
1203 | for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) | ||
1204 | if (cfg->input_pins[i]) | ||
1205 | return; | ||
1206 | |||
1207 | fixed = ext = 0; | ||
1208 | for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) { | ||
1209 | hda_nid_t nid = cfg->input_pins[i]; | ||
1210 | unsigned int defcfg; | ||
1211 | if (!nid) | ||
1212 | return; | ||
1213 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | ||
1214 | switch (get_defcfg_connect(defcfg)) { | ||
1215 | case AC_JACK_PORT_FIXED: | ||
1216 | if (fixed) | ||
1217 | return; /* already occupied */ | ||
1218 | fixed = nid; | ||
1219 | break; | ||
1220 | case AC_JACK_PORT_COMPLEX: | ||
1221 | if (ext) | ||
1222 | return; /* already occupied */ | ||
1223 | ext = nid; | ||
1224 | break; | ||
1225 | default: | ||
1226 | return; /* invalid entry */ | ||
1227 | } | ||
1228 | } | ||
1229 | if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) | ||
1230 | return; /* no unsol support */ | ||
1231 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", | ||
1232 | ext, fixed); | ||
1233 | spec->ext_mic.pin = ext; | ||
1234 | spec->int_mic.pin = fixed; | ||
1235 | spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ | ||
1236 | spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ | ||
1237 | spec->auto_mic = 1; | ||
1238 | snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, | ||
1239 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1240 | AC_USRSP_EN | ALC880_MIC_EVENT); | ||
1241 | spec->unsol_event = alc_sku_unsol_event; | ||
1242 | } | ||
1243 | |||
1145 | /* check subsystem ID and set up device-specific initialization; | 1244 | /* check subsystem ID and set up device-specific initialization; |
1146 | * return 1 if initialized, 0 if invalid SSID | 1245 | * return 1 if initialized, 0 if invalid SSID |
1147 | */ | 1246 | */ |
@@ -1243,6 +1342,7 @@ do_sku: | |||
1243 | } | 1342 | } |
1244 | 1343 | ||
1245 | alc_init_auto_hp(codec); | 1344 | alc_init_auto_hp(codec); |
1345 | alc_init_auto_mic(codec); | ||
1246 | return 1; | 1346 | return 1; |
1247 | } | 1347 | } |
1248 | 1348 | ||
@@ -1255,6 +1355,7 @@ static void alc_ssid_check(struct hda_codec *codec, | |||
1255 | "Enable default setup for auto mode as fallback\n"); | 1355 | "Enable default setup for auto mode as fallback\n"); |
1256 | spec->init_amp = ALC_INIT_DEFAULT; | 1356 | spec->init_amp = ALC_INIT_DEFAULT; |
1257 | alc_init_auto_hp(codec); | 1357 | alc_init_auto_hp(codec); |
1358 | alc_init_auto_mic(codec); | ||
1258 | } | 1359 | } |
1259 | } | 1360 | } |
1260 | 1361 | ||
@@ -1436,7 +1537,25 @@ static void alc_automute_amp_unsol_event(struct hda_codec *codec, | |||
1436 | alc_automute_amp(codec); | 1537 | alc_automute_amp(codec); |
1437 | } | 1538 | } |
1438 | 1539 | ||
1439 | static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec) | 1540 | static void alc889_automute_setup(struct hda_codec *codec) |
1541 | { | ||
1542 | struct alc_spec *spec = codec->spec; | ||
1543 | |||
1544 | spec->autocfg.hp_pins[0] = 0x15; | ||
1545 | spec->autocfg.speaker_pins[0] = 0x14; | ||
1546 | spec->autocfg.speaker_pins[1] = 0x16; | ||
1547 | spec->autocfg.speaker_pins[2] = 0x17; | ||
1548 | spec->autocfg.speaker_pins[3] = 0x19; | ||
1549 | spec->autocfg.speaker_pins[4] = 0x1a; | ||
1550 | } | ||
1551 | |||
1552 | static void alc889_intel_init_hook(struct hda_codec *codec) | ||
1553 | { | ||
1554 | alc889_coef_init(codec); | ||
1555 | alc_automute_amp(codec); | ||
1556 | } | ||
1557 | |||
1558 | static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) | ||
1440 | { | 1559 | { |
1441 | struct alc_spec *spec = codec->spec; | 1560 | struct alc_spec *spec = codec->spec; |
1442 | 1561 | ||
@@ -1444,7 +1563,6 @@ static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec) | |||
1444 | spec->autocfg.hp_pins[1] = 0x1b; /* hp */ | 1563 | spec->autocfg.hp_pins[1] = 0x1b; /* hp */ |
1445 | spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ | 1564 | spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ |
1446 | spec->autocfg.speaker_pins[1] = 0x15; /* bass */ | 1565 | spec->autocfg.speaker_pins[1] = 0x15; /* bass */ |
1447 | alc_automute_amp(codec); | ||
1448 | } | 1566 | } |
1449 | 1567 | ||
1450 | /* | 1568 | /* |
@@ -1643,16 +1761,15 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { | |||
1643 | { } /* end */ | 1761 | { } /* end */ |
1644 | }; | 1762 | }; |
1645 | 1763 | ||
1646 | static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec) | 1764 | static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) |
1647 | { | 1765 | { |
1648 | struct alc_spec *spec = codec->spec; | 1766 | struct alc_spec *spec = codec->spec; |
1649 | 1767 | ||
1650 | spec->autocfg.hp_pins[0] = 0x15; | 1768 | spec->autocfg.hp_pins[0] = 0x15; |
1651 | spec->autocfg.speaker_pins[0] = 0x14; | 1769 | spec->autocfg.speaker_pins[0] = 0x14; |
1652 | alc_automute_amp(codec); | ||
1653 | } | 1770 | } |
1654 | 1771 | ||
1655 | static void alc888_acer_aspire_6530g_init_hook(struct hda_codec *codec) | 1772 | static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) |
1656 | { | 1773 | { |
1657 | struct alc_spec *spec = codec->spec; | 1774 | struct alc_spec *spec = codec->spec; |
1658 | 1775 | ||
@@ -1660,10 +1777,9 @@ static void alc888_acer_aspire_6530g_init_hook(struct hda_codec *codec) | |||
1660 | spec->autocfg.speaker_pins[0] = 0x14; | 1777 | spec->autocfg.speaker_pins[0] = 0x14; |
1661 | spec->autocfg.speaker_pins[1] = 0x16; | 1778 | spec->autocfg.speaker_pins[1] = 0x16; |
1662 | spec->autocfg.speaker_pins[2] = 0x17; | 1779 | spec->autocfg.speaker_pins[2] = 0x17; |
1663 | alc_automute_amp(codec); | ||
1664 | } | 1780 | } |
1665 | 1781 | ||
1666 | static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec) | 1782 | static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) |
1667 | { | 1783 | { |
1668 | struct alc_spec *spec = codec->spec; | 1784 | struct alc_spec *spec = codec->spec; |
1669 | 1785 | ||
@@ -1671,7 +1787,6 @@ static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec) | |||
1671 | spec->autocfg.speaker_pins[0] = 0x14; | 1787 | spec->autocfg.speaker_pins[0] = 0x14; |
1672 | spec->autocfg.speaker_pins[1] = 0x16; | 1788 | spec->autocfg.speaker_pins[1] = 0x16; |
1673 | spec->autocfg.speaker_pins[2] = 0x1b; | 1789 | spec->autocfg.speaker_pins[2] = 0x1b; |
1674 | alc_automute_amp(codec); | ||
1675 | } | 1790 | } |
1676 | 1791 | ||
1677 | /* | 1792 | /* |
@@ -2651,13 +2766,17 @@ static void alc880_uniwill_mic_automute(struct hda_codec *codec) | |||
2651 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); | 2766 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); |
2652 | } | 2767 | } |
2653 | 2768 | ||
2654 | static void alc880_uniwill_init_hook(struct hda_codec *codec) | 2769 | static void alc880_uniwill_setup(struct hda_codec *codec) |
2655 | { | 2770 | { |
2656 | struct alc_spec *spec = codec->spec; | 2771 | struct alc_spec *spec = codec->spec; |
2657 | 2772 | ||
2658 | spec->autocfg.hp_pins[0] = 0x14; | 2773 | spec->autocfg.hp_pins[0] = 0x14; |
2659 | spec->autocfg.speaker_pins[0] = 0x15; | 2774 | spec->autocfg.speaker_pins[0] = 0x15; |
2660 | spec->autocfg.speaker_pins[0] = 0x16; | 2775 | spec->autocfg.speaker_pins[0] = 0x16; |
2776 | } | ||
2777 | |||
2778 | static void alc880_uniwill_init_hook(struct hda_codec *codec) | ||
2779 | { | ||
2661 | alc_automute_amp(codec); | 2780 | alc_automute_amp(codec); |
2662 | alc880_uniwill_mic_automute(codec); | 2781 | alc880_uniwill_mic_automute(codec); |
2663 | } | 2782 | } |
@@ -2678,13 +2797,12 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, | |||
2678 | } | 2797 | } |
2679 | } | 2798 | } |
2680 | 2799 | ||
2681 | static void alc880_uniwill_p53_init_hook(struct hda_codec *codec) | 2800 | static void alc880_uniwill_p53_setup(struct hda_codec *codec) |
2682 | { | 2801 | { |
2683 | struct alc_spec *spec = codec->spec; | 2802 | struct alc_spec *spec = codec->spec; |
2684 | 2803 | ||
2685 | spec->autocfg.hp_pins[0] = 0x14; | 2804 | spec->autocfg.hp_pins[0] = 0x14; |
2686 | spec->autocfg.speaker_pins[0] = 0x15; | 2805 | spec->autocfg.speaker_pins[0] = 0x15; |
2687 | alc_automute_amp(codec); | ||
2688 | } | 2806 | } |
2689 | 2807 | ||
2690 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) | 2808 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) |
@@ -2947,13 +3065,12 @@ static struct hda_verb alc880_lg_init_verbs[] = { | |||
2947 | }; | 3065 | }; |
2948 | 3066 | ||
2949 | /* toggle speaker-output according to the hp-jack state */ | 3067 | /* toggle speaker-output according to the hp-jack state */ |
2950 | static void alc880_lg_init_hook(struct hda_codec *codec) | 3068 | static void alc880_lg_setup(struct hda_codec *codec) |
2951 | { | 3069 | { |
2952 | struct alc_spec *spec = codec->spec; | 3070 | struct alc_spec *spec = codec->spec; |
2953 | 3071 | ||
2954 | spec->autocfg.hp_pins[0] = 0x1b; | 3072 | spec->autocfg.hp_pins[0] = 0x1b; |
2955 | spec->autocfg.speaker_pins[0] = 0x17; | 3073 | spec->autocfg.speaker_pins[0] = 0x17; |
2956 | alc_automute_amp(codec); | ||
2957 | } | 3074 | } |
2958 | 3075 | ||
2959 | /* | 3076 | /* |
@@ -3032,13 +3149,12 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { | |||
3032 | }; | 3149 | }; |
3033 | 3150 | ||
3034 | /* toggle speaker-output according to the hp-jack state */ | 3151 | /* toggle speaker-output according to the hp-jack state */ |
3035 | static void alc880_lg_lw_init_hook(struct hda_codec *codec) | 3152 | static void alc880_lg_lw_setup(struct hda_codec *codec) |
3036 | { | 3153 | { |
3037 | struct alc_spec *spec = codec->spec; | 3154 | struct alc_spec *spec = codec->spec; |
3038 | 3155 | ||
3039 | spec->autocfg.hp_pins[0] = 0x1b; | 3156 | spec->autocfg.hp_pins[0] = 0x1b; |
3040 | spec->autocfg.speaker_pins[0] = 0x14; | 3157 | spec->autocfg.speaker_pins[0] = 0x14; |
3041 | alc_automute_amp(codec); | ||
3042 | } | 3158 | } |
3043 | 3159 | ||
3044 | static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { | 3160 | static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { |
@@ -3104,13 +3220,12 @@ static void alc880_medion_rim_unsol_event(struct hda_codec *codec, | |||
3104 | alc880_medion_rim_automute(codec); | 3220 | alc880_medion_rim_automute(codec); |
3105 | } | 3221 | } |
3106 | 3222 | ||
3107 | static void alc880_medion_rim_init_hook(struct hda_codec *codec) | 3223 | static void alc880_medion_rim_setup(struct hda_codec *codec) |
3108 | { | 3224 | { |
3109 | struct alc_spec *spec = codec->spec; | 3225 | struct alc_spec *spec = codec->spec; |
3110 | 3226 | ||
3111 | spec->autocfg.hp_pins[0] = 0x14; | 3227 | spec->autocfg.hp_pins[0] = 0x14; |
3112 | spec->autocfg.speaker_pins[0] = 0x1b; | 3228 | spec->autocfg.speaker_pins[0] = 0x1b; |
3113 | alc880_medion_rim_automute(codec); | ||
3114 | } | 3229 | } |
3115 | 3230 | ||
3116 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3231 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -3977,7 +4092,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
3977 | .channel_mode = alc880_2_jack_modes, | 4092 | .channel_mode = alc880_2_jack_modes, |
3978 | .input_mux = &alc880_f1734_capture_source, | 4093 | .input_mux = &alc880_f1734_capture_source, |
3979 | .unsol_event = alc880_uniwill_p53_unsol_event, | 4094 | .unsol_event = alc880_uniwill_p53_unsol_event, |
3980 | .init_hook = alc880_uniwill_p53_init_hook, | 4095 | .setup = alc880_uniwill_p53_setup, |
4096 | .init_hook = alc_automute_amp, | ||
3981 | }, | 4097 | }, |
3982 | [ALC880_ASUS] = { | 4098 | [ALC880_ASUS] = { |
3983 | .mixers = { alc880_asus_mixer }, | 4099 | .mixers = { alc880_asus_mixer }, |
@@ -4054,6 +4170,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
4054 | .need_dac_fix = 1, | 4170 | .need_dac_fix = 1, |
4055 | .input_mux = &alc880_capture_source, | 4171 | .input_mux = &alc880_capture_source, |
4056 | .unsol_event = alc880_uniwill_unsol_event, | 4172 | .unsol_event = alc880_uniwill_unsol_event, |
4173 | .setup = alc880_uniwill_setup, | ||
4057 | .init_hook = alc880_uniwill_init_hook, | 4174 | .init_hook = alc880_uniwill_init_hook, |
4058 | }, | 4175 | }, |
4059 | [ALC880_UNIWILL_P53] = { | 4176 | [ALC880_UNIWILL_P53] = { |
@@ -4066,7 +4183,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
4066 | .channel_mode = alc880_threestack_modes, | 4183 | .channel_mode = alc880_threestack_modes, |
4067 | .input_mux = &alc880_capture_source, | 4184 | .input_mux = &alc880_capture_source, |
4068 | .unsol_event = alc880_uniwill_p53_unsol_event, | 4185 | .unsol_event = alc880_uniwill_p53_unsol_event, |
4069 | .init_hook = alc880_uniwill_p53_init_hook, | 4186 | .setup = alc880_uniwill_p53_setup, |
4187 | .init_hook = alc_automute_amp, | ||
4070 | }, | 4188 | }, |
4071 | [ALC880_FUJITSU] = { | 4189 | [ALC880_FUJITSU] = { |
4072 | .mixers = { alc880_fujitsu_mixer }, | 4190 | .mixers = { alc880_fujitsu_mixer }, |
@@ -4080,7 +4198,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
4080 | .channel_mode = alc880_2_jack_modes, | 4198 | .channel_mode = alc880_2_jack_modes, |
4081 | .input_mux = &alc880_capture_source, | 4199 | .input_mux = &alc880_capture_source, |
4082 | .unsol_event = alc880_uniwill_p53_unsol_event, | 4200 | .unsol_event = alc880_uniwill_p53_unsol_event, |
4083 | .init_hook = alc880_uniwill_p53_init_hook, | 4201 | .setup = alc880_uniwill_p53_setup, |
4202 | .init_hook = alc_automute_amp, | ||
4084 | }, | 4203 | }, |
4085 | [ALC880_CLEVO] = { | 4204 | [ALC880_CLEVO] = { |
4086 | .mixers = { alc880_three_stack_mixer }, | 4205 | .mixers = { alc880_three_stack_mixer }, |
@@ -4106,7 +4225,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
4106 | .need_dac_fix = 1, | 4225 | .need_dac_fix = 1, |
4107 | .input_mux = &alc880_lg_capture_source, | 4226 | .input_mux = &alc880_lg_capture_source, |
4108 | .unsol_event = alc_automute_amp_unsol_event, | 4227 | .unsol_event = alc_automute_amp_unsol_event, |
4109 | .init_hook = alc880_lg_init_hook, | 4228 | .setup = alc880_lg_setup, |
4229 | .init_hook = alc_automute_amp, | ||
4110 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4230 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4111 | .loopbacks = alc880_lg_loopbacks, | 4231 | .loopbacks = alc880_lg_loopbacks, |
4112 | #endif | 4232 | #endif |
@@ -4122,7 +4242,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
4122 | .channel_mode = alc880_lg_lw_modes, | 4242 | .channel_mode = alc880_lg_lw_modes, |
4123 | .input_mux = &alc880_lg_lw_capture_source, | 4243 | .input_mux = &alc880_lg_lw_capture_source, |
4124 | .unsol_event = alc_automute_amp_unsol_event, | 4244 | .unsol_event = alc_automute_amp_unsol_event, |
4125 | .init_hook = alc880_lg_lw_init_hook, | 4245 | .setup = alc880_lg_lw_setup, |
4246 | .init_hook = alc_automute_amp, | ||
4126 | }, | 4247 | }, |
4127 | [ALC880_MEDION_RIM] = { | 4248 | [ALC880_MEDION_RIM] = { |
4128 | .mixers = { alc880_medion_rim_mixer }, | 4249 | .mixers = { alc880_medion_rim_mixer }, |
@@ -4136,7 +4257,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
4136 | .channel_mode = alc880_2_jack_modes, | 4257 | .channel_mode = alc880_2_jack_modes, |
4137 | .input_mux = &alc880_medion_rim_capture_source, | 4258 | .input_mux = &alc880_medion_rim_capture_source, |
4138 | .unsol_event = alc880_medion_rim_unsol_event, | 4259 | .unsol_event = alc880_medion_rim_unsol_event, |
4139 | .init_hook = alc880_medion_rim_init_hook, | 4260 | .setup = alc880_medion_rim_setup, |
4261 | .init_hook = alc880_medion_rim_automute, | ||
4140 | }, | 4262 | }, |
4141 | #ifdef CONFIG_SND_DEBUG | 4263 | #ifdef CONFIG_SND_DEBUG |
4142 | [ALC880_TEST] = { | 4264 | [ALC880_TEST] = { |
@@ -4505,12 +4627,6 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
4505 | &dig_nid, 1); | 4627 | &dig_nid, 1); |
4506 | if (err < 0) | 4628 | if (err < 0) |
4507 | continue; | 4629 | 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) | 4630 | if (!i) |
4515 | spec->multiout.dig_out_nid = dig_nid; | 4631 | spec->multiout.dig_out_nid = dig_nid; |
4516 | else { | 4632 | else { |
@@ -4547,8 +4663,42 @@ static void alc880_auto_init(struct hda_codec *codec) | |||
4547 | alc_inithook(codec); | 4663 | alc_inithook(codec); |
4548 | } | 4664 | } |
4549 | 4665 | ||
4550 | static void set_capture_mixer(struct alc_spec *spec) | 4666 | /* check the ADC/MUX contains all input pins; some ADC/MUX contains only |
4667 | * one of two digital mic pins, e.g. on ALC272 | ||
4668 | */ | ||
4669 | static void fixup_automic_adc(struct hda_codec *codec) | ||
4670 | { | ||
4671 | struct alc_spec *spec = codec->spec; | ||
4672 | int i; | ||
4673 | |||
4674 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
4675 | hda_nid_t cap = spec->capsrc_nids ? | ||
4676 | spec->capsrc_nids[i] : spec->adc_nids[i]; | ||
4677 | int iidx, eidx; | ||
4678 | |||
4679 | iidx = get_connection_index(codec, cap, spec->int_mic.pin); | ||
4680 | if (iidx < 0) | ||
4681 | continue; | ||
4682 | eidx = get_connection_index(codec, cap, spec->ext_mic.pin); | ||
4683 | if (eidx < 0) | ||
4684 | continue; | ||
4685 | spec->int_mic.mux_idx = iidx; | ||
4686 | spec->ext_mic.mux_idx = eidx; | ||
4687 | if (spec->capsrc_nids) | ||
4688 | spec->capsrc_nids += i; | ||
4689 | spec->adc_nids += i; | ||
4690 | spec->num_adc_nids = 1; | ||
4691 | return; | ||
4692 | } | ||
4693 | snd_printd(KERN_INFO "hda_codec: %s: " | ||
4694 | "No ADC/MUX containing both 0x%x and 0x%x pins\n", | ||
4695 | codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); | ||
4696 | spec->auto_mic = 0; /* disable auto-mic to be sure */ | ||
4697 | } | ||
4698 | |||
4699 | static void set_capture_mixer(struct hda_codec *codec) | ||
4551 | { | 4700 | { |
4701 | struct alc_spec *spec = codec->spec; | ||
4552 | static struct snd_kcontrol_new *caps[2][3] = { | 4702 | static struct snd_kcontrol_new *caps[2][3] = { |
4553 | { alc_capture_mixer_nosrc1, | 4703 | { alc_capture_mixer_nosrc1, |
4554 | alc_capture_mixer_nosrc2, | 4704 | alc_capture_mixer_nosrc2, |
@@ -4559,7 +4709,10 @@ static void set_capture_mixer(struct alc_spec *spec) | |||
4559 | }; | 4709 | }; |
4560 | if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { | 4710 | if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { |
4561 | int mux; | 4711 | int mux; |
4562 | if (spec->input_mux && spec->input_mux->num_items > 1) | 4712 | if (spec->auto_mic) { |
4713 | mux = 0; | ||
4714 | fixup_automic_adc(codec); | ||
4715 | } else if (spec->input_mux && spec->input_mux->num_items > 1) | ||
4563 | mux = 1; | 4716 | mux = 1; |
4564 | else | 4717 | else |
4565 | mux = 0; | 4718 | mux = 0; |
@@ -4590,8 +4743,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
4590 | alc880_models, | 4743 | alc880_models, |
4591 | alc880_cfg_tbl); | 4744 | alc880_cfg_tbl); |
4592 | if (board_config < 0) { | 4745 | if (board_config < 0) { |
4593 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 4746 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
4594 | "trying auto-probe from BIOS...\n", codec->chip_name); | 4747 | codec->chip_name); |
4595 | board_config = ALC880_AUTO; | 4748 | board_config = ALC880_AUTO; |
4596 | } | 4749 | } |
4597 | 4750 | ||
@@ -4616,7 +4769,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
4616 | } | 4769 | } |
4617 | 4770 | ||
4618 | if (board_config != ALC880_AUTO) | 4771 | if (board_config != ALC880_AUTO) |
4619 | setup_preset(spec, &alc880_presets[board_config]); | 4772 | setup_preset(codec, &alc880_presets[board_config]); |
4620 | 4773 | ||
4621 | spec->stream_analog_playback = &alc880_pcm_analog_playback; | 4774 | spec->stream_analog_playback = &alc880_pcm_analog_playback; |
4622 | spec->stream_analog_capture = &alc880_pcm_analog_capture; | 4775 | spec->stream_analog_capture = &alc880_pcm_analog_capture; |
@@ -4629,7 +4782,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
4629 | /* check whether NID 0x07 is valid */ | 4782 | /* check whether NID 0x07 is valid */ |
4630 | unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); | 4783 | unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); |
4631 | /* get type */ | 4784 | /* get type */ |
4632 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 4785 | wcap = get_wcaps_type(wcap); |
4633 | if (wcap != AC_WID_AUD_IN) { | 4786 | if (wcap != AC_WID_AUD_IN) { |
4634 | spec->adc_nids = alc880_adc_nids_alt; | 4787 | spec->adc_nids = alc880_adc_nids_alt; |
4635 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); | 4788 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); |
@@ -4638,7 +4791,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
4638 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); | 4791 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); |
4639 | } | 4792 | } |
4640 | } | 4793 | } |
4641 | set_capture_mixer(spec); | 4794 | set_capture_mixer(codec); |
4642 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 4795 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
4643 | 4796 | ||
4644 | spec->vmaster_nid = 0x0c; | 4797 | spec->vmaster_nid = 0x0c; |
@@ -6234,8 +6387,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
6234 | alc260_models, | 6387 | alc260_models, |
6235 | alc260_cfg_tbl); | 6388 | alc260_cfg_tbl); |
6236 | if (board_config < 0) { | 6389 | if (board_config < 0) { |
6237 | snd_printd(KERN_INFO "hda_codec: Unknown model for %s, " | 6390 | snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
6238 | "trying auto-probe from BIOS...\n", | ||
6239 | codec->chip_name); | 6391 | codec->chip_name); |
6240 | board_config = ALC260_AUTO; | 6392 | board_config = ALC260_AUTO; |
6241 | } | 6393 | } |
@@ -6261,7 +6413,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
6261 | } | 6413 | } |
6262 | 6414 | ||
6263 | if (board_config != ALC260_AUTO) | 6415 | if (board_config != ALC260_AUTO) |
6264 | setup_preset(spec, &alc260_presets[board_config]); | 6416 | setup_preset(codec, &alc260_presets[board_config]); |
6265 | 6417 | ||
6266 | spec->stream_analog_playback = &alc260_pcm_analog_playback; | 6418 | spec->stream_analog_playback = &alc260_pcm_analog_playback; |
6267 | spec->stream_analog_capture = &alc260_pcm_analog_capture; | 6419 | spec->stream_analog_capture = &alc260_pcm_analog_capture; |
@@ -6272,7 +6424,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
6272 | if (!spec->adc_nids && spec->input_mux) { | 6424 | if (!spec->adc_nids && spec->input_mux) { |
6273 | /* check whether NID 0x04 is valid */ | 6425 | /* check whether NID 0x04 is valid */ |
6274 | unsigned int wcap = get_wcaps(codec, 0x04); | 6426 | unsigned int wcap = get_wcaps(codec, 0x04); |
6275 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 6427 | wcap = get_wcaps_type(wcap); |
6276 | /* get type */ | 6428 | /* get type */ |
6277 | if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { | 6429 | if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { |
6278 | spec->adc_nids = alc260_adc_nids_alt; | 6430 | spec->adc_nids = alc260_adc_nids_alt; |
@@ -6282,7 +6434,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
6282 | spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); | 6434 | spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); |
6283 | } | 6435 | } |
6284 | } | 6436 | } |
6285 | set_capture_mixer(spec); | 6437 | set_capture_mixer(codec); |
6286 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); | 6438 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); |
6287 | 6439 | ||
6288 | spec->vmaster_nid = 0x08; | 6440 | spec->vmaster_nid = 0x08; |
@@ -6301,7 +6453,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
6301 | 6453 | ||
6302 | 6454 | ||
6303 | /* | 6455 | /* |
6304 | * ALC882 support | 6456 | * ALC882/883/885/888/889 support |
6305 | * | 6457 | * |
6306 | * ALC882 is almost identical with ALC880 but has cleaner and more flexible | 6458 | * 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. | 6459 | * configuration. Each pin widget can choose any input DACs and a mixer. |
@@ -6313,22 +6465,35 @@ static int patch_alc260(struct hda_codec *codec) | |||
6313 | */ | 6465 | */ |
6314 | #define ALC882_DIGOUT_NID 0x06 | 6466 | #define ALC882_DIGOUT_NID 0x06 |
6315 | #define ALC882_DIGIN_NID 0x0a | 6467 | #define ALC882_DIGIN_NID 0x0a |
6468 | #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID | ||
6469 | #define ALC883_DIGIN_NID ALC882_DIGIN_NID | ||
6470 | #define ALC1200_DIGOUT_NID 0x10 | ||
6471 | |||
6316 | 6472 | ||
6317 | static struct hda_channel_mode alc882_ch_modes[1] = { | 6473 | static struct hda_channel_mode alc882_ch_modes[1] = { |
6318 | { 8, NULL } | 6474 | { 8, NULL } |
6319 | }; | 6475 | }; |
6320 | 6476 | ||
6477 | /* DACs */ | ||
6321 | static hda_nid_t alc882_dac_nids[4] = { | 6478 | static hda_nid_t alc882_dac_nids[4] = { |
6322 | /* front, rear, clfe, rear_surr */ | 6479 | /* front, rear, clfe, rear_surr */ |
6323 | 0x02, 0x03, 0x04, 0x05 | 6480 | 0x02, 0x03, 0x04, 0x05 |
6324 | }; | 6481 | }; |
6482 | #define alc883_dac_nids alc882_dac_nids | ||
6325 | 6483 | ||
6326 | /* identical with ALC880 */ | 6484 | /* ADCs */ |
6327 | #define alc882_adc_nids alc880_adc_nids | 6485 | #define alc882_adc_nids alc880_adc_nids |
6328 | #define alc882_adc_nids_alt alc880_adc_nids_alt | 6486 | #define alc882_adc_nids_alt alc880_adc_nids_alt |
6487 | #define alc883_adc_nids alc882_adc_nids_alt | ||
6488 | static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; | ||
6489 | static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; | ||
6490 | #define alc889_adc_nids alc880_adc_nids | ||
6329 | 6491 | ||
6330 | static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; | 6492 | static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; |
6331 | static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; | 6493 | static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; |
6494 | #define alc883_capsrc_nids alc882_capsrc_nids_alt | ||
6495 | static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; | ||
6496 | #define alc889_capsrc_nids alc882_capsrc_nids | ||
6332 | 6497 | ||
6333 | /* input MUX */ | 6498 | /* input MUX */ |
6334 | /* FIXME: should be a matrix-type input source selection */ | 6499 | /* FIXME: should be a matrix-type input source selection */ |
@@ -6343,6 +6508,17 @@ static struct hda_input_mux alc882_capture_source = { | |||
6343 | }, | 6508 | }, |
6344 | }; | 6509 | }; |
6345 | 6510 | ||
6511 | #define alc883_capture_source alc882_capture_source | ||
6512 | |||
6513 | static struct hda_input_mux alc889_capture_source = { | ||
6514 | .num_items = 3, | ||
6515 | .items = { | ||
6516 | { "Front Mic", 0x0 }, | ||
6517 | { "Mic", 0x3 }, | ||
6518 | { "Line", 0x2 }, | ||
6519 | }, | ||
6520 | }; | ||
6521 | |||
6346 | static struct hda_input_mux mb5_capture_source = { | 6522 | static struct hda_input_mux mb5_capture_source = { |
6347 | .num_items = 3, | 6523 | .num_items = 3, |
6348 | .items = { | 6524 | .items = { |
@@ -6352,6 +6528,77 @@ static struct hda_input_mux mb5_capture_source = { | |||
6352 | }, | 6528 | }, |
6353 | }; | 6529 | }; |
6354 | 6530 | ||
6531 | static struct hda_input_mux alc883_3stack_6ch_intel = { | ||
6532 | .num_items = 4, | ||
6533 | .items = { | ||
6534 | { "Mic", 0x1 }, | ||
6535 | { "Front Mic", 0x0 }, | ||
6536 | { "Line", 0x2 }, | ||
6537 | { "CD", 0x4 }, | ||
6538 | }, | ||
6539 | }; | ||
6540 | |||
6541 | static struct hda_input_mux alc883_lenovo_101e_capture_source = { | ||
6542 | .num_items = 2, | ||
6543 | .items = { | ||
6544 | { "Mic", 0x1 }, | ||
6545 | { "Line", 0x2 }, | ||
6546 | }, | ||
6547 | }; | ||
6548 | |||
6549 | static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { | ||
6550 | .num_items = 4, | ||
6551 | .items = { | ||
6552 | { "Mic", 0x0 }, | ||
6553 | { "iMic", 0x1 }, | ||
6554 | { "Line", 0x2 }, | ||
6555 | { "CD", 0x4 }, | ||
6556 | }, | ||
6557 | }; | ||
6558 | |||
6559 | static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { | ||
6560 | .num_items = 2, | ||
6561 | .items = { | ||
6562 | { "Mic", 0x0 }, | ||
6563 | { "Int Mic", 0x1 }, | ||
6564 | }, | ||
6565 | }; | ||
6566 | |||
6567 | static struct hda_input_mux alc883_lenovo_sky_capture_source = { | ||
6568 | .num_items = 3, | ||
6569 | .items = { | ||
6570 | { "Mic", 0x0 }, | ||
6571 | { "Front Mic", 0x1 }, | ||
6572 | { "Line", 0x4 }, | ||
6573 | }, | ||
6574 | }; | ||
6575 | |||
6576 | static struct hda_input_mux alc883_asus_eee1601_capture_source = { | ||
6577 | .num_items = 2, | ||
6578 | .items = { | ||
6579 | { "Mic", 0x0 }, | ||
6580 | { "Line", 0x2 }, | ||
6581 | }, | ||
6582 | }; | ||
6583 | |||
6584 | static struct hda_input_mux alc889A_mb31_capture_source = { | ||
6585 | .num_items = 2, | ||
6586 | .items = { | ||
6587 | { "Mic", 0x0 }, | ||
6588 | /* Front Mic (0x01) unused */ | ||
6589 | { "Line", 0x2 }, | ||
6590 | /* Line 2 (0x03) unused */ | ||
6591 | /* CD (0x04) unsused? */ | ||
6592 | }, | ||
6593 | }; | ||
6594 | |||
6595 | /* | ||
6596 | * 2ch mode | ||
6597 | */ | ||
6598 | static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { | ||
6599 | { 2, NULL } | ||
6600 | }; | ||
6601 | |||
6355 | /* | 6602 | /* |
6356 | * 2ch mode | 6603 | * 2ch mode |
6357 | */ | 6604 | */ |
@@ -6364,6 +6611,18 @@ static struct hda_verb alc882_3ST_ch2_init[] = { | |||
6364 | }; | 6611 | }; |
6365 | 6612 | ||
6366 | /* | 6613 | /* |
6614 | * 4ch mode | ||
6615 | */ | ||
6616 | static struct hda_verb alc882_3ST_ch4_init[] = { | ||
6617 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
6618 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6619 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6620 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6621 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6622 | { } /* end */ | ||
6623 | }; | ||
6624 | |||
6625 | /* | ||
6367 | * 6ch mode | 6626 | * 6ch mode |
6368 | */ | 6627 | */ |
6369 | static struct hda_verb alc882_3ST_ch6_init[] = { | 6628 | static struct hda_verb alc882_3ST_ch6_init[] = { |
@@ -6376,11 +6635,14 @@ static struct hda_verb alc882_3ST_ch6_init[] = { | |||
6376 | { } /* end */ | 6635 | { } /* end */ |
6377 | }; | 6636 | }; |
6378 | 6637 | ||
6379 | static struct hda_channel_mode alc882_3ST_6ch_modes[2] = { | 6638 | static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { |
6380 | { 2, alc882_3ST_ch2_init }, | 6639 | { 2, alc882_3ST_ch2_init }, |
6640 | { 4, alc882_3ST_ch4_init }, | ||
6381 | { 6, alc882_3ST_ch6_init }, | 6641 | { 6, alc882_3ST_ch6_init }, |
6382 | }; | 6642 | }; |
6383 | 6643 | ||
6644 | #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes | ||
6645 | |||
6384 | /* | 6646 | /* |
6385 | * 6ch mode | 6647 | * 6ch mode |
6386 | */ | 6648 | */ |
@@ -6468,6 +6730,189 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { | |||
6468 | { 6, alc885_mb5_ch6_init }, | 6730 | { 6, alc885_mb5_ch6_init }, |
6469 | }; | 6731 | }; |
6470 | 6732 | ||
6733 | |||
6734 | /* | ||
6735 | * 2ch mode | ||
6736 | */ | ||
6737 | static struct hda_verb alc883_4ST_ch2_init[] = { | ||
6738 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6739 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6740 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
6741 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6742 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
6743 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6744 | { } /* end */ | ||
6745 | }; | ||
6746 | |||
6747 | /* | ||
6748 | * 4ch mode | ||
6749 | */ | ||
6750 | static struct hda_verb alc883_4ST_ch4_init[] = { | ||
6751 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6752 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6753 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
6754 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6755 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6756 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6757 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6758 | { } /* end */ | ||
6759 | }; | ||
6760 | |||
6761 | /* | ||
6762 | * 6ch mode | ||
6763 | */ | ||
6764 | static struct hda_verb alc883_4ST_ch6_init[] = { | ||
6765 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6766 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6767 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6768 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6769 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
6770 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6771 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6772 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6773 | { } /* end */ | ||
6774 | }; | ||
6775 | |||
6776 | /* | ||
6777 | * 8ch mode | ||
6778 | */ | ||
6779 | static struct hda_verb alc883_4ST_ch8_init[] = { | ||
6780 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6781 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6782 | { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, | ||
6783 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6784 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6785 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
6786 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6787 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6788 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6789 | { } /* end */ | ||
6790 | }; | ||
6791 | |||
6792 | static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { | ||
6793 | { 2, alc883_4ST_ch2_init }, | ||
6794 | { 4, alc883_4ST_ch4_init }, | ||
6795 | { 6, alc883_4ST_ch6_init }, | ||
6796 | { 8, alc883_4ST_ch8_init }, | ||
6797 | }; | ||
6798 | |||
6799 | |||
6800 | /* | ||
6801 | * 2ch mode | ||
6802 | */ | ||
6803 | static struct hda_verb alc883_3ST_ch2_intel_init[] = { | ||
6804 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
6805 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6806 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
6807 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6808 | { } /* end */ | ||
6809 | }; | ||
6810 | |||
6811 | /* | ||
6812 | * 4ch mode | ||
6813 | */ | ||
6814 | static struct hda_verb alc883_3ST_ch4_intel_init[] = { | ||
6815 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
6816 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6817 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6818 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6819 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6820 | { } /* end */ | ||
6821 | }; | ||
6822 | |||
6823 | /* | ||
6824 | * 6ch mode | ||
6825 | */ | ||
6826 | static struct hda_verb alc883_3ST_ch6_intel_init[] = { | ||
6827 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6828 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6829 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
6830 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6831 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6832 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6833 | { } /* end */ | ||
6834 | }; | ||
6835 | |||
6836 | static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { | ||
6837 | { 2, alc883_3ST_ch2_intel_init }, | ||
6838 | { 4, alc883_3ST_ch4_intel_init }, | ||
6839 | { 6, alc883_3ST_ch6_intel_init }, | ||
6840 | }; | ||
6841 | |||
6842 | /* | ||
6843 | * 2ch mode | ||
6844 | */ | ||
6845 | static struct hda_verb alc889_ch2_intel_init[] = { | ||
6846 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6847 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6848 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6849 | { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6850 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
6851 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6852 | { } /* end */ | ||
6853 | }; | ||
6854 | |||
6855 | /* | ||
6856 | * 6ch mode | ||
6857 | */ | ||
6858 | static struct hda_verb alc889_ch6_intel_init[] = { | ||
6859 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6860 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6861 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
6862 | { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, | ||
6863 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
6864 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6865 | { } /* end */ | ||
6866 | }; | ||
6867 | |||
6868 | /* | ||
6869 | * 8ch mode | ||
6870 | */ | ||
6871 | static struct hda_verb alc889_ch8_intel_init[] = { | ||
6872 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6873 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
6874 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
6875 | { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, | ||
6876 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 }, | ||
6877 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6878 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6879 | { } /* end */ | ||
6880 | }; | ||
6881 | |||
6882 | static struct hda_channel_mode alc889_8ch_intel_modes[3] = { | ||
6883 | { 2, alc889_ch2_intel_init }, | ||
6884 | { 6, alc889_ch6_intel_init }, | ||
6885 | { 8, alc889_ch8_intel_init }, | ||
6886 | }; | ||
6887 | |||
6888 | /* | ||
6889 | * 6ch mode | ||
6890 | */ | ||
6891 | static struct hda_verb alc883_sixstack_ch6_init[] = { | ||
6892 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
6893 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6894 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6895 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6896 | { } /* end */ | ||
6897 | }; | ||
6898 | |||
6899 | /* | ||
6900 | * 8ch mode | ||
6901 | */ | ||
6902 | static struct hda_verb alc883_sixstack_ch8_init[] = { | ||
6903 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6904 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6905 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6906 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6907 | { } /* end */ | ||
6908 | }; | ||
6909 | |||
6910 | static struct hda_channel_mode alc883_sixstack_modes[2] = { | ||
6911 | { 6, alc883_sixstack_ch6_init }, | ||
6912 | { 8, alc883_sixstack_ch8_init }, | ||
6913 | }; | ||
6914 | |||
6915 | |||
6471 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | 6916 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 |
6472 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | 6917 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b |
6473 | */ | 6918 | */ |
@@ -6603,7 +7048,7 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = { | |||
6603 | { } /* end */ | 7048 | { } /* end */ |
6604 | }; | 7049 | }; |
6605 | 7050 | ||
6606 | static struct hda_verb alc882_init_verbs[] = { | 7051 | static struct hda_verb alc882_base_init_verbs[] = { |
6607 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | 7052 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ |
6608 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 7053 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
6609 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 7054 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
@@ -6621,6 +7066,13 @@ static struct hda_verb alc882_init_verbs[] = { | |||
6621 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 7066 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
6622 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 7067 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
6623 | 7068 | ||
7069 | /* mute analog input loopbacks */ | ||
7070 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7071 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
7072 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
7073 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
7074 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
7075 | |||
6624 | /* Front Pin: output 0 (0x0c) */ | 7076 | /* Front Pin: output 0 (0x0c) */ |
6625 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 7077 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
6626 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 7078 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -6655,11 +7107,6 @@ static struct hda_verb alc882_init_verbs[] = { | |||
6655 | 7107 | ||
6656 | /* FIXME: use matrix-type input source selection */ | 7108 | /* FIXME: use matrix-type input source selection */ |
6657 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | 7109 | /* 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 */ | 7110 | /* Input mixer2 */ |
6664 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7111 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
6665 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 7112 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
@@ -6670,9 +7117,6 @@ static struct hda_verb alc882_init_verbs[] = { | |||
6670 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 7117 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
6671 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | 7118 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
6672 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | 7119 | {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 */ | 7120 | /* ADC2: mute amp left and right */ |
6677 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 7121 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
6678 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | 7122 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -6683,6 +7127,18 @@ static struct hda_verb alc882_init_verbs[] = { | |||
6683 | { } | 7127 | { } |
6684 | }; | 7128 | }; |
6685 | 7129 | ||
7130 | static struct hda_verb alc882_adc1_init_verbs[] = { | ||
7131 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
7132 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7133 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
7134 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
7135 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
7136 | /* ADC1: mute amp left and right */ | ||
7137 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7138 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7139 | { } | ||
7140 | }; | ||
7141 | |||
6686 | static struct hda_verb alc882_eapd_verbs[] = { | 7142 | static struct hda_verb alc882_eapd_verbs[] = { |
6687 | /* change to EAPD mode */ | 7143 | /* change to EAPD mode */ |
6688 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | 7144 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, |
@@ -6690,6 +7146,110 @@ static struct hda_verb alc882_eapd_verbs[] = { | |||
6690 | { } | 7146 | { } |
6691 | }; | 7147 | }; |
6692 | 7148 | ||
7149 | static struct hda_verb alc889_eapd_verbs[] = { | ||
7150 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
7151 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
7152 | { } | ||
7153 | }; | ||
7154 | |||
7155 | static struct hda_verb alc_hp15_unsol_verbs[] = { | ||
7156 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
7157 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
7158 | {} | ||
7159 | }; | ||
7160 | |||
7161 | static struct hda_verb alc885_init_verbs[] = { | ||
7162 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | ||
7163 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
7164 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7165 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
7166 | /* Rear mixer */ | ||
7167 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
7168 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7169 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
7170 | /* CLFE mixer */ | ||
7171 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
7172 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7173 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
7174 | /* Side mixer */ | ||
7175 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
7176 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7177 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
7178 | |||
7179 | /* mute analog input loopbacks */ | ||
7180 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7181 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
7182 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
7183 | |||
7184 | /* Front HP Pin: output 0 (0x0c) */ | ||
7185 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
7186 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7187 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7188 | /* Front Pin: output 0 (0x0c) */ | ||
7189 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
7190 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7191 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7192 | /* Rear Pin: output 1 (0x0d) */ | ||
7193 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
7194 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7195 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
7196 | /* CLFE Pin: output 2 (0x0e) */ | ||
7197 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
7198 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7199 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
7200 | /* Side Pin: output 3 (0x0f) */ | ||
7201 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
7202 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7203 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
7204 | /* Mic (rear) pin: input vref at 80% */ | ||
7205 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
7206 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
7207 | /* Front Mic pin: input vref at 80% */ | ||
7208 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
7209 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
7210 | /* Line In pin: input */ | ||
7211 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
7212 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
7213 | |||
7214 | /* Mixer elements: 0x18, , 0x1a, 0x1b */ | ||
7215 | /* Input mixer1 */ | ||
7216 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7217 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7218 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
7219 | /* Input mixer2 */ | ||
7220 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7221 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
7222 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
7223 | /* Input mixer3 */ | ||
7224 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
7225 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7226 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
7227 | /* ADC2: mute amp left and right */ | ||
7228 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7229 | /* ADC3: mute amp left and right */ | ||
7230 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
7231 | |||
7232 | { } | ||
7233 | }; | ||
7234 | |||
7235 | static struct hda_verb alc885_init_input_verbs[] = { | ||
7236 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7237 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
7238 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
7239 | { } | ||
7240 | }; | ||
7241 | |||
7242 | |||
7243 | /* Unmute Selector 24h and set the default input to front mic */ | ||
7244 | static struct hda_verb alc889_init_input_verbs[] = { | ||
7245 | {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7246 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7247 | { } | ||
7248 | }; | ||
7249 | |||
7250 | |||
7251 | #define alc883_init_verbs alc882_base_init_verbs | ||
7252 | |||
6693 | /* Mac Pro test */ | 7253 | /* Mac Pro test */ |
6694 | static struct snd_kcontrol_new alc882_macpro_mixer[] = { | 7254 | static struct snd_kcontrol_new alc882_macpro_mixer[] = { |
6695 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 7255 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
@@ -6893,23 +7453,21 @@ static struct hda_verb alc885_imac24_init_verbs[] = { | |||
6893 | }; | 7453 | }; |
6894 | 7454 | ||
6895 | /* Toggle speaker-output according to the hp-jack state */ | 7455 | /* Toggle speaker-output according to the hp-jack state */ |
6896 | static void alc885_imac24_automute_init_hook(struct hda_codec *codec) | 7456 | static void alc885_imac24_setup(struct hda_codec *codec) |
6897 | { | 7457 | { |
6898 | struct alc_spec *spec = codec->spec; | 7458 | struct alc_spec *spec = codec->spec; |
6899 | 7459 | ||
6900 | spec->autocfg.hp_pins[0] = 0x14; | 7460 | spec->autocfg.hp_pins[0] = 0x14; |
6901 | spec->autocfg.speaker_pins[0] = 0x18; | 7461 | spec->autocfg.speaker_pins[0] = 0x18; |
6902 | spec->autocfg.speaker_pins[1] = 0x1a; | 7462 | spec->autocfg.speaker_pins[1] = 0x1a; |
6903 | alc_automute_amp(codec); | ||
6904 | } | 7463 | } |
6905 | 7464 | ||
6906 | static void alc885_mbp3_init_hook(struct hda_codec *codec) | 7465 | static void alc885_mbp3_setup(struct hda_codec *codec) |
6907 | { | 7466 | { |
6908 | struct alc_spec *spec = codec->spec; | 7467 | struct alc_spec *spec = codec->spec; |
6909 | 7468 | ||
6910 | spec->autocfg.hp_pins[0] = 0x15; | 7469 | spec->autocfg.hp_pins[0] = 0x15; |
6911 | spec->autocfg.speaker_pins[0] = 0x14; | 7470 | spec->autocfg.speaker_pins[0] = 0x14; |
6912 | alc_automute_amp(codec); | ||
6913 | } | 7471 | } |
6914 | 7472 | ||
6915 | 7473 | ||
@@ -6937,13 +7495,12 @@ static void alc882_targa_automute(struct hda_codec *codec) | |||
6937 | spec->jack_present ? 1 : 3); | 7495 | spec->jack_present ? 1 : 3); |
6938 | } | 7496 | } |
6939 | 7497 | ||
6940 | static void alc882_targa_init_hook(struct hda_codec *codec) | 7498 | static void alc882_targa_setup(struct hda_codec *codec) |
6941 | { | 7499 | { |
6942 | struct alc_spec *spec = codec->spec; | 7500 | struct alc_spec *spec = codec->spec; |
6943 | 7501 | ||
6944 | spec->autocfg.hp_pins[0] = 0x14; | 7502 | spec->autocfg.hp_pins[0] = 0x14; |
6945 | spec->autocfg.speaker_pins[0] = 0x1b; | 7503 | spec->autocfg.speaker_pins[0] = 0x1b; |
6946 | alc882_targa_automute(codec); | ||
6947 | } | 7504 | } |
6948 | 7505 | ||
6949 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) | 7506 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -7031,18 +7588,16 @@ static void alc885_macpro_init_hook(struct hda_codec *codec) | |||
7031 | static void alc885_imac24_init_hook(struct hda_codec *codec) | 7588 | static void alc885_imac24_init_hook(struct hda_codec *codec) |
7032 | { | 7589 | { |
7033 | alc885_macpro_init_hook(codec); | 7590 | alc885_macpro_init_hook(codec); |
7034 | alc885_imac24_automute_init_hook(codec); | 7591 | alc_automute_amp(codec); |
7035 | } | 7592 | } |
7036 | 7593 | ||
7037 | /* | 7594 | /* |
7038 | * generic initialization of ADC, input mixers and output mixers | 7595 | * generic initialization of ADC, input mixers and output mixers |
7039 | */ | 7596 | */ |
7040 | static struct hda_verb alc882_auto_init_verbs[] = { | 7597 | static struct hda_verb alc883_auto_init_verbs[] = { |
7041 | /* | 7598 | /* |
7042 | * Unmute ADC0-2 and set the default input to mic-in | 7599 | * Unmute ADC0-2 and set the default input to mic-in |
7043 | */ | 7600 | */ |
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}, | 7601 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, |
7047 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 7602 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
7048 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | 7603 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -7083,11 +7638,6 @@ static struct hda_verb alc882_auto_init_verbs[] = { | |||
7083 | 7638 | ||
7084 | /* FIXME: use matrix-type input source selection */ | 7639 | /* FIXME: use matrix-type input source selection */ |
7085 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | 7640 | /* 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 */ | 7641 | /* Input mixer2 */ |
7092 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | 7642 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, |
7093 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, | 7643 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, |
@@ -7102,820 +7652,6 @@ static struct hda_verb alc882_auto_init_verbs[] = { | |||
7102 | { } | 7652 | { } |
7103 | }; | 7653 | }; |
7104 | 7654 | ||
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) */ | 7655 | /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ |
7920 | static struct hda_verb alc889A_mb31_ch2_init[] = { | 7656 | static struct hda_verb alc889A_mb31_ch2_init[] = { |
7921 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ | 7657 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ |
@@ -7966,34 +7702,7 @@ static struct hda_verb alc883_medion_eapd_verbs[] = { | |||
7966 | { } | 7702 | { } |
7967 | }; | 7703 | }; |
7968 | 7704 | ||
7969 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | 7705 | #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 | 7706 | ||
7998 | static struct snd_kcontrol_new alc883_mitac_mixer[] = { | 7707 | static struct snd_kcontrol_new alc883_mitac_mixer[] = { |
7999 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 7708 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
@@ -8104,6 +7813,30 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { | |||
8104 | { } /* end */ | 7813 | { } /* end */ |
8105 | }; | 7814 | }; |
8106 | 7815 | ||
7816 | static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { | ||
7817 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
7818 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
7819 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
7820 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
7821 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, | ||
7822 | HDA_OUTPUT), | ||
7823 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
7824 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
7825 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
7826 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | ||
7827 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT), | ||
7828 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
7829 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
7830 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
7831 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), | ||
7832 | HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT), | ||
7833 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), | ||
7834 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
7835 | HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), | ||
7836 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
7837 | { } /* end */ | ||
7838 | }; | ||
7839 | |||
8107 | static struct snd_kcontrol_new alc883_fivestack_mixer[] = { | 7840 | static struct snd_kcontrol_new alc883_fivestack_mixer[] = { |
8108 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 7841 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8109 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 7842 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
@@ -8344,93 +8077,14 @@ static struct snd_kcontrol_new alc883_chmode_mixer[] = { | |||
8344 | { } /* end */ | 8077 | { } /* end */ |
8345 | }; | 8078 | }; |
8346 | 8079 | ||
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 */ | 8080 | /* toggle speaker-output according to the hp-jack state */ |
8426 | static void alc883_mitac_init_hook(struct hda_codec *codec) | 8081 | static void alc883_mitac_setup(struct hda_codec *codec) |
8427 | { | 8082 | { |
8428 | struct alc_spec *spec = codec->spec; | 8083 | struct alc_spec *spec = codec->spec; |
8429 | 8084 | ||
8430 | spec->autocfg.hp_pins[0] = 0x15; | 8085 | spec->autocfg.hp_pins[0] = 0x15; |
8431 | spec->autocfg.speaker_pins[0] = 0x14; | 8086 | spec->autocfg.speaker_pins[0] = 0x14; |
8432 | spec->autocfg.speaker_pins[1] = 0x17; | 8087 | spec->autocfg.speaker_pins[1] = 0x17; |
8433 | alc_automute_amp(codec); | ||
8434 | } | 8088 | } |
8435 | 8089 | ||
8436 | /* auto-toggle front mic */ | 8090 | /* auto-toggle front mic */ |
@@ -8585,7 +8239,7 @@ static struct hda_verb alc883_vaiott_verbs[] = { | |||
8585 | { } /* end */ | 8239 | { } /* end */ |
8586 | }; | 8240 | }; |
8587 | 8241 | ||
8588 | static void alc888_3st_hp_init_hook(struct hda_codec *codec) | 8242 | static void alc888_3st_hp_setup(struct hda_codec *codec) |
8589 | { | 8243 | { |
8590 | struct alc_spec *spec = codec->spec; | 8244 | struct alc_spec *spec = codec->spec; |
8591 | 8245 | ||
@@ -8593,7 +8247,6 @@ static void alc888_3st_hp_init_hook(struct hda_codec *codec) | |||
8593 | spec->autocfg.speaker_pins[0] = 0x14; | 8247 | spec->autocfg.speaker_pins[0] = 0x14; |
8594 | spec->autocfg.speaker_pins[1] = 0x16; | 8248 | spec->autocfg.speaker_pins[1] = 0x16; |
8595 | spec->autocfg.speaker_pins[2] = 0x18; | 8249 | spec->autocfg.speaker_pins[2] = 0x18; |
8596 | alc_automute_amp(codec); | ||
8597 | } | 8250 | } |
8598 | 8251 | ||
8599 | static struct hda_verb alc888_3st_hp_verbs[] = { | 8252 | static struct hda_verb alc888_3st_hp_verbs[] = { |
@@ -8690,13 +8343,12 @@ static struct hda_verb alc883_medion_md2_verbs[] = { | |||
8690 | }; | 8343 | }; |
8691 | 8344 | ||
8692 | /* toggle speaker-output according to the hp-jack state */ | 8345 | /* toggle speaker-output according to the hp-jack state */ |
8693 | static void alc883_medion_md2_init_hook(struct hda_codec *codec) | 8346 | static void alc883_medion_md2_setup(struct hda_codec *codec) |
8694 | { | 8347 | { |
8695 | struct alc_spec *spec = codec->spec; | 8348 | struct alc_spec *spec = codec->spec; |
8696 | 8349 | ||
8697 | spec->autocfg.hp_pins[0] = 0x14; | 8350 | spec->autocfg.hp_pins[0] = 0x14; |
8698 | spec->autocfg.speaker_pins[0] = 0x15; | 8351 | spec->autocfg.speaker_pins[0] = 0x15; |
8699 | alc_automute_amp(codec); | ||
8700 | } | 8352 | } |
8701 | 8353 | ||
8702 | /* toggle speaker-output according to the hp-jack state */ | 8354 | /* toggle speaker-output according to the hp-jack state */ |
@@ -8713,12 +8365,16 @@ static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) | |||
8713 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 8365 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
8714 | } | 8366 | } |
8715 | 8367 | ||
8716 | static void alc883_clevo_m720_init_hook(struct hda_codec *codec) | 8368 | static void alc883_clevo_m720_setup(struct hda_codec *codec) |
8717 | { | 8369 | { |
8718 | struct alc_spec *spec = codec->spec; | 8370 | struct alc_spec *spec = codec->spec; |
8719 | 8371 | ||
8720 | spec->autocfg.hp_pins[0] = 0x15; | 8372 | spec->autocfg.hp_pins[0] = 0x15; |
8721 | spec->autocfg.speaker_pins[0] = 0x14; | 8373 | spec->autocfg.speaker_pins[0] = 0x14; |
8374 | } | ||
8375 | |||
8376 | static void alc883_clevo_m720_init_hook(struct hda_codec *codec) | ||
8377 | { | ||
8722 | alc_automute_amp(codec); | 8378 | alc_automute_amp(codec); |
8723 | alc883_clevo_m720_mic_automute(codec); | 8379 | alc883_clevo_m720_mic_automute(codec); |
8724 | } | 8380 | } |
@@ -8737,22 +8393,20 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, | |||
8737 | } | 8393 | } |
8738 | 8394 | ||
8739 | /* toggle speaker-output according to the hp-jack state */ | 8395 | /* toggle speaker-output according to the hp-jack state */ |
8740 | static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec) | 8396 | static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) |
8741 | { | 8397 | { |
8742 | struct alc_spec *spec = codec->spec; | 8398 | struct alc_spec *spec = codec->spec; |
8743 | 8399 | ||
8744 | spec->autocfg.hp_pins[0] = 0x14; | 8400 | spec->autocfg.hp_pins[0] = 0x14; |
8745 | spec->autocfg.speaker_pins[0] = 0x15; | 8401 | spec->autocfg.speaker_pins[0] = 0x15; |
8746 | alc_automute_amp(codec); | ||
8747 | } | 8402 | } |
8748 | 8403 | ||
8749 | static void alc883_haier_w66_init_hook(struct hda_codec *codec) | 8404 | static void alc883_haier_w66_setup(struct hda_codec *codec) |
8750 | { | 8405 | { |
8751 | struct alc_spec *spec = codec->spec; | 8406 | struct alc_spec *spec = codec->spec; |
8752 | 8407 | ||
8753 | spec->autocfg.hp_pins[0] = 0x1b; | 8408 | spec->autocfg.hp_pins[0] = 0x1b; |
8754 | spec->autocfg.speaker_pins[0] = 0x14; | 8409 | spec->autocfg.speaker_pins[0] = 0x14; |
8755 | alc_automute_amp(codec); | ||
8756 | } | 8410 | } |
8757 | 8411 | ||
8758 | static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | 8412 | static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) |
@@ -8791,14 +8445,13 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, | |||
8791 | } | 8445 | } |
8792 | 8446 | ||
8793 | /* toggle speaker-output according to the hp-jack state */ | 8447 | /* toggle speaker-output according to the hp-jack state */ |
8794 | static void alc883_acer_aspire_init_hook(struct hda_codec *codec) | 8448 | static void alc883_acer_aspire_setup(struct hda_codec *codec) |
8795 | { | 8449 | { |
8796 | struct alc_spec *spec = codec->spec; | 8450 | struct alc_spec *spec = codec->spec; |
8797 | 8451 | ||
8798 | spec->autocfg.hp_pins[0] = 0x14; | 8452 | spec->autocfg.hp_pins[0] = 0x14; |
8799 | spec->autocfg.speaker_pins[0] = 0x15; | 8453 | spec->autocfg.speaker_pins[0] = 0x15; |
8800 | spec->autocfg.speaker_pins[1] = 0x16; | 8454 | spec->autocfg.speaker_pins[1] = 0x16; |
8801 | alc_automute_amp(codec); | ||
8802 | } | 8455 | } |
8803 | 8456 | ||
8804 | static struct hda_verb alc883_acer_eapd_verbs[] = { | 8457 | static struct hda_verb alc883_acer_eapd_verbs[] = { |
@@ -8819,7 +8472,7 @@ static struct hda_verb alc883_acer_eapd_verbs[] = { | |||
8819 | { } | 8472 | { } |
8820 | }; | 8473 | }; |
8821 | 8474 | ||
8822 | static void alc888_6st_dell_init_hook(struct hda_codec *codec) | 8475 | static void alc888_6st_dell_setup(struct hda_codec *codec) |
8823 | { | 8476 | { |
8824 | struct alc_spec *spec = codec->spec; | 8477 | struct alc_spec *spec = codec->spec; |
8825 | 8478 | ||
@@ -8828,10 +8481,9 @@ static void alc888_6st_dell_init_hook(struct hda_codec *codec) | |||
8828 | spec->autocfg.speaker_pins[1] = 0x15; | 8481 | spec->autocfg.speaker_pins[1] = 0x15; |
8829 | spec->autocfg.speaker_pins[2] = 0x16; | 8482 | spec->autocfg.speaker_pins[2] = 0x16; |
8830 | spec->autocfg.speaker_pins[3] = 0x17; | 8483 | spec->autocfg.speaker_pins[3] = 0x17; |
8831 | alc_automute_amp(codec); | ||
8832 | } | 8484 | } |
8833 | 8485 | ||
8834 | static void alc888_lenovo_sky_init_hook(struct hda_codec *codec) | 8486 | static void alc888_lenovo_sky_setup(struct hda_codec *codec) |
8835 | { | 8487 | { |
8836 | struct alc_spec *spec = codec->spec; | 8488 | struct alc_spec *spec = codec->spec; |
8837 | 8489 | ||
@@ -8841,82 +8493,17 @@ static void alc888_lenovo_sky_init_hook(struct hda_codec *codec) | |||
8841 | spec->autocfg.speaker_pins[2] = 0x16; | 8493 | spec->autocfg.speaker_pins[2] = 0x16; |
8842 | spec->autocfg.speaker_pins[3] = 0x17; | 8494 | spec->autocfg.speaker_pins[3] = 0x17; |
8843 | spec->autocfg.speaker_pins[4] = 0x1a; | 8495 | spec->autocfg.speaker_pins[4] = 0x1a; |
8844 | alc_automute_amp(codec); | ||
8845 | } | 8496 | } |
8846 | 8497 | ||
8847 | static void alc883_vaiott_init_hook(struct hda_codec *codec) | 8498 | static void alc883_vaiott_setup(struct hda_codec *codec) |
8848 | { | 8499 | { |
8849 | struct alc_spec *spec = codec->spec; | 8500 | struct alc_spec *spec = codec->spec; |
8850 | 8501 | ||
8851 | spec->autocfg.hp_pins[0] = 0x15; | 8502 | spec->autocfg.hp_pins[0] = 0x15; |
8852 | spec->autocfg.speaker_pins[0] = 0x14; | 8503 | spec->autocfg.speaker_pins[0] = 0x14; |
8853 | spec->autocfg.speaker_pins[1] = 0x17; | 8504 | spec->autocfg.speaker_pins[1] = 0x17; |
8854 | alc_automute_amp(codec); | ||
8855 | } | 8505 | } |
8856 | 8506 | ||
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[] = { | 8507 | static struct hda_verb alc888_asus_m90v_verbs[] = { |
8921 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8508 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
8922 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8509 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
@@ -8927,19 +8514,7 @@ static struct hda_verb alc888_asus_m90v_verbs[] = { | |||
8927 | { } /* end */ | 8514 | { } /* end */ |
8928 | }; | 8515 | }; |
8929 | 8516 | ||
8930 | static void alc883_nb_mic_automute(struct hda_codec *codec) | 8517 | static void alc883_mode2_setup(struct hda_codec *codec) |
8931 | { | ||
8932 | unsigned int present; | ||
8933 | |||
8934 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
8935 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8936 | snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
8937 | 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); | ||
8938 | snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
8939 | 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); | ||
8940 | } | ||
8941 | |||
8942 | static void alc883_M90V_init_hook(struct hda_codec *codec) | ||
8943 | { | 8518 | { |
8944 | struct alc_spec *spec = codec->spec; | 8519 | struct alc_spec *spec = codec->spec; |
8945 | 8520 | ||
@@ -8947,26 +8522,11 @@ static void alc883_M90V_init_hook(struct hda_codec *codec) | |||
8947 | spec->autocfg.speaker_pins[0] = 0x14; | 8522 | spec->autocfg.speaker_pins[0] = 0x14; |
8948 | spec->autocfg.speaker_pins[1] = 0x15; | 8523 | spec->autocfg.speaker_pins[1] = 0x15; |
8949 | spec->autocfg.speaker_pins[2] = 0x16; | 8524 | spec->autocfg.speaker_pins[2] = 0x16; |
8950 | alc_automute_pin(codec); | 8525 | spec->ext_mic.pin = 0x18; |
8951 | } | 8526 | spec->int_mic.pin = 0x19; |
8952 | 8527 | spec->ext_mic.mux_idx = 0; | |
8953 | static void alc883_mode2_unsol_event(struct hda_codec *codec, | 8528 | spec->int_mic.mux_idx = 1; |
8954 | unsigned int res) | 8529 | spec->auto_mic = 1; |
8955 | { | ||
8956 | switch (res >> 26) { | ||
8957 | case ALC880_MIC_EVENT: | ||
8958 | alc883_nb_mic_automute(codec); | ||
8959 | break; | ||
8960 | default: | ||
8961 | alc_sku_unsol_event(codec, res); | ||
8962 | break; | ||
8963 | } | ||
8964 | } | ||
8965 | |||
8966 | static void alc883_mode2_inithook(struct hda_codec *codec) | ||
8967 | { | ||
8968 | alc883_M90V_init_hook(codec); | ||
8969 | alc883_nb_mic_automute(codec); | ||
8970 | } | 8530 | } |
8971 | 8531 | ||
8972 | static struct hda_verb alc888_asus_eee1601_verbs[] = { | 8532 | static struct hda_verb alc888_asus_eee1601_verbs[] = { |
@@ -9027,25 +8587,44 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) | |||
9027 | alc889A_mb31_automute(codec); | 8587 | alc889A_mb31_automute(codec); |
9028 | } | 8588 | } |
9029 | 8589 | ||
8590 | |||
9030 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 8591 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
9031 | #define alc883_loopbacks alc880_loopbacks | 8592 | #define alc882_loopbacks alc880_loopbacks |
9032 | #endif | 8593 | #endif |
9033 | 8594 | ||
9034 | /* pcm configuration: identical with ALC880 */ | 8595 | /* pcm configuration: identical with ALC880 */ |
9035 | #define alc883_pcm_analog_playback alc880_pcm_analog_playback | 8596 | #define alc882_pcm_analog_playback alc880_pcm_analog_playback |
9036 | #define alc883_pcm_analog_capture alc880_pcm_analog_capture | 8597 | #define alc882_pcm_analog_capture alc880_pcm_analog_capture |
9037 | #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture | 8598 | #define alc882_pcm_digital_playback alc880_pcm_digital_playback |
9038 | #define alc883_pcm_digital_playback alc880_pcm_digital_playback | 8599 | #define alc882_pcm_digital_capture alc880_pcm_digital_capture |
9039 | #define alc883_pcm_digital_capture alc880_pcm_digital_capture | 8600 | |
8601 | static hda_nid_t alc883_slave_dig_outs[] = { | ||
8602 | ALC1200_DIGOUT_NID, 0, | ||
8603 | }; | ||
8604 | |||
8605 | static hda_nid_t alc1200_slave_dig_outs[] = { | ||
8606 | ALC883_DIGOUT_NID, 0, | ||
8607 | }; | ||
9040 | 8608 | ||
9041 | /* | 8609 | /* |
9042 | * configuration and preset | 8610 | * configuration and preset |
9043 | */ | 8611 | */ |
9044 | static const char *alc883_models[ALC883_MODEL_LAST] = { | 8612 | static const char *alc882_models[ALC882_MODEL_LAST] = { |
9045 | [ALC883_3ST_2ch_DIG] = "3stack-dig", | 8613 | [ALC882_3ST_DIG] = "3stack-dig", |
8614 | [ALC882_6ST_DIG] = "6stack-dig", | ||
8615 | [ALC882_ARIMA] = "arima", | ||
8616 | [ALC882_W2JC] = "w2jc", | ||
8617 | [ALC882_TARGA] = "targa", | ||
8618 | [ALC882_ASUS_A7J] = "asus-a7j", | ||
8619 | [ALC882_ASUS_A7M] = "asus-a7m", | ||
8620 | [ALC885_MACPRO] = "macpro", | ||
8621 | [ALC885_MB5] = "mb5", | ||
8622 | [ALC885_MBP3] = "mbp3", | ||
8623 | [ALC885_IMAC24] = "imac24", | ||
8624 | [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", | ||
9046 | [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", | 8625 | [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", |
9047 | [ALC883_3ST_6ch] = "3stack-6ch", | 8626 | [ALC883_3ST_6ch] = "3stack-6ch", |
9048 | [ALC883_6ST_DIG] = "6stack-dig", | 8627 | [ALC883_6ST_DIG] = "alc883-6stack-dig", |
9049 | [ALC883_TARGA_DIG] = "targa-dig", | 8628 | [ALC883_TARGA_DIG] = "targa-dig", |
9050 | [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", | 8629 | [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", |
9051 | [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", | 8630 | [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", |
@@ -9069,14 +8648,17 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { | |||
9069 | [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", | 8648 | [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", |
9070 | [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", | 8649 | [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", |
9071 | [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", | 8650 | [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", |
8651 | [ALC889A_INTEL] = "intel-alc889a", | ||
8652 | [ALC889_INTEL] = "intel-x58", | ||
9072 | [ALC1200_ASUS_P5Q] = "asus-p5q", | 8653 | [ALC1200_ASUS_P5Q] = "asus-p5q", |
9073 | [ALC889A_MB31] = "mb31", | 8654 | [ALC889A_MB31] = "mb31", |
9074 | [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", | 8655 | [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", |
9075 | [ALC883_AUTO] = "auto", | 8656 | [ALC882_AUTO] = "auto", |
9076 | }; | 8657 | }; |
9077 | 8658 | ||
9078 | static struct snd_pci_quirk alc883_cfg_tbl[] = { | 8659 | static struct snd_pci_quirk alc882_cfg_tbl[] = { |
9079 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), | 8660 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), |
8661 | |||
9080 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), | 8662 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), |
9081 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), | 8663 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), |
9082 | SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), | 8664 | SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), |
@@ -9091,8 +8673,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
9091 | ALC888_ACER_ASPIRE_8930G), | 8673 | ALC888_ACER_ASPIRE_8930G), |
9092 | SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", | 8674 | SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", |
9093 | ALC888_ACER_ASPIRE_8930G), | 8675 | ALC888_ACER_ASPIRE_8930G), |
9094 | SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), | 8676 | SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO), |
9095 | SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), | 8677 | SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO), |
9096 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", | 8678 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", |
9097 | ALC888_ACER_ASPIRE_6530G), | 8679 | ALC888_ACER_ASPIRE_6530G), |
9098 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", | 8680 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", |
@@ -9101,30 +8683,44 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
9101 | * model=auto should work fine now | 8683 | * model=auto should work fine now |
9102 | */ | 8684 | */ |
9103 | /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ | 8685 | /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ |
8686 | |||
9104 | SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), | 8687 | SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), |
8688 | |||
9105 | SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), | 8689 | SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), |
9106 | SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), | 8690 | SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), |
9107 | SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), | 8691 | SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), |
9108 | SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), | 8692 | SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), |
9109 | SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), | 8693 | SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), |
9110 | SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), | 8694 | SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), |
8695 | |||
8696 | SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), | ||
8697 | SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), | ||
8698 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), | ||
9111 | SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), | 8699 | SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), |
8700 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), | ||
8701 | SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), | ||
8702 | SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), | ||
9112 | SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), | 8703 | SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), |
9113 | SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), | 8704 | SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), |
9114 | SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), | 8705 | SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), |
9115 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), | 8706 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), |
8707 | |||
8708 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT), | ||
9116 | SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), | 8709 | SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), |
9117 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), | 8710 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), |
9118 | SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), | 8711 | SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), |
9119 | SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), | 8712 | SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), |
9120 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), | 8713 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), |
9121 | SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), | 8714 | SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), |
9122 | SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), | 8715 | SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), |
9123 | SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), | 8716 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), |
8717 | |||
9124 | SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), | 8718 | SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), |
9125 | SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), | 8719 | SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), |
9126 | SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), | 8720 | SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), |
8721 | SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ | ||
9127 | SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG), | 8722 | SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG), |
8723 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), | ||
9128 | SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), | 8724 | SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), |
9129 | SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), | 8725 | SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), |
9130 | SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), | 8726 | SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), |
@@ -9133,6 +8729,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
9133 | SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), | 8729 | SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), |
9134 | SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), | 8730 | SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), |
9135 | SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), | 8731 | SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), |
8732 | SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG), | ||
9136 | SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), | 8733 | SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), |
9137 | SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), | 8734 | SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), |
9138 | SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), | 8735 | SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), |
@@ -9146,11 +8743,14 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
9146 | SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), | 8743 | SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), |
9147 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), | 8744 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), |
9148 | SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), | 8745 | SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), |
8746 | SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), | ||
8747 | |||
9149 | SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), | 8748 | SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), |
9150 | SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), | 8749 | SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), |
9151 | SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), | 8750 | SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), |
9152 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), | 8751 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), |
9153 | SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), | 8752 | SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), |
8753 | /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */ | ||
9154 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), | 8754 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), |
9155 | SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", | 8755 | SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", |
9156 | ALC883_FUJITSU_PI2515), | 8756 | ALC883_FUJITSU_PI2515), |
@@ -9165,24 +8765,185 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
9165 | SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), | 8765 | SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), |
9166 | SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), | 8766 | SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), |
9167 | SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), | 8767 | SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), |
8768 | |||
9168 | SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), | 8769 | SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), |
9169 | SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), | 8770 | SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), |
9170 | SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), | 8771 | SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), |
9171 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), | 8772 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), |
8773 | SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), | ||
8774 | SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), | ||
9172 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), | 8775 | 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 | 8776 | ||
9177 | static hda_nid_t alc883_slave_dig_outs[] = { | 8777 | {} |
9178 | ALC1200_DIGOUT_NID, 0, | ||
9179 | }; | 8778 | }; |
9180 | 8779 | ||
9181 | static hda_nid_t alc1200_slave_dig_outs[] = { | 8780 | /* codec SSID table for Intel Mac */ |
9182 | ALC883_DIGOUT_NID, 0, | 8781 | static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { |
8782 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), | ||
8783 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), | ||
8784 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), | ||
8785 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO), | ||
8786 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), | ||
8787 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), | ||
8788 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), | ||
8789 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), | ||
8790 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), | ||
8791 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), | ||
8792 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), | ||
8793 | /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently | ||
8794 | * no perfect solution yet | ||
8795 | */ | ||
8796 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), | ||
8797 | {} /* terminator */ | ||
9183 | }; | 8798 | }; |
9184 | 8799 | ||
9185 | static struct alc_config_preset alc883_presets[] = { | 8800 | static struct alc_config_preset alc882_presets[] = { |
8801 | [ALC882_3ST_DIG] = { | ||
8802 | .mixers = { alc882_base_mixer }, | ||
8803 | .init_verbs = { alc882_base_init_verbs, | ||
8804 | alc882_adc1_init_verbs }, | ||
8805 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
8806 | .dac_nids = alc882_dac_nids, | ||
8807 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
8808 | .dig_in_nid = ALC882_DIGIN_NID, | ||
8809 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), | ||
8810 | .channel_mode = alc882_ch_modes, | ||
8811 | .need_dac_fix = 1, | ||
8812 | .input_mux = &alc882_capture_source, | ||
8813 | }, | ||
8814 | [ALC882_6ST_DIG] = { | ||
8815 | .mixers = { alc882_base_mixer, alc882_chmode_mixer }, | ||
8816 | .init_verbs = { alc882_base_init_verbs, | ||
8817 | alc882_adc1_init_verbs }, | ||
8818 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
8819 | .dac_nids = alc882_dac_nids, | ||
8820 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
8821 | .dig_in_nid = ALC882_DIGIN_NID, | ||
8822 | .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), | ||
8823 | .channel_mode = alc882_sixstack_modes, | ||
8824 | .input_mux = &alc882_capture_source, | ||
8825 | }, | ||
8826 | [ALC882_ARIMA] = { | ||
8827 | .mixers = { alc882_base_mixer, alc882_chmode_mixer }, | ||
8828 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, | ||
8829 | alc882_eapd_verbs }, | ||
8830 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
8831 | .dac_nids = alc882_dac_nids, | ||
8832 | .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), | ||
8833 | .channel_mode = alc882_sixstack_modes, | ||
8834 | .input_mux = &alc882_capture_source, | ||
8835 | }, | ||
8836 | [ALC882_W2JC] = { | ||
8837 | .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, | ||
8838 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, | ||
8839 | alc882_eapd_verbs, alc880_gpio1_init_verbs }, | ||
8840 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
8841 | .dac_nids = alc882_dac_nids, | ||
8842 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
8843 | .channel_mode = alc880_threestack_modes, | ||
8844 | .need_dac_fix = 1, | ||
8845 | .input_mux = &alc882_capture_source, | ||
8846 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
8847 | }, | ||
8848 | [ALC885_MBP3] = { | ||
8849 | .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, | ||
8850 | .init_verbs = { alc885_mbp3_init_verbs, | ||
8851 | alc880_gpio1_init_verbs }, | ||
8852 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
8853 | .dac_nids = alc882_dac_nids, | ||
8854 | .channel_mode = alc885_mbp_6ch_modes, | ||
8855 | .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes), | ||
8856 | .input_mux = &alc882_capture_source, | ||
8857 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
8858 | .dig_in_nid = ALC882_DIGIN_NID, | ||
8859 | .unsol_event = alc_automute_amp_unsol_event, | ||
8860 | .setup = alc885_mbp3_setup, | ||
8861 | .init_hook = alc_automute_amp, | ||
8862 | }, | ||
8863 | [ALC885_MB5] = { | ||
8864 | .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, | ||
8865 | .init_verbs = { alc885_mb5_init_verbs, | ||
8866 | alc880_gpio1_init_verbs }, | ||
8867 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
8868 | .dac_nids = alc882_dac_nids, | ||
8869 | .channel_mode = alc885_mb5_6ch_modes, | ||
8870 | .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes), | ||
8871 | .input_mux = &mb5_capture_source, | ||
8872 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
8873 | .dig_in_nid = ALC882_DIGIN_NID, | ||
8874 | }, | ||
8875 | [ALC885_MACPRO] = { | ||
8876 | .mixers = { alc882_macpro_mixer }, | ||
8877 | .init_verbs = { alc882_macpro_init_verbs }, | ||
8878 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
8879 | .dac_nids = alc882_dac_nids, | ||
8880 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
8881 | .dig_in_nid = ALC882_DIGIN_NID, | ||
8882 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), | ||
8883 | .channel_mode = alc882_ch_modes, | ||
8884 | .input_mux = &alc882_capture_source, | ||
8885 | .init_hook = alc885_macpro_init_hook, | ||
8886 | }, | ||
8887 | [ALC885_IMAC24] = { | ||
8888 | .mixers = { alc885_imac24_mixer }, | ||
8889 | .init_verbs = { alc885_imac24_init_verbs }, | ||
8890 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
8891 | .dac_nids = alc882_dac_nids, | ||
8892 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
8893 | .dig_in_nid = ALC882_DIGIN_NID, | ||
8894 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), | ||
8895 | .channel_mode = alc882_ch_modes, | ||
8896 | .input_mux = &alc882_capture_source, | ||
8897 | .unsol_event = alc_automute_amp_unsol_event, | ||
8898 | .setup = alc885_imac24_setup, | ||
8899 | .init_hook = alc885_imac24_init_hook, | ||
8900 | }, | ||
8901 | [ALC882_TARGA] = { | ||
8902 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, | ||
8903 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, | ||
8904 | alc880_gpio3_init_verbs, alc882_targa_verbs}, | ||
8905 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
8906 | .dac_nids = alc882_dac_nids, | ||
8907 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
8908 | .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), | ||
8909 | .adc_nids = alc882_adc_nids, | ||
8910 | .capsrc_nids = alc882_capsrc_nids, | ||
8911 | .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), | ||
8912 | .channel_mode = alc882_3ST_6ch_modes, | ||
8913 | .need_dac_fix = 1, | ||
8914 | .input_mux = &alc882_capture_source, | ||
8915 | .unsol_event = alc882_targa_unsol_event, | ||
8916 | .setup = alc882_targa_setup, | ||
8917 | .init_hook = alc882_targa_automute, | ||
8918 | }, | ||
8919 | [ALC882_ASUS_A7J] = { | ||
8920 | .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, | ||
8921 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, | ||
8922 | alc882_asus_a7j_verbs}, | ||
8923 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
8924 | .dac_nids = alc882_dac_nids, | ||
8925 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
8926 | .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), | ||
8927 | .adc_nids = alc882_adc_nids, | ||
8928 | .capsrc_nids = alc882_capsrc_nids, | ||
8929 | .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), | ||
8930 | .channel_mode = alc882_3ST_6ch_modes, | ||
8931 | .need_dac_fix = 1, | ||
8932 | .input_mux = &alc882_capture_source, | ||
8933 | }, | ||
8934 | [ALC882_ASUS_A7M] = { | ||
8935 | .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, | ||
8936 | .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, | ||
8937 | alc882_eapd_verbs, alc880_gpio1_init_verbs, | ||
8938 | alc882_asus_a7m_verbs }, | ||
8939 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
8940 | .dac_nids = alc882_dac_nids, | ||
8941 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
8942 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
8943 | .channel_mode = alc880_threestack_modes, | ||
8944 | .need_dac_fix = 1, | ||
8945 | .input_mux = &alc882_capture_source, | ||
8946 | }, | ||
9186 | [ALC883_3ST_2ch_DIG] = { | 8947 | [ALC883_3ST_2ch_DIG] = { |
9187 | .mixers = { alc883_3ST_2ch_mixer }, | 8948 | .mixers = { alc883_3ST_2ch_mixer }, |
9188 | .init_verbs = { alc883_init_verbs }, | 8949 | .init_verbs = { alc883_init_verbs }, |
@@ -9229,6 +8990,46 @@ static struct alc_config_preset alc883_presets[] = { | |||
9229 | .need_dac_fix = 1, | 8990 | .need_dac_fix = 1, |
9230 | .input_mux = &alc883_3stack_6ch_intel, | 8991 | .input_mux = &alc883_3stack_6ch_intel, |
9231 | }, | 8992 | }, |
8993 | [ALC889A_INTEL] = { | ||
8994 | .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, | ||
8995 | .init_verbs = { alc885_init_verbs, alc885_init_input_verbs, | ||
8996 | alc_hp15_unsol_verbs }, | ||
8997 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
8998 | .dac_nids = alc883_dac_nids, | ||
8999 | .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), | ||
9000 | .adc_nids = alc889_adc_nids, | ||
9001 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
9002 | .dig_in_nid = ALC883_DIGIN_NID, | ||
9003 | .slave_dig_outs = alc883_slave_dig_outs, | ||
9004 | .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), | ||
9005 | .channel_mode = alc889_8ch_intel_modes, | ||
9006 | .capsrc_nids = alc889_capsrc_nids, | ||
9007 | .input_mux = &alc889_capture_source, | ||
9008 | .setup = alc889_automute_setup, | ||
9009 | .init_hook = alc_automute_amp, | ||
9010 | .unsol_event = alc_automute_amp_unsol_event, | ||
9011 | .need_dac_fix = 1, | ||
9012 | }, | ||
9013 | [ALC889_INTEL] = { | ||
9014 | .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, | ||
9015 | .init_verbs = { alc885_init_verbs, alc889_init_input_verbs, | ||
9016 | alc889_eapd_verbs, alc_hp15_unsol_verbs}, | ||
9017 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
9018 | .dac_nids = alc883_dac_nids, | ||
9019 | .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), | ||
9020 | .adc_nids = alc889_adc_nids, | ||
9021 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
9022 | .dig_in_nid = ALC883_DIGIN_NID, | ||
9023 | .slave_dig_outs = alc883_slave_dig_outs, | ||
9024 | .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), | ||
9025 | .channel_mode = alc889_8ch_intel_modes, | ||
9026 | .capsrc_nids = alc889_capsrc_nids, | ||
9027 | .input_mux = &alc889_capture_source, | ||
9028 | .setup = alc889_automute_setup, | ||
9029 | .init_hook = alc889_intel_init_hook, | ||
9030 | .unsol_event = alc_automute_amp_unsol_event, | ||
9031 | .need_dac_fix = 1, | ||
9032 | }, | ||
9232 | [ALC883_6ST_DIG] = { | 9033 | [ALC883_6ST_DIG] = { |
9233 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 9034 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
9234 | .init_verbs = { alc883_init_verbs }, | 9035 | .init_verbs = { alc883_init_verbs }, |
@@ -9252,7 +9053,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9252 | .need_dac_fix = 1, | 9053 | .need_dac_fix = 1, |
9253 | .input_mux = &alc883_capture_source, | 9054 | .input_mux = &alc883_capture_source, |
9254 | .unsol_event = alc883_targa_unsol_event, | 9055 | .unsol_event = alc883_targa_unsol_event, |
9255 | .init_hook = alc883_targa_init_hook, | 9056 | .setup = alc882_targa_setup, |
9057 | .init_hook = alc882_targa_automute, | ||
9256 | }, | 9058 | }, |
9257 | [ALC883_TARGA_2ch_DIG] = { | 9059 | [ALC883_TARGA_2ch_DIG] = { |
9258 | .mixers = { alc883_targa_2ch_mixer}, | 9060 | .mixers = { alc883_targa_2ch_mixer}, |
@@ -9267,7 +9069,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9267 | .channel_mode = alc883_3ST_2ch_modes, | 9069 | .channel_mode = alc883_3ST_2ch_modes, |
9268 | .input_mux = &alc883_capture_source, | 9070 | .input_mux = &alc883_capture_source, |
9269 | .unsol_event = alc883_targa_unsol_event, | 9071 | .unsol_event = alc883_targa_unsol_event, |
9270 | .init_hook = alc883_targa_init_hook, | 9072 | .setup = alc882_targa_setup, |
9073 | .init_hook = alc882_targa_automute, | ||
9271 | }, | 9074 | }, |
9272 | [ALC883_TARGA_8ch_DIG] = { | 9075 | [ALC883_TARGA_8ch_DIG] = { |
9273 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 9076 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
@@ -9285,7 +9088,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9285 | .need_dac_fix = 1, | 9088 | .need_dac_fix = 1, |
9286 | .input_mux = &alc883_capture_source, | 9089 | .input_mux = &alc883_capture_source, |
9287 | .unsol_event = alc883_targa_unsol_event, | 9090 | .unsol_event = alc883_targa_unsol_event, |
9288 | .init_hook = alc883_targa_init_hook, | 9091 | .setup = alc882_targa_setup, |
9092 | .init_hook = alc882_targa_automute, | ||
9289 | }, | 9093 | }, |
9290 | [ALC883_ACER] = { | 9094 | [ALC883_ACER] = { |
9291 | .mixers = { alc883_base_mixer }, | 9095 | .mixers = { alc883_base_mixer }, |
@@ -9311,7 +9115,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9311 | .channel_mode = alc883_3ST_2ch_modes, | 9115 | .channel_mode = alc883_3ST_2ch_modes, |
9312 | .input_mux = &alc883_capture_source, | 9116 | .input_mux = &alc883_capture_source, |
9313 | .unsol_event = alc_automute_amp_unsol_event, | 9117 | .unsol_event = alc_automute_amp_unsol_event, |
9314 | .init_hook = alc883_acer_aspire_init_hook, | 9118 | .setup = alc883_acer_aspire_setup, |
9119 | .init_hook = alc_automute_amp, | ||
9315 | }, | 9120 | }, |
9316 | [ALC888_ACER_ASPIRE_4930G] = { | 9121 | [ALC888_ACER_ASPIRE_4930G] = { |
9317 | .mixers = { alc888_base_mixer, | 9122 | .mixers = { alc888_base_mixer, |
@@ -9331,7 +9136,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9331 | ARRAY_SIZE(alc888_2_capture_sources), | 9136 | ARRAY_SIZE(alc888_2_capture_sources), |
9332 | .input_mux = alc888_2_capture_sources, | 9137 | .input_mux = alc888_2_capture_sources, |
9333 | .unsol_event = alc_automute_amp_unsol_event, | 9138 | .unsol_event = alc_automute_amp_unsol_event, |
9334 | .init_hook = alc888_acer_aspire_4930g_init_hook, | 9139 | .setup = alc888_acer_aspire_4930g_setup, |
9140 | .init_hook = alc_automute_amp, | ||
9335 | }, | 9141 | }, |
9336 | [ALC888_ACER_ASPIRE_6530G] = { | 9142 | [ALC888_ACER_ASPIRE_6530G] = { |
9337 | .mixers = { alc888_acer_aspire_6530_mixer }, | 9143 | .mixers = { alc888_acer_aspire_6530_mixer }, |
@@ -9349,7 +9155,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9349 | ARRAY_SIZE(alc888_2_capture_sources), | 9155 | ARRAY_SIZE(alc888_2_capture_sources), |
9350 | .input_mux = alc888_acer_aspire_6530_sources, | 9156 | .input_mux = alc888_acer_aspire_6530_sources, |
9351 | .unsol_event = alc_automute_amp_unsol_event, | 9157 | .unsol_event = alc_automute_amp_unsol_event, |
9352 | .init_hook = alc888_acer_aspire_6530g_init_hook, | 9158 | .setup = alc888_acer_aspire_6530g_setup, |
9159 | .init_hook = alc_automute_amp, | ||
9353 | }, | 9160 | }, |
9354 | [ALC888_ACER_ASPIRE_8930G] = { | 9161 | [ALC888_ACER_ASPIRE_8930G] = { |
9355 | .mixers = { alc888_base_mixer, | 9162 | .mixers = { alc888_base_mixer, |
@@ -9370,7 +9177,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9370 | ARRAY_SIZE(alc889_capture_sources), | 9177 | ARRAY_SIZE(alc889_capture_sources), |
9371 | .input_mux = alc889_capture_sources, | 9178 | .input_mux = alc889_capture_sources, |
9372 | .unsol_event = alc_automute_amp_unsol_event, | 9179 | .unsol_event = alc_automute_amp_unsol_event, |
9373 | .init_hook = alc889_acer_aspire_8930g_init_hook, | 9180 | .setup = alc889_acer_aspire_8930g_setup, |
9181 | .init_hook = alc_automute_amp, | ||
9374 | }, | 9182 | }, |
9375 | [ALC883_MEDION] = { | 9183 | [ALC883_MEDION] = { |
9376 | .mixers = { alc883_fivestack_mixer, | 9184 | .mixers = { alc883_fivestack_mixer, |
@@ -9395,7 +9203,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9395 | .channel_mode = alc883_3ST_2ch_modes, | 9203 | .channel_mode = alc883_3ST_2ch_modes, |
9396 | .input_mux = &alc883_capture_source, | 9204 | .input_mux = &alc883_capture_source, |
9397 | .unsol_event = alc_automute_amp_unsol_event, | 9205 | .unsol_event = alc_automute_amp_unsol_event, |
9398 | .init_hook = alc883_medion_md2_init_hook, | 9206 | .setup = alc883_medion_md2_setup, |
9207 | .init_hook = alc_automute_amp, | ||
9399 | }, | 9208 | }, |
9400 | [ALC883_LAPTOP_EAPD] = { | 9209 | [ALC883_LAPTOP_EAPD] = { |
9401 | .mixers = { alc883_base_mixer }, | 9210 | .mixers = { alc883_base_mixer }, |
@@ -9416,6 +9225,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
9416 | .channel_mode = alc883_3ST_2ch_modes, | 9225 | .channel_mode = alc883_3ST_2ch_modes, |
9417 | .input_mux = &alc883_capture_source, | 9226 | .input_mux = &alc883_capture_source, |
9418 | .unsol_event = alc883_clevo_m720_unsol_event, | 9227 | .unsol_event = alc883_clevo_m720_unsol_event, |
9228 | .setup = alc883_clevo_m720_setup, | ||
9419 | .init_hook = alc883_clevo_m720_init_hook, | 9229 | .init_hook = alc883_clevo_m720_init_hook, |
9420 | }, | 9230 | }, |
9421 | [ALC883_LENOVO_101E_2ch] = { | 9231 | [ALC883_LENOVO_101E_2ch] = { |
@@ -9441,7 +9251,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9441 | .need_dac_fix = 1, | 9251 | .need_dac_fix = 1, |
9442 | .input_mux = &alc883_lenovo_nb0763_capture_source, | 9252 | .input_mux = &alc883_lenovo_nb0763_capture_source, |
9443 | .unsol_event = alc_automute_amp_unsol_event, | 9253 | .unsol_event = alc_automute_amp_unsol_event, |
9444 | .init_hook = alc883_medion_md2_init_hook, | 9254 | .setup = alc883_medion_md2_setup, |
9255 | .init_hook = alc_automute_amp, | ||
9445 | }, | 9256 | }, |
9446 | [ALC888_LENOVO_MS7195_DIG] = { | 9257 | [ALC888_LENOVO_MS7195_DIG] = { |
9447 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 9258 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -9466,7 +9277,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9466 | .channel_mode = alc883_3ST_2ch_modes, | 9277 | .channel_mode = alc883_3ST_2ch_modes, |
9467 | .input_mux = &alc883_capture_source, | 9278 | .input_mux = &alc883_capture_source, |
9468 | .unsol_event = alc_automute_amp_unsol_event, | 9279 | .unsol_event = alc_automute_amp_unsol_event, |
9469 | .init_hook = alc883_haier_w66_init_hook, | 9280 | .setup = alc883_haier_w66_setup, |
9281 | .init_hook = alc_automute_amp, | ||
9470 | }, | 9282 | }, |
9471 | [ALC888_3ST_HP] = { | 9283 | [ALC888_3ST_HP] = { |
9472 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 9284 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -9478,7 +9290,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9478 | .need_dac_fix = 1, | 9290 | .need_dac_fix = 1, |
9479 | .input_mux = &alc883_capture_source, | 9291 | .input_mux = &alc883_capture_source, |
9480 | .unsol_event = alc_automute_amp_unsol_event, | 9292 | .unsol_event = alc_automute_amp_unsol_event, |
9481 | .init_hook = alc888_3st_hp_init_hook, | 9293 | .setup = alc888_3st_hp_setup, |
9294 | .init_hook = alc_automute_amp, | ||
9482 | }, | 9295 | }, |
9483 | [ALC888_6ST_DELL] = { | 9296 | [ALC888_6ST_DELL] = { |
9484 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 9297 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
@@ -9491,7 +9304,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9491 | .channel_mode = alc883_sixstack_modes, | 9304 | .channel_mode = alc883_sixstack_modes, |
9492 | .input_mux = &alc883_capture_source, | 9305 | .input_mux = &alc883_capture_source, |
9493 | .unsol_event = alc_automute_amp_unsol_event, | 9306 | .unsol_event = alc_automute_amp_unsol_event, |
9494 | .init_hook = alc888_6st_dell_init_hook, | 9307 | .setup = alc888_6st_dell_setup, |
9308 | .init_hook = alc_automute_amp, | ||
9495 | }, | 9309 | }, |
9496 | [ALC883_MITAC] = { | 9310 | [ALC883_MITAC] = { |
9497 | .mixers = { alc883_mitac_mixer }, | 9311 | .mixers = { alc883_mitac_mixer }, |
@@ -9502,7 +9316,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9502 | .channel_mode = alc883_3ST_2ch_modes, | 9316 | .channel_mode = alc883_3ST_2ch_modes, |
9503 | .input_mux = &alc883_capture_source, | 9317 | .input_mux = &alc883_capture_source, |
9504 | .unsol_event = alc_automute_amp_unsol_event, | 9318 | .unsol_event = alc_automute_amp_unsol_event, |
9505 | .init_hook = alc883_mitac_init_hook, | 9319 | .setup = alc883_mitac_setup, |
9320 | .init_hook = alc_automute_amp, | ||
9506 | }, | 9321 | }, |
9507 | [ALC883_FUJITSU_PI2515] = { | 9322 | [ALC883_FUJITSU_PI2515] = { |
9508 | .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, | 9323 | .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, |
@@ -9515,7 +9330,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9515 | .channel_mode = alc883_3ST_2ch_modes, | 9330 | .channel_mode = alc883_3ST_2ch_modes, |
9516 | .input_mux = &alc883_fujitsu_pi2515_capture_source, | 9331 | .input_mux = &alc883_fujitsu_pi2515_capture_source, |
9517 | .unsol_event = alc_automute_amp_unsol_event, | 9332 | .unsol_event = alc_automute_amp_unsol_event, |
9518 | .init_hook = alc883_2ch_fujitsu_pi2515_init_hook, | 9333 | .setup = alc883_2ch_fujitsu_pi2515_setup, |
9334 | .init_hook = alc_automute_amp, | ||
9519 | }, | 9335 | }, |
9520 | [ALC888_FUJITSU_XA3530] = { | 9336 | [ALC888_FUJITSU_XA3530] = { |
9521 | .mixers = { alc888_base_mixer, alc883_chmode_mixer }, | 9337 | .mixers = { alc888_base_mixer, alc883_chmode_mixer }, |
@@ -9533,7 +9349,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9533 | ARRAY_SIZE(alc888_2_capture_sources), | 9349 | ARRAY_SIZE(alc888_2_capture_sources), |
9534 | .input_mux = alc888_2_capture_sources, | 9350 | .input_mux = alc888_2_capture_sources, |
9535 | .unsol_event = alc_automute_amp_unsol_event, | 9351 | .unsol_event = alc_automute_amp_unsol_event, |
9536 | .init_hook = alc888_fujitsu_xa3530_init_hook, | 9352 | .setup = alc888_fujitsu_xa3530_setup, |
9353 | .init_hook = alc_automute_amp, | ||
9537 | }, | 9354 | }, |
9538 | [ALC888_LENOVO_SKY] = { | 9355 | [ALC888_LENOVO_SKY] = { |
9539 | .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, | 9356 | .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, |
@@ -9546,7 +9363,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9546 | .need_dac_fix = 1, | 9363 | .need_dac_fix = 1, |
9547 | .input_mux = &alc883_lenovo_sky_capture_source, | 9364 | .input_mux = &alc883_lenovo_sky_capture_source, |
9548 | .unsol_event = alc_automute_amp_unsol_event, | 9365 | .unsol_event = alc_automute_amp_unsol_event, |
9549 | .init_hook = alc888_lenovo_sky_init_hook, | 9366 | .setup = alc888_lenovo_sky_setup, |
9367 | .init_hook = alc_automute_amp, | ||
9550 | }, | 9368 | }, |
9551 | [ALC888_ASUS_M90V] = { | 9369 | [ALC888_ASUS_M90V] = { |
9552 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 9370 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -9559,8 +9377,9 @@ static struct alc_config_preset alc883_presets[] = { | |||
9559 | .channel_mode = alc883_3ST_6ch_modes, | 9377 | .channel_mode = alc883_3ST_6ch_modes, |
9560 | .need_dac_fix = 1, | 9378 | .need_dac_fix = 1, |
9561 | .input_mux = &alc883_fujitsu_pi2515_capture_source, | 9379 | .input_mux = &alc883_fujitsu_pi2515_capture_source, |
9562 | .unsol_event = alc883_mode2_unsol_event, | 9380 | .unsol_event = alc_sku_unsol_event, |
9563 | .init_hook = alc883_mode2_inithook, | 9381 | .setup = alc883_mode2_setup, |
9382 | .init_hook = alc_inithook, | ||
9564 | }, | 9383 | }, |
9565 | [ALC888_ASUS_EEE1601] = { | 9384 | [ALC888_ASUS_EEE1601] = { |
9566 | .mixers = { alc883_asus_eee1601_mixer }, | 9385 | .mixers = { alc883_asus_eee1601_mixer }, |
@@ -9613,15 +9432,39 @@ static struct alc_config_preset alc883_presets[] = { | |||
9613 | .channel_mode = alc883_3ST_2ch_modes, | 9432 | .channel_mode = alc883_3ST_2ch_modes, |
9614 | .input_mux = &alc883_capture_source, | 9433 | .input_mux = &alc883_capture_source, |
9615 | .unsol_event = alc_automute_amp_unsol_event, | 9434 | .unsol_event = alc_automute_amp_unsol_event, |
9616 | .init_hook = alc883_vaiott_init_hook, | 9435 | .setup = alc883_vaiott_setup, |
9436 | .init_hook = alc_automute_amp, | ||
9617 | }, | 9437 | }, |
9618 | }; | 9438 | }; |
9619 | 9439 | ||
9620 | 9440 | ||
9621 | /* | 9441 | /* |
9442 | * Pin config fixes | ||
9443 | */ | ||
9444 | enum { | ||
9445 | PINFIX_ABIT_AW9D_MAX | ||
9446 | }; | ||
9447 | |||
9448 | static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { | ||
9449 | { 0x15, 0x01080104 }, /* side */ | ||
9450 | { 0x16, 0x01011012 }, /* rear */ | ||
9451 | { 0x17, 0x01016011 }, /* clfe */ | ||
9452 | { } | ||
9453 | }; | ||
9454 | |||
9455 | static const struct alc_pincfg *alc882_pin_fixes[] = { | ||
9456 | [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, | ||
9457 | }; | ||
9458 | |||
9459 | static struct snd_pci_quirk alc882_pinfix_tbl[] = { | ||
9460 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), | ||
9461 | {} | ||
9462 | }; | ||
9463 | |||
9464 | /* | ||
9622 | * BIOS auto configuration | 9465 | * BIOS auto configuration |
9623 | */ | 9466 | */ |
9624 | static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, | 9467 | static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, |
9625 | hda_nid_t nid, int pin_type, | 9468 | hda_nid_t nid, int pin_type, |
9626 | int dac_idx) | 9469 | int dac_idx) |
9627 | { | 9470 | { |
@@ -9638,7 +9481,7 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, | |||
9638 | 9481 | ||
9639 | } | 9482 | } |
9640 | 9483 | ||
9641 | static void alc883_auto_init_multi_out(struct hda_codec *codec) | 9484 | static void alc882_auto_init_multi_out(struct hda_codec *codec) |
9642 | { | 9485 | { |
9643 | struct alc_spec *spec = codec->spec; | 9486 | struct alc_spec *spec = codec->spec; |
9644 | int i; | 9487 | int i; |
@@ -9647,12 +9490,12 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec) | |||
9647 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 9490 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
9648 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 9491 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
9649 | if (nid) | 9492 | if (nid) |
9650 | alc883_auto_set_output_and_unmute(codec, nid, pin_type, | 9493 | alc882_auto_set_output_and_unmute(codec, nid, pin_type, |
9651 | i); | 9494 | i); |
9652 | } | 9495 | } |
9653 | } | 9496 | } |
9654 | 9497 | ||
9655 | static void alc883_auto_init_hp_out(struct hda_codec *codec) | 9498 | static void alc882_auto_init_hp_out(struct hda_codec *codec) |
9656 | { | 9499 | { |
9657 | struct alc_spec *spec = codec->spec; | 9500 | struct alc_spec *spec = codec->spec; |
9658 | hda_nid_t pin; | 9501 | hda_nid_t pin; |
@@ -9660,42 +9503,111 @@ static void alc883_auto_init_hp_out(struct hda_codec *codec) | |||
9660 | pin = spec->autocfg.hp_pins[0]; | 9503 | pin = spec->autocfg.hp_pins[0]; |
9661 | if (pin) /* connect to front */ | 9504 | if (pin) /* connect to front */ |
9662 | /* use dac 0 */ | 9505 | /* use dac 0 */ |
9663 | alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); | 9506 | alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); |
9664 | pin = spec->autocfg.speaker_pins[0]; | 9507 | pin = spec->autocfg.speaker_pins[0]; |
9665 | if (pin) | 9508 | if (pin) |
9666 | alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); | 9509 | alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); |
9667 | } | 9510 | } |
9668 | 9511 | ||
9669 | #define alc883_is_input_pin(nid) alc880_is_input_pin(nid) | 9512 | 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 | { | 9513 | { |
9674 | struct alc_spec *spec = codec->spec; | 9514 | struct alc_spec *spec = codec->spec; |
9675 | int i; | 9515 | int i; |
9676 | 9516 | ||
9677 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 9517 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
9678 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 9518 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
9679 | if (alc883_is_input_pin(nid)) { | 9519 | if (!nid) |
9680 | alc_set_input_pin(codec, nid, i); | 9520 | continue; |
9681 | if (nid != ALC883_PIN_CD_NID && | 9521 | alc_set_input_pin(codec, nid, i); |
9682 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) | 9522 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) |
9523 | snd_hda_codec_write(codec, nid, 0, | ||
9524 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
9525 | AMP_OUT_MUTE); | ||
9526 | } | ||
9527 | } | ||
9528 | |||
9529 | static void alc882_auto_init_input_src(struct hda_codec *codec) | ||
9530 | { | ||
9531 | struct alc_spec *spec = codec->spec; | ||
9532 | int c; | ||
9533 | |||
9534 | for (c = 0; c < spec->num_adc_nids; c++) { | ||
9535 | hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; | ||
9536 | hda_nid_t nid = spec->capsrc_nids[c]; | ||
9537 | unsigned int mux_idx; | ||
9538 | const struct hda_input_mux *imux; | ||
9539 | int conns, mute, idx, item; | ||
9540 | |||
9541 | conns = snd_hda_get_connections(codec, nid, conn_list, | ||
9542 | ARRAY_SIZE(conn_list)); | ||
9543 | if (conns < 0) | ||
9544 | continue; | ||
9545 | mux_idx = c >= spec->num_mux_defs ? 0 : c; | ||
9546 | imux = &spec->input_mux[mux_idx]; | ||
9547 | for (idx = 0; idx < conns; idx++) { | ||
9548 | /* if the current connection is the selected one, | ||
9549 | * unmute it as default - otherwise mute it | ||
9550 | */ | ||
9551 | mute = AMP_IN_MUTE(idx); | ||
9552 | for (item = 0; item < imux->num_items; item++) { | ||
9553 | if (imux->items[item].index == idx) { | ||
9554 | if (spec->cur_mux[c] == item) | ||
9555 | mute = AMP_IN_UNMUTE(idx); | ||
9556 | break; | ||
9557 | } | ||
9558 | } | ||
9559 | /* check if we have a selector or mixer | ||
9560 | * we could check for the widget type instead, but | ||
9561 | * just check for Amp-In presence (in case of mixer | ||
9562 | * without amp-in there is something wrong, this | ||
9563 | * function shouldn't be used or capsrc nid is wrong) | ||
9564 | */ | ||
9565 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) | ||
9683 | snd_hda_codec_write(codec, nid, 0, | 9566 | snd_hda_codec_write(codec, nid, 0, |
9684 | AC_VERB_SET_AMP_GAIN_MUTE, | 9567 | AC_VERB_SET_AMP_GAIN_MUTE, |
9685 | AMP_OUT_MUTE); | 9568 | mute); |
9569 | else if (mute != AMP_IN_MUTE(idx)) | ||
9570 | snd_hda_codec_write(codec, nid, 0, | ||
9571 | AC_VERB_SET_CONNECT_SEL, | ||
9572 | idx); | ||
9686 | } | 9573 | } |
9687 | } | 9574 | } |
9688 | } | 9575 | } |
9689 | 9576 | ||
9690 | #define alc883_auto_init_input_src alc882_auto_init_input_src | 9577 | /* add mic boosts if needed */ |
9578 | static int alc_auto_add_mic_boost(struct hda_codec *codec) | ||
9579 | { | ||
9580 | struct alc_spec *spec = codec->spec; | ||
9581 | int err; | ||
9582 | hda_nid_t nid; | ||
9583 | |||
9584 | nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; | ||
9585 | if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { | ||
9586 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
9587 | "Mic Boost", | ||
9588 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | ||
9589 | if (err < 0) | ||
9590 | return err; | ||
9591 | } | ||
9592 | nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; | ||
9593 | if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { | ||
9594 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
9595 | "Front Mic Boost", | ||
9596 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | ||
9597 | if (err < 0) | ||
9598 | return err; | ||
9599 | } | ||
9600 | return 0; | ||
9601 | } | ||
9691 | 9602 | ||
9692 | /* almost identical with ALC880 parser... */ | 9603 | /* almost identical with ALC880 parser... */ |
9693 | static int alc883_parse_auto_config(struct hda_codec *codec) | 9604 | static int alc882_parse_auto_config(struct hda_codec *codec) |
9694 | { | 9605 | { |
9695 | struct alc_spec *spec = codec->spec; | 9606 | struct alc_spec *spec = codec->spec; |
9696 | int err = alc880_parse_auto_config(codec); | 9607 | struct auto_pin_cfg *autocfg = &spec->autocfg; |
9697 | struct auto_pin_cfg *cfg = &spec->autocfg; | 9608 | unsigned int wcap; |
9698 | int i; | 9609 | int i; |
9610 | int err = alc880_parse_auto_config(codec); | ||
9699 | 9611 | ||
9700 | if (err < 0) | 9612 | if (err < 0) |
9701 | return err; | 9613 | return err; |
@@ -9708,43 +9620,45 @@ static int alc883_parse_auto_config(struct hda_codec *codec) | |||
9708 | 9620 | ||
9709 | /* hack - override the init verbs */ | 9621 | /* hack - override the init verbs */ |
9710 | spec->init_verbs[0] = alc883_auto_init_verbs; | 9622 | spec->init_verbs[0] = alc883_auto_init_verbs; |
9623 | /* if ADC 0x07 is available, initialize it, too */ | ||
9624 | wcap = get_wcaps(codec, 0x07); | ||
9625 | wcap = get_wcaps_type(wcap); | ||
9626 | if (wcap == AC_WID_AUD_IN) | ||
9627 | add_verb(spec, alc882_adc1_init_verbs); | ||
9711 | 9628 | ||
9712 | /* setup input_mux for ALC889 */ | 9629 | /* digital-mic input pin is excluded in alc880_auto_create..() |
9713 | if (codec->vendor_id == 0x10ec0889) { | 9630 | * because it's under 0x18 |
9714 | /* digital-mic input pin is excluded in alc880_auto_create..() | 9631 | */ |
9715 | * because it's under 0x18 | 9632 | if (autocfg->input_pins[AUTO_PIN_MIC] == 0x12 || |
9716 | */ | 9633 | autocfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { |
9717 | if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || | 9634 | struct hda_input_mux *imux = &spec->private_imux[0]; |
9718 | cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { | 9635 | for (i = 1; i < 3; i++) |
9719 | struct hda_input_mux *imux = &spec->private_imux[0]; | 9636 | memcpy(&spec->private_imux[i], |
9720 | for (i = 1; i < 3; i++) | 9637 | &spec->private_imux[0], |
9721 | memcpy(&spec->private_imux[i], | 9638 | sizeof(spec->private_imux[0])); |
9722 | &spec->private_imux[0], | 9639 | imux->items[imux->num_items].label = "Int DMic"; |
9723 | sizeof(spec->private_imux[0])); | 9640 | imux->items[imux->num_items].index = 0x0b; |
9724 | imux->items[imux->num_items].label = "Int DMic"; | 9641 | imux->num_items++; |
9725 | imux->items[imux->num_items].index = 0x0b; | 9642 | spec->num_mux_defs = 3; |
9726 | imux->num_items++; | 9643 | spec->input_mux = spec->private_imux; |
9727 | spec->num_mux_defs = 3; | ||
9728 | spec->input_mux = spec->private_imux; | ||
9729 | } | ||
9730 | } | 9644 | } |
9731 | 9645 | ||
9732 | return 1; /* config found */ | 9646 | return 1; /* config found */ |
9733 | } | 9647 | } |
9734 | 9648 | ||
9735 | /* additional initialization for auto-configuration model */ | 9649 | /* additional initialization for auto-configuration model */ |
9736 | static void alc883_auto_init(struct hda_codec *codec) | 9650 | static void alc882_auto_init(struct hda_codec *codec) |
9737 | { | 9651 | { |
9738 | struct alc_spec *spec = codec->spec; | 9652 | struct alc_spec *spec = codec->spec; |
9739 | alc883_auto_init_multi_out(codec); | 9653 | alc882_auto_init_multi_out(codec); |
9740 | alc883_auto_init_hp_out(codec); | 9654 | alc882_auto_init_hp_out(codec); |
9741 | alc883_auto_init_analog_input(codec); | 9655 | alc882_auto_init_analog_input(codec); |
9742 | alc883_auto_init_input_src(codec); | 9656 | alc882_auto_init_input_src(codec); |
9743 | if (spec->unsol_event) | 9657 | if (spec->unsol_event) |
9744 | alc_inithook(codec); | 9658 | alc_inithook(codec); |
9745 | } | 9659 | } |
9746 | 9660 | ||
9747 | static int patch_alc883(struct hda_codec *codec) | 9661 | static int patch_alc882(struct hda_codec *codec) |
9748 | { | 9662 | { |
9749 | struct alc_spec *spec; | 9663 | struct alc_spec *spec; |
9750 | int err, board_config; | 9664 | int err, board_config; |
@@ -9755,28 +9669,35 @@ static int patch_alc883(struct hda_codec *codec) | |||
9755 | 9669 | ||
9756 | codec->spec = spec; | 9670 | codec->spec = spec; |
9757 | 9671 | ||
9758 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | 9672 | switch (codec->vendor_id) { |
9673 | case 0x10ec0882: | ||
9674 | case 0x10ec0885: | ||
9675 | break; | ||
9676 | default: | ||
9677 | /* ALC883 and variants */ | ||
9678 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | ||
9679 | break; | ||
9680 | } | ||
9759 | 9681 | ||
9760 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, | 9682 | board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, |
9761 | alc883_models, | 9683 | alc882_models, |
9762 | alc883_cfg_tbl); | 9684 | alc882_cfg_tbl); |
9763 | if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { | 9685 | |
9764 | /* Pick up systems that don't supply PCI SSID */ | 9686 | if (board_config < 0 || board_config >= ALC882_MODEL_LAST) |
9765 | switch (codec->subsystem_id) { | 9687 | board_config = snd_hda_check_board_codec_sid_config(codec, |
9766 | case 0x106b3600: /* Macbook 3.1 */ | 9688 | ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); |
9767 | board_config = ALC889A_MB31; | 9689 | |
9768 | break; | 9690 | if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { |
9769 | default: | 9691 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
9770 | printk(KERN_INFO | 9692 | codec->chip_name); |
9771 | "hda_codec: Unknown model for %s, trying " | 9693 | board_config = ALC882_AUTO; |
9772 | "auto-probe from BIOS...\n", codec->chip_name); | ||
9773 | board_config = ALC883_AUTO; | ||
9774 | } | ||
9775 | } | 9694 | } |
9776 | 9695 | ||
9777 | if (board_config == ALC883_AUTO) { | 9696 | alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); |
9697 | |||
9698 | if (board_config == ALC882_AUTO) { | ||
9778 | /* automatic parse from the BIOS config */ | 9699 | /* automatic parse from the BIOS config */ |
9779 | err = alc883_parse_auto_config(codec); | 9700 | err = alc882_parse_auto_config(codec); |
9780 | if (err < 0) { | 9701 | if (err < 0) { |
9781 | alc_free(codec); | 9702 | alc_free(codec); |
9782 | return err; | 9703 | return err; |
@@ -9784,7 +9705,7 @@ static int patch_alc883(struct hda_codec *codec) | |||
9784 | printk(KERN_INFO | 9705 | printk(KERN_INFO |
9785 | "hda_codec: Cannot set up configuration " | 9706 | "hda_codec: Cannot set up configuration " |
9786 | "from BIOS. Using base mode...\n"); | 9707 | "from BIOS. Using base mode...\n"); |
9787 | board_config = ALC883_3ST_2ch_DIG; | 9708 | board_config = ALC882_3ST_DIG; |
9788 | } | 9709 | } |
9789 | } | 9710 | } |
9790 | 9711 | ||
@@ -9794,63 +9715,61 @@ static int patch_alc883(struct hda_codec *codec) | |||
9794 | return err; | 9715 | return err; |
9795 | } | 9716 | } |
9796 | 9717 | ||
9797 | if (board_config != ALC883_AUTO) | 9718 | if (board_config != ALC882_AUTO) |
9798 | setup_preset(spec, &alc883_presets[board_config]); | 9719 | setup_preset(codec, &alc882_presets[board_config]); |
9799 | 9720 | ||
9800 | switch (codec->vendor_id) { | 9721 | spec->stream_analog_playback = &alc882_pcm_analog_playback; |
9801 | case 0x10ec0888: | 9722 | spec->stream_analog_capture = &alc882_pcm_analog_capture; |
9802 | if (!spec->num_adc_nids) { | 9723 | /* FIXME: setup DAC5 */ |
9803 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | 9724 | /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ |
9804 | spec->adc_nids = alc883_adc_nids; | 9725 | spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; |
9805 | } | 9726 | |
9806 | if (!spec->capsrc_nids) | 9727 | spec->stream_digital_playback = &alc882_pcm_digital_playback; |
9807 | spec->capsrc_nids = alc883_capsrc_nids; | 9728 | spec->stream_digital_capture = &alc882_pcm_digital_capture; |
9729 | |||
9730 | if (codec->vendor_id == 0x10ec0888) | ||
9808 | spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ | 9731 | spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ |
9809 | break; | 9732 | |
9810 | case 0x10ec0889: | 9733 | if (!spec->adc_nids && spec->input_mux) { |
9811 | if (!spec->num_adc_nids) { | 9734 | int i; |
9812 | spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids); | 9735 | spec->num_adc_nids = 0; |
9813 | spec->adc_nids = alc889_adc_nids; | 9736 | for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { |
9814 | } | 9737 | hda_nid_t cap; |
9815 | if (!spec->capsrc_nids) | 9738 | hda_nid_t nid = alc882_adc_nids[i]; |
9816 | spec->capsrc_nids = alc889_capsrc_nids; | 9739 | unsigned int wcap = get_wcaps(codec, nid); |
9817 | break; | 9740 | /* get type */ |
9818 | default: | 9741 | wcap = get_wcaps_type(wcap); |
9819 | if (!spec->num_adc_nids) { | 9742 | if (wcap != AC_WID_AUD_IN) |
9820 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | 9743 | continue; |
9821 | spec->adc_nids = alc883_adc_nids; | 9744 | spec->private_adc_nids[spec->num_adc_nids] = nid; |
9745 | err = snd_hda_get_connections(codec, nid, &cap, 1); | ||
9746 | if (err < 0) | ||
9747 | continue; | ||
9748 | spec->private_capsrc_nids[spec->num_adc_nids] = cap; | ||
9749 | spec->num_adc_nids++; | ||
9822 | } | 9750 | } |
9823 | if (!spec->capsrc_nids) | 9751 | spec->adc_nids = spec->private_adc_nids; |
9824 | spec->capsrc_nids = alc883_capsrc_nids; | 9752 | spec->capsrc_nids = spec->private_capsrc_nids; |
9825 | break; | ||
9826 | } | 9753 | } |
9827 | 9754 | ||
9828 | spec->stream_analog_playback = &alc883_pcm_analog_playback; | 9755 | set_capture_mixer(codec); |
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); | 9756 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
9838 | 9757 | ||
9839 | spec->vmaster_nid = 0x0c; | 9758 | spec->vmaster_nid = 0x0c; |
9840 | 9759 | ||
9841 | codec->patch_ops = alc_patch_ops; | 9760 | codec->patch_ops = alc_patch_ops; |
9842 | if (board_config == ALC883_AUTO) | 9761 | if (board_config == ALC882_AUTO) |
9843 | spec->init_hook = alc883_auto_init; | 9762 | spec->init_hook = alc882_auto_init; |
9844 | |||
9845 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 9763 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
9846 | if (!spec->loopback.amplist) | 9764 | if (!spec->loopback.amplist) |
9847 | spec->loopback.amplist = alc883_loopbacks; | 9765 | spec->loopback.amplist = alc882_loopbacks; |
9848 | #endif | 9766 | #endif |
9849 | codec->proc_widget_hook = print_realtek_coef; | 9767 | codec->proc_widget_hook = print_realtek_coef; |
9850 | 9768 | ||
9851 | return 0; | 9769 | return 0; |
9852 | } | 9770 | } |
9853 | 9771 | ||
9772 | |||
9854 | /* | 9773 | /* |
9855 | * ALC262 support | 9774 | * ALC262 support |
9856 | */ | 9775 | */ |
@@ -10026,13 +9945,12 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { | |||
10026 | }; | 9945 | }; |
10027 | 9946 | ||
10028 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 9947 | /* mute/unmute internal speaker according to the hp jack and mute state */ |
10029 | static void alc262_hp_t5735_init_hook(struct hda_codec *codec) | 9948 | static void alc262_hp_t5735_setup(struct hda_codec *codec) |
10030 | { | 9949 | { |
10031 | struct alc_spec *spec = codec->spec; | 9950 | struct alc_spec *spec = codec->spec; |
10032 | 9951 | ||
10033 | spec->autocfg.hp_pins[0] = 0x15; | 9952 | spec->autocfg.hp_pins[0] = 0x15; |
10034 | spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */ | 9953 | spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */ |
10035 | alc_automute_amp(codec); | ||
10036 | } | 9954 | } |
10037 | 9955 | ||
10038 | static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { | 9956 | static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { |
@@ -10189,22 +10107,20 @@ static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) | |||
10189 | alc262_hippo_automute(codec); | 10107 | alc262_hippo_automute(codec); |
10190 | } | 10108 | } |
10191 | 10109 | ||
10192 | static void alc262_hippo_init_hook(struct hda_codec *codec) | 10110 | static void alc262_hippo_setup(struct hda_codec *codec) |
10193 | { | 10111 | { |
10194 | struct alc_spec *spec = codec->spec; | 10112 | struct alc_spec *spec = codec->spec; |
10195 | 10113 | ||
10196 | spec->autocfg.hp_pins[0] = 0x15; | 10114 | spec->autocfg.hp_pins[0] = 0x15; |
10197 | spec->autocfg.speaker_pins[0] = 0x14; | 10115 | spec->autocfg.speaker_pins[0] = 0x14; |
10198 | alc262_hippo_automute(codec); | ||
10199 | } | 10116 | } |
10200 | 10117 | ||
10201 | static void alc262_hippo1_init_hook(struct hda_codec *codec) | 10118 | static void alc262_hippo1_setup(struct hda_codec *codec) |
10202 | { | 10119 | { |
10203 | struct alc_spec *spec = codec->spec; | 10120 | struct alc_spec *spec = codec->spec; |
10204 | 10121 | ||
10205 | spec->autocfg.hp_pins[0] = 0x1b; | 10122 | spec->autocfg.hp_pins[0] = 0x1b; |
10206 | spec->autocfg.speaker_pins[0] = 0x14; | 10123 | spec->autocfg.speaker_pins[0] = 0x14; |
10207 | alc262_hippo_automute(codec); | ||
10208 | } | 10124 | } |
10209 | 10125 | ||
10210 | 10126 | ||
@@ -10261,13 +10177,12 @@ static struct hda_verb alc262_tyan_verbs[] = { | |||
10261 | }; | 10177 | }; |
10262 | 10178 | ||
10263 | /* unsolicited event for HP jack sensing */ | 10179 | /* unsolicited event for HP jack sensing */ |
10264 | static void alc262_tyan_init_hook(struct hda_codec *codec) | 10180 | static void alc262_tyan_setup(struct hda_codec *codec) |
10265 | { | 10181 | { |
10266 | struct alc_spec *spec = codec->spec; | 10182 | struct alc_spec *spec = codec->spec; |
10267 | 10183 | ||
10268 | spec->autocfg.hp_pins[0] = 0x1b; | 10184 | spec->autocfg.hp_pins[0] = 0x1b; |
10269 | spec->autocfg.speaker_pins[0] = 0x15; | 10185 | spec->autocfg.speaker_pins[0] = 0x15; |
10270 | alc_automute_amp(codec); | ||
10271 | } | 10186 | } |
10272 | 10187 | ||
10273 | 10188 | ||
@@ -10359,12 +10274,6 @@ static struct hda_verb alc262_eapd_verbs[] = { | |||
10359 | { } | 10274 | { } |
10360 | }; | 10275 | }; |
10361 | 10276 | ||
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[] = { | 10277 | static struct hda_verb alc262_hippo1_unsol_verbs[] = { |
10369 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | 10278 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, |
10370 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | 10279 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -10385,14 +10294,6 @@ static struct hda_verb alc262_sony_unsol_verbs[] = { | |||
10385 | {} | 10294 | {} |
10386 | }; | 10295 | }; |
10387 | 10296 | ||
10388 | static struct hda_input_mux alc262_dmic_capture_source = { | ||
10389 | .num_items = 2, | ||
10390 | .items = { | ||
10391 | { "Int DMic", 0x9 }, | ||
10392 | { "Mic", 0x0 }, | ||
10393 | }, | ||
10394 | }; | ||
10395 | |||
10396 | static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { | 10297 | static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { |
10397 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 10298 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
10398 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 10299 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -10414,35 +10315,17 @@ static struct hda_verb alc262_toshiba_s06_verbs[] = { | |||
10414 | {} | 10315 | {} |
10415 | }; | 10316 | }; |
10416 | 10317 | ||
10417 | static void alc262_dmic_automute(struct hda_codec *codec) | 10318 | static void alc262_toshiba_s06_setup(struct hda_codec *codec) |
10418 | { | ||
10419 | unsigned int present; | ||
10420 | |||
10421 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
10422 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
10423 | snd_hda_codec_write(codec, 0x22, 0, | ||
10424 | AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09); | ||
10425 | } | ||
10426 | |||
10427 | |||
10428 | /* unsolicited event for HP jack sensing */ | ||
10429 | static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec, | ||
10430 | unsigned int res) | ||
10431 | { | ||
10432 | if ((res >> 26) == ALC880_MIC_EVENT) | ||
10433 | alc262_dmic_automute(codec); | ||
10434 | else | ||
10435 | alc_sku_unsol_event(codec, res); | ||
10436 | } | ||
10437 | |||
10438 | static void alc262_toshiba_s06_init_hook(struct hda_codec *codec) | ||
10439 | { | 10319 | { |
10440 | struct alc_spec *spec = codec->spec; | 10320 | struct alc_spec *spec = codec->spec; |
10441 | 10321 | ||
10442 | spec->autocfg.hp_pins[0] = 0x15; | 10322 | spec->autocfg.hp_pins[0] = 0x15; |
10443 | spec->autocfg.speaker_pins[0] = 0x14; | 10323 | spec->autocfg.speaker_pins[0] = 0x14; |
10444 | alc_automute_pin(codec); | 10324 | spec->ext_mic.pin = 0x18; |
10445 | alc262_dmic_automute(codec); | 10325 | spec->ext_mic.mux_idx = 0; |
10326 | spec->int_mic.pin = 0x12; | ||
10327 | spec->int_mic.mux_idx = 9; | ||
10328 | spec->auto_mic = 1; | ||
10446 | } | 10329 | } |
10447 | 10330 | ||
10448 | /* | 10331 | /* |
@@ -11406,7 +11289,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
11406 | }, | 11289 | }, |
11407 | [ALC262_HIPPO] = { | 11290 | [ALC262_HIPPO] = { |
11408 | .mixers = { alc262_hippo_mixer }, | 11291 | .mixers = { alc262_hippo_mixer }, |
11409 | .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, | 11292 | .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs}, |
11410 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | 11293 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), |
11411 | .dac_nids = alc262_dac_nids, | 11294 | .dac_nids = alc262_dac_nids, |
11412 | .hp_nid = 0x03, | 11295 | .hp_nid = 0x03, |
@@ -11415,7 +11298,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
11415 | .channel_mode = alc262_modes, | 11298 | .channel_mode = alc262_modes, |
11416 | .input_mux = &alc262_capture_source, | 11299 | .input_mux = &alc262_capture_source, |
11417 | .unsol_event = alc262_hippo_unsol_event, | 11300 | .unsol_event = alc262_hippo_unsol_event, |
11418 | .init_hook = alc262_hippo_init_hook, | 11301 | .setup = alc262_hippo_setup, |
11302 | .init_hook = alc262_hippo_automute, | ||
11419 | }, | 11303 | }, |
11420 | [ALC262_HIPPO_1] = { | 11304 | [ALC262_HIPPO_1] = { |
11421 | .mixers = { alc262_hippo1_mixer }, | 11305 | .mixers = { alc262_hippo1_mixer }, |
@@ -11428,7 +11312,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
11428 | .channel_mode = alc262_modes, | 11312 | .channel_mode = alc262_modes, |
11429 | .input_mux = &alc262_capture_source, | 11313 | .input_mux = &alc262_capture_source, |
11430 | .unsol_event = alc262_hippo_unsol_event, | 11314 | .unsol_event = alc262_hippo_unsol_event, |
11431 | .init_hook = alc262_hippo1_init_hook, | 11315 | .setup = alc262_hippo1_setup, |
11316 | .init_hook = alc262_hippo_automute, | ||
11432 | }, | 11317 | }, |
11433 | [ALC262_FUJITSU] = { | 11318 | [ALC262_FUJITSU] = { |
11434 | .mixers = { alc262_fujitsu_mixer }, | 11319 | .mixers = { alc262_fujitsu_mixer }, |
@@ -11491,7 +11376,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
11491 | .channel_mode = alc262_modes, | 11376 | .channel_mode = alc262_modes, |
11492 | .input_mux = &alc262_capture_source, | 11377 | .input_mux = &alc262_capture_source, |
11493 | .unsol_event = alc_automute_amp_unsol_event, | 11378 | .unsol_event = alc_automute_amp_unsol_event, |
11494 | .init_hook = alc262_hp_t5735_init_hook, | 11379 | .setup = alc262_hp_t5735_setup, |
11380 | .init_hook = alc_automute_amp, | ||
11495 | }, | 11381 | }, |
11496 | [ALC262_HP_RP5700] = { | 11382 | [ALC262_HP_RP5700] = { |
11497 | .mixers = { alc262_hp_rp5700_mixer }, | 11383 | .mixers = { alc262_hp_rp5700_mixer }, |
@@ -11522,11 +11408,13 @@ static struct alc_config_preset alc262_presets[] = { | |||
11522 | .channel_mode = alc262_modes, | 11408 | .channel_mode = alc262_modes, |
11523 | .input_mux = &alc262_capture_source, | 11409 | .input_mux = &alc262_capture_source, |
11524 | .unsol_event = alc262_hippo_unsol_event, | 11410 | .unsol_event = alc262_hippo_unsol_event, |
11525 | .init_hook = alc262_hippo_init_hook, | 11411 | .setup = alc262_hippo_setup, |
11412 | .init_hook = alc262_hippo_automute, | ||
11526 | }, | 11413 | }, |
11527 | [ALC262_BENQ_T31] = { | 11414 | [ALC262_BENQ_T31] = { |
11528 | .mixers = { alc262_benq_t31_mixer }, | 11415 | .mixers = { alc262_benq_t31_mixer }, |
11529 | .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, | 11416 | .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, |
11417 | alc_hp15_unsol_verbs }, | ||
11530 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | 11418 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), |
11531 | .dac_nids = alc262_dac_nids, | 11419 | .dac_nids = alc262_dac_nids, |
11532 | .hp_nid = 0x03, | 11420 | .hp_nid = 0x03, |
@@ -11534,7 +11422,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
11534 | .channel_mode = alc262_modes, | 11422 | .channel_mode = alc262_modes, |
11535 | .input_mux = &alc262_capture_source, | 11423 | .input_mux = &alc262_capture_source, |
11536 | .unsol_event = alc262_hippo_unsol_event, | 11424 | .unsol_event = alc262_hippo_unsol_event, |
11537 | .init_hook = alc262_hippo_init_hook, | 11425 | .setup = alc262_hippo_setup, |
11426 | .init_hook = alc262_hippo_automute, | ||
11538 | }, | 11427 | }, |
11539 | [ALC262_ULTRA] = { | 11428 | [ALC262_ULTRA] = { |
11540 | .mixers = { alc262_ultra_mixer }, | 11429 | .mixers = { alc262_ultra_mixer }, |
@@ -11586,9 +11475,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
11586 | .dig_out_nid = ALC262_DIGOUT_NID, | 11475 | .dig_out_nid = ALC262_DIGOUT_NID, |
11587 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 11476 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
11588 | .channel_mode = alc262_modes, | 11477 | .channel_mode = alc262_modes, |
11589 | .input_mux = &alc262_dmic_capture_source, | 11478 | .unsol_event = alc_sku_unsol_event, |
11590 | .unsol_event = alc262_toshiba_s06_unsol_event, | 11479 | .setup = alc262_toshiba_s06_setup, |
11591 | .init_hook = alc262_toshiba_s06_init_hook, | 11480 | .init_hook = alc_inithook, |
11592 | }, | 11481 | }, |
11593 | [ALC262_TOSHIBA_RX1] = { | 11482 | [ALC262_TOSHIBA_RX1] = { |
11594 | .mixers = { alc262_toshiba_rx1_mixer }, | 11483 | .mixers = { alc262_toshiba_rx1_mixer }, |
@@ -11600,7 +11489,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
11600 | .channel_mode = alc262_modes, | 11489 | .channel_mode = alc262_modes, |
11601 | .input_mux = &alc262_capture_source, | 11490 | .input_mux = &alc262_capture_source, |
11602 | .unsol_event = alc262_hippo_unsol_event, | 11491 | .unsol_event = alc262_hippo_unsol_event, |
11603 | .init_hook = alc262_hippo_init_hook, | 11492 | .setup = alc262_hippo_setup, |
11493 | .init_hook = alc262_hippo_automute, | ||
11604 | }, | 11494 | }, |
11605 | [ALC262_TYAN] = { | 11495 | [ALC262_TYAN] = { |
11606 | .mixers = { alc262_tyan_mixer }, | 11496 | .mixers = { alc262_tyan_mixer }, |
@@ -11613,7 +11503,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
11613 | .channel_mode = alc262_modes, | 11503 | .channel_mode = alc262_modes, |
11614 | .input_mux = &alc262_capture_source, | 11504 | .input_mux = &alc262_capture_source, |
11615 | .unsol_event = alc_automute_amp_unsol_event, | 11505 | .unsol_event = alc_automute_amp_unsol_event, |
11616 | .init_hook = alc262_tyan_init_hook, | 11506 | .setup = alc262_tyan_setup, |
11507 | .init_hook = alc_automute_amp, | ||
11617 | }, | 11508 | }, |
11618 | }; | 11509 | }; |
11619 | 11510 | ||
@@ -11648,8 +11539,8 @@ static int patch_alc262(struct hda_codec *codec) | |||
11648 | alc262_cfg_tbl); | 11539 | alc262_cfg_tbl); |
11649 | 11540 | ||
11650 | if (board_config < 0) { | 11541 | if (board_config < 0) { |
11651 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 11542 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
11652 | "trying auto-probe from BIOS...\n", codec->chip_name); | 11543 | codec->chip_name); |
11653 | board_config = ALC262_AUTO; | 11544 | board_config = ALC262_AUTO; |
11654 | } | 11545 | } |
11655 | 11546 | ||
@@ -11676,7 +11567,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
11676 | } | 11567 | } |
11677 | 11568 | ||
11678 | if (board_config != ALC262_AUTO) | 11569 | if (board_config != ALC262_AUTO) |
11679 | setup_preset(spec, &alc262_presets[board_config]); | 11570 | setup_preset(codec, &alc262_presets[board_config]); |
11680 | 11571 | ||
11681 | spec->stream_analog_playback = &alc262_pcm_analog_playback; | 11572 | spec->stream_analog_playback = &alc262_pcm_analog_playback; |
11682 | spec->stream_analog_capture = &alc262_pcm_analog_capture; | 11573 | spec->stream_analog_capture = &alc262_pcm_analog_capture; |
@@ -11702,7 +11593,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
11702 | unsigned int wcap = get_wcaps(codec, 0x07); | 11593 | unsigned int wcap = get_wcaps(codec, 0x07); |
11703 | 11594 | ||
11704 | /* get type */ | 11595 | /* get type */ |
11705 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 11596 | wcap = get_wcaps_type(wcap); |
11706 | if (wcap != AC_WID_AUD_IN) { | 11597 | if (wcap != AC_WID_AUD_IN) { |
11707 | spec->adc_nids = alc262_adc_nids_alt; | 11598 | spec->adc_nids = alc262_adc_nids_alt; |
11708 | spec->num_adc_nids = | 11599 | spec->num_adc_nids = |
@@ -11717,7 +11608,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
11717 | } | 11608 | } |
11718 | } | 11609 | } |
11719 | if (!spec->cap_mixer && !spec->no_analog) | 11610 | if (!spec->cap_mixer && !spec->no_analog) |
11720 | set_capture_mixer(spec); | 11611 | set_capture_mixer(codec); |
11721 | if (!spec->no_analog) | 11612 | if (!spec->no_analog) |
11722 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 11613 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
11723 | 11614 | ||
@@ -11809,14 +11700,6 @@ static struct hda_verb alc268_toshiba_verbs[] = { | |||
11809 | { } /* end */ | 11700 | { } /* end */ |
11810 | }; | 11701 | }; |
11811 | 11702 | ||
11812 | static struct hda_input_mux alc268_acer_lc_capture_source = { | ||
11813 | .num_items = 2, | ||
11814 | .items = { | ||
11815 | { "i-Mic", 0x6 }, | ||
11816 | { "E-Mic", 0x0 }, | ||
11817 | }, | ||
11818 | }; | ||
11819 | |||
11820 | /* Acer specific */ | 11703 | /* Acer specific */ |
11821 | /* bind volumes of both NID 0x02 and 0x03 */ | 11704 | /* bind volumes of both NID 0x02 and 0x03 */ |
11822 | static struct hda_bind_ctls alc268_acer_bind_master_vol = { | 11705 | static struct hda_bind_ctls alc268_acer_bind_master_vol = { |
@@ -11935,7 +11818,8 @@ static struct hda_verb alc268_acer_verbs[] = { | |||
11935 | 11818 | ||
11936 | /* unsolicited event for HP jack sensing */ | 11819 | /* unsolicited event for HP jack sensing */ |
11937 | #define alc268_toshiba_unsol_event alc262_hippo_unsol_event | 11820 | #define alc268_toshiba_unsol_event alc262_hippo_unsol_event |
11938 | #define alc268_toshiba_init_hook alc262_hippo_init_hook | 11821 | #define alc268_toshiba_setup alc262_hippo_setup |
11822 | #define alc268_toshiba_automute alc262_hippo_automute | ||
11939 | 11823 | ||
11940 | static void alc268_acer_unsol_event(struct hda_codec *codec, | 11824 | static void alc268_acer_unsol_event(struct hda_codec *codec, |
11941 | unsigned int res) | 11825 | unsigned int res) |
@@ -11965,30 +11849,33 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) | |||
11965 | AMP_IN_MUTE(0), bits); | 11849 | AMP_IN_MUTE(0), bits); |
11966 | } | 11850 | } |
11967 | 11851 | ||
11968 | |||
11969 | static void alc268_acer_mic_automute(struct hda_codec *codec) | ||
11970 | { | ||
11971 | unsigned int present; | ||
11972 | |||
11973 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
11974 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
11975 | snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL, | ||
11976 | present ? 0x0 : 0x6); | ||
11977 | } | ||
11978 | |||
11979 | static void alc268_acer_lc_unsol_event(struct hda_codec *codec, | 11852 | static void alc268_acer_lc_unsol_event(struct hda_codec *codec, |
11980 | unsigned int res) | 11853 | unsigned int res) |
11981 | { | 11854 | { |
11982 | if ((res >> 26) == ALC880_HP_EVENT) | 11855 | switch (res >> 26) { |
11856 | case ALC880_HP_EVENT: | ||
11983 | alc268_aspire_one_speaker_automute(codec); | 11857 | alc268_aspire_one_speaker_automute(codec); |
11984 | if ((res >> 26) == ALC880_MIC_EVENT) | 11858 | break; |
11985 | alc268_acer_mic_automute(codec); | 11859 | case ALC880_MIC_EVENT: |
11860 | alc_mic_automute(codec); | ||
11861 | break; | ||
11862 | } | ||
11863 | } | ||
11864 | |||
11865 | static void alc268_acer_lc_setup(struct hda_codec *codec) | ||
11866 | { | ||
11867 | struct alc_spec *spec = codec->spec; | ||
11868 | spec->ext_mic.pin = 0x18; | ||
11869 | spec->ext_mic.mux_idx = 0; | ||
11870 | spec->int_mic.pin = 0x12; | ||
11871 | spec->int_mic.mux_idx = 6; | ||
11872 | spec->auto_mic = 1; | ||
11986 | } | 11873 | } |
11987 | 11874 | ||
11988 | static void alc268_acer_lc_init_hook(struct hda_codec *codec) | 11875 | static void alc268_acer_lc_init_hook(struct hda_codec *codec) |
11989 | { | 11876 | { |
11990 | alc268_aspire_one_speaker_automute(codec); | 11877 | alc268_aspire_one_speaker_automute(codec); |
11991 | alc268_acer_mic_automute(codec); | 11878 | alc_mic_automute(codec); |
11992 | } | 11879 | } |
11993 | 11880 | ||
11994 | static struct snd_kcontrol_new alc268_dell_mixer[] = { | 11881 | static struct snd_kcontrol_new alc268_dell_mixer[] = { |
@@ -12006,17 +11893,22 @@ static struct hda_verb alc268_dell_verbs[] = { | |||
12006 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 11893 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
12007 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 11894 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
12008 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 11895 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
11896 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, | ||
12009 | { } | 11897 | { } |
12010 | }; | 11898 | }; |
12011 | 11899 | ||
12012 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 11900 | /* mute/unmute internal speaker according to the hp jack and mute state */ |
12013 | static void alc268_dell_init_hook(struct hda_codec *codec) | 11901 | static void alc268_dell_setup(struct hda_codec *codec) |
12014 | { | 11902 | { |
12015 | struct alc_spec *spec = codec->spec; | 11903 | struct alc_spec *spec = codec->spec; |
12016 | 11904 | ||
12017 | spec->autocfg.hp_pins[0] = 0x15; | 11905 | spec->autocfg.hp_pins[0] = 0x15; |
12018 | spec->autocfg.speaker_pins[0] = 0x14; | 11906 | spec->autocfg.speaker_pins[0] = 0x14; |
12019 | alc_automute_pin(codec); | 11907 | spec->ext_mic.pin = 0x18; |
11908 | spec->ext_mic.mux_idx = 0; | ||
11909 | spec->int_mic.pin = 0x19; | ||
11910 | spec->int_mic.mux_idx = 1; | ||
11911 | spec->auto_mic = 1; | ||
12020 | } | 11912 | } |
12021 | 11913 | ||
12022 | static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { | 11914 | static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { |
@@ -12037,38 +11929,16 @@ static struct hda_verb alc267_quanta_il1_verbs[] = { | |||
12037 | { } | 11929 | { } |
12038 | }; | 11930 | }; |
12039 | 11931 | ||
12040 | static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) | 11932 | static void alc267_quanta_il1_setup(struct hda_codec *codec) |
12041 | { | ||
12042 | unsigned int present; | ||
12043 | |||
12044 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
12045 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
12046 | snd_hda_codec_write(codec, 0x23, 0, | ||
12047 | AC_VERB_SET_CONNECT_SEL, | ||
12048 | present ? 0x00 : 0x01); | ||
12049 | } | ||
12050 | |||
12051 | static void alc267_quanta_il1_init_hook(struct hda_codec *codec) | ||
12052 | { | 11933 | { |
12053 | struct alc_spec *spec = codec->spec; | 11934 | struct alc_spec *spec = codec->spec; |
12054 | |||
12055 | spec->autocfg.hp_pins[0] = 0x15; | 11935 | spec->autocfg.hp_pins[0] = 0x15; |
12056 | spec->autocfg.speaker_pins[0] = 0x14; | 11936 | spec->autocfg.speaker_pins[0] = 0x14; |
12057 | alc_automute_pin(codec); | 11937 | spec->ext_mic.pin = 0x18; |
12058 | alc267_quanta_il1_mic_automute(codec); | 11938 | spec->ext_mic.mux_idx = 0; |
12059 | } | 11939 | spec->int_mic.pin = 0x19; |
12060 | 11940 | spec->int_mic.mux_idx = 1; | |
12061 | static void alc267_quanta_il1_unsol_event(struct hda_codec *codec, | 11941 | spec->auto_mic = 1; |
12062 | unsigned int res) | ||
12063 | { | ||
12064 | switch (res >> 26) { | ||
12065 | case ALC880_MIC_EVENT: | ||
12066 | alc267_quanta_il1_mic_automute(codec); | ||
12067 | break; | ||
12068 | default: | ||
12069 | alc_sku_unsol_event(codec, res); | ||
12070 | break; | ||
12071 | } | ||
12072 | } | 11942 | } |
12073 | 11943 | ||
12074 | /* | 11944 | /* |
@@ -12148,21 +12018,16 @@ static struct hda_verb alc268_volume_init_verbs[] = { | |||
12148 | { } | 12018 | { } |
12149 | }; | 12019 | }; |
12150 | 12020 | ||
12021 | static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { | ||
12022 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), | ||
12023 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), | ||
12024 | { } /* end */ | ||
12025 | }; | ||
12026 | |||
12151 | static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { | 12027 | static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { |
12152 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), | 12028 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), |
12153 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), | 12029 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), |
12154 | { | 12030 | _DEFINE_CAPSRC(1), |
12155 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
12156 | /* The multiple "Capture Source" controls confuse alsamixer | ||
12157 | * So call somewhat different.. | ||
12158 | */ | ||
12159 | /* .name = "Capture Source", */ | ||
12160 | .name = "Input Source", | ||
12161 | .count = 1, | ||
12162 | .info = alc_mux_enum_info, | ||
12163 | .get = alc_mux_enum_get, | ||
12164 | .put = alc_mux_enum_put, | ||
12165 | }, | ||
12166 | { } /* end */ | 12031 | { } /* end */ |
12167 | }; | 12032 | }; |
12168 | 12033 | ||
@@ -12171,18 +12036,7 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = { | |||
12171 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), | 12036 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), |
12172 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), | 12037 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), |
12173 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), | 12038 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), |
12174 | { | 12039 | _DEFINE_CAPSRC(2), |
12175 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
12176 | /* The multiple "Capture Source" controls confuse alsamixer | ||
12177 | * So call somewhat different.. | ||
12178 | */ | ||
12179 | /* .name = "Capture Source", */ | ||
12180 | .name = "Input Source", | ||
12181 | .count = 2, | ||
12182 | .info = alc_mux_enum_info, | ||
12183 | .get = alc_mux_enum_get, | ||
12184 | .put = alc_mux_enum_put, | ||
12185 | }, | ||
12186 | { } /* end */ | 12040 | { } /* end */ |
12187 | }; | 12041 | }; |
12188 | 12042 | ||
@@ -12269,26 +12123,38 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | |||
12269 | const char *ctlname, int idx) | 12123 | const char *ctlname, int idx) |
12270 | { | 12124 | { |
12271 | char name[32]; | 12125 | char name[32]; |
12126 | hda_nid_t dac; | ||
12272 | int err; | 12127 | int err; |
12273 | 12128 | ||
12274 | sprintf(name, "%s Playback Volume", ctlname); | 12129 | sprintf(name, "%s Playback Volume", ctlname); |
12275 | if (nid == 0x14) { | 12130 | switch (nid) { |
12276 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 12131 | case 0x14: |
12277 | HDA_COMPOSE_AMP_VAL(0x02, 3, idx, | 12132 | case 0x16: |
12278 | HDA_OUTPUT)); | 12133 | dac = 0x02; |
12279 | if (err < 0) | 12134 | break; |
12280 | return err; | 12135 | case 0x15: |
12281 | } else if (nid == 0x15) { | 12136 | dac = 0x03; |
12137 | break; | ||
12138 | default: | ||
12139 | return 0; | ||
12140 | } | ||
12141 | if (spec->multiout.dac_nids[0] != dac && | ||
12142 | spec->multiout.dac_nids[1] != dac) { | ||
12282 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | 12143 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, |
12283 | HDA_COMPOSE_AMP_VAL(0x03, 3, idx, | 12144 | HDA_COMPOSE_AMP_VAL(dac, 3, idx, |
12284 | HDA_OUTPUT)); | 12145 | HDA_OUTPUT)); |
12285 | if (err < 0) | 12146 | if (err < 0) |
12286 | return err; | 12147 | return err; |
12287 | } else | 12148 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; |
12288 | return -1; | 12149 | } |
12150 | |||
12289 | sprintf(name, "%s Playback Switch", ctlname); | 12151 | sprintf(name, "%s Playback Switch", ctlname); |
12290 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 12152 | if (nid != 0x16) |
12153 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
12291 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); | 12154 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); |
12155 | else /* mono */ | ||
12156 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
12157 | HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); | ||
12292 | if (err < 0) | 12158 | if (err < 0) |
12293 | return err; | 12159 | return err; |
12294 | return 0; | 12160 | return 0; |
@@ -12301,14 +12167,19 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
12301 | hda_nid_t nid; | 12167 | hda_nid_t nid; |
12302 | int err; | 12168 | int err; |
12303 | 12169 | ||
12304 | spec->multiout.num_dacs = 2; /* only use one dac */ | ||
12305 | spec->multiout.dac_nids = spec->private_dac_nids; | 12170 | spec->multiout.dac_nids = spec->private_dac_nids; |
12306 | spec->multiout.dac_nids[0] = 2; | ||
12307 | spec->multiout.dac_nids[1] = 3; | ||
12308 | 12171 | ||
12309 | nid = cfg->line_out_pins[0]; | 12172 | nid = cfg->line_out_pins[0]; |
12310 | if (nid) | 12173 | if (nid) { |
12311 | alc268_new_analog_output(spec, nid, "Front", 0); | 12174 | const char *name; |
12175 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
12176 | name = "Speaker"; | ||
12177 | else | ||
12178 | name = "Front"; | ||
12179 | err = alc268_new_analog_output(spec, nid, name, 0); | ||
12180 | if (err < 0) | ||
12181 | return err; | ||
12182 | } | ||
12312 | 12183 | ||
12313 | nid = cfg->speaker_pins[0]; | 12184 | nid = cfg->speaker_pins[0]; |
12314 | if (nid == 0x1d) { | 12185 | if (nid == 0x1d) { |
@@ -12317,16 +12188,23 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
12317 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 12188 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); |
12318 | if (err < 0) | 12189 | if (err < 0) |
12319 | return err; | 12190 | return err; |
12191 | } else { | ||
12192 | err = alc268_new_analog_output(spec, nid, "Speaker", 0); | ||
12193 | if (err < 0) | ||
12194 | return err; | ||
12320 | } | 12195 | } |
12321 | nid = cfg->hp_pins[0]; | 12196 | nid = cfg->hp_pins[0]; |
12322 | if (nid) | 12197 | if (nid) { |
12323 | alc268_new_analog_output(spec, nid, "Headphone", 0); | 12198 | err = alc268_new_analog_output(spec, nid, "Headphone", 0); |
12199 | if (err < 0) | ||
12200 | return err; | ||
12201 | } | ||
12324 | 12202 | ||
12325 | nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; | 12203 | nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; |
12326 | if (nid == 0x16) { | 12204 | if (nid == 0x16) { |
12327 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, | 12205 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, |
12328 | "Mono Playback Switch", | 12206 | "Mono Playback Switch", |
12329 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); | 12207 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); |
12330 | if (err < 0) | 12208 | if (err < 0) |
12331 | return err; | 12209 | return err; |
12332 | } | 12210 | } |
@@ -12338,32 +12216,40 @@ static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, | |||
12338 | const struct auto_pin_cfg *cfg) | 12216 | const struct auto_pin_cfg *cfg) |
12339 | { | 12217 | { |
12340 | struct hda_input_mux *imux = &spec->private_imux[0]; | 12218 | struct hda_input_mux *imux = &spec->private_imux[0]; |
12341 | int i, idx1; | 12219 | int i, idx1, dmic_nid; |
12342 | 12220 | ||
12343 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 12221 | dmic_nid = 0x12; |
12344 | switch(cfg->input_pins[i]) { | 12222 | while (dmic_nid <= 0x13) { |
12345 | case 0x18: | 12223 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
12346 | idx1 = 0; /* Mic 1 */ | 12224 | switch (cfg->input_pins[i]) { |
12347 | break; | 12225 | case 0x18: |
12348 | case 0x19: | 12226 | idx1 = 0; /* Mic 1 */ |
12349 | idx1 = 1; /* Mic 2 */ | 12227 | break; |
12350 | break; | 12228 | case 0x19: |
12351 | case 0x1a: | 12229 | idx1 = 1; /* Mic 2 */ |
12352 | idx1 = 2; /* Line In */ | 12230 | break; |
12353 | break; | 12231 | case 0x1a: |
12354 | case 0x1c: | 12232 | idx1 = 2; /* Line In */ |
12355 | idx1 = 3; /* CD */ | 12233 | break; |
12356 | break; | 12234 | case 0x1c: |
12357 | case 0x12: | 12235 | idx1 = 3; /* CD */ |
12358 | case 0x13: | 12236 | break; |
12359 | idx1 = 6; /* digital mics */ | 12237 | case 0x12: |
12360 | break; | 12238 | case 0x13: |
12361 | default: | 12239 | if (cfg->input_pins[i] != dmic_nid) |
12362 | continue; | 12240 | continue; |
12241 | idx1 = 6; /* digital mics */ | ||
12242 | break; | ||
12243 | default: | ||
12244 | continue; | ||
12245 | } | ||
12246 | imux->items[imux->num_items].label = | ||
12247 | auto_pin_cfg_labels[i]; | ||
12248 | imux->items[imux->num_items].index = idx1; | ||
12249 | imux->num_items++; | ||
12363 | } | 12250 | } |
12364 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 12251 | imux++; |
12365 | imux->items[imux->num_items].index = idx1; | 12252 | dmic_nid++; |
12366 | imux->num_items++; | ||
12367 | } | 12253 | } |
12368 | return 0; | 12254 | return 0; |
12369 | } | 12255 | } |
@@ -12461,7 +12347,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
12461 | add_mixer(spec, alc268_beep_mixer); | 12347 | add_mixer(spec, alc268_beep_mixer); |
12462 | 12348 | ||
12463 | add_verb(spec, alc268_volume_init_verbs); | 12349 | add_verb(spec, alc268_volume_init_verbs); |
12464 | spec->num_mux_defs = 1; | 12350 | spec->num_mux_defs = 2; |
12465 | spec->input_mux = &spec->private_imux[0]; | 12351 | spec->input_mux = &spec->private_imux[0]; |
12466 | 12352 | ||
12467 | err = alc_auto_add_mic_boost(codec); | 12353 | err = alc_auto_add_mic_boost(codec); |
@@ -12532,7 +12418,8 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { | |||
12532 | 12418 | ||
12533 | static struct alc_config_preset alc268_presets[] = { | 12419 | static struct alc_config_preset alc268_presets[] = { |
12534 | [ALC267_QUANTA_IL1] = { | 12420 | [ALC267_QUANTA_IL1] = { |
12535 | .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer }, | 12421 | .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, |
12422 | alc268_capture_nosrc_mixer }, | ||
12536 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | 12423 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, |
12537 | alc267_quanta_il1_verbs }, | 12424 | alc267_quanta_il1_verbs }, |
12538 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | 12425 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), |
@@ -12542,9 +12429,9 @@ static struct alc_config_preset alc268_presets[] = { | |||
12542 | .hp_nid = 0x03, | 12429 | .hp_nid = 0x03, |
12543 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 12430 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
12544 | .channel_mode = alc268_modes, | 12431 | .channel_mode = alc268_modes, |
12545 | .input_mux = &alc268_capture_source, | 12432 | .unsol_event = alc_sku_unsol_event, |
12546 | .unsol_event = alc267_quanta_il1_unsol_event, | 12433 | .setup = alc267_quanta_il1_setup, |
12547 | .init_hook = alc267_quanta_il1_init_hook, | 12434 | .init_hook = alc_inithook, |
12548 | }, | 12435 | }, |
12549 | [ALC268_3ST] = { | 12436 | [ALC268_3ST] = { |
12550 | .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, | 12437 | .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, |
@@ -12576,10 +12463,11 @@ static struct alc_config_preset alc268_presets[] = { | |||
12576 | .channel_mode = alc268_modes, | 12463 | .channel_mode = alc268_modes, |
12577 | .input_mux = &alc268_capture_source, | 12464 | .input_mux = &alc268_capture_source, |
12578 | .unsol_event = alc268_toshiba_unsol_event, | 12465 | .unsol_event = alc268_toshiba_unsol_event, |
12579 | .init_hook = alc268_toshiba_init_hook, | 12466 | .setup = alc268_toshiba_setup, |
12467 | .init_hook = alc268_toshiba_automute, | ||
12580 | }, | 12468 | }, |
12581 | [ALC268_ACER] = { | 12469 | [ALC268_ACER] = { |
12582 | .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, | 12470 | .mixers = { alc268_acer_mixer, alc268_capture_nosrc_mixer, |
12583 | alc268_beep_mixer }, | 12471 | alc268_beep_mixer }, |
12584 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | 12472 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, |
12585 | alc268_acer_verbs }, | 12473 | alc268_acer_verbs }, |
@@ -12615,7 +12503,7 @@ static struct alc_config_preset alc268_presets[] = { | |||
12615 | [ALC268_ACER_ASPIRE_ONE] = { | 12503 | [ALC268_ACER_ASPIRE_ONE] = { |
12616 | .mixers = { alc268_acer_aspire_one_mixer, | 12504 | .mixers = { alc268_acer_aspire_one_mixer, |
12617 | alc268_beep_mixer, | 12505 | alc268_beep_mixer, |
12618 | alc268_capture_alt_mixer }, | 12506 | alc268_capture_nosrc_mixer }, |
12619 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | 12507 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, |
12620 | alc268_acer_aspire_one_verbs }, | 12508 | alc268_acer_aspire_one_verbs }, |
12621 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | 12509 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), |
@@ -12626,22 +12514,26 @@ static struct alc_config_preset alc268_presets[] = { | |||
12626 | .hp_nid = 0x03, | 12514 | .hp_nid = 0x03, |
12627 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 12515 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
12628 | .channel_mode = alc268_modes, | 12516 | .channel_mode = alc268_modes, |
12629 | .input_mux = &alc268_acer_lc_capture_source, | ||
12630 | .unsol_event = alc268_acer_lc_unsol_event, | 12517 | .unsol_event = alc268_acer_lc_unsol_event, |
12518 | .setup = alc268_acer_lc_setup, | ||
12631 | .init_hook = alc268_acer_lc_init_hook, | 12519 | .init_hook = alc268_acer_lc_init_hook, |
12632 | }, | 12520 | }, |
12633 | [ALC268_DELL] = { | 12521 | [ALC268_DELL] = { |
12634 | .mixers = { alc268_dell_mixer, alc268_beep_mixer }, | 12522 | .mixers = { alc268_dell_mixer, alc268_beep_mixer, |
12523 | alc268_capture_nosrc_mixer }, | ||
12635 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | 12524 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, |
12636 | alc268_dell_verbs }, | 12525 | alc268_dell_verbs }, |
12637 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | 12526 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), |
12638 | .dac_nids = alc268_dac_nids, | 12527 | .dac_nids = alc268_dac_nids, |
12528 | .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), | ||
12529 | .adc_nids = alc268_adc_nids_alt, | ||
12530 | .capsrc_nids = alc268_capsrc_nids, | ||
12639 | .hp_nid = 0x02, | 12531 | .hp_nid = 0x02, |
12640 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 12532 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
12641 | .channel_mode = alc268_modes, | 12533 | .channel_mode = alc268_modes, |
12642 | .unsol_event = alc_sku_unsol_event, | 12534 | .unsol_event = alc_sku_unsol_event, |
12643 | .init_hook = alc268_dell_init_hook, | 12535 | .setup = alc268_dell_setup, |
12644 | .input_mux = &alc268_capture_source, | 12536 | .init_hook = alc_inithook, |
12645 | }, | 12537 | }, |
12646 | [ALC268_ZEPTO] = { | 12538 | [ALC268_ZEPTO] = { |
12647 | .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, | 12539 | .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, |
@@ -12658,8 +12550,8 @@ static struct alc_config_preset alc268_presets[] = { | |||
12658 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 12550 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
12659 | .channel_mode = alc268_modes, | 12551 | .channel_mode = alc268_modes, |
12660 | .input_mux = &alc268_capture_source, | 12552 | .input_mux = &alc268_capture_source, |
12661 | .unsol_event = alc268_toshiba_unsol_event, | 12553 | .setup = alc268_toshiba_setup, |
12662 | .init_hook = alc268_toshiba_init_hook | 12554 | .init_hook = alc268_toshiba_automute, |
12663 | }, | 12555 | }, |
12664 | #ifdef CONFIG_SND_DEBUG | 12556 | #ifdef CONFIG_SND_DEBUG |
12665 | [ALC268_TEST] = { | 12557 | [ALC268_TEST] = { |
@@ -12697,8 +12589,8 @@ static int patch_alc268(struct hda_codec *codec) | |||
12697 | alc268_cfg_tbl); | 12589 | alc268_cfg_tbl); |
12698 | 12590 | ||
12699 | if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { | 12591 | if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { |
12700 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 12592 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
12701 | "trying auto-probe from BIOS...\n", codec->chip_name); | 12593 | codec->chip_name); |
12702 | board_config = ALC268_AUTO; | 12594 | board_config = ALC268_AUTO; |
12703 | } | 12595 | } |
12704 | 12596 | ||
@@ -12717,7 +12609,7 @@ static int patch_alc268(struct hda_codec *codec) | |||
12717 | } | 12609 | } |
12718 | 12610 | ||
12719 | if (board_config != ALC268_AUTO) | 12611 | if (board_config != ALC268_AUTO) |
12720 | setup_preset(spec, &alc268_presets[board_config]); | 12612 | setup_preset(codec, &alc268_presets[board_config]); |
12721 | 12613 | ||
12722 | spec->stream_analog_playback = &alc268_pcm_analog_playback; | 12614 | spec->stream_analog_playback = &alc268_pcm_analog_playback; |
12723 | spec->stream_analog_capture = &alc268_pcm_analog_capture; | 12615 | spec->stream_analog_capture = &alc268_pcm_analog_capture; |
@@ -12754,11 +12646,15 @@ static int patch_alc268(struct hda_codec *codec) | |||
12754 | int i; | 12646 | int i; |
12755 | 12647 | ||
12756 | /* get type */ | 12648 | /* get type */ |
12757 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 12649 | wcap = get_wcaps_type(wcap); |
12758 | if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { | 12650 | if (spec->auto_mic || |
12651 | wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { | ||
12759 | spec->adc_nids = alc268_adc_nids_alt; | 12652 | spec->adc_nids = alc268_adc_nids_alt; |
12760 | spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); | 12653 | spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); |
12761 | add_mixer(spec, alc268_capture_alt_mixer); | 12654 | if (spec->auto_mic || spec->input_mux->num_items == 1) |
12655 | add_mixer(spec, alc268_capture_nosrc_mixer); | ||
12656 | else | ||
12657 | add_mixer(spec, alc268_capture_alt_mixer); | ||
12762 | } else { | 12658 | } else { |
12763 | spec->adc_nids = alc268_adc_nids; | 12659 | spec->adc_nids = alc268_adc_nids; |
12764 | spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); | 12660 | spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); |
@@ -12769,6 +12665,8 @@ static int patch_alc268(struct hda_codec *codec) | |||
12769 | for (i = 0; i < spec->num_adc_nids; i++) | 12665 | for (i = 0; i < spec->num_adc_nids; i++) |
12770 | snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], | 12666 | snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], |
12771 | 0, AC_VERB_SET_CONNECT_SEL, | 12667 | 0, AC_VERB_SET_CONNECT_SEL, |
12668 | i < spec->num_mux_defs ? | ||
12669 | spec->input_mux[i].items[0].index : | ||
12772 | spec->input_mux->items[0].index); | 12670 | spec->input_mux->items[0].index); |
12773 | } | 12671 | } |
12774 | 12672 | ||
@@ -12803,22 +12701,6 @@ static hda_nid_t alc269_capsrc_nids[1] = { | |||
12803 | * not a mux! | 12701 | * not a mux! |
12804 | */ | 12702 | */ |
12805 | 12703 | ||
12806 | static struct hda_input_mux alc269_eeepc_dmic_capture_source = { | ||
12807 | .num_items = 2, | ||
12808 | .items = { | ||
12809 | { "i-Mic", 0x5 }, | ||
12810 | { "e-Mic", 0x0 }, | ||
12811 | }, | ||
12812 | }; | ||
12813 | |||
12814 | static struct hda_input_mux alc269_eeepc_amic_capture_source = { | ||
12815 | .num_items = 2, | ||
12816 | .items = { | ||
12817 | { "i-Mic", 0x1 }, | ||
12818 | { "e-Mic", 0x0 }, | ||
12819 | }, | ||
12820 | }; | ||
12821 | |||
12822 | #define alc269_modes alc260_modes | 12704 | #define alc269_modes alc260_modes |
12823 | #define alc269_capture_source alc880_lg_lw_capture_source | 12705 | #define alc269_capture_source alc880_lg_lw_capture_source |
12824 | 12706 | ||
@@ -12980,16 +12862,6 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec) | |||
12980 | AC_VERB_SET_PROC_COEF, 0x480); | 12862 | AC_VERB_SET_PROC_COEF, 0x480); |
12981 | } | 12863 | } |
12982 | 12864 | ||
12983 | static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec) | ||
12984 | { | ||
12985 | unsigned int present; | ||
12986 | |||
12987 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
12988 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
12989 | snd_hda_codec_write(codec, 0x23, 0, | ||
12990 | AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1); | ||
12991 | } | ||
12992 | |||
12993 | static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) | 12865 | static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) |
12994 | { | 12866 | { |
12995 | unsigned int present_laptop; | 12867 | unsigned int present_laptop; |
@@ -13016,10 +12888,14 @@ static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) | |||
13016 | static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, | 12888 | static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, |
13017 | unsigned int res) | 12889 | unsigned int res) |
13018 | { | 12890 | { |
13019 | if ((res >> 26) == ALC880_HP_EVENT) | 12891 | switch (res >> 26) { |
12892 | case ALC880_HP_EVENT: | ||
13020 | alc269_quanta_fl1_speaker_automute(codec); | 12893 | alc269_quanta_fl1_speaker_automute(codec); |
13021 | if ((res >> 26) == ALC880_MIC_EVENT) | 12894 | break; |
13022 | alc269_quanta_fl1_mic_automute(codec); | 12895 | case ALC880_MIC_EVENT: |
12896 | alc_mic_automute(codec); | ||
12897 | break; | ||
12898 | } | ||
13023 | } | 12899 | } |
13024 | 12900 | ||
13025 | static void alc269_lifebook_unsol_event(struct hda_codec *codec, | 12901 | static void alc269_lifebook_unsol_event(struct hda_codec *codec, |
@@ -13031,10 +12907,20 @@ static void alc269_lifebook_unsol_event(struct hda_codec *codec, | |||
13031 | alc269_lifebook_mic_autoswitch(codec); | 12907 | alc269_lifebook_mic_autoswitch(codec); |
13032 | } | 12908 | } |
13033 | 12909 | ||
12910 | static void alc269_quanta_fl1_setup(struct hda_codec *codec) | ||
12911 | { | ||
12912 | struct alc_spec *spec = codec->spec; | ||
12913 | spec->ext_mic.pin = 0x18; | ||
12914 | spec->ext_mic.mux_idx = 0; | ||
12915 | spec->int_mic.pin = 0x19; | ||
12916 | spec->int_mic.mux_idx = 1; | ||
12917 | spec->auto_mic = 1; | ||
12918 | } | ||
12919 | |||
13034 | static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) | 12920 | static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) |
13035 | { | 12921 | { |
13036 | alc269_quanta_fl1_speaker_automute(codec); | 12922 | alc269_quanta_fl1_speaker_automute(codec); |
13037 | alc269_quanta_fl1_mic_automute(codec); | 12923 | alc_mic_automute(codec); |
13038 | } | 12924 | } |
13039 | 12925 | ||
13040 | static void alc269_lifebook_init_hook(struct hda_codec *codec) | 12926 | static void alc269_lifebook_init_hook(struct hda_codec *codec) |
@@ -13079,60 +12965,44 @@ static void alc269_speaker_automute(struct hda_codec *codec) | |||
13079 | AMP_IN_MUTE(0), bits); | 12965 | AMP_IN_MUTE(0), bits); |
13080 | } | 12966 | } |
13081 | 12967 | ||
13082 | static void alc269_eeepc_dmic_automute(struct hda_codec *codec) | ||
13083 | { | ||
13084 | unsigned int present; | ||
13085 | |||
13086 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
13087 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
13088 | snd_hda_codec_write(codec, 0x23, 0, | ||
13089 | AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5)); | ||
13090 | } | ||
13091 | |||
13092 | static void alc269_eeepc_amic_automute(struct hda_codec *codec) | ||
13093 | { | ||
13094 | unsigned int present; | ||
13095 | |||
13096 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
13097 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
13098 | snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
13099 | 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); | ||
13100 | snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
13101 | 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); | ||
13102 | } | ||
13103 | |||
13104 | /* unsolicited event for HP jack sensing */ | 12968 | /* unsolicited event for HP jack sensing */ |
13105 | static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec, | 12969 | static void alc269_eeepc_unsol_event(struct hda_codec *codec, |
13106 | unsigned int res) | 12970 | unsigned int res) |
13107 | { | 12971 | { |
13108 | if ((res >> 26) == ALC880_HP_EVENT) | 12972 | switch (res >> 26) { |
12973 | case ALC880_HP_EVENT: | ||
13109 | alc269_speaker_automute(codec); | 12974 | alc269_speaker_automute(codec); |
13110 | 12975 | break; | |
13111 | if ((res >> 26) == ALC880_MIC_EVENT) | 12976 | case ALC880_MIC_EVENT: |
13112 | alc269_eeepc_dmic_automute(codec); | 12977 | alc_mic_automute(codec); |
12978 | break; | ||
12979 | } | ||
13113 | } | 12980 | } |
13114 | 12981 | ||
13115 | static void alc269_eeepc_dmic_inithook(struct hda_codec *codec) | 12982 | static void alc269_eeepc_dmic_setup(struct hda_codec *codec) |
13116 | { | 12983 | { |
13117 | alc269_speaker_automute(codec); | 12984 | struct alc_spec *spec = codec->spec; |
13118 | alc269_eeepc_dmic_automute(codec); | 12985 | spec->ext_mic.pin = 0x18; |
12986 | spec->ext_mic.mux_idx = 0; | ||
12987 | spec->int_mic.pin = 0x12; | ||
12988 | spec->int_mic.mux_idx = 5; | ||
12989 | spec->auto_mic = 1; | ||
13119 | } | 12990 | } |
13120 | 12991 | ||
13121 | /* unsolicited event for HP jack sensing */ | 12992 | static void alc269_eeepc_amic_setup(struct hda_codec *codec) |
13122 | static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec, | ||
13123 | unsigned int res) | ||
13124 | { | 12993 | { |
13125 | if ((res >> 26) == ALC880_HP_EVENT) | 12994 | struct alc_spec *spec = codec->spec; |
13126 | alc269_speaker_automute(codec); | 12995 | spec->ext_mic.pin = 0x18; |
13127 | 12996 | spec->ext_mic.mux_idx = 0; | |
13128 | if ((res >> 26) == ALC880_MIC_EVENT) | 12997 | spec->int_mic.pin = 0x19; |
13129 | alc269_eeepc_amic_automute(codec); | 12998 | spec->int_mic.mux_idx = 1; |
12999 | spec->auto_mic = 1; | ||
13130 | } | 13000 | } |
13131 | 13001 | ||
13132 | static void alc269_eeepc_amic_inithook(struct hda_codec *codec) | 13002 | static void alc269_eeepc_inithook(struct hda_codec *codec) |
13133 | { | 13003 | { |
13134 | alc269_speaker_automute(codec); | 13004 | alc269_speaker_automute(codec); |
13135 | alc269_eeepc_amic_automute(codec); | 13005 | alc_mic_automute(codec); |
13136 | } | 13006 | } |
13137 | 13007 | ||
13138 | /* | 13008 | /* |
@@ -13362,7 +13232,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
13362 | return err; | 13232 | return err; |
13363 | 13233 | ||
13364 | if (!spec->cap_mixer && !spec->no_analog) | 13234 | if (!spec->cap_mixer && !spec->no_analog) |
13365 | set_capture_mixer(spec); | 13235 | set_capture_mixer(codec); |
13366 | 13236 | ||
13367 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); | 13237 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); |
13368 | 13238 | ||
@@ -13438,6 +13308,7 @@ static struct alc_config_preset alc269_presets[] = { | |||
13438 | .channel_mode = alc269_modes, | 13308 | .channel_mode = alc269_modes, |
13439 | .input_mux = &alc269_capture_source, | 13309 | .input_mux = &alc269_capture_source, |
13440 | .unsol_event = alc269_quanta_fl1_unsol_event, | 13310 | .unsol_event = alc269_quanta_fl1_unsol_event, |
13311 | .setup = alc269_quanta_fl1_setup, | ||
13441 | .init_hook = alc269_quanta_fl1_init_hook, | 13312 | .init_hook = alc269_quanta_fl1_init_hook, |
13442 | }, | 13313 | }, |
13443 | [ALC269_ASUS_EEEPC_P703] = { | 13314 | [ALC269_ASUS_EEEPC_P703] = { |
@@ -13450,9 +13321,9 @@ static struct alc_config_preset alc269_presets[] = { | |||
13450 | .hp_nid = 0x03, | 13321 | .hp_nid = 0x03, |
13451 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | 13322 | .num_channel_mode = ARRAY_SIZE(alc269_modes), |
13452 | .channel_mode = alc269_modes, | 13323 | .channel_mode = alc269_modes, |
13453 | .input_mux = &alc269_eeepc_amic_capture_source, | 13324 | .unsol_event = alc269_eeepc_unsol_event, |
13454 | .unsol_event = alc269_eeepc_amic_unsol_event, | 13325 | .setup = alc269_eeepc_amic_setup, |
13455 | .init_hook = alc269_eeepc_amic_inithook, | 13326 | .init_hook = alc269_eeepc_inithook, |
13456 | }, | 13327 | }, |
13457 | [ALC269_ASUS_EEEPC_P901] = { | 13328 | [ALC269_ASUS_EEEPC_P901] = { |
13458 | .mixers = { alc269_eeepc_mixer }, | 13329 | .mixers = { alc269_eeepc_mixer }, |
@@ -13464,9 +13335,9 @@ static struct alc_config_preset alc269_presets[] = { | |||
13464 | .hp_nid = 0x03, | 13335 | .hp_nid = 0x03, |
13465 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | 13336 | .num_channel_mode = ARRAY_SIZE(alc269_modes), |
13466 | .channel_mode = alc269_modes, | 13337 | .channel_mode = alc269_modes, |
13467 | .input_mux = &alc269_eeepc_dmic_capture_source, | 13338 | .unsol_event = alc269_eeepc_unsol_event, |
13468 | .unsol_event = alc269_eeepc_dmic_unsol_event, | 13339 | .setup = alc269_eeepc_dmic_setup, |
13469 | .init_hook = alc269_eeepc_dmic_inithook, | 13340 | .init_hook = alc269_eeepc_inithook, |
13470 | }, | 13341 | }, |
13471 | [ALC269_FUJITSU] = { | 13342 | [ALC269_FUJITSU] = { |
13472 | .mixers = { alc269_fujitsu_mixer }, | 13343 | .mixers = { alc269_fujitsu_mixer }, |
@@ -13478,9 +13349,9 @@ static struct alc_config_preset alc269_presets[] = { | |||
13478 | .hp_nid = 0x03, | 13349 | .hp_nid = 0x03, |
13479 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | 13350 | .num_channel_mode = ARRAY_SIZE(alc269_modes), |
13480 | .channel_mode = alc269_modes, | 13351 | .channel_mode = alc269_modes, |
13481 | .input_mux = &alc269_eeepc_dmic_capture_source, | 13352 | .unsol_event = alc269_eeepc_unsol_event, |
13482 | .unsol_event = alc269_eeepc_dmic_unsol_event, | 13353 | .setup = alc269_eeepc_dmic_setup, |
13483 | .init_hook = alc269_eeepc_dmic_inithook, | 13354 | .init_hook = alc269_eeepc_inithook, |
13484 | }, | 13355 | }, |
13485 | [ALC269_LIFEBOOK] = { | 13356 | [ALC269_LIFEBOOK] = { |
13486 | .mixers = { alc269_lifebook_mixer }, | 13357 | .mixers = { alc269_lifebook_mixer }, |
@@ -13515,8 +13386,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
13515 | alc269_cfg_tbl); | 13386 | alc269_cfg_tbl); |
13516 | 13387 | ||
13517 | if (board_config < 0) { | 13388 | if (board_config < 0) { |
13518 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 13389 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
13519 | "trying auto-probe from BIOS...\n", codec->chip_name); | 13390 | codec->chip_name); |
13520 | board_config = ALC269_AUTO; | 13391 | board_config = ALC269_AUTO; |
13521 | } | 13392 | } |
13522 | 13393 | ||
@@ -13541,7 +13412,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
13541 | } | 13412 | } |
13542 | 13413 | ||
13543 | if (board_config != ALC269_AUTO) | 13414 | if (board_config != ALC269_AUTO) |
13544 | setup_preset(spec, &alc269_presets[board_config]); | 13415 | setup_preset(codec, &alc269_presets[board_config]); |
13545 | 13416 | ||
13546 | if (codec->subsystem_id == 0x17aa3bf8) { | 13417 | if (codec->subsystem_id == 0x17aa3bf8) { |
13547 | /* Due to a hardware problem on Lenovo Ideadpad, we need to | 13418 | /* Due to a hardware problem on Lenovo Ideadpad, we need to |
@@ -13560,7 +13431,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
13560 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); | 13431 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); |
13561 | spec->capsrc_nids = alc269_capsrc_nids; | 13432 | spec->capsrc_nids = alc269_capsrc_nids; |
13562 | if (!spec->cap_mixer) | 13433 | if (!spec->cap_mixer) |
13563 | set_capture_mixer(spec); | 13434 | set_capture_mixer(codec); |
13564 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 13435 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
13565 | 13436 | ||
13566 | spec->vmaster_nid = 0x02; | 13437 | spec->vmaster_nid = 0x02; |
@@ -14110,23 +13981,23 @@ static struct hda_verb alc861_auto_init_verbs[] = { | |||
14110 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 13981 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
14111 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, | 13982 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, |
14112 | 13983 | ||
14113 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 13984 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
14114 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 13985 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
14115 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 13986 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
14116 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 13987 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
14117 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 13988 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
14118 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 13989 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
14119 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 13990 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
14120 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 13991 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
14121 | 13992 | ||
14122 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 13993 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
14123 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 13994 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
14124 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 13995 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
14125 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 13996 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
14126 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 13997 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
14127 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 13998 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
14128 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 13999 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
14129 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 14000 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
14130 | 14001 | ||
14131 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ | 14002 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ |
14132 | 14003 | ||
@@ -14198,64 +14069,96 @@ static struct hda_input_mux alc861_capture_source = { | |||
14198 | }, | 14069 | }, |
14199 | }; | 14070 | }; |
14200 | 14071 | ||
14072 | static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | ||
14073 | { | ||
14074 | struct alc_spec *spec = codec->spec; | ||
14075 | hda_nid_t mix, srcs[5]; | ||
14076 | int i, j, num; | ||
14077 | |||
14078 | if (snd_hda_get_connections(codec, pin, &mix, 1) != 1) | ||
14079 | return 0; | ||
14080 | num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); | ||
14081 | if (num < 0) | ||
14082 | return 0; | ||
14083 | for (i = 0; i < num; i++) { | ||
14084 | unsigned int type; | ||
14085 | type = get_wcaps_type(get_wcaps(codec, srcs[i])); | ||
14086 | if (type != AC_WID_AUD_OUT) | ||
14087 | continue; | ||
14088 | for (j = 0; j < spec->multiout.num_dacs; j++) | ||
14089 | if (spec->multiout.dac_nids[j] == srcs[i]) | ||
14090 | break; | ||
14091 | if (j >= spec->multiout.num_dacs) | ||
14092 | return srcs[i]; | ||
14093 | } | ||
14094 | return 0; | ||
14095 | } | ||
14096 | |||
14201 | /* fill in the dac_nids table from the parsed pin configuration */ | 14097 | /* fill in the dac_nids table from the parsed pin configuration */ |
14202 | static int alc861_auto_fill_dac_nids(struct alc_spec *spec, | 14098 | static int alc861_auto_fill_dac_nids(struct hda_codec *codec, |
14203 | const struct auto_pin_cfg *cfg) | 14099 | const struct auto_pin_cfg *cfg) |
14204 | { | 14100 | { |
14101 | struct alc_spec *spec = codec->spec; | ||
14205 | int i; | 14102 | int i; |
14206 | hda_nid_t nid; | 14103 | hda_nid_t nid, dac; |
14207 | 14104 | ||
14208 | spec->multiout.dac_nids = spec->private_dac_nids; | 14105 | spec->multiout.dac_nids = spec->private_dac_nids; |
14209 | for (i = 0; i < cfg->line_outs; i++) { | 14106 | for (i = 0; i < cfg->line_outs; i++) { |
14210 | nid = cfg->line_out_pins[i]; | 14107 | nid = cfg->line_out_pins[i]; |
14211 | if (nid) { | 14108 | dac = alc861_look_for_dac(codec, nid); |
14212 | if (i >= ARRAY_SIZE(alc861_dac_nids)) | 14109 | if (!dac) |
14213 | continue; | 14110 | continue; |
14214 | spec->multiout.dac_nids[i] = alc861_dac_nids[i]; | 14111 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; |
14215 | } | ||
14216 | } | 14112 | } |
14217 | spec->multiout.num_dacs = cfg->line_outs; | ||
14218 | return 0; | 14113 | return 0; |
14219 | } | 14114 | } |
14220 | 14115 | ||
14116 | static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, | ||
14117 | hda_nid_t nid, unsigned int chs) | ||
14118 | { | ||
14119 | char name[32]; | ||
14120 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); | ||
14121 | return add_control(codec->spec, ALC_CTL_WIDGET_MUTE, name, | ||
14122 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | ||
14123 | } | ||
14124 | |||
14221 | /* add playback controls from the parsed DAC table */ | 14125 | /* add playback controls from the parsed DAC table */ |
14222 | static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, | 14126 | static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, |
14223 | const struct auto_pin_cfg *cfg) | 14127 | const struct auto_pin_cfg *cfg) |
14224 | { | 14128 | { |
14225 | char name[32]; | 14129 | struct alc_spec *spec = codec->spec; |
14226 | static const char *chname[4] = { | 14130 | static const char *chname[4] = { |
14227 | "Front", "Surround", NULL /*CLFE*/, "Side" | 14131 | "Front", "Surround", NULL /*CLFE*/, "Side" |
14228 | }; | 14132 | }; |
14229 | hda_nid_t nid; | 14133 | hda_nid_t nid; |
14230 | int i, idx, err; | 14134 | int i, err; |
14135 | |||
14136 | if (cfg->line_outs == 1) { | ||
14137 | const char *pfx = NULL; | ||
14138 | if (!cfg->hp_outs) | ||
14139 | pfx = "Master"; | ||
14140 | else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
14141 | pfx = "Speaker"; | ||
14142 | if (pfx) { | ||
14143 | nid = spec->multiout.dac_nids[0]; | ||
14144 | return alc861_create_out_sw(codec, pfx, nid, 3); | ||
14145 | } | ||
14146 | } | ||
14231 | 14147 | ||
14232 | for (i = 0; i < cfg->line_outs; i++) { | 14148 | for (i = 0; i < cfg->line_outs; i++) { |
14233 | nid = spec->multiout.dac_nids[i]; | 14149 | nid = spec->multiout.dac_nids[i]; |
14234 | if (!nid) | 14150 | if (!nid) |
14235 | continue; | 14151 | continue; |
14236 | if (nid == 0x05) { | 14152 | if (i == 2) { |
14237 | /* Center/LFE */ | 14153 | /* Center/LFE */ |
14238 | err = add_control(spec, ALC_CTL_BIND_MUTE, | 14154 | err = alc861_create_out_sw(codec, "Center", nid, 1); |
14239 | "Center Playback Switch", | ||
14240 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, | ||
14241 | HDA_OUTPUT)); | ||
14242 | if (err < 0) | 14155 | if (err < 0) |
14243 | return err; | 14156 | return err; |
14244 | err = add_control(spec, ALC_CTL_BIND_MUTE, | 14157 | err = alc861_create_out_sw(codec, "LFE", nid, 2); |
14245 | "LFE Playback Switch", | ||
14246 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
14247 | HDA_OUTPUT)); | ||
14248 | if (err < 0) | 14158 | if (err < 0) |
14249 | return err; | 14159 | return err; |
14250 | } else { | 14160 | } else { |
14251 | for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; | 14161 | err = alc861_create_out_sw(codec, chname[i], nid, 3); |
14252 | idx++) | ||
14253 | if (nid == alc861_dac_nids[idx]) | ||
14254 | break; | ||
14255 | sprintf(name, "%s Playback Switch", chname[idx]); | ||
14256 | err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
14257 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | ||
14258 | HDA_OUTPUT)); | ||
14259 | if (err < 0) | 14162 | if (err < 0) |
14260 | return err; | 14163 | return err; |
14261 | } | 14164 | } |
@@ -14263,8 +14166,9 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
14263 | return 0; | 14166 | return 0; |
14264 | } | 14167 | } |
14265 | 14168 | ||
14266 | static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) | 14169 | static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) |
14267 | { | 14170 | { |
14171 | struct alc_spec *spec = codec->spec; | ||
14268 | int err; | 14172 | int err; |
14269 | hda_nid_t nid; | 14173 | hda_nid_t nid; |
14270 | 14174 | ||
@@ -14272,21 +14176,22 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) | |||
14272 | return 0; | 14176 | return 0; |
14273 | 14177 | ||
14274 | if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { | 14178 | if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { |
14275 | nid = 0x03; | 14179 | nid = alc861_look_for_dac(codec, pin); |
14276 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, | 14180 | if (nid) { |
14277 | "Headphone Playback Switch", | 14181 | err = alc861_create_out_sw(codec, "Headphone", nid, 3); |
14278 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | 14182 | if (err < 0) |
14279 | if (err < 0) | 14183 | return err; |
14280 | return err; | 14184 | spec->multiout.hp_nid = nid; |
14281 | spec->multiout.hp_nid = nid; | 14185 | } |
14282 | } | 14186 | } |
14283 | return 0; | 14187 | return 0; |
14284 | } | 14188 | } |
14285 | 14189 | ||
14286 | /* create playback/capture controls for input pins */ | 14190 | /* create playback/capture controls for input pins */ |
14287 | static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, | 14191 | static int alc861_auto_create_analog_input_ctls(struct hda_codec *codec, |
14288 | const struct auto_pin_cfg *cfg) | 14192 | const struct auto_pin_cfg *cfg) |
14289 | { | 14193 | { |
14194 | struct alc_spec *spec = codec->spec; | ||
14290 | struct hda_input_mux *imux = &spec->private_imux[0]; | 14195 | struct hda_input_mux *imux = &spec->private_imux[0]; |
14291 | int i, err, idx, idx1; | 14196 | int i, err, idx, idx1; |
14292 | 14197 | ||
@@ -14330,12 +14235,29 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, | |||
14330 | 14235 | ||
14331 | static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, | 14236 | static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, |
14332 | hda_nid_t nid, | 14237 | hda_nid_t nid, |
14333 | int pin_type, int dac_idx) | 14238 | int pin_type, hda_nid_t dac) |
14334 | { | 14239 | { |
14240 | hda_nid_t mix, srcs[5]; | ||
14241 | int i, num; | ||
14242 | |||
14335 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 14243 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
14336 | pin_type); | 14244 | pin_type); |
14337 | snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 14245 | snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
14338 | AMP_OUT_UNMUTE); | 14246 | AMP_OUT_UNMUTE); |
14247 | if (snd_hda_get_connections(codec, nid, &mix, 1) != 1) | ||
14248 | return; | ||
14249 | num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); | ||
14250 | if (num < 0) | ||
14251 | return; | ||
14252 | for (i = 0; i < num; i++) { | ||
14253 | unsigned int mute; | ||
14254 | if (srcs[i] == dac || srcs[i] == 0x15) | ||
14255 | mute = AMP_IN_UNMUTE(i); | ||
14256 | else | ||
14257 | mute = AMP_IN_MUTE(i); | ||
14258 | snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
14259 | mute); | ||
14260 | } | ||
14339 | } | 14261 | } |
14340 | 14262 | ||
14341 | static void alc861_auto_init_multi_out(struct hda_codec *codec) | 14263 | static void alc861_auto_init_multi_out(struct hda_codec *codec) |
@@ -14358,12 +14280,13 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec) | |||
14358 | hda_nid_t pin; | 14280 | hda_nid_t pin; |
14359 | 14281 | ||
14360 | pin = spec->autocfg.hp_pins[0]; | 14282 | pin = spec->autocfg.hp_pins[0]; |
14361 | if (pin) /* connect to front */ | 14283 | if (pin) |
14362 | alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, | 14284 | alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, |
14363 | spec->multiout.dac_nids[0]); | 14285 | spec->multiout.hp_nid); |
14364 | pin = spec->autocfg.speaker_pins[0]; | 14286 | pin = spec->autocfg.speaker_pins[0]; |
14365 | if (pin) | 14287 | if (pin) |
14366 | alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); | 14288 | alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, |
14289 | spec->multiout.dac_nids[0]); | ||
14367 | } | 14290 | } |
14368 | 14291 | ||
14369 | static void alc861_auto_init_analog_input(struct hda_codec *codec) | 14292 | static void alc861_auto_init_analog_input(struct hda_codec *codec) |
@@ -14395,16 +14318,16 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
14395 | if (!spec->autocfg.line_outs) | 14318 | if (!spec->autocfg.line_outs) |
14396 | return 0; /* can't find valid BIOS pin config */ | 14319 | return 0; /* can't find valid BIOS pin config */ |
14397 | 14320 | ||
14398 | err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); | 14321 | err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); |
14399 | if (err < 0) | 14322 | if (err < 0) |
14400 | return err; | 14323 | return err; |
14401 | err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); | 14324 | err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); |
14402 | if (err < 0) | 14325 | if (err < 0) |
14403 | return err; | 14326 | return err; |
14404 | err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); | 14327 | err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]); |
14405 | if (err < 0) | 14328 | if (err < 0) |
14406 | return err; | 14329 | return err; |
14407 | err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); | 14330 | err = alc861_auto_create_analog_input_ctls(codec, &spec->autocfg); |
14408 | if (err < 0) | 14331 | if (err < 0) |
14409 | return err; | 14332 | return err; |
14410 | 14333 | ||
@@ -14423,7 +14346,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
14423 | 14346 | ||
14424 | spec->adc_nids = alc861_adc_nids; | 14347 | spec->adc_nids = alc861_adc_nids; |
14425 | spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); | 14348 | spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); |
14426 | set_capture_mixer(spec); | 14349 | set_capture_mixer(codec); |
14427 | 14350 | ||
14428 | alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); | 14351 | alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); |
14429 | 14352 | ||
@@ -14616,8 +14539,8 @@ static int patch_alc861(struct hda_codec *codec) | |||
14616 | alc861_cfg_tbl); | 14539 | alc861_cfg_tbl); |
14617 | 14540 | ||
14618 | if (board_config < 0) { | 14541 | if (board_config < 0) { |
14619 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 14542 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
14620 | "trying auto-probe from BIOS...\n", codec->chip_name); | 14543 | codec->chip_name); |
14621 | board_config = ALC861_AUTO; | 14544 | board_config = ALC861_AUTO; |
14622 | } | 14545 | } |
14623 | 14546 | ||
@@ -14642,7 +14565,7 @@ static int patch_alc861(struct hda_codec *codec) | |||
14642 | } | 14565 | } |
14643 | 14566 | ||
14644 | if (board_config != ALC861_AUTO) | 14567 | if (board_config != ALC861_AUTO) |
14645 | setup_preset(spec, &alc861_presets[board_config]); | 14568 | setup_preset(codec, &alc861_presets[board_config]); |
14646 | 14569 | ||
14647 | spec->stream_analog_playback = &alc861_pcm_analog_playback; | 14570 | spec->stream_analog_playback = &alc861_pcm_analog_playback; |
14648 | spec->stream_analog_capture = &alc861_pcm_analog_capture; | 14571 | spec->stream_analog_capture = &alc861_pcm_analog_capture; |
@@ -15045,12 +14968,15 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) | |||
15045 | HDA_AMP_MUTE, bits); | 14968 | HDA_AMP_MUTE, bits); |
15046 | } | 14969 | } |
15047 | 14970 | ||
15048 | static void alc861vd_lenovo_init_hook(struct hda_codec *codec) | 14971 | static void alc861vd_lenovo_setup(struct hda_codec *codec) |
15049 | { | 14972 | { |
15050 | struct alc_spec *spec = codec->spec; | 14973 | struct alc_spec *spec = codec->spec; |
15051 | |||
15052 | spec->autocfg.hp_pins[0] = 0x1b; | 14974 | spec->autocfg.hp_pins[0] = 0x1b; |
15053 | spec->autocfg.speaker_pins[0] = 0x14; | 14975 | spec->autocfg.speaker_pins[0] = 0x14; |
14976 | } | ||
14977 | |||
14978 | static void alc861vd_lenovo_init_hook(struct hda_codec *codec) | ||
14979 | { | ||
15054 | alc_automute_amp(codec); | 14980 | alc_automute_amp(codec); |
15055 | alc861vd_lenovo_mic_automute(codec); | 14981 | alc861vd_lenovo_mic_automute(codec); |
15056 | } | 14982 | } |
@@ -15114,13 +15040,12 @@ static struct hda_verb alc861vd_dallas_verbs[] = { | |||
15114 | }; | 15040 | }; |
15115 | 15041 | ||
15116 | /* toggle speaker-output according to the hp-jack state */ | 15042 | /* toggle speaker-output according to the hp-jack state */ |
15117 | static void alc861vd_dallas_init_hook(struct hda_codec *codec) | 15043 | static void alc861vd_dallas_setup(struct hda_codec *codec) |
15118 | { | 15044 | { |
15119 | struct alc_spec *spec = codec->spec; | 15045 | struct alc_spec *spec = codec->spec; |
15120 | 15046 | ||
15121 | spec->autocfg.hp_pins[0] = 0x15; | 15047 | spec->autocfg.hp_pins[0] = 0x15; |
15122 | spec->autocfg.speaker_pins[0] = 0x14; | 15048 | spec->autocfg.speaker_pins[0] = 0x14; |
15123 | alc_automute_amp(codec); | ||
15124 | } | 15049 | } |
15125 | 15050 | ||
15126 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 15051 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -15234,6 +15159,7 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
15234 | .channel_mode = alc861vd_3stack_2ch_modes, | 15159 | .channel_mode = alc861vd_3stack_2ch_modes, |
15235 | .input_mux = &alc861vd_capture_source, | 15160 | .input_mux = &alc861vd_capture_source, |
15236 | .unsol_event = alc861vd_lenovo_unsol_event, | 15161 | .unsol_event = alc861vd_lenovo_unsol_event, |
15162 | .setup = alc861vd_lenovo_setup, | ||
15237 | .init_hook = alc861vd_lenovo_init_hook, | 15163 | .init_hook = alc861vd_lenovo_init_hook, |
15238 | }, | 15164 | }, |
15239 | [ALC861VD_DALLAS] = { | 15165 | [ALC861VD_DALLAS] = { |
@@ -15245,7 +15171,8 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
15245 | .channel_mode = alc861vd_3stack_2ch_modes, | 15171 | .channel_mode = alc861vd_3stack_2ch_modes, |
15246 | .input_mux = &alc861vd_dallas_capture_source, | 15172 | .input_mux = &alc861vd_dallas_capture_source, |
15247 | .unsol_event = alc_automute_amp_unsol_event, | 15173 | .unsol_event = alc_automute_amp_unsol_event, |
15248 | .init_hook = alc861vd_dallas_init_hook, | 15174 | .setup = alc861vd_dallas_setup, |
15175 | .init_hook = alc_automute_amp, | ||
15249 | }, | 15176 | }, |
15250 | [ALC861VD_HP] = { | 15177 | [ALC861VD_HP] = { |
15251 | .mixers = { alc861vd_hp_mixer }, | 15178 | .mixers = { alc861vd_hp_mixer }, |
@@ -15257,7 +15184,8 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
15257 | .channel_mode = alc861vd_3stack_2ch_modes, | 15184 | .channel_mode = alc861vd_3stack_2ch_modes, |
15258 | .input_mux = &alc861vd_hp_capture_source, | 15185 | .input_mux = &alc861vd_hp_capture_source, |
15259 | .unsol_event = alc_automute_amp_unsol_event, | 15186 | .unsol_event = alc_automute_amp_unsol_event, |
15260 | .init_hook = alc861vd_dallas_init_hook, | 15187 | .setup = alc861vd_dallas_setup, |
15188 | .init_hook = alc_automute_amp, | ||
15261 | }, | 15189 | }, |
15262 | [ALC660VD_ASUS_V1S] = { | 15190 | [ALC660VD_ASUS_V1S] = { |
15263 | .mixers = { alc861vd_lenovo_mixer }, | 15191 | .mixers = { alc861vd_lenovo_mixer }, |
@@ -15272,6 +15200,7 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
15272 | .channel_mode = alc861vd_3stack_2ch_modes, | 15200 | .channel_mode = alc861vd_3stack_2ch_modes, |
15273 | .input_mux = &alc861vd_capture_source, | 15201 | .input_mux = &alc861vd_capture_source, |
15274 | .unsol_event = alc861vd_lenovo_unsol_event, | 15202 | .unsol_event = alc861vd_lenovo_unsol_event, |
15203 | .setup = alc861vd_lenovo_setup, | ||
15275 | .init_hook = alc861vd_lenovo_init_hook, | 15204 | .init_hook = alc861vd_lenovo_init_hook, |
15276 | }, | 15205 | }, |
15277 | }; | 15206 | }; |
@@ -15540,8 +15469,8 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
15540 | alc861vd_cfg_tbl); | 15469 | alc861vd_cfg_tbl); |
15541 | 15470 | ||
15542 | if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { | 15471 | if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { |
15543 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 15472 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
15544 | "trying auto-probe from BIOS...\n", codec->chip_name); | 15473 | codec->chip_name); |
15545 | board_config = ALC861VD_AUTO; | 15474 | board_config = ALC861VD_AUTO; |
15546 | } | 15475 | } |
15547 | 15476 | ||
@@ -15566,7 +15495,7 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
15566 | } | 15495 | } |
15567 | 15496 | ||
15568 | if (board_config != ALC861VD_AUTO) | 15497 | if (board_config != ALC861VD_AUTO) |
15569 | setup_preset(spec, &alc861vd_presets[board_config]); | 15498 | setup_preset(codec, &alc861vd_presets[board_config]); |
15570 | 15499 | ||
15571 | if (codec->vendor_id == 0x10ec0660) { | 15500 | if (codec->vendor_id == 0x10ec0660) { |
15572 | /* always turn on EAPD */ | 15501 | /* always turn on EAPD */ |
@@ -15586,7 +15515,7 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
15586 | if (!spec->capsrc_nids) | 15515 | if (!spec->capsrc_nids) |
15587 | spec->capsrc_nids = alc861vd_capsrc_nids; | 15516 | spec->capsrc_nids = alc861vd_capsrc_nids; |
15588 | 15517 | ||
15589 | set_capture_mixer(spec); | 15518 | set_capture_mixer(codec); |
15590 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 15519 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
15591 | 15520 | ||
15592 | spec->vmaster_nid = 0x02; | 15521 | spec->vmaster_nid = 0x02; |
@@ -15627,9 +15556,9 @@ static hda_nid_t alc272_dac_nids[2] = { | |||
15627 | 0x02, 0x03 | 15556 | 0x02, 0x03 |
15628 | }; | 15557 | }; |
15629 | 15558 | ||
15630 | static hda_nid_t alc662_adc_nids[1] = { | 15559 | static hda_nid_t alc662_adc_nids[2] = { |
15631 | /* ADC1-2 */ | 15560 | /* ADC1-2 */ |
15632 | 0x09, | 15561 | 0x09, 0x08 |
15633 | }; | 15562 | }; |
15634 | 15563 | ||
15635 | static hda_nid_t alc272_adc_nids[1] = { | 15564 | static hda_nid_t alc272_adc_nids[1] = { |
@@ -15637,7 +15566,7 @@ static hda_nid_t alc272_adc_nids[1] = { | |||
15637 | 0x08, | 15566 | 0x08, |
15638 | }; | 15567 | }; |
15639 | 15568 | ||
15640 | static hda_nid_t alc662_capsrc_nids[1] = { 0x22 }; | 15569 | static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; |
15641 | static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; | 15570 | static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; |
15642 | 15571 | ||
15643 | 15572 | ||
@@ -15661,14 +15590,6 @@ static struct hda_input_mux alc662_lenovo_101e_capture_source = { | |||
15661 | }, | 15590 | }, |
15662 | }; | 15591 | }; |
15663 | 15592 | ||
15664 | static struct hda_input_mux alc662_eeepc_capture_source = { | ||
15665 | .num_items = 2, | ||
15666 | .items = { | ||
15667 | { "i-Mic", 0x1 }, | ||
15668 | { "e-Mic", 0x0 }, | ||
15669 | }, | ||
15670 | }; | ||
15671 | |||
15672 | static struct hda_input_mux alc663_capture_source = { | 15593 | static struct hda_input_mux alc663_capture_source = { |
15673 | .num_items = 3, | 15594 | .num_items = 3, |
15674 | .items = { | 15595 | .items = { |
@@ -15678,23 +15599,7 @@ static struct hda_input_mux alc663_capture_source = { | |||
15678 | }, | 15599 | }, |
15679 | }; | 15600 | }; |
15680 | 15601 | ||
15681 | static struct hda_input_mux alc663_m51va_capture_source = { | 15602 | #if 0 /* set to 1 for testing other input sources below */ |
15682 | .num_items = 2, | ||
15683 | .items = { | ||
15684 | { "Ext-Mic", 0x0 }, | ||
15685 | { "D-Mic", 0x9 }, | ||
15686 | }, | ||
15687 | }; | ||
15688 | |||
15689 | #if 1 /* set to 0 for testing other input sources below */ | ||
15690 | static struct hda_input_mux alc272_nc10_capture_source = { | ||
15691 | .num_items = 2, | ||
15692 | .items = { | ||
15693 | { "Autoselect Mic", 0x0 }, | ||
15694 | { "Internal Mic", 0x1 }, | ||
15695 | }, | ||
15696 | }; | ||
15697 | #else | ||
15698 | static struct hda_input_mux alc272_nc10_capture_source = { | 15603 | static struct hda_input_mux alc272_nc10_capture_source = { |
15699 | .num_items = 16, | 15604 | .num_items = 16, |
15700 | .items = { | 15605 | .items = { |
@@ -16363,47 +16268,44 @@ static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, | |||
16363 | alc662_lenovo_101e_ispeaker_automute(codec); | 16268 | alc662_lenovo_101e_ispeaker_automute(codec); |
16364 | } | 16269 | } |
16365 | 16270 | ||
16366 | static void alc662_eeepc_mic_automute(struct hda_codec *codec) | ||
16367 | { | ||
16368 | unsigned int present; | ||
16369 | |||
16370 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
16371 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
16372 | snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
16373 | 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); | ||
16374 | snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
16375 | 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); | ||
16376 | snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
16377 | 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); | ||
16378 | snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
16379 | 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); | ||
16380 | } | ||
16381 | |||
16382 | /* unsolicited event for HP jack sensing */ | 16271 | /* unsolicited event for HP jack sensing */ |
16383 | static void alc662_eeepc_unsol_event(struct hda_codec *codec, | 16272 | static void alc662_eeepc_unsol_event(struct hda_codec *codec, |
16384 | unsigned int res) | 16273 | unsigned int res) |
16385 | { | 16274 | { |
16386 | if ((res >> 26) == ALC880_MIC_EVENT) | 16275 | if ((res >> 26) == ALC880_MIC_EVENT) |
16387 | alc662_eeepc_mic_automute(codec); | 16276 | alc_mic_automute(codec); |
16388 | else | 16277 | else |
16389 | alc262_hippo_unsol_event(codec, res); | 16278 | alc262_hippo_unsol_event(codec, res); |
16390 | } | 16279 | } |
16391 | 16280 | ||
16281 | static void alc662_eeepc_setup(struct hda_codec *codec) | ||
16282 | { | ||
16283 | struct alc_spec *spec = codec->spec; | ||
16284 | |||
16285 | alc262_hippo1_setup(codec); | ||
16286 | spec->ext_mic.pin = 0x18; | ||
16287 | spec->ext_mic.mux_idx = 0; | ||
16288 | spec->int_mic.pin = 0x19; | ||
16289 | spec->int_mic.mux_idx = 1; | ||
16290 | spec->auto_mic = 1; | ||
16291 | } | ||
16292 | |||
16392 | static void alc662_eeepc_inithook(struct hda_codec *codec) | 16293 | static void alc662_eeepc_inithook(struct hda_codec *codec) |
16393 | { | 16294 | { |
16394 | alc262_hippo1_init_hook(codec); | 16295 | alc262_hippo_automute(codec); |
16395 | alc662_eeepc_mic_automute(codec); | 16296 | alc_mic_automute(codec); |
16396 | } | 16297 | } |
16397 | 16298 | ||
16398 | static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) | 16299 | static void alc662_eeepc_ep20_setup(struct hda_codec *codec) |
16399 | { | 16300 | { |
16400 | struct alc_spec *spec = codec->spec; | 16301 | struct alc_spec *spec = codec->spec; |
16401 | 16302 | ||
16402 | spec->autocfg.hp_pins[0] = 0x14; | 16303 | spec->autocfg.hp_pins[0] = 0x14; |
16403 | spec->autocfg.speaker_pins[0] = 0x1b; | 16304 | spec->autocfg.speaker_pins[0] = 0x1b; |
16404 | alc262_hippo_master_update(codec); | ||
16405 | } | 16305 | } |
16406 | 16306 | ||
16307 | #define alc662_eeepc_ep20_inithook alc262_hippo_master_update | ||
16308 | |||
16407 | static void alc663_m51va_speaker_automute(struct hda_codec *codec) | 16309 | static void alc663_m51va_speaker_automute(struct hda_codec *codec) |
16408 | { | 16310 | { |
16409 | unsigned int present; | 16311 | unsigned int present; |
@@ -16514,23 +16416,6 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) | |||
16514 | } | 16416 | } |
16515 | } | 16417 | } |
16516 | 16418 | ||
16517 | static void alc663_m51va_mic_automute(struct hda_codec *codec) | ||
16518 | { | ||
16519 | unsigned int present; | ||
16520 | |||
16521 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
16522 | AC_VERB_GET_PIN_SENSE, 0) | ||
16523 | & AC_PINSENSE_PRESENCE; | ||
16524 | snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
16525 | 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); | ||
16526 | snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
16527 | 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); | ||
16528 | snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
16529 | 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); | ||
16530 | snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
16531 | 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); | ||
16532 | } | ||
16533 | |||
16534 | static void alc663_m51va_unsol_event(struct hda_codec *codec, | 16419 | static void alc663_m51va_unsol_event(struct hda_codec *codec, |
16535 | unsigned int res) | 16420 | unsigned int res) |
16536 | { | 16421 | { |
@@ -16539,36 +16424,32 @@ static void alc663_m51va_unsol_event(struct hda_codec *codec, | |||
16539 | alc663_m51va_speaker_automute(codec); | 16424 | alc663_m51va_speaker_automute(codec); |
16540 | break; | 16425 | break; |
16541 | case ALC880_MIC_EVENT: | 16426 | case ALC880_MIC_EVENT: |
16542 | alc663_m51va_mic_automute(codec); | 16427 | alc_mic_automute(codec); |
16543 | break; | 16428 | break; |
16544 | } | 16429 | } |
16545 | } | 16430 | } |
16546 | 16431 | ||
16432 | static void alc663_m51va_setup(struct hda_codec *codec) | ||
16433 | { | ||
16434 | struct alc_spec *spec = codec->spec; | ||
16435 | spec->ext_mic.pin = 0x18; | ||
16436 | spec->ext_mic.mux_idx = 0; | ||
16437 | spec->int_mic.pin = 0x12; | ||
16438 | spec->int_mic.mux_idx = 1; | ||
16439 | spec->auto_mic = 1; | ||
16440 | } | ||
16441 | |||
16547 | static void alc663_m51va_inithook(struct hda_codec *codec) | 16442 | static void alc663_m51va_inithook(struct hda_codec *codec) |
16548 | { | 16443 | { |
16549 | alc663_m51va_speaker_automute(codec); | 16444 | alc663_m51va_speaker_automute(codec); |
16550 | alc663_m51va_mic_automute(codec); | 16445 | alc_mic_automute(codec); |
16551 | } | 16446 | } |
16552 | 16447 | ||
16553 | /* ***************** Mode1 ******************************/ | 16448 | /* ***************** Mode1 ******************************/ |
16554 | static void alc663_mode1_unsol_event(struct hda_codec *codec, | 16449 | #define alc663_mode1_unsol_event alc663_m51va_unsol_event |
16555 | unsigned int res) | 16450 | #define alc663_mode1_setup alc663_m51va_setup |
16556 | { | 16451 | #define alc663_mode1_inithook alc663_m51va_inithook |
16557 | switch (res >> 26) { | ||
16558 | case ALC880_HP_EVENT: | ||
16559 | alc663_m51va_speaker_automute(codec); | ||
16560 | break; | ||
16561 | case ALC880_MIC_EVENT: | ||
16562 | alc662_eeepc_mic_automute(codec); | ||
16563 | break; | ||
16564 | } | ||
16565 | } | ||
16566 | 16452 | ||
16567 | static void alc663_mode1_inithook(struct hda_codec *codec) | ||
16568 | { | ||
16569 | alc663_m51va_speaker_automute(codec); | ||
16570 | alc662_eeepc_mic_automute(codec); | ||
16571 | } | ||
16572 | /* ***************** Mode2 ******************************/ | 16453 | /* ***************** Mode2 ******************************/ |
16573 | static void alc662_mode2_unsol_event(struct hda_codec *codec, | 16454 | static void alc662_mode2_unsol_event(struct hda_codec *codec, |
16574 | unsigned int res) | 16455 | unsigned int res) |
@@ -16578,15 +16459,17 @@ static void alc662_mode2_unsol_event(struct hda_codec *codec, | |||
16578 | alc662_f5z_speaker_automute(codec); | 16459 | alc662_f5z_speaker_automute(codec); |
16579 | break; | 16460 | break; |
16580 | case ALC880_MIC_EVENT: | 16461 | case ALC880_MIC_EVENT: |
16581 | alc662_eeepc_mic_automute(codec); | 16462 | alc_mic_automute(codec); |
16582 | break; | 16463 | break; |
16583 | } | 16464 | } |
16584 | } | 16465 | } |
16585 | 16466 | ||
16467 | #define alc662_mode2_setup alc663_m51va_setup | ||
16468 | |||
16586 | static void alc662_mode2_inithook(struct hda_codec *codec) | 16469 | static void alc662_mode2_inithook(struct hda_codec *codec) |
16587 | { | 16470 | { |
16588 | alc662_f5z_speaker_automute(codec); | 16471 | alc662_f5z_speaker_automute(codec); |
16589 | alc662_eeepc_mic_automute(codec); | 16472 | alc_mic_automute(codec); |
16590 | } | 16473 | } |
16591 | /* ***************** Mode3 ******************************/ | 16474 | /* ***************** Mode3 ******************************/ |
16592 | static void alc663_mode3_unsol_event(struct hda_codec *codec, | 16475 | static void alc663_mode3_unsol_event(struct hda_codec *codec, |
@@ -16597,15 +16480,17 @@ static void alc663_mode3_unsol_event(struct hda_codec *codec, | |||
16597 | alc663_two_hp_m1_speaker_automute(codec); | 16480 | alc663_two_hp_m1_speaker_automute(codec); |
16598 | break; | 16481 | break; |
16599 | case ALC880_MIC_EVENT: | 16482 | case ALC880_MIC_EVENT: |
16600 | alc662_eeepc_mic_automute(codec); | 16483 | alc_mic_automute(codec); |
16601 | break; | 16484 | break; |
16602 | } | 16485 | } |
16603 | } | 16486 | } |
16604 | 16487 | ||
16488 | #define alc663_mode3_setup alc663_m51va_setup | ||
16489 | |||
16605 | static void alc663_mode3_inithook(struct hda_codec *codec) | 16490 | static void alc663_mode3_inithook(struct hda_codec *codec) |
16606 | { | 16491 | { |
16607 | alc663_two_hp_m1_speaker_automute(codec); | 16492 | alc663_two_hp_m1_speaker_automute(codec); |
16608 | alc662_eeepc_mic_automute(codec); | 16493 | alc_mic_automute(codec); |
16609 | } | 16494 | } |
16610 | /* ***************** Mode4 ******************************/ | 16495 | /* ***************** Mode4 ******************************/ |
16611 | static void alc663_mode4_unsol_event(struct hda_codec *codec, | 16496 | static void alc663_mode4_unsol_event(struct hda_codec *codec, |
@@ -16616,15 +16501,17 @@ static void alc663_mode4_unsol_event(struct hda_codec *codec, | |||
16616 | alc663_21jd_two_speaker_automute(codec); | 16501 | alc663_21jd_two_speaker_automute(codec); |
16617 | break; | 16502 | break; |
16618 | case ALC880_MIC_EVENT: | 16503 | case ALC880_MIC_EVENT: |
16619 | alc662_eeepc_mic_automute(codec); | 16504 | alc_mic_automute(codec); |
16620 | break; | 16505 | break; |
16621 | } | 16506 | } |
16622 | } | 16507 | } |
16623 | 16508 | ||
16509 | #define alc663_mode4_setup alc663_m51va_setup | ||
16510 | |||
16624 | static void alc663_mode4_inithook(struct hda_codec *codec) | 16511 | static void alc663_mode4_inithook(struct hda_codec *codec) |
16625 | { | 16512 | { |
16626 | alc663_21jd_two_speaker_automute(codec); | 16513 | alc663_21jd_two_speaker_automute(codec); |
16627 | alc662_eeepc_mic_automute(codec); | 16514 | alc_mic_automute(codec); |
16628 | } | 16515 | } |
16629 | /* ***************** Mode5 ******************************/ | 16516 | /* ***************** Mode5 ******************************/ |
16630 | static void alc663_mode5_unsol_event(struct hda_codec *codec, | 16517 | static void alc663_mode5_unsol_event(struct hda_codec *codec, |
@@ -16635,15 +16522,17 @@ static void alc663_mode5_unsol_event(struct hda_codec *codec, | |||
16635 | alc663_15jd_two_speaker_automute(codec); | 16522 | alc663_15jd_two_speaker_automute(codec); |
16636 | break; | 16523 | break; |
16637 | case ALC880_MIC_EVENT: | 16524 | case ALC880_MIC_EVENT: |
16638 | alc662_eeepc_mic_automute(codec); | 16525 | alc_mic_automute(codec); |
16639 | break; | 16526 | break; |
16640 | } | 16527 | } |
16641 | } | 16528 | } |
16642 | 16529 | ||
16530 | #define alc663_mode5_setup alc663_m51va_setup | ||
16531 | |||
16643 | static void alc663_mode5_inithook(struct hda_codec *codec) | 16532 | static void alc663_mode5_inithook(struct hda_codec *codec) |
16644 | { | 16533 | { |
16645 | alc663_15jd_two_speaker_automute(codec); | 16534 | alc663_15jd_two_speaker_automute(codec); |
16646 | alc662_eeepc_mic_automute(codec); | 16535 | alc_mic_automute(codec); |
16647 | } | 16536 | } |
16648 | /* ***************** Mode6 ******************************/ | 16537 | /* ***************** Mode6 ******************************/ |
16649 | static void alc663_mode6_unsol_event(struct hda_codec *codec, | 16538 | static void alc663_mode6_unsol_event(struct hda_codec *codec, |
@@ -16654,15 +16543,17 @@ static void alc663_mode6_unsol_event(struct hda_codec *codec, | |||
16654 | alc663_two_hp_m2_speaker_automute(codec); | 16543 | alc663_two_hp_m2_speaker_automute(codec); |
16655 | break; | 16544 | break; |
16656 | case ALC880_MIC_EVENT: | 16545 | case ALC880_MIC_EVENT: |
16657 | alc662_eeepc_mic_automute(codec); | 16546 | alc_mic_automute(codec); |
16658 | break; | 16547 | break; |
16659 | } | 16548 | } |
16660 | } | 16549 | } |
16661 | 16550 | ||
16551 | #define alc663_mode6_setup alc663_m51va_setup | ||
16552 | |||
16662 | static void alc663_mode6_inithook(struct hda_codec *codec) | 16553 | static void alc663_mode6_inithook(struct hda_codec *codec) |
16663 | { | 16554 | { |
16664 | alc663_two_hp_m2_speaker_automute(codec); | 16555 | alc663_two_hp_m2_speaker_automute(codec); |
16665 | alc662_eeepc_mic_automute(codec); | 16556 | alc_mic_automute(codec); |
16666 | } | 16557 | } |
16667 | 16558 | ||
16668 | static void alc663_g71v_hp_automute(struct hda_codec *codec) | 16559 | static void alc663_g71v_hp_automute(struct hda_codec *codec) |
@@ -16704,16 +16595,18 @@ static void alc663_g71v_unsol_event(struct hda_codec *codec, | |||
16704 | alc663_g71v_front_automute(codec); | 16595 | alc663_g71v_front_automute(codec); |
16705 | break; | 16596 | break; |
16706 | case ALC880_MIC_EVENT: | 16597 | case ALC880_MIC_EVENT: |
16707 | alc662_eeepc_mic_automute(codec); | 16598 | alc_mic_automute(codec); |
16708 | break; | 16599 | break; |
16709 | } | 16600 | } |
16710 | } | 16601 | } |
16711 | 16602 | ||
16603 | #define alc663_g71v_setup alc663_m51va_setup | ||
16604 | |||
16712 | static void alc663_g71v_inithook(struct hda_codec *codec) | 16605 | static void alc663_g71v_inithook(struct hda_codec *codec) |
16713 | { | 16606 | { |
16714 | alc663_g71v_front_automute(codec); | 16607 | alc663_g71v_front_automute(codec); |
16715 | alc663_g71v_hp_automute(codec); | 16608 | alc663_g71v_hp_automute(codec); |
16716 | alc662_eeepc_mic_automute(codec); | 16609 | alc_mic_automute(codec); |
16717 | } | 16610 | } |
16718 | 16611 | ||
16719 | static void alc663_g50v_unsol_event(struct hda_codec *codec, | 16612 | static void alc663_g50v_unsol_event(struct hda_codec *codec, |
@@ -16724,15 +16617,17 @@ static void alc663_g50v_unsol_event(struct hda_codec *codec, | |||
16724 | alc663_m51va_speaker_automute(codec); | 16617 | alc663_m51va_speaker_automute(codec); |
16725 | break; | 16618 | break; |
16726 | case ALC880_MIC_EVENT: | 16619 | case ALC880_MIC_EVENT: |
16727 | alc662_eeepc_mic_automute(codec); | 16620 | alc_mic_automute(codec); |
16728 | break; | 16621 | break; |
16729 | } | 16622 | } |
16730 | } | 16623 | } |
16731 | 16624 | ||
16625 | #define alc663_g50v_setup alc663_m51va_setup | ||
16626 | |||
16732 | static void alc663_g50v_inithook(struct hda_codec *codec) | 16627 | static void alc663_g50v_inithook(struct hda_codec *codec) |
16733 | { | 16628 | { |
16734 | alc663_m51va_speaker_automute(codec); | 16629 | alc663_m51va_speaker_automute(codec); |
16735 | alc662_eeepc_mic_automute(codec); | 16630 | alc_mic_automute(codec); |
16736 | } | 16631 | } |
16737 | 16632 | ||
16738 | static struct snd_kcontrol_new alc662_ecs_mixer[] = { | 16633 | static struct snd_kcontrol_new alc662_ecs_mixer[] = { |
@@ -16936,8 +16831,8 @@ static struct alc_config_preset alc662_presets[] = { | |||
16936 | .dac_nids = alc662_dac_nids, | 16831 | .dac_nids = alc662_dac_nids, |
16937 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 16832 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
16938 | .channel_mode = alc662_3ST_2ch_modes, | 16833 | .channel_mode = alc662_3ST_2ch_modes, |
16939 | .input_mux = &alc662_eeepc_capture_source, | ||
16940 | .unsol_event = alc662_eeepc_unsol_event, | 16834 | .unsol_event = alc662_eeepc_unsol_event, |
16835 | .setup = alc662_eeepc_setup, | ||
16941 | .init_hook = alc662_eeepc_inithook, | 16836 | .init_hook = alc662_eeepc_inithook, |
16942 | }, | 16837 | }, |
16943 | [ALC662_ASUS_EEEPC_EP20] = { | 16838 | [ALC662_ASUS_EEEPC_EP20] = { |
@@ -16951,6 +16846,7 @@ static struct alc_config_preset alc662_presets[] = { | |||
16951 | .channel_mode = alc662_3ST_6ch_modes, | 16846 | .channel_mode = alc662_3ST_6ch_modes, |
16952 | .input_mux = &alc662_lenovo_101e_capture_source, | 16847 | .input_mux = &alc662_lenovo_101e_capture_source, |
16953 | .unsol_event = alc662_eeepc_unsol_event, | 16848 | .unsol_event = alc662_eeepc_unsol_event, |
16849 | .setup = alc662_eeepc_ep20_setup, | ||
16954 | .init_hook = alc662_eeepc_ep20_inithook, | 16850 | .init_hook = alc662_eeepc_ep20_inithook, |
16955 | }, | 16851 | }, |
16956 | [ALC662_ECS] = { | 16852 | [ALC662_ECS] = { |
@@ -16961,8 +16857,8 @@ static struct alc_config_preset alc662_presets[] = { | |||
16961 | .dac_nids = alc662_dac_nids, | 16857 | .dac_nids = alc662_dac_nids, |
16962 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 16858 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
16963 | .channel_mode = alc662_3ST_2ch_modes, | 16859 | .channel_mode = alc662_3ST_2ch_modes, |
16964 | .input_mux = &alc662_eeepc_capture_source, | ||
16965 | .unsol_event = alc662_eeepc_unsol_event, | 16860 | .unsol_event = alc662_eeepc_unsol_event, |
16861 | .setup = alc662_eeepc_setup, | ||
16966 | .init_hook = alc662_eeepc_inithook, | 16862 | .init_hook = alc662_eeepc_inithook, |
16967 | }, | 16863 | }, |
16968 | [ALC663_ASUS_M51VA] = { | 16864 | [ALC663_ASUS_M51VA] = { |
@@ -16973,8 +16869,8 @@ static struct alc_config_preset alc662_presets[] = { | |||
16973 | .dig_out_nid = ALC662_DIGOUT_NID, | 16869 | .dig_out_nid = ALC662_DIGOUT_NID, |
16974 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 16870 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
16975 | .channel_mode = alc662_3ST_2ch_modes, | 16871 | .channel_mode = alc662_3ST_2ch_modes, |
16976 | .input_mux = &alc663_m51va_capture_source, | ||
16977 | .unsol_event = alc663_m51va_unsol_event, | 16872 | .unsol_event = alc663_m51va_unsol_event, |
16873 | .setup = alc663_m51va_setup, | ||
16978 | .init_hook = alc663_m51va_inithook, | 16874 | .init_hook = alc663_m51va_inithook, |
16979 | }, | 16875 | }, |
16980 | [ALC663_ASUS_G71V] = { | 16876 | [ALC663_ASUS_G71V] = { |
@@ -16985,8 +16881,8 @@ static struct alc_config_preset alc662_presets[] = { | |||
16985 | .dig_out_nid = ALC662_DIGOUT_NID, | 16881 | .dig_out_nid = ALC662_DIGOUT_NID, |
16986 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 16882 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
16987 | .channel_mode = alc662_3ST_2ch_modes, | 16883 | .channel_mode = alc662_3ST_2ch_modes, |
16988 | .input_mux = &alc662_eeepc_capture_source, | ||
16989 | .unsol_event = alc663_g71v_unsol_event, | 16884 | .unsol_event = alc663_g71v_unsol_event, |
16885 | .setup = alc663_g71v_setup, | ||
16990 | .init_hook = alc663_g71v_inithook, | 16886 | .init_hook = alc663_g71v_inithook, |
16991 | }, | 16887 | }, |
16992 | [ALC663_ASUS_H13] = { | 16888 | [ALC663_ASUS_H13] = { |
@@ -16996,7 +16892,6 @@ static struct alc_config_preset alc662_presets[] = { | |||
16996 | .dac_nids = alc662_dac_nids, | 16892 | .dac_nids = alc662_dac_nids, |
16997 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 16893 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
16998 | .channel_mode = alc662_3ST_2ch_modes, | 16894 | .channel_mode = alc662_3ST_2ch_modes, |
16999 | .input_mux = &alc663_m51va_capture_source, | ||
17000 | .unsol_event = alc663_m51va_unsol_event, | 16895 | .unsol_event = alc663_m51va_unsol_event, |
17001 | .init_hook = alc663_m51va_inithook, | 16896 | .init_hook = alc663_m51va_inithook, |
17002 | }, | 16897 | }, |
@@ -17010,6 +16905,7 @@ static struct alc_config_preset alc662_presets[] = { | |||
17010 | .channel_mode = alc662_3ST_6ch_modes, | 16905 | .channel_mode = alc662_3ST_6ch_modes, |
17011 | .input_mux = &alc663_capture_source, | 16906 | .input_mux = &alc663_capture_source, |
17012 | .unsol_event = alc663_g50v_unsol_event, | 16907 | .unsol_event = alc663_g50v_unsol_event, |
16908 | .setup = alc663_g50v_setup, | ||
17013 | .init_hook = alc663_g50v_inithook, | 16909 | .init_hook = alc663_g50v_inithook, |
17014 | }, | 16910 | }, |
17015 | [ALC663_ASUS_MODE1] = { | 16911 | [ALC663_ASUS_MODE1] = { |
@@ -17023,8 +16919,8 @@ static struct alc_config_preset alc662_presets[] = { | |||
17023 | .dig_out_nid = ALC662_DIGOUT_NID, | 16919 | .dig_out_nid = ALC662_DIGOUT_NID, |
17024 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 16920 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
17025 | .channel_mode = alc662_3ST_2ch_modes, | 16921 | .channel_mode = alc662_3ST_2ch_modes, |
17026 | .input_mux = &alc662_eeepc_capture_source, | ||
17027 | .unsol_event = alc663_mode1_unsol_event, | 16922 | .unsol_event = alc663_mode1_unsol_event, |
16923 | .setup = alc663_mode1_setup, | ||
17028 | .init_hook = alc663_mode1_inithook, | 16924 | .init_hook = alc663_mode1_inithook, |
17029 | }, | 16925 | }, |
17030 | [ALC662_ASUS_MODE2] = { | 16926 | [ALC662_ASUS_MODE2] = { |
@@ -17037,8 +16933,8 @@ static struct alc_config_preset alc662_presets[] = { | |||
17037 | .dig_out_nid = ALC662_DIGOUT_NID, | 16933 | .dig_out_nid = ALC662_DIGOUT_NID, |
17038 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 16934 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
17039 | .channel_mode = alc662_3ST_2ch_modes, | 16935 | .channel_mode = alc662_3ST_2ch_modes, |
17040 | .input_mux = &alc662_eeepc_capture_source, | ||
17041 | .unsol_event = alc662_mode2_unsol_event, | 16936 | .unsol_event = alc662_mode2_unsol_event, |
16937 | .setup = alc662_mode2_setup, | ||
17042 | .init_hook = alc662_mode2_inithook, | 16938 | .init_hook = alc662_mode2_inithook, |
17043 | }, | 16939 | }, |
17044 | [ALC663_ASUS_MODE3] = { | 16940 | [ALC663_ASUS_MODE3] = { |
@@ -17052,8 +16948,8 @@ static struct alc_config_preset alc662_presets[] = { | |||
17052 | .dig_out_nid = ALC662_DIGOUT_NID, | 16948 | .dig_out_nid = ALC662_DIGOUT_NID, |
17053 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 16949 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
17054 | .channel_mode = alc662_3ST_2ch_modes, | 16950 | .channel_mode = alc662_3ST_2ch_modes, |
17055 | .input_mux = &alc662_eeepc_capture_source, | ||
17056 | .unsol_event = alc663_mode3_unsol_event, | 16951 | .unsol_event = alc663_mode3_unsol_event, |
16952 | .setup = alc663_mode3_setup, | ||
17057 | .init_hook = alc663_mode3_inithook, | 16953 | .init_hook = alc663_mode3_inithook, |
17058 | }, | 16954 | }, |
17059 | [ALC663_ASUS_MODE4] = { | 16955 | [ALC663_ASUS_MODE4] = { |
@@ -17067,8 +16963,8 @@ static struct alc_config_preset alc662_presets[] = { | |||
17067 | .dig_out_nid = ALC662_DIGOUT_NID, | 16963 | .dig_out_nid = ALC662_DIGOUT_NID, |
17068 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 16964 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
17069 | .channel_mode = alc662_3ST_2ch_modes, | 16965 | .channel_mode = alc662_3ST_2ch_modes, |
17070 | .input_mux = &alc662_eeepc_capture_source, | ||
17071 | .unsol_event = alc663_mode4_unsol_event, | 16966 | .unsol_event = alc663_mode4_unsol_event, |
16967 | .setup = alc663_mode4_setup, | ||
17072 | .init_hook = alc663_mode4_inithook, | 16968 | .init_hook = alc663_mode4_inithook, |
17073 | }, | 16969 | }, |
17074 | [ALC663_ASUS_MODE5] = { | 16970 | [ALC663_ASUS_MODE5] = { |
@@ -17082,8 +16978,8 @@ static struct alc_config_preset alc662_presets[] = { | |||
17082 | .dig_out_nid = ALC662_DIGOUT_NID, | 16978 | .dig_out_nid = ALC662_DIGOUT_NID, |
17083 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 16979 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
17084 | .channel_mode = alc662_3ST_2ch_modes, | 16980 | .channel_mode = alc662_3ST_2ch_modes, |
17085 | .input_mux = &alc662_eeepc_capture_source, | ||
17086 | .unsol_event = alc663_mode5_unsol_event, | 16981 | .unsol_event = alc663_mode5_unsol_event, |
16982 | .setup = alc663_mode5_setup, | ||
17087 | .init_hook = alc663_mode5_inithook, | 16983 | .init_hook = alc663_mode5_inithook, |
17088 | }, | 16984 | }, |
17089 | [ALC663_ASUS_MODE6] = { | 16985 | [ALC663_ASUS_MODE6] = { |
@@ -17097,8 +16993,8 @@ static struct alc_config_preset alc662_presets[] = { | |||
17097 | .dig_out_nid = ALC662_DIGOUT_NID, | 16993 | .dig_out_nid = ALC662_DIGOUT_NID, |
17098 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 16994 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
17099 | .channel_mode = alc662_3ST_2ch_modes, | 16995 | .channel_mode = alc662_3ST_2ch_modes, |
17100 | .input_mux = &alc662_eeepc_capture_source, | ||
17101 | .unsol_event = alc663_mode6_unsol_event, | 16996 | .unsol_event = alc663_mode6_unsol_event, |
16997 | .setup = alc663_mode6_setup, | ||
17102 | .init_hook = alc663_mode6_inithook, | 16998 | .init_hook = alc663_mode6_inithook, |
17103 | }, | 16999 | }, |
17104 | [ALC272_DELL] = { | 17000 | [ALC272_DELL] = { |
@@ -17112,8 +17008,8 @@ static struct alc_config_preset alc662_presets[] = { | |||
17112 | .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), | 17008 | .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), |
17113 | .capsrc_nids = alc272_capsrc_nids, | 17009 | .capsrc_nids = alc272_capsrc_nids, |
17114 | .channel_mode = alc662_3ST_2ch_modes, | 17010 | .channel_mode = alc662_3ST_2ch_modes, |
17115 | .input_mux = &alc663_m51va_capture_source, | ||
17116 | .unsol_event = alc663_m51va_unsol_event, | 17011 | .unsol_event = alc663_m51va_unsol_event, |
17012 | .setup = alc663_m51va_setup, | ||
17117 | .init_hook = alc663_m51va_inithook, | 17013 | .init_hook = alc663_m51va_inithook, |
17118 | }, | 17014 | }, |
17119 | [ALC272_DELL_ZM1] = { | 17015 | [ALC272_DELL_ZM1] = { |
@@ -17124,11 +17020,11 @@ static struct alc_config_preset alc662_presets[] = { | |||
17124 | .dac_nids = alc662_dac_nids, | 17020 | .dac_nids = alc662_dac_nids, |
17125 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 17021 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
17126 | .adc_nids = alc662_adc_nids, | 17022 | .adc_nids = alc662_adc_nids, |
17127 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | 17023 | .num_adc_nids = 1, |
17128 | .capsrc_nids = alc662_capsrc_nids, | 17024 | .capsrc_nids = alc662_capsrc_nids, |
17129 | .channel_mode = alc662_3ST_2ch_modes, | 17025 | .channel_mode = alc662_3ST_2ch_modes, |
17130 | .input_mux = &alc663_m51va_capture_source, | ||
17131 | .unsol_event = alc663_m51va_unsol_event, | 17026 | .unsol_event = alc663_m51va_unsol_event, |
17027 | .setup = alc663_m51va_setup, | ||
17132 | .init_hook = alc663_m51va_inithook, | 17028 | .init_hook = alc663_m51va_inithook, |
17133 | }, | 17029 | }, |
17134 | [ALC272_SAMSUNG_NC10] = { | 17030 | [ALC272_SAMSUNG_NC10] = { |
@@ -17139,8 +17035,9 @@ static struct alc_config_preset alc662_presets[] = { | |||
17139 | .dac_nids = alc272_dac_nids, | 17035 | .dac_nids = alc272_dac_nids, |
17140 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 17036 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
17141 | .channel_mode = alc662_3ST_2ch_modes, | 17037 | .channel_mode = alc662_3ST_2ch_modes, |
17142 | .input_mux = &alc272_nc10_capture_source, | 17038 | /*.input_mux = &alc272_nc10_capture_source,*/ |
17143 | .unsol_event = alc663_mode4_unsol_event, | 17039 | .unsol_event = alc663_mode4_unsol_event, |
17040 | .setup = alc663_mode4_setup, | ||
17144 | .init_hook = alc663_mode4_inithook, | 17041 | .init_hook = alc663_mode4_inithook, |
17145 | }, | 17042 | }, |
17146 | }; | 17043 | }; |
@@ -17260,25 +17157,6 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
17260 | return 0; | 17157 | return 0; |
17261 | } | 17158 | } |
17262 | 17159 | ||
17263 | /* return the index of the src widget from the connection list of the nid. | ||
17264 | * return -1 if not found | ||
17265 | */ | ||
17266 | static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid, | ||
17267 | hda_nid_t src) | ||
17268 | { | ||
17269 | hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; | ||
17270 | int i, conns; | ||
17271 | |||
17272 | conns = snd_hda_get_connections(codec, nid, conn_list, | ||
17273 | ARRAY_SIZE(conn_list)); | ||
17274 | if (conns < 0) | ||
17275 | return -1; | ||
17276 | for (i = 0; i < conns; i++) | ||
17277 | if (conn_list[i] == src) | ||
17278 | return i; | ||
17279 | return -1; | ||
17280 | } | ||
17281 | |||
17282 | static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid) | 17160 | static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid) |
17283 | { | 17161 | { |
17284 | unsigned int pincap = snd_hda_query_pin_caps(codec, nid); | 17162 | unsigned int pincap = snd_hda_query_pin_caps(codec, nid); |
@@ -17295,7 +17173,7 @@ static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec, | |||
17295 | 17173 | ||
17296 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 17174 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
17297 | if (alc662_is_input_pin(codec, cfg->input_pins[i])) { | 17175 | if (alc662_is_input_pin(codec, cfg->input_pins[i])) { |
17298 | idx = alc662_input_pin_idx(codec, 0x0b, | 17176 | idx = get_connection_index(codec, 0x0b, |
17299 | cfg->input_pins[i]); | 17177 | cfg->input_pins[i]); |
17300 | if (idx >= 0) { | 17178 | if (idx >= 0) { |
17301 | err = new_analog_input(spec, cfg->input_pins[i], | 17179 | err = new_analog_input(spec, cfg->input_pins[i], |
@@ -17304,7 +17182,7 @@ static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec, | |||
17304 | if (err < 0) | 17182 | if (err < 0) |
17305 | return err; | 17183 | return err; |
17306 | } | 17184 | } |
17307 | idx = alc662_input_pin_idx(codec, 0x22, | 17185 | idx = get_connection_index(codec, 0x22, |
17308 | cfg->input_pins[i]); | 17186 | cfg->input_pins[i]); |
17309 | if (idx >= 0) { | 17187 | if (idx >= 0) { |
17310 | imux->items[imux->num_items].label = | 17188 | imux->items[imux->num_items].label = |
@@ -17467,8 +17345,8 @@ static int patch_alc662(struct hda_codec *codec) | |||
17467 | alc662_models, | 17345 | alc662_models, |
17468 | alc662_cfg_tbl); | 17346 | alc662_cfg_tbl); |
17469 | if (board_config < 0) { | 17347 | if (board_config < 0) { |
17470 | printk(KERN_INFO "hda_codec: Unknown model for %s, " | 17348 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
17471 | "trying auto-probe from BIOS...\n", codec->chip_name); | 17349 | codec->chip_name); |
17472 | board_config = ALC662_AUTO; | 17350 | board_config = ALC662_AUTO; |
17473 | } | 17351 | } |
17474 | 17352 | ||
@@ -17493,7 +17371,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
17493 | } | 17371 | } |
17494 | 17372 | ||
17495 | if (board_config != ALC662_AUTO) | 17373 | if (board_config != ALC662_AUTO) |
17496 | setup_preset(spec, &alc662_presets[board_config]); | 17374 | setup_preset(codec, &alc662_presets[board_config]); |
17497 | 17375 | ||
17498 | spec->stream_analog_playback = &alc662_pcm_analog_playback; | 17376 | spec->stream_analog_playback = &alc662_pcm_analog_playback; |
17499 | spec->stream_analog_capture = &alc662_pcm_analog_capture; | 17377 | spec->stream_analog_capture = &alc662_pcm_analog_capture; |
@@ -17509,7 +17387,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
17509 | spec->capsrc_nids = alc662_capsrc_nids; | 17387 | spec->capsrc_nids = alc662_capsrc_nids; |
17510 | 17388 | ||
17511 | if (!spec->cap_mixer) | 17389 | if (!spec->cap_mixer) |
17512 | set_capture_mixer(spec); | 17390 | set_capture_mixer(codec); |
17513 | if (codec->vendor_id == 0x10ec0662) | 17391 | if (codec->vendor_id == 0x10ec0662) |
17514 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 17392 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
17515 | else | 17393 | else |
@@ -17545,23 +17423,23 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
17545 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, | 17423 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, |
17546 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, | 17424 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, |
17547 | { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", | 17425 | { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", |
17548 | .patch = patch_alc883 }, | 17426 | .patch = patch_alc882 }, |
17549 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", | 17427 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", |
17550 | .patch = patch_alc662 }, | 17428 | .patch = patch_alc662 }, |
17551 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, | 17429 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, |
17552 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 17430 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
17553 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 17431 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
17554 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, | 17432 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, |
17555 | { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", | 17433 | { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", |
17556 | .patch = patch_alc882 }, /* should be patch_alc883() in future */ | 17434 | .patch = patch_alc882 }, |
17557 | { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", | 17435 | { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", |
17558 | .patch = patch_alc882 }, /* should be patch_alc883() in future */ | 17436 | .patch = patch_alc882 }, |
17559 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, | 17437 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, |
17560 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 }, | 17438 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, |
17561 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", | 17439 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", |
17562 | .patch = patch_alc883 }, | 17440 | .patch = patch_alc882 }, |
17563 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, | 17441 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, |
17564 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, | 17442 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, |
17565 | {} /* terminator */ | 17443 | {} /* terminator */ |
17566 | }; | 17444 | }; |
17567 | 17445 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6990cfcb6a3..742b9c8b25e 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 { |
@@ -177,6 +179,12 @@ struct sigmatel_jack { | |||
177 | struct snd_jack *jack; | 179 | struct snd_jack *jack; |
178 | }; | 180 | }; |
179 | 181 | ||
182 | struct sigmatel_mic_route { | ||
183 | hda_nid_t pin; | ||
184 | unsigned char mux_idx; | ||
185 | unsigned char dmux_idx; | ||
186 | }; | ||
187 | |||
180 | struct sigmatel_spec { | 188 | struct sigmatel_spec { |
181 | struct snd_kcontrol_new *mixers[4]; | 189 | struct snd_kcontrol_new *mixers[4]; |
182 | unsigned int num_mixers; | 190 | unsigned int num_mixers; |
@@ -188,6 +196,7 @@ struct sigmatel_spec { | |||
188 | unsigned int hp_detect: 1; | 196 | unsigned int hp_detect: 1; |
189 | unsigned int spdif_mute: 1; | 197 | unsigned int spdif_mute: 1; |
190 | unsigned int check_volume_offset:1; | 198 | unsigned int check_volume_offset:1; |
199 | unsigned int auto_mic:1; | ||
191 | 200 | ||
192 | /* gpio lines */ | 201 | /* gpio lines */ |
193 | unsigned int eapd_mask; | 202 | unsigned int eapd_mask; |
@@ -239,6 +248,15 @@ struct sigmatel_spec { | |||
239 | unsigned int num_dmuxes; | 248 | unsigned int num_dmuxes; |
240 | hda_nid_t *smux_nids; | 249 | hda_nid_t *smux_nids; |
241 | unsigned int num_smuxes; | 250 | unsigned int num_smuxes; |
251 | unsigned int num_analog_muxes; | ||
252 | |||
253 | unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */ | ||
254 | unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */ | ||
255 | unsigned int num_caps; /* number of capture volume/switch elements */ | ||
256 | |||
257 | struct sigmatel_mic_route ext_mic; | ||
258 | struct sigmatel_mic_route int_mic; | ||
259 | |||
242 | const char **spdif_labels; | 260 | const char **spdif_labels; |
243 | 261 | ||
244 | hda_nid_t dig_in_nid; | 262 | hda_nid_t dig_in_nid; |
@@ -335,14 +353,16 @@ static hda_nid_t stac92hd73xx_smux_nids[2] = { | |||
335 | 0x22, 0x23, | 353 | 0x22, 0x23, |
336 | }; | 354 | }; |
337 | 355 | ||
338 | #define STAC92HD83XXX_NUM_DMICS 2 | 356 | #define STAC92HD73XX_NUM_CAPS 2 |
339 | static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { | 357 | static unsigned long stac92hd73xx_capvols[] = { |
340 | 0x11, 0x12, 0 | 358 | HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT), |
359 | HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), | ||
341 | }; | 360 | }; |
361 | #define stac92hd73xx_capsws stac92hd73xx_capvols | ||
342 | 362 | ||
343 | #define STAC92HD83_DAC_COUNT 3 | 363 | #define STAC92HD83_DAC_COUNT 3 |
344 | 364 | ||
345 | static hda_nid_t stac92hd83xxx_dmux_nids[2] = { | 365 | static hda_nid_t stac92hd83xxx_mux_nids[2] = { |
346 | 0x17, 0x18, | 366 | 0x17, 0x18, |
347 | }; | 367 | }; |
348 | 368 | ||
@@ -362,9 +382,12 @@ static unsigned int stac92hd83xxx_pwr_mapping[4] = { | |||
362 | 0x03, 0x0c, 0x20, 0x40, | 382 | 0x03, 0x0c, 0x20, 0x40, |
363 | }; | 383 | }; |
364 | 384 | ||
365 | static hda_nid_t stac92hd83xxx_amp_nids[1] = { | 385 | #define STAC92HD83XXX_NUM_CAPS 2 |
366 | 0xc, | 386 | static unsigned long stac92hd83xxx_capvols[] = { |
387 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), | ||
388 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_OUTPUT), | ||
367 | }; | 389 | }; |
390 | #define stac92hd83xxx_capsws stac92hd83xxx_capvols | ||
368 | 391 | ||
369 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { | 392 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { |
370 | 0x0a, 0x0d, 0x0f | 393 | 0x0a, 0x0d, 0x0f |
@@ -395,6 +418,13 @@ static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { | |||
395 | 0x22, 0 | 418 | 0x22, 0 |
396 | }; | 419 | }; |
397 | 420 | ||
421 | #define STAC92HD71BXX_NUM_CAPS 2 | ||
422 | static unsigned long stac92hd71bxx_capvols[] = { | ||
423 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), | ||
424 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | ||
425 | }; | ||
426 | #define stac92hd71bxx_capsws stac92hd71bxx_capvols | ||
427 | |||
398 | static hda_nid_t stac925x_adc_nids[1] = { | 428 | static hda_nid_t stac925x_adc_nids[1] = { |
399 | 0x03, | 429 | 0x03, |
400 | }; | 430 | }; |
@@ -416,6 +446,13 @@ static hda_nid_t stac925x_dmux_nids[1] = { | |||
416 | 0x14, | 446 | 0x14, |
417 | }; | 447 | }; |
418 | 448 | ||
449 | static unsigned long stac925x_capvols[] = { | ||
450 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), | ||
451 | }; | ||
452 | static unsigned long stac925x_capsws[] = { | ||
453 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
454 | }; | ||
455 | |||
419 | static hda_nid_t stac922x_adc_nids[2] = { | 456 | static hda_nid_t stac922x_adc_nids[2] = { |
420 | 0x06, 0x07, | 457 | 0x06, 0x07, |
421 | }; | 458 | }; |
@@ -424,6 +461,13 @@ static hda_nid_t stac922x_mux_nids[2] = { | |||
424 | 0x12, 0x13, | 461 | 0x12, 0x13, |
425 | }; | 462 | }; |
426 | 463 | ||
464 | #define STAC922X_NUM_CAPS 2 | ||
465 | static unsigned long stac922x_capvols[] = { | ||
466 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT), | ||
467 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), | ||
468 | }; | ||
469 | #define stac922x_capsws stac922x_capvols | ||
470 | |||
427 | static hda_nid_t stac927x_slave_dig_outs[2] = { | 471 | static hda_nid_t stac927x_slave_dig_outs[2] = { |
428 | 0x1f, 0, | 472 | 0x1f, 0, |
429 | }; | 473 | }; |
@@ -453,6 +497,18 @@ static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { | |||
453 | 0x13, 0x14, 0 | 497 | 0x13, 0x14, 0 |
454 | }; | 498 | }; |
455 | 499 | ||
500 | #define STAC927X_NUM_CAPS 3 | ||
501 | static unsigned long stac927x_capvols[] = { | ||
502 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), | ||
503 | HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT), | ||
504 | HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT), | ||
505 | }; | ||
506 | static unsigned long stac927x_capsws[] = { | ||
507 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), | ||
508 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), | ||
509 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | ||
510 | }; | ||
511 | |||
456 | static const char *stac927x_spdif_labels[5] = { | 512 | static const char *stac927x_spdif_labels[5] = { |
457 | "Digital Playback", "ADAT", "Analog Mux 1", | 513 | "Digital Playback", "ADAT", "Analog Mux 1", |
458 | "Analog Mux 2", "Analog Mux 3" | 514 | "Analog Mux 2", "Analog Mux 3" |
@@ -479,6 +535,16 @@ static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { | |||
479 | 0x17, 0x18, 0 | 535 | 0x17, 0x18, 0 |
480 | }; | 536 | }; |
481 | 537 | ||
538 | #define STAC9205_NUM_CAPS 2 | ||
539 | static unsigned long stac9205_capvols[] = { | ||
540 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT), | ||
541 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT), | ||
542 | }; | ||
543 | static unsigned long stac9205_capsws[] = { | ||
544 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | ||
545 | HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT), | ||
546 | }; | ||
547 | |||
482 | static hda_nid_t stac9200_pin_nids[8] = { | 548 | static hda_nid_t stac9200_pin_nids[8] = { |
483 | 0x08, 0x09, 0x0d, 0x0e, | 549 | 0x08, 0x09, 0x0d, 0x0e, |
484 | 0x0f, 0x10, 0x11, 0x12, | 550 | 0x0f, 0x10, 0x11, 0x12, |
@@ -693,9 +759,35 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
693 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 759 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
694 | struct sigmatel_spec *spec = codec->spec; | 760 | struct sigmatel_spec *spec = codec->spec; |
695 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 761 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
696 | 762 | const struct hda_input_mux *imux = spec->input_mux; | |
697 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | 763 | unsigned int idx, prev_idx; |
698 | spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); | 764 | |
765 | idx = ucontrol->value.enumerated.item[0]; | ||
766 | if (idx >= imux->num_items) | ||
767 | idx = imux->num_items - 1; | ||
768 | prev_idx = spec->cur_mux[adc_idx]; | ||
769 | if (prev_idx == idx) | ||
770 | return 0; | ||
771 | if (idx < spec->num_analog_muxes) { | ||
772 | snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0, | ||
773 | AC_VERB_SET_CONNECT_SEL, | ||
774 | imux->items[idx].index); | ||
775 | if (prev_idx >= spec->num_analog_muxes) { | ||
776 | imux = spec->dinput_mux; | ||
777 | /* 0 = analog */ | ||
778 | snd_hda_codec_write_cache(codec, | ||
779 | spec->dmux_nids[adc_idx], 0, | ||
780 | AC_VERB_SET_CONNECT_SEL, | ||
781 | imux->items[0].index); | ||
782 | } | ||
783 | } else { | ||
784 | imux = spec->dinput_mux; | ||
785 | snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0, | ||
786 | AC_VERB_SET_CONNECT_SEL, | ||
787 | imux->items[idx - 1].index); | ||
788 | } | ||
789 | spec->cur_mux[adc_idx] = idx; | ||
790 | return 1; | ||
699 | } | 791 | } |
700 | 792 | ||
701 | static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol, | 793 | static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol, |
@@ -925,19 +1017,6 @@ static struct hda_verb stac92hd71bxx_core_init[] = { | |||
925 | {} | 1017 | {} |
926 | }; | 1018 | }; |
927 | 1019 | ||
928 | #define HD_DISABLE_PORTF 1 | ||
929 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { | ||
930 | /* start of config #1 */ | ||
931 | |||
932 | /* connect port 0f to audio mixer */ | ||
933 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | ||
934 | /* start of config #2 */ | ||
935 | |||
936 | /* set master volume and direct control */ | ||
937 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | ||
938 | {} | ||
939 | }; | ||
940 | |||
941 | static struct hda_verb stac92hd71bxx_unmute_core_init[] = { | 1020 | static struct hda_verb stac92hd71bxx_unmute_core_init[] = { |
942 | /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ | 1021 | /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ |
943 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 1022 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -1070,12 +1149,6 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { | |||
1070 | HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), | 1149 | HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), |
1071 | HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), | 1150 | HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), |
1072 | 1151 | ||
1073 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1074 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1075 | |||
1076 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1077 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1078 | |||
1079 | { } /* end */ | 1152 | { } /* end */ |
1080 | }; | 1153 | }; |
1081 | 1154 | ||
@@ -1095,12 +1168,6 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { | |||
1095 | }; | 1168 | }; |
1096 | 1169 | ||
1097 | static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { | 1170 | static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { |
1098 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1099 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1100 | |||
1101 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1102 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1103 | |||
1104 | HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), | 1171 | HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), |
1105 | HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), | 1172 | HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), |
1106 | 1173 | ||
@@ -1119,12 +1186,6 @@ static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { | |||
1119 | }; | 1186 | }; |
1120 | 1187 | ||
1121 | static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { | 1188 | static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { |
1122 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1123 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1124 | |||
1125 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1126 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1127 | |||
1128 | HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), | 1189 | HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), |
1129 | HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), | 1190 | HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), |
1130 | 1191 | ||
@@ -1143,85 +1204,13 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { | |||
1143 | }; | 1204 | }; |
1144 | 1205 | ||
1145 | 1206 | ||
1146 | static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | ||
1147 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT), | ||
1148 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT), | ||
1149 | |||
1150 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT), | ||
1151 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT), | ||
1152 | |||
1153 | HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT), | ||
1154 | HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT), | ||
1155 | |||
1156 | HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x4, HDA_INPUT), | ||
1157 | HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x4, HDA_INPUT), | ||
1158 | |||
1159 | HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x0, HDA_INPUT), | ||
1160 | HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x0, HDA_INPUT), | ||
1161 | |||
1162 | HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x2, HDA_INPUT), | ||
1163 | HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x2, HDA_INPUT), | ||
1164 | |||
1165 | /* | ||
1166 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x1, HDA_INPUT), | ||
1167 | HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x1, HDA_INPUT), | ||
1168 | */ | ||
1169 | { } /* end */ | ||
1170 | }; | ||
1171 | |||
1172 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | ||
1173 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | ||
1174 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | ||
1175 | |||
1176 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), | ||
1177 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), | ||
1178 | /* analog pc-beep replaced with digital beep support */ | ||
1179 | /* | ||
1180 | HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), | ||
1181 | HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), | ||
1182 | */ | ||
1183 | |||
1184 | HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT), | ||
1185 | HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT), | ||
1186 | |||
1187 | HDA_CODEC_MUTE("Import1 Mux Capture Switch", 0x17, 0x1, HDA_INPUT), | ||
1188 | HDA_CODEC_VOLUME("Import1 Mux Capture Volume", 0x17, 0x1, HDA_INPUT), | ||
1189 | |||
1190 | HDA_CODEC_MUTE("DAC0 Capture Switch", 0x17, 0x3, HDA_INPUT), | ||
1191 | HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x17, 0x3, HDA_INPUT), | ||
1192 | |||
1193 | HDA_CODEC_MUTE("DAC1 Capture Switch", 0x17, 0x4, HDA_INPUT), | ||
1194 | HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x17, 0x4, HDA_INPUT), | ||
1195 | { } /* end */ | ||
1196 | }; | ||
1197 | |||
1198 | static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { | 1207 | static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { |
1199 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) | 1208 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) |
1200 | }; | 1209 | }; |
1201 | 1210 | ||
1202 | static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | ||
1203 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | ||
1204 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | ||
1205 | |||
1206 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), | ||
1207 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), | ||
1208 | { } /* end */ | ||
1209 | }; | ||
1210 | |||
1211 | static struct snd_kcontrol_new stac925x_mixer[] = { | 1211 | static struct snd_kcontrol_new stac925x_mixer[] = { |
1212 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), | 1212 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), |
1213 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), | 1213 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), |
1214 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), | ||
1215 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), | ||
1216 | { } /* end */ | ||
1217 | }; | ||
1218 | |||
1219 | static struct snd_kcontrol_new stac9205_mixer[] = { | ||
1220 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), | ||
1221 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), | ||
1222 | |||
1223 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT), | ||
1224 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT), | ||
1225 | { } /* end */ | 1214 | { } /* end */ |
1226 | }; | 1215 | }; |
1227 | 1216 | ||
@@ -1230,29 +1219,6 @@ static struct snd_kcontrol_new stac9205_loopback[] = { | |||
1230 | {} | 1219 | {} |
1231 | }; | 1220 | }; |
1232 | 1221 | ||
1233 | /* This needs to be generated dynamically based on sequence */ | ||
1234 | static struct snd_kcontrol_new stac922x_mixer[] = { | ||
1235 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), | ||
1236 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), | ||
1237 | |||
1238 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT), | ||
1239 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT), | ||
1240 | { } /* end */ | ||
1241 | }; | ||
1242 | |||
1243 | |||
1244 | static struct snd_kcontrol_new stac927x_mixer[] = { | ||
1245 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), | ||
1246 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), | ||
1247 | |||
1248 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT), | ||
1249 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT), | ||
1250 | |||
1251 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT), | ||
1252 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT), | ||
1253 | { } /* end */ | ||
1254 | }; | ||
1255 | |||
1256 | static struct snd_kcontrol_new stac927x_loopback[] = { | 1222 | static struct snd_kcontrol_new stac927x_loopback[] = { |
1257 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), | 1223 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), |
1258 | {} | 1224 | {} |
@@ -1310,16 +1276,19 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1310 | int err; | 1276 | int err; |
1311 | int i; | 1277 | int i; |
1312 | 1278 | ||
1313 | err = snd_hda_add_new_ctls(codec, spec->mixer); | 1279 | if (spec->mixer) { |
1314 | if (err < 0) | 1280 | err = snd_hda_add_new_ctls(codec, spec->mixer); |
1315 | return err; | 1281 | if (err < 0) |
1282 | return err; | ||
1283 | } | ||
1316 | 1284 | ||
1317 | for (i = 0; i < spec->num_mixers; i++) { | 1285 | for (i = 0; i < spec->num_mixers; i++) { |
1318 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | 1286 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
1319 | if (err < 0) | 1287 | if (err < 0) |
1320 | return err; | 1288 | return err; |
1321 | } | 1289 | } |
1322 | if (spec->num_dmuxes > 0) { | 1290 | if (!spec->auto_mic && spec->num_dmuxes > 0 && |
1291 | snd_hda_get_bool_hint(codec, "separate_dmux") == 1) { | ||
1323 | stac_dmux_mixer.count = spec->num_dmuxes; | 1292 | stac_dmux_mixer.count = spec->num_dmuxes; |
1324 | err = snd_hda_ctl_add(codec, | 1293 | err = snd_hda_ctl_add(codec, |
1325 | snd_ctl_new1(&stac_dmux_mixer, codec)); | 1294 | snd_ctl_new1(&stac_dmux_mixer, codec)); |
@@ -1927,6 +1896,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |||
1927 | "HP mini 1000", STAC_HP_M4), | 1896 | "HP mini 1000", STAC_HP_M4), |
1928 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b, | 1897 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b, |
1929 | "HP HDX", STAC_HP_HDX), /* HDX16 */ | 1898 | "HP HDX", STAC_HP_HDX), /* HDX16 */ |
1899 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, | ||
1900 | "HP", STAC_HP_DV5), | ||
1930 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, | 1901 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, |
1931 | "unknown Dell", STAC_DELL_M4_1), | 1902 | "unknown Dell", STAC_DELL_M4_1), |
1932 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, | 1903 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, |
@@ -2642,8 +2613,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol, | |||
2642 | return 0; | 2613 | return 0; |
2643 | } | 2614 | } |
2644 | 2615 | ||
2645 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, | 2616 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid); |
2646 | unsigned char type); | ||
2647 | 2617 | ||
2648 | static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, | 2618 | static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, |
2649 | struct snd_ctl_elem_value *ucontrol) | 2619 | struct snd_ctl_elem_value *ucontrol) |
@@ -2657,7 +2627,7 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, | |||
2657 | /* check to be sure that the ports are upto date with | 2627 | /* check to be sure that the ports are upto date with |
2658 | * switch changes | 2628 | * switch changes |
2659 | */ | 2629 | */ |
2660 | stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); | 2630 | stac_issue_unsol_event(codec, nid); |
2661 | 2631 | ||
2662 | return 1; | 2632 | return 1; |
2663 | } | 2633 | } |
@@ -2790,7 +2760,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
2790 | * appropriately according to the pin direction | 2760 | * appropriately according to the pin direction |
2791 | */ | 2761 | */ |
2792 | if (spec->hp_detect) | 2762 | if (spec->hp_detect) |
2793 | stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); | 2763 | stac_issue_unsol_event(codec, nid); |
2794 | 2764 | ||
2795 | return 1; | 2765 | return 1; |
2796 | } | 2766 | } |
@@ -2973,6 +2943,8 @@ static int stac92xx_add_input_source(struct sigmatel_spec *spec) | |||
2973 | struct snd_kcontrol_new *knew; | 2943 | struct snd_kcontrol_new *knew; |
2974 | struct hda_input_mux *imux = &spec->private_imux; | 2944 | struct hda_input_mux *imux = &spec->private_imux; |
2975 | 2945 | ||
2946 | if (spec->auto_mic) | ||
2947 | return 0; /* no need for input source */ | ||
2976 | if (!spec->num_adcs || imux->num_items <= 1) | 2948 | if (!spec->num_adcs || imux->num_items <= 1) |
2977 | return 0; /* no need for input source control */ | 2949 | return 0; /* no need for input source control */ |
2978 | knew = stac_control_new(spec, &stac_input_src_temp, | 2950 | knew = stac_control_new(spec, &stac_input_src_temp, |
@@ -3066,7 +3038,7 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | |||
3066 | HDA_MAX_CONNECTIONS); | 3038 | HDA_MAX_CONNECTIONS); |
3067 | for (j = 0; j < conn_len; j++) { | 3039 | for (j = 0; j < conn_len; j++) { |
3068 | wcaps = get_wcaps(codec, conn[j]); | 3040 | wcaps = get_wcaps(codec, conn[j]); |
3069 | wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 3041 | wtype = get_wcaps_type(wcaps); |
3070 | /* we check only analog outputs */ | 3042 | /* we check only analog outputs */ |
3071 | if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) | 3043 | if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) |
3072 | continue; | 3044 | continue; |
@@ -3325,6 +3297,21 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, | |||
3325 | return 0; | 3297 | return 0; |
3326 | } | 3298 | } |
3327 | 3299 | ||
3300 | static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol, | ||
3301 | unsigned long sw, int idx) | ||
3302 | { | ||
3303 | int err; | ||
3304 | err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, | ||
3305 | "Capture Volume", vol); | ||
3306 | if (err < 0) | ||
3307 | return err; | ||
3308 | err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_MUTE, idx, | ||
3309 | "Capture Switch", sw); | ||
3310 | if (err < 0) | ||
3311 | return err; | ||
3312 | return 0; | ||
3313 | } | ||
3314 | |||
3328 | /* add playback controls from the parsed DAC table */ | 3315 | /* add playback controls from the parsed DAC table */ |
3329 | static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | 3316 | static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, |
3330 | const struct auto_pin_cfg *cfg) | 3317 | const struct auto_pin_cfg *cfg) |
@@ -3398,7 +3385,7 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec) | |||
3398 | spec->mono_nid, | 3385 | spec->mono_nid, |
3399 | con_lst, | 3386 | con_lst, |
3400 | HDA_MAX_NUM_INPUTS); | 3387 | HDA_MAX_NUM_INPUTS); |
3401 | if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) | 3388 | if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) |
3402 | return -EINVAL; | 3389 | return -EINVAL; |
3403 | 3390 | ||
3404 | for (i = 0; i < num_cons; i++) { | 3391 | for (i = 0; i < num_cons; i++) { |
@@ -3511,19 +3498,33 @@ static int stac92xx_beep_switch_ctl(struct hda_codec *codec) | |||
3511 | static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) | 3498 | static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) |
3512 | { | 3499 | { |
3513 | struct sigmatel_spec *spec = codec->spec; | 3500 | struct sigmatel_spec *spec = codec->spec; |
3514 | int wcaps, nid, i, err = 0; | 3501 | int i, j, err = 0; |
3515 | 3502 | ||
3516 | for (i = 0; i < spec->num_muxes; i++) { | 3503 | for (i = 0; i < spec->num_muxes; i++) { |
3504 | hda_nid_t nid; | ||
3505 | unsigned int wcaps; | ||
3506 | unsigned long val; | ||
3507 | |||
3517 | nid = spec->mux_nids[i]; | 3508 | nid = spec->mux_nids[i]; |
3518 | wcaps = get_wcaps(codec, nid); | 3509 | wcaps = get_wcaps(codec, nid); |
3510 | if (!(wcaps & AC_WCAP_OUT_AMP)) | ||
3511 | continue; | ||
3519 | 3512 | ||
3520 | if (wcaps & AC_WCAP_OUT_AMP) { | 3513 | /* check whether already the same control was created as |
3521 | err = stac92xx_add_control_idx(spec, | 3514 | * normal Capture Volume. |
3522 | STAC_CTL_WIDGET_VOL, i, "Mux Capture Volume", | 3515 | */ |
3523 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | 3516 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); |
3524 | if (err < 0) | 3517 | for (j = 0; j < spec->num_caps; j++) { |
3525 | return err; | 3518 | if (spec->capvols[j] == val) |
3519 | break; | ||
3526 | } | 3520 | } |
3521 | if (j < spec->num_caps) | ||
3522 | continue; | ||
3523 | |||
3524 | err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, i, | ||
3525 | "Mux Capture Volume", val); | ||
3526 | if (err < 0) | ||
3527 | return err; | ||
3527 | } | 3528 | } |
3528 | return 0; | 3529 | return 0; |
3529 | }; | 3530 | }; |
@@ -3544,7 +3545,7 @@ static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec) | |||
3544 | spec->smux_nids[0], | 3545 | spec->smux_nids[0], |
3545 | con_lst, | 3546 | con_lst, |
3546 | HDA_MAX_NUM_INPUTS); | 3547 | HDA_MAX_NUM_INPUTS); |
3547 | if (!num_cons) | 3548 | if (num_cons <= 0) |
3548 | return -EINVAL; | 3549 | return -EINVAL; |
3549 | 3550 | ||
3550 | if (!labels) | 3551 | if (!labels) |
@@ -3565,101 +3566,215 @@ static const char *stac92xx_dmic_labels[5] = { | |||
3565 | "Digital Mic 3", "Digital Mic 4" | 3566 | "Digital Mic 3", "Digital Mic 4" |
3566 | }; | 3567 | }; |
3567 | 3568 | ||
3569 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | ||
3570 | hda_nid_t nid) | ||
3571 | { | ||
3572 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
3573 | int i, nums; | ||
3574 | |||
3575 | nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); | ||
3576 | for (i = 0; i < nums; i++) | ||
3577 | if (conn[i] == nid) | ||
3578 | return i; | ||
3579 | return -1; | ||
3580 | } | ||
3581 | |||
3582 | /* create a volume assigned to the given pin (only if supported) */ | ||
3583 | static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid, | ||
3584 | const char *label) | ||
3585 | { | ||
3586 | unsigned int caps, nums; | ||
3587 | char name[32]; | ||
3588 | |||
3589 | if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) | ||
3590 | return 0; | ||
3591 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); | ||
3592 | nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | ||
3593 | if (!nums) | ||
3594 | return 0; | ||
3595 | snprintf(name, sizeof(name), "%s Capture Volume", label); | ||
3596 | return stac92xx_add_control(codec->spec, STAC_CTL_WIDGET_VOL, name, | ||
3597 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | ||
3598 | } | ||
3599 | |||
3568 | /* create playback/capture controls for input pins on dmic capable codecs */ | 3600 | /* create playback/capture controls for input pins on dmic capable codecs */ |
3569 | static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | 3601 | static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, |
3570 | const struct auto_pin_cfg *cfg) | 3602 | const struct auto_pin_cfg *cfg) |
3571 | { | 3603 | { |
3572 | struct sigmatel_spec *spec = codec->spec; | 3604 | struct sigmatel_spec *spec = codec->spec; |
3605 | struct hda_input_mux *imux = &spec->private_imux; | ||
3573 | struct hda_input_mux *dimux = &spec->private_dimux; | 3606 | struct hda_input_mux *dimux = &spec->private_dimux; |
3574 | hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; | 3607 | int err, i, active_mics; |
3575 | int err, i, j; | 3608 | unsigned int def_conf; |
3576 | char name[32]; | ||
3577 | 3609 | ||
3578 | dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; | 3610 | dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; |
3579 | dimux->items[dimux->num_items].index = 0; | 3611 | dimux->items[dimux->num_items].index = 0; |
3580 | dimux->num_items++; | 3612 | dimux->num_items++; |
3581 | 3613 | ||
3614 | active_mics = 0; | ||
3615 | for (i = 0; i < spec->num_dmics; i++) { | ||
3616 | /* check the validity: sometimes it's a dead vendor-spec node */ | ||
3617 | if (get_wcaps_type(get_wcaps(codec, spec->dmic_nids[i])) | ||
3618 | != AC_WID_PIN) | ||
3619 | continue; | ||
3620 | def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); | ||
3621 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) | ||
3622 | active_mics++; | ||
3623 | } | ||
3624 | |||
3582 | for (i = 0; i < spec->num_dmics; i++) { | 3625 | for (i = 0; i < spec->num_dmics; i++) { |
3583 | hda_nid_t nid; | 3626 | hda_nid_t nid; |
3584 | int index; | 3627 | int index; |
3585 | int num_cons; | 3628 | const char *label; |
3586 | unsigned int wcaps; | ||
3587 | unsigned int def_conf; | ||
3588 | 3629 | ||
3589 | def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); | 3630 | nid = spec->dmic_nids[i]; |
3631 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) | ||
3632 | continue; | ||
3633 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
3590 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | 3634 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) |
3591 | continue; | 3635 | continue; |
3592 | 3636 | ||
3593 | nid = spec->dmic_nids[i]; | 3637 | index = get_connection_index(codec, spec->dmux_nids[0], nid); |
3594 | num_cons = snd_hda_get_connections(codec, | 3638 | if (index < 0) |
3595 | spec->dmux_nids[0], | 3639 | continue; |
3596 | con_lst, | ||
3597 | HDA_MAX_NUM_INPUTS); | ||
3598 | for (j = 0; j < num_cons; j++) | ||
3599 | if (con_lst[j] == nid) { | ||
3600 | index = j; | ||
3601 | goto found; | ||
3602 | } | ||
3603 | continue; | ||
3604 | found: | ||
3605 | wcaps = get_wcaps(codec, nid) & | ||
3606 | (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); | ||
3607 | 3640 | ||
3608 | if (wcaps) { | 3641 | if (active_mics == 1) |
3609 | sprintf(name, "%s Capture Volume", | 3642 | label = "Digital Mic"; |
3610 | stac92xx_dmic_labels[dimux->num_items]); | 3643 | else |
3644 | label = stac92xx_dmic_labels[dimux->num_items]; | ||
3611 | 3645 | ||
3612 | err = stac92xx_add_control(spec, | 3646 | err = create_elem_capture_vol(codec, nid, label); |
3613 | STAC_CTL_WIDGET_VOL, | 3647 | if (err < 0) |
3614 | name, | 3648 | return err; |
3615 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | ||
3616 | (wcaps & AC_WCAP_OUT_AMP) ? | ||
3617 | HDA_OUTPUT : HDA_INPUT)); | ||
3618 | if (err < 0) | ||
3619 | return err; | ||
3620 | } | ||
3621 | 3649 | ||
3622 | dimux->items[dimux->num_items].label = | 3650 | dimux->items[dimux->num_items].label = label; |
3623 | stac92xx_dmic_labels[dimux->num_items]; | ||
3624 | dimux->items[dimux->num_items].index = index; | 3651 | dimux->items[dimux->num_items].index = index; |
3625 | dimux->num_items++; | 3652 | dimux->num_items++; |
3653 | if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) { | ||
3654 | imux->items[imux->num_items].label = label; | ||
3655 | imux->items[imux->num_items].index = index; | ||
3656 | imux->num_items++; | ||
3657 | } | ||
3626 | } | 3658 | } |
3627 | 3659 | ||
3628 | return 0; | 3660 | return 0; |
3629 | } | 3661 | } |
3630 | 3662 | ||
3663 | static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, | ||
3664 | hda_nid_t *fixed, hda_nid_t *ext) | ||
3665 | { | ||
3666 | unsigned int cfg; | ||
3667 | |||
3668 | if (!nid) | ||
3669 | return 0; | ||
3670 | cfg = snd_hda_codec_get_pincfg(codec, nid); | ||
3671 | switch (get_defcfg_connect(cfg)) { | ||
3672 | case AC_JACK_PORT_FIXED: | ||
3673 | if (*fixed) | ||
3674 | return 1; /* already occupied */ | ||
3675 | *fixed = nid; | ||
3676 | break; | ||
3677 | case AC_JACK_PORT_COMPLEX: | ||
3678 | if (*ext) | ||
3679 | return 1; /* already occupied */ | ||
3680 | *ext = nid; | ||
3681 | break; | ||
3682 | } | ||
3683 | return 0; | ||
3684 | } | ||
3685 | |||
3686 | static int set_mic_route(struct hda_codec *codec, | ||
3687 | struct sigmatel_mic_route *mic, | ||
3688 | hda_nid_t pin) | ||
3689 | { | ||
3690 | struct sigmatel_spec *spec = codec->spec; | ||
3691 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3692 | int i; | ||
3693 | |||
3694 | mic->pin = pin; | ||
3695 | for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) | ||
3696 | if (pin == cfg->input_pins[i]) | ||
3697 | break; | ||
3698 | if (i <= AUTO_PIN_FRONT_MIC) { | ||
3699 | /* analog pin */ | ||
3700 | mic->dmux_idx = 0; | ||
3701 | i = get_connection_index(codec, spec->mux_nids[0], pin); | ||
3702 | if (i < 0) | ||
3703 | return -1; | ||
3704 | mic->mux_idx = i; | ||
3705 | } else if (spec->dmux_nids) { | ||
3706 | /* digital pin */ | ||
3707 | mic->mux_idx = 0; | ||
3708 | i = get_connection_index(codec, spec->dmux_nids[0], pin); | ||
3709 | if (i < 0) | ||
3710 | return -1; | ||
3711 | mic->dmux_idx = i; | ||
3712 | } | ||
3713 | return 0; | ||
3714 | } | ||
3715 | |||
3716 | /* return non-zero if the device is for automatic mic switch */ | ||
3717 | static int stac_check_auto_mic(struct hda_codec *codec) | ||
3718 | { | ||
3719 | struct sigmatel_spec *spec = codec->spec; | ||
3720 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3721 | hda_nid_t fixed, ext; | ||
3722 | int i; | ||
3723 | |||
3724 | for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) { | ||
3725 | if (cfg->input_pins[i]) | ||
3726 | return 0; /* must be exclusively mics */ | ||
3727 | } | ||
3728 | fixed = ext = 0; | ||
3729 | for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) | ||
3730 | if (check_mic_pin(codec, cfg->input_pins[i], &fixed, &ext)) | ||
3731 | return 0; | ||
3732 | for (i = 0; i < spec->num_dmics; i++) | ||
3733 | if (check_mic_pin(codec, spec->dmic_nids[i], &fixed, &ext)) | ||
3734 | return 0; | ||
3735 | if (!fixed || !ext) | ||
3736 | return 0; | ||
3737 | if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) | ||
3738 | return 0; /* no unsol support */ | ||
3739 | if (set_mic_route(codec, &spec->ext_mic, ext) || | ||
3740 | set_mic_route(codec, &spec->int_mic, fixed)) | ||
3741 | return 0; /* something is wrong */ | ||
3742 | return 1; | ||
3743 | } | ||
3744 | |||
3631 | /* create playback/capture controls for input pins */ | 3745 | /* create playback/capture controls for input pins */ |
3632 | static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) | 3746 | static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) |
3633 | { | 3747 | { |
3634 | struct sigmatel_spec *spec = codec->spec; | 3748 | struct sigmatel_spec *spec = codec->spec; |
3635 | struct hda_input_mux *imux = &spec->private_imux; | 3749 | struct hda_input_mux *imux = &spec->private_imux; |
3636 | hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; | 3750 | int i, j; |
3637 | int i, j, k; | ||
3638 | 3751 | ||
3639 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 3752 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
3640 | int index; | 3753 | hda_nid_t nid = cfg->input_pins[i]; |
3754 | int index, err; | ||
3641 | 3755 | ||
3642 | if (!cfg->input_pins[i]) | 3756 | if (!nid) |
3643 | continue; | 3757 | continue; |
3644 | index = -1; | 3758 | index = -1; |
3645 | for (j = 0; j < spec->num_muxes; j++) { | 3759 | for (j = 0; j < spec->num_muxes; j++) { |
3646 | int num_cons; | 3760 | index = get_connection_index(codec, spec->mux_nids[j], |
3647 | num_cons = snd_hda_get_connections(codec, | 3761 | nid); |
3648 | spec->mux_nids[j], | 3762 | if (index >= 0) |
3649 | con_lst, | 3763 | break; |
3650 | HDA_MAX_NUM_INPUTS); | ||
3651 | for (k = 0; k < num_cons; k++) | ||
3652 | if (con_lst[k] == cfg->input_pins[i]) { | ||
3653 | index = k; | ||
3654 | goto found; | ||
3655 | } | ||
3656 | } | 3764 | } |
3657 | continue; | 3765 | if (index < 0) |
3658 | found: | 3766 | continue; |
3767 | |||
3768 | err = create_elem_capture_vol(codec, nid, | ||
3769 | auto_pin_cfg_labels[i]); | ||
3770 | if (err < 0) | ||
3771 | return err; | ||
3772 | |||
3659 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 3773 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; |
3660 | imux->items[imux->num_items].index = index; | 3774 | imux->items[imux->num_items].index = index; |
3661 | imux->num_items++; | 3775 | imux->num_items++; |
3662 | } | 3776 | } |
3777 | spec->num_analog_muxes = imux->num_items; | ||
3663 | 3778 | ||
3664 | if (imux->num_items) { | 3779 | if (imux->num_items) { |
3665 | /* | 3780 | /* |
@@ -3711,7 +3826,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3711 | { | 3826 | { |
3712 | struct sigmatel_spec *spec = codec->spec; | 3827 | struct sigmatel_spec *spec = codec->spec; |
3713 | int hp_swap = 0; | 3828 | int hp_swap = 0; |
3714 | int err; | 3829 | int i, err; |
3715 | 3830 | ||
3716 | if ((err = snd_hda_parse_pin_def_config(codec, | 3831 | if ((err = snd_hda_parse_pin_def_config(codec, |
3717 | &spec->autocfg, | 3832 | &spec->autocfg, |
@@ -3751,11 +3866,10 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3751 | if (snd_hda_get_connections(codec, | 3866 | if (snd_hda_get_connections(codec, |
3752 | spec->autocfg.mono_out_pin, conn_list, 1) && | 3867 | spec->autocfg.mono_out_pin, conn_list, 1) && |
3753 | snd_hda_get_connections(codec, conn_list[0], | 3868 | snd_hda_get_connections(codec, conn_list[0], |
3754 | conn_list, 1)) { | 3869 | conn_list, 1) > 0) { |
3755 | 3870 | ||
3756 | int wcaps = get_wcaps(codec, conn_list[0]); | 3871 | int wcaps = get_wcaps(codec, conn_list[0]); |
3757 | int wid_type = (wcaps & AC_WCAP_TYPE) | 3872 | int wid_type = get_wcaps_type(wcaps); |
3758 | >> AC_WCAP_TYPE_SHIFT; | ||
3759 | /* LR swap check, some stac925x have a mux that | 3873 | /* LR swap check, some stac925x have a mux that |
3760 | * changes the DACs output path instead of the | 3874 | * changes the DACs output path instead of the |
3761 | * mono-mux path. | 3875 | * mono-mux path. |
@@ -3846,6 +3960,21 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3846 | spec->autocfg.line_outs = 0; | 3960 | spec->autocfg.line_outs = 0; |
3847 | } | 3961 | } |
3848 | 3962 | ||
3963 | if (stac_check_auto_mic(codec)) { | ||
3964 | spec->auto_mic = 1; | ||
3965 | /* only one capture for auto-mic */ | ||
3966 | spec->num_adcs = 1; | ||
3967 | spec->num_caps = 1; | ||
3968 | spec->num_muxes = 1; | ||
3969 | } | ||
3970 | |||
3971 | for (i = 0; i < spec->num_caps; i++) { | ||
3972 | err = stac92xx_add_capvol_ctls(codec, spec->capvols[i], | ||
3973 | spec->capsws[i], i); | ||
3974 | if (err < 0) | ||
3975 | return err; | ||
3976 | } | ||
3977 | |||
3849 | err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); | 3978 | err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); |
3850 | if (err < 0) | 3979 | if (err < 0) |
3851 | return err; | 3980 | return err; |
@@ -4108,14 +4237,14 @@ static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, | |||
4108 | } | 4237 | } |
4109 | 4238 | ||
4110 | static struct sigmatel_event *stac_get_event(struct hda_codec *codec, | 4239 | static struct sigmatel_event *stac_get_event(struct hda_codec *codec, |
4111 | hda_nid_t nid, unsigned char type) | 4240 | hda_nid_t nid) |
4112 | { | 4241 | { |
4113 | struct sigmatel_spec *spec = codec->spec; | 4242 | struct sigmatel_spec *spec = codec->spec; |
4114 | struct sigmatel_event *event = spec->events.list; | 4243 | struct sigmatel_event *event = spec->events.list; |
4115 | int i; | 4244 | int i; |
4116 | 4245 | ||
4117 | for (i = 0; i < spec->events.used; i++, event++) { | 4246 | for (i = 0; i < spec->events.used; i++, event++) { |
4118 | if (event->nid == nid && event->type == type) | 4247 | if (event->nid == nid) |
4119 | return event; | 4248 | return event; |
4120 | } | 4249 | } |
4121 | return NULL; | 4250 | return NULL; |
@@ -4135,24 +4264,32 @@ static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec, | |||
4135 | return NULL; | 4264 | return NULL; |
4136 | } | 4265 | } |
4137 | 4266 | ||
4138 | static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, | 4267 | /* check if given nid is a valid pin and no other events are assigned |
4139 | unsigned int type) | 4268 | * to it. If OK, assign the event, set the unsol flag, and returns 1. |
4269 | * Otherwise, returns zero. | ||
4270 | */ | ||
4271 | static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, | ||
4272 | unsigned int type) | ||
4140 | { | 4273 | { |
4141 | struct sigmatel_event *event; | 4274 | struct sigmatel_event *event; |
4142 | int tag; | 4275 | int tag; |
4143 | 4276 | ||
4144 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) | 4277 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) |
4145 | return; | 4278 | return 0; |
4146 | event = stac_get_event(codec, nid, type); | 4279 | event = stac_get_event(codec, nid); |
4147 | if (event) | 4280 | if (event) { |
4281 | if (event->type != type) | ||
4282 | return 0; | ||
4148 | tag = event->tag; | 4283 | tag = event->tag; |
4149 | else | 4284 | } else { |
4150 | tag = stac_add_event(codec->spec, nid, type, 0); | 4285 | tag = stac_add_event(codec->spec, nid, type, 0); |
4151 | if (tag < 0) | 4286 | if (tag < 0) |
4152 | return; | 4287 | return 0; |
4288 | } | ||
4153 | snd_hda_codec_write_cache(codec, nid, 0, | 4289 | snd_hda_codec_write_cache(codec, nid, 0, |
4154 | AC_VERB_SET_UNSOLICITED_ENABLE, | 4290 | AC_VERB_SET_UNSOLICITED_ENABLE, |
4155 | AC_USRSP_EN | tag); | 4291 | AC_USRSP_EN | tag); |
4292 | return 1; | ||
4156 | } | 4293 | } |
4157 | 4294 | ||
4158 | static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) | 4295 | static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) |
@@ -4245,20 +4382,36 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4245 | hda_nid_t nid = cfg->hp_pins[i]; | 4382 | hda_nid_t nid = cfg->hp_pins[i]; |
4246 | enable_pin_detect(codec, nid, STAC_HP_EVENT); | 4383 | enable_pin_detect(codec, nid, STAC_HP_EVENT); |
4247 | } | 4384 | } |
4385 | if (cfg->line_out_type == AUTO_PIN_LINE_OUT && | ||
4386 | cfg->speaker_outs > 0) { | ||
4387 | /* enable pin-detect for line-outs as well */ | ||
4388 | for (i = 0; i < cfg->line_outs; i++) { | ||
4389 | hda_nid_t nid = cfg->line_out_pins[i]; | ||
4390 | enable_pin_detect(codec, nid, STAC_LO_EVENT); | ||
4391 | } | ||
4392 | } | ||
4393 | |||
4248 | /* force to enable the first line-out; the others are set up | 4394 | /* force to enable the first line-out; the others are set up |
4249 | * in unsol_event | 4395 | * in unsol_event |
4250 | */ | 4396 | */ |
4251 | stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], | 4397 | stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], |
4252 | AC_PINCTL_OUT_EN); | 4398 | AC_PINCTL_OUT_EN); |
4253 | /* fake event to set up pins */ | 4399 | /* fake event to set up pins */ |
4254 | stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], | 4400 | stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]); |
4255 | STAC_HP_EVENT); | ||
4256 | } else { | 4401 | } else { |
4257 | stac92xx_auto_init_multi_out(codec); | 4402 | stac92xx_auto_init_multi_out(codec); |
4258 | stac92xx_auto_init_hp_out(codec); | 4403 | stac92xx_auto_init_hp_out(codec); |
4259 | for (i = 0; i < cfg->hp_outs; i++) | 4404 | for (i = 0; i < cfg->hp_outs; i++) |
4260 | stac_toggle_power_map(codec, cfg->hp_pins[i], 1); | 4405 | stac_toggle_power_map(codec, cfg->hp_pins[i], 1); |
4261 | } | 4406 | } |
4407 | if (spec->auto_mic) { | ||
4408 | /* initialize connection to analog input */ | ||
4409 | if (spec->dmux_nids) | ||
4410 | snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, | ||
4411 | AC_VERB_SET_CONNECT_SEL, 0); | ||
4412 | if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT)) | ||
4413 | stac_issue_unsol_event(codec, spec->ext_mic.pin); | ||
4414 | } | ||
4262 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 4415 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
4263 | hda_nid_t nid = cfg->input_pins[i]; | 4416 | hda_nid_t nid = cfg->input_pins[i]; |
4264 | if (nid) { | 4417 | if (nid) { |
@@ -4285,10 +4438,9 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4285 | } | 4438 | } |
4286 | conf = snd_hda_codec_get_pincfg(codec, nid); | 4439 | conf = snd_hda_codec_get_pincfg(codec, nid); |
4287 | if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { | 4440 | if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { |
4288 | enable_pin_detect(codec, nid, | 4441 | if (enable_pin_detect(codec, nid, |
4289 | STAC_INSERT_EVENT); | 4442 | STAC_INSERT_EVENT)) |
4290 | stac_issue_unsol_event(codec, nid, | 4443 | stac_issue_unsol_event(codec, nid); |
4291 | STAC_INSERT_EVENT); | ||
4292 | } | 4444 | } |
4293 | } | 4445 | } |
4294 | } | 4446 | } |
@@ -4333,10 +4485,8 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4333 | stac_toggle_power_map(codec, nid, 1); | 4485 | stac_toggle_power_map(codec, nid, 1); |
4334 | continue; | 4486 | continue; |
4335 | } | 4487 | } |
4336 | if (!stac_get_event(codec, nid, STAC_INSERT_EVENT)) { | 4488 | if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) |
4337 | enable_pin_detect(codec, nid, STAC_PWR_EVENT); | 4489 | stac_issue_unsol_event(codec, nid); |
4338 | stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT); | ||
4339 | } | ||
4340 | } | 4490 | } |
4341 | if (spec->dac_list) | 4491 | if (spec->dac_list) |
4342 | stac92xx_power_down(codec); | 4492 | stac92xx_power_down(codec); |
@@ -4440,6 +4590,48 @@ static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) | |||
4440 | return 0; | 4590 | return 0; |
4441 | } | 4591 | } |
4442 | 4592 | ||
4593 | static void stac92xx_line_out_detect(struct hda_codec *codec, | ||
4594 | int presence) | ||
4595 | { | ||
4596 | struct sigmatel_spec *spec = codec->spec; | ||
4597 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
4598 | int i; | ||
4599 | |||
4600 | for (i = 0; i < cfg->line_outs; i++) { | ||
4601 | if (presence) | ||
4602 | break; | ||
4603 | presence = get_pin_presence(codec, cfg->line_out_pins[i]); | ||
4604 | if (presence) { | ||
4605 | unsigned int pinctl; | ||
4606 | pinctl = snd_hda_codec_read(codec, | ||
4607 | cfg->line_out_pins[i], 0, | ||
4608 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
4609 | if (pinctl & AC_PINCTL_IN_EN) | ||
4610 | presence = 0; /* mic- or line-input */ | ||
4611 | } | ||
4612 | } | ||
4613 | |||
4614 | if (presence) { | ||
4615 | /* disable speakers */ | ||
4616 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4617 | stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], | ||
4618 | AC_PINCTL_OUT_EN); | ||
4619 | if (spec->eapd_mask && spec->eapd_switch) | ||
4620 | stac_gpio_set(codec, spec->gpio_mask, | ||
4621 | spec->gpio_dir, spec->gpio_data & | ||
4622 | ~spec->eapd_mask); | ||
4623 | } else { | ||
4624 | /* enable speakers */ | ||
4625 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4626 | stac92xx_set_pinctl(codec, cfg->speaker_pins[i], | ||
4627 | AC_PINCTL_OUT_EN); | ||
4628 | if (spec->eapd_mask && spec->eapd_switch) | ||
4629 | stac_gpio_set(codec, spec->gpio_mask, | ||
4630 | spec->gpio_dir, spec->gpio_data | | ||
4631 | spec->eapd_mask); | ||
4632 | } | ||
4633 | } | ||
4634 | |||
4443 | /* return non-zero if the hp-pin of the given array index isn't | 4635 | /* return non-zero if the hp-pin of the given array index isn't |
4444 | * a jack-detection target | 4636 | * a jack-detection target |
4445 | */ | 4637 | */ |
@@ -4492,13 +4684,6 @@ static void stac92xx_hp_detect(struct hda_codec *codec) | |||
4492 | for (i = 0; i < cfg->line_outs; i++) | 4684 | for (i = 0; i < cfg->line_outs; i++) |
4493 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], | 4685 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], |
4494 | AC_PINCTL_OUT_EN); | 4686 | AC_PINCTL_OUT_EN); |
4495 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4496 | stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], | ||
4497 | AC_PINCTL_OUT_EN); | ||
4498 | if (spec->eapd_mask && spec->eapd_switch) | ||
4499 | stac_gpio_set(codec, spec->gpio_mask, | ||
4500 | spec->gpio_dir, spec->gpio_data & | ||
4501 | ~spec->eapd_mask); | ||
4502 | } else { | 4687 | } else { |
4503 | /* enable lineouts */ | 4688 | /* enable lineouts */ |
4504 | if (spec->hp_switch) | 4689 | if (spec->hp_switch) |
@@ -4507,14 +4692,8 @@ static void stac92xx_hp_detect(struct hda_codec *codec) | |||
4507 | for (i = 0; i < cfg->line_outs; i++) | 4692 | for (i = 0; i < cfg->line_outs; i++) |
4508 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], | 4693 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], |
4509 | AC_PINCTL_OUT_EN); | 4694 | AC_PINCTL_OUT_EN); |
4510 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4511 | stac92xx_set_pinctl(codec, cfg->speaker_pins[i], | ||
4512 | AC_PINCTL_OUT_EN); | ||
4513 | if (spec->eapd_mask && spec->eapd_switch) | ||
4514 | stac_gpio_set(codec, spec->gpio_mask, | ||
4515 | spec->gpio_dir, spec->gpio_data | | ||
4516 | spec->eapd_mask); | ||
4517 | } | 4695 | } |
4696 | stac92xx_line_out_detect(codec, presence); | ||
4518 | /* toggle hp outs */ | 4697 | /* toggle hp outs */ |
4519 | for (i = 0; i < cfg->hp_outs; i++) { | 4698 | for (i = 0; i < cfg->hp_outs; i++) { |
4520 | unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; | 4699 | unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; |
@@ -4599,10 +4778,28 @@ static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid) | |||
4599 | } | 4778 | } |
4600 | } | 4779 | } |
4601 | 4780 | ||
4602 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, | 4781 | static void stac92xx_mic_detect(struct hda_codec *codec) |
4603 | unsigned char type) | ||
4604 | { | 4782 | { |
4605 | struct sigmatel_event *event = stac_get_event(codec, nid, type); | 4783 | struct sigmatel_spec *spec = codec->spec; |
4784 | struct sigmatel_mic_route *mic; | ||
4785 | |||
4786 | if (get_pin_presence(codec, spec->ext_mic.pin)) | ||
4787 | mic = &spec->ext_mic; | ||
4788 | else | ||
4789 | mic = &spec->int_mic; | ||
4790 | if (mic->dmux_idx) | ||
4791 | snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, | ||
4792 | AC_VERB_SET_CONNECT_SEL, | ||
4793 | mic->dmux_idx); | ||
4794 | else | ||
4795 | snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0, | ||
4796 | AC_VERB_SET_CONNECT_SEL, | ||
4797 | mic->mux_idx); | ||
4798 | } | ||
4799 | |||
4800 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid) | ||
4801 | { | ||
4802 | struct sigmatel_event *event = stac_get_event(codec, nid); | ||
4606 | if (!event) | 4803 | if (!event) |
4607 | return; | 4804 | return; |
4608 | codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26); | 4805 | codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26); |
@@ -4621,8 +4818,18 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | |||
4621 | 4818 | ||
4622 | switch (event->type) { | 4819 | switch (event->type) { |
4623 | case STAC_HP_EVENT: | 4820 | case STAC_HP_EVENT: |
4821 | case STAC_LO_EVENT: | ||
4624 | stac92xx_hp_detect(codec); | 4822 | stac92xx_hp_detect(codec); |
4625 | /* fallthru */ | 4823 | break; |
4824 | case STAC_MIC_EVENT: | ||
4825 | stac92xx_mic_detect(codec); | ||
4826 | break; | ||
4827 | } | ||
4828 | |||
4829 | switch (event->type) { | ||
4830 | case STAC_HP_EVENT: | ||
4831 | case STAC_LO_EVENT: | ||
4832 | case STAC_MIC_EVENT: | ||
4626 | case STAC_INSERT_EVENT: | 4833 | case STAC_INSERT_EVENT: |
4627 | case STAC_PWR_EVENT: | 4834 | case STAC_PWR_EVENT: |
4628 | if (spec->num_pwrs > 0) | 4835 | if (spec->num_pwrs > 0) |
@@ -4713,8 +4920,7 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4713 | snd_hda_codec_resume_cache(codec); | 4920 | snd_hda_codec_resume_cache(codec); |
4714 | /* fake event to set up pins again to override cached values */ | 4921 | /* fake event to set up pins again to override cached values */ |
4715 | if (spec->hp_detect) | 4922 | if (spec->hp_detect) |
4716 | stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], | 4923 | stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]); |
4717 | STAC_HP_EVENT); | ||
4718 | return 0; | 4924 | return 0; |
4719 | } | 4925 | } |
4720 | 4926 | ||
@@ -4754,6 +4960,19 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec, | |||
4754 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | 4960 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) |
4755 | { | 4961 | { |
4756 | struct sigmatel_spec *spec = codec->spec; | 4962 | struct sigmatel_spec *spec = codec->spec; |
4963 | int i; | ||
4964 | hda_nid_t nid; | ||
4965 | |||
4966 | /* reset each pin before powering down DAC/ADC to avoid click noise */ | ||
4967 | nid = codec->start_nid; | ||
4968 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
4969 | unsigned int wcaps = get_wcaps(codec, nid); | ||
4970 | unsigned int wid_type = get_wcaps_type(wcaps); | ||
4971 | if (wid_type == AC_WID_PIN) | ||
4972 | snd_hda_codec_read(codec, nid, 0, | ||
4973 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
4974 | } | ||
4975 | |||
4757 | if (spec->eapd_mask) | 4976 | if (spec->eapd_mask) |
4758 | stac_gpio_set(codec, spec->gpio_mask, | 4977 | stac_gpio_set(codec, spec->gpio_mask, |
4759 | spec->gpio_dir, spec->gpio_data & | 4978 | spec->gpio_dir, spec->gpio_data & |
@@ -4790,7 +5009,8 @@ static int patch_stac9200(struct hda_codec *codec) | |||
4790 | stac9200_models, | 5009 | stac9200_models, |
4791 | stac9200_cfg_tbl); | 5010 | stac9200_cfg_tbl); |
4792 | if (spec->board_config < 0) | 5011 | if (spec->board_config < 0) |
4793 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); | 5012 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5013 | codec->chip_name); | ||
4794 | else | 5014 | else |
4795 | stac92xx_set_config_regs(codec, | 5015 | stac92xx_set_config_regs(codec, |
4796 | stac9200_brd_tbl[spec->board_config]); | 5016 | stac9200_brd_tbl[spec->board_config]); |
@@ -4862,8 +5082,8 @@ static int patch_stac925x(struct hda_codec *codec) | |||
4862 | stac925x_cfg_tbl); | 5082 | stac925x_cfg_tbl); |
4863 | again: | 5083 | again: |
4864 | if (spec->board_config < 0) | 5084 | if (spec->board_config < 0) |
4865 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," | 5085 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
4866 | "using BIOS defaults\n"); | 5086 | codec->chip_name); |
4867 | else | 5087 | else |
4868 | stac92xx_set_config_regs(codec, | 5088 | stac92xx_set_config_regs(codec, |
4869 | stac925x_brd_tbl[spec->board_config]); | 5089 | stac925x_brd_tbl[spec->board_config]); |
@@ -4893,6 +5113,9 @@ static int patch_stac925x(struct hda_codec *codec) | |||
4893 | 5113 | ||
4894 | spec->init = stac925x_core_init; | 5114 | spec->init = stac925x_core_init; |
4895 | spec->mixer = stac925x_mixer; | 5115 | spec->mixer = stac925x_mixer; |
5116 | spec->num_caps = 1; | ||
5117 | spec->capvols = stac925x_capvols; | ||
5118 | spec->capsws = stac925x_capsws; | ||
4896 | 5119 | ||
4897 | err = stac92xx_parse_auto_config(codec, 0x8, 0x7); | 5120 | err = stac92xx_parse_auto_config(codec, 0x8, 0x7); |
4898 | if (!err) { | 5121 | if (!err) { |
@@ -4914,16 +5137,6 @@ static int patch_stac925x(struct hda_codec *codec) | |||
4914 | return 0; | 5137 | return 0; |
4915 | } | 5138 | } |
4916 | 5139 | ||
4917 | static struct hda_input_mux stac92hd73xx_dmux = { | ||
4918 | .num_items = 4, | ||
4919 | .items = { | ||
4920 | { "Analog Inputs", 0x0b }, | ||
4921 | { "Digital Mic 1", 0x09 }, | ||
4922 | { "Digital Mic 2", 0x0a }, | ||
4923 | { "CD", 0x08 }, | ||
4924 | } | ||
4925 | }; | ||
4926 | |||
4927 | static int patch_stac92hd73xx(struct hda_codec *codec) | 5140 | static int patch_stac92hd73xx(struct hda_codec *codec) |
4928 | { | 5141 | { |
4929 | struct sigmatel_spec *spec; | 5142 | struct sigmatel_spec *spec; |
@@ -4945,8 +5158,8 @@ static int patch_stac92hd73xx(struct hda_codec *codec) | |||
4945 | stac92hd73xx_cfg_tbl); | 5158 | stac92hd73xx_cfg_tbl); |
4946 | again: | 5159 | again: |
4947 | if (spec->board_config < 0) | 5160 | if (spec->board_config < 0) |
4948 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5161 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
4949 | " STAC92HD73XX, using BIOS defaults\n"); | 5162 | codec->chip_name); |
4950 | else | 5163 | else |
4951 | stac92xx_set_config_regs(codec, | 5164 | stac92xx_set_config_regs(codec, |
4952 | stac92hd73xx_brd_tbl[spec->board_config]); | 5165 | stac92hd73xx_brd_tbl[spec->board_config]); |
@@ -4993,8 +5206,10 @@ again: | |||
4993 | spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); | 5206 | spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); |
4994 | spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); | 5207 | spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); |
4995 | spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); | 5208 | spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); |
4996 | memcpy(&spec->private_dimux, &stac92hd73xx_dmux, | 5209 | |
4997 | sizeof(stac92hd73xx_dmux)); | 5210 | spec->num_caps = STAC92HD73XX_NUM_CAPS; |
5211 | spec->capvols = stac92hd73xx_capvols; | ||
5212 | spec->capsws = stac92hd73xx_capsws; | ||
4998 | 5213 | ||
4999 | switch (spec->board_config) { | 5214 | switch (spec->board_config) { |
5000 | case STAC_DELL_EQ: | 5215 | case STAC_DELL_EQ: |
@@ -5015,18 +5230,15 @@ again: | |||
5015 | case STAC_DELL_M6_AMIC: /* Analog Mics */ | 5230 | case STAC_DELL_M6_AMIC: /* Analog Mics */ |
5016 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); | 5231 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); |
5017 | spec->num_dmics = 0; | 5232 | spec->num_dmics = 0; |
5018 | spec->private_dimux.num_items = 1; | ||
5019 | break; | 5233 | break; |
5020 | case STAC_DELL_M6_DMIC: /* Digital Mics */ | 5234 | case STAC_DELL_M6_DMIC: /* Digital Mics */ |
5021 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); | 5235 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); |
5022 | spec->num_dmics = 1; | 5236 | spec->num_dmics = 1; |
5023 | spec->private_dimux.num_items = 2; | ||
5024 | break; | 5237 | break; |
5025 | case STAC_DELL_M6_BOTH: /* Both */ | 5238 | case STAC_DELL_M6_BOTH: /* Both */ |
5026 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); | 5239 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); |
5027 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); | 5240 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); |
5028 | spec->num_dmics = 1; | 5241 | spec->num_dmics = 1; |
5029 | spec->private_dimux.num_items = 2; | ||
5030 | break; | 5242 | break; |
5031 | } | 5243 | } |
5032 | break; | 5244 | break; |
@@ -5034,13 +5246,13 @@ again: | |||
5034 | spec->num_dmics = STAC92HD73XX_NUM_DMICS; | 5246 | spec->num_dmics = STAC92HD73XX_NUM_DMICS; |
5035 | spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); | 5247 | spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); |
5036 | spec->eapd_switch = 1; | 5248 | spec->eapd_switch = 1; |
5249 | break; | ||
5037 | } | 5250 | } |
5038 | if (spec->board_config > STAC_92HD73XX_REF) { | 5251 | if (spec->board_config > STAC_92HD73XX_REF) { |
5039 | /* GPIO0 High = Enable EAPD */ | 5252 | /* GPIO0 High = Enable EAPD */ |
5040 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | 5253 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; |
5041 | spec->gpio_data = 0x01; | 5254 | spec->gpio_data = 0x01; |
5042 | } | 5255 | } |
5043 | spec->dinput_mux = &spec->private_dimux; | ||
5044 | 5256 | ||
5045 | spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); | 5257 | spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); |
5046 | spec->pwr_nids = stac92hd73xx_pwr_nids; | 5258 | spec->pwr_nids = stac92hd73xx_pwr_nids; |
@@ -5072,15 +5284,6 @@ again: | |||
5072 | return 0; | 5284 | return 0; |
5073 | } | 5285 | } |
5074 | 5286 | ||
5075 | static struct hda_input_mux stac92hd83xxx_dmux = { | ||
5076 | .num_items = 3, | ||
5077 | .items = { | ||
5078 | { "Analog Inputs", 0x03 }, | ||
5079 | { "Digital Mic 1", 0x04 }, | ||
5080 | { "Digital Mic 2", 0x05 }, | ||
5081 | } | ||
5082 | }; | ||
5083 | |||
5084 | static int patch_stac92hd83xxx(struct hda_codec *codec) | 5287 | static int patch_stac92hd83xxx(struct hda_codec *codec) |
5085 | { | 5288 | { |
5086 | struct sigmatel_spec *spec; | 5289 | struct sigmatel_spec *spec; |
@@ -5097,32 +5300,30 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5097 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | 5300 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; |
5098 | spec->mono_nid = 0x19; | 5301 | spec->mono_nid = 0x19; |
5099 | spec->digbeep_nid = 0x21; | 5302 | spec->digbeep_nid = 0x21; |
5100 | spec->dmic_nids = stac92hd83xxx_dmic_nids; | 5303 | spec->mux_nids = stac92hd83xxx_mux_nids; |
5101 | spec->dmux_nids = stac92hd83xxx_dmux_nids; | 5304 | spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids); |
5102 | spec->adc_nids = stac92hd83xxx_adc_nids; | 5305 | spec->adc_nids = stac92hd83xxx_adc_nids; |
5306 | spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); | ||
5103 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | 5307 | spec->pwr_nids = stac92hd83xxx_pwr_nids; |
5104 | spec->amp_nids = stac92hd83xxx_amp_nids; | ||
5105 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; | 5308 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; |
5106 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 5309 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
5107 | spec->multiout.dac_nids = spec->dac_nids; | 5310 | spec->multiout.dac_nids = spec->dac_nids; |
5108 | 5311 | ||
5109 | spec->init = stac92hd83xxx_core_init; | 5312 | spec->init = stac92hd83xxx_core_init; |
5110 | spec->mixer = stac92hd83xxx_mixer; | ||
5111 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); | 5313 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); |
5112 | spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids); | ||
5113 | spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); | ||
5114 | spec->num_amps = ARRAY_SIZE(stac92hd83xxx_amp_nids); | ||
5115 | spec->num_dmics = STAC92HD83XXX_NUM_DMICS; | ||
5116 | spec->dinput_mux = &stac92hd83xxx_dmux; | ||
5117 | spec->pin_nids = stac92hd83xxx_pin_nids; | 5314 | spec->pin_nids = stac92hd83xxx_pin_nids; |
5315 | spec->num_caps = STAC92HD83XXX_NUM_CAPS; | ||
5316 | spec->capvols = stac92hd83xxx_capvols; | ||
5317 | spec->capsws = stac92hd83xxx_capsws; | ||
5318 | |||
5118 | spec->board_config = snd_hda_check_board_config(codec, | 5319 | spec->board_config = snd_hda_check_board_config(codec, |
5119 | STAC_92HD83XXX_MODELS, | 5320 | STAC_92HD83XXX_MODELS, |
5120 | stac92hd83xxx_models, | 5321 | stac92hd83xxx_models, |
5121 | stac92hd83xxx_cfg_tbl); | 5322 | stac92hd83xxx_cfg_tbl); |
5122 | again: | 5323 | again: |
5123 | if (spec->board_config < 0) | 5324 | if (spec->board_config < 0) |
5124 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5325 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5125 | " STAC92HD83XXX, using BIOS defaults\n"); | 5326 | codec->chip_name); |
5126 | else | 5327 | else |
5127 | stac92xx_set_config_regs(codec, | 5328 | stac92xx_set_config_regs(codec, |
5128 | stac92hd83xxx_brd_tbl[spec->board_config]); | 5329 | stac92hd83xxx_brd_tbl[spec->board_config]); |
@@ -5164,6 +5365,8 @@ again: | |||
5164 | 5365 | ||
5165 | num_dacs = snd_hda_get_connections(codec, nid, | 5366 | num_dacs = snd_hda_get_connections(codec, nid, |
5166 | conn, STAC92HD83_DAC_COUNT + 1) - 1; | 5367 | conn, STAC92HD83_DAC_COUNT + 1) - 1; |
5368 | if (num_dacs < 0) | ||
5369 | num_dacs = STAC92HD83_DAC_COUNT; | ||
5167 | 5370 | ||
5168 | /* set port X to select the last DAC | 5371 | /* set port X to select the last DAC |
5169 | */ | 5372 | */ |
@@ -5177,25 +5380,6 @@ again: | |||
5177 | return 0; | 5380 | return 0; |
5178 | } | 5381 | } |
5179 | 5382 | ||
5180 | static struct hda_input_mux stac92hd71bxx_dmux_nomixer = { | ||
5181 | .num_items = 3, | ||
5182 | .items = { | ||
5183 | { "Analog Inputs", 0x00 }, | ||
5184 | { "Digital Mic 1", 0x02 }, | ||
5185 | { "Digital Mic 2", 0x03 }, | ||
5186 | } | ||
5187 | }; | ||
5188 | |||
5189 | static struct hda_input_mux stac92hd71bxx_dmux_amixer = { | ||
5190 | .num_items = 4, | ||
5191 | .items = { | ||
5192 | { "Analog Inputs", 0x00 }, | ||
5193 | { "Mixer", 0x01 }, | ||
5194 | { "Digital Mic 1", 0x02 }, | ||
5195 | { "Digital Mic 2", 0x03 }, | ||
5196 | } | ||
5197 | }; | ||
5198 | |||
5199 | /* get the pin connection (fixed, none, etc) */ | 5383 | /* get the pin connection (fixed, none, etc) */ |
5200 | static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) | 5384 | static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) |
5201 | { | 5385 | { |
@@ -5256,7 +5440,6 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
5256 | struct sigmatel_spec *spec; | 5440 | struct sigmatel_spec *spec; |
5257 | struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; | 5441 | struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; |
5258 | int err = 0; | 5442 | int err = 0; |
5259 | unsigned int ndmic_nids = 0; | ||
5260 | 5443 | ||
5261 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5444 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
5262 | if (spec == NULL) | 5445 | if (spec == NULL) |
@@ -5285,8 +5468,8 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
5285 | stac92hd71bxx_cfg_tbl); | 5468 | stac92hd71bxx_cfg_tbl); |
5286 | again: | 5469 | again: |
5287 | if (spec->board_config < 0) | 5470 | if (spec->board_config < 0) |
5288 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5471 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5289 | " STAC92HD71BXX, using BIOS defaults\n"); | 5472 | codec->chip_name); |
5290 | else | 5473 | else |
5291 | stac92xx_set_config_regs(codec, | 5474 | stac92xx_set_config_regs(codec, |
5292 | stac92hd71bxx_brd_tbl[spec->board_config]); | 5475 | stac92hd71bxx_brd_tbl[spec->board_config]); |
@@ -5301,6 +5484,10 @@ again: | |||
5301 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | 5484 | spec->dmic_nids = stac92hd71bxx_dmic_nids; |
5302 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | 5485 | spec->dmux_nids = stac92hd71bxx_dmux_nids; |
5303 | 5486 | ||
5487 | spec->num_caps = STAC92HD71BXX_NUM_CAPS; | ||
5488 | spec->capvols = stac92hd71bxx_capvols; | ||
5489 | spec->capsws = stac92hd71bxx_capsws; | ||
5490 | |||
5304 | switch (codec->vendor_id) { | 5491 | switch (codec->vendor_id) { |
5305 | case 0x111d76b6: /* 4 Port without Analog Mixer */ | 5492 | case 0x111d76b6: /* 4 Port without Analog Mixer */ |
5306 | case 0x111d76b7: | 5493 | case 0x111d76b7: |
@@ -5308,24 +5495,13 @@ again: | |||
5308 | /* fallthru */ | 5495 | /* fallthru */ |
5309 | case 0x111d76b4: /* 6 Port without Analog Mixer */ | 5496 | case 0x111d76b4: /* 6 Port without Analog Mixer */ |
5310 | case 0x111d76b5: | 5497 | case 0x111d76b5: |
5311 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_nomixer, | ||
5312 | sizeof(stac92hd71bxx_dmux_nomixer)); | ||
5313 | spec->mixer = stac92hd71bxx_mixer; | ||
5314 | spec->init = stac92hd71bxx_core_init; | 5498 | spec->init = stac92hd71bxx_core_init; |
5315 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5499 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5316 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | 5500 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, |
5317 | stac92hd71bxx_dmic_nids, | 5501 | stac92hd71bxx_dmic_nids, |
5318 | STAC92HD71BXX_NUM_DMICS); | 5502 | STAC92HD71BXX_NUM_DMICS); |
5319 | if (spec->num_dmics) { | ||
5320 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5321 | spec->dinput_mux = &spec->private_dimux; | ||
5322 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | ||
5323 | } | ||
5324 | break; | 5503 | break; |
5325 | case 0x111d7608: /* 5 Port with Analog Mixer */ | 5504 | case 0x111d7608: /* 5 Port with Analog Mixer */ |
5326 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | ||
5327 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
5328 | spec->private_dimux.num_items--; | ||
5329 | switch (spec->board_config) { | 5505 | switch (spec->board_config) { |
5330 | case STAC_HP_M4: | 5506 | case STAC_HP_M4: |
5331 | /* Enable VREF power saving on GPIO1 detect */ | 5507 | /* Enable VREF power saving on GPIO1 detect */ |
@@ -5347,11 +5523,8 @@ again: | |||
5347 | 5523 | ||
5348 | /* no output amps */ | 5524 | /* no output amps */ |
5349 | spec->num_pwrs = 0; | 5525 | spec->num_pwrs = 0; |
5350 | spec->mixer = stac92hd71bxx_analog_mixer; | ||
5351 | spec->dinput_mux = &spec->private_dimux; | ||
5352 | |||
5353 | /* disable VSW */ | 5526 | /* disable VSW */ |
5354 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; | 5527 | spec->init = stac92hd71bxx_core_init; |
5355 | unmute_init++; | 5528 | unmute_init++; |
5356 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); | 5529 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); |
5357 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); | 5530 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); |
@@ -5359,8 +5532,6 @@ again: | |||
5359 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | 5532 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, |
5360 | stac92hd71bxx_dmic_nids, | 5533 | stac92hd71bxx_dmic_nids, |
5361 | STAC92HD71BXX_NUM_DMICS - 1); | 5534 | STAC92HD71BXX_NUM_DMICS - 1); |
5362 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5363 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2; | ||
5364 | break; | 5535 | break; |
5365 | case 0x111d7603: /* 6 Port with Analog Mixer */ | 5536 | case 0x111d7603: /* 6 Port with Analog Mixer */ |
5366 | if ((codec->revision_id & 0xf) == 1) | 5537 | if ((codec->revision_id & 0xf) == 1) |
@@ -5370,17 +5541,12 @@ again: | |||
5370 | spec->num_pwrs = 0; | 5541 | spec->num_pwrs = 0; |
5371 | /* fallthru */ | 5542 | /* fallthru */ |
5372 | default: | 5543 | default: |
5373 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | 5544 | spec->init = stac92hd71bxx_core_init; |
5374 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
5375 | spec->dinput_mux = &spec->private_dimux; | ||
5376 | spec->mixer = stac92hd71bxx_analog_mixer; | ||
5377 | spec->init = stac92hd71bxx_analog_core_init; | ||
5378 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5545 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5379 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | 5546 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, |
5380 | stac92hd71bxx_dmic_nids, | 5547 | stac92hd71bxx_dmic_nids, |
5381 | STAC92HD71BXX_NUM_DMICS); | 5548 | STAC92HD71BXX_NUM_DMICS); |
5382 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | 5549 | break; |
5383 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | ||
5384 | } | 5550 | } |
5385 | 5551 | ||
5386 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | 5552 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) |
@@ -5408,6 +5574,7 @@ again: | |||
5408 | 5574 | ||
5409 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); | 5575 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); |
5410 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); | 5576 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); |
5577 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5411 | spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e); | 5578 | spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e); |
5412 | 5579 | ||
5413 | switch (spec->board_config) { | 5580 | switch (spec->board_config) { |
@@ -5462,8 +5629,6 @@ again: | |||
5462 | #endif | 5629 | #endif |
5463 | 5630 | ||
5464 | spec->multiout.dac_nids = spec->dac_nids; | 5631 | spec->multiout.dac_nids = spec->dac_nids; |
5465 | if (spec->dinput_mux) | ||
5466 | spec->private_dimux.num_items += spec->num_dmics - ndmic_nids; | ||
5467 | 5632 | ||
5468 | err = stac92xx_parse_auto_config(codec, 0x21, 0); | 5633 | err = stac92xx_parse_auto_config(codec, 0x21, 0); |
5469 | if (!err) { | 5634 | if (!err) { |
@@ -5541,8 +5706,8 @@ static int patch_stac922x(struct hda_codec *codec) | |||
5541 | 5706 | ||
5542 | again: | 5707 | again: |
5543 | if (spec->board_config < 0) | 5708 | if (spec->board_config < 0) |
5544 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " | 5709 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5545 | "using BIOS defaults\n"); | 5710 | codec->chip_name); |
5546 | else | 5711 | else |
5547 | stac92xx_set_config_regs(codec, | 5712 | stac92xx_set_config_regs(codec, |
5548 | stac922x_brd_tbl[spec->board_config]); | 5713 | stac922x_brd_tbl[spec->board_config]); |
@@ -5555,7 +5720,10 @@ static int patch_stac922x(struct hda_codec *codec) | |||
5555 | spec->num_pwrs = 0; | 5720 | spec->num_pwrs = 0; |
5556 | 5721 | ||
5557 | spec->init = stac922x_core_init; | 5722 | spec->init = stac922x_core_init; |
5558 | spec->mixer = stac922x_mixer; | 5723 | |
5724 | spec->num_caps = STAC922X_NUM_CAPS; | ||
5725 | spec->capvols = stac922x_capvols; | ||
5726 | spec->capsws = stac922x_capsws; | ||
5559 | 5727 | ||
5560 | spec->multiout.dac_nids = spec->dac_nids; | 5728 | spec->multiout.dac_nids = spec->dac_nids; |
5561 | 5729 | ||
@@ -5604,8 +5772,8 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5604 | stac927x_cfg_tbl); | 5772 | stac927x_cfg_tbl); |
5605 | again: | 5773 | again: |
5606 | if (spec->board_config < 0) | 5774 | if (spec->board_config < 0) |
5607 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5775 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5608 | "STAC927x, using BIOS defaults\n"); | 5776 | codec->chip_name); |
5609 | else | 5777 | else |
5610 | stac92xx_set_config_regs(codec, | 5778 | stac92xx_set_config_regs(codec, |
5611 | stac927x_brd_tbl[spec->board_config]); | 5779 | stac927x_brd_tbl[spec->board_config]); |
@@ -5630,7 +5798,6 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5630 | spec->num_dmics = 0; | 5798 | spec->num_dmics = 0; |
5631 | 5799 | ||
5632 | spec->init = d965_core_init; | 5800 | spec->init = d965_core_init; |
5633 | spec->mixer = stac927x_mixer; | ||
5634 | break; | 5801 | break; |
5635 | case STAC_DELL_BIOS: | 5802 | case STAC_DELL_BIOS: |
5636 | switch (codec->subsystem_id) { | 5803 | switch (codec->subsystem_id) { |
@@ -5662,7 +5829,6 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5662 | spec->num_dmics = STAC927X_NUM_DMICS; | 5829 | spec->num_dmics = STAC927X_NUM_DMICS; |
5663 | 5830 | ||
5664 | spec->init = d965_core_init; | 5831 | spec->init = d965_core_init; |
5665 | spec->mixer = stac927x_mixer; | ||
5666 | spec->dmux_nids = stac927x_dmux_nids; | 5832 | spec->dmux_nids = stac927x_dmux_nids; |
5667 | spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); | 5833 | spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); |
5668 | break; | 5834 | break; |
@@ -5675,9 +5841,12 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5675 | spec->num_dmics = 0; | 5841 | spec->num_dmics = 0; |
5676 | 5842 | ||
5677 | spec->init = stac927x_core_init; | 5843 | spec->init = stac927x_core_init; |
5678 | spec->mixer = stac927x_mixer; | ||
5679 | } | 5844 | } |
5680 | 5845 | ||
5846 | spec->num_caps = STAC927X_NUM_CAPS; | ||
5847 | spec->capvols = stac927x_capvols; | ||
5848 | spec->capsws = stac927x_capsws; | ||
5849 | |||
5681 | spec->num_pwrs = 0; | 5850 | spec->num_pwrs = 0; |
5682 | spec->aloopback_ctl = stac927x_loopback; | 5851 | spec->aloopback_ctl = stac927x_loopback; |
5683 | spec->aloopback_mask = 0x40; | 5852 | spec->aloopback_mask = 0x40; |
@@ -5739,7 +5908,8 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5739 | stac9205_cfg_tbl); | 5908 | stac9205_cfg_tbl); |
5740 | again: | 5909 | again: |
5741 | if (spec->board_config < 0) | 5910 | if (spec->board_config < 0) |
5742 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); | 5911 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5912 | codec->chip_name); | ||
5743 | else | 5913 | else |
5744 | stac92xx_set_config_regs(codec, | 5914 | stac92xx_set_config_regs(codec, |
5745 | stac9205_brd_tbl[spec->board_config]); | 5915 | stac9205_brd_tbl[spec->board_config]); |
@@ -5758,9 +5928,12 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5758 | spec->num_pwrs = 0; | 5928 | spec->num_pwrs = 0; |
5759 | 5929 | ||
5760 | spec->init = stac9205_core_init; | 5930 | spec->init = stac9205_core_init; |
5761 | spec->mixer = stac9205_mixer; | ||
5762 | spec->aloopback_ctl = stac9205_loopback; | 5931 | spec->aloopback_ctl = stac9205_loopback; |
5763 | 5932 | ||
5933 | spec->num_caps = STAC9205_NUM_CAPS; | ||
5934 | spec->capvols = stac9205_capvols; | ||
5935 | spec->capsws = stac9205_capsws; | ||
5936 | |||
5764 | spec->aloopback_mask = 0x40; | 5937 | spec->aloopback_mask = 0x40; |
5765 | spec->aloopback_shift = 0; | 5938 | spec->aloopback_shift = 0; |
5766 | /* Turn on/off EAPD per HP plugging */ | 5939 | /* Turn on/off EAPD per HP plugging */ |
@@ -5835,12 +6008,6 @@ static struct hda_verb stac9872_core_init[] = { | |||
5835 | {} | 6008 | {} |
5836 | }; | 6009 | }; |
5837 | 6010 | ||
5838 | static struct snd_kcontrol_new stac9872_mixer[] = { | ||
5839 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | ||
5840 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | ||
5841 | { } /* end */ | ||
5842 | }; | ||
5843 | |||
5844 | static hda_nid_t stac9872_pin_nids[] = { | 6011 | static hda_nid_t stac9872_pin_nids[] = { |
5845 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, | 6012 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
5846 | 0x11, 0x13, 0x14, | 6013 | 0x11, 0x13, 0x14, |
@@ -5854,6 +6021,11 @@ static hda_nid_t stac9872_mux_nids[] = { | |||
5854 | 0x15 | 6021 | 0x15 |
5855 | }; | 6022 | }; |
5856 | 6023 | ||
6024 | static unsigned long stac9872_capvols[] = { | ||
6025 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), | ||
6026 | }; | ||
6027 | #define stac9872_capsws stac9872_capvols | ||
6028 | |||
5857 | static unsigned int stac9872_vaio_pin_configs[9] = { | 6029 | static unsigned int stac9872_vaio_pin_configs[9] = { |
5858 | 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, | 6030 | 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, |
5859 | 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, | 6031 | 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, |
@@ -5891,8 +6063,8 @@ static int patch_stac9872(struct hda_codec *codec) | |||
5891 | stac9872_models, | 6063 | stac9872_models, |
5892 | stac9872_cfg_tbl); | 6064 | stac9872_cfg_tbl); |
5893 | if (spec->board_config < 0) | 6065 | if (spec->board_config < 0) |
5894 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9872, " | 6066 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
5895 | "using BIOS defaults\n"); | 6067 | codec->chip_name); |
5896 | else | 6068 | else |
5897 | stac92xx_set_config_regs(codec, | 6069 | stac92xx_set_config_regs(codec, |
5898 | stac9872_brd_tbl[spec->board_config]); | 6070 | stac9872_brd_tbl[spec->board_config]); |
@@ -5902,8 +6074,10 @@ static int patch_stac9872(struct hda_codec *codec) | |||
5902 | spec->adc_nids = stac9872_adc_nids; | 6074 | spec->adc_nids = stac9872_adc_nids; |
5903 | spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids); | 6075 | spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids); |
5904 | spec->mux_nids = stac9872_mux_nids; | 6076 | spec->mux_nids = stac9872_mux_nids; |
5905 | spec->mixer = stac9872_mixer; | ||
5906 | spec->init = stac9872_core_init; | 6077 | spec->init = stac9872_core_init; |
6078 | spec->num_caps = 1; | ||
6079 | spec->capvols = stac9872_capvols; | ||
6080 | spec->capsws = stac9872_capsws; | ||
5907 | 6081 | ||
5908 | err = stac92xx_parse_auto_config(codec, 0x10, 0x12); | 6082 | err = stac92xx_parse_auto_config(codec, 0x10, 0x12); |
5909 | if (err < 0) { | 6083 | if (err < 0) { |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 9008b4b013a..ab90abb04cc 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, |