diff options
-rw-r--r-- | Documentation/sound/alsa/HD-Audio-Models.txt | 13 | ||||
-rw-r--r-- | sound/pci/hda/Kconfig | 13 | ||||
-rw-r--r-- | sound/pci/hda/Makefile | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.c | 55 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.h | 5 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 243 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_hwdep.c | 9 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 172 | ||||
-rw-r--r-- | sound/pci/hda/hda_proc.c | 8 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0110.c | 573 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 1935 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 165 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 111 |
14 files changed, 2055 insertions, 1255 deletions
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 322869fc8a9e..818d06f54e36 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt | |||
@@ -36,6 +36,7 @@ ALC260 | |||
36 | acer Acer TravelMate | 36 | acer Acer TravelMate |
37 | will Will laptops (PB V7900) | 37 | will Will laptops (PB V7900) |
38 | replacer Replacer 672V | 38 | replacer Replacer 672V |
39 | favorit100 Maxdata Favorit 100XS | ||
39 | basic fixed pin assignment (old default model) | 40 | basic fixed pin assignment (old default model) |
40 | test for testing/debugging purpose, almost all controls can | 41 | test for testing/debugging purpose, almost all controls can |
41 | adjusted. Appearing only when compiled with | 42 | adjusted. Appearing only when compiled with |
@@ -85,10 +86,11 @@ ALC269 | |||
85 | eeepc-p703 ASUS Eeepc P703 P900A | 86 | eeepc-p703 ASUS Eeepc P703 P900A |
86 | eeepc-p901 ASUS Eeepc P901 S101 | 87 | eeepc-p901 ASUS Eeepc P901 S101 |
87 | fujitsu FSC Amilo | 88 | fujitsu FSC Amilo |
89 | lifebook Fujitsu Lifebook S6420 | ||
88 | auto auto-config reading BIOS (default) | 90 | auto auto-config reading BIOS (default) |
89 | 91 | ||
90 | ALC662/663 | 92 | ALC662/663/272 |
91 | ========== | 93 | ============== |
92 | 3stack-dig 3-stack (2-channel) with SPDIF | 94 | 3stack-dig 3-stack (2-channel) with SPDIF |
93 | 3stack-6ch 3-stack (6-channel) | 95 | 3stack-6ch 3-stack (6-channel) |
94 | 3stack-6ch-dig 3-stack (6-channel) with SPDIF | 96 | 3stack-6ch-dig 3-stack (6-channel) with SPDIF |
@@ -107,6 +109,9 @@ ALC662/663 | |||
107 | asus-mode4 ASUS | 109 | asus-mode4 ASUS |
108 | asus-mode5 ASUS | 110 | asus-mode5 ASUS |
109 | asus-mode6 ASUS | 111 | asus-mode6 ASUS |
112 | dell Dell with ALC272 | ||
113 | dell-zm1 Dell ZM1 with ALC272 | ||
114 | samsung-nc10 Samsung NC10 mini notebook | ||
110 | auto auto-config reading BIOS (default) | 115 | auto auto-config reading BIOS (default) |
111 | 116 | ||
112 | ALC882/885 | 117 | ALC882/885 |
@@ -118,6 +123,7 @@ ALC882/885 | |||
118 | asus-a7j ASUS A7J | 123 | asus-a7j ASUS A7J |
119 | asus-a7m ASUS A7M | 124 | asus-a7m ASUS A7M |
120 | macpro MacPro support | 125 | macpro MacPro support |
126 | mb5 Macbook 5,1 | ||
121 | mbp3 Macbook Pro rev3 | 127 | mbp3 Macbook Pro rev3 |
122 | imac24 iMac 24'' with jack detection | 128 | imac24 iMac 24'' with jack detection |
123 | w2jc ASUS W2JC | 129 | w2jc ASUS W2JC |
@@ -150,6 +156,8 @@ ALC883/888 | |||
150 | fujitsu-pi2515 Fujitsu AMILO Pi2515 | 156 | fujitsu-pi2515 Fujitsu AMILO Pi2515 |
151 | fujitsu-xa3530 Fujitsu AMILO XA3530 | 157 | fujitsu-xa3530 Fujitsu AMILO XA3530 |
152 | 3stack-6ch-intel Intel DG33* boards | 158 | 3stack-6ch-intel Intel DG33* boards |
159 | asus-p5q ASUS P5Q-EM boards | ||
160 | mb31 MacBook 3,1 | ||
153 | auto auto-config reading BIOS (default) | 161 | auto auto-config reading BIOS (default) |
154 | 162 | ||
155 | ALC861/660 | 163 | ALC861/660 |
@@ -348,6 +356,7 @@ STAC92HD71B* | |||
348 | hp-m4 HP mini 1000 | 356 | hp-m4 HP mini 1000 |
349 | hp-dv5 HP dv series | 357 | hp-dv5 HP dv series |
350 | hp-hdx HP HDX series | 358 | hp-hdx HP HDX series |
359 | hp-dv4-1222nr HP dv4-1222nr (with LED support) | ||
351 | auto BIOS setup (default) | 360 | auto BIOS setup (default) |
352 | 361 | ||
353 | STAC92HD73* | 362 | STAC92HD73* |
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index eb2a19b894a0..c710150d5065 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig | |||
@@ -139,6 +139,19 @@ config SND_HDA_CODEC_CONEXANT | |||
139 | snd-hda-codec-conexant. | 139 | snd-hda-codec-conexant. |
140 | This module is automatically loaded at probing. | 140 | This module is automatically loaded at probing. |
141 | 141 | ||
142 | config SND_HDA_CODEC_CA0110 | ||
143 | bool "Build Creative CA0110-IBG codec support" | ||
144 | depends on SND_HDA_INTEL | ||
145 | default y | ||
146 | help | ||
147 | Say Y here to include Creative CA0110-IBG codec support in | ||
148 | snd-hda-intel driver, found on some Creative X-Fi cards. | ||
149 | |||
150 | When the HD-audio driver is built as a module, the codec | ||
151 | support code is also built as another module, | ||
152 | snd-hda-codec-ca0110. | ||
153 | This module is automatically loaded at probing. | ||
154 | |||
142 | config SND_HDA_CODEC_CMEDIA | 155 | config SND_HDA_CODEC_CMEDIA |
143 | bool "Build C-Media HD-audio codec support" | 156 | bool "Build C-Media HD-audio codec support" |
144 | default y | 157 | default y |
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 50f9d0967251..e3081d4586cc 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-ca0110-objs := patch_ca0110.o | ||
16 | snd-hda-codec-conexant-objs := patch_conexant.o | 17 | snd-hda-codec-conexant-objs := patch_conexant.o |
17 | snd-hda-codec-via-objs := patch_via.o | 18 | snd-hda-codec-via-objs := patch_via.o |
18 | snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o | 19 | snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o |
@@ -40,6 +41,9 @@ endif | |||
40 | ifdef CONFIG_SND_HDA_CODEC_ATIHDMI | 41 | ifdef CONFIG_SND_HDA_CODEC_ATIHDMI |
41 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o | 42 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o |
42 | endif | 43 | endif |
44 | ifdef CONFIG_SND_HDA_CODEC_CA0110 | ||
45 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o | ||
46 | endif | ||
43 | ifdef CONFIG_SND_HDA_CODEC_CONEXANT | 47 | ifdef CONFIG_SND_HDA_CODEC_CONEXANT |
44 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o | 48 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o |
45 | endif | 49 | endif |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 4de5bacd3929..29272f2e95a0 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -45,6 +45,46 @@ static void snd_hda_generate_beep(struct work_struct *work) | |||
45 | AC_VERB_SET_BEEP_CONTROL, beep->tone); | 45 | AC_VERB_SET_BEEP_CONTROL, beep->tone); |
46 | } | 46 | } |
47 | 47 | ||
48 | /* (non-standard) Linear beep tone calculation for IDT/STAC codecs | ||
49 | * | ||
50 | * The tone frequency of beep generator on IDT/STAC codecs is | ||
51 | * defined from the 8bit tone parameter, in Hz, | ||
52 | * freq = 48000 * (257 - tone) / 1024 | ||
53 | * that is from 12kHz to 93.75kHz in step of 46.875 hz | ||
54 | */ | ||
55 | static int beep_linear_tone(struct hda_beep *beep, int hz) | ||
56 | { | ||
57 | hz *= 1000; /* fixed point */ | ||
58 | hz = hz - DIGBEEP_HZ_MIN; | ||
59 | if (hz < 0) | ||
60 | hz = 0; /* turn off PC beep*/ | ||
61 | else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN)) | ||
62 | hz = 0xff; | ||
63 | else { | ||
64 | hz /= DIGBEEP_HZ_STEP; | ||
65 | hz++; | ||
66 | } | ||
67 | return hz; | ||
68 | } | ||
69 | |||
70 | /* HD-audio standard beep tone parameter calculation | ||
71 | * | ||
72 | * The tone frequency in Hz is calculated as | ||
73 | * freq = 48000 / (tone * 4) | ||
74 | * from 47Hz to 12kHz | ||
75 | */ | ||
76 | static int beep_standard_tone(struct hda_beep *beep, int hz) | ||
77 | { | ||
78 | if (hz <= 0) | ||
79 | return 0; /* disabled */ | ||
80 | hz = 12000 / hz; | ||
81 | if (hz > 0xff) | ||
82 | return 0xff; | ||
83 | if (hz <= 0) | ||
84 | return 1; | ||
85 | return hz; | ||
86 | } | ||
87 | |||
48 | static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, | 88 | static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, |
49 | unsigned int code, int hz) | 89 | unsigned int code, int hz) |
50 | { | 90 | { |
@@ -55,21 +95,14 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, | |||
55 | if (hz) | 95 | if (hz) |
56 | hz = 1000; | 96 | hz = 1000; |
57 | case SND_TONE: | 97 | case SND_TONE: |
58 | hz *= 1000; /* fixed point */ | 98 | if (beep->linear_tone) |
59 | hz = hz - DIGBEEP_HZ_MIN; | 99 | beep->tone = beep_linear_tone(beep, hz); |
60 | if (hz < 0) | 100 | else |
61 | hz = 0; /* turn off PC beep*/ | 101 | beep->tone = beep_standard_tone(beep, hz); |
62 | else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN)) | ||
63 | hz = 0xff; | ||
64 | else { | ||
65 | hz /= DIGBEEP_HZ_STEP; | ||
66 | hz++; | ||
67 | } | ||
68 | break; | 102 | break; |
69 | default: | 103 | default: |
70 | return -1; | 104 | return -1; |
71 | } | 105 | } |
72 | beep->tone = hz; | ||
73 | 106 | ||
74 | /* schedule beep event */ | 107 | /* schedule beep event */ |
75 | schedule_work(&beep->beep_work); | 108 | schedule_work(&beep->beep_work); |
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index 51bf6a5daf39..0c3de787c717 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h | |||
@@ -30,8 +30,9 @@ struct hda_beep { | |||
30 | struct hda_codec *codec; | 30 | struct hda_codec *codec; |
31 | char phys[32]; | 31 | char phys[32]; |
32 | int tone; | 32 | int tone; |
33 | int nid; | 33 | hda_nid_t nid; |
34 | int enabled; | 34 | unsigned int enabled:1; |
35 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ | ||
35 | struct work_struct beep_work; /* scheduled task for beep event */ | 36 | struct work_struct beep_work; /* scheduled task for beep event */ |
36 | }; | 37 | }; |
37 | 38 | ||
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 8820faf6c9d8..d1d5fb9d7afb 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -48,6 +48,7 @@ static struct hda_vendor_id hda_vendor_ids[] = { | |||
48 | { 0x1095, "Silicon Image" }, | 48 | { 0x1095, "Silicon Image" }, |
49 | { 0x10de, "Nvidia" }, | 49 | { 0x10de, "Nvidia" }, |
50 | { 0x10ec, "Realtek" }, | 50 | { 0x10ec, "Realtek" }, |
51 | { 0x1102, "Creative" }, | ||
51 | { 0x1106, "VIA" }, | 52 | { 0x1106, "VIA" }, |
52 | { 0x111d, "IDT" }, | 53 | { 0x111d, "IDT" }, |
53 | { 0x11c1, "LSI" }, | 54 | { 0x11c1, "LSI" }, |
@@ -157,6 +158,38 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | |||
157 | return val; | 158 | return val; |
158 | } | 159 | } |
159 | 160 | ||
161 | /* | ||
162 | * Send and receive a verb | ||
163 | */ | ||
164 | static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, | ||
165 | unsigned int *res) | ||
166 | { | ||
167 | struct hda_bus *bus = codec->bus; | ||
168 | int err, repeated = 0; | ||
169 | |||
170 | if (res) | ||
171 | *res = -1; | ||
172 | snd_hda_power_up(codec); | ||
173 | mutex_lock(&bus->cmd_mutex); | ||
174 | again: | ||
175 | err = bus->ops.command(bus, cmd); | ||
176 | if (!err) { | ||
177 | if (res) { | ||
178 | *res = bus->ops.get_response(bus); | ||
179 | if (*res == -1 && bus->rirb_error) { | ||
180 | if (repeated++ < 1) { | ||
181 | snd_printd(KERN_WARNING "hda_codec: " | ||
182 | "Trying verb 0x%08x again\n", cmd); | ||
183 | goto again; | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | mutex_unlock(&bus->cmd_mutex); | ||
189 | snd_hda_power_down(codec); | ||
190 | return err; | ||
191 | } | ||
192 | |||
160 | /** | 193 | /** |
161 | * snd_hda_codec_read - send a command and get the response | 194 | * snd_hda_codec_read - send a command and get the response |
162 | * @codec: the HDA codec | 195 | * @codec: the HDA codec |
@@ -173,22 +206,18 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, | |||
173 | int direct, | 206 | int direct, |
174 | unsigned int verb, unsigned int parm) | 207 | unsigned int verb, unsigned int parm) |
175 | { | 208 | { |
176 | struct hda_bus *bus = codec->bus; | 209 | unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm); |
177 | unsigned int res; | 210 | unsigned int res; |
178 | 211 | codec_exec_verb(codec, cmd, &res); | |
179 | res = make_codec_cmd(codec, nid, direct, verb, parm); | ||
180 | snd_hda_power_up(codec); | ||
181 | mutex_lock(&bus->cmd_mutex); | ||
182 | if (!bus->ops.command(bus, res)) | ||
183 | res = bus->ops.get_response(bus); | ||
184 | else | ||
185 | res = (unsigned int)-1; | ||
186 | mutex_unlock(&bus->cmd_mutex); | ||
187 | snd_hda_power_down(codec); | ||
188 | return res; | 212 | return res; |
189 | } | 213 | } |
190 | EXPORT_SYMBOL_HDA(snd_hda_codec_read); | 214 | EXPORT_SYMBOL_HDA(snd_hda_codec_read); |
191 | 215 | ||
216 | /* Define the below to send and receive verbs synchronously. | ||
217 | * If you often get any codec communication errors, this is worth to try. | ||
218 | */ | ||
219 | /* #define SND_HDA_SUPPORT_SYNC_WRITE */ | ||
220 | |||
192 | /** | 221 | /** |
193 | * snd_hda_codec_write - send a single command without waiting for response | 222 | * snd_hda_codec_write - send a single command without waiting for response |
194 | * @codec: the HDA codec | 223 | * @codec: the HDA codec |
@@ -204,17 +233,13 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_read); | |||
204 | int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, | 233 | int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, |
205 | unsigned int verb, unsigned int parm) | 234 | unsigned int verb, unsigned int parm) |
206 | { | 235 | { |
207 | struct hda_bus *bus = codec->bus; | 236 | unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm); |
237 | #ifdef SND_HDA_SUPPORT_SYNC_WRITE | ||
208 | unsigned int res; | 238 | unsigned int res; |
209 | int err; | 239 | return codec_exec_verb(codec, cmd, &res); |
210 | 240 | #else | |
211 | res = make_codec_cmd(codec, nid, direct, verb, parm); | 241 | return codec_exec_verb(codec, cmd, NULL); |
212 | snd_hda_power_up(codec); | 242 | #endif |
213 | mutex_lock(&bus->cmd_mutex); | ||
214 | err = bus->ops.command(bus, res); | ||
215 | mutex_unlock(&bus->cmd_mutex); | ||
216 | snd_hda_power_down(codec); | ||
217 | return err; | ||
218 | } | 243 | } |
219 | EXPORT_SYMBOL_HDA(snd_hda_codec_write); | 244 | EXPORT_SYMBOL_HDA(snd_hda_codec_write); |
220 | 245 | ||
@@ -613,7 +638,10 @@ static int get_codec_name(struct hda_codec *codec) | |||
613 | const struct hda_vendor_id *c; | 638 | const struct hda_vendor_id *c; |
614 | const char *vendor = NULL; | 639 | const char *vendor = NULL; |
615 | u16 vendor_id = codec->vendor_id >> 16; | 640 | u16 vendor_id = codec->vendor_id >> 16; |
616 | char tmp[16], name[32]; | 641 | char tmp[16]; |
642 | |||
643 | if (codec->vendor_name) | ||
644 | goto get_chip_name; | ||
617 | 645 | ||
618 | for (c = hda_vendor_ids; c->id; c++) { | 646 | for (c = hda_vendor_ids; c->id; c++) { |
619 | if (c->id == vendor_id) { | 647 | if (c->id == vendor_id) { |
@@ -625,14 +653,21 @@ static int get_codec_name(struct hda_codec *codec) | |||
625 | sprintf(tmp, "Generic %04x", vendor_id); | 653 | sprintf(tmp, "Generic %04x", vendor_id); |
626 | vendor = tmp; | 654 | vendor = tmp; |
627 | } | 655 | } |
656 | codec->vendor_name = kstrdup(vendor, GFP_KERNEL); | ||
657 | if (!codec->vendor_name) | ||
658 | return -ENOMEM; | ||
659 | |||
660 | get_chip_name: | ||
661 | if (codec->chip_name) | ||
662 | return 0; | ||
663 | |||
628 | if (codec->preset && codec->preset->name) | 664 | if (codec->preset && codec->preset->name) |
629 | snprintf(name, sizeof(name), "%s %s", vendor, | 665 | codec->chip_name = kstrdup(codec->preset->name, GFP_KERNEL); |
630 | codec->preset->name); | 666 | else { |
631 | else | 667 | sprintf(tmp, "ID %x", codec->vendor_id & 0xffff); |
632 | snprintf(name, sizeof(name), "%s ID %x", vendor, | 668 | codec->chip_name = kstrdup(tmp, GFP_KERNEL); |
633 | codec->vendor_id & 0xffff); | 669 | } |
634 | codec->name = kstrdup(name, GFP_KERNEL); | 670 | if (!codec->chip_name) |
635 | if (!codec->name) | ||
636 | return -ENOMEM; | 671 | return -ENOMEM; |
637 | return 0; | 672 | return 0; |
638 | } | 673 | } |
@@ -838,7 +873,8 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
838 | module_put(codec->owner); | 873 | module_put(codec->owner); |
839 | free_hda_cache(&codec->amp_cache); | 874 | free_hda_cache(&codec->amp_cache); |
840 | free_hda_cache(&codec->cmd_cache); | 875 | free_hda_cache(&codec->cmd_cache); |
841 | kfree(codec->name); | 876 | kfree(codec->vendor_name); |
877 | kfree(codec->chip_name); | ||
842 | kfree(codec->modelname); | 878 | kfree(codec->modelname); |
843 | kfree(codec->wcaps); | 879 | kfree(codec->wcaps); |
844 | kfree(codec); | 880 | kfree(codec); |
@@ -979,15 +1015,16 @@ int snd_hda_codec_configure(struct hda_codec *codec) | |||
979 | int err; | 1015 | int err; |
980 | 1016 | ||
981 | codec->preset = find_codec_preset(codec); | 1017 | codec->preset = find_codec_preset(codec); |
982 | if (!codec->name) { | 1018 | if (!codec->vendor_name || !codec->chip_name) { |
983 | err = get_codec_name(codec); | 1019 | err = get_codec_name(codec); |
984 | if (err < 0) | 1020 | if (err < 0) |
985 | return err; | 1021 | return err; |
986 | } | 1022 | } |
987 | /* audio codec should override the mixer name */ | 1023 | /* audio codec should override the mixer name */ |
988 | if (codec->afg || !*codec->bus->card->mixername) | 1024 | if (codec->afg || !*codec->bus->card->mixername) |
989 | strlcpy(codec->bus->card->mixername, codec->name, | 1025 | snprintf(codec->bus->card->mixername, |
990 | sizeof(codec->bus->card->mixername)); | 1026 | sizeof(codec->bus->card->mixername), |
1027 | "%s %s", codec->vendor_name, codec->chip_name); | ||
991 | 1028 | ||
992 | if (is_generic_config(codec)) { | 1029 | if (is_generic_config(codec)) { |
993 | err = snd_hda_parse_generic_codec(codec); | 1030 | err = snd_hda_parse_generic_codec(codec); |
@@ -1055,6 +1092,8 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream); | |||
1055 | /* FIXME: more better hash key? */ | 1092 | /* FIXME: more better hash key? */ |
1056 | #define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) | 1093 | #define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) |
1057 | #define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24)) | 1094 | #define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24)) |
1095 | #define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24)) | ||
1096 | #define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24)) | ||
1058 | #define INFO_AMP_CAPS (1<<0) | 1097 | #define INFO_AMP_CAPS (1<<0) |
1059 | #define INFO_AMP_VOL(ch) (1 << (1 + (ch))) | 1098 | #define INFO_AMP_VOL(ch) (1 << (1 + (ch))) |
1060 | 1099 | ||
@@ -1145,19 +1184,32 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | |||
1145 | } | 1184 | } |
1146 | EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); | 1185 | EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); |
1147 | 1186 | ||
1148 | u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) | 1187 | static unsigned int |
1188 | query_caps_hash(struct hda_codec *codec, hda_nid_t nid, u32 key, | ||
1189 | unsigned int (*func)(struct hda_codec *, hda_nid_t)) | ||
1149 | { | 1190 | { |
1150 | struct hda_amp_info *info; | 1191 | struct hda_amp_info *info; |
1151 | 1192 | ||
1152 | info = get_alloc_amp_hash(codec, HDA_HASH_PINCAP_KEY(nid)); | 1193 | info = get_alloc_amp_hash(codec, key); |
1153 | if (!info) | 1194 | if (!info) |
1154 | return 0; | 1195 | return 0; |
1155 | if (!info->head.val) { | 1196 | if (!info->head.val) { |
1156 | info->amp_caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | ||
1157 | info->head.val |= INFO_AMP_CAPS; | 1197 | info->head.val |= INFO_AMP_CAPS; |
1198 | info->amp_caps = func(codec, nid); | ||
1158 | } | 1199 | } |
1159 | return info->amp_caps; | 1200 | return info->amp_caps; |
1160 | } | 1201 | } |
1202 | |||
1203 | static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid) | ||
1204 | { | ||
1205 | return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | ||
1206 | } | ||
1207 | |||
1208 | u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) | ||
1209 | { | ||
1210 | return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid), | ||
1211 | read_pin_cap); | ||
1212 | } | ||
1161 | EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); | 1213 | EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); |
1162 | 1214 | ||
1163 | /* | 1215 | /* |
@@ -1432,6 +1484,8 @@ _snd_hda_find_mixer_ctl(struct hda_codec *codec, | |||
1432 | memset(&id, 0, sizeof(id)); | 1484 | memset(&id, 0, sizeof(id)); |
1433 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 1485 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
1434 | id.index = idx; | 1486 | id.index = idx; |
1487 | if (snd_BUG_ON(strlen(name) >= sizeof(id.name))) | ||
1488 | return NULL; | ||
1435 | strcpy(id.name, name); | 1489 | strcpy(id.name, name); |
1436 | return snd_ctl_find_id(codec->bus->card, &id); | 1490 | return snd_ctl_find_id(codec->bus->card, &id); |
1437 | } | 1491 | } |
@@ -2242,28 +2296,22 @@ EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls); | |||
2242 | int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, | 2296 | int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, |
2243 | int direct, unsigned int verb, unsigned int parm) | 2297 | int direct, unsigned int verb, unsigned int parm) |
2244 | { | 2298 | { |
2245 | struct hda_bus *bus = codec->bus; | 2299 | int err = snd_hda_codec_write(codec, nid, direct, verb, parm); |
2246 | unsigned int res; | 2300 | struct hda_cache_head *c; |
2247 | int err; | 2301 | u32 key; |
2248 | 2302 | ||
2249 | res = make_codec_cmd(codec, nid, direct, verb, parm); | 2303 | if (err < 0) |
2250 | snd_hda_power_up(codec); | 2304 | return err; |
2251 | mutex_lock(&bus->cmd_mutex); | 2305 | /* parm may contain the verb stuff for get/set amp */ |
2252 | err = bus->ops.command(bus, res); | 2306 | verb = verb | (parm >> 8); |
2253 | if (!err) { | 2307 | parm &= 0xff; |
2254 | struct hda_cache_head *c; | 2308 | key = build_cmd_cache_key(nid, verb); |
2255 | u32 key; | 2309 | mutex_lock(&codec->bus->cmd_mutex); |
2256 | /* parm may contain the verb stuff for get/set amp */ | 2310 | c = get_alloc_hash(&codec->cmd_cache, key); |
2257 | verb = verb | (parm >> 8); | 2311 | if (c) |
2258 | parm &= 0xff; | 2312 | c->val = parm; |
2259 | key = build_cmd_cache_key(nid, verb); | 2313 | mutex_unlock(&codec->bus->cmd_mutex); |
2260 | c = get_alloc_hash(&codec->cmd_cache, key); | 2314 | return 0; |
2261 | if (c) | ||
2262 | c->val = parm; | ||
2263 | } | ||
2264 | mutex_unlock(&bus->cmd_mutex); | ||
2265 | snd_hda_power_down(codec); | ||
2266 | return err; | ||
2267 | } | 2315 | } |
2268 | EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache); | 2316 | EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache); |
2269 | 2317 | ||
@@ -2321,7 +2369,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
2321 | if (wcaps & AC_WCAP_POWER) { | 2369 | if (wcaps & AC_WCAP_POWER) { |
2322 | unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> | 2370 | unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> |
2323 | AC_WCAP_TYPE_SHIFT; | 2371 | AC_WCAP_TYPE_SHIFT; |
2324 | if (wid_type == AC_WID_PIN) { | 2372 | if (power_state == AC_PWRST_D3 && |
2373 | wid_type == AC_WID_PIN) { | ||
2325 | unsigned int pincap; | 2374 | unsigned int pincap; |
2326 | /* | 2375 | /* |
2327 | * don't power down the widget if it controls | 2376 | * don't power down the widget if it controls |
@@ -2333,7 +2382,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
2333 | nid, 0, | 2382 | nid, 0, |
2334 | AC_VERB_GET_EAPD_BTLENABLE, 0); | 2383 | AC_VERB_GET_EAPD_BTLENABLE, 0); |
2335 | eapd &= 0x02; | 2384 | eapd &= 0x02; |
2336 | if (power_state == AC_PWRST_D3 && eapd) | 2385 | if (eapd) |
2337 | continue; | 2386 | continue; |
2338 | } | 2387 | } |
2339 | } | 2388 | } |
@@ -2544,6 +2593,41 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
2544 | } | 2593 | } |
2545 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); | 2594 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); |
2546 | 2595 | ||
2596 | static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid) | ||
2597 | { | ||
2598 | unsigned int val = 0; | ||
2599 | if (nid != codec->afg && | ||
2600 | (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) | ||
2601 | val = snd_hda_param_read(codec, nid, AC_PAR_PCM); | ||
2602 | if (!val || val == -1) | ||
2603 | val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); | ||
2604 | if (!val || val == -1) | ||
2605 | return 0; | ||
2606 | return val; | ||
2607 | } | ||
2608 | |||
2609 | static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid) | ||
2610 | { | ||
2611 | return query_caps_hash(codec, nid, HDA_HASH_PARPCM_KEY(nid), | ||
2612 | get_pcm_param); | ||
2613 | } | ||
2614 | |||
2615 | static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid) | ||
2616 | { | ||
2617 | unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | ||
2618 | if (!streams || streams == -1) | ||
2619 | streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); | ||
2620 | if (!streams || streams == -1) | ||
2621 | return 0; | ||
2622 | return streams; | ||
2623 | } | ||
2624 | |||
2625 | static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid) | ||
2626 | { | ||
2627 | return query_caps_hash(codec, nid, HDA_HASH_PARSTR_KEY(nid), | ||
2628 | get_stream_param); | ||
2629 | } | ||
2630 | |||
2547 | /** | 2631 | /** |
2548 | * snd_hda_query_supported_pcm - query the supported PCM rates and formats | 2632 | * snd_hda_query_supported_pcm - query the supported PCM rates and formats |
2549 | * @codec: the HDA codec | 2633 | * @codec: the HDA codec |
@@ -2562,15 +2646,8 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
2562 | { | 2646 | { |
2563 | unsigned int i, val, wcaps; | 2647 | unsigned int i, val, wcaps; |
2564 | 2648 | ||
2565 | val = 0; | ||
2566 | wcaps = get_wcaps(codec, nid); | 2649 | wcaps = get_wcaps(codec, nid); |
2567 | if (nid != codec->afg && (wcaps & AC_WCAP_FORMAT_OVRD)) { | 2650 | val = query_pcm_param(codec, nid); |
2568 | val = snd_hda_param_read(codec, nid, AC_PAR_PCM); | ||
2569 | if (val == -1) | ||
2570 | return -EIO; | ||
2571 | } | ||
2572 | if (!val) | ||
2573 | val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); | ||
2574 | 2651 | ||
2575 | if (ratesp) { | 2652 | if (ratesp) { |
2576 | u32 rates = 0; | 2653 | u32 rates = 0; |
@@ -2592,15 +2669,9 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
2592 | u64 formats = 0; | 2669 | u64 formats = 0; |
2593 | unsigned int streams, bps; | 2670 | unsigned int streams, bps; |
2594 | 2671 | ||
2595 | streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | 2672 | streams = query_stream_param(codec, nid); |
2596 | if (streams == -1) | 2673 | if (!streams) |
2597 | return -EIO; | 2674 | return -EIO; |
2598 | if (!streams) { | ||
2599 | streams = snd_hda_param_read(codec, codec->afg, | ||
2600 | AC_PAR_STREAM); | ||
2601 | if (streams == -1) | ||
2602 | return -EIO; | ||
2603 | } | ||
2604 | 2675 | ||
2605 | bps = 0; | 2676 | bps = 0; |
2606 | if (streams & AC_SUPFMT_PCM) { | 2677 | if (streams & AC_SUPFMT_PCM) { |
@@ -2674,17 +2745,9 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, | |||
2674 | int i; | 2745 | int i; |
2675 | unsigned int val = 0, rate, stream; | 2746 | unsigned int val = 0, rate, stream; |
2676 | 2747 | ||
2677 | if (nid != codec->afg && | 2748 | val = query_pcm_param(codec, nid); |
2678 | (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) { | 2749 | if (!val) |
2679 | val = snd_hda_param_read(codec, nid, AC_PAR_PCM); | 2750 | return 0; |
2680 | if (val == -1) | ||
2681 | return 0; | ||
2682 | } | ||
2683 | if (!val) { | ||
2684 | val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); | ||
2685 | if (val == -1) | ||
2686 | return 0; | ||
2687 | } | ||
2688 | 2751 | ||
2689 | rate = format & 0xff00; | 2752 | rate = format & 0xff00; |
2690 | for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) | 2753 | for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) |
@@ -2696,12 +2759,8 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, | |||
2696 | if (i >= AC_PAR_PCM_RATE_BITS) | 2759 | if (i >= AC_PAR_PCM_RATE_BITS) |
2697 | return 0; | 2760 | return 0; |
2698 | 2761 | ||
2699 | stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | 2762 | stream = query_stream_param(codec, nid); |
2700 | if (stream == -1) | 2763 | if (!stream) |
2701 | return 0; | ||
2702 | if (!stream && nid != codec->afg) | ||
2703 | stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); | ||
2704 | if (!stream || stream == -1) | ||
2705 | return 0; | 2764 | return 0; |
2706 | 2765 | ||
2707 | if (stream & AC_SUPFMT_PCM) { | 2766 | if (stream & AC_SUPFMT_PCM) { |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 2fdecf4b0eb6..c5bd40f77bb9 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -623,6 +623,7 @@ struct hda_bus { | |||
623 | /* misc op flags */ | 623 | /* misc op flags */ |
624 | unsigned int needs_damn_long_delay :1; | 624 | unsigned int needs_damn_long_delay :1; |
625 | unsigned int shutdown :1; /* being unloaded */ | 625 | unsigned int shutdown :1; /* being unloaded */ |
626 | unsigned int rirb_error:1; /* error in codec communication */ | ||
626 | }; | 627 | }; |
627 | 628 | ||
628 | /* | 629 | /* |
@@ -747,7 +748,8 @@ struct hda_codec { | |||
747 | /* detected preset */ | 748 | /* detected preset */ |
748 | const struct hda_codec_preset *preset; | 749 | const struct hda_codec_preset *preset; |
749 | struct module *owner; | 750 | struct module *owner; |
750 | const char *name; /* codec name */ | 751 | const char *vendor_name; /* codec vendor name */ |
752 | const char *chip_name; /* codec chip name */ | ||
751 | const char *modelname; /* model name for preset */ | 753 | const char *modelname; /* model name for preset */ |
752 | 754 | ||
753 | /* set by patch */ | 755 | /* set by patch */ |
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 1c57505c2874..6812fbe80fa4 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
@@ -242,7 +242,8 @@ CODEC_INFO_SHOW(subsystem_id); | |||
242 | CODEC_INFO_SHOW(revision_id); | 242 | CODEC_INFO_SHOW(revision_id); |
243 | CODEC_INFO_SHOW(afg); | 243 | CODEC_INFO_SHOW(afg); |
244 | CODEC_INFO_SHOW(mfg); | 244 | CODEC_INFO_SHOW(mfg); |
245 | CODEC_INFO_STR_SHOW(name); | 245 | CODEC_INFO_STR_SHOW(vendor_name); |
246 | CODEC_INFO_STR_SHOW(chip_name); | ||
246 | CODEC_INFO_STR_SHOW(modelname); | 247 | CODEC_INFO_STR_SHOW(modelname); |
247 | 248 | ||
248 | #define CODEC_INFO_STORE(type) \ | 249 | #define CODEC_INFO_STORE(type) \ |
@@ -275,7 +276,8 @@ static ssize_t type##_store(struct device *dev, \ | |||
275 | CODEC_INFO_STORE(vendor_id); | 276 | CODEC_INFO_STORE(vendor_id); |
276 | CODEC_INFO_STORE(subsystem_id); | 277 | CODEC_INFO_STORE(subsystem_id); |
277 | CODEC_INFO_STORE(revision_id); | 278 | CODEC_INFO_STORE(revision_id); |
278 | CODEC_INFO_STR_STORE(name); | 279 | CODEC_INFO_STR_STORE(vendor_name); |
280 | CODEC_INFO_STR_STORE(chip_name); | ||
279 | CODEC_INFO_STR_STORE(modelname); | 281 | CODEC_INFO_STR_STORE(modelname); |
280 | 282 | ||
281 | #define CODEC_ACTION_STORE(type) \ | 283 | #define CODEC_ACTION_STORE(type) \ |
@@ -499,7 +501,8 @@ static struct device_attribute codec_attrs[] = { | |||
499 | CODEC_ATTR_RW(revision_id), | 501 | CODEC_ATTR_RW(revision_id), |
500 | CODEC_ATTR_RO(afg), | 502 | CODEC_ATTR_RO(afg), |
501 | CODEC_ATTR_RO(mfg), | 503 | CODEC_ATTR_RO(mfg), |
502 | CODEC_ATTR_RW(name), | 504 | CODEC_ATTR_RW(vendor_name), |
505 | CODEC_ATTR_RW(chip_name), | ||
503 | CODEC_ATTR_RW(modelname), | 506 | CODEC_ATTR_RW(modelname), |
504 | CODEC_ATTR_RW(init_verbs), | 507 | CODEC_ATTR_RW(init_verbs), |
505 | CODEC_ATTR_RW(hints), | 508 | CODEC_ATTR_RW(hints), |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 3128e1a6bc65..f63bc6510e0f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -128,21 +128,33 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
128 | "{ULI, M5461}}"); | 128 | "{ULI, M5461}}"); |
129 | MODULE_DESCRIPTION("Intel HDA driver"); | 129 | MODULE_DESCRIPTION("Intel HDA driver"); |
130 | 130 | ||
131 | #ifdef CONFIG_SND_VERBOSE_PRINTK | ||
132 | #define SFX /* nop */ | ||
133 | #else | ||
131 | #define SFX "hda-intel: " | 134 | #define SFX "hda-intel: " |
132 | 135 | #endif | |
133 | 136 | ||
134 | /* | 137 | /* |
135 | * registers | 138 | * registers |
136 | */ | 139 | */ |
137 | #define ICH6_REG_GCAP 0x00 | 140 | #define ICH6_REG_GCAP 0x00 |
141 | #define ICH6_GCAP_64OK (1 << 0) /* 64bit address support */ | ||
142 | #define ICH6_GCAP_NSDO (3 << 1) /* # of serial data out signals */ | ||
143 | #define ICH6_GCAP_BSS (31 << 3) /* # of bidirectional streams */ | ||
144 | #define ICH6_GCAP_ISS (15 << 8) /* # of input streams */ | ||
145 | #define ICH6_GCAP_OSS (15 << 12) /* # of output streams */ | ||
138 | #define ICH6_REG_VMIN 0x02 | 146 | #define ICH6_REG_VMIN 0x02 |
139 | #define ICH6_REG_VMAJ 0x03 | 147 | #define ICH6_REG_VMAJ 0x03 |
140 | #define ICH6_REG_OUTPAY 0x04 | 148 | #define ICH6_REG_OUTPAY 0x04 |
141 | #define ICH6_REG_INPAY 0x06 | 149 | #define ICH6_REG_INPAY 0x06 |
142 | #define ICH6_REG_GCTL 0x08 | 150 | #define ICH6_REG_GCTL 0x08 |
151 | #define ICH6_GCTL_RESET (1 << 1) /* controller reset */ | ||
152 | #define ICH6_GCTL_FCNTRL (1 << 1) /* flush control */ | ||
153 | #define ICH6_GCTL_UNSOL (1 << 8) /* accept unsol. response enable */ | ||
143 | #define ICH6_REG_WAKEEN 0x0c | 154 | #define ICH6_REG_WAKEEN 0x0c |
144 | #define ICH6_REG_STATESTS 0x0e | 155 | #define ICH6_REG_STATESTS 0x0e |
145 | #define ICH6_REG_GSTS 0x10 | 156 | #define ICH6_REG_GSTS 0x10 |
157 | #define ICH6_GSTS_FSTS (1 << 1) /* flush status */ | ||
146 | #define ICH6_REG_INTCTL 0x20 | 158 | #define ICH6_REG_INTCTL 0x20 |
147 | #define ICH6_REG_INTSTS 0x24 | 159 | #define ICH6_REG_INTSTS 0x24 |
148 | #define ICH6_REG_WALCLK 0x30 | 160 | #define ICH6_REG_WALCLK 0x30 |
@@ -150,17 +162,27 @@ MODULE_DESCRIPTION("Intel HDA driver"); | |||
150 | #define ICH6_REG_CORBLBASE 0x40 | 162 | #define ICH6_REG_CORBLBASE 0x40 |
151 | #define ICH6_REG_CORBUBASE 0x44 | 163 | #define ICH6_REG_CORBUBASE 0x44 |
152 | #define ICH6_REG_CORBWP 0x48 | 164 | #define ICH6_REG_CORBWP 0x48 |
153 | #define ICH6_REG_CORBRP 0x4A | 165 | #define ICH6_REG_CORBRP 0x4a |
166 | #define ICH6_CORBRP_RST (1 << 15) /* read pointer reset */ | ||
154 | #define ICH6_REG_CORBCTL 0x4c | 167 | #define ICH6_REG_CORBCTL 0x4c |
168 | #define ICH6_CORBCTL_RUN (1 << 1) /* enable DMA */ | ||
169 | #define ICH6_CORBCTL_CMEIE (1 << 0) /* enable memory error irq */ | ||
155 | #define ICH6_REG_CORBSTS 0x4d | 170 | #define ICH6_REG_CORBSTS 0x4d |
171 | #define ICH6_CORBSTS_CMEI (1 << 0) /* memory error indication */ | ||
156 | #define ICH6_REG_CORBSIZE 0x4e | 172 | #define ICH6_REG_CORBSIZE 0x4e |
157 | 173 | ||
158 | #define ICH6_REG_RIRBLBASE 0x50 | 174 | #define ICH6_REG_RIRBLBASE 0x50 |
159 | #define ICH6_REG_RIRBUBASE 0x54 | 175 | #define ICH6_REG_RIRBUBASE 0x54 |
160 | #define ICH6_REG_RIRBWP 0x58 | 176 | #define ICH6_REG_RIRBWP 0x58 |
177 | #define ICH6_RIRBWP_RST (1 << 15) /* write pointer reset */ | ||
161 | #define ICH6_REG_RINTCNT 0x5a | 178 | #define ICH6_REG_RINTCNT 0x5a |
162 | #define ICH6_REG_RIRBCTL 0x5c | 179 | #define ICH6_REG_RIRBCTL 0x5c |
180 | #define ICH6_RBCTL_IRQ_EN (1 << 0) /* enable IRQ */ | ||
181 | #define ICH6_RBCTL_DMA_EN (1 << 1) /* enable DMA */ | ||
182 | #define ICH6_RBCTL_OVERRUN_EN (1 << 2) /* enable overrun irq */ | ||
163 | #define ICH6_REG_RIRBSTS 0x5d | 183 | #define ICH6_REG_RIRBSTS 0x5d |
184 | #define ICH6_RBSTS_IRQ (1 << 0) /* response irq */ | ||
185 | #define ICH6_RBSTS_OVERRUN (1 << 2) /* overrun irq */ | ||
164 | #define ICH6_REG_RIRBSIZE 0x5e | 186 | #define ICH6_REG_RIRBSIZE 0x5e |
165 | 187 | ||
166 | #define ICH6_REG_IC 0x60 | 188 | #define ICH6_REG_IC 0x60 |
@@ -257,16 +279,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
257 | #define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */ | 279 | #define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */ |
258 | #define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */ | 280 | #define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */ |
259 | 281 | ||
260 | /* GCTL unsolicited response enable bit */ | ||
261 | #define ICH6_GCTL_UREN (1<<8) | ||
262 | |||
263 | /* GCTL reset bit */ | ||
264 | #define ICH6_GCTL_RESET (1<<0) | ||
265 | |||
266 | /* CORB/RIRB control, read/write pointer */ | ||
267 | #define ICH6_RBCTL_DMA_EN 0x02 /* enable DMA */ | ||
268 | #define ICH6_RBCTL_IRQ_EN 0x01 /* enable IRQ */ | ||
269 | #define ICH6_RBRWP_CLR 0x8000 /* read/write pointer clear */ | ||
270 | /* below are so far hardcoded - should read registers in future */ | 282 | /* below are so far hardcoded - should read registers in future */ |
271 | #define ICH6_MAX_CORB_ENTRIES 256 | 283 | #define ICH6_MAX_CORB_ENTRIES 256 |
272 | #define ICH6_MAX_RIRB_ENTRIES 256 | 284 | #define ICH6_MAX_RIRB_ENTRIES 256 |
@@ -512,25 +524,25 @@ static void azx_init_cmd_io(struct azx *chip) | |||
512 | /* set the corb write pointer to 0 */ | 524 | /* set the corb write pointer to 0 */ |
513 | azx_writew(chip, CORBWP, 0); | 525 | azx_writew(chip, CORBWP, 0); |
514 | /* reset the corb hw read pointer */ | 526 | /* reset the corb hw read pointer */ |
515 | azx_writew(chip, CORBRP, ICH6_RBRWP_CLR); | 527 | azx_writew(chip, CORBRP, ICH6_CORBRP_RST); |
516 | /* enable corb dma */ | 528 | /* enable corb dma */ |
517 | azx_writeb(chip, CORBCTL, ICH6_RBCTL_DMA_EN); | 529 | azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN); |
518 | 530 | ||
519 | /* RIRB set up */ | 531 | /* RIRB set up */ |
520 | chip->rirb.addr = chip->rb.addr + 2048; | 532 | chip->rirb.addr = chip->rb.addr + 2048; |
521 | chip->rirb.buf = (u32 *)(chip->rb.area + 2048); | 533 | chip->rirb.buf = (u32 *)(chip->rb.area + 2048); |
534 | chip->rirb.wp = chip->rirb.rp = chip->rirb.cmds = 0; | ||
522 | azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr); | 535 | azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr); |
523 | azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr)); | 536 | azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr)); |
524 | 537 | ||
525 | /* set the rirb size to 256 entries (ULI requires explicitly) */ | 538 | /* set the rirb size to 256 entries (ULI requires explicitly) */ |
526 | azx_writeb(chip, RIRBSIZE, 0x02); | 539 | azx_writeb(chip, RIRBSIZE, 0x02); |
527 | /* reset the rirb hw write pointer */ | 540 | /* reset the rirb hw write pointer */ |
528 | azx_writew(chip, RIRBWP, ICH6_RBRWP_CLR); | 541 | azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST); |
529 | /* set N=1, get RIRB response interrupt for new entry */ | 542 | /* set N=1, get RIRB response interrupt for new entry */ |
530 | azx_writew(chip, RINTCNT, 1); | 543 | azx_writew(chip, RINTCNT, 1); |
531 | /* enable rirb dma and response irq */ | 544 | /* enable rirb dma and response irq */ |
532 | azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); | 545 | azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); |
533 | chip->rirb.rp = chip->rirb.cmds = 0; | ||
534 | } | 546 | } |
535 | 547 | ||
536 | static void azx_free_cmd_io(struct azx *chip) | 548 | static void azx_free_cmd_io(struct azx *chip) |
@@ -606,6 +618,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) | |||
606 | } | 618 | } |
607 | if (!chip->rirb.cmds) { | 619 | if (!chip->rirb.cmds) { |
608 | smp_rmb(); | 620 | smp_rmb(); |
621 | bus->rirb_error = 0; | ||
609 | return chip->rirb.res; /* the last value */ | 622 | return chip->rirb.res; /* the last value */ |
610 | } | 623 | } |
611 | if (time_after(jiffies, timeout)) | 624 | if (time_after(jiffies, timeout)) |
@@ -619,19 +632,21 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) | |||
619 | } | 632 | } |
620 | 633 | ||
621 | if (chip->msi) { | 634 | if (chip->msi) { |
622 | snd_printk(KERN_WARNING "hda_intel: No response from codec, " | 635 | snd_printk(KERN_WARNING SFX "No response from codec, " |
623 | "disabling MSI: last cmd=0x%08x\n", chip->last_cmd); | 636 | "disabling MSI: last cmd=0x%08x\n", chip->last_cmd); |
624 | free_irq(chip->irq, chip); | 637 | free_irq(chip->irq, chip); |
625 | chip->irq = -1; | 638 | chip->irq = -1; |
626 | pci_disable_msi(chip->pci); | 639 | pci_disable_msi(chip->pci); |
627 | chip->msi = 0; | 640 | chip->msi = 0; |
628 | if (azx_acquire_irq(chip, 1) < 0) | 641 | if (azx_acquire_irq(chip, 1) < 0) { |
642 | bus->rirb_error = 1; | ||
629 | return -1; | 643 | return -1; |
644 | } | ||
630 | goto again; | 645 | goto again; |
631 | } | 646 | } |
632 | 647 | ||
633 | if (!chip->polling_mode) { | 648 | if (!chip->polling_mode) { |
634 | snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " | 649 | snd_printk(KERN_WARNING SFX "azx_get_response timeout, " |
635 | "switching to polling mode: last cmd=0x%08x\n", | 650 | "switching to polling mode: last cmd=0x%08x\n", |
636 | chip->last_cmd); | 651 | chip->last_cmd); |
637 | chip->polling_mode = 1; | 652 | chip->polling_mode = 1; |
@@ -646,14 +661,14 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) | |||
646 | return -1; | 661 | return -1; |
647 | } | 662 | } |
648 | 663 | ||
649 | snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " | 664 | snd_printk(KERN_ERR SFX "azx_get_response timeout (ERROR): " |
650 | "switching to single_cmd mode: last cmd=0x%08x\n", | 665 | "last cmd=0x%08x\n", chip->last_cmd); |
651 | chip->last_cmd); | 666 | /* re-initialize CORB/RIRB */ |
652 | chip->rirb.rp = azx_readb(chip, RIRBWP); | 667 | spin_lock_irq(&chip->reg_lock); |
653 | chip->rirb.cmds = 0; | 668 | bus->rirb_error = 1; |
654 | /* switch to single_cmd mode */ | ||
655 | chip->single_cmd = 1; | ||
656 | azx_free_cmd_io(chip); | 669 | azx_free_cmd_io(chip); |
670 | azx_init_cmd_io(chip); | ||
671 | spin_unlock_irq(&chip->reg_lock); | ||
657 | return -1; | 672 | return -1; |
658 | } | 673 | } |
659 | 674 | ||
@@ -667,6 +682,27 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) | |||
667 | * I left the codes, however, for debugging/testing purposes. | 682 | * I left the codes, however, for debugging/testing purposes. |
668 | */ | 683 | */ |
669 | 684 | ||
685 | /* receive a response */ | ||
686 | static int azx_single_wait_for_response(struct azx *chip) | ||
687 | { | ||
688 | int timeout = 50; | ||
689 | |||
690 | while (timeout--) { | ||
691 | /* check IRV busy bit */ | ||
692 | if (azx_readw(chip, IRS) & ICH6_IRS_VALID) { | ||
693 | /* reuse rirb.res as the response return value */ | ||
694 | chip->rirb.res = azx_readl(chip, IR); | ||
695 | return 0; | ||
696 | } | ||
697 | udelay(1); | ||
698 | } | ||
699 | if (printk_ratelimit()) | ||
700 | snd_printd(SFX "get_response timeout: IRS=0x%x\n", | ||
701 | azx_readw(chip, IRS)); | ||
702 | chip->rirb.res = -1; | ||
703 | return -EIO; | ||
704 | } | ||
705 | |||
670 | /* send a command */ | 706 | /* send a command */ |
671 | static int azx_single_send_cmd(struct hda_bus *bus, u32 val) | 707 | static int azx_single_send_cmd(struct hda_bus *bus, u32 val) |
672 | { | 708 | { |
@@ -682,7 +718,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val) | |||
682 | azx_writel(chip, IC, val); | 718 | azx_writel(chip, IC, val); |
683 | azx_writew(chip, IRS, azx_readw(chip, IRS) | | 719 | azx_writew(chip, IRS, azx_readw(chip, IRS) | |
684 | ICH6_IRS_BUSY); | 720 | ICH6_IRS_BUSY); |
685 | return 0; | 721 | return azx_single_wait_for_response(chip); |
686 | } | 722 | } |
687 | udelay(1); | 723 | udelay(1); |
688 | } | 724 | } |
@@ -696,18 +732,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val) | |||
696 | static unsigned int azx_single_get_response(struct hda_bus *bus) | 732 | static unsigned int azx_single_get_response(struct hda_bus *bus) |
697 | { | 733 | { |
698 | struct azx *chip = bus->private_data; | 734 | struct azx *chip = bus->private_data; |
699 | int timeout = 50; | 735 | return chip->rirb.res; |
700 | |||
701 | while (timeout--) { | ||
702 | /* check IRV busy bit */ | ||
703 | if (azx_readw(chip, IRS) & ICH6_IRS_VALID) | ||
704 | return azx_readl(chip, IR); | ||
705 | udelay(1); | ||
706 | } | ||
707 | if (printk_ratelimit()) | ||
708 | snd_printd(SFX "get_response timeout: IRS=0x%x\n", | ||
709 | azx_readw(chip, IRS)); | ||
710 | return (unsigned int)-1; | ||
711 | } | 736 | } |
712 | 737 | ||
713 | /* | 738 | /* |
@@ -775,17 +800,17 @@ static int azx_reset(struct azx *chip) | |||
775 | 800 | ||
776 | /* check to see if controller is ready */ | 801 | /* check to see if controller is ready */ |
777 | if (!azx_readb(chip, GCTL)) { | 802 | if (!azx_readb(chip, GCTL)) { |
778 | snd_printd("azx_reset: controller not ready!\n"); | 803 | snd_printd(SFX "azx_reset: controller not ready!\n"); |
779 | return -EBUSY; | 804 | return -EBUSY; |
780 | } | 805 | } |
781 | 806 | ||
782 | /* Accept unsolicited responses */ | 807 | /* Accept unsolicited responses */ |
783 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UREN); | 808 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UNSOL); |
784 | 809 | ||
785 | /* detect codecs */ | 810 | /* detect codecs */ |
786 | if (!chip->codec_mask) { | 811 | if (!chip->codec_mask) { |
787 | chip->codec_mask = azx_readw(chip, STATESTS); | 812 | chip->codec_mask = azx_readw(chip, STATESTS); |
788 | snd_printdd("codec_mask = 0x%x\n", chip->codec_mask); | 813 | snd_printdd(SFX "codec_mask = 0x%x\n", chip->codec_mask); |
789 | } | 814 | } |
790 | 815 | ||
791 | return 0; | 816 | return 0; |
@@ -895,8 +920,7 @@ static void azx_init_chip(struct azx *chip) | |||
895 | azx_int_enable(chip); | 920 | azx_int_enable(chip); |
896 | 921 | ||
897 | /* initialize the codec command I/O */ | 922 | /* initialize the codec command I/O */ |
898 | if (!chip->single_cmd) | 923 | azx_init_cmd_io(chip); |
899 | azx_init_cmd_io(chip); | ||
900 | 924 | ||
901 | /* program the position buffer */ | 925 | /* program the position buffer */ |
902 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); | 926 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); |
@@ -953,12 +977,12 @@ static void azx_init_pci(struct azx *chip) | |||
953 | case AZX_DRIVER_SCH: | 977 | case AZX_DRIVER_SCH: |
954 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); | 978 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); |
955 | if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { | 979 | if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { |
956 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, \ | 980 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, |
957 | snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP)); | 981 | snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP)); |
958 | pci_read_config_word(chip->pci, | 982 | pci_read_config_word(chip->pci, |
959 | INTEL_SCH_HDA_DEVC, &snoop); | 983 | INTEL_SCH_HDA_DEVC, &snoop); |
960 | snd_printdd("HDA snoop disabled, enabling ... %s\n",\ | 984 | snd_printdd(SFX "HDA snoop disabled, enabling ... %s\n", |
961 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) \ | 985 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) |
962 | ? "Failed" : "OK"); | 986 | ? "Failed" : "OK"); |
963 | } | 987 | } |
964 | break; | 988 | break; |
@@ -1012,7 +1036,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
1012 | /* clear rirb int */ | 1036 | /* clear rirb int */ |
1013 | status = azx_readb(chip, RIRBSTS); | 1037 | status = azx_readb(chip, RIRBSTS); |
1014 | if (status & RIRB_INT_MASK) { | 1038 | if (status & RIRB_INT_MASK) { |
1015 | if (!chip->single_cmd && (status & RIRB_INT_RESPONSE)) | 1039 | if (status & RIRB_INT_RESPONSE) |
1016 | azx_update_rirb(chip); | 1040 | azx_update_rirb(chip); |
1017 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); | 1041 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); |
1018 | } | 1042 | } |
@@ -1098,7 +1122,7 @@ static int azx_setup_periods(struct azx *chip, | |||
1098 | pos_align; | 1122 | pos_align; |
1099 | pos_adj = frames_to_bytes(runtime, pos_adj); | 1123 | pos_adj = frames_to_bytes(runtime, pos_adj); |
1100 | if (pos_adj >= period_bytes) { | 1124 | if (pos_adj >= period_bytes) { |
1101 | snd_printk(KERN_WARNING "Too big adjustment %d\n", | 1125 | snd_printk(KERN_WARNING SFX "Too big adjustment %d\n", |
1102 | bdl_pos_adj[chip->dev_index]); | 1126 | bdl_pos_adj[chip->dev_index]); |
1103 | pos_adj = 0; | 1127 | pos_adj = 0; |
1104 | } else { | 1128 | } else { |
@@ -1122,7 +1146,7 @@ static int azx_setup_periods(struct azx *chip, | |||
1122 | return 0; | 1146 | return 0; |
1123 | 1147 | ||
1124 | error: | 1148 | error: |
1125 | snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n", | 1149 | snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n", |
1126 | azx_dev->bufsize, period_bytes); | 1150 | azx_dev->bufsize, period_bytes); |
1127 | return -EINVAL; | 1151 | return -EINVAL; |
1128 | } | 1152 | } |
@@ -1215,7 +1239,7 @@ static int probe_codec(struct azx *chip, int addr) | |||
1215 | chip->probing = 0; | 1239 | chip->probing = 0; |
1216 | if (res == -1) | 1240 | if (res == -1) |
1217 | return -EIO; | 1241 | return -EIO; |
1218 | snd_printdd("hda_intel: codec #%d probed OK\n", addr); | 1242 | snd_printdd(SFX "codec #%d probed OK\n", addr); |
1219 | return 0; | 1243 | return 0; |
1220 | } | 1244 | } |
1221 | 1245 | ||
@@ -1270,8 +1294,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, | |||
1270 | /* Some BIOSen give you wrong codec addresses | 1294 | /* Some BIOSen give you wrong codec addresses |
1271 | * that don't exist | 1295 | * that don't exist |
1272 | */ | 1296 | */ |
1273 | snd_printk(KERN_WARNING | 1297 | snd_printk(KERN_WARNING SFX |
1274 | "hda_intel: Codec #%d probe error; " | 1298 | "Codec #%d probe error; " |
1275 | "disabling it...\n", c); | 1299 | "disabling it...\n", c); |
1276 | chip->codec_mask &= ~(1 << c); | 1300 | chip->codec_mask &= ~(1 << c); |
1277 | /* More badly, accessing to a non-existing | 1301 | /* More badly, accessing to a non-existing |
@@ -1487,7 +1511,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1487 | bufsize = snd_pcm_lib_buffer_bytes(substream); | 1511 | bufsize = snd_pcm_lib_buffer_bytes(substream); |
1488 | period_bytes = snd_pcm_lib_period_bytes(substream); | 1512 | period_bytes = snd_pcm_lib_period_bytes(substream); |
1489 | 1513 | ||
1490 | snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", | 1514 | snd_printdd(SFX "azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", |
1491 | bufsize, format_val); | 1515 | bufsize, format_val); |
1492 | 1516 | ||
1493 | if (bufsize != azx_dev->bufsize || | 1517 | if (bufsize != azx_dev->bufsize || |
@@ -1830,7 +1854,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
1830 | &pcm); | 1854 | &pcm); |
1831 | if (err < 0) | 1855 | if (err < 0) |
1832 | return err; | 1856 | return err; |
1833 | strcpy(pcm->name, cpcm->name); | 1857 | strlcpy(pcm->name, cpcm->name, sizeof(pcm->name)); |
1834 | apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); | 1858 | apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); |
1835 | if (apcm == NULL) | 1859 | if (apcm == NULL) |
1836 | return -ENOMEM; | 1860 | return -ENOMEM; |
@@ -2265,14 +2289,14 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2265 | synchronize_irq(chip->irq); | 2289 | synchronize_irq(chip->irq); |
2266 | 2290 | ||
2267 | gcap = azx_readw(chip, GCAP); | 2291 | gcap = azx_readw(chip, GCAP); |
2268 | snd_printdd("chipset global capabilities = 0x%x\n", gcap); | 2292 | snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); |
2269 | 2293 | ||
2270 | /* ATI chips seems buggy about 64bit DMA addresses */ | 2294 | /* ATI chips seems buggy about 64bit DMA addresses */ |
2271 | if (chip->driver_type == AZX_DRIVER_ATI) | 2295 | if (chip->driver_type == AZX_DRIVER_ATI) |
2272 | gcap &= ~0x01; | 2296 | gcap &= ~ICH6_GCAP_64OK; |
2273 | 2297 | ||
2274 | /* allow 64bit DMA address if supported by H/W */ | 2298 | /* allow 64bit DMA address if supported by H/W */ |
2275 | if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 2299 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) |
2276 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); | 2300 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); |
2277 | else { | 2301 | else { |
2278 | pci_set_dma_mask(pci, DMA_BIT_MASK(32)); | 2302 | pci_set_dma_mask(pci, DMA_BIT_MASK(32)); |
@@ -2309,7 +2333,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2309 | chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), | 2333 | chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), |
2310 | GFP_KERNEL); | 2334 | GFP_KERNEL); |
2311 | if (!chip->azx_dev) { | 2335 | if (!chip->azx_dev) { |
2312 | snd_printk(KERN_ERR "cannot malloc azx_dev\n"); | 2336 | snd_printk(KERN_ERR SFX "cannot malloc azx_dev\n"); |
2313 | goto errout; | 2337 | goto errout; |
2314 | } | 2338 | } |
2315 | 2339 | ||
@@ -2332,11 +2356,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2332 | goto errout; | 2356 | goto errout; |
2333 | } | 2357 | } |
2334 | /* allocate CORB/RIRB */ | 2358 | /* allocate CORB/RIRB */ |
2335 | if (!chip->single_cmd) { | 2359 | err = azx_alloc_cmd_io(chip); |
2336 | err = azx_alloc_cmd_io(chip); | 2360 | if (err < 0) |
2337 | if (err < 0) | 2361 | goto errout; |
2338 | goto errout; | ||
2339 | } | ||
2340 | 2362 | ||
2341 | /* initialize streams */ | 2363 | /* initialize streams */ |
2342 | azx_init_stream(chip); | 2364 | azx_init_stream(chip); |
@@ -2359,9 +2381,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2359 | } | 2381 | } |
2360 | 2382 | ||
2361 | strcpy(card->driver, "HDA-Intel"); | 2383 | strcpy(card->driver, "HDA-Intel"); |
2362 | strcpy(card->shortname, driver_short_names[chip->driver_type]); | 2384 | strlcpy(card->shortname, driver_short_names[chip->driver_type], |
2363 | sprintf(card->longname, "%s at 0x%lx irq %i", | 2385 | sizeof(card->shortname)); |
2364 | card->shortname, chip->addr, chip->irq); | 2386 | snprintf(card->longname, sizeof(card->longname), |
2387 | "%s at 0x%lx irq %i", | ||
2388 | card->shortname, chip->addr, chip->irq); | ||
2365 | 2389 | ||
2366 | *rchip = chip; | 2390 | *rchip = chip; |
2367 | return 0; | 2391 | return 0; |
@@ -2514,6 +2538,20 @@ static struct pci_device_id azx_ids[] = { | |||
2514 | { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA }, | 2538 | { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA }, |
2515 | /* Teradici */ | 2539 | /* Teradici */ |
2516 | { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, | 2540 | { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, |
2541 | /* Creative X-Fi (CA0110-IBG) */ | ||
2542 | #if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE) | ||
2543 | /* the following entry conflicts with snd-ctxfi driver, | ||
2544 | * as ctxfi driver mutates from HD-audio to native mode with | ||
2545 | * a special command sequence. | ||
2546 | */ | ||
2547 | { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), | ||
2548 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | ||
2549 | .class_mask = 0xffffff, | ||
2550 | .driver_data = AZX_DRIVER_GENERIC }, | ||
2551 | #else | ||
2552 | /* this entry seems still valid -- i.e. without emu20kx chip */ | ||
2553 | { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, | ||
2554 | #endif | ||
2517 | /* AMD Generic, PCI class code and Vendor ID for HD Audio */ | 2555 | /* AMD Generic, PCI class code and Vendor ID for HD Audio */ |
2518 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), | 2556 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), |
2519 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2557 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 93d7499350c6..418c5d1badaa 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -466,8 +466,12 @@ static void print_codec_info(struct snd_info_entry *entry, | |||
466 | hda_nid_t nid; | 466 | hda_nid_t nid; |
467 | int i, nodes; | 467 | int i, nodes; |
468 | 468 | ||
469 | snd_iprintf(buffer, "Codec: %s\n", | 469 | snd_iprintf(buffer, "Codec: "); |
470 | codec->name ? codec->name : "Not Set"); | 470 | if (codec->vendor_name && codec->chip_name) |
471 | snd_iprintf(buffer, "%s %s\n", | ||
472 | codec->vendor_name, codec->chip_name); | ||
473 | else | ||
474 | snd_iprintf(buffer, "Not Set\n"); | ||
471 | snd_iprintf(buffer, "Address: %d\n", codec->addr); | 475 | snd_iprintf(buffer, "Address: %d\n", codec->addr); |
472 | snd_iprintf(buffer, "Function Id: 0x%x\n", codec->function_id); | 476 | snd_iprintf(buffer, "Function Id: 0x%x\n", codec->function_id); |
473 | snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id); | 477 | snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id); |
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c new file mode 100644 index 000000000000..392d108c3558 --- /dev/null +++ b/sound/pci/hda/patch_ca0110.c | |||
@@ -0,0 +1,573 @@ | |||
1 | /* | ||
2 | * HD audio interface patch for Creative X-Fi CA0110-IBG chip | ||
3 | * | ||
4 | * Copyright (c) 2008 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 ca0110_spec { | ||
33 | struct auto_pin_cfg autocfg; | ||
34 | struct hda_multi_out multiout; | ||
35 | hda_nid_t out_pins[AUTO_CFG_MAX_OUTS]; | ||
36 | hda_nid_t dacs[AUTO_CFG_MAX_OUTS]; | ||
37 | hda_nid_t hp_dac; | ||
38 | hda_nid_t input_pins[AUTO_PIN_LAST]; | ||
39 | hda_nid_t adcs[AUTO_PIN_LAST]; | ||
40 | hda_nid_t dig_out; | ||
41 | hda_nid_t dig_in; | ||
42 | unsigned int num_inputs; | ||
43 | const char *input_labels[AUTO_PIN_LAST]; | ||
44 | struct hda_pcm pcm_rec[2]; /* PCM information */ | ||
45 | }; | ||
46 | |||
47 | /* | ||
48 | * PCM callbacks | ||
49 | */ | ||
50 | static int ca0110_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
51 | struct hda_codec *codec, | ||
52 | struct snd_pcm_substream *substream) | ||
53 | { | ||
54 | struct ca0110_spec *spec = codec->spec; | ||
55 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
56 | hinfo); | ||
57 | } | ||
58 | |||
59 | static int ca0110_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
60 | struct hda_codec *codec, | ||
61 | unsigned int stream_tag, | ||
62 | unsigned int format, | ||
63 | struct snd_pcm_substream *substream) | ||
64 | { | ||
65 | struct ca0110_spec *spec = codec->spec; | ||
66 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | ||
67 | stream_tag, format, substream); | ||
68 | } | ||
69 | |||
70 | static int ca0110_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
71 | struct hda_codec *codec, | ||
72 | struct snd_pcm_substream *substream) | ||
73 | { | ||
74 | struct ca0110_spec *spec = codec->spec; | ||
75 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * Digital out | ||
80 | */ | ||
81 | static int ca0110_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
82 | struct hda_codec *codec, | ||
83 | struct snd_pcm_substream *substream) | ||
84 | { | ||
85 | struct ca0110_spec *spec = codec->spec; | ||
86 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | ||
87 | } | ||
88 | |||
89 | static int ca0110_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
90 | struct hda_codec *codec, | ||
91 | struct snd_pcm_substream *substream) | ||
92 | { | ||
93 | struct ca0110_spec *spec = codec->spec; | ||
94 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | ||
95 | } | ||
96 | |||
97 | static int ca0110_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
98 | struct hda_codec *codec, | ||
99 | unsigned int stream_tag, | ||
100 | unsigned int format, | ||
101 | struct snd_pcm_substream *substream) | ||
102 | { | ||
103 | struct ca0110_spec *spec = codec->spec; | ||
104 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
105 | format, substream); | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Analog capture | ||
110 | */ | ||
111 | static int ca0110_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
112 | struct hda_codec *codec, | ||
113 | unsigned int stream_tag, | ||
114 | unsigned int format, | ||
115 | struct snd_pcm_substream *substream) | ||
116 | { | ||
117 | struct ca0110_spec *spec = codec->spec; | ||
118 | |||
119 | snd_hda_codec_setup_stream(codec, spec->adcs[substream->number], | ||
120 | stream_tag, 0, format); | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static int ca0110_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
125 | struct hda_codec *codec, | ||
126 | struct snd_pcm_substream *substream) | ||
127 | { | ||
128 | struct ca0110_spec *spec = codec->spec; | ||
129 | |||
130 | snd_hda_codec_cleanup_stream(codec, spec->adcs[substream->number]); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | */ | ||
136 | |||
137 | static char *dirstr[2] = { "Playback", "Capture" }; | ||
138 | |||
139 | static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | ||
140 | int chan, int dir) | ||
141 | { | ||
142 | char namestr[44]; | ||
143 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | ||
144 | struct snd_kcontrol_new knew = | ||
145 | HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); | ||
146 | sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); | ||
147 | return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); | ||
148 | } | ||
149 | |||
150 | static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | ||
151 | int chan, int dir) | ||
152 | { | ||
153 | char namestr[44]; | ||
154 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | ||
155 | struct snd_kcontrol_new knew = | ||
156 | HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); | ||
157 | sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); | ||
158 | return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); | ||
159 | } | ||
160 | |||
161 | #define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0) | ||
162 | #define add_out_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 0) | ||
163 | #define add_in_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 1) | ||
164 | #define add_in_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 1) | ||
165 | #define add_mono_switch(codec, nid, pfx, chan) \ | ||
166 | _add_switch(codec, nid, pfx, chan, 0) | ||
167 | #define add_mono_volume(codec, nid, pfx, chan) \ | ||
168 | _add_volume(codec, nid, pfx, chan, 0) | ||
169 | |||
170 | static int ca0110_build_controls(struct hda_codec *codec) | ||
171 | { | ||
172 | struct ca0110_spec *spec = codec->spec; | ||
173 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
174 | static char *prefix[AUTO_CFG_MAX_OUTS] = { | ||
175 | "Front", "Surround", NULL, "Side", "Multi" | ||
176 | }; | ||
177 | hda_nid_t mutenid; | ||
178 | int i, err; | ||
179 | |||
180 | for (i = 0; i < spec->multiout.num_dacs; i++) { | ||
181 | if (get_wcaps(codec, spec->out_pins[i]) & AC_WCAP_OUT_AMP) | ||
182 | mutenid = spec->out_pins[i]; | ||
183 | else | ||
184 | mutenid = spec->multiout.dac_nids[i]; | ||
185 | if (!prefix[i]) { | ||
186 | err = add_mono_switch(codec, mutenid, | ||
187 | "Center", 1); | ||
188 | if (err < 0) | ||
189 | return err; | ||
190 | err = add_mono_switch(codec, mutenid, | ||
191 | "LFE", 1); | ||
192 | if (err < 0) | ||
193 | return err; | ||
194 | err = add_mono_volume(codec, spec->multiout.dac_nids[i], | ||
195 | "Center", 1); | ||
196 | if (err < 0) | ||
197 | return err; | ||
198 | err = add_mono_volume(codec, spec->multiout.dac_nids[i], | ||
199 | "LFE", 1); | ||
200 | if (err < 0) | ||
201 | return err; | ||
202 | } else { | ||
203 | err = add_out_switch(codec, mutenid, | ||
204 | prefix[i]); | ||
205 | if (err < 0) | ||
206 | return err; | ||
207 | err = add_out_volume(codec, spec->multiout.dac_nids[i], | ||
208 | prefix[i]); | ||
209 | if (err < 0) | ||
210 | return err; | ||
211 | } | ||
212 | } | ||
213 | if (cfg->hp_outs) { | ||
214 | if (get_wcaps(codec, cfg->hp_pins[0]) & AC_WCAP_OUT_AMP) | ||
215 | mutenid = cfg->hp_pins[0]; | ||
216 | else | ||
217 | mutenid = spec->multiout.dac_nids[i]; | ||
218 | |||
219 | err = add_out_switch(codec, mutenid, "Headphone"); | ||
220 | if (err < 0) | ||
221 | return err; | ||
222 | if (spec->hp_dac) { | ||
223 | err = add_out_volume(codec, spec->hp_dac, "Headphone"); | ||
224 | if (err < 0) | ||
225 | return err; | ||
226 | } | ||
227 | } | ||
228 | for (i = 0; i < spec->num_inputs; i++) { | ||
229 | const char *label = spec->input_labels[i]; | ||
230 | if (get_wcaps(codec, spec->input_pins[i]) & AC_WCAP_IN_AMP) | ||
231 | mutenid = spec->input_pins[i]; | ||
232 | else | ||
233 | mutenid = spec->adcs[i]; | ||
234 | err = add_in_switch(codec, mutenid, label); | ||
235 | if (err < 0) | ||
236 | return err; | ||
237 | err = add_in_volume(codec, spec->adcs[i], label); | ||
238 | if (err < 0) | ||
239 | return err; | ||
240 | } | ||
241 | |||
242 | if (spec->dig_out) { | ||
243 | err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out); | ||
244 | if (err < 0) | ||
245 | return err; | ||
246 | err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); | ||
247 | if (err < 0) | ||
248 | return err; | ||
249 | spec->multiout.share_spdif = 1; | ||
250 | } | ||
251 | if (spec->dig_in) { | ||
252 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); | ||
253 | if (err < 0) | ||
254 | return err; | ||
255 | err = add_in_volume(codec, spec->dig_in, "IEC958"); | ||
256 | } | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | */ | ||
262 | static struct hda_pcm_stream ca0110_pcm_analog_playback = { | ||
263 | .substreams = 1, | ||
264 | .channels_min = 2, | ||
265 | .channels_max = 8, | ||
266 | .ops = { | ||
267 | .open = ca0110_playback_pcm_open, | ||
268 | .prepare = ca0110_playback_pcm_prepare, | ||
269 | .cleanup = ca0110_playback_pcm_cleanup | ||
270 | }, | ||
271 | }; | ||
272 | |||
273 | static struct hda_pcm_stream ca0110_pcm_analog_capture = { | ||
274 | .substreams = 1, | ||
275 | .channels_min = 2, | ||
276 | .channels_max = 2, | ||
277 | .ops = { | ||
278 | .prepare = ca0110_capture_pcm_prepare, | ||
279 | .cleanup = ca0110_capture_pcm_cleanup | ||
280 | }, | ||
281 | }; | ||
282 | |||
283 | static struct hda_pcm_stream ca0110_pcm_digital_playback = { | ||
284 | .substreams = 1, | ||
285 | .channels_min = 2, | ||
286 | .channels_max = 2, | ||
287 | .ops = { | ||
288 | .open = ca0110_dig_playback_pcm_open, | ||
289 | .close = ca0110_dig_playback_pcm_close, | ||
290 | .prepare = ca0110_dig_playback_pcm_prepare | ||
291 | }, | ||
292 | }; | ||
293 | |||
294 | static struct hda_pcm_stream ca0110_pcm_digital_capture = { | ||
295 | .substreams = 1, | ||
296 | .channels_min = 2, | ||
297 | .channels_max = 2, | ||
298 | }; | ||
299 | |||
300 | static int ca0110_build_pcms(struct hda_codec *codec) | ||
301 | { | ||
302 | struct ca0110_spec *spec = codec->spec; | ||
303 | struct hda_pcm *info = spec->pcm_rec; | ||
304 | |||
305 | codec->pcm_info = info; | ||
306 | codec->num_pcms = 0; | ||
307 | |||
308 | info->name = "CA0110 Analog"; | ||
309 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0110_pcm_analog_playback; | ||
310 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0]; | ||
311 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | ||
312 | spec->multiout.max_channels; | ||
313 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0110_pcm_analog_capture; | ||
314 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs; | ||
315 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; | ||
316 | codec->num_pcms++; | ||
317 | |||
318 | if (!spec->dig_out && !spec->dig_in) | ||
319 | return 0; | ||
320 | |||
321 | info++; | ||
322 | info->name = "CA0110 Digital"; | ||
323 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | ||
324 | if (spec->dig_out) { | ||
325 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | ||
326 | ca0110_pcm_digital_playback; | ||
327 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out; | ||
328 | } | ||
329 | if (spec->dig_in) { | ||
330 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
331 | ca0110_pcm_digital_capture; | ||
332 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in; | ||
333 | } | ||
334 | codec->num_pcms++; | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) | ||
340 | { | ||
341 | if (pin) { | ||
342 | snd_hda_codec_write(codec, pin, 0, | ||
343 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); | ||
344 | if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) | ||
345 | snd_hda_codec_write(codec, pin, 0, | ||
346 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
347 | AMP_OUT_UNMUTE); | ||
348 | } | ||
349 | if (dac) | ||
350 | snd_hda_codec_write(codec, dac, 0, | ||
351 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); | ||
352 | } | ||
353 | |||
354 | static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) | ||
355 | { | ||
356 | if (pin) { | ||
357 | snd_hda_codec_write(codec, pin, 0, | ||
358 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80); | ||
359 | if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP) | ||
360 | snd_hda_codec_write(codec, pin, 0, | ||
361 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
362 | AMP_IN_UNMUTE(0)); | ||
363 | } | ||
364 | if (adc) | ||
365 | snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
366 | AMP_IN_UNMUTE(0)); | ||
367 | } | ||
368 | |||
369 | static int ca0110_init(struct hda_codec *codec) | ||
370 | { | ||
371 | struct ca0110_spec *spec = codec->spec; | ||
372 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
373 | int i; | ||
374 | |||
375 | for (i = 0; i < spec->multiout.num_dacs; i++) | ||
376 | init_output(codec, spec->out_pins[i], | ||
377 | spec->multiout.dac_nids[i]); | ||
378 | init_output(codec, cfg->hp_pins[0], spec->hp_dac); | ||
379 | init_output(codec, cfg->dig_out_pins[0], spec->dig_out); | ||
380 | |||
381 | for (i = 0; i < spec->num_inputs; i++) | ||
382 | init_input(codec, spec->input_pins[i], spec->adcs[i]); | ||
383 | init_input(codec, cfg->dig_in_pin, spec->dig_in); | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static void ca0110_free(struct hda_codec *codec) | ||
388 | { | ||
389 | kfree(codec->spec); | ||
390 | } | ||
391 | |||
392 | static struct hda_codec_ops ca0110_patch_ops = { | ||
393 | .build_controls = ca0110_build_controls, | ||
394 | .build_pcms = ca0110_build_pcms, | ||
395 | .init = ca0110_init, | ||
396 | .free = ca0110_free, | ||
397 | }; | ||
398 | |||
399 | |||
400 | static void parse_line_outs(struct hda_codec *codec) | ||
401 | { | ||
402 | struct ca0110_spec *spec = codec->spec; | ||
403 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
404 | int i, n; | ||
405 | unsigned int def_conf; | ||
406 | hda_nid_t nid; | ||
407 | |||
408 | n = 0; | ||
409 | for (i = 0; i < cfg->line_outs; i++) { | ||
410 | nid = cfg->line_out_pins[i]; | ||
411 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
412 | if (!def_conf) | ||
413 | continue; /* invalid pin */ | ||
414 | if (snd_hda_get_connections(codec, nid, &spec->dacs[i], 1) != 1) | ||
415 | continue; | ||
416 | spec->out_pins[n++] = nid; | ||
417 | } | ||
418 | spec->multiout.dac_nids = spec->dacs; | ||
419 | spec->multiout.num_dacs = n; | ||
420 | spec->multiout.max_channels = n * 2; | ||
421 | } | ||
422 | |||
423 | static void parse_hp_out(struct hda_codec *codec) | ||
424 | { | ||
425 | struct ca0110_spec *spec = codec->spec; | ||
426 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
427 | int i; | ||
428 | unsigned int def_conf; | ||
429 | hda_nid_t nid, dac; | ||
430 | |||
431 | if (!cfg->hp_outs) | ||
432 | return; | ||
433 | nid = cfg->hp_pins[0]; | ||
434 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
435 | if (!def_conf) { | ||
436 | cfg->hp_outs = 0; | ||
437 | return; | ||
438 | } | ||
439 | if (snd_hda_get_connections(codec, nid, &dac, 1) != 1) | ||
440 | return; | ||
441 | |||
442 | for (i = 0; i < cfg->line_outs; i++) | ||
443 | if (dac == spec->dacs[i]) | ||
444 | break; | ||
445 | if (i >= cfg->line_outs) { | ||
446 | spec->hp_dac = dac; | ||
447 | spec->multiout.hp_nid = dac; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | static void parse_input(struct hda_codec *codec) | ||
452 | { | ||
453 | struct ca0110_spec *spec = codec->spec; | ||
454 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
455 | hda_nid_t nid, pin; | ||
456 | int n, i, j; | ||
457 | |||
458 | n = 0; | ||
459 | nid = codec->start_nid; | ||
460 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
461 | unsigned int wcaps = get_wcaps(codec, nid); | ||
462 | unsigned int type = (wcaps & AC_WCAP_TYPE) >> | ||
463 | AC_WCAP_TYPE_SHIFT; | ||
464 | if (type != AC_WID_AUD_IN) | ||
465 | continue; | ||
466 | if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) | ||
467 | continue; | ||
468 | if (pin == cfg->dig_in_pin) { | ||
469 | spec->dig_in = nid; | ||
470 | continue; | ||
471 | } | ||
472 | for (j = 0; j < AUTO_PIN_LAST; j++) | ||
473 | if (cfg->input_pins[j] == pin) | ||
474 | break; | ||
475 | if (j >= AUTO_PIN_LAST) | ||
476 | continue; | ||
477 | spec->input_pins[n] = pin; | ||
478 | spec->input_labels[n] = auto_pin_cfg_labels[j]; | ||
479 | spec->adcs[n] = nid; | ||
480 | n++; | ||
481 | } | ||
482 | spec->num_inputs = n; | ||
483 | } | ||
484 | |||
485 | static void parse_digital(struct hda_codec *codec) | ||
486 | { | ||
487 | struct ca0110_spec *spec = codec->spec; | ||
488 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
489 | |||
490 | if (cfg->dig_outs && | ||
491 | snd_hda_get_connections(codec, cfg->dig_out_pins[0], | ||
492 | &spec->dig_out, 1) == 1) | ||
493 | spec->multiout.dig_out_nid = cfg->dig_out_pins[0]; | ||
494 | } | ||
495 | |||
496 | static int ca0110_parse_auto_config(struct hda_codec *codec) | ||
497 | { | ||
498 | struct ca0110_spec *spec = codec->spec; | ||
499 | int err; | ||
500 | |||
501 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); | ||
502 | if (err < 0) | ||
503 | return err; | ||
504 | |||
505 | parse_line_outs(codec); | ||
506 | parse_hp_out(codec); | ||
507 | parse_digital(codec); | ||
508 | parse_input(codec); | ||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | |||
513 | int patch_ca0110(struct hda_codec *codec) | ||
514 | { | ||
515 | struct ca0110_spec *spec; | ||
516 | int err; | ||
517 | |||
518 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
519 | if (!spec) | ||
520 | return -ENOMEM; | ||
521 | codec->spec = spec; | ||
522 | |||
523 | codec->bus->needs_damn_long_delay = 1; | ||
524 | |||
525 | err = ca0110_parse_auto_config(codec); | ||
526 | if (err < 0) | ||
527 | goto error; | ||
528 | |||
529 | codec->patch_ops = ca0110_patch_ops; | ||
530 | |||
531 | return 0; | ||
532 | |||
533 | error: | ||
534 | kfree(codec->spec); | ||
535 | codec->spec = NULL; | ||
536 | return err; | ||
537 | } | ||
538 | |||
539 | |||
540 | /* | ||
541 | * patch entries | ||
542 | */ | ||
543 | static struct hda_codec_preset snd_hda_preset_ca0110[] = { | ||
544 | { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 }, | ||
545 | { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 }, | ||
546 | { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 }, | ||
547 | {} /* terminator */ | ||
548 | }; | ||
549 | |||
550 | MODULE_ALIAS("snd-hda-codec-id:1102000a"); | ||
551 | MODULE_ALIAS("snd-hda-codec-id:1102000b"); | ||
552 | MODULE_ALIAS("snd-hda-codec-id:1102000d"); | ||
553 | |||
554 | MODULE_LICENSE("GPL"); | ||
555 | MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec"); | ||
556 | |||
557 | static struct hda_codec_preset_list ca0110_list = { | ||
558 | .preset = snd_hda_preset_ca0110, | ||
559 | .owner = THIS_MODULE, | ||
560 | }; | ||
561 | |||
562 | static int __init patch_ca0110_init(void) | ||
563 | { | ||
564 | return snd_hda_add_codec_preset(&ca0110_list); | ||
565 | } | ||
566 | |||
567 | static void __exit patch_ca0110_exit(void) | ||
568 | { | ||
569 | snd_hda_delete_codec_preset(&ca0110_list); | ||
570 | } | ||
571 | |||
572 | module_init(patch_ca0110_init) | ||
573 | module_exit(patch_ca0110_exit) | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0fd258eba3a5..add920a925c7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -190,6 +190,7 @@ enum { | |||
190 | ALC663_ASUS_MODE6, | 190 | ALC663_ASUS_MODE6, |
191 | ALC272_DELL, | 191 | ALC272_DELL, |
192 | ALC272_DELL_ZM1, | 192 | ALC272_DELL_ZM1, |
193 | ALC272_SAMSUNG_NC10, | ||
193 | ALC662_AUTO, | 194 | ALC662_AUTO, |
194 | ALC662_MODEL_LAST, | 195 | ALC662_MODEL_LAST, |
195 | }; | 196 | }; |
@@ -205,6 +206,7 @@ enum { | |||
205 | ALC882_ASUS_A7M, | 206 | ALC882_ASUS_A7M, |
206 | ALC885_MACPRO, | 207 | ALC885_MACPRO, |
207 | ALC885_MBP3, | 208 | ALC885_MBP3, |
209 | ALC885_MB5, | ||
208 | ALC885_IMAC24, | 210 | ALC885_IMAC24, |
209 | ALC882_AUTO, | 211 | ALC882_AUTO, |
210 | ALC882_MODEL_LAST, | 212 | ALC882_MODEL_LAST, |
@@ -238,6 +240,7 @@ enum { | |||
238 | ALC883_3ST_6ch_INTEL, | 240 | ALC883_3ST_6ch_INTEL, |
239 | ALC888_ASUS_M90V, | 241 | ALC888_ASUS_M90V, |
240 | ALC888_ASUS_EEE1601, | 242 | ALC888_ASUS_EEE1601, |
243 | ALC889A_MB31, | ||
241 | ALC1200_ASUS_P5Q, | 244 | ALC1200_ASUS_P5Q, |
242 | ALC883_AUTO, | 245 | ALC883_AUTO, |
243 | ALC883_MODEL_LAST, | 246 | ALC883_MODEL_LAST, |
@@ -253,6 +256,15 @@ enum { | |||
253 | /* for GPIO Poll */ | 256 | /* for GPIO Poll */ |
254 | #define GPIO_MASK 0x03 | 257 | #define GPIO_MASK 0x03 |
255 | 258 | ||
259 | /* extra amp-initialization sequence types */ | ||
260 | enum { | ||
261 | ALC_INIT_NONE, | ||
262 | ALC_INIT_DEFAULT, | ||
263 | ALC_INIT_GPIO1, | ||
264 | ALC_INIT_GPIO2, | ||
265 | ALC_INIT_GPIO3, | ||
266 | }; | ||
267 | |||
256 | struct alc_spec { | 268 | struct alc_spec { |
257 | /* codec parameterization */ | 269 | /* codec parameterization */ |
258 | struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ | 270 | struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ |
@@ -266,13 +278,13 @@ struct alc_spec { | |||
266 | */ | 278 | */ |
267 | unsigned int num_init_verbs; | 279 | unsigned int num_init_verbs; |
268 | 280 | ||
269 | char *stream_name_analog; /* analog PCM stream */ | 281 | char stream_name_analog[16]; /* analog PCM stream */ |
270 | struct hda_pcm_stream *stream_analog_playback; | 282 | struct hda_pcm_stream *stream_analog_playback; |
271 | struct hda_pcm_stream *stream_analog_capture; | 283 | struct hda_pcm_stream *stream_analog_capture; |
272 | struct hda_pcm_stream *stream_analog_alt_playback; | 284 | struct hda_pcm_stream *stream_analog_alt_playback; |
273 | struct hda_pcm_stream *stream_analog_alt_capture; | 285 | struct hda_pcm_stream *stream_analog_alt_capture; |
274 | 286 | ||
275 | char *stream_name_digital; /* digital PCM stream */ | 287 | char stream_name_digital[16]; /* digital PCM stream */ |
276 | struct hda_pcm_stream *stream_digital_playback; | 288 | struct hda_pcm_stream *stream_digital_playback; |
277 | struct hda_pcm_stream *stream_digital_capture; | 289 | struct hda_pcm_stream *stream_digital_capture; |
278 | 290 | ||
@@ -322,6 +334,7 @@ struct alc_spec { | |||
322 | 334 | ||
323 | /* other flags */ | 335 | /* other flags */ |
324 | unsigned int no_analog :1; /* digital I/O only */ | 336 | unsigned int no_analog :1; /* digital I/O only */ |
337 | int init_amp; | ||
325 | 338 | ||
326 | /* for virtual master */ | 339 | /* for virtual master */ |
327 | hda_nid_t vmaster_nid; | 340 | hda_nid_t vmaster_nid; |
@@ -921,20 +934,26 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | |||
921 | alc_fix_pll(codec); | 934 | alc_fix_pll(codec); |
922 | } | 935 | } |
923 | 936 | ||
924 | static void alc_sku_automute(struct hda_codec *codec) | 937 | static void alc_automute_pin(struct hda_codec *codec) |
925 | { | 938 | { |
926 | struct alc_spec *spec = codec->spec; | 939 | struct alc_spec *spec = codec->spec; |
927 | unsigned int present; | 940 | unsigned int present; |
928 | unsigned int hp_nid = spec->autocfg.hp_pins[0]; | 941 | unsigned int nid = spec->autocfg.hp_pins[0]; |
929 | unsigned int sp_nid = spec->autocfg.speaker_pins[0]; | 942 | int i; |
930 | 943 | ||
931 | /* need to execute and sync at first */ | 944 | /* need to execute and sync at first */ |
932 | snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); | 945 | snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); |
933 | present = snd_hda_codec_read(codec, hp_nid, 0, | 946 | present = snd_hda_codec_read(codec, nid, 0, |
934 | AC_VERB_GET_PIN_SENSE, 0); | 947 | AC_VERB_GET_PIN_SENSE, 0); |
935 | spec->jack_present = (present & 0x80000000) != 0; | 948 | spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; |
936 | snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 949 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { |
937 | spec->jack_present ? 0 : PIN_OUT); | 950 | nid = spec->autocfg.speaker_pins[i]; |
951 | if (!nid) | ||
952 | break; | ||
953 | snd_hda_codec_write(codec, nid, 0, | ||
954 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
955 | spec->jack_present ? 0 : PIN_OUT); | ||
956 | } | ||
938 | } | 957 | } |
939 | 958 | ||
940 | #if 0 /* it's broken in some acses -- temporarily disabled */ | 959 | #if 0 /* it's broken in some acses -- temporarily disabled */ |
@@ -969,16 +988,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | |||
969 | res >>= 28; | 988 | res >>= 28; |
970 | else | 989 | else |
971 | res >>= 26; | 990 | res >>= 26; |
972 | if (res == ALC880_HP_EVENT) | 991 | switch (res) { |
973 | alc_sku_automute(codec); | 992 | case ALC880_HP_EVENT: |
974 | 993 | alc_automute_pin(codec); | |
975 | if (res == ALC880_MIC_EVENT) | 994 | break; |
995 | case ALC880_MIC_EVENT: | ||
976 | alc_mic_automute(codec); | 996 | alc_mic_automute(codec); |
997 | break; | ||
998 | } | ||
977 | } | 999 | } |
978 | 1000 | ||
979 | static void alc_inithook(struct hda_codec *codec) | 1001 | static void alc_inithook(struct hda_codec *codec) |
980 | { | 1002 | { |
981 | alc_sku_automute(codec); | 1003 | alc_automute_pin(codec); |
982 | alc_mic_automute(codec); | 1004 | alc_mic_automute(codec); |
983 | } | 1005 | } |
984 | 1006 | ||
@@ -1000,69 +1022,21 @@ static void alc888_coef_init(struct hda_codec *codec) | |||
1000 | AC_VERB_SET_PROC_COEF, 0x3030); | 1022 | AC_VERB_SET_PROC_COEF, 0x3030); |
1001 | } | 1023 | } |
1002 | 1024 | ||
1003 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. | 1025 | static void alc_auto_init_amp(struct hda_codec *codec, int type) |
1004 | * 31 ~ 16 : Manufacture ID | ||
1005 | * 15 ~ 8 : SKU ID | ||
1006 | * 7 ~ 0 : Assembly ID | ||
1007 | * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 | ||
1008 | */ | ||
1009 | static void alc_subsystem_id(struct hda_codec *codec, | ||
1010 | unsigned int porta, unsigned int porte, | ||
1011 | unsigned int portd) | ||
1012 | { | 1026 | { |
1013 | unsigned int ass, tmp, i; | 1027 | unsigned int tmp; |
1014 | unsigned nid; | ||
1015 | struct alc_spec *spec = codec->spec; | ||
1016 | |||
1017 | ass = codec->subsystem_id & 0xffff; | ||
1018 | if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) | ||
1019 | goto do_sku; | ||
1020 | |||
1021 | /* | ||
1022 | * 31~30 : port conetcivity | ||
1023 | * 29~21 : reserve | ||
1024 | * 20 : PCBEEP input | ||
1025 | * 19~16 : Check sum (15:1) | ||
1026 | * 15~1 : Custom | ||
1027 | * 0 : override | ||
1028 | */ | ||
1029 | nid = 0x1d; | ||
1030 | if (codec->vendor_id == 0x10ec0260) | ||
1031 | nid = 0x17; | ||
1032 | ass = snd_hda_codec_get_pincfg(codec, nid); | ||
1033 | if (!(ass & 1) && !(ass & 0x100000)) | ||
1034 | return; | ||
1035 | if ((ass >> 30) != 1) /* no physical connection */ | ||
1036 | return; | ||
1037 | 1028 | ||
1038 | /* check sum */ | 1029 | switch (type) { |
1039 | tmp = 0; | 1030 | case ALC_INIT_GPIO1: |
1040 | for (i = 1; i < 16; i++) { | ||
1041 | if ((ass >> i) & 1) | ||
1042 | tmp++; | ||
1043 | } | ||
1044 | if (((ass >> 16) & 0xf) != tmp) | ||
1045 | return; | ||
1046 | do_sku: | ||
1047 | /* | ||
1048 | * 0 : override | ||
1049 | * 1 : Swap Jack | ||
1050 | * 2 : 0 --> Desktop, 1 --> Laptop | ||
1051 | * 3~5 : External Amplifier control | ||
1052 | * 7~6 : Reserved | ||
1053 | */ | ||
1054 | tmp = (ass & 0x38) >> 3; /* external Amp control */ | ||
1055 | switch (tmp) { | ||
1056 | case 1: | ||
1057 | snd_hda_sequence_write(codec, alc_gpio1_init_verbs); | 1031 | snd_hda_sequence_write(codec, alc_gpio1_init_verbs); |
1058 | break; | 1032 | break; |
1059 | case 3: | 1033 | case ALC_INIT_GPIO2: |
1060 | snd_hda_sequence_write(codec, alc_gpio2_init_verbs); | 1034 | snd_hda_sequence_write(codec, alc_gpio2_init_verbs); |
1061 | break; | 1035 | break; |
1062 | case 7: | 1036 | case ALC_INIT_GPIO3: |
1063 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); | 1037 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); |
1064 | break; | 1038 | break; |
1065 | case 5: /* set EAPD output high */ | 1039 | case ALC_INIT_DEFAULT: |
1066 | switch (codec->vendor_id) { | 1040 | switch (codec->vendor_id) { |
1067 | case 0x10ec0260: | 1041 | case 0x10ec0260: |
1068 | snd_hda_codec_write(codec, 0x0f, 0, | 1042 | snd_hda_codec_write(codec, 0x0f, 0, |
@@ -1116,7 +1090,7 @@ do_sku: | |||
1116 | tmp | 0x2010); | 1090 | tmp | 0x2010); |
1117 | break; | 1091 | break; |
1118 | case 0x10ec0888: | 1092 | case 0x10ec0888: |
1119 | /*alc888_coef_init(codec);*/ /* called in alc_init() */ | 1093 | alc888_coef_init(codec); |
1120 | break; | 1094 | break; |
1121 | case 0x10ec0267: | 1095 | case 0x10ec0267: |
1122 | case 0x10ec0268: | 1096 | case 0x10ec0268: |
@@ -1131,7 +1105,107 @@ do_sku: | |||
1131 | tmp | 0x3000); | 1105 | tmp | 0x3000); |
1132 | break; | 1106 | break; |
1133 | } | 1107 | } |
1134 | default: | 1108 | break; |
1109 | } | ||
1110 | } | ||
1111 | |||
1112 | static void alc_init_auto_hp(struct hda_codec *codec) | ||
1113 | { | ||
1114 | struct alc_spec *spec = codec->spec; | ||
1115 | |||
1116 | if (!spec->autocfg.hp_pins[0]) | ||
1117 | return; | ||
1118 | |||
1119 | if (!spec->autocfg.speaker_pins[0]) { | ||
1120 | if (spec->autocfg.line_out_pins[0] && | ||
1121 | spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
1122 | spec->autocfg.speaker_pins[0] = | ||
1123 | spec->autocfg.line_out_pins[0]; | ||
1124 | else | ||
1125 | return; | ||
1126 | } | ||
1127 | |||
1128 | snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", | ||
1129 | spec->autocfg.hp_pins[0]); | ||
1130 | snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0, | ||
1131 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1132 | AC_USRSP_EN | ALC880_HP_EVENT); | ||
1133 | spec->unsol_event = alc_sku_unsol_event; | ||
1134 | } | ||
1135 | |||
1136 | /* check subsystem ID and set up device-specific initialization; | ||
1137 | * return 1 if initialized, 0 if invalid SSID | ||
1138 | */ | ||
1139 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. | ||
1140 | * 31 ~ 16 : Manufacture ID | ||
1141 | * 15 ~ 8 : SKU ID | ||
1142 | * 7 ~ 0 : Assembly ID | ||
1143 | * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 | ||
1144 | */ | ||
1145 | static int alc_subsystem_id(struct hda_codec *codec, | ||
1146 | hda_nid_t porta, hda_nid_t porte, | ||
1147 | hda_nid_t portd) | ||
1148 | { | ||
1149 | unsigned int ass, tmp, i; | ||
1150 | unsigned nid; | ||
1151 | struct alc_spec *spec = codec->spec; | ||
1152 | |||
1153 | ass = codec->subsystem_id & 0xffff; | ||
1154 | if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) | ||
1155 | goto do_sku; | ||
1156 | |||
1157 | /* invalid SSID, check the special NID pin defcfg instead */ | ||
1158 | /* | ||
1159 | * 31~30 : port conetcivity | ||
1160 | * 29~21 : reserve | ||
1161 | * 20 : PCBEEP input | ||
1162 | * 19~16 : Check sum (15:1) | ||
1163 | * 15~1 : Custom | ||
1164 | * 0 : override | ||
1165 | */ | ||
1166 | nid = 0x1d; | ||
1167 | if (codec->vendor_id == 0x10ec0260) | ||
1168 | nid = 0x17; | ||
1169 | ass = snd_hda_codec_get_pincfg(codec, nid); | ||
1170 | snd_printd("realtek: No valid SSID, " | ||
1171 | "checking pincfg 0x%08x for NID 0x%x\n", | ||
1172 | ass, nid); | ||
1173 | if (!(ass & 1) && !(ass & 0x100000)) | ||
1174 | return 0; | ||
1175 | if ((ass >> 30) != 1) /* no physical connection */ | ||
1176 | return 0; | ||
1177 | |||
1178 | /* check sum */ | ||
1179 | tmp = 0; | ||
1180 | for (i = 1; i < 16; i++) { | ||
1181 | if ((ass >> i) & 1) | ||
1182 | tmp++; | ||
1183 | } | ||
1184 | if (((ass >> 16) & 0xf) != tmp) | ||
1185 | return 0; | ||
1186 | do_sku: | ||
1187 | snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", | ||
1188 | ass & 0xffff, codec->vendor_id); | ||
1189 | /* | ||
1190 | * 0 : override | ||
1191 | * 1 : Swap Jack | ||
1192 | * 2 : 0 --> Desktop, 1 --> Laptop | ||
1193 | * 3~5 : External Amplifier control | ||
1194 | * 7~6 : Reserved | ||
1195 | */ | ||
1196 | tmp = (ass & 0x38) >> 3; /* external Amp control */ | ||
1197 | switch (tmp) { | ||
1198 | case 1: | ||
1199 | spec->init_amp = ALC_INIT_GPIO1; | ||
1200 | break; | ||
1201 | case 3: | ||
1202 | spec->init_amp = ALC_INIT_GPIO2; | ||
1203 | break; | ||
1204 | case 7: | ||
1205 | spec->init_amp = ALC_INIT_GPIO3; | ||
1206 | break; | ||
1207 | case 5: | ||
1208 | spec->init_amp = ALC_INIT_DEFAULT; | ||
1135 | break; | 1209 | break; |
1136 | } | 1210 | } |
1137 | 1211 | ||
@@ -1139,7 +1213,7 @@ do_sku: | |||
1139 | * when the external headphone out jack is plugged" | 1213 | * when the external headphone out jack is plugged" |
1140 | */ | 1214 | */ |
1141 | if (!(ass & 0x8000)) | 1215 | if (!(ass & 0x8000)) |
1142 | return; | 1216 | return 1; |
1143 | /* | 1217 | /* |
1144 | * 10~8 : Jack location | 1218 | * 10~8 : Jack location |
1145 | * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered | 1219 | * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered |
@@ -1147,14 +1221,6 @@ do_sku: | |||
1147 | * 15 : 1 --> enable the function "Mute internal speaker | 1221 | * 15 : 1 --> enable the function "Mute internal speaker |
1148 | * when the external headphone out jack is plugged" | 1222 | * when the external headphone out jack is plugged" |
1149 | */ | 1223 | */ |
1150 | if (!spec->autocfg.speaker_pins[0]) { | ||
1151 | if (spec->autocfg.line_out_pins[0]) | ||
1152 | spec->autocfg.speaker_pins[0] = | ||
1153 | spec->autocfg.line_out_pins[0]; | ||
1154 | else | ||
1155 | return; | ||
1156 | } | ||
1157 | |||
1158 | if (!spec->autocfg.hp_pins[0]) { | 1224 | if (!spec->autocfg.hp_pins[0]) { |
1159 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ | 1225 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ |
1160 | if (tmp == 0) | 1226 | if (tmp == 0) |
@@ -1164,23 +1230,23 @@ do_sku: | |||
1164 | else if (tmp == 2) | 1230 | else if (tmp == 2) |
1165 | spec->autocfg.hp_pins[0] = portd; | 1231 | spec->autocfg.hp_pins[0] = portd; |
1166 | else | 1232 | else |
1167 | return; | 1233 | return 1; |
1168 | } | 1234 | } |
1169 | if (spec->autocfg.hp_pins[0]) | ||
1170 | snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0, | ||
1171 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1172 | AC_USRSP_EN | ALC880_HP_EVENT); | ||
1173 | 1235 | ||
1174 | #if 0 /* it's broken in some acses -- temporarily disabled */ | 1236 | alc_init_auto_hp(codec); |
1175 | if (spec->autocfg.input_pins[AUTO_PIN_MIC] && | 1237 | return 1; |
1176 | spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]) | 1238 | } |
1177 | snd_hda_codec_write(codec, | ||
1178 | spec->autocfg.input_pins[AUTO_PIN_MIC], 0, | ||
1179 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1180 | AC_USRSP_EN | ALC880_MIC_EVENT); | ||
1181 | #endif /* disabled */ | ||
1182 | 1239 | ||
1183 | spec->unsol_event = alc_sku_unsol_event; | 1240 | static void alc_ssid_check(struct hda_codec *codec, |
1241 | hda_nid_t porta, hda_nid_t porte, hda_nid_t portd) | ||
1242 | { | ||
1243 | if (!alc_subsystem_id(codec, porta, porte, portd)) { | ||
1244 | struct alc_spec *spec = codec->spec; | ||
1245 | snd_printd("realtek: " | ||
1246 | "Enable default setup for auto mode as fallback\n"); | ||
1247 | spec->init_amp = ALC_INIT_DEFAULT; | ||
1248 | alc_init_auto_hp(codec); | ||
1249 | } | ||
1184 | } | 1250 | } |
1185 | 1251 | ||
1186 | /* | 1252 | /* |
@@ -1315,32 +1381,58 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { | |||
1315 | {} | 1381 | {} |
1316 | }; | 1382 | }; |
1317 | 1383 | ||
1318 | static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec) | 1384 | static void alc_automute_amp(struct hda_codec *codec) |
1319 | { | 1385 | { |
1320 | unsigned int present; | 1386 | struct alc_spec *spec = codec->spec; |
1321 | unsigned int bits; | 1387 | unsigned int val, mute; |
1322 | /* Line out presence */ | 1388 | hda_nid_t nid; |
1323 | present = snd_hda_codec_read(codec, 0x17, 0, | 1389 | int i; |
1324 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1390 | |
1325 | /* HP out presence */ | 1391 | spec->jack_present = 0; |
1326 | present = present || snd_hda_codec_read(codec, 0x1b, 0, | 1392 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { |
1327 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1393 | nid = spec->autocfg.hp_pins[i]; |
1328 | bits = present ? HDA_AMP_MUTE : 0; | 1394 | if (!nid) |
1395 | break; | ||
1396 | val = snd_hda_codec_read(codec, nid, 0, | ||
1397 | AC_VERB_GET_PIN_SENSE, 0); | ||
1398 | if (val & AC_PINSENSE_PRESENCE) { | ||
1399 | spec->jack_present = 1; | ||
1400 | break; | ||
1401 | } | ||
1402 | } | ||
1403 | |||
1404 | mute = spec->jack_present ? HDA_AMP_MUTE : 0; | ||
1329 | /* Toggle internal speakers muting */ | 1405 | /* Toggle internal speakers muting */ |
1330 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 1406 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { |
1331 | HDA_AMP_MUTE, bits); | 1407 | nid = spec->autocfg.speaker_pins[i]; |
1332 | /* Toggle internal bass muting */ | 1408 | if (!nid) |
1333 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 1409 | break; |
1334 | HDA_AMP_MUTE, bits); | 1410 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, |
1411 | HDA_AMP_MUTE, mute); | ||
1412 | } | ||
1335 | } | 1413 | } |
1336 | 1414 | ||
1337 | static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec, | 1415 | static void alc_automute_amp_unsol_event(struct hda_codec *codec, |
1338 | unsigned int res) | 1416 | unsigned int res) |
1339 | { | 1417 | { |
1340 | if (res >> 26 == ALC880_HP_EVENT) | 1418 | if (codec->vendor_id == 0x10ec0880) |
1341 | alc888_fujitsu_xa3530_automute(codec); | 1419 | res >>= 28; |
1420 | else | ||
1421 | res >>= 26; | ||
1422 | if (res == ALC880_HP_EVENT) | ||
1423 | alc_automute_amp(codec); | ||
1342 | } | 1424 | } |
1343 | 1425 | ||
1426 | static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec) | ||
1427 | { | ||
1428 | struct alc_spec *spec = codec->spec; | ||
1429 | |||
1430 | spec->autocfg.hp_pins[0] = 0x17; /* line-out */ | ||
1431 | spec->autocfg.hp_pins[1] = 0x1b; /* hp */ | ||
1432 | spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ | ||
1433 | spec->autocfg.speaker_pins[1] = 0x15; /* bass */ | ||
1434 | alc_automute_amp(codec); | ||
1435 | } | ||
1344 | 1436 | ||
1345 | /* | 1437 | /* |
1346 | * ALC888 Acer Aspire 4930G model | 1438 | * ALC888 Acer Aspire 4930G model |
@@ -1407,22 +1499,13 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { | |||
1407 | { } /* end */ | 1499 | { } /* end */ |
1408 | }; | 1500 | }; |
1409 | 1501 | ||
1410 | static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec) | 1502 | static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec) |
1411 | { | 1503 | { |
1412 | unsigned int present; | 1504 | struct alc_spec *spec = codec->spec; |
1413 | unsigned int bits; | ||
1414 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
1415 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
1416 | bits = present ? HDA_AMP_MUTE : 0; | ||
1417 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
1418 | HDA_AMP_MUTE, bits); | ||
1419 | } | ||
1420 | 1505 | ||
1421 | static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec, | 1506 | spec->autocfg.hp_pins[0] = 0x15; |
1422 | unsigned int res) | 1507 | spec->autocfg.speaker_pins[0] = 0x14; |
1423 | { | 1508 | alc_automute_amp(codec); |
1424 | if (res >> 26 == ALC880_HP_EVENT) | ||
1425 | alc888_acer_aspire_4930g_automute(codec); | ||
1426 | } | 1509 | } |
1427 | 1510 | ||
1428 | /* | 1511 | /* |
@@ -2390,21 +2473,6 @@ static struct hda_verb alc880_beep_init_verbs[] = { | |||
2390 | { } | 2473 | { } |
2391 | }; | 2474 | }; |
2392 | 2475 | ||
2393 | /* toggle speaker-output according to the hp-jack state */ | ||
2394 | static void alc880_uniwill_hp_automute(struct hda_codec *codec) | ||
2395 | { | ||
2396 | unsigned int present; | ||
2397 | unsigned char bits; | ||
2398 | |||
2399 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
2400 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
2401 | bits = present ? HDA_AMP_MUTE : 0; | ||
2402 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
2403 | HDA_AMP_MUTE, bits); | ||
2404 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
2405 | HDA_AMP_MUTE, bits); | ||
2406 | } | ||
2407 | |||
2408 | /* auto-toggle front mic */ | 2476 | /* auto-toggle front mic */ |
2409 | static void alc880_uniwill_mic_automute(struct hda_codec *codec) | 2477 | static void alc880_uniwill_mic_automute(struct hda_codec *codec) |
2410 | { | 2478 | { |
@@ -2417,9 +2485,14 @@ static void alc880_uniwill_mic_automute(struct hda_codec *codec) | |||
2417 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); | 2485 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); |
2418 | } | 2486 | } |
2419 | 2487 | ||
2420 | static void alc880_uniwill_automute(struct hda_codec *codec) | 2488 | static void alc880_uniwill_init_hook(struct hda_codec *codec) |
2421 | { | 2489 | { |
2422 | alc880_uniwill_hp_automute(codec); | 2490 | struct alc_spec *spec = codec->spec; |
2491 | |||
2492 | spec->autocfg.hp_pins[0] = 0x14; | ||
2493 | spec->autocfg.speaker_pins[0] = 0x15; | ||
2494 | spec->autocfg.speaker_pins[0] = 0x16; | ||
2495 | alc_automute_amp(codec); | ||
2423 | alc880_uniwill_mic_automute(codec); | 2496 | alc880_uniwill_mic_automute(codec); |
2424 | } | 2497 | } |
2425 | 2498 | ||
@@ -2430,24 +2503,22 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, | |||
2430 | * definition. 4bit tag is placed at 28 bit! | 2503 | * definition. 4bit tag is placed at 28 bit! |
2431 | */ | 2504 | */ |
2432 | switch (res >> 28) { | 2505 | switch (res >> 28) { |
2433 | case ALC880_HP_EVENT: | ||
2434 | alc880_uniwill_hp_automute(codec); | ||
2435 | break; | ||
2436 | case ALC880_MIC_EVENT: | 2506 | case ALC880_MIC_EVENT: |
2437 | alc880_uniwill_mic_automute(codec); | 2507 | alc880_uniwill_mic_automute(codec); |
2438 | break; | 2508 | break; |
2509 | default: | ||
2510 | alc_automute_amp_unsol_event(codec, res); | ||
2511 | break; | ||
2439 | } | 2512 | } |
2440 | } | 2513 | } |
2441 | 2514 | ||
2442 | static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) | 2515 | static void alc880_uniwill_p53_init_hook(struct hda_codec *codec) |
2443 | { | 2516 | { |
2444 | unsigned int present; | 2517 | struct alc_spec *spec = codec->spec; |
2445 | unsigned char bits; | ||
2446 | 2518 | ||
2447 | present = snd_hda_codec_read(codec, 0x14, 0, | 2519 | spec->autocfg.hp_pins[0] = 0x14; |
2448 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 2520 | spec->autocfg.speaker_pins[0] = 0x15; |
2449 | bits = present ? HDA_AMP_MUTE : 0; | 2521 | alc_automute_amp(codec); |
2450 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits); | ||
2451 | } | 2522 | } |
2452 | 2523 | ||
2453 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) | 2524 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) |
@@ -2469,10 +2540,10 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, | |||
2469 | /* Looks like the unsol event is incompatible with the standard | 2540 | /* Looks like the unsol event is incompatible with the standard |
2470 | * definition. 4bit tag is placed at 28 bit! | 2541 | * definition. 4bit tag is placed at 28 bit! |
2471 | */ | 2542 | */ |
2472 | if ((res >> 28) == ALC880_HP_EVENT) | ||
2473 | alc880_uniwill_p53_hp_automute(codec); | ||
2474 | if ((res >> 28) == ALC880_DCVOL_EVENT) | 2543 | if ((res >> 28) == ALC880_DCVOL_EVENT) |
2475 | alc880_uniwill_p53_dcvol_automute(codec); | 2544 | alc880_uniwill_p53_dcvol_automute(codec); |
2545 | else | ||
2546 | alc_automute_amp_unsol_event(codec, res); | ||
2476 | } | 2547 | } |
2477 | 2548 | ||
2478 | /* | 2549 | /* |
@@ -2704,30 +2775,18 @@ static struct hda_verb alc880_lg_init_verbs[] = { | |||
2704 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 2775 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
2705 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2776 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2706 | /* jack sense */ | 2777 | /* jack sense */ |
2707 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, | 2778 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
2708 | { } | 2779 | { } |
2709 | }; | 2780 | }; |
2710 | 2781 | ||
2711 | /* toggle speaker-output according to the hp-jack state */ | 2782 | /* toggle speaker-output according to the hp-jack state */ |
2712 | static void alc880_lg_automute(struct hda_codec *codec) | 2783 | static void alc880_lg_init_hook(struct hda_codec *codec) |
2713 | { | 2784 | { |
2714 | unsigned int present; | 2785 | struct alc_spec *spec = codec->spec; |
2715 | unsigned char bits; | ||
2716 | |||
2717 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
2718 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
2719 | bits = present ? HDA_AMP_MUTE : 0; | ||
2720 | snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, | ||
2721 | HDA_AMP_MUTE, bits); | ||
2722 | } | ||
2723 | 2786 | ||
2724 | static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) | 2787 | spec->autocfg.hp_pins[0] = 0x1b; |
2725 | { | 2788 | spec->autocfg.speaker_pins[0] = 0x17; |
2726 | /* Looks like the unsol event is incompatible with the standard | 2789 | alc_automute_amp(codec); |
2727 | * definition. 4bit tag is placed at 28 bit! | ||
2728 | */ | ||
2729 | if ((res >> 28) == 0x01) | ||
2730 | alc880_lg_automute(codec); | ||
2731 | } | 2790 | } |
2732 | 2791 | ||
2733 | /* | 2792 | /* |
@@ -2801,30 +2860,18 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { | |||
2801 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 2860 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
2802 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2861 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2803 | /* jack sense */ | 2862 | /* jack sense */ |
2804 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, | 2863 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
2805 | { } | 2864 | { } |
2806 | }; | 2865 | }; |
2807 | 2866 | ||
2808 | /* toggle speaker-output according to the hp-jack state */ | 2867 | /* toggle speaker-output according to the hp-jack state */ |
2809 | static void alc880_lg_lw_automute(struct hda_codec *codec) | 2868 | static void alc880_lg_lw_init_hook(struct hda_codec *codec) |
2810 | { | 2869 | { |
2811 | unsigned int present; | 2870 | struct alc_spec *spec = codec->spec; |
2812 | unsigned char bits; | ||
2813 | 2871 | ||
2814 | present = snd_hda_codec_read(codec, 0x1b, 0, | 2872 | spec->autocfg.hp_pins[0] = 0x1b; |
2815 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 2873 | spec->autocfg.speaker_pins[0] = 0x14; |
2816 | bits = present ? HDA_AMP_MUTE : 0; | 2874 | alc_automute_amp(codec); |
2817 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
2818 | HDA_AMP_MUTE, bits); | ||
2819 | } | ||
2820 | |||
2821 | static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) | ||
2822 | { | ||
2823 | /* Looks like the unsol event is incompatible with the standard | ||
2824 | * definition. 4bit tag is placed at 28 bit! | ||
2825 | */ | ||
2826 | if ((res >> 28) == 0x01) | ||
2827 | alc880_lg_lw_automute(codec); | ||
2828 | } | 2875 | } |
2829 | 2876 | ||
2830 | static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { | 2877 | static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { |
@@ -2871,16 +2918,10 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = { | |||
2871 | /* toggle speaker-output according to the hp-jack state */ | 2918 | /* toggle speaker-output according to the hp-jack state */ |
2872 | static void alc880_medion_rim_automute(struct hda_codec *codec) | 2919 | static void alc880_medion_rim_automute(struct hda_codec *codec) |
2873 | { | 2920 | { |
2874 | unsigned int present; | 2921 | struct alc_spec *spec = codec->spec; |
2875 | unsigned char bits; | 2922 | alc_automute_amp(codec); |
2876 | 2923 | /* toggle EAPD */ | |
2877 | present = snd_hda_codec_read(codec, 0x14, 0, | 2924 | if (spec->jack_present) |
2878 | AC_VERB_GET_PIN_SENSE, 0) | ||
2879 | & AC_PINSENSE_PRESENCE; | ||
2880 | bits = present ? HDA_AMP_MUTE : 0; | ||
2881 | snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, | ||
2882 | HDA_AMP_MUTE, bits); | ||
2883 | if (present) | ||
2884 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); | 2925 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); |
2885 | else | 2926 | else |
2886 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); | 2927 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); |
@@ -2896,6 +2937,15 @@ static void alc880_medion_rim_unsol_event(struct hda_codec *codec, | |||
2896 | alc880_medion_rim_automute(codec); | 2937 | alc880_medion_rim_automute(codec); |
2897 | } | 2938 | } |
2898 | 2939 | ||
2940 | static void alc880_medion_rim_init_hook(struct hda_codec *codec) | ||
2941 | { | ||
2942 | struct alc_spec *spec = codec->spec; | ||
2943 | |||
2944 | spec->autocfg.hp_pins[0] = 0x14; | ||
2945 | spec->autocfg.speaker_pins[0] = 0x1b; | ||
2946 | alc880_medion_rim_automute(codec); | ||
2947 | } | ||
2948 | |||
2899 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2949 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2900 | static struct hda_amp_list alc880_loopbacks[] = { | 2950 | static struct hda_amp_list alc880_loopbacks[] = { |
2901 | { 0x0b, HDA_INPUT, 0 }, | 2951 | { 0x0b, HDA_INPUT, 0 }, |
@@ -2924,8 +2974,7 @@ static int alc_init(struct hda_codec *codec) | |||
2924 | unsigned int i; | 2974 | unsigned int i; |
2925 | 2975 | ||
2926 | alc_fix_pll(codec); | 2976 | alc_fix_pll(codec); |
2927 | if (codec->vendor_id == 0x10ec0888) | 2977 | alc_auto_init_amp(codec, spec->init_amp); |
2928 | alc888_coef_init(codec); | ||
2929 | 2978 | ||
2930 | for (i = 0; i < spec->num_init_verbs; i++) | 2979 | for (i = 0; i < spec->num_init_verbs; i++) |
2931 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | 2980 | snd_hda_sequence_write(codec, spec->init_verbs[i]); |
@@ -3127,7 +3176,10 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
3127 | if (spec->no_analog) | 3176 | if (spec->no_analog) |
3128 | goto skip_analog; | 3177 | goto skip_analog; |
3129 | 3178 | ||
3179 | snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), | ||
3180 | "%s Analog", codec->chip_name); | ||
3130 | info->name = spec->stream_name_analog; | 3181 | info->name = spec->stream_name_analog; |
3182 | |||
3131 | if (spec->stream_analog_playback) { | 3183 | if (spec->stream_analog_playback) { |
3132 | if (snd_BUG_ON(!spec->multiout.dac_nids)) | 3184 | if (snd_BUG_ON(!spec->multiout.dac_nids)) |
3133 | return -EINVAL; | 3185 | return -EINVAL; |
@@ -3153,6 +3205,9 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
3153 | skip_analog: | 3205 | skip_analog: |
3154 | /* SPDIF for stream index #1 */ | 3206 | /* SPDIF for stream index #1 */ |
3155 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { | 3207 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { |
3208 | snprintf(spec->stream_name_digital, | ||
3209 | sizeof(spec->stream_name_digital), | ||
3210 | "%s Digital", codec->chip_name); | ||
3156 | codec->num_pcms = 2; | 3211 | codec->num_pcms = 2; |
3157 | codec->slave_dig_outs = spec->multiout.slave_dig_outs; | 3212 | codec->slave_dig_outs = spec->multiout.slave_dig_outs; |
3158 | info = spec->pcm_rec + 1; | 3213 | info = spec->pcm_rec + 1; |
@@ -3755,7 +3810,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3755 | .channel_mode = alc880_2_jack_modes, | 3810 | .channel_mode = alc880_2_jack_modes, |
3756 | .input_mux = &alc880_f1734_capture_source, | 3811 | .input_mux = &alc880_f1734_capture_source, |
3757 | .unsol_event = alc880_uniwill_p53_unsol_event, | 3812 | .unsol_event = alc880_uniwill_p53_unsol_event, |
3758 | .init_hook = alc880_uniwill_p53_hp_automute, | 3813 | .init_hook = alc880_uniwill_p53_init_hook, |
3759 | }, | 3814 | }, |
3760 | [ALC880_ASUS] = { | 3815 | [ALC880_ASUS] = { |
3761 | .mixers = { alc880_asus_mixer }, | 3816 | .mixers = { alc880_asus_mixer }, |
@@ -3832,7 +3887,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3832 | .need_dac_fix = 1, | 3887 | .need_dac_fix = 1, |
3833 | .input_mux = &alc880_capture_source, | 3888 | .input_mux = &alc880_capture_source, |
3834 | .unsol_event = alc880_uniwill_unsol_event, | 3889 | .unsol_event = alc880_uniwill_unsol_event, |
3835 | .init_hook = alc880_uniwill_automute, | 3890 | .init_hook = alc880_uniwill_init_hook, |
3836 | }, | 3891 | }, |
3837 | [ALC880_UNIWILL_P53] = { | 3892 | [ALC880_UNIWILL_P53] = { |
3838 | .mixers = { alc880_uniwill_p53_mixer }, | 3893 | .mixers = { alc880_uniwill_p53_mixer }, |
@@ -3844,7 +3899,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3844 | .channel_mode = alc880_threestack_modes, | 3899 | .channel_mode = alc880_threestack_modes, |
3845 | .input_mux = &alc880_capture_source, | 3900 | .input_mux = &alc880_capture_source, |
3846 | .unsol_event = alc880_uniwill_p53_unsol_event, | 3901 | .unsol_event = alc880_uniwill_p53_unsol_event, |
3847 | .init_hook = alc880_uniwill_p53_hp_automute, | 3902 | .init_hook = alc880_uniwill_p53_init_hook, |
3848 | }, | 3903 | }, |
3849 | [ALC880_FUJITSU] = { | 3904 | [ALC880_FUJITSU] = { |
3850 | .mixers = { alc880_fujitsu_mixer }, | 3905 | .mixers = { alc880_fujitsu_mixer }, |
@@ -3858,7 +3913,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3858 | .channel_mode = alc880_2_jack_modes, | 3913 | .channel_mode = alc880_2_jack_modes, |
3859 | .input_mux = &alc880_capture_source, | 3914 | .input_mux = &alc880_capture_source, |
3860 | .unsol_event = alc880_uniwill_p53_unsol_event, | 3915 | .unsol_event = alc880_uniwill_p53_unsol_event, |
3861 | .init_hook = alc880_uniwill_p53_hp_automute, | 3916 | .init_hook = alc880_uniwill_p53_init_hook, |
3862 | }, | 3917 | }, |
3863 | [ALC880_CLEVO] = { | 3918 | [ALC880_CLEVO] = { |
3864 | .mixers = { alc880_three_stack_mixer }, | 3919 | .mixers = { alc880_three_stack_mixer }, |
@@ -3883,8 +3938,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
3883 | .channel_mode = alc880_lg_ch_modes, | 3938 | .channel_mode = alc880_lg_ch_modes, |
3884 | .need_dac_fix = 1, | 3939 | .need_dac_fix = 1, |
3885 | .input_mux = &alc880_lg_capture_source, | 3940 | .input_mux = &alc880_lg_capture_source, |
3886 | .unsol_event = alc880_lg_unsol_event, | 3941 | .unsol_event = alc_automute_amp_unsol_event, |
3887 | .init_hook = alc880_lg_automute, | 3942 | .init_hook = alc880_lg_init_hook, |
3888 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3943 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3889 | .loopbacks = alc880_lg_loopbacks, | 3944 | .loopbacks = alc880_lg_loopbacks, |
3890 | #endif | 3945 | #endif |
@@ -3899,8 +3954,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
3899 | .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), | 3954 | .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), |
3900 | .channel_mode = alc880_lg_lw_modes, | 3955 | .channel_mode = alc880_lg_lw_modes, |
3901 | .input_mux = &alc880_lg_lw_capture_source, | 3956 | .input_mux = &alc880_lg_lw_capture_source, |
3902 | .unsol_event = alc880_lg_lw_unsol_event, | 3957 | .unsol_event = alc_automute_amp_unsol_event, |
3903 | .init_hook = alc880_lg_lw_automute, | 3958 | .init_hook = alc880_lg_lw_init_hook, |
3904 | }, | 3959 | }, |
3905 | [ALC880_MEDION_RIM] = { | 3960 | [ALC880_MEDION_RIM] = { |
3906 | .mixers = { alc880_medion_rim_mixer }, | 3961 | .mixers = { alc880_medion_rim_mixer }, |
@@ -3914,7 +3969,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3914 | .channel_mode = alc880_2_jack_modes, | 3969 | .channel_mode = alc880_2_jack_modes, |
3915 | .input_mux = &alc880_medion_rim_capture_source, | 3970 | .input_mux = &alc880_medion_rim_capture_source, |
3916 | .unsol_event = alc880_medion_rim_unsol_event, | 3971 | .unsol_event = alc880_medion_rim_unsol_event, |
3917 | .init_hook = alc880_medion_rim_automute, | 3972 | .init_hook = alc880_medion_rim_init_hook, |
3918 | }, | 3973 | }, |
3919 | #ifdef CONFIG_SND_DEBUG | 3974 | #ifdef CONFIG_SND_DEBUG |
3920 | [ALC880_TEST] = { | 3975 | [ALC880_TEST] = { |
@@ -4199,7 +4254,6 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec) | |||
4199 | struct alc_spec *spec = codec->spec; | 4254 | struct alc_spec *spec = codec->spec; |
4200 | int i; | 4255 | int i; |
4201 | 4256 | ||
4202 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
4203 | for (i = 0; i < spec->autocfg.line_outs; i++) { | 4257 | for (i = 0; i < spec->autocfg.line_outs; i++) { |
4204 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 4258 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
4205 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 4259 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -4304,6 +4358,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
4304 | spec->num_mux_defs = 1; | 4358 | spec->num_mux_defs = 1; |
4305 | spec->input_mux = &spec->private_imux[0]; | 4359 | spec->input_mux = &spec->private_imux[0]; |
4306 | 4360 | ||
4361 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); | ||
4362 | |||
4307 | return 1; | 4363 | return 1; |
4308 | } | 4364 | } |
4309 | 4365 | ||
@@ -4361,8 +4417,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
4361 | alc880_models, | 4417 | alc880_models, |
4362 | alc880_cfg_tbl); | 4418 | alc880_cfg_tbl); |
4363 | if (board_config < 0) { | 4419 | if (board_config < 0) { |
4364 | printk(KERN_INFO "hda_codec: Unknown model for ALC880, " | 4420 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
4365 | "trying auto-probe from BIOS...\n"); | 4421 | "trying auto-probe from BIOS...\n", codec->chip_name); |
4366 | board_config = ALC880_AUTO; | 4422 | board_config = ALC880_AUTO; |
4367 | } | 4423 | } |
4368 | 4424 | ||
@@ -4389,12 +4445,10 @@ static int patch_alc880(struct hda_codec *codec) | |||
4389 | if (board_config != ALC880_AUTO) | 4445 | if (board_config != ALC880_AUTO) |
4390 | setup_preset(spec, &alc880_presets[board_config]); | 4446 | setup_preset(spec, &alc880_presets[board_config]); |
4391 | 4447 | ||
4392 | spec->stream_name_analog = "ALC880 Analog"; | ||
4393 | spec->stream_analog_playback = &alc880_pcm_analog_playback; | 4448 | spec->stream_analog_playback = &alc880_pcm_analog_playback; |
4394 | spec->stream_analog_capture = &alc880_pcm_analog_capture; | 4449 | spec->stream_analog_capture = &alc880_pcm_analog_capture; |
4395 | spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; | 4450 | spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; |
4396 | 4451 | ||
4397 | spec->stream_name_digital = "ALC880 Digital"; | ||
4398 | spec->stream_digital_playback = &alc880_pcm_digital_playback; | 4452 | spec->stream_digital_playback = &alc880_pcm_digital_playback; |
4399 | spec->stream_digital_capture = &alc880_pcm_digital_capture; | 4453 | spec->stream_digital_capture = &alc880_pcm_digital_capture; |
4400 | 4454 | ||
@@ -5679,7 +5733,6 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) | |||
5679 | struct alc_spec *spec = codec->spec; | 5733 | struct alc_spec *spec = codec->spec; |
5680 | hda_nid_t nid; | 5734 | hda_nid_t nid; |
5681 | 5735 | ||
5682 | alc_subsystem_id(codec, 0x10, 0x15, 0x0f); | ||
5683 | nid = spec->autocfg.line_out_pins[0]; | 5736 | nid = spec->autocfg.line_out_pins[0]; |
5684 | if (nid) { | 5737 | if (nid) { |
5685 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 5738 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -5789,6 +5842,8 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
5789 | spec->num_mux_defs = 1; | 5842 | spec->num_mux_defs = 1; |
5790 | spec->input_mux = &spec->private_imux[0]; | 5843 | spec->input_mux = &spec->private_imux[0]; |
5791 | 5844 | ||
5845 | alc_ssid_check(codec, 0x10, 0x15, 0x0f); | ||
5846 | |||
5792 | return 1; | 5847 | return 1; |
5793 | } | 5848 | } |
5794 | 5849 | ||
@@ -6006,8 +6061,9 @@ static int patch_alc260(struct hda_codec *codec) | |||
6006 | alc260_models, | 6061 | alc260_models, |
6007 | alc260_cfg_tbl); | 6062 | alc260_cfg_tbl); |
6008 | if (board_config < 0) { | 6063 | if (board_config < 0) { |
6009 | snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " | 6064 | snd_printd(KERN_INFO "hda_codec: Unknown model for %s, " |
6010 | "trying auto-probe from BIOS...\n"); | 6065 | "trying auto-probe from BIOS...\n", |
6066 | codec->chip_name); | ||
6011 | board_config = ALC260_AUTO; | 6067 | board_config = ALC260_AUTO; |
6012 | } | 6068 | } |
6013 | 6069 | ||
@@ -6034,11 +6090,9 @@ static int patch_alc260(struct hda_codec *codec) | |||
6034 | if (board_config != ALC260_AUTO) | 6090 | if (board_config != ALC260_AUTO) |
6035 | setup_preset(spec, &alc260_presets[board_config]); | 6091 | setup_preset(spec, &alc260_presets[board_config]); |
6036 | 6092 | ||
6037 | spec->stream_name_analog = "ALC260 Analog"; | ||
6038 | spec->stream_analog_playback = &alc260_pcm_analog_playback; | 6093 | spec->stream_analog_playback = &alc260_pcm_analog_playback; |
6039 | spec->stream_analog_capture = &alc260_pcm_analog_capture; | 6094 | spec->stream_analog_capture = &alc260_pcm_analog_capture; |
6040 | 6095 | ||
6041 | spec->stream_name_digital = "ALC260 Digital"; | ||
6042 | spec->stream_digital_playback = &alc260_pcm_digital_playback; | 6096 | spec->stream_digital_playback = &alc260_pcm_digital_playback; |
6043 | spec->stream_digital_capture = &alc260_pcm_digital_capture; | 6097 | spec->stream_digital_capture = &alc260_pcm_digital_capture; |
6044 | 6098 | ||
@@ -6115,6 +6169,16 @@ static struct hda_input_mux alc882_capture_source = { | |||
6115 | { "CD", 0x4 }, | 6169 | { "CD", 0x4 }, |
6116 | }, | 6170 | }, |
6117 | }; | 6171 | }; |
6172 | |||
6173 | static struct hda_input_mux mb5_capture_source = { | ||
6174 | .num_items = 3, | ||
6175 | .items = { | ||
6176 | { "Mic", 0x1 }, | ||
6177 | { "Line", 0x2 }, | ||
6178 | { "CD", 0x4 }, | ||
6179 | }, | ||
6180 | }; | ||
6181 | |||
6118 | /* | 6182 | /* |
6119 | * 2ch mode | 6183 | * 2ch mode |
6120 | */ | 6184 | */ |
@@ -6244,6 +6308,20 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = { | |||
6244 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), | 6308 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), |
6245 | { } /* end */ | 6309 | { } /* end */ |
6246 | }; | 6310 | }; |
6311 | |||
6312 | static struct snd_kcontrol_new alc885_mb5_mixer[] = { | ||
6313 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
6314 | HDA_BIND_MUTE ("Front Playback Switch", 0x0d, 0x02, HDA_INPUT), | ||
6315 | HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
6316 | HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT), | ||
6317 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
6318 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
6319 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
6320 | HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
6321 | HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), | ||
6322 | HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT), | ||
6323 | { } /* end */ | ||
6324 | }; | ||
6247 | static struct snd_kcontrol_new alc882_w2jc_mixer[] = { | 6325 | static struct snd_kcontrol_new alc882_w2jc_mixer[] = { |
6248 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 6326 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
6249 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 6327 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
@@ -6471,6 +6549,38 @@ static struct hda_verb alc882_macpro_init_verbs[] = { | |||
6471 | { } | 6549 | { } |
6472 | }; | 6550 | }; |
6473 | 6551 | ||
6552 | /* Macbook 5,1 */ | ||
6553 | static struct hda_verb alc885_mb5_init_verbs[] = { | ||
6554 | /* Front mixer */ | ||
6555 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
6556 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
6557 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
6558 | /* LineOut mixer */ | ||
6559 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
6560 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
6561 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
6562 | /* Front Pin: output 0 (0x0d) */ | ||
6563 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, | ||
6564 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
6565 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
6566 | /* HP Pin: output 0 (0x0c) */ | ||
6567 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
6568 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
6569 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
6570 | /* Front Mic pin: input vref at 80% */ | ||
6571 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
6572 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
6573 | /* Line In pin */ | ||
6574 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
6575 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
6576 | |||
6577 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
6578 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
6579 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
6580 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
6581 | { } | ||
6582 | }; | ||
6583 | |||
6474 | /* Macbook Pro rev3 */ | 6584 | /* Macbook Pro rev3 */ |
6475 | static struct hda_verb alc885_mbp3_init_verbs[] = { | 6585 | static struct hda_verb alc885_mbp3_init_verbs[] = { |
6476 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | 6586 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ |
@@ -6560,45 +6670,23 @@ static struct hda_verb alc885_imac24_init_verbs[] = { | |||
6560 | }; | 6670 | }; |
6561 | 6671 | ||
6562 | /* Toggle speaker-output according to the hp-jack state */ | 6672 | /* Toggle speaker-output according to the hp-jack state */ |
6563 | static void alc885_imac24_automute(struct hda_codec *codec) | 6673 | static void alc885_imac24_automute_init_hook(struct hda_codec *codec) |
6564 | { | 6674 | { |
6565 | unsigned int present; | 6675 | struct alc_spec *spec = codec->spec; |
6566 | |||
6567 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
6568 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
6569 | snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, | ||
6570 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
6571 | snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, | ||
6572 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
6573 | } | ||
6574 | 6676 | ||
6575 | /* Processes unsolicited events. */ | 6677 | spec->autocfg.hp_pins[0] = 0x14; |
6576 | static void alc885_imac24_unsol_event(struct hda_codec *codec, | 6678 | spec->autocfg.speaker_pins[0] = 0x18; |
6577 | unsigned int res) | 6679 | spec->autocfg.speaker_pins[1] = 0x1a; |
6578 | { | 6680 | alc_automute_amp(codec); |
6579 | /* Headphone insertion or removal. */ | ||
6580 | if ((res >> 26) == ALC880_HP_EVENT) | ||
6581 | alc885_imac24_automute(codec); | ||
6582 | } | 6681 | } |
6583 | 6682 | ||
6584 | static void alc885_mbp3_automute(struct hda_codec *codec) | 6683 | static void alc885_mbp3_init_hook(struct hda_codec *codec) |
6585 | { | 6684 | { |
6586 | unsigned int present; | 6685 | struct alc_spec *spec = codec->spec; |
6587 | |||
6588 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
6589 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
6590 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
6591 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
6592 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
6593 | HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); | ||
6594 | 6686 | ||
6595 | } | 6687 | spec->autocfg.hp_pins[0] = 0x15; |
6596 | static void alc885_mbp3_unsol_event(struct hda_codec *codec, | 6688 | spec->autocfg.speaker_pins[0] = 0x14; |
6597 | unsigned int res) | 6689 | alc_automute_amp(codec); |
6598 | { | ||
6599 | /* Headphone insertion or removal. */ | ||
6600 | if ((res >> 26) == ALC880_HP_EVENT) | ||
6601 | alc885_mbp3_automute(codec); | ||
6602 | } | 6690 | } |
6603 | 6691 | ||
6604 | 6692 | ||
@@ -6623,24 +6711,25 @@ static struct hda_verb alc882_targa_verbs[] = { | |||
6623 | /* toggle speaker-output according to the hp-jack state */ | 6711 | /* toggle speaker-output according to the hp-jack state */ |
6624 | static void alc882_targa_automute(struct hda_codec *codec) | 6712 | static void alc882_targa_automute(struct hda_codec *codec) |
6625 | { | 6713 | { |
6626 | unsigned int present; | 6714 | struct alc_spec *spec = codec->spec; |
6627 | 6715 | alc_automute_amp(codec); | |
6628 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
6629 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
6630 | snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, | ||
6631 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
6632 | snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, | 6716 | snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, |
6633 | present ? 1 : 3); | 6717 | spec->jack_present ? 1 : 3); |
6718 | } | ||
6719 | |||
6720 | static void alc882_targa_init_hook(struct hda_codec *codec) | ||
6721 | { | ||
6722 | struct alc_spec *spec = codec->spec; | ||
6723 | |||
6724 | spec->autocfg.hp_pins[0] = 0x14; | ||
6725 | spec->autocfg.speaker_pins[0] = 0x1b; | ||
6726 | alc882_targa_automute(codec); | ||
6634 | } | 6727 | } |
6635 | 6728 | ||
6636 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) | 6729 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) |
6637 | { | 6730 | { |
6638 | /* Looks like the unsol event is incompatible with the standard | 6731 | if ((res >> 26) == ALC880_HP_EVENT) |
6639 | * definition. 4bit tag is placed at 26 bit! | ||
6640 | */ | ||
6641 | if (((res >> 26) == ALC880_HP_EVENT)) { | ||
6642 | alc882_targa_automute(codec); | 6732 | alc882_targa_automute(codec); |
6643 | } | ||
6644 | } | 6733 | } |
6645 | 6734 | ||
6646 | static struct hda_verb alc882_asus_a7j_verbs[] = { | 6735 | static struct hda_verb alc882_asus_a7j_verbs[] = { |
@@ -6722,7 +6811,7 @@ static void alc885_macpro_init_hook(struct hda_codec *codec) | |||
6722 | static void alc885_imac24_init_hook(struct hda_codec *codec) | 6811 | static void alc885_imac24_init_hook(struct hda_codec *codec) |
6723 | { | 6812 | { |
6724 | alc885_macpro_init_hook(codec); | 6813 | alc885_macpro_init_hook(codec); |
6725 | alc885_imac24_automute(codec); | 6814 | alc885_imac24_automute_init_hook(codec); |
6726 | } | 6815 | } |
6727 | 6816 | ||
6728 | /* | 6817 | /* |
@@ -6815,6 +6904,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { | |||
6815 | [ALC882_ASUS_A7J] = "asus-a7j", | 6904 | [ALC882_ASUS_A7J] = "asus-a7j", |
6816 | [ALC882_ASUS_A7M] = "asus-a7m", | 6905 | [ALC882_ASUS_A7M] = "asus-a7m", |
6817 | [ALC885_MACPRO] = "macpro", | 6906 | [ALC885_MACPRO] = "macpro", |
6907 | [ALC885_MB5] = "mb5", | ||
6818 | [ALC885_MBP3] = "mbp3", | 6908 | [ALC885_MBP3] = "mbp3", |
6819 | [ALC885_IMAC24] = "imac24", | 6909 | [ALC885_IMAC24] = "imac24", |
6820 | [ALC882_AUTO] = "auto", | 6910 | [ALC882_AUTO] = "auto", |
@@ -6892,8 +6982,20 @@ static struct alc_config_preset alc882_presets[] = { | |||
6892 | .input_mux = &alc882_capture_source, | 6982 | .input_mux = &alc882_capture_source, |
6893 | .dig_out_nid = ALC882_DIGOUT_NID, | 6983 | .dig_out_nid = ALC882_DIGOUT_NID, |
6894 | .dig_in_nid = ALC882_DIGIN_NID, | 6984 | .dig_in_nid = ALC882_DIGIN_NID, |
6895 | .unsol_event = alc885_mbp3_unsol_event, | 6985 | .unsol_event = alc_automute_amp_unsol_event, |
6896 | .init_hook = alc885_mbp3_automute, | 6986 | .init_hook = alc885_mbp3_init_hook, |
6987 | }, | ||
6988 | [ALC885_MB5] = { | ||
6989 | .mixers = { alc885_mb5_mixer }, | ||
6990 | .init_verbs = { alc885_mb5_init_verbs, | ||
6991 | alc880_gpio1_init_verbs }, | ||
6992 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
6993 | .dac_nids = alc882_dac_nids, | ||
6994 | .channel_mode = alc885_mbp_6ch_modes, | ||
6995 | .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes), | ||
6996 | .input_mux = &mb5_capture_source, | ||
6997 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
6998 | .dig_in_nid = ALC882_DIGIN_NID, | ||
6897 | }, | 6999 | }, |
6898 | [ALC885_MACPRO] = { | 7000 | [ALC885_MACPRO] = { |
6899 | .mixers = { alc882_macpro_mixer }, | 7001 | .mixers = { alc882_macpro_mixer }, |
@@ -6917,7 +7019,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
6917 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), | 7019 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), |
6918 | .channel_mode = alc882_ch_modes, | 7020 | .channel_mode = alc882_ch_modes, |
6919 | .input_mux = &alc882_capture_source, | 7021 | .input_mux = &alc882_capture_source, |
6920 | .unsol_event = alc885_imac24_unsol_event, | 7022 | .unsol_event = alc_automute_amp_unsol_event, |
6921 | .init_hook = alc885_imac24_init_hook, | 7023 | .init_hook = alc885_imac24_init_hook, |
6922 | }, | 7024 | }, |
6923 | [ALC882_TARGA] = { | 7025 | [ALC882_TARGA] = { |
@@ -6934,7 +7036,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
6934 | .need_dac_fix = 1, | 7036 | .need_dac_fix = 1, |
6935 | .input_mux = &alc882_capture_source, | 7037 | .input_mux = &alc882_capture_source, |
6936 | .unsol_event = alc882_targa_unsol_event, | 7038 | .unsol_event = alc882_targa_unsol_event, |
6937 | .init_hook = alc882_targa_automute, | 7039 | .init_hook = alc882_targa_init_hook, |
6938 | }, | 7040 | }, |
6939 | [ALC882_ASUS_A7J] = { | 7041 | [ALC882_ASUS_A7J] = { |
6940 | .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, | 7042 | .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, |
@@ -7014,7 +7116,6 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec) | |||
7014 | struct alc_spec *spec = codec->spec; | 7116 | struct alc_spec *spec = codec->spec; |
7015 | int i; | 7117 | int i; |
7016 | 7118 | ||
7017 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
7018 | for (i = 0; i <= HDA_SIDE; i++) { | 7119 | for (i = 0; i <= HDA_SIDE; i++) { |
7019 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 7120 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
7020 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 7121 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -7197,10 +7298,17 @@ static int patch_alc882(struct hda_codec *codec) | |||
7197 | case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ | 7298 | case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ |
7198 | case 0x106b00a4: /* MacbookPro4,1 */ | 7299 | case 0x106b00a4: /* MacbookPro4,1 */ |
7199 | case 0x106b2c00: /* Macbook Pro rev3 */ | 7300 | case 0x106b2c00: /* Macbook Pro rev3 */ |
7200 | case 0x106b3600: /* Macbook 3.1 */ | 7301 | /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */ |
7201 | case 0x106b3800: /* MacbookPro4,1 - latter revision */ | 7302 | case 0x106b3800: /* MacbookPro4,1 - latter revision */ |
7202 | board_config = ALC885_MBP3; | 7303 | board_config = ALC885_MBP3; |
7203 | break; | 7304 | break; |
7305 | case 0x106b3f00: /* Macbook 5,1 */ | ||
7306 | case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense | ||
7307 | * seems not working, so apparently | ||
7308 | * no perfect solution yet | ||
7309 | */ | ||
7310 | board_config = ALC885_MB5; | ||
7311 | break; | ||
7204 | default: | 7312 | default: |
7205 | /* ALC889A is handled better as ALC888-compatible */ | 7313 | /* ALC889A is handled better as ALC888-compatible */ |
7206 | if (codec->revision_id == 0x100101 || | 7314 | if (codec->revision_id == 0x100101 || |
@@ -7208,8 +7316,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
7208 | alc_free(codec); | 7316 | alc_free(codec); |
7209 | return patch_alc883(codec); | 7317 | return patch_alc883(codec); |
7210 | } | 7318 | } |
7211 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, " | 7319 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
7212 | "trying auto-probe from BIOS...\n"); | 7320 | "trying auto-probe from BIOS...\n", |
7321 | codec->chip_name); | ||
7213 | board_config = ALC882_AUTO; | 7322 | board_config = ALC882_AUTO; |
7214 | } | 7323 | } |
7215 | } | 7324 | } |
@@ -7239,14 +7348,6 @@ static int patch_alc882(struct hda_codec *codec) | |||
7239 | if (board_config != ALC882_AUTO) | 7348 | if (board_config != ALC882_AUTO) |
7240 | setup_preset(spec, &alc882_presets[board_config]); | 7349 | setup_preset(spec, &alc882_presets[board_config]); |
7241 | 7350 | ||
7242 | if (codec->vendor_id == 0x10ec0885) { | ||
7243 | spec->stream_name_analog = "ALC885 Analog"; | ||
7244 | spec->stream_name_digital = "ALC885 Digital"; | ||
7245 | } else { | ||
7246 | spec->stream_name_analog = "ALC882 Analog"; | ||
7247 | spec->stream_name_digital = "ALC882 Digital"; | ||
7248 | } | ||
7249 | |||
7250 | spec->stream_analog_playback = &alc882_pcm_analog_playback; | 7351 | spec->stream_analog_playback = &alc882_pcm_analog_playback; |
7251 | spec->stream_analog_capture = &alc882_pcm_analog_capture; | 7352 | spec->stream_analog_capture = &alc882_pcm_analog_capture; |
7252 | /* FIXME: setup DAC5 */ | 7353 | /* FIXME: setup DAC5 */ |
@@ -7399,6 +7500,17 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = { | |||
7399 | }, | 7500 | }, |
7400 | }; | 7501 | }; |
7401 | 7502 | ||
7503 | static struct hda_input_mux alc889A_mb31_capture_source = { | ||
7504 | .num_items = 2, | ||
7505 | .items = { | ||
7506 | { "Mic", 0x0 }, | ||
7507 | /* Front Mic (0x01) unused */ | ||
7508 | { "Line", 0x2 }, | ||
7509 | /* Line 2 (0x03) unused */ | ||
7510 | /* CD (0x04) unsused? */ | ||
7511 | }, | ||
7512 | }; | ||
7513 | |||
7402 | /* | 7514 | /* |
7403 | * 2ch mode | 7515 | * 2ch mode |
7404 | */ | 7516 | */ |
@@ -7517,6 +7629,49 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = { | |||
7517 | { 8, alc883_sixstack_ch8_init }, | 7629 | { 8, alc883_sixstack_ch8_init }, |
7518 | }; | 7630 | }; |
7519 | 7631 | ||
7632 | /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ | ||
7633 | static struct hda_verb alc889A_mb31_ch2_init[] = { | ||
7634 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ | ||
7635 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
7636 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ | ||
7637 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ | ||
7638 | { } /* end */ | ||
7639 | }; | ||
7640 | |||
7641 | /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ | ||
7642 | static struct hda_verb alc889A_mb31_ch4_init[] = { | ||
7643 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ | ||
7644 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
7645 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ | ||
7646 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ | ||
7647 | { } /* end */ | ||
7648 | }; | ||
7649 | |||
7650 | /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ | ||
7651 | static struct hda_verb alc889A_mb31_ch5_init[] = { | ||
7652 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ | ||
7653 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
7654 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ | ||
7655 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ | ||
7656 | { } /* end */ | ||
7657 | }; | ||
7658 | |||
7659 | /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ | ||
7660 | static struct hda_verb alc889A_mb31_ch6_init[] = { | ||
7661 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ | ||
7662 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ | ||
7663 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ | ||
7664 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ | ||
7665 | { } /* end */ | ||
7666 | }; | ||
7667 | |||
7668 | static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { | ||
7669 | { 2, alc889A_mb31_ch2_init }, | ||
7670 | { 4, alc889A_mb31_ch4_init }, | ||
7671 | { 5, alc889A_mb31_ch5_init }, | ||
7672 | { 6, alc889A_mb31_ch6_init }, | ||
7673 | }; | ||
7674 | |||
7520 | static struct hda_verb alc883_medion_eapd_verbs[] = { | 7675 | static struct hda_verb alc883_medion_eapd_verbs[] = { |
7521 | /* eanable EAPD on medion laptop */ | 7676 | /* eanable EAPD on medion laptop */ |
7522 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | 7677 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, |
@@ -7782,8 +7937,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { | |||
7782 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), | 7937 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), |
7783 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 7938 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
7784 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | 7939 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), |
7785 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
7786 | HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT), | ||
7787 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 7940 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
7788 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 7941 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
7789 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 7942 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
@@ -7797,6 +7950,32 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { | |||
7797 | { } /* end */ | 7950 | { } /* end */ |
7798 | }; | 7951 | }; |
7799 | 7952 | ||
7953 | static struct snd_kcontrol_new alc889A_mb31_mixer[] = { | ||
7954 | /* Output mixers */ | ||
7955 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
7956 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), | ||
7957 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
7958 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), | ||
7959 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00, | ||
7960 | HDA_OUTPUT), | ||
7961 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT), | ||
7962 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT), | ||
7963 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT), | ||
7964 | /* Output switches */ | ||
7965 | HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT), | ||
7966 | HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), | ||
7967 | HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), | ||
7968 | /* Boost mixers */ | ||
7969 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), | ||
7970 | HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), | ||
7971 | /* Input mixers */ | ||
7972 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), | ||
7973 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), | ||
7974 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
7975 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
7976 | { } /* end */ | ||
7977 | }; | ||
7978 | |||
7800 | static struct hda_bind_ctls alc883_bind_cap_vol = { | 7979 | static struct hda_bind_ctls alc883_bind_cap_vol = { |
7801 | .ops = &snd_hda_bind_vol, | 7980 | .ops = &snd_hda_bind_vol, |
7802 | .values = { | 7981 | .values = { |
@@ -7932,16 +8111,14 @@ static struct hda_verb alc883_init_verbs[] = { | |||
7932 | }; | 8111 | }; |
7933 | 8112 | ||
7934 | /* toggle speaker-output according to the hp-jack state */ | 8113 | /* toggle speaker-output according to the hp-jack state */ |
7935 | static void alc883_mitac_hp_automute(struct hda_codec *codec) | 8114 | static void alc883_mitac_init_hook(struct hda_codec *codec) |
7936 | { | 8115 | { |
7937 | unsigned int present; | 8116 | struct alc_spec *spec = codec->spec; |
7938 | 8117 | ||
7939 | present = snd_hda_codec_read(codec, 0x15, 0, | 8118 | spec->autocfg.hp_pins[0] = 0x15; |
7940 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 8119 | spec->autocfg.speaker_pins[0] = 0x14; |
7941 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 8120 | spec->autocfg.speaker_pins[1] = 0x17; |
7942 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 8121 | alc_automute_amp(codec); |
7943 | snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, | ||
7944 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
7945 | } | 8122 | } |
7946 | 8123 | ||
7947 | /* auto-toggle front mic */ | 8124 | /* auto-toggle front mic */ |
@@ -7958,25 +8135,6 @@ static void alc883_mitac_mic_automute(struct hda_codec *codec) | |||
7958 | } | 8135 | } |
7959 | */ | 8136 | */ |
7960 | 8137 | ||
7961 | static void alc883_mitac_automute(struct hda_codec *codec) | ||
7962 | { | ||
7963 | alc883_mitac_hp_automute(codec); | ||
7964 | /* alc883_mitac_mic_automute(codec); */ | ||
7965 | } | ||
7966 | |||
7967 | static void alc883_mitac_unsol_event(struct hda_codec *codec, | ||
7968 | unsigned int res) | ||
7969 | { | ||
7970 | switch (res >> 26) { | ||
7971 | case ALC880_HP_EVENT: | ||
7972 | alc883_mitac_hp_automute(codec); | ||
7973 | break; | ||
7974 | case ALC880_MIC_EVENT: | ||
7975 | /* alc883_mitac_mic_automute(codec); */ | ||
7976 | break; | ||
7977 | } | ||
7978 | } | ||
7979 | |||
7980 | static struct hda_verb alc883_mitac_verbs[] = { | 8138 | static struct hda_verb alc883_mitac_verbs[] = { |
7981 | /* HP */ | 8139 | /* HP */ |
7982 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 8140 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -8094,29 +8252,15 @@ static struct hda_verb alc888_6st_dell_verbs[] = { | |||
8094 | { } | 8252 | { } |
8095 | }; | 8253 | }; |
8096 | 8254 | ||
8097 | static void alc888_3st_hp_front_automute(struct hda_codec *codec) | 8255 | static void alc888_3st_hp_init_hook(struct hda_codec *codec) |
8098 | { | 8256 | { |
8099 | unsigned int present, bits; | 8257 | struct alc_spec *spec = codec->spec; |
8100 | |||
8101 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
8102 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8103 | bits = present ? HDA_AMP_MUTE : 0; | ||
8104 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
8105 | HDA_AMP_MUTE, bits); | ||
8106 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
8107 | HDA_AMP_MUTE, bits); | ||
8108 | snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, | ||
8109 | HDA_AMP_MUTE, bits); | ||
8110 | } | ||
8111 | 8258 | ||
8112 | static void alc888_3st_hp_unsol_event(struct hda_codec *codec, | 8259 | spec->autocfg.hp_pins[0] = 0x1b; |
8113 | unsigned int res) | 8260 | spec->autocfg.speaker_pins[0] = 0x14; |
8114 | { | 8261 | spec->autocfg.speaker_pins[1] = 0x16; |
8115 | switch (res >> 26) { | 8262 | spec->autocfg.speaker_pins[2] = 0x18; |
8116 | case ALC880_HP_EVENT: | 8263 | alc_automute_amp(codec); |
8117 | alc888_3st_hp_front_automute(codec); | ||
8118 | break; | ||
8119 | } | ||
8120 | } | 8264 | } |
8121 | 8265 | ||
8122 | static struct hda_verb alc888_3st_hp_verbs[] = { | 8266 | static struct hda_verb alc888_3st_hp_verbs[] = { |
@@ -8213,56 +8357,18 @@ static struct hda_verb alc883_medion_md2_verbs[] = { | |||
8213 | }; | 8357 | }; |
8214 | 8358 | ||
8215 | /* toggle speaker-output according to the hp-jack state */ | 8359 | /* toggle speaker-output according to the hp-jack state */ |
8216 | static void alc883_medion_md2_automute(struct hda_codec *codec) | 8360 | static void alc883_medion_md2_init_hook(struct hda_codec *codec) |
8217 | { | ||
8218 | unsigned int present; | ||
8219 | |||
8220 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
8221 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8222 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
8223 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8224 | } | ||
8225 | |||
8226 | static void alc883_medion_md2_unsol_event(struct hda_codec *codec, | ||
8227 | unsigned int res) | ||
8228 | { | ||
8229 | if ((res >> 26) == ALC880_HP_EVENT) | ||
8230 | alc883_medion_md2_automute(codec); | ||
8231 | } | ||
8232 | |||
8233 | /* toggle speaker-output according to the hp-jack state */ | ||
8234 | static void alc883_tagra_automute(struct hda_codec *codec) | ||
8235 | { | 8361 | { |
8236 | unsigned int present; | 8362 | struct alc_spec *spec = codec->spec; |
8237 | unsigned char bits; | ||
8238 | |||
8239 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
8240 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8241 | bits = present ? HDA_AMP_MUTE : 0; | ||
8242 | snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, | ||
8243 | HDA_AMP_MUTE, bits); | ||
8244 | snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, | ||
8245 | present ? 1 : 3); | ||
8246 | } | ||
8247 | 8363 | ||
8248 | static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) | 8364 | spec->autocfg.hp_pins[0] = 0x14; |
8249 | { | 8365 | spec->autocfg.speaker_pins[0] = 0x15; |
8250 | if ((res >> 26) == ALC880_HP_EVENT) | 8366 | alc_automute_amp(codec); |
8251 | alc883_tagra_automute(codec); | ||
8252 | } | 8367 | } |
8253 | 8368 | ||
8254 | /* toggle speaker-output according to the hp-jack state */ | 8369 | /* toggle speaker-output according to the hp-jack state */ |
8255 | static void alc883_clevo_m720_hp_automute(struct hda_codec *codec) | 8370 | #define alc883_tagra_init_hook alc882_targa_init_hook |
8256 | { | 8371 | #define alc883_tagra_unsol_event alc882_targa_unsol_event |
8257 | unsigned int present; | ||
8258 | unsigned char bits; | ||
8259 | |||
8260 | present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0) | ||
8261 | & AC_PINSENSE_PRESENCE; | ||
8262 | bits = present ? HDA_AMP_MUTE : 0; | ||
8263 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
8264 | HDA_AMP_MUTE, bits); | ||
8265 | } | ||
8266 | 8372 | ||
8267 | static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) | 8373 | static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) |
8268 | { | 8374 | { |
@@ -8274,9 +8380,13 @@ static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) | |||
8274 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 8380 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
8275 | } | 8381 | } |
8276 | 8382 | ||
8277 | static void alc883_clevo_m720_automute(struct hda_codec *codec) | 8383 | static void alc883_clevo_m720_init_hook(struct hda_codec *codec) |
8278 | { | 8384 | { |
8279 | alc883_clevo_m720_hp_automute(codec); | 8385 | struct alc_spec *spec = codec->spec; |
8386 | |||
8387 | spec->autocfg.hp_pins[0] = 0x15; | ||
8388 | spec->autocfg.speaker_pins[0] = 0x14; | ||
8389 | alc_automute_amp(codec); | ||
8280 | alc883_clevo_m720_mic_automute(codec); | 8390 | alc883_clevo_m720_mic_automute(codec); |
8281 | } | 8391 | } |
8282 | 8392 | ||
@@ -8284,52 +8394,32 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, | |||
8284 | unsigned int res) | 8394 | unsigned int res) |
8285 | { | 8395 | { |
8286 | switch (res >> 26) { | 8396 | switch (res >> 26) { |
8287 | case ALC880_HP_EVENT: | ||
8288 | alc883_clevo_m720_hp_automute(codec); | ||
8289 | break; | ||
8290 | case ALC880_MIC_EVENT: | 8397 | case ALC880_MIC_EVENT: |
8291 | alc883_clevo_m720_mic_automute(codec); | 8398 | alc883_clevo_m720_mic_automute(codec); |
8292 | break; | 8399 | break; |
8400 | default: | ||
8401 | alc_automute_amp_unsol_event(codec, res); | ||
8402 | break; | ||
8293 | } | 8403 | } |
8294 | } | 8404 | } |
8295 | 8405 | ||
8296 | /* toggle speaker-output according to the hp-jack state */ | 8406 | /* toggle speaker-output according to the hp-jack state */ |
8297 | static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec) | 8407 | static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec) |
8298 | { | 8408 | { |
8299 | unsigned int present; | 8409 | struct alc_spec *spec = codec->spec; |
8300 | unsigned char bits; | ||
8301 | |||
8302 | present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) | ||
8303 | & AC_PINSENSE_PRESENCE; | ||
8304 | bits = present ? HDA_AMP_MUTE : 0; | ||
8305 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
8306 | HDA_AMP_MUTE, bits); | ||
8307 | } | ||
8308 | 8410 | ||
8309 | static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec, | 8411 | spec->autocfg.hp_pins[0] = 0x14; |
8310 | unsigned int res) | 8412 | spec->autocfg.speaker_pins[0] = 0x15; |
8311 | { | 8413 | alc_automute_amp(codec); |
8312 | if ((res >> 26) == ALC880_HP_EVENT) | ||
8313 | alc883_2ch_fujitsu_pi2515_automute(codec); | ||
8314 | } | 8414 | } |
8315 | 8415 | ||
8316 | static void alc883_haier_w66_automute(struct hda_codec *codec) | 8416 | static void alc883_haier_w66_init_hook(struct hda_codec *codec) |
8317 | { | 8417 | { |
8318 | unsigned int present; | 8418 | struct alc_spec *spec = codec->spec; |
8319 | unsigned char bits; | ||
8320 | |||
8321 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
8322 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8323 | bits = present ? 0x80 : 0; | ||
8324 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
8325 | 0x80, bits); | ||
8326 | } | ||
8327 | 8419 | ||
8328 | static void alc883_haier_w66_unsol_event(struct hda_codec *codec, | 8420 | spec->autocfg.hp_pins[0] = 0x1b; |
8329 | unsigned int res) | 8421 | spec->autocfg.speaker_pins[0] = 0x14; |
8330 | { | 8422 | alc_automute_amp(codec); |
8331 | if ((res >> 26) == ALC880_HP_EVENT) | ||
8332 | alc883_haier_w66_automute(codec); | ||
8333 | } | 8423 | } |
8334 | 8424 | ||
8335 | static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | 8425 | static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) |
@@ -8368,23 +8458,14 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, | |||
8368 | } | 8458 | } |
8369 | 8459 | ||
8370 | /* toggle speaker-output according to the hp-jack state */ | 8460 | /* toggle speaker-output according to the hp-jack state */ |
8371 | static void alc883_acer_aspire_automute(struct hda_codec *codec) | 8461 | static void alc883_acer_aspire_init_hook(struct hda_codec *codec) |
8372 | { | 8462 | { |
8373 | unsigned int present; | 8463 | struct alc_spec *spec = codec->spec; |
8374 | |||
8375 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
8376 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8377 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
8378 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8379 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
8380 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8381 | } | ||
8382 | 8464 | ||
8383 | static void alc883_acer_aspire_unsol_event(struct hda_codec *codec, | 8465 | spec->autocfg.hp_pins[0] = 0x14; |
8384 | unsigned int res) | 8466 | spec->autocfg.speaker_pins[0] = 0x15; |
8385 | { | 8467 | spec->autocfg.speaker_pins[1] = 0x16; |
8386 | if ((res >> 26) == ALC880_HP_EVENT) | 8468 | alc_automute_amp(codec); |
8387 | alc883_acer_aspire_automute(codec); | ||
8388 | } | 8469 | } |
8389 | 8470 | ||
8390 | static struct hda_verb alc883_acer_eapd_verbs[] = { | 8471 | static struct hda_verb alc883_acer_eapd_verbs[] = { |
@@ -8405,75 +8486,29 @@ static struct hda_verb alc883_acer_eapd_verbs[] = { | |||
8405 | { } | 8486 | { } |
8406 | }; | 8487 | }; |
8407 | 8488 | ||
8408 | static void alc888_6st_dell_front_automute(struct hda_codec *codec) | 8489 | static void alc888_6st_dell_init_hook(struct hda_codec *codec) |
8409 | { | 8490 | { |
8410 | unsigned int present; | 8491 | struct alc_spec *spec = codec->spec; |
8411 | |||
8412 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
8413 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8414 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
8415 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8416 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
8417 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8418 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
8419 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8420 | snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, | ||
8421 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8422 | } | ||
8423 | 8492 | ||
8424 | static void alc888_6st_dell_unsol_event(struct hda_codec *codec, | 8493 | spec->autocfg.hp_pins[0] = 0x1b; |
8425 | unsigned int res) | 8494 | spec->autocfg.speaker_pins[0] = 0x14; |
8426 | { | 8495 | spec->autocfg.speaker_pins[1] = 0x15; |
8427 | switch (res >> 26) { | 8496 | spec->autocfg.speaker_pins[2] = 0x16; |
8428 | case ALC880_HP_EVENT: | 8497 | spec->autocfg.speaker_pins[3] = 0x17; |
8429 | /* printk(KERN_DEBUG "hp_event\n"); */ | 8498 | alc_automute_amp(codec); |
8430 | alc888_6st_dell_front_automute(codec); | ||
8431 | break; | ||
8432 | } | ||
8433 | } | 8499 | } |
8434 | 8500 | ||
8435 | static void alc888_lenovo_sky_front_automute(struct hda_codec *codec) | 8501 | static void alc888_lenovo_sky_init_hook(struct hda_codec *codec) |
8436 | { | 8502 | { |
8437 | unsigned int mute; | 8503 | struct alc_spec *spec = codec->spec; |
8438 | unsigned int present; | ||
8439 | |||
8440 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
8441 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
8442 | AC_VERB_GET_PIN_SENSE, 0); | ||
8443 | present = (present & 0x80000000) != 0; | ||
8444 | if (present) { | ||
8445 | /* mute internal speaker */ | ||
8446 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
8447 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
8448 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
8449 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
8450 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
8451 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
8452 | snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, | ||
8453 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
8454 | snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, | ||
8455 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
8456 | } else { | ||
8457 | /* unmute internal speaker if necessary */ | ||
8458 | mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); | ||
8459 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
8460 | HDA_AMP_MUTE, mute); | ||
8461 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
8462 | HDA_AMP_MUTE, mute); | ||
8463 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
8464 | HDA_AMP_MUTE, mute); | ||
8465 | snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, | ||
8466 | HDA_AMP_MUTE, mute); | ||
8467 | snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, | ||
8468 | HDA_AMP_MUTE, mute); | ||
8469 | } | ||
8470 | } | ||
8471 | 8504 | ||
8472 | static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec, | 8505 | spec->autocfg.hp_pins[0] = 0x1b; |
8473 | unsigned int res) | 8506 | spec->autocfg.speaker_pins[0] = 0x14; |
8474 | { | 8507 | spec->autocfg.speaker_pins[1] = 0x15; |
8475 | if ((res >> 26) == ALC880_HP_EVENT) | 8508 | spec->autocfg.speaker_pins[2] = 0x16; |
8476 | alc888_lenovo_sky_front_automute(codec); | 8509 | spec->autocfg.speaker_pins[3] = 0x17; |
8510 | spec->autocfg.speaker_pins[4] = 0x1a; | ||
8511 | alc_automute_amp(codec); | ||
8477 | } | 8512 | } |
8478 | 8513 | ||
8479 | /* | 8514 | /* |
@@ -8561,39 +8596,33 @@ static void alc883_nb_mic_automute(struct hda_codec *codec) | |||
8561 | 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); | 8596 | 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); |
8562 | } | 8597 | } |
8563 | 8598 | ||
8564 | static void alc883_M90V_speaker_automute(struct hda_codec *codec) | 8599 | static void alc883_M90V_init_hook(struct hda_codec *codec) |
8565 | { | 8600 | { |
8566 | unsigned int present; | 8601 | struct alc_spec *spec = codec->spec; |
8567 | unsigned char bits; | ||
8568 | 8602 | ||
8569 | present = snd_hda_codec_read(codec, 0x1b, 0, | 8603 | spec->autocfg.hp_pins[0] = 0x1b; |
8570 | AC_VERB_GET_PIN_SENSE, 0) | 8604 | spec->autocfg.speaker_pins[0] = 0x14; |
8571 | & AC_PINSENSE_PRESENCE; | 8605 | spec->autocfg.speaker_pins[1] = 0x15; |
8572 | bits = present ? 0 : PIN_OUT; | 8606 | spec->autocfg.speaker_pins[2] = 0x16; |
8573 | snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 8607 | alc_automute_pin(codec); |
8574 | bits); | ||
8575 | snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
8576 | bits); | ||
8577 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
8578 | bits); | ||
8579 | } | 8608 | } |
8580 | 8609 | ||
8581 | static void alc883_mode2_unsol_event(struct hda_codec *codec, | 8610 | static void alc883_mode2_unsol_event(struct hda_codec *codec, |
8582 | unsigned int res) | 8611 | unsigned int res) |
8583 | { | 8612 | { |
8584 | switch (res >> 26) { | 8613 | switch (res >> 26) { |
8585 | case ALC880_HP_EVENT: | ||
8586 | alc883_M90V_speaker_automute(codec); | ||
8587 | break; | ||
8588 | case ALC880_MIC_EVENT: | 8614 | case ALC880_MIC_EVENT: |
8589 | alc883_nb_mic_automute(codec); | 8615 | alc883_nb_mic_automute(codec); |
8590 | break; | 8616 | break; |
8617 | default: | ||
8618 | alc_sku_unsol_event(codec, res); | ||
8619 | break; | ||
8591 | } | 8620 | } |
8592 | } | 8621 | } |
8593 | 8622 | ||
8594 | static void alc883_mode2_inithook(struct hda_codec *codec) | 8623 | static void alc883_mode2_inithook(struct hda_codec *codec) |
8595 | { | 8624 | { |
8596 | alc883_M90V_speaker_automute(codec); | 8625 | alc883_M90V_init_hook(codec); |
8597 | alc883_nb_mic_automute(codec); | 8626 | alc883_nb_mic_automute(codec); |
8598 | } | 8627 | } |
8599 | 8628 | ||
@@ -8610,32 +8639,49 @@ static struct hda_verb alc888_asus_eee1601_verbs[] = { | |||
8610 | { } /* end */ | 8639 | { } /* end */ |
8611 | }; | 8640 | }; |
8612 | 8641 | ||
8613 | static void alc883_eee1601_speaker_automute(struct hda_codec *codec) | 8642 | static void alc883_eee1601_inithook(struct hda_codec *codec) |
8614 | { | 8643 | { |
8615 | unsigned int present; | 8644 | struct alc_spec *spec = codec->spec; |
8616 | unsigned char bits; | ||
8617 | 8645 | ||
8618 | present = snd_hda_codec_read(codec, 0x14, 0, | 8646 | spec->autocfg.hp_pins[0] = 0x14; |
8619 | AC_VERB_GET_PIN_SENSE, 0) | 8647 | spec->autocfg.speaker_pins[0] = 0x1b; |
8620 | & AC_PINSENSE_PRESENCE; | 8648 | alc_automute_pin(codec); |
8621 | bits = present ? 0 : PIN_OUT; | ||
8622 | snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
8623 | bits); | ||
8624 | } | 8649 | } |
8625 | 8650 | ||
8626 | static void alc883_eee1601_unsol_event(struct hda_codec *codec, | 8651 | static struct hda_verb alc889A_mb31_verbs[] = { |
8627 | unsigned int res) | 8652 | /* Init rear pin (used as headphone output) */ |
8653 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ | ||
8654 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ | ||
8655 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
8656 | /* Init line pin (used as output in 4ch and 6ch mode) */ | ||
8657 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */ | ||
8658 | /* Init line 2 pin (used as headphone out by default) */ | ||
8659 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */ | ||
8660 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */ | ||
8661 | { } /* end */ | ||
8662 | }; | ||
8663 | |||
8664 | /* Mute speakers according to the headphone jack state */ | ||
8665 | static void alc889A_mb31_automute(struct hda_codec *codec) | ||
8628 | { | 8666 | { |
8629 | switch (res >> 26) { | 8667 | unsigned int present; |
8630 | case ALC880_HP_EVENT: | 8668 | |
8631 | alc883_eee1601_speaker_automute(codec); | 8669 | /* Mute only in 2ch or 4ch mode */ |
8632 | break; | 8670 | if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) |
8671 | == 0x00) { | ||
8672 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
8673 | AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; | ||
8674 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
8675 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8676 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
8677 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8633 | } | 8678 | } |
8634 | } | 8679 | } |
8635 | 8680 | ||
8636 | static void alc883_eee1601_inithook(struct hda_codec *codec) | 8681 | static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) |
8637 | { | 8682 | { |
8638 | alc883_eee1601_speaker_automute(codec); | 8683 | if ((res >> 26) == ALC880_HP_EVENT) |
8684 | alc889A_mb31_automute(codec); | ||
8639 | } | 8685 | } |
8640 | 8686 | ||
8641 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 8687 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -8678,6 +8724,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { | |||
8678 | [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", | 8724 | [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", |
8679 | [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", | 8725 | [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", |
8680 | [ALC1200_ASUS_P5Q] = "asus-p5q", | 8726 | [ALC1200_ASUS_P5Q] = "asus-p5q", |
8727 | [ALC889A_MB31] = "mb31", | ||
8681 | [ALC883_AUTO] = "auto", | 8728 | [ALC883_AUTO] = "auto", |
8682 | }; | 8729 | }; |
8683 | 8730 | ||
@@ -8699,8 +8746,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8699 | ALC888_ACER_ASPIRE_4930G), | 8746 | ALC888_ACER_ASPIRE_4930G), |
8700 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", | 8747 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", |
8701 | ALC888_ACER_ASPIRE_4930G), | 8748 | ALC888_ACER_ASPIRE_4930G), |
8702 | /* default Acer */ | 8749 | /* default Acer -- disabled as it causes more problems. |
8703 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), | 8750 | * model=auto should work fine now |
8751 | */ | ||
8752 | /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ | ||
8704 | SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), | 8753 | SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), |
8705 | SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), | 8754 | SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), |
8706 | SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), | 8755 | SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), |
@@ -8848,7 +8897,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
8848 | .need_dac_fix = 1, | 8897 | .need_dac_fix = 1, |
8849 | .input_mux = &alc883_capture_source, | 8898 | .input_mux = &alc883_capture_source, |
8850 | .unsol_event = alc883_tagra_unsol_event, | 8899 | .unsol_event = alc883_tagra_unsol_event, |
8851 | .init_hook = alc883_tagra_automute, | 8900 | .init_hook = alc883_tagra_init_hook, |
8852 | }, | 8901 | }, |
8853 | [ALC883_TARGA_2ch_DIG] = { | 8902 | [ALC883_TARGA_2ch_DIG] = { |
8854 | .mixers = { alc883_tagra_2ch_mixer}, | 8903 | .mixers = { alc883_tagra_2ch_mixer}, |
@@ -8862,7 +8911,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
8862 | .channel_mode = alc883_3ST_2ch_modes, | 8911 | .channel_mode = alc883_3ST_2ch_modes, |
8863 | .input_mux = &alc883_capture_source, | 8912 | .input_mux = &alc883_capture_source, |
8864 | .unsol_event = alc883_tagra_unsol_event, | 8913 | .unsol_event = alc883_tagra_unsol_event, |
8865 | .init_hook = alc883_tagra_automute, | 8914 | .init_hook = alc883_tagra_init_hook, |
8866 | }, | 8915 | }, |
8867 | [ALC883_ACER] = { | 8916 | [ALC883_ACER] = { |
8868 | .mixers = { alc883_base_mixer }, | 8917 | .mixers = { alc883_base_mixer }, |
@@ -8887,8 +8936,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
8887 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 8936 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
8888 | .channel_mode = alc883_3ST_2ch_modes, | 8937 | .channel_mode = alc883_3ST_2ch_modes, |
8889 | .input_mux = &alc883_capture_source, | 8938 | .input_mux = &alc883_capture_source, |
8890 | .unsol_event = alc883_acer_aspire_unsol_event, | 8939 | .unsol_event = alc_automute_amp_unsol_event, |
8891 | .init_hook = alc883_acer_aspire_automute, | 8940 | .init_hook = alc883_acer_aspire_init_hook, |
8892 | }, | 8941 | }, |
8893 | [ALC888_ACER_ASPIRE_4930G] = { | 8942 | [ALC888_ACER_ASPIRE_4930G] = { |
8894 | .mixers = { alc888_base_mixer, | 8943 | .mixers = { alc888_base_mixer, |
@@ -8907,8 +8956,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
8907 | .num_mux_defs = | 8956 | .num_mux_defs = |
8908 | ARRAY_SIZE(alc888_2_capture_sources), | 8957 | ARRAY_SIZE(alc888_2_capture_sources), |
8909 | .input_mux = alc888_2_capture_sources, | 8958 | .input_mux = alc888_2_capture_sources, |
8910 | .unsol_event = alc888_acer_aspire_4930g_unsol_event, | 8959 | .unsol_event = alc_automute_amp_unsol_event, |
8911 | .init_hook = alc888_acer_aspire_4930g_automute, | 8960 | .init_hook = alc888_acer_aspire_4930g_init_hook, |
8912 | }, | 8961 | }, |
8913 | [ALC883_MEDION] = { | 8962 | [ALC883_MEDION] = { |
8914 | .mixers = { alc883_fivestack_mixer, | 8963 | .mixers = { alc883_fivestack_mixer, |
@@ -8932,8 +8981,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
8932 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 8981 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
8933 | .channel_mode = alc883_3ST_2ch_modes, | 8982 | .channel_mode = alc883_3ST_2ch_modes, |
8934 | .input_mux = &alc883_capture_source, | 8983 | .input_mux = &alc883_capture_source, |
8935 | .unsol_event = alc883_medion_md2_unsol_event, | 8984 | .unsol_event = alc_automute_amp_unsol_event, |
8936 | .init_hook = alc883_medion_md2_automute, | 8985 | .init_hook = alc883_medion_md2_init_hook, |
8937 | }, | 8986 | }, |
8938 | [ALC883_LAPTOP_EAPD] = { | 8987 | [ALC883_LAPTOP_EAPD] = { |
8939 | .mixers = { alc883_base_mixer }, | 8988 | .mixers = { alc883_base_mixer }, |
@@ -8954,7 +9003,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
8954 | .channel_mode = alc883_3ST_2ch_modes, | 9003 | .channel_mode = alc883_3ST_2ch_modes, |
8955 | .input_mux = &alc883_capture_source, | 9004 | .input_mux = &alc883_capture_source, |
8956 | .unsol_event = alc883_clevo_m720_unsol_event, | 9005 | .unsol_event = alc883_clevo_m720_unsol_event, |
8957 | .init_hook = alc883_clevo_m720_automute, | 9006 | .init_hook = alc883_clevo_m720_init_hook, |
8958 | }, | 9007 | }, |
8959 | [ALC883_LENOVO_101E_2ch] = { | 9008 | [ALC883_LENOVO_101E_2ch] = { |
8960 | .mixers = { alc883_lenovo_101e_2ch_mixer}, | 9009 | .mixers = { alc883_lenovo_101e_2ch_mixer}, |
@@ -8978,8 +9027,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
8978 | .channel_mode = alc883_3ST_2ch_modes, | 9027 | .channel_mode = alc883_3ST_2ch_modes, |
8979 | .need_dac_fix = 1, | 9028 | .need_dac_fix = 1, |
8980 | .input_mux = &alc883_lenovo_nb0763_capture_source, | 9029 | .input_mux = &alc883_lenovo_nb0763_capture_source, |
8981 | .unsol_event = alc883_medion_md2_unsol_event, | 9030 | .unsol_event = alc_automute_amp_unsol_event, |
8982 | .init_hook = alc883_medion_md2_automute, | 9031 | .init_hook = alc883_medion_md2_init_hook, |
8983 | }, | 9032 | }, |
8984 | [ALC888_LENOVO_MS7195_DIG] = { | 9033 | [ALC888_LENOVO_MS7195_DIG] = { |
8985 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 9034 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -9003,8 +9052,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9003 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 9052 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
9004 | .channel_mode = alc883_3ST_2ch_modes, | 9053 | .channel_mode = alc883_3ST_2ch_modes, |
9005 | .input_mux = &alc883_capture_source, | 9054 | .input_mux = &alc883_capture_source, |
9006 | .unsol_event = alc883_haier_w66_unsol_event, | 9055 | .unsol_event = alc_automute_amp_unsol_event, |
9007 | .init_hook = alc883_haier_w66_automute, | 9056 | .init_hook = alc883_haier_w66_init_hook, |
9008 | }, | 9057 | }, |
9009 | [ALC888_3ST_HP] = { | 9058 | [ALC888_3ST_HP] = { |
9010 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 9059 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -9015,8 +9064,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9015 | .channel_mode = alc888_3st_hp_modes, | 9064 | .channel_mode = alc888_3st_hp_modes, |
9016 | .need_dac_fix = 1, | 9065 | .need_dac_fix = 1, |
9017 | .input_mux = &alc883_capture_source, | 9066 | .input_mux = &alc883_capture_source, |
9018 | .unsol_event = alc888_3st_hp_unsol_event, | 9067 | .unsol_event = alc_automute_amp_unsol_event, |
9019 | .init_hook = alc888_3st_hp_front_automute, | 9068 | .init_hook = alc888_3st_hp_init_hook, |
9020 | }, | 9069 | }, |
9021 | [ALC888_6ST_DELL] = { | 9070 | [ALC888_6ST_DELL] = { |
9022 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 9071 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
@@ -9028,8 +9077,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9028 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), | 9077 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), |
9029 | .channel_mode = alc883_sixstack_modes, | 9078 | .channel_mode = alc883_sixstack_modes, |
9030 | .input_mux = &alc883_capture_source, | 9079 | .input_mux = &alc883_capture_source, |
9031 | .unsol_event = alc888_6st_dell_unsol_event, | 9080 | .unsol_event = alc_automute_amp_unsol_event, |
9032 | .init_hook = alc888_6st_dell_front_automute, | 9081 | .init_hook = alc888_6st_dell_init_hook, |
9033 | }, | 9082 | }, |
9034 | [ALC883_MITAC] = { | 9083 | [ALC883_MITAC] = { |
9035 | .mixers = { alc883_mitac_mixer }, | 9084 | .mixers = { alc883_mitac_mixer }, |
@@ -9039,8 +9088,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9039 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 9088 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
9040 | .channel_mode = alc883_3ST_2ch_modes, | 9089 | .channel_mode = alc883_3ST_2ch_modes, |
9041 | .input_mux = &alc883_capture_source, | 9090 | .input_mux = &alc883_capture_source, |
9042 | .unsol_event = alc883_mitac_unsol_event, | 9091 | .unsol_event = alc_automute_amp_unsol_event, |
9043 | .init_hook = alc883_mitac_automute, | 9092 | .init_hook = alc883_mitac_init_hook, |
9044 | }, | 9093 | }, |
9045 | [ALC883_FUJITSU_PI2515] = { | 9094 | [ALC883_FUJITSU_PI2515] = { |
9046 | .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, | 9095 | .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, |
@@ -9052,8 +9101,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9052 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 9101 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
9053 | .channel_mode = alc883_3ST_2ch_modes, | 9102 | .channel_mode = alc883_3ST_2ch_modes, |
9054 | .input_mux = &alc883_fujitsu_pi2515_capture_source, | 9103 | .input_mux = &alc883_fujitsu_pi2515_capture_source, |
9055 | .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event, | 9104 | .unsol_event = alc_automute_amp_unsol_event, |
9056 | .init_hook = alc883_2ch_fujitsu_pi2515_automute, | 9105 | .init_hook = alc883_2ch_fujitsu_pi2515_init_hook, |
9057 | }, | 9106 | }, |
9058 | [ALC888_FUJITSU_XA3530] = { | 9107 | [ALC888_FUJITSU_XA3530] = { |
9059 | .mixers = { alc888_base_mixer, alc883_chmode_mixer }, | 9108 | .mixers = { alc888_base_mixer, alc883_chmode_mixer }, |
@@ -9070,8 +9119,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9070 | .num_mux_defs = | 9119 | .num_mux_defs = |
9071 | ARRAY_SIZE(alc888_2_capture_sources), | 9120 | ARRAY_SIZE(alc888_2_capture_sources), |
9072 | .input_mux = alc888_2_capture_sources, | 9121 | .input_mux = alc888_2_capture_sources, |
9073 | .unsol_event = alc888_fujitsu_xa3530_unsol_event, | 9122 | .unsol_event = alc_automute_amp_unsol_event, |
9074 | .init_hook = alc888_fujitsu_xa3530_automute, | 9123 | .init_hook = alc888_fujitsu_xa3530_init_hook, |
9075 | }, | 9124 | }, |
9076 | [ALC888_LENOVO_SKY] = { | 9125 | [ALC888_LENOVO_SKY] = { |
9077 | .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, | 9126 | .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, |
@@ -9083,8 +9132,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9083 | .channel_mode = alc883_sixstack_modes, | 9132 | .channel_mode = alc883_sixstack_modes, |
9084 | .need_dac_fix = 1, | 9133 | .need_dac_fix = 1, |
9085 | .input_mux = &alc883_lenovo_sky_capture_source, | 9134 | .input_mux = &alc883_lenovo_sky_capture_source, |
9086 | .unsol_event = alc883_lenovo_sky_unsol_event, | 9135 | .unsol_event = alc_automute_amp_unsol_event, |
9087 | .init_hook = alc888_lenovo_sky_front_automute, | 9136 | .init_hook = alc888_lenovo_sky_init_hook, |
9088 | }, | 9137 | }, |
9089 | [ALC888_ASUS_M90V] = { | 9138 | [ALC888_ASUS_M90V] = { |
9090 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 9139 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -9112,7 +9161,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
9112 | .channel_mode = alc883_3ST_2ch_modes, | 9161 | .channel_mode = alc883_3ST_2ch_modes, |
9113 | .need_dac_fix = 1, | 9162 | .need_dac_fix = 1, |
9114 | .input_mux = &alc883_asus_eee1601_capture_source, | 9163 | .input_mux = &alc883_asus_eee1601_capture_source, |
9115 | .unsol_event = alc883_eee1601_unsol_event, | 9164 | .unsol_event = alc_sku_unsol_event, |
9116 | .init_hook = alc883_eee1601_inithook, | 9165 | .init_hook = alc883_eee1601_inithook, |
9117 | }, | 9166 | }, |
9118 | [ALC1200_ASUS_P5Q] = { | 9167 | [ALC1200_ASUS_P5Q] = { |
@@ -9127,6 +9176,21 @@ static struct alc_config_preset alc883_presets[] = { | |||
9127 | .channel_mode = alc883_sixstack_modes, | 9176 | .channel_mode = alc883_sixstack_modes, |
9128 | .input_mux = &alc883_capture_source, | 9177 | .input_mux = &alc883_capture_source, |
9129 | }, | 9178 | }, |
9179 | [ALC889A_MB31] = { | ||
9180 | .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, | ||
9181 | .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, | ||
9182 | alc880_gpio1_init_verbs }, | ||
9183 | .adc_nids = alc883_adc_nids, | ||
9184 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
9185 | .dac_nids = alc883_dac_nids, | ||
9186 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
9187 | .channel_mode = alc889A_mb31_6ch_modes, | ||
9188 | .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes), | ||
9189 | .input_mux = &alc889A_mb31_capture_source, | ||
9190 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
9191 | .unsol_event = alc889A_mb31_unsol_event, | ||
9192 | .init_hook = alc889A_mb31_automute, | ||
9193 | }, | ||
9130 | }; | 9194 | }; |
9131 | 9195 | ||
9132 | 9196 | ||
@@ -9155,7 +9219,6 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec) | |||
9155 | struct alc_spec *spec = codec->spec; | 9219 | struct alc_spec *spec = codec->spec; |
9156 | int i; | 9220 | int i; |
9157 | 9221 | ||
9158 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
9159 | for (i = 0; i <= HDA_SIDE; i++) { | 9222 | for (i = 0; i <= HDA_SIDE; i++) { |
9160 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 9223 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
9161 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 9224 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -9273,10 +9336,18 @@ static int patch_alc883(struct hda_codec *codec) | |||
9273 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, | 9336 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, |
9274 | alc883_models, | 9337 | alc883_models, |
9275 | alc883_cfg_tbl); | 9338 | alc883_cfg_tbl); |
9276 | if (board_config < 0) { | 9339 | if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { |
9277 | printk(KERN_INFO "hda_codec: Unknown model for ALC883, " | 9340 | /* Pick up systems that don't supply PCI SSID */ |
9278 | "trying auto-probe from BIOS...\n"); | 9341 | switch (codec->subsystem_id) { |
9279 | board_config = ALC883_AUTO; | 9342 | case 0x106b3600: /* Macbook 3.1 */ |
9343 | board_config = ALC889A_MB31; | ||
9344 | break; | ||
9345 | default: | ||
9346 | printk(KERN_INFO | ||
9347 | "hda_codec: Unknown model for %s, trying " | ||
9348 | "auto-probe from BIOS...\n", codec->chip_name); | ||
9349 | board_config = ALC883_AUTO; | ||
9350 | } | ||
9280 | } | 9351 | } |
9281 | 9352 | ||
9282 | if (board_config == ALC883_AUTO) { | 9353 | if (board_config == ALC883_AUTO) { |
@@ -9304,13 +9375,6 @@ static int patch_alc883(struct hda_codec *codec) | |||
9304 | 9375 | ||
9305 | switch (codec->vendor_id) { | 9376 | switch (codec->vendor_id) { |
9306 | case 0x10ec0888: | 9377 | case 0x10ec0888: |
9307 | if (codec->revision_id == 0x100101) { | ||
9308 | spec->stream_name_analog = "ALC1200 Analog"; | ||
9309 | spec->stream_name_digital = "ALC1200 Digital"; | ||
9310 | } else { | ||
9311 | spec->stream_name_analog = "ALC888 Analog"; | ||
9312 | spec->stream_name_digital = "ALC888 Digital"; | ||
9313 | } | ||
9314 | if (!spec->num_adc_nids) { | 9378 | if (!spec->num_adc_nids) { |
9315 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | 9379 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); |
9316 | spec->adc_nids = alc883_adc_nids; | 9380 | spec->adc_nids = alc883_adc_nids; |
@@ -9318,10 +9382,9 @@ static int patch_alc883(struct hda_codec *codec) | |||
9318 | if (!spec->capsrc_nids) | 9382 | if (!spec->capsrc_nids) |
9319 | spec->capsrc_nids = alc883_capsrc_nids; | 9383 | spec->capsrc_nids = alc883_capsrc_nids; |
9320 | spec->capture_style = CAPT_MIX; /* matrix-style capture */ | 9384 | spec->capture_style = CAPT_MIX; /* matrix-style capture */ |
9385 | spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ | ||
9321 | break; | 9386 | break; |
9322 | case 0x10ec0889: | 9387 | case 0x10ec0889: |
9323 | spec->stream_name_analog = "ALC889 Analog"; | ||
9324 | spec->stream_name_digital = "ALC889 Digital"; | ||
9325 | if (!spec->num_adc_nids) { | 9388 | if (!spec->num_adc_nids) { |
9326 | spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids); | 9389 | spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids); |
9327 | spec->adc_nids = alc889_adc_nids; | 9390 | spec->adc_nids = alc889_adc_nids; |
@@ -9332,8 +9395,6 @@ static int patch_alc883(struct hda_codec *codec) | |||
9332 | capture */ | 9395 | capture */ |
9333 | break; | 9396 | break; |
9334 | default: | 9397 | default: |
9335 | spec->stream_name_analog = "ALC883 Analog"; | ||
9336 | spec->stream_name_digital = "ALC883 Digital"; | ||
9337 | if (!spec->num_adc_nids) { | 9398 | if (!spec->num_adc_nids) { |
9338 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | 9399 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); |
9339 | spec->adc_nids = alc883_adc_nids; | 9400 | spec->adc_nids = alc883_adc_nids; |
@@ -9413,24 +9474,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { | |||
9413 | { } /* end */ | 9474 | { } /* end */ |
9414 | }; | 9475 | }; |
9415 | 9476 | ||
9416 | static struct snd_kcontrol_new alc262_hippo1_mixer[] = { | ||
9417 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
9418 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
9419 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
9420 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
9421 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
9422 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
9423 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
9424 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
9425 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
9426 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
9427 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
9428 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
9429 | /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ | ||
9430 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
9431 | { } /* end */ | ||
9432 | }; | ||
9433 | |||
9434 | /* update HP, line and mono-out pins according to the master switch */ | 9477 | /* update HP, line and mono-out pins according to the master switch */ |
9435 | static void alc262_hp_master_update(struct hda_codec *codec) | 9478 | static void alc262_hp_master_update(struct hda_codec *codec) |
9436 | { | 9479 | { |
@@ -9486,14 +9529,7 @@ static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, | |||
9486 | alc262_hp_wildwest_automute(codec); | 9529 | alc262_hp_wildwest_automute(codec); |
9487 | } | 9530 | } |
9488 | 9531 | ||
9489 | static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol, | 9532 | #define alc262_hp_master_sw_get alc260_hp_master_sw_get |
9490 | struct snd_ctl_elem_value *ucontrol) | ||
9491 | { | ||
9492 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
9493 | struct alc_spec *spec = codec->spec; | ||
9494 | *ucontrol->value.integer.value = spec->master_sw; | ||
9495 | return 0; | ||
9496 | } | ||
9497 | 9533 | ||
9498 | static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, | 9534 | static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, |
9499 | struct snd_ctl_elem_value *ucontrol) | 9535 | struct snd_ctl_elem_value *ucontrol) |
@@ -9509,14 +9545,17 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
9509 | return 1; | 9545 | return 1; |
9510 | } | 9546 | } |
9511 | 9547 | ||
9548 | #define ALC262_HP_MASTER_SWITCH \ | ||
9549 | { \ | ||
9550 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
9551 | .name = "Master Playback Switch", \ | ||
9552 | .info = snd_ctl_boolean_mono_info, \ | ||
9553 | .get = alc262_hp_master_sw_get, \ | ||
9554 | .put = alc262_hp_master_sw_put, \ | ||
9555 | } | ||
9556 | |||
9512 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | 9557 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { |
9513 | { | 9558 | ALC262_HP_MASTER_SWITCH, |
9514 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9515 | .name = "Master Playback Switch", | ||
9516 | .info = snd_ctl_boolean_mono_info, | ||
9517 | .get = alc262_hp_master_sw_get, | ||
9518 | .put = alc262_hp_master_sw_put, | ||
9519 | }, | ||
9520 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9559 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9521 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 9560 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
9522 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 9561 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
@@ -9540,13 +9579,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | |||
9540 | }; | 9579 | }; |
9541 | 9580 | ||
9542 | static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { | 9581 | static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { |
9543 | { | 9582 | ALC262_HP_MASTER_SWITCH, |
9544 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9545 | .name = "Master Playback Switch", | ||
9546 | .info = snd_ctl_boolean_mono_info, | ||
9547 | .get = alc262_hp_master_sw_get, | ||
9548 | .put = alc262_hp_master_sw_put, | ||
9549 | }, | ||
9550 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9583 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9551 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 9584 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
9552 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 9585 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -9573,32 +9606,13 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { | |||
9573 | }; | 9606 | }; |
9574 | 9607 | ||
9575 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 9608 | /* mute/unmute internal speaker according to the hp jack and mute state */ |
9576 | static void alc262_hp_t5735_automute(struct hda_codec *codec, int force) | 9609 | static void alc262_hp_t5735_init_hook(struct hda_codec *codec) |
9577 | { | 9610 | { |
9578 | struct alc_spec *spec = codec->spec; | 9611 | struct alc_spec *spec = codec->spec; |
9579 | 9612 | ||
9580 | if (force || !spec->sense_updated) { | 9613 | spec->autocfg.hp_pins[0] = 0x15; |
9581 | unsigned int present; | 9614 | spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */ |
9582 | present = snd_hda_codec_read(codec, 0x15, 0, | 9615 | alc_automute_amp(codec); |
9583 | AC_VERB_GET_PIN_SENSE, 0); | ||
9584 | spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; | ||
9585 | spec->sense_updated = 1; | ||
9586 | } | ||
9587 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE, | ||
9588 | spec->jack_present ? HDA_AMP_MUTE : 0); | ||
9589 | } | ||
9590 | |||
9591 | static void alc262_hp_t5735_unsol_event(struct hda_codec *codec, | ||
9592 | unsigned int res) | ||
9593 | { | ||
9594 | if ((res >> 26) != ALC880_HP_EVENT) | ||
9595 | return; | ||
9596 | alc262_hp_t5735_automute(codec, 1); | ||
9597 | } | ||
9598 | |||
9599 | static void alc262_hp_t5735_init_hook(struct hda_codec *codec) | ||
9600 | { | ||
9601 | alc262_hp_t5735_automute(codec, 1); | ||
9602 | } | 9616 | } |
9603 | 9617 | ||
9604 | static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { | 9618 | static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { |
@@ -9651,46 +9665,132 @@ static struct hda_input_mux alc262_hp_rp5700_capture_source = { | |||
9651 | }, | 9665 | }, |
9652 | }; | 9666 | }; |
9653 | 9667 | ||
9654 | /* bind hp and internal speaker mute (with plug check) */ | 9668 | /* bind hp and internal speaker mute (with plug check) as master switch */ |
9655 | static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol, | 9669 | static void alc262_hippo_master_update(struct hda_codec *codec) |
9656 | struct snd_ctl_elem_value *ucontrol) | ||
9657 | { | 9670 | { |
9658 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 9671 | struct alc_spec *spec = codec->spec; |
9659 | long *valp = ucontrol->value.integer.value; | 9672 | hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; |
9660 | int change; | 9673 | hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; |
9674 | hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; | ||
9675 | unsigned int mute; | ||
9661 | 9676 | ||
9662 | /* change hp mute */ | 9677 | /* HP */ |
9663 | change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | 9678 | mute = spec->master_sw ? 0 : HDA_AMP_MUTE; |
9664 | HDA_AMP_MUTE, | 9679 | snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, |
9665 | valp[0] ? 0 : HDA_AMP_MUTE); | 9680 | HDA_AMP_MUTE, mute); |
9666 | change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | 9681 | /* mute internal speaker per jack sense */ |
9667 | HDA_AMP_MUTE, | 9682 | if (spec->jack_present) |
9668 | valp[1] ? 0 : HDA_AMP_MUTE); | 9683 | mute = HDA_AMP_MUTE; |
9669 | if (change) { | 9684 | if (line_nid) |
9670 | /* change speaker according to HP jack state */ | 9685 | snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, |
9671 | struct alc_spec *spec = codec->spec; | 9686 | HDA_AMP_MUTE, mute); |
9672 | unsigned int mute; | 9687 | if (speaker_nid && speaker_nid != line_nid) |
9673 | if (spec->jack_present) | 9688 | snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, |
9674 | mute = HDA_AMP_MUTE; | ||
9675 | else | ||
9676 | mute = snd_hda_codec_amp_read(codec, 0x15, 0, | ||
9677 | HDA_OUTPUT, 0); | ||
9678 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
9679 | HDA_AMP_MUTE, mute); | 9689 | HDA_AMP_MUTE, mute); |
9690 | } | ||
9691 | |||
9692 | #define alc262_hippo_master_sw_get alc262_hp_master_sw_get | ||
9693 | |||
9694 | static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, | ||
9695 | struct snd_ctl_elem_value *ucontrol) | ||
9696 | { | ||
9697 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
9698 | struct alc_spec *spec = codec->spec; | ||
9699 | int val = !!*ucontrol->value.integer.value; | ||
9700 | |||
9701 | if (val == spec->master_sw) | ||
9702 | return 0; | ||
9703 | spec->master_sw = val; | ||
9704 | alc262_hippo_master_update(codec); | ||
9705 | return 1; | ||
9706 | } | ||
9707 | |||
9708 | #define ALC262_HIPPO_MASTER_SWITCH \ | ||
9709 | { \ | ||
9710 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
9711 | .name = "Master Playback Switch", \ | ||
9712 | .info = snd_ctl_boolean_mono_info, \ | ||
9713 | .get = alc262_hippo_master_sw_get, \ | ||
9714 | .put = alc262_hippo_master_sw_put, \ | ||
9680 | } | 9715 | } |
9681 | return change; | 9716 | |
9717 | static struct snd_kcontrol_new alc262_hippo_mixer[] = { | ||
9718 | ALC262_HIPPO_MASTER_SWITCH, | ||
9719 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
9720 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
9721 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
9722 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
9723 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
9724 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
9725 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
9726 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
9727 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
9728 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
9729 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
9730 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
9731 | { } /* end */ | ||
9732 | }; | ||
9733 | |||
9734 | static struct snd_kcontrol_new alc262_hippo1_mixer[] = { | ||
9735 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
9736 | ALC262_HIPPO_MASTER_SWITCH, | ||
9737 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
9738 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
9739 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
9740 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
9741 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
9742 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
9743 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
9744 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
9745 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
9746 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
9747 | { } /* end */ | ||
9748 | }; | ||
9749 | |||
9750 | /* mute/unmute internal speaker according to the hp jack and mute state */ | ||
9751 | static void alc262_hippo_automute(struct hda_codec *codec) | ||
9752 | { | ||
9753 | struct alc_spec *spec = codec->spec; | ||
9754 | hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; | ||
9755 | unsigned int present; | ||
9756 | |||
9757 | /* need to execute and sync at first */ | ||
9758 | snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
9759 | present = snd_hda_codec_read(codec, hp_nid, 0, | ||
9760 | AC_VERB_GET_PIN_SENSE, 0); | ||
9761 | spec->jack_present = (present & 0x80000000) != 0; | ||
9762 | alc262_hippo_master_update(codec); | ||
9763 | } | ||
9764 | |||
9765 | static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) | ||
9766 | { | ||
9767 | if ((res >> 26) != ALC880_HP_EVENT) | ||
9768 | return; | ||
9769 | alc262_hippo_automute(codec); | ||
9770 | } | ||
9771 | |||
9772 | static void alc262_hippo_init_hook(struct hda_codec *codec) | ||
9773 | { | ||
9774 | struct alc_spec *spec = codec->spec; | ||
9775 | |||
9776 | spec->autocfg.hp_pins[0] = 0x15; | ||
9777 | spec->autocfg.speaker_pins[0] = 0x14; | ||
9778 | alc262_hippo_automute(codec); | ||
9779 | } | ||
9780 | |||
9781 | static void alc262_hippo1_init_hook(struct hda_codec *codec) | ||
9782 | { | ||
9783 | struct alc_spec *spec = codec->spec; | ||
9784 | |||
9785 | spec->autocfg.hp_pins[0] = 0x1b; | ||
9786 | spec->autocfg.speaker_pins[0] = 0x14; | ||
9787 | alc262_hippo_automute(codec); | ||
9682 | } | 9788 | } |
9683 | 9789 | ||
9790 | |||
9684 | static struct snd_kcontrol_new alc262_sony_mixer[] = { | 9791 | static struct snd_kcontrol_new alc262_sony_mixer[] = { |
9685 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9792 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9686 | { | 9793 | ALC262_HIPPO_MASTER_SWITCH, |
9687 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
9688 | .name = "Master Playback Switch", | ||
9689 | .info = snd_hda_mixer_amp_switch_info, | ||
9690 | .get = snd_hda_mixer_amp_switch_get, | ||
9691 | .put = alc262_sony_master_sw_put, | ||
9692 | .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), | ||
9693 | }, | ||
9694 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 9794 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
9695 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 9795 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
9696 | HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | 9796 | HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), |
@@ -9699,8 +9799,8 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = { | |||
9699 | }; | 9799 | }; |
9700 | 9800 | ||
9701 | static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { | 9801 | static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { |
9702 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9802 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9703 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 9803 | ALC262_HIPPO_MASTER_SWITCH, |
9704 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 9804 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
9705 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 9805 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
9706 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 9806 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
@@ -9741,34 +9841,15 @@ static struct hda_verb alc262_tyan_verbs[] = { | |||
9741 | }; | 9841 | }; |
9742 | 9842 | ||
9743 | /* unsolicited event for HP jack sensing */ | 9843 | /* unsolicited event for HP jack sensing */ |
9744 | static void alc262_tyan_automute(struct hda_codec *codec) | 9844 | static void alc262_tyan_init_hook(struct hda_codec *codec) |
9745 | { | 9845 | { |
9746 | unsigned int mute; | 9846 | struct alc_spec *spec = codec->spec; |
9747 | unsigned int present; | ||
9748 | 9847 | ||
9749 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | 9848 | spec->autocfg.hp_pins[0] = 0x1b; |
9750 | present = snd_hda_codec_read(codec, 0x1b, 0, | 9849 | spec->autocfg.speaker_pins[0] = 0x15; |
9751 | AC_VERB_GET_PIN_SENSE, 0); | 9850 | alc_automute_amp(codec); |
9752 | present = (present & 0x80000000) != 0; | ||
9753 | if (present) { | ||
9754 | /* mute line output on ATX panel */ | ||
9755 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
9756 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
9757 | } else { | ||
9758 | /* unmute line output if necessary */ | ||
9759 | mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); | ||
9760 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
9761 | HDA_AMP_MUTE, mute); | ||
9762 | } | ||
9763 | } | 9851 | } |
9764 | 9852 | ||
9765 | static void alc262_tyan_unsol_event(struct hda_codec *codec, | ||
9766 | unsigned int res) | ||
9767 | { | ||
9768 | if ((res >> 26) != ALC880_HP_EVENT) | ||
9769 | return; | ||
9770 | alc262_tyan_automute(codec); | ||
9771 | } | ||
9772 | 9853 | ||
9773 | #define alc262_capture_mixer alc882_capture_mixer | 9854 | #define alc262_capture_mixer alc882_capture_mixer |
9774 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer | 9855 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer |
@@ -9923,99 +10004,25 @@ static void alc262_dmic_automute(struct hda_codec *codec) | |||
9923 | AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09); | 10004 | AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09); |
9924 | } | 10005 | } |
9925 | 10006 | ||
9926 | /* toggle speaker-output according to the hp-jack state */ | ||
9927 | static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec) | ||
9928 | { | ||
9929 | unsigned int present; | ||
9930 | unsigned char bits; | ||
9931 | |||
9932 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
9933 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
9934 | bits = present ? 0 : PIN_OUT; | ||
9935 | snd_hda_codec_write(codec, 0x14, 0, | ||
9936 | AC_VERB_SET_PIN_WIDGET_CONTROL, bits); | ||
9937 | } | ||
9938 | |||
9939 | |||
9940 | 10007 | ||
9941 | /* unsolicited event for HP jack sensing */ | 10008 | /* unsolicited event for HP jack sensing */ |
9942 | static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec, | 10009 | static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec, |
9943 | unsigned int res) | 10010 | unsigned int res) |
9944 | { | 10011 | { |
9945 | if ((res >> 26) == ALC880_HP_EVENT) | ||
9946 | alc262_toshiba_s06_speaker_automute(codec); | ||
9947 | if ((res >> 26) == ALC880_MIC_EVENT) | 10012 | if ((res >> 26) == ALC880_MIC_EVENT) |
9948 | alc262_dmic_automute(codec); | 10013 | alc262_dmic_automute(codec); |
9949 | 10014 | else | |
10015 | alc_sku_unsol_event(codec, res); | ||
9950 | } | 10016 | } |
9951 | 10017 | ||
9952 | static void alc262_toshiba_s06_init_hook(struct hda_codec *codec) | 10018 | static void alc262_toshiba_s06_init_hook(struct hda_codec *codec) |
9953 | { | 10019 | { |
9954 | alc262_toshiba_s06_speaker_automute(codec); | ||
9955 | alc262_dmic_automute(codec); | ||
9956 | } | ||
9957 | |||
9958 | /* mute/unmute internal speaker according to the hp jack and mute state */ | ||
9959 | static void alc262_hippo_automute(struct hda_codec *codec) | ||
9960 | { | ||
9961 | struct alc_spec *spec = codec->spec; | 10020 | struct alc_spec *spec = codec->spec; |
9962 | unsigned int mute; | ||
9963 | unsigned int present; | ||
9964 | |||
9965 | /* need to execute and sync at first */ | ||
9966 | snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
9967 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
9968 | AC_VERB_GET_PIN_SENSE, 0); | ||
9969 | spec->jack_present = (present & 0x80000000) != 0; | ||
9970 | if (spec->jack_present) { | ||
9971 | /* mute internal speaker */ | ||
9972 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
9973 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
9974 | } else { | ||
9975 | /* unmute internal speaker if necessary */ | ||
9976 | mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); | ||
9977 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
9978 | HDA_AMP_MUTE, mute); | ||
9979 | } | ||
9980 | } | ||
9981 | |||
9982 | /* unsolicited event for HP jack sensing */ | ||
9983 | static void alc262_hippo_unsol_event(struct hda_codec *codec, | ||
9984 | unsigned int res) | ||
9985 | { | ||
9986 | if ((res >> 26) != ALC880_HP_EVENT) | ||
9987 | return; | ||
9988 | alc262_hippo_automute(codec); | ||
9989 | } | ||
9990 | |||
9991 | static void alc262_hippo1_automute(struct hda_codec *codec) | ||
9992 | { | ||
9993 | unsigned int mute; | ||
9994 | unsigned int present; | ||
9995 | |||
9996 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
9997 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
9998 | AC_VERB_GET_PIN_SENSE, 0); | ||
9999 | present = (present & 0x80000000) != 0; | ||
10000 | if (present) { | ||
10001 | /* mute internal speaker */ | ||
10002 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
10003 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
10004 | } else { | ||
10005 | /* unmute internal speaker if necessary */ | ||
10006 | mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); | ||
10007 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
10008 | HDA_AMP_MUTE, mute); | ||
10009 | } | ||
10010 | } | ||
10011 | 10021 | ||
10012 | /* unsolicited event for HP jack sensing */ | 10022 | spec->autocfg.hp_pins[0] = 0x15; |
10013 | static void alc262_hippo1_unsol_event(struct hda_codec *codec, | 10023 | spec->autocfg.speaker_pins[0] = 0x14; |
10014 | unsigned int res) | 10024 | alc_automute_pin(codec); |
10015 | { | 10025 | alc262_dmic_automute(codec); |
10016 | if ((res >> 26) != ALC880_HP_EVENT) | ||
10017 | return; | ||
10018 | alc262_hippo1_automute(codec); | ||
10019 | } | 10026 | } |
10020 | 10027 | ||
10021 | /* | 10028 | /* |
@@ -10285,14 +10292,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { | |||
10285 | 10292 | ||
10286 | static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { | 10293 | static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { |
10287 | HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), | 10294 | HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), |
10288 | { | 10295 | ALC262_HIPPO_MASTER_SWITCH, |
10289 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
10290 | .name = "Master Playback Switch", | ||
10291 | .info = snd_hda_mixer_amp_switch_info, | ||
10292 | .get = snd_hda_mixer_amp_switch_get, | ||
10293 | .put = alc262_sony_master_sw_put, | ||
10294 | .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), | ||
10295 | }, | ||
10296 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 10296 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
10297 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 10297 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
10298 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | 10298 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), |
@@ -10843,6 +10843,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
10843 | if (err < 0) | 10843 | if (err < 0) |
10844 | return err; | 10844 | return err; |
10845 | 10845 | ||
10846 | alc_ssid_check(codec, 0x15, 0x14, 0x1b); | ||
10847 | |||
10846 | return 1; | 10848 | return 1; |
10847 | } | 10849 | } |
10848 | 10850 | ||
@@ -10945,7 +10947,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
10945 | .input_mux = &alc262_capture_source, | 10947 | .input_mux = &alc262_capture_source, |
10946 | }, | 10948 | }, |
10947 | [ALC262_HIPPO] = { | 10949 | [ALC262_HIPPO] = { |
10948 | .mixers = { alc262_base_mixer }, | 10950 | .mixers = { alc262_hippo_mixer }, |
10949 | .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, | 10951 | .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, |
10950 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | 10952 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), |
10951 | .dac_nids = alc262_dac_nids, | 10953 | .dac_nids = alc262_dac_nids, |
@@ -10955,7 +10957,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
10955 | .channel_mode = alc262_modes, | 10957 | .channel_mode = alc262_modes, |
10956 | .input_mux = &alc262_capture_source, | 10958 | .input_mux = &alc262_capture_source, |
10957 | .unsol_event = alc262_hippo_unsol_event, | 10959 | .unsol_event = alc262_hippo_unsol_event, |
10958 | .init_hook = alc262_hippo_automute, | 10960 | .init_hook = alc262_hippo_init_hook, |
10959 | }, | 10961 | }, |
10960 | [ALC262_HIPPO_1] = { | 10962 | [ALC262_HIPPO_1] = { |
10961 | .mixers = { alc262_hippo1_mixer }, | 10963 | .mixers = { alc262_hippo1_mixer }, |
@@ -10967,8 +10969,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
10967 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 10969 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
10968 | .channel_mode = alc262_modes, | 10970 | .channel_mode = alc262_modes, |
10969 | .input_mux = &alc262_capture_source, | 10971 | .input_mux = &alc262_capture_source, |
10970 | .unsol_event = alc262_hippo1_unsol_event, | 10972 | .unsol_event = alc262_hippo_unsol_event, |
10971 | .init_hook = alc262_hippo1_automute, | 10973 | .init_hook = alc262_hippo1_init_hook, |
10972 | }, | 10974 | }, |
10973 | [ALC262_FUJITSU] = { | 10975 | [ALC262_FUJITSU] = { |
10974 | .mixers = { alc262_fujitsu_mixer }, | 10976 | .mixers = { alc262_fujitsu_mixer }, |
@@ -11030,7 +11032,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
11030 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 11032 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
11031 | .channel_mode = alc262_modes, | 11033 | .channel_mode = alc262_modes, |
11032 | .input_mux = &alc262_capture_source, | 11034 | .input_mux = &alc262_capture_source, |
11033 | .unsol_event = alc262_hp_t5735_unsol_event, | 11035 | .unsol_event = alc_automute_amp_unsol_event, |
11034 | .init_hook = alc262_hp_t5735_init_hook, | 11036 | .init_hook = alc262_hp_t5735_init_hook, |
11035 | }, | 11037 | }, |
11036 | [ALC262_HP_RP5700] = { | 11038 | [ALC262_HP_RP5700] = { |
@@ -11062,7 +11064,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
11062 | .channel_mode = alc262_modes, | 11064 | .channel_mode = alc262_modes, |
11063 | .input_mux = &alc262_capture_source, | 11065 | .input_mux = &alc262_capture_source, |
11064 | .unsol_event = alc262_hippo_unsol_event, | 11066 | .unsol_event = alc262_hippo_unsol_event, |
11065 | .init_hook = alc262_hippo_automute, | 11067 | .init_hook = alc262_hippo_init_hook, |
11066 | }, | 11068 | }, |
11067 | [ALC262_BENQ_T31] = { | 11069 | [ALC262_BENQ_T31] = { |
11068 | .mixers = { alc262_benq_t31_mixer }, | 11070 | .mixers = { alc262_benq_t31_mixer }, |
@@ -11074,7 +11076,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
11074 | .channel_mode = alc262_modes, | 11076 | .channel_mode = alc262_modes, |
11075 | .input_mux = &alc262_capture_source, | 11077 | .input_mux = &alc262_capture_source, |
11076 | .unsol_event = alc262_hippo_unsol_event, | 11078 | .unsol_event = alc262_hippo_unsol_event, |
11077 | .init_hook = alc262_hippo_automute, | 11079 | .init_hook = alc262_hippo_init_hook, |
11078 | }, | 11080 | }, |
11079 | [ALC262_ULTRA] = { | 11081 | [ALC262_ULTRA] = { |
11080 | .mixers = { alc262_ultra_mixer }, | 11082 | .mixers = { alc262_ultra_mixer }, |
@@ -11139,7 +11141,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
11139 | .channel_mode = alc262_modes, | 11141 | .channel_mode = alc262_modes, |
11140 | .input_mux = &alc262_capture_source, | 11142 | .input_mux = &alc262_capture_source, |
11141 | .unsol_event = alc262_hippo_unsol_event, | 11143 | .unsol_event = alc262_hippo_unsol_event, |
11142 | .init_hook = alc262_hippo_automute, | 11144 | .init_hook = alc262_hippo_init_hook, |
11143 | }, | 11145 | }, |
11144 | [ALC262_TYAN] = { | 11146 | [ALC262_TYAN] = { |
11145 | .mixers = { alc262_tyan_mixer }, | 11147 | .mixers = { alc262_tyan_mixer }, |
@@ -11151,8 +11153,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
11151 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 11153 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
11152 | .channel_mode = alc262_modes, | 11154 | .channel_mode = alc262_modes, |
11153 | .input_mux = &alc262_capture_source, | 11155 | .input_mux = &alc262_capture_source, |
11154 | .unsol_event = alc262_tyan_unsol_event, | 11156 | .unsol_event = alc_automute_amp_unsol_event, |
11155 | .init_hook = alc262_tyan_automute, | 11157 | .init_hook = alc262_tyan_init_hook, |
11156 | }, | 11158 | }, |
11157 | }; | 11159 | }; |
11158 | 11160 | ||
@@ -11187,8 +11189,8 @@ static int patch_alc262(struct hda_codec *codec) | |||
11187 | alc262_cfg_tbl); | 11189 | alc262_cfg_tbl); |
11188 | 11190 | ||
11189 | if (board_config < 0) { | 11191 | if (board_config < 0) { |
11190 | printk(KERN_INFO "hda_codec: Unknown model for ALC262, " | 11192 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
11191 | "trying auto-probe from BIOS...\n"); | 11193 | "trying auto-probe from BIOS...\n", codec->chip_name); |
11192 | board_config = ALC262_AUTO; | 11194 | board_config = ALC262_AUTO; |
11193 | } | 11195 | } |
11194 | 11196 | ||
@@ -11217,11 +11219,9 @@ static int patch_alc262(struct hda_codec *codec) | |||
11217 | if (board_config != ALC262_AUTO) | 11219 | if (board_config != ALC262_AUTO) |
11218 | setup_preset(spec, &alc262_presets[board_config]); | 11220 | setup_preset(spec, &alc262_presets[board_config]); |
11219 | 11221 | ||
11220 | spec->stream_name_analog = "ALC262 Analog"; | ||
11221 | spec->stream_analog_playback = &alc262_pcm_analog_playback; | 11222 | spec->stream_analog_playback = &alc262_pcm_analog_playback; |
11222 | spec->stream_analog_capture = &alc262_pcm_analog_capture; | 11223 | spec->stream_analog_capture = &alc262_pcm_analog_capture; |
11223 | 11224 | ||
11224 | spec->stream_name_digital = "ALC262 Digital"; | ||
11225 | spec->stream_digital_playback = &alc262_pcm_digital_playback; | 11225 | spec->stream_digital_playback = &alc262_pcm_digital_playback; |
11226 | spec->stream_digital_capture = &alc262_pcm_digital_capture; | 11226 | spec->stream_digital_capture = &alc262_pcm_digital_capture; |
11227 | 11227 | ||
@@ -11296,6 +11296,17 @@ static struct snd_kcontrol_new alc268_base_mixer[] = { | |||
11296 | { } | 11296 | { } |
11297 | }; | 11297 | }; |
11298 | 11298 | ||
11299 | static struct snd_kcontrol_new alc268_toshiba_mixer[] = { | ||
11300 | /* output mixer control */ | ||
11301 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
11302 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), | ||
11303 | ALC262_HIPPO_MASTER_SWITCH, | ||
11304 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
11305 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
11306 | HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), | ||
11307 | { } | ||
11308 | }; | ||
11309 | |||
11299 | /* bind Beep switches of both NID 0x0f and 0x10 */ | 11310 | /* bind Beep switches of both NID 0x0f and 0x10 */ |
11300 | static struct hda_bind_ctls alc268_bind_beep_sw = { | 11311 | static struct hda_bind_ctls alc268_bind_beep_sw = { |
11301 | .ops = &snd_hda_bind_sw, | 11312 | .ops = &snd_hda_bind_sw, |
@@ -11319,8 +11330,6 @@ static struct hda_verb alc268_eapd_verbs[] = { | |||
11319 | }; | 11330 | }; |
11320 | 11331 | ||
11321 | /* Toshiba specific */ | 11332 | /* Toshiba specific */ |
11322 | #define alc268_toshiba_automute alc262_hippo_automute | ||
11323 | |||
11324 | static struct hda_verb alc268_toshiba_verbs[] = { | 11333 | static struct hda_verb alc268_toshiba_verbs[] = { |
11325 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 11334 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
11326 | { } /* end */ | 11335 | { } /* end */ |
@@ -11456,13 +11465,8 @@ static struct hda_verb alc268_acer_verbs[] = { | |||
11456 | }; | 11465 | }; |
11457 | 11466 | ||
11458 | /* unsolicited event for HP jack sensing */ | 11467 | /* unsolicited event for HP jack sensing */ |
11459 | static void alc268_toshiba_unsol_event(struct hda_codec *codec, | 11468 | #define alc268_toshiba_unsol_event alc262_hippo_unsol_event |
11460 | unsigned int res) | 11469 | #define alc268_toshiba_init_hook alc262_hippo_init_hook |
11461 | { | ||
11462 | if ((res >> 26) != ALC880_HP_EVENT) | ||
11463 | return; | ||
11464 | alc268_toshiba_automute(codec); | ||
11465 | } | ||
11466 | 11470 | ||
11467 | static void alc268_acer_unsol_event(struct hda_codec *codec, | 11471 | static void alc268_acer_unsol_event(struct hda_codec *codec, |
11468 | unsigned int res) | 11472 | unsigned int res) |
@@ -11537,30 +11541,15 @@ static struct hda_verb alc268_dell_verbs[] = { | |||
11537 | }; | 11541 | }; |
11538 | 11542 | ||
11539 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 11543 | /* mute/unmute internal speaker according to the hp jack and mute state */ |
11540 | static void alc268_dell_automute(struct hda_codec *codec) | 11544 | static void alc268_dell_init_hook(struct hda_codec *codec) |
11541 | { | 11545 | { |
11542 | unsigned int present; | 11546 | struct alc_spec *spec = codec->spec; |
11543 | unsigned int mute; | ||
11544 | |||
11545 | present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0); | ||
11546 | if (present & 0x80000000) | ||
11547 | mute = HDA_AMP_MUTE; | ||
11548 | else | ||
11549 | mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); | ||
11550 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
11551 | HDA_AMP_MUTE, mute); | ||
11552 | } | ||
11553 | 11547 | ||
11554 | static void alc268_dell_unsol_event(struct hda_codec *codec, | 11548 | spec->autocfg.hp_pins[0] = 0x15; |
11555 | unsigned int res) | 11549 | spec->autocfg.speaker_pins[0] = 0x14; |
11556 | { | 11550 | alc_automute_pin(codec); |
11557 | if ((res >> 26) != ALC880_HP_EVENT) | ||
11558 | return; | ||
11559 | alc268_dell_automute(codec); | ||
11560 | } | 11551 | } |
11561 | 11552 | ||
11562 | #define alc268_dell_init_hook alc268_dell_automute | ||
11563 | |||
11564 | static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { | 11553 | static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { |
11565 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), | 11554 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), |
11566 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 11555 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -11579,16 +11568,6 @@ static struct hda_verb alc267_quanta_il1_verbs[] = { | |||
11579 | { } | 11568 | { } |
11580 | }; | 11569 | }; |
11581 | 11570 | ||
11582 | static void alc267_quanta_il1_hp_automute(struct hda_codec *codec) | ||
11583 | { | ||
11584 | unsigned int present; | ||
11585 | |||
11586 | present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0) | ||
11587 | & AC_PINSENSE_PRESENCE; | ||
11588 | snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
11589 | present ? 0 : PIN_OUT); | ||
11590 | } | ||
11591 | |||
11592 | static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) | 11571 | static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) |
11593 | { | 11572 | { |
11594 | unsigned int present; | 11573 | unsigned int present; |
@@ -11600,9 +11579,13 @@ static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) | |||
11600 | present ? 0x00 : 0x01); | 11579 | present ? 0x00 : 0x01); |
11601 | } | 11580 | } |
11602 | 11581 | ||
11603 | static void alc267_quanta_il1_automute(struct hda_codec *codec) | 11582 | static void alc267_quanta_il1_init_hook(struct hda_codec *codec) |
11604 | { | 11583 | { |
11605 | alc267_quanta_il1_hp_automute(codec); | 11584 | struct alc_spec *spec = codec->spec; |
11585 | |||
11586 | spec->autocfg.hp_pins[0] = 0x15; | ||
11587 | spec->autocfg.speaker_pins[0] = 0x14; | ||
11588 | alc_automute_pin(codec); | ||
11606 | alc267_quanta_il1_mic_automute(codec); | 11589 | alc267_quanta_il1_mic_automute(codec); |
11607 | } | 11590 | } |
11608 | 11591 | ||
@@ -11610,12 +11593,12 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec, | |||
11610 | unsigned int res) | 11593 | unsigned int res) |
11611 | { | 11594 | { |
11612 | switch (res >> 26) { | 11595 | switch (res >> 26) { |
11613 | case ALC880_HP_EVENT: | ||
11614 | alc267_quanta_il1_hp_automute(codec); | ||
11615 | break; | ||
11616 | case ALC880_MIC_EVENT: | 11596 | case ALC880_MIC_EVENT: |
11617 | alc267_quanta_il1_mic_automute(codec); | 11597 | alc267_quanta_il1_mic_automute(codec); |
11618 | break; | 11598 | break; |
11599 | default: | ||
11600 | alc_sku_unsol_event(codec, res); | ||
11601 | break; | ||
11619 | } | 11602 | } |
11620 | } | 11603 | } |
11621 | 11604 | ||
@@ -12090,7 +12073,7 @@ static struct alc_config_preset alc268_presets[] = { | |||
12090 | .channel_mode = alc268_modes, | 12073 | .channel_mode = alc268_modes, |
12091 | .input_mux = &alc268_capture_source, | 12074 | .input_mux = &alc268_capture_source, |
12092 | .unsol_event = alc267_quanta_il1_unsol_event, | 12075 | .unsol_event = alc267_quanta_il1_unsol_event, |
12093 | .init_hook = alc267_quanta_il1_automute, | 12076 | .init_hook = alc267_quanta_il1_init_hook, |
12094 | }, | 12077 | }, |
12095 | [ALC268_3ST] = { | 12078 | [ALC268_3ST] = { |
12096 | .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, | 12079 | .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, |
@@ -12108,7 +12091,7 @@ static struct alc_config_preset alc268_presets[] = { | |||
12108 | .input_mux = &alc268_capture_source, | 12091 | .input_mux = &alc268_capture_source, |
12109 | }, | 12092 | }, |
12110 | [ALC268_TOSHIBA] = { | 12093 | [ALC268_TOSHIBA] = { |
12111 | .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, | 12094 | .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer, |
12112 | alc268_beep_mixer }, | 12095 | alc268_beep_mixer }, |
12113 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | 12096 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, |
12114 | alc268_toshiba_verbs }, | 12097 | alc268_toshiba_verbs }, |
@@ -12122,7 +12105,7 @@ static struct alc_config_preset alc268_presets[] = { | |||
12122 | .channel_mode = alc268_modes, | 12105 | .channel_mode = alc268_modes, |
12123 | .input_mux = &alc268_capture_source, | 12106 | .input_mux = &alc268_capture_source, |
12124 | .unsol_event = alc268_toshiba_unsol_event, | 12107 | .unsol_event = alc268_toshiba_unsol_event, |
12125 | .init_hook = alc268_toshiba_automute, | 12108 | .init_hook = alc268_toshiba_init_hook, |
12126 | }, | 12109 | }, |
12127 | [ALC268_ACER] = { | 12110 | [ALC268_ACER] = { |
12128 | .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, | 12111 | .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, |
@@ -12185,7 +12168,7 @@ static struct alc_config_preset alc268_presets[] = { | |||
12185 | .hp_nid = 0x02, | 12168 | .hp_nid = 0x02, |
12186 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 12169 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
12187 | .channel_mode = alc268_modes, | 12170 | .channel_mode = alc268_modes, |
12188 | .unsol_event = alc268_dell_unsol_event, | 12171 | .unsol_event = alc_sku_unsol_event, |
12189 | .init_hook = alc268_dell_init_hook, | 12172 | .init_hook = alc268_dell_init_hook, |
12190 | .input_mux = &alc268_capture_source, | 12173 | .input_mux = &alc268_capture_source, |
12191 | }, | 12174 | }, |
@@ -12205,7 +12188,7 @@ static struct alc_config_preset alc268_presets[] = { | |||
12205 | .channel_mode = alc268_modes, | 12188 | .channel_mode = alc268_modes, |
12206 | .input_mux = &alc268_capture_source, | 12189 | .input_mux = &alc268_capture_source, |
12207 | .unsol_event = alc268_toshiba_unsol_event, | 12190 | .unsol_event = alc268_toshiba_unsol_event, |
12208 | .init_hook = alc268_toshiba_automute | 12191 | .init_hook = alc268_toshiba_init_hook |
12209 | }, | 12192 | }, |
12210 | #ifdef CONFIG_SND_DEBUG | 12193 | #ifdef CONFIG_SND_DEBUG |
12211 | [ALC268_TEST] = { | 12194 | [ALC268_TEST] = { |
@@ -12243,8 +12226,8 @@ static int patch_alc268(struct hda_codec *codec) | |||
12243 | alc268_cfg_tbl); | 12226 | alc268_cfg_tbl); |
12244 | 12227 | ||
12245 | if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { | 12228 | if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { |
12246 | printk(KERN_INFO "hda_codec: Unknown model for ALC268, " | 12229 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
12247 | "trying auto-probe from BIOS...\n"); | 12230 | "trying auto-probe from BIOS...\n", codec->chip_name); |
12248 | board_config = ALC268_AUTO; | 12231 | board_config = ALC268_AUTO; |
12249 | } | 12232 | } |
12250 | 12233 | ||
@@ -12265,14 +12248,6 @@ static int patch_alc268(struct hda_codec *codec) | |||
12265 | if (board_config != ALC268_AUTO) | 12248 | if (board_config != ALC268_AUTO) |
12266 | setup_preset(spec, &alc268_presets[board_config]); | 12249 | setup_preset(spec, &alc268_presets[board_config]); |
12267 | 12250 | ||
12268 | if (codec->vendor_id == 0x10ec0267) { | ||
12269 | spec->stream_name_analog = "ALC267 Analog"; | ||
12270 | spec->stream_name_digital = "ALC267 Digital"; | ||
12271 | } else { | ||
12272 | spec->stream_name_analog = "ALC268 Analog"; | ||
12273 | spec->stream_name_digital = "ALC268 Digital"; | ||
12274 | } | ||
12275 | |||
12276 | spec->stream_analog_playback = &alc268_pcm_analog_playback; | 12251 | spec->stream_analog_playback = &alc268_pcm_analog_playback; |
12277 | spec->stream_analog_capture = &alc268_pcm_analog_capture; | 12252 | spec->stream_analog_capture = &alc268_pcm_analog_capture; |
12278 | spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; | 12253 | spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; |
@@ -13099,8 +13074,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
13099 | alc269_cfg_tbl); | 13074 | alc269_cfg_tbl); |
13100 | 13075 | ||
13101 | if (board_config < 0) { | 13076 | if (board_config < 0) { |
13102 | printk(KERN_INFO "hda_codec: Unknown model for ALC269, " | 13077 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
13103 | "trying auto-probe from BIOS...\n"); | 13078 | "trying auto-probe from BIOS...\n", codec->chip_name); |
13104 | board_config = ALC269_AUTO; | 13079 | board_config = ALC269_AUTO; |
13105 | } | 13080 | } |
13106 | 13081 | ||
@@ -13127,7 +13102,6 @@ static int patch_alc269(struct hda_codec *codec) | |||
13127 | if (board_config != ALC269_AUTO) | 13102 | if (board_config != ALC269_AUTO) |
13128 | setup_preset(spec, &alc269_presets[board_config]); | 13103 | setup_preset(spec, &alc269_presets[board_config]); |
13129 | 13104 | ||
13130 | spec->stream_name_analog = "ALC269 Analog"; | ||
13131 | if (codec->subsystem_id == 0x17aa3bf8) { | 13105 | if (codec->subsystem_id == 0x17aa3bf8) { |
13132 | /* Due to a hardware problem on Lenovo Ideadpad, we need to | 13106 | /* Due to a hardware problem on Lenovo Ideadpad, we need to |
13133 | * fix the sample rate of analog I/O to 44.1kHz | 13107 | * fix the sample rate of analog I/O to 44.1kHz |
@@ -13138,7 +13112,6 @@ static int patch_alc269(struct hda_codec *codec) | |||
13138 | spec->stream_analog_playback = &alc269_pcm_analog_playback; | 13112 | spec->stream_analog_playback = &alc269_pcm_analog_playback; |
13139 | spec->stream_analog_capture = &alc269_pcm_analog_capture; | 13113 | spec->stream_analog_capture = &alc269_pcm_analog_capture; |
13140 | } | 13114 | } |
13141 | spec->stream_name_digital = "ALC269 Digital"; | ||
13142 | spec->stream_digital_playback = &alc269_pcm_digital_playback; | 13115 | spec->stream_digital_playback = &alc269_pcm_digital_playback; |
13143 | spec->stream_digital_capture = &alc269_pcm_digital_capture; | 13116 | spec->stream_digital_capture = &alc269_pcm_digital_capture; |
13144 | 13117 | ||
@@ -13927,7 +13900,6 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec) | |||
13927 | struct alc_spec *spec = codec->spec; | 13900 | struct alc_spec *spec = codec->spec; |
13928 | int i; | 13901 | int i; |
13929 | 13902 | ||
13930 | alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); | ||
13931 | for (i = 0; i < spec->autocfg.line_outs; i++) { | 13903 | for (i = 0; i < spec->autocfg.line_outs; i++) { |
13932 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 13904 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
13933 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 13905 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -14010,6 +13982,8 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
14010 | spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); | 13982 | spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); |
14011 | set_capture_mixer(spec); | 13983 | set_capture_mixer(spec); |
14012 | 13984 | ||
13985 | alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); | ||
13986 | |||
14013 | return 1; | 13987 | return 1; |
14014 | } | 13988 | } |
14015 | 13989 | ||
@@ -14199,8 +14173,8 @@ static int patch_alc861(struct hda_codec *codec) | |||
14199 | alc861_cfg_tbl); | 14173 | alc861_cfg_tbl); |
14200 | 14174 | ||
14201 | if (board_config < 0) { | 14175 | if (board_config < 0) { |
14202 | printk(KERN_INFO "hda_codec: Unknown model for ALC861, " | 14176 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
14203 | "trying auto-probe from BIOS...\n"); | 14177 | "trying auto-probe from BIOS...\n", codec->chip_name); |
14204 | board_config = ALC861_AUTO; | 14178 | board_config = ALC861_AUTO; |
14205 | } | 14179 | } |
14206 | 14180 | ||
@@ -14227,11 +14201,9 @@ static int patch_alc861(struct hda_codec *codec) | |||
14227 | if (board_config != ALC861_AUTO) | 14201 | if (board_config != ALC861_AUTO) |
14228 | setup_preset(spec, &alc861_presets[board_config]); | 14202 | setup_preset(spec, &alc861_presets[board_config]); |
14229 | 14203 | ||
14230 | spec->stream_name_analog = "ALC861 Analog"; | ||
14231 | spec->stream_analog_playback = &alc861_pcm_analog_playback; | 14204 | spec->stream_analog_playback = &alc861_pcm_analog_playback; |
14232 | spec->stream_analog_capture = &alc861_pcm_analog_capture; | 14205 | spec->stream_analog_capture = &alc861_pcm_analog_capture; |
14233 | 14206 | ||
14234 | spec->stream_name_digital = "ALC861 Digital"; | ||
14235 | spec->stream_digital_playback = &alc861_pcm_digital_playback; | 14207 | spec->stream_digital_playback = &alc861_pcm_digital_playback; |
14236 | spec->stream_digital_capture = &alc861_pcm_digital_capture; | 14208 | spec->stream_digital_capture = &alc861_pcm_digital_capture; |
14237 | 14209 | ||
@@ -14618,19 +14590,6 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { | |||
14618 | {} | 14590 | {} |
14619 | }; | 14591 | }; |
14620 | 14592 | ||
14621 | /* toggle speaker-output according to the hp-jack state */ | ||
14622 | static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) | ||
14623 | { | ||
14624 | unsigned int present; | ||
14625 | unsigned char bits; | ||
14626 | |||
14627 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
14628 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
14629 | bits = present ? HDA_AMP_MUTE : 0; | ||
14630 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
14631 | HDA_AMP_MUTE, bits); | ||
14632 | } | ||
14633 | |||
14634 | static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) | 14593 | static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) |
14635 | { | 14594 | { |
14636 | unsigned int present; | 14595 | unsigned int present; |
@@ -14643,9 +14602,13 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) | |||
14643 | HDA_AMP_MUTE, bits); | 14602 | HDA_AMP_MUTE, bits); |
14644 | } | 14603 | } |
14645 | 14604 | ||
14646 | static void alc861vd_lenovo_automute(struct hda_codec *codec) | 14605 | static void alc861vd_lenovo_init_hook(struct hda_codec *codec) |
14647 | { | 14606 | { |
14648 | alc861vd_lenovo_hp_automute(codec); | 14607 | struct alc_spec *spec = codec->spec; |
14608 | |||
14609 | spec->autocfg.hp_pins[0] = 0x1b; | ||
14610 | spec->autocfg.speaker_pins[0] = 0x14; | ||
14611 | alc_automute_amp(codec); | ||
14649 | alc861vd_lenovo_mic_automute(codec); | 14612 | alc861vd_lenovo_mic_automute(codec); |
14650 | } | 14613 | } |
14651 | 14614 | ||
@@ -14653,12 +14616,12 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, | |||
14653 | unsigned int res) | 14616 | unsigned int res) |
14654 | { | 14617 | { |
14655 | switch (res >> 26) { | 14618 | switch (res >> 26) { |
14656 | case ALC880_HP_EVENT: | ||
14657 | alc861vd_lenovo_hp_automute(codec); | ||
14658 | break; | ||
14659 | case ALC880_MIC_EVENT: | 14619 | case ALC880_MIC_EVENT: |
14660 | alc861vd_lenovo_mic_automute(codec); | 14620 | alc861vd_lenovo_mic_automute(codec); |
14661 | break; | 14621 | break; |
14622 | default: | ||
14623 | alc_automute_amp_unsol_event(codec, res); | ||
14624 | break; | ||
14662 | } | 14625 | } |
14663 | } | 14626 | } |
14664 | 14627 | ||
@@ -14708,20 +14671,13 @@ static struct hda_verb alc861vd_dallas_verbs[] = { | |||
14708 | }; | 14671 | }; |
14709 | 14672 | ||
14710 | /* toggle speaker-output according to the hp-jack state */ | 14673 | /* toggle speaker-output according to the hp-jack state */ |
14711 | static void alc861vd_dallas_automute(struct hda_codec *codec) | 14674 | static void alc861vd_dallas_init_hook(struct hda_codec *codec) |
14712 | { | 14675 | { |
14713 | unsigned int present; | 14676 | struct alc_spec *spec = codec->spec; |
14714 | |||
14715 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
14716 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
14717 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
14718 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
14719 | } | ||
14720 | 14677 | ||
14721 | static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res) | 14678 | spec->autocfg.hp_pins[0] = 0x15; |
14722 | { | 14679 | spec->autocfg.speaker_pins[0] = 0x14; |
14723 | if ((res >> 26) == ALC880_HP_EVENT) | 14680 | alc_automute_amp(codec); |
14724 | alc861vd_dallas_automute(codec); | ||
14725 | } | 14681 | } |
14726 | 14682 | ||
14727 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 14683 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -14835,7 +14791,7 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
14835 | .channel_mode = alc861vd_3stack_2ch_modes, | 14791 | .channel_mode = alc861vd_3stack_2ch_modes, |
14836 | .input_mux = &alc861vd_capture_source, | 14792 | .input_mux = &alc861vd_capture_source, |
14837 | .unsol_event = alc861vd_lenovo_unsol_event, | 14793 | .unsol_event = alc861vd_lenovo_unsol_event, |
14838 | .init_hook = alc861vd_lenovo_automute, | 14794 | .init_hook = alc861vd_lenovo_init_hook, |
14839 | }, | 14795 | }, |
14840 | [ALC861VD_DALLAS] = { | 14796 | [ALC861VD_DALLAS] = { |
14841 | .mixers = { alc861vd_dallas_mixer }, | 14797 | .mixers = { alc861vd_dallas_mixer }, |
@@ -14845,8 +14801,8 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
14845 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | 14801 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), |
14846 | .channel_mode = alc861vd_3stack_2ch_modes, | 14802 | .channel_mode = alc861vd_3stack_2ch_modes, |
14847 | .input_mux = &alc861vd_dallas_capture_source, | 14803 | .input_mux = &alc861vd_dallas_capture_source, |
14848 | .unsol_event = alc861vd_dallas_unsol_event, | 14804 | .unsol_event = alc_automute_amp_unsol_event, |
14849 | .init_hook = alc861vd_dallas_automute, | 14805 | .init_hook = alc861vd_dallas_init_hook, |
14850 | }, | 14806 | }, |
14851 | [ALC861VD_HP] = { | 14807 | [ALC861VD_HP] = { |
14852 | .mixers = { alc861vd_hp_mixer }, | 14808 | .mixers = { alc861vd_hp_mixer }, |
@@ -14857,8 +14813,8 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
14857 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | 14813 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), |
14858 | .channel_mode = alc861vd_3stack_2ch_modes, | 14814 | .channel_mode = alc861vd_3stack_2ch_modes, |
14859 | .input_mux = &alc861vd_hp_capture_source, | 14815 | .input_mux = &alc861vd_hp_capture_source, |
14860 | .unsol_event = alc861vd_dallas_unsol_event, | 14816 | .unsol_event = alc_automute_amp_unsol_event, |
14861 | .init_hook = alc861vd_dallas_automute, | 14817 | .init_hook = alc861vd_dallas_init_hook, |
14862 | }, | 14818 | }, |
14863 | [ALC660VD_ASUS_V1S] = { | 14819 | [ALC660VD_ASUS_V1S] = { |
14864 | .mixers = { alc861vd_lenovo_mixer }, | 14820 | .mixers = { alc861vd_lenovo_mixer }, |
@@ -14873,7 +14829,7 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
14873 | .channel_mode = alc861vd_3stack_2ch_modes, | 14829 | .channel_mode = alc861vd_3stack_2ch_modes, |
14874 | .input_mux = &alc861vd_capture_source, | 14830 | .input_mux = &alc861vd_capture_source, |
14875 | .unsol_event = alc861vd_lenovo_unsol_event, | 14831 | .unsol_event = alc861vd_lenovo_unsol_event, |
14876 | .init_hook = alc861vd_lenovo_automute, | 14832 | .init_hook = alc861vd_lenovo_init_hook, |
14877 | }, | 14833 | }, |
14878 | }; | 14834 | }; |
14879 | 14835 | ||
@@ -14891,7 +14847,6 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec) | |||
14891 | struct alc_spec *spec = codec->spec; | 14847 | struct alc_spec *spec = codec->spec; |
14892 | int i; | 14848 | int i; |
14893 | 14849 | ||
14894 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
14895 | for (i = 0; i <= HDA_SIDE; i++) { | 14850 | for (i = 0; i <= HDA_SIDE; i++) { |
14896 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 14851 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
14897 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 14852 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -15109,6 +15064,8 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
15109 | if (err < 0) | 15064 | if (err < 0) |
15110 | return err; | 15065 | return err; |
15111 | 15066 | ||
15067 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); | ||
15068 | |||
15112 | return 1; | 15069 | return 1; |
15113 | } | 15070 | } |
15114 | 15071 | ||
@@ -15140,8 +15097,8 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
15140 | alc861vd_cfg_tbl); | 15097 | alc861vd_cfg_tbl); |
15141 | 15098 | ||
15142 | if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { | 15099 | if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { |
15143 | printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/" | 15100 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
15144 | "ALC861VD, trying auto-probe from BIOS...\n"); | 15101 | "trying auto-probe from BIOS...\n", codec->chip_name); |
15145 | board_config = ALC861VD_AUTO; | 15102 | board_config = ALC861VD_AUTO; |
15146 | } | 15103 | } |
15147 | 15104 | ||
@@ -15169,13 +15126,8 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
15169 | setup_preset(spec, &alc861vd_presets[board_config]); | 15126 | setup_preset(spec, &alc861vd_presets[board_config]); |
15170 | 15127 | ||
15171 | if (codec->vendor_id == 0x10ec0660) { | 15128 | if (codec->vendor_id == 0x10ec0660) { |
15172 | spec->stream_name_analog = "ALC660-VD Analog"; | ||
15173 | spec->stream_name_digital = "ALC660-VD Digital"; | ||
15174 | /* always turn on EAPD */ | 15129 | /* always turn on EAPD */ |
15175 | add_verb(spec, alc660vd_eapd_verbs); | 15130 | add_verb(spec, alc660vd_eapd_verbs); |
15176 | } else { | ||
15177 | spec->stream_name_analog = "ALC861VD Analog"; | ||
15178 | spec->stream_name_digital = "ALC861VD Digital"; | ||
15179 | } | 15131 | } |
15180 | 15132 | ||
15181 | spec->stream_analog_playback = &alc861vd_pcm_analog_playback; | 15133 | spec->stream_analog_playback = &alc861vd_pcm_analog_playback; |
@@ -15289,6 +15241,38 @@ static struct hda_input_mux alc663_m51va_capture_source = { | |||
15289 | }, | 15241 | }, |
15290 | }; | 15242 | }; |
15291 | 15243 | ||
15244 | #if 1 /* set to 0 for testing other input sources below */ | ||
15245 | static struct hda_input_mux alc272_nc10_capture_source = { | ||
15246 | .num_items = 2, | ||
15247 | .items = { | ||
15248 | { "Autoselect Mic", 0x0 }, | ||
15249 | { "Internal Mic", 0x1 }, | ||
15250 | }, | ||
15251 | }; | ||
15252 | #else | ||
15253 | static struct hda_input_mux alc272_nc10_capture_source = { | ||
15254 | .num_items = 16, | ||
15255 | .items = { | ||
15256 | { "Autoselect Mic", 0x0 }, | ||
15257 | { "Internal Mic", 0x1 }, | ||
15258 | { "In-0x02", 0x2 }, | ||
15259 | { "In-0x03", 0x3 }, | ||
15260 | { "In-0x04", 0x4 }, | ||
15261 | { "In-0x05", 0x5 }, | ||
15262 | { "In-0x06", 0x6 }, | ||
15263 | { "In-0x07", 0x7 }, | ||
15264 | { "In-0x08", 0x8 }, | ||
15265 | { "In-0x09", 0x9 }, | ||
15266 | { "In-0x0a", 0x0a }, | ||
15267 | { "In-0x0b", 0x0b }, | ||
15268 | { "In-0x0c", 0x0c }, | ||
15269 | { "In-0x0d", 0x0d }, | ||
15270 | { "In-0x0e", 0x0e }, | ||
15271 | { "In-0x0f", 0x0f }, | ||
15272 | }, | ||
15273 | }; | ||
15274 | #endif | ||
15275 | |||
15292 | /* | 15276 | /* |
15293 | * 2ch mode | 15277 | * 2ch mode |
15294 | */ | 15278 | */ |
@@ -15428,10 +15412,8 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { | |||
15428 | }; | 15412 | }; |
15429 | 15413 | ||
15430 | static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { | 15414 | static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { |
15431 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 15415 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
15432 | 15416 | ALC262_HIPPO_MASTER_SWITCH, | |
15433 | HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
15434 | HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
15435 | 15417 | ||
15436 | HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), | 15418 | HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), |
15437 | HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 15419 | HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -15444,15 +15426,11 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { | |||
15444 | }; | 15426 | }; |
15445 | 15427 | ||
15446 | static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { | 15428 | static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { |
15447 | HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 15429 | ALC262_HIPPO_MASTER_SWITCH, |
15448 | HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 15430 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
15449 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 15431 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
15450 | HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), | ||
15451 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), | 15432 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), |
15452 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), | 15433 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), |
15453 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), | ||
15454 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), | ||
15455 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
15456 | HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), | 15434 | HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), |
15457 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 15435 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
15458 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 15436 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
@@ -15960,51 +15938,25 @@ static void alc662_eeepc_mic_automute(struct hda_codec *codec) | |||
15960 | static void alc662_eeepc_unsol_event(struct hda_codec *codec, | 15938 | static void alc662_eeepc_unsol_event(struct hda_codec *codec, |
15961 | unsigned int res) | 15939 | unsigned int res) |
15962 | { | 15940 | { |
15963 | if ((res >> 26) == ALC880_HP_EVENT) | ||
15964 | alc262_hippo1_automute( codec ); | ||
15965 | |||
15966 | if ((res >> 26) == ALC880_MIC_EVENT) | 15941 | if ((res >> 26) == ALC880_MIC_EVENT) |
15967 | alc662_eeepc_mic_automute(codec); | 15942 | alc662_eeepc_mic_automute(codec); |
15943 | else | ||
15944 | alc262_hippo_unsol_event(codec, res); | ||
15968 | } | 15945 | } |
15969 | 15946 | ||
15970 | static void alc662_eeepc_inithook(struct hda_codec *codec) | 15947 | static void alc662_eeepc_inithook(struct hda_codec *codec) |
15971 | { | 15948 | { |
15972 | alc262_hippo1_automute( codec ); | 15949 | alc262_hippo1_init_hook(codec); |
15973 | alc662_eeepc_mic_automute(codec); | 15950 | alc662_eeepc_mic_automute(codec); |
15974 | } | 15951 | } |
15975 | 15952 | ||
15976 | static void alc662_eeepc_ep20_automute(struct hda_codec *codec) | ||
15977 | { | ||
15978 | unsigned int mute; | ||
15979 | unsigned int present; | ||
15980 | |||
15981 | snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
15982 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
15983 | AC_VERB_GET_PIN_SENSE, 0); | ||
15984 | present = (present & 0x80000000) != 0; | ||
15985 | if (present) { | ||
15986 | /* mute internal speaker */ | ||
15987 | snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, | ||
15988 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
15989 | } else { | ||
15990 | /* unmute internal speaker if necessary */ | ||
15991 | mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); | ||
15992 | snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, | ||
15993 | HDA_AMP_MUTE, mute); | ||
15994 | } | ||
15995 | } | ||
15996 | |||
15997 | /* unsolicited event for HP jack sensing */ | ||
15998 | static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec, | ||
15999 | unsigned int res) | ||
16000 | { | ||
16001 | if ((res >> 26) == ALC880_HP_EVENT) | ||
16002 | alc662_eeepc_ep20_automute(codec); | ||
16003 | } | ||
16004 | |||
16005 | static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) | 15953 | static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) |
16006 | { | 15954 | { |
16007 | alc662_eeepc_ep20_automute(codec); | 15955 | struct alc_spec *spec = codec->spec; |
15956 | |||
15957 | spec->autocfg.hp_pins[0] = 0x14; | ||
15958 | spec->autocfg.speaker_pins[0] = 0x1b; | ||
15959 | alc262_hippo_master_update(codec); | ||
16008 | } | 15960 | } |
16009 | 15961 | ||
16010 | static void alc663_m51va_speaker_automute(struct hda_codec *codec) | 15962 | static void alc663_m51va_speaker_automute(struct hda_codec *codec) |
@@ -16338,35 +16290,9 @@ static void alc663_g50v_inithook(struct hda_codec *codec) | |||
16338 | alc662_eeepc_mic_automute(codec); | 16290 | alc662_eeepc_mic_automute(codec); |
16339 | } | 16291 | } |
16340 | 16292 | ||
16341 | /* bind hp and internal speaker mute (with plug check) */ | ||
16342 | static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol, | ||
16343 | struct snd_ctl_elem_value *ucontrol) | ||
16344 | { | ||
16345 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
16346 | long *valp = ucontrol->value.integer.value; | ||
16347 | int change; | ||
16348 | |||
16349 | change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, | ||
16350 | HDA_AMP_MUTE, | ||
16351 | valp[0] ? 0 : HDA_AMP_MUTE); | ||
16352 | change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, | ||
16353 | HDA_AMP_MUTE, | ||
16354 | valp[1] ? 0 : HDA_AMP_MUTE); | ||
16355 | if (change) | ||
16356 | alc262_hippo1_automute(codec); | ||
16357 | return change; | ||
16358 | } | ||
16359 | |||
16360 | static struct snd_kcontrol_new alc662_ecs_mixer[] = { | 16293 | static struct snd_kcontrol_new alc662_ecs_mixer[] = { |
16361 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 16294 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
16362 | { | 16295 | ALC262_HIPPO_MASTER_SWITCH, |
16363 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
16364 | .name = "Master Playback Switch", | ||
16365 | .info = snd_hda_mixer_amp_switch_info, | ||
16366 | .get = snd_hda_mixer_amp_switch_get, | ||
16367 | .put = alc662_ecs_master_sw_put, | ||
16368 | .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), | ||
16369 | }, | ||
16370 | 16296 | ||
16371 | HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), | 16297 | HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), |
16372 | HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), | 16298 | HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -16378,6 +16304,23 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = { | |||
16378 | { } /* end */ | 16304 | { } /* end */ |
16379 | }; | 16305 | }; |
16380 | 16306 | ||
16307 | static struct snd_kcontrol_new alc272_nc10_mixer[] = { | ||
16308 | /* Master Playback automatically created from Speaker and Headphone */ | ||
16309 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
16310 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
16311 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
16312 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
16313 | |||
16314 | HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
16315 | HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
16316 | HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), | ||
16317 | |||
16318 | HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
16319 | HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
16320 | HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), | ||
16321 | { } /* end */ | ||
16322 | }; | ||
16323 | |||
16381 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 16324 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
16382 | #define alc662_loopbacks alc880_loopbacks | 16325 | #define alc662_loopbacks alc880_loopbacks |
16383 | #endif | 16326 | #endif |
@@ -16411,6 +16354,9 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { | |||
16411 | [ALC663_ASUS_MODE4] = "asus-mode4", | 16354 | [ALC663_ASUS_MODE4] = "asus-mode4", |
16412 | [ALC663_ASUS_MODE5] = "asus-mode5", | 16355 | [ALC663_ASUS_MODE5] = "asus-mode5", |
16413 | [ALC663_ASUS_MODE6] = "asus-mode6", | 16356 | [ALC663_ASUS_MODE6] = "asus-mode6", |
16357 | [ALC272_DELL] = "dell", | ||
16358 | [ALC272_DELL_ZM1] = "dell-zm1", | ||
16359 | [ALC272_SAMSUNG_NC10] = "samsung-nc10", | ||
16414 | [ALC662_AUTO] = "auto", | 16360 | [ALC662_AUTO] = "auto", |
16415 | }; | 16361 | }; |
16416 | 16362 | ||
@@ -16468,6 +16414,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { | |||
16468 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), | 16414 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), |
16469 | SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", | 16415 | SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", |
16470 | ALC662_3ST_6ch_DIG), | 16416 | ALC662_3ST_6ch_DIG), |
16417 | SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), | ||
16471 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", | 16418 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", |
16472 | ALC662_3ST_6ch_DIG), | 16419 | ALC662_3ST_6ch_DIG), |
16473 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), | 16420 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), |
@@ -16558,7 +16505,7 @@ static struct alc_config_preset alc662_presets[] = { | |||
16558 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | 16505 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), |
16559 | .channel_mode = alc662_3ST_6ch_modes, | 16506 | .channel_mode = alc662_3ST_6ch_modes, |
16560 | .input_mux = &alc662_lenovo_101e_capture_source, | 16507 | .input_mux = &alc662_lenovo_101e_capture_source, |
16561 | .unsol_event = alc662_eeepc_ep20_unsol_event, | 16508 | .unsol_event = alc662_eeepc_unsol_event, |
16562 | .init_hook = alc662_eeepc_ep20_inithook, | 16509 | .init_hook = alc662_eeepc_ep20_inithook, |
16563 | }, | 16510 | }, |
16564 | [ALC662_ECS] = { | 16511 | [ALC662_ECS] = { |
@@ -16739,6 +16686,18 @@ static struct alc_config_preset alc662_presets[] = { | |||
16739 | .unsol_event = alc663_m51va_unsol_event, | 16686 | .unsol_event = alc663_m51va_unsol_event, |
16740 | .init_hook = alc663_m51va_inithook, | 16687 | .init_hook = alc663_m51va_inithook, |
16741 | }, | 16688 | }, |
16689 | [ALC272_SAMSUNG_NC10] = { | ||
16690 | .mixers = { alc272_nc10_mixer }, | ||
16691 | .init_verbs = { alc662_init_verbs, | ||
16692 | alc663_21jd_amic_init_verbs }, | ||
16693 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | ||
16694 | .dac_nids = alc272_dac_nids, | ||
16695 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
16696 | .channel_mode = alc662_3ST_2ch_modes, | ||
16697 | .input_mux = &alc272_nc10_capture_source, | ||
16698 | .unsol_event = alc663_mode4_unsol_event, | ||
16699 | .init_hook = alc663_mode4_inithook, | ||
16700 | }, | ||
16742 | }; | 16701 | }; |
16743 | 16702 | ||
16744 | 16703 | ||
@@ -16933,7 +16892,6 @@ static void alc662_auto_init_multi_out(struct hda_codec *codec) | |||
16933 | struct alc_spec *spec = codec->spec; | 16892 | struct alc_spec *spec = codec->spec; |
16934 | int i; | 16893 | int i; |
16935 | 16894 | ||
16936 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
16937 | for (i = 0; i <= HDA_SIDE; i++) { | 16895 | for (i = 0; i <= HDA_SIDE; i++) { |
16938 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 16896 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
16939 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 16897 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -17030,6 +16988,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
17030 | if (err < 0) | 16988 | if (err < 0) |
17031 | return err; | 16989 | return err; |
17032 | 16990 | ||
16991 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); | ||
16992 | |||
17033 | return 1; | 16993 | return 1; |
17034 | } | 16994 | } |
17035 | 16995 | ||
@@ -17062,8 +17022,8 @@ static int patch_alc662(struct hda_codec *codec) | |||
17062 | alc662_models, | 17022 | alc662_models, |
17063 | alc662_cfg_tbl); | 17023 | alc662_cfg_tbl); |
17064 | if (board_config < 0) { | 17024 | if (board_config < 0) { |
17065 | printk(KERN_INFO "hda_codec: Unknown model for ALC662, " | 17025 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
17066 | "trying auto-probe from BIOS...\n"); | 17026 | "trying auto-probe from BIOS...\n", codec->chip_name); |
17067 | board_config = ALC662_AUTO; | 17027 | board_config = ALC662_AUTO; |
17068 | } | 17028 | } |
17069 | 17029 | ||
@@ -17090,17 +17050,6 @@ static int patch_alc662(struct hda_codec *codec) | |||
17090 | if (board_config != ALC662_AUTO) | 17050 | if (board_config != ALC662_AUTO) |
17091 | setup_preset(spec, &alc662_presets[board_config]); | 17051 | setup_preset(spec, &alc662_presets[board_config]); |
17092 | 17052 | ||
17093 | if (codec->vendor_id == 0x10ec0663) { | ||
17094 | spec->stream_name_analog = "ALC663 Analog"; | ||
17095 | spec->stream_name_digital = "ALC663 Digital"; | ||
17096 | } else if (codec->vendor_id == 0x10ec0272) { | ||
17097 | spec->stream_name_analog = "ALC272 Analog"; | ||
17098 | spec->stream_name_digital = "ALC272 Digital"; | ||
17099 | } else { | ||
17100 | spec->stream_name_analog = "ALC662 Analog"; | ||
17101 | spec->stream_name_digital = "ALC662 Digital"; | ||
17102 | } | ||
17103 | |||
17104 | spec->stream_analog_playback = &alc662_pcm_analog_playback; | 17053 | spec->stream_analog_playback = &alc662_pcm_analog_playback; |
17105 | spec->stream_analog_capture = &alc662_pcm_analog_capture; | 17054 | spec->stream_analog_capture = &alc662_pcm_analog_capture; |
17106 | 17055 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d2fd8ef6aef8..a1b4c9496d47 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -100,6 +100,7 @@ enum { | |||
100 | STAC_HP_M4, | 100 | STAC_HP_M4, |
101 | STAC_HP_DV5, | 101 | STAC_HP_DV5, |
102 | STAC_HP_HDX, | 102 | STAC_HP_HDX, |
103 | STAC_HP_DV4_1222NR, | ||
103 | STAC_92HD71BXX_MODELS | 104 | STAC_92HD71BXX_MODELS |
104 | }; | 105 | }; |
105 | 106 | ||
@@ -193,6 +194,7 @@ struct sigmatel_spec { | |||
193 | unsigned int gpio_dir; | 194 | unsigned int gpio_dir; |
194 | unsigned int gpio_data; | 195 | unsigned int gpio_data; |
195 | unsigned int gpio_mute; | 196 | unsigned int gpio_mute; |
197 | unsigned int gpio_led; | ||
196 | 198 | ||
197 | /* stream */ | 199 | /* stream */ |
198 | unsigned int stream_delay; | 200 | unsigned int stream_delay; |
@@ -634,6 +636,96 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, | |||
634 | return 0; | 636 | return 0; |
635 | } | 637 | } |
636 | 638 | ||
639 | static unsigned int stac92xx_vref_set(struct hda_codec *codec, | ||
640 | hda_nid_t nid, unsigned int new_vref) | ||
641 | { | ||
642 | unsigned int error; | ||
643 | unsigned int pincfg; | ||
644 | pincfg = snd_hda_codec_read(codec, nid, 0, | ||
645 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
646 | |||
647 | pincfg &= 0xff; | ||
648 | pincfg &= ~(AC_PINCTL_VREFEN | AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); | ||
649 | pincfg |= new_vref; | ||
650 | |||
651 | if (new_vref == AC_PINCTL_VREF_HIZ) | ||
652 | pincfg |= AC_PINCTL_OUT_EN; | ||
653 | else | ||
654 | pincfg |= AC_PINCTL_IN_EN; | ||
655 | |||
656 | error = snd_hda_codec_write_cache(codec, nid, 0, | ||
657 | AC_VERB_SET_PIN_WIDGET_CONTROL, pincfg); | ||
658 | if (error < 0) | ||
659 | return error; | ||
660 | else | ||
661 | return 1; | ||
662 | } | ||
663 | |||
664 | static unsigned int stac92xx_vref_get(struct hda_codec *codec, hda_nid_t nid) | ||
665 | { | ||
666 | unsigned int vref; | ||
667 | vref = snd_hda_codec_read(codec, nid, 0, | ||
668 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
669 | vref &= AC_PINCTL_VREFEN; | ||
670 | return vref; | ||
671 | } | ||
672 | |||
673 | static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol, | ||
674 | struct snd_ctl_elem_value *ucontrol) | ||
675 | { | ||
676 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
677 | unsigned int new_vref; | ||
678 | unsigned int error; | ||
679 | |||
680 | if (ucontrol->value.enumerated.item[0] == 0) | ||
681 | new_vref = AC_PINCTL_VREF_80; | ||
682 | else if (ucontrol->value.enumerated.item[0] == 1) | ||
683 | new_vref = AC_PINCTL_VREF_GRD; | ||
684 | else | ||
685 | new_vref = AC_PINCTL_VREF_HIZ; | ||
686 | |||
687 | if (new_vref != stac92xx_vref_get(codec, kcontrol->private_value)) { | ||
688 | error = stac92xx_vref_set(codec, | ||
689 | kcontrol->private_value, new_vref); | ||
690 | return error; | ||
691 | } | ||
692 | |||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol, | ||
697 | struct snd_ctl_elem_value *ucontrol) | ||
698 | { | ||
699 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
700 | unsigned int vref = stac92xx_vref_get(codec, kcontrol->private_value); | ||
701 | if (vref == AC_PINCTL_VREF_80) | ||
702 | ucontrol->value.enumerated.item[0] = 0; | ||
703 | else if (vref == AC_PINCTL_VREF_GRD) | ||
704 | ucontrol->value.enumerated.item[0] = 1; | ||
705 | else if (vref == AC_PINCTL_VREF_HIZ) | ||
706 | ucontrol->value.enumerated.item[0] = 2; | ||
707 | |||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol, | ||
712 | struct snd_ctl_elem_info *uinfo) | ||
713 | { | ||
714 | static char *texts[] = { | ||
715 | "Mic In", "Line In", "Line Out" | ||
716 | }; | ||
717 | |||
718 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
719 | uinfo->value.enumerated.items = 3; | ||
720 | uinfo->count = 1; | ||
721 | if (uinfo->value.enumerated.item >= 3) | ||
722 | uinfo->value.enumerated.item = 2; | ||
723 | strcpy(uinfo->value.enumerated.name, | ||
724 | texts[uinfo->value.enumerated.item]); | ||
725 | |||
726 | return 0; | ||
727 | } | ||
728 | |||
637 | static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 729 | static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
638 | { | 730 | { |
639 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 731 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
@@ -995,6 +1087,17 @@ static struct hda_verb stac9205_core_init[] = { | |||
995 | .private_value = verb_read | (verb_write << 16), \ | 1087 | .private_value = verb_read | (verb_write << 16), \ |
996 | } | 1088 | } |
997 | 1089 | ||
1090 | #define DC_BIAS(xname, idx, nid) \ | ||
1091 | { \ | ||
1092 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
1093 | .name = xname, \ | ||
1094 | .index = idx, \ | ||
1095 | .info = stac92xx_dc_bias_info, \ | ||
1096 | .get = stac92xx_dc_bias_get, \ | ||
1097 | .put = stac92xx_dc_bias_put, \ | ||
1098 | .private_value = nid, \ | ||
1099 | } | ||
1100 | |||
998 | static struct snd_kcontrol_new stac9200_mixer[] = { | 1101 | static struct snd_kcontrol_new stac9200_mixer[] = { |
999 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), | 1102 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), |
1000 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), | 1103 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), |
@@ -1837,6 +1940,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | |||
1837 | [STAC_HP_M4] = NULL, | 1940 | [STAC_HP_M4] = NULL, |
1838 | [STAC_HP_DV5] = NULL, | 1941 | [STAC_HP_DV5] = NULL, |
1839 | [STAC_HP_HDX] = NULL, | 1942 | [STAC_HP_HDX] = NULL, |
1943 | [STAC_HP_DV4_1222NR] = NULL, | ||
1840 | }; | 1944 | }; |
1841 | 1945 | ||
1842 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | 1946 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { |
@@ -1848,6 +1952,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | |||
1848 | [STAC_HP_M4] = "hp-m4", | 1952 | [STAC_HP_M4] = "hp-m4", |
1849 | [STAC_HP_DV5] = "hp-dv5", | 1953 | [STAC_HP_DV5] = "hp-dv5", |
1850 | [STAC_HP_HDX] = "hp-hdx", | 1954 | [STAC_HP_HDX] = "hp-hdx", |
1955 | [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", | ||
1851 | }; | 1956 | }; |
1852 | 1957 | ||
1853 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | 1958 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { |
@@ -1856,6 +1961,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |||
1856 | "DFI LanParty", STAC_92HD71BXX_REF), | 1961 | "DFI LanParty", STAC_92HD71BXX_REF), |
1857 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | 1962 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, |
1858 | "DFI LanParty", STAC_92HD71BXX_REF), | 1963 | "DFI LanParty", STAC_92HD71BXX_REF), |
1964 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb, | ||
1965 | "HP dv4-1222nr", STAC_HP_DV4_1222NR), | ||
1859 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, | 1966 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, |
1860 | "HP", STAC_HP_DV5), | 1967 | "HP", STAC_HP_DV5), |
1861 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, | 1968 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, |
@@ -2707,7 +2814,8 @@ enum { | |||
2707 | STAC_CTL_WIDGET_AMP_VOL, | 2814 | STAC_CTL_WIDGET_AMP_VOL, |
2708 | STAC_CTL_WIDGET_HP_SWITCH, | 2815 | STAC_CTL_WIDGET_HP_SWITCH, |
2709 | STAC_CTL_WIDGET_IO_SWITCH, | 2816 | STAC_CTL_WIDGET_IO_SWITCH, |
2710 | STAC_CTL_WIDGET_CLFE_SWITCH | 2817 | STAC_CTL_WIDGET_CLFE_SWITCH, |
2818 | STAC_CTL_WIDGET_DC_BIAS | ||
2711 | }; | 2819 | }; |
2712 | 2820 | ||
2713 | static struct snd_kcontrol_new stac92xx_control_templates[] = { | 2821 | static struct snd_kcontrol_new stac92xx_control_templates[] = { |
@@ -2719,6 +2827,7 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { | |||
2719 | STAC_CODEC_HP_SWITCH(NULL), | 2827 | STAC_CODEC_HP_SWITCH(NULL), |
2720 | STAC_CODEC_IO_SWITCH(NULL, 0), | 2828 | STAC_CODEC_IO_SWITCH(NULL, 0), |
2721 | STAC_CODEC_CLFE_SWITCH(NULL, 0), | 2829 | STAC_CODEC_CLFE_SWITCH(NULL, 0), |
2830 | DC_BIAS(NULL, 0, 0), | ||
2722 | }; | 2831 | }; |
2723 | 2832 | ||
2724 | /* add dynamic controls */ | 2833 | /* add dynamic controls */ |
@@ -3170,9 +3279,9 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3170 | } | 3279 | } |
3171 | 3280 | ||
3172 | if (spec->mic_switch) { | 3281 | if (spec->mic_switch) { |
3173 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, | 3282 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_DC_BIAS, |
3174 | "Mic as Output Switch", | 3283 | "Mic Jack Mode", |
3175 | (spec->mic_switch << 8) | 1); | 3284 | spec->mic_switch); |
3176 | if (err < 0) | 3285 | if (err < 0) |
3177 | return err; | 3286 | return err; |
3178 | } | 3287 | } |
@@ -3639,6 +3748,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3639 | err = snd_hda_attach_beep_device(codec, nid); | 3748 | err = snd_hda_attach_beep_device(codec, nid); |
3640 | if (err < 0) | 3749 | if (err < 0) |
3641 | return err; | 3750 | return err; |
3751 | /* IDT/STAC codecs have linear beep tone parameter */ | ||
3752 | codec->beep->linear_tone = 1; | ||
3642 | /* if no beep switch is available, make its own one */ | 3753 | /* if no beep switch is available, make its own one */ |
3643 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); | 3754 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); |
3644 | if (codec->beep && | 3755 | if (codec->beep && |
@@ -4535,17 +4646,19 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4535 | return 0; | 4646 | return 0; |
4536 | } | 4647 | } |
4537 | 4648 | ||
4538 | |||
4539 | /* | 4649 | /* |
4540 | * using power check for controlling mute led of HP HDX notebooks | 4650 | * using power check for controlling mute led of HP notebooks |
4541 | * check for mute state only on Speakers (nid = 0x10) | 4651 | * check for mute state only on Speakers (nid = 0x10) |
4542 | * | 4652 | * |
4543 | * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise | 4653 | * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise |
4544 | * the LED is NOT working properly ! | 4654 | * the LED is NOT working properly ! |
4655 | * | ||
4656 | * Changed name to reflect that it now works for any designated | ||
4657 | * model, not just HP HDX. | ||
4545 | */ | 4658 | */ |
4546 | 4659 | ||
4547 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4660 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4548 | static int stac92xx_hp_hdx_check_power_status(struct hda_codec *codec, | 4661 | static int stac92xx_hp_check_power_status(struct hda_codec *codec, |
4549 | hda_nid_t nid) | 4662 | hda_nid_t nid) |
4550 | { | 4663 | { |
4551 | struct sigmatel_spec *spec = codec->spec; | 4664 | struct sigmatel_spec *spec = codec->spec; |
@@ -4553,9 +4666,9 @@ static int stac92xx_hp_hdx_check_power_status(struct hda_codec *codec, | |||
4553 | if (nid == 0x10) { | 4666 | if (nid == 0x10) { |
4554 | if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & | 4667 | if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & |
4555 | HDA_AMP_MUTE) | 4668 | HDA_AMP_MUTE) |
4556 | spec->gpio_data &= ~0x08; /* orange */ | 4669 | spec->gpio_data |= spec->gpio_led; /* white */ |
4557 | else | 4670 | else |
4558 | spec->gpio_data |= 0x08; /* white */ | 4671 | spec->gpio_data &= ~spec->gpio_led; /* orange */ |
4559 | 4672 | ||
4560 | stac_gpio_set(codec, spec->gpio_mask, | 4673 | stac_gpio_set(codec, spec->gpio_mask, |
4561 | spec->gpio_dir, | 4674 | spec->gpio_dir, |
@@ -5234,6 +5347,15 @@ again: | |||
5234 | spec->num_smuxes = 0; | 5347 | spec->num_smuxes = 0; |
5235 | spec->num_dmuxes = 1; | 5348 | spec->num_dmuxes = 1; |
5236 | break; | 5349 | break; |
5350 | case STAC_HP_DV4_1222NR: | ||
5351 | spec->num_dmics = 1; | ||
5352 | /* I don't know if it needs 1 or 2 smuxes - will wait for | ||
5353 | * bug reports to fix if needed | ||
5354 | */ | ||
5355 | spec->num_smuxes = 1; | ||
5356 | spec->num_dmuxes = 1; | ||
5357 | spec->gpio_led = 0x01; | ||
5358 | /* fallthrough */ | ||
5237 | case STAC_HP_DV5: | 5359 | case STAC_HP_DV5: |
5238 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); | 5360 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); |
5239 | stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); | 5361 | stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); |
@@ -5242,22 +5364,21 @@ again: | |||
5242 | spec->num_dmics = 1; | 5364 | spec->num_dmics = 1; |
5243 | spec->num_dmuxes = 1; | 5365 | spec->num_dmuxes = 1; |
5244 | spec->num_smuxes = 1; | 5366 | spec->num_smuxes = 1; |
5245 | /* | ||
5246 | * For controlling MUTE LED on HP HDX16/HDX18 notebooks, | ||
5247 | * the CONFIG_SND_HDA_POWER_SAVE is needed to be set. | ||
5248 | */ | ||
5249 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
5250 | /* orange/white mute led on GPIO3, orange=0, white=1 */ | 5367 | /* orange/white mute led on GPIO3, orange=0, white=1 */ |
5251 | spec->gpio_mask |= 0x08; | 5368 | spec->gpio_led = 0x08; |
5252 | spec->gpio_dir |= 0x08; | 5369 | break; |
5253 | spec->gpio_data |= 0x08; /* set to white */ | 5370 | } |
5254 | 5371 | ||
5372 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
5373 | if (spec->gpio_led) { | ||
5374 | spec->gpio_mask |= spec->gpio_led; | ||
5375 | spec->gpio_dir |= spec->gpio_led; | ||
5376 | spec->gpio_data |= spec->gpio_led; | ||
5255 | /* register check_power_status callback. */ | 5377 | /* register check_power_status callback. */ |
5256 | codec->patch_ops.check_power_status = | 5378 | codec->patch_ops.check_power_status = |
5257 | stac92xx_hp_hdx_check_power_status; | 5379 | stac92xx_hp_check_power_status; |
5380 | } | ||
5258 | #endif | 5381 | #endif |
5259 | break; | ||
5260 | }; | ||
5261 | 5382 | ||
5262 | spec->multiout.dac_nids = spec->dac_nids; | 5383 | spec->multiout.dac_nids = spec->dac_nids; |
5263 | if (spec->dinput_mux) | 5384 | if (spec->dinput_mux) |
@@ -5282,7 +5403,7 @@ again: | |||
5282 | codec->proc_widget_hook = stac92hd7x_proc_hook; | 5403 | codec->proc_widget_hook = stac92hd7x_proc_hook; |
5283 | 5404 | ||
5284 | return 0; | 5405 | return 0; |
5285 | }; | 5406 | } |
5286 | 5407 | ||
5287 | static int patch_stac922x(struct hda_codec *codec) | 5408 | static int patch_stac922x(struct hda_codec *codec) |
5288 | { | 5409 | { |
@@ -5437,7 +5558,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5437 | /* correct the device field to SPDIF out */ | 5558 | /* correct the device field to SPDIF out */ |
5438 | snd_hda_codec_set_pincfg(codec, 0x21, 0x01442070); | 5559 | snd_hda_codec_set_pincfg(codec, 0x21, 0x01442070); |
5439 | break; | 5560 | break; |
5440 | }; | 5561 | } |
5441 | /* configure the analog microphone on some laptops */ | 5562 | /* configure the analog microphone on some laptops */ |
5442 | snd_hda_codec_set_pincfg(codec, 0x0c, 0x90a79130); | 5563 | snd_hda_codec_set_pincfg(codec, 0x0c, 0x90a79130); |
5443 | /* correct the front output jack as a hp out */ | 5564 | /* correct the front output jack as a hp out */ |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index b25a5cc637d6..8e004fb6961a 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -205,7 +205,7 @@ struct via_spec { | |||
205 | 205 | ||
206 | /* playback */ | 206 | /* playback */ |
207 | struct hda_multi_out multiout; | 207 | struct hda_multi_out multiout; |
208 | hda_nid_t extra_dig_out_nid; | 208 | hda_nid_t slave_dig_outs[2]; |
209 | 209 | ||
210 | /* capture */ | 210 | /* capture */ |
211 | unsigned int num_adc_nids; | 211 | unsigned int num_adc_nids; |
@@ -731,21 +731,6 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
731 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 731 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
732 | } | 732 | } |
733 | 733 | ||
734 | /* setup SPDIF output stream */ | ||
735 | static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid, | ||
736 | unsigned int stream_tag, unsigned int format) | ||
737 | { | ||
738 | /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ | ||
739 | if (codec->spdif_ctls & AC_DIG1_ENABLE) | ||
740 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, | ||
741 | codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); | ||
742 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); | ||
743 | /* turn on again (if needed) */ | ||
744 | if (codec->spdif_ctls & AC_DIG1_ENABLE) | ||
745 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, | ||
746 | codec->spdif_ctls & 0xff); | ||
747 | } | ||
748 | |||
749 | static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 734 | static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
750 | struct hda_codec *codec, | 735 | struct hda_codec *codec, |
751 | unsigned int stream_tag, | 736 | unsigned int stream_tag, |
@@ -753,19 +738,16 @@ static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
753 | struct snd_pcm_substream *substream) | 738 | struct snd_pcm_substream *substream) |
754 | { | 739 | { |
755 | struct via_spec *spec = codec->spec; | 740 | struct via_spec *spec = codec->spec; |
756 | hda_nid_t nid; | 741 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, |
757 | 742 | stream_tag, format, substream); | |
758 | /* 1st or 2nd S/PDIF */ | 743 | } |
759 | if (substream->number == 0) | ||
760 | nid = spec->multiout.dig_out_nid; | ||
761 | else if (substream->number == 1) | ||
762 | nid = spec->extra_dig_out_nid; | ||
763 | else | ||
764 | return -1; | ||
765 | 744 | ||
766 | mutex_lock(&codec->spdif_mutex); | 745 | static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
767 | setup_dig_playback_stream(codec, nid, stream_tag, format); | 746 | struct hda_codec *codec, |
768 | mutex_unlock(&codec->spdif_mutex); | 747 | struct snd_pcm_substream *substream) |
748 | { | ||
749 | struct via_spec *spec = codec->spec; | ||
750 | snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | ||
769 | return 0; | 751 | return 0; |
770 | } | 752 | } |
771 | 753 | ||
@@ -842,7 +824,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = { | |||
842 | .ops = { | 824 | .ops = { |
843 | .open = via_dig_playback_pcm_open, | 825 | .open = via_dig_playback_pcm_open, |
844 | .close = via_dig_playback_pcm_close, | 826 | .close = via_dig_playback_pcm_close, |
845 | .prepare = via_dig_playback_pcm_prepare | 827 | .prepare = via_dig_playback_pcm_prepare, |
828 | .cleanup = via_dig_playback_pcm_cleanup | ||
846 | }, | 829 | }, |
847 | }; | 830 | }; |
848 | 831 | ||
@@ -874,13 +857,6 @@ static int via_build_controls(struct hda_codec *codec) | |||
874 | if (err < 0) | 857 | if (err < 0) |
875 | return err; | 858 | return err; |
876 | spec->multiout.share_spdif = 1; | 859 | spec->multiout.share_spdif = 1; |
877 | |||
878 | if (spec->extra_dig_out_nid) { | ||
879 | err = snd_hda_create_spdif_out_ctls(codec, | ||
880 | spec->extra_dig_out_nid); | ||
881 | if (err < 0) | ||
882 | return err; | ||
883 | } | ||
884 | } | 860 | } |
885 | if (spec->dig_in_nid) { | 861 | if (spec->dig_in_nid) { |
886 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | 862 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); |
@@ -1013,10 +989,6 @@ static void via_unsol_event(struct hda_codec *codec, | |||
1013 | via_gpio_control(codec); | 989 | via_gpio_control(codec); |
1014 | } | 990 | } |
1015 | 991 | ||
1016 | static hda_nid_t slave_dig_outs[] = { | ||
1017 | 0, | ||
1018 | }; | ||
1019 | |||
1020 | static int via_init(struct hda_codec *codec) | 992 | static int via_init(struct hda_codec *codec) |
1021 | { | 993 | { |
1022 | struct via_spec *spec = codec->spec; | 994 | struct via_spec *spec = codec->spec; |
@@ -1051,8 +1023,9 @@ static int via_init(struct hda_codec *codec) | |||
1051 | snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0, | 1023 | snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0, |
1052 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN); | 1024 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN); |
1053 | 1025 | ||
1054 | /* no slave outs */ | 1026 | /* assign slave outs */ |
1055 | codec->slave_dig_outs = slave_dig_outs; | 1027 | if (spec->slave_dig_outs[0]) |
1028 | codec->slave_dig_outs = spec->slave_dig_outs; | ||
1056 | 1029 | ||
1057 | return 0; | 1030 | return 0; |
1058 | } | 1031 | } |
@@ -2134,7 +2107,8 @@ static struct hda_pcm_stream vt1708B_pcm_digital_playback = { | |||
2134 | .ops = { | 2107 | .ops = { |
2135 | .open = via_dig_playback_pcm_open, | 2108 | .open = via_dig_playback_pcm_open, |
2136 | .close = via_dig_playback_pcm_close, | 2109 | .close = via_dig_playback_pcm_close, |
2137 | .prepare = via_dig_playback_pcm_prepare | 2110 | .prepare = via_dig_playback_pcm_prepare, |
2111 | .cleanup = via_dig_playback_pcm_cleanup | ||
2138 | }, | 2112 | }, |
2139 | }; | 2113 | }; |
2140 | 2114 | ||
@@ -2589,14 +2563,15 @@ static struct hda_pcm_stream vt1708S_pcm_analog_capture = { | |||
2589 | }; | 2563 | }; |
2590 | 2564 | ||
2591 | static struct hda_pcm_stream vt1708S_pcm_digital_playback = { | 2565 | static struct hda_pcm_stream vt1708S_pcm_digital_playback = { |
2592 | .substreams = 2, | 2566 | .substreams = 1, |
2593 | .channels_min = 2, | 2567 | .channels_min = 2, |
2594 | .channels_max = 2, | 2568 | .channels_max = 2, |
2595 | /* NID is set in via_build_pcms */ | 2569 | /* NID is set in via_build_pcms */ |
2596 | .ops = { | 2570 | .ops = { |
2597 | .open = via_dig_playback_pcm_open, | 2571 | .open = via_dig_playback_pcm_open, |
2598 | .close = via_dig_playback_pcm_close, | 2572 | .close = via_dig_playback_pcm_close, |
2599 | .prepare = via_dig_playback_pcm_prepare | 2573 | .prepare = via_dig_playback_pcm_prepare, |
2574 | .cleanup = via_dig_playback_pcm_cleanup | ||
2600 | }, | 2575 | }, |
2601 | }; | 2576 | }; |
2602 | 2577 | ||
@@ -2805,14 +2780,37 @@ static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec, | |||
2805 | return 0; | 2780 | return 0; |
2806 | } | 2781 | } |
2807 | 2782 | ||
2783 | /* fill out digital output widgets; one for master and one for slave outputs */ | ||
2784 | static void fill_dig_outs(struct hda_codec *codec) | ||
2785 | { | ||
2786 | struct via_spec *spec = codec->spec; | ||
2787 | int i; | ||
2788 | |||
2789 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
2790 | hda_nid_t nid; | ||
2791 | int conn; | ||
2792 | |||
2793 | nid = spec->autocfg.dig_out_pins[i]; | ||
2794 | if (!nid) | ||
2795 | continue; | ||
2796 | conn = snd_hda_get_connections(codec, nid, &nid, 1); | ||
2797 | if (conn < 1) | ||
2798 | continue; | ||
2799 | if (!spec->multiout.dig_out_nid) | ||
2800 | spec->multiout.dig_out_nid = nid; | ||
2801 | else { | ||
2802 | spec->slave_dig_outs[0] = nid; | ||
2803 | break; /* at most two dig outs */ | ||
2804 | } | ||
2805 | } | ||
2806 | } | ||
2807 | |||
2808 | static int vt1708S_parse_auto_config(struct hda_codec *codec) | 2808 | static int vt1708S_parse_auto_config(struct hda_codec *codec) |
2809 | { | 2809 | { |
2810 | struct via_spec *spec = codec->spec; | 2810 | struct via_spec *spec = codec->spec; |
2811 | int err; | 2811 | int err; |
2812 | static hda_nid_t vt1708s_ignore[] = {0x21, 0}; | ||
2813 | 2812 | ||
2814 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 2813 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); |
2815 | vt1708s_ignore); | ||
2816 | if (err < 0) | 2814 | if (err < 0) |
2817 | return err; | 2815 | return err; |
2818 | err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg); | 2816 | err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg); |
@@ -2833,10 +2831,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) | |||
2833 | 2831 | ||
2834 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 2832 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
2835 | 2833 | ||
2836 | if (spec->autocfg.dig_outs) | 2834 | fill_dig_outs(codec); |
2837 | spec->multiout.dig_out_nid = VT1708S_DIGOUT_NID; | ||
2838 | |||
2839 | spec->extra_dig_out_nid = 0x15; | ||
2840 | 2835 | ||
2841 | if (spec->kctls.list) | 2836 | if (spec->kctls.list) |
2842 | spec->mixers[spec->num_mixers++] = spec->kctls.list; | 2837 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |
@@ -3000,7 +2995,8 @@ static struct hda_pcm_stream vt1702_pcm_digital_playback = { | |||
3000 | .ops = { | 2995 | .ops = { |
3001 | .open = via_dig_playback_pcm_open, | 2996 | .open = via_dig_playback_pcm_open, |
3002 | .close = via_dig_playback_pcm_close, | 2997 | .close = via_dig_playback_pcm_close, |
3003 | .prepare = via_dig_playback_pcm_prepare | 2998 | .prepare = via_dig_playback_pcm_prepare, |
2999 | .cleanup = via_dig_playback_pcm_cleanup | ||
3004 | }, | 3000 | }, |
3005 | }; | 3001 | }; |
3006 | 3002 | ||
@@ -3128,10 +3124,8 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) | |||
3128 | { | 3124 | { |
3129 | struct via_spec *spec = codec->spec; | 3125 | struct via_spec *spec = codec->spec; |
3130 | int err; | 3126 | int err; |
3131 | static hda_nid_t vt1702_ignore[] = {0x1C, 0}; | ||
3132 | 3127 | ||
3133 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 3128 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); |
3134 | vt1702_ignore); | ||
3135 | if (err < 0) | 3129 | if (err < 0) |
3136 | return err; | 3130 | return err; |
3137 | err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg); | 3131 | err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg); |
@@ -3152,10 +3146,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) | |||
3152 | 3146 | ||
3153 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 3147 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
3154 | 3148 | ||
3155 | if (spec->autocfg.dig_outs) | 3149 | fill_dig_outs(codec); |
3156 | spec->multiout.dig_out_nid = VT1702_DIGOUT_NID; | ||
3157 | |||
3158 | spec->extra_dig_out_nid = 0x1B; | ||
3159 | 3150 | ||
3160 | if (spec->kctls.list) | 3151 | if (spec->kctls.list) |
3161 | spec->mixers[spec->num_mixers++] = spec->kctls.list; | 3152 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |