diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-06-10 01:26:31 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-06-10 01:26:31 -0400 |
commit | 81ad969dbf8b10c3e79c5811b8328c054c21ef39 (patch) | |
tree | 88f9d582d9c88dcb65f203160ee5701c1514ccb6 | |
parent | 2f0dabcc5f5fde67c64a6f71e9fb369aed39d56f (diff) | |
parent | f03ecf50534a81b06544c58a713076d59d54baf9 (diff) |
Merge branch 'topic/hda' into for-linus
* topic/hda: (51 commits)
ALSA: hda - Fix the previous tagra-8ch patch
ALSA: hda - Add 7.1 support for MSI GX620
ALSA: support Sony Vaio TT
ALSA: hda_intel: fix build error when !PM
ALSA: hda - More Aspire 8930G fixes
ALSA: hda - Acer Aspire 8930G support
ALSA: hda - Limit codec-verb retry to limited hardwares
ALSA: hda - Add codec bus reset and verb-retry at critical errors
ALSA: hda - Reorder and clean-up ALC268 quirk table
ALSA: hda - fix audio on LG R510
ALSA: hda - Macbook[Pro] 5 6ch support
ALSA: hda-intel: improve initialization for ALC262_HP_BPC model
ALSA: hda - Jack Mode changes for Sigmatel boards
ALSA: hda - Support NVIDIA 8 channel HDMI audio
ALSA: hda - Fix a typo in the previous patch
ALSA: hda - Fix reverted LED setup for HP
ALSA: hda - Add more register bits definitions
ALSA: hda - Always sync writes in single_cmd mode
ALSA: hda - Support sync after writing a verb
ALSA: hda - Allow concurrent RIRB access in single_cmd mode
...
-rw-r--r-- | Documentation/sound/alsa/HD-Audio-Models.txt | 18 | ||||
-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 | 239 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 13 | ||||
-rw-r--r-- | sound/pci/hda/hda_hwdep.c | 9 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 197 | ||||
-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_nvhdmi.c | 279 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 2328 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 275 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 111 |
15 files changed, 2794 insertions, 1333 deletions
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 322869fc8a9e..de8e10a94103 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 |
@@ -133,10 +139,12 @@ ALC883/888 | |||
133 | acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) | 139 | acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) |
134 | acer-aspire Acer Aspire 9810 | 140 | acer-aspire Acer Aspire 9810 |
135 | acer-aspire-4930g Acer Aspire 4930G | 141 | acer-aspire-4930g Acer Aspire 4930G |
142 | acer-aspire-8930g Acer Aspire 8930G | ||
136 | medion Medion Laptops | 143 | medion Medion Laptops |
137 | medion-md2 Medion MD2 | 144 | medion-md2 Medion MD2 |
138 | targa-dig Targa/MSI | 145 | targa-dig Targa/MSI |
139 | targa-2ch-dig Targs/MSI with 2-channel | 146 | targa-2ch-dig Targa/MSI with 2-channel |
147 | targa-8ch-dig Targa/MSI with 8-channel (MSI GX620) | ||
140 | laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE) | 148 | laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE) |
141 | lenovo-101e Lenovo 101E | 149 | lenovo-101e Lenovo 101E |
142 | lenovo-nb0763 Lenovo NB0763 | 150 | lenovo-nb0763 Lenovo NB0763 |
@@ -150,6 +158,9 @@ ALC883/888 | |||
150 | fujitsu-pi2515 Fujitsu AMILO Pi2515 | 158 | fujitsu-pi2515 Fujitsu AMILO Pi2515 |
151 | fujitsu-xa3530 Fujitsu AMILO XA3530 | 159 | fujitsu-xa3530 Fujitsu AMILO XA3530 |
152 | 3stack-6ch-intel Intel DG33* boards | 160 | 3stack-6ch-intel Intel DG33* boards |
161 | asus-p5q ASUS P5Q-EM boards | ||
162 | mb31 MacBook 3,1 | ||
163 | sony-vaio-tt Sony VAIO TT | ||
153 | auto auto-config reading BIOS (default) | 164 | auto auto-config reading BIOS (default) |
154 | 165 | ||
155 | ALC861/660 | 166 | ALC861/660 |
@@ -348,6 +359,7 @@ STAC92HD71B* | |||
348 | hp-m4 HP mini 1000 | 359 | hp-m4 HP mini 1000 |
349 | hp-dv5 HP dv series | 360 | hp-dv5 HP dv series |
350 | hp-hdx HP HDX series | 361 | hp-hdx HP HDX series |
362 | hp-dv4-1222nr HP dv4-1222nr (with LED support) | ||
351 | auto BIOS setup (default) | 363 | auto BIOS setup (default) |
352 | 364 | ||
353 | STAC92HD73* | 365 | 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..562403a23488 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,39 @@ 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; | ||
169 | |||
170 | if (res) | ||
171 | *res = -1; | ||
172 | again: | ||
173 | snd_hda_power_up(codec); | ||
174 | mutex_lock(&bus->cmd_mutex); | ||
175 | err = bus->ops.command(bus, cmd); | ||
176 | if (!err && res) | ||
177 | *res = bus->ops.get_response(bus); | ||
178 | mutex_unlock(&bus->cmd_mutex); | ||
179 | snd_hda_power_down(codec); | ||
180 | if (res && *res == -1 && bus->rirb_error) { | ||
181 | if (bus->response_reset) { | ||
182 | snd_printd("hda_codec: resetting BUS due to " | ||
183 | "fatal communication error\n"); | ||
184 | bus->ops.bus_reset(bus); | ||
185 | } | ||
186 | goto again; | ||
187 | } | ||
188 | /* clear reset-flag when the communication gets recovered */ | ||
189 | if (!err) | ||
190 | bus->response_reset = 0; | ||
191 | return err; | ||
192 | } | ||
193 | |||
160 | /** | 194 | /** |
161 | * snd_hda_codec_read - send a command and get the response | 195 | * snd_hda_codec_read - send a command and get the response |
162 | * @codec: the HDA codec | 196 | * @codec: the HDA codec |
@@ -173,18 +207,9 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, | |||
173 | int direct, | 207 | int direct, |
174 | unsigned int verb, unsigned int parm) | 208 | unsigned int verb, unsigned int parm) |
175 | { | 209 | { |
176 | struct hda_bus *bus = codec->bus; | 210 | unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm); |
177 | unsigned int res; | 211 | unsigned int res; |
178 | 212 | 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; | 213 | return res; |
189 | } | 214 | } |
190 | EXPORT_SYMBOL_HDA(snd_hda_codec_read); | 215 | EXPORT_SYMBOL_HDA(snd_hda_codec_read); |
@@ -204,17 +229,10 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_read); | |||
204 | int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, | 229 | int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, |
205 | unsigned int verb, unsigned int parm) | 230 | unsigned int verb, unsigned int parm) |
206 | { | 231 | { |
207 | struct hda_bus *bus = codec->bus; | 232 | unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm); |
208 | unsigned int res; | 233 | unsigned int res; |
209 | int err; | 234 | return codec_exec_verb(codec, cmd, |
210 | 235 | codec->bus->sync_write ? &res : NULL); | |
211 | res = make_codec_cmd(codec, nid, direct, verb, parm); | ||
212 | snd_hda_power_up(codec); | ||
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 | } | 236 | } |
219 | EXPORT_SYMBOL_HDA(snd_hda_codec_write); | 237 | EXPORT_SYMBOL_HDA(snd_hda_codec_write); |
220 | 238 | ||
@@ -613,7 +631,10 @@ static int get_codec_name(struct hda_codec *codec) | |||
613 | const struct hda_vendor_id *c; | 631 | const struct hda_vendor_id *c; |
614 | const char *vendor = NULL; | 632 | const char *vendor = NULL; |
615 | u16 vendor_id = codec->vendor_id >> 16; | 633 | u16 vendor_id = codec->vendor_id >> 16; |
616 | char tmp[16], name[32]; | 634 | char tmp[16]; |
635 | |||
636 | if (codec->vendor_name) | ||
637 | goto get_chip_name; | ||
617 | 638 | ||
618 | for (c = hda_vendor_ids; c->id; c++) { | 639 | for (c = hda_vendor_ids; c->id; c++) { |
619 | if (c->id == vendor_id) { | 640 | if (c->id == vendor_id) { |
@@ -625,14 +646,21 @@ static int get_codec_name(struct hda_codec *codec) | |||
625 | sprintf(tmp, "Generic %04x", vendor_id); | 646 | sprintf(tmp, "Generic %04x", vendor_id); |
626 | vendor = tmp; | 647 | vendor = tmp; |
627 | } | 648 | } |
649 | codec->vendor_name = kstrdup(vendor, GFP_KERNEL); | ||
650 | if (!codec->vendor_name) | ||
651 | return -ENOMEM; | ||
652 | |||
653 | get_chip_name: | ||
654 | if (codec->chip_name) | ||
655 | return 0; | ||
656 | |||
628 | if (codec->preset && codec->preset->name) | 657 | if (codec->preset && codec->preset->name) |
629 | snprintf(name, sizeof(name), "%s %s", vendor, | 658 | codec->chip_name = kstrdup(codec->preset->name, GFP_KERNEL); |
630 | codec->preset->name); | 659 | else { |
631 | else | 660 | sprintf(tmp, "ID %x", codec->vendor_id & 0xffff); |
632 | snprintf(name, sizeof(name), "%s ID %x", vendor, | 661 | codec->chip_name = kstrdup(tmp, GFP_KERNEL); |
633 | codec->vendor_id & 0xffff); | 662 | } |
634 | codec->name = kstrdup(name, GFP_KERNEL); | 663 | if (!codec->chip_name) |
635 | if (!codec->name) | ||
636 | return -ENOMEM; | 664 | return -ENOMEM; |
637 | return 0; | 665 | return 0; |
638 | } | 666 | } |
@@ -838,7 +866,8 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
838 | module_put(codec->owner); | 866 | module_put(codec->owner); |
839 | free_hda_cache(&codec->amp_cache); | 867 | free_hda_cache(&codec->amp_cache); |
840 | free_hda_cache(&codec->cmd_cache); | 868 | free_hda_cache(&codec->cmd_cache); |
841 | kfree(codec->name); | 869 | kfree(codec->vendor_name); |
870 | kfree(codec->chip_name); | ||
842 | kfree(codec->modelname); | 871 | kfree(codec->modelname); |
843 | kfree(codec->wcaps); | 872 | kfree(codec->wcaps); |
844 | kfree(codec); | 873 | kfree(codec); |
@@ -979,15 +1008,16 @@ int snd_hda_codec_configure(struct hda_codec *codec) | |||
979 | int err; | 1008 | int err; |
980 | 1009 | ||
981 | codec->preset = find_codec_preset(codec); | 1010 | codec->preset = find_codec_preset(codec); |
982 | if (!codec->name) { | 1011 | if (!codec->vendor_name || !codec->chip_name) { |
983 | err = get_codec_name(codec); | 1012 | err = get_codec_name(codec); |
984 | if (err < 0) | 1013 | if (err < 0) |
985 | return err; | 1014 | return err; |
986 | } | 1015 | } |
987 | /* audio codec should override the mixer name */ | 1016 | /* audio codec should override the mixer name */ |
988 | if (codec->afg || !*codec->bus->card->mixername) | 1017 | if (codec->afg || !*codec->bus->card->mixername) |
989 | strlcpy(codec->bus->card->mixername, codec->name, | 1018 | snprintf(codec->bus->card->mixername, |
990 | sizeof(codec->bus->card->mixername)); | 1019 | sizeof(codec->bus->card->mixername), |
1020 | "%s %s", codec->vendor_name, codec->chip_name); | ||
991 | 1021 | ||
992 | if (is_generic_config(codec)) { | 1022 | if (is_generic_config(codec)) { |
993 | err = snd_hda_parse_generic_codec(codec); | 1023 | err = snd_hda_parse_generic_codec(codec); |
@@ -1055,6 +1085,8 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream); | |||
1055 | /* FIXME: more better hash key? */ | 1085 | /* FIXME: more better hash key? */ |
1056 | #define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) | 1086 | #define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) |
1057 | #define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24)) | 1087 | #define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24)) |
1088 | #define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24)) | ||
1089 | #define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24)) | ||
1058 | #define INFO_AMP_CAPS (1<<0) | 1090 | #define INFO_AMP_CAPS (1<<0) |
1059 | #define INFO_AMP_VOL(ch) (1 << (1 + (ch))) | 1091 | #define INFO_AMP_VOL(ch) (1 << (1 + (ch))) |
1060 | 1092 | ||
@@ -1145,19 +1177,32 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | |||
1145 | } | 1177 | } |
1146 | EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); | 1178 | EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); |
1147 | 1179 | ||
1148 | u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) | 1180 | static unsigned int |
1181 | query_caps_hash(struct hda_codec *codec, hda_nid_t nid, u32 key, | ||
1182 | unsigned int (*func)(struct hda_codec *, hda_nid_t)) | ||
1149 | { | 1183 | { |
1150 | struct hda_amp_info *info; | 1184 | struct hda_amp_info *info; |
1151 | 1185 | ||
1152 | info = get_alloc_amp_hash(codec, HDA_HASH_PINCAP_KEY(nid)); | 1186 | info = get_alloc_amp_hash(codec, key); |
1153 | if (!info) | 1187 | if (!info) |
1154 | return 0; | 1188 | return 0; |
1155 | if (!info->head.val) { | 1189 | 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; | 1190 | info->head.val |= INFO_AMP_CAPS; |
1191 | info->amp_caps = func(codec, nid); | ||
1158 | } | 1192 | } |
1159 | return info->amp_caps; | 1193 | return info->amp_caps; |
1160 | } | 1194 | } |
1195 | |||
1196 | static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid) | ||
1197 | { | ||
1198 | return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | ||
1199 | } | ||
1200 | |||
1201 | u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) | ||
1202 | { | ||
1203 | return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid), | ||
1204 | read_pin_cap); | ||
1205 | } | ||
1161 | EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); | 1206 | EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); |
1162 | 1207 | ||
1163 | /* | 1208 | /* |
@@ -1432,6 +1477,8 @@ _snd_hda_find_mixer_ctl(struct hda_codec *codec, | |||
1432 | memset(&id, 0, sizeof(id)); | 1477 | memset(&id, 0, sizeof(id)); |
1433 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 1478 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
1434 | id.index = idx; | 1479 | id.index = idx; |
1480 | if (snd_BUG_ON(strlen(name) >= sizeof(id.name))) | ||
1481 | return NULL; | ||
1435 | strcpy(id.name, name); | 1482 | strcpy(id.name, name); |
1436 | return snd_ctl_find_id(codec->bus->card, &id); | 1483 | return snd_ctl_find_id(codec->bus->card, &id); |
1437 | } | 1484 | } |
@@ -2242,28 +2289,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, | 2289 | int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, |
2243 | int direct, unsigned int verb, unsigned int parm) | 2290 | int direct, unsigned int verb, unsigned int parm) |
2244 | { | 2291 | { |
2245 | struct hda_bus *bus = codec->bus; | 2292 | int err = snd_hda_codec_write(codec, nid, direct, verb, parm); |
2246 | unsigned int res; | 2293 | struct hda_cache_head *c; |
2247 | int err; | 2294 | u32 key; |
2248 | 2295 | ||
2249 | res = make_codec_cmd(codec, nid, direct, verb, parm); | 2296 | if (err < 0) |
2250 | snd_hda_power_up(codec); | 2297 | return err; |
2251 | mutex_lock(&bus->cmd_mutex); | 2298 | /* parm may contain the verb stuff for get/set amp */ |
2252 | err = bus->ops.command(bus, res); | 2299 | verb = verb | (parm >> 8); |
2253 | if (!err) { | 2300 | parm &= 0xff; |
2254 | struct hda_cache_head *c; | 2301 | key = build_cmd_cache_key(nid, verb); |
2255 | u32 key; | 2302 | mutex_lock(&codec->bus->cmd_mutex); |
2256 | /* parm may contain the verb stuff for get/set amp */ | 2303 | c = get_alloc_hash(&codec->cmd_cache, key); |
2257 | verb = verb | (parm >> 8); | 2304 | if (c) |
2258 | parm &= 0xff; | 2305 | c->val = parm; |
2259 | key = build_cmd_cache_key(nid, verb); | 2306 | mutex_unlock(&codec->bus->cmd_mutex); |
2260 | c = get_alloc_hash(&codec->cmd_cache, key); | 2307 | 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 | } | 2308 | } |
2268 | EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache); | 2309 | EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache); |
2269 | 2310 | ||
@@ -2321,7 +2362,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
2321 | if (wcaps & AC_WCAP_POWER) { | 2362 | if (wcaps & AC_WCAP_POWER) { |
2322 | unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> | 2363 | unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> |
2323 | AC_WCAP_TYPE_SHIFT; | 2364 | AC_WCAP_TYPE_SHIFT; |
2324 | if (wid_type == AC_WID_PIN) { | 2365 | if (power_state == AC_PWRST_D3 && |
2366 | wid_type == AC_WID_PIN) { | ||
2325 | unsigned int pincap; | 2367 | unsigned int pincap; |
2326 | /* | 2368 | /* |
2327 | * don't power down the widget if it controls | 2369 | * don't power down the widget if it controls |
@@ -2333,7 +2375,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
2333 | nid, 0, | 2375 | nid, 0, |
2334 | AC_VERB_GET_EAPD_BTLENABLE, 0); | 2376 | AC_VERB_GET_EAPD_BTLENABLE, 0); |
2335 | eapd &= 0x02; | 2377 | eapd &= 0x02; |
2336 | if (power_state == AC_PWRST_D3 && eapd) | 2378 | if (eapd) |
2337 | continue; | 2379 | continue; |
2338 | } | 2380 | } |
2339 | } | 2381 | } |
@@ -2544,6 +2586,41 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
2544 | } | 2586 | } |
2545 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); | 2587 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); |
2546 | 2588 | ||
2589 | static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid) | ||
2590 | { | ||
2591 | unsigned int val = 0; | ||
2592 | if (nid != codec->afg && | ||
2593 | (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) | ||
2594 | val = snd_hda_param_read(codec, nid, AC_PAR_PCM); | ||
2595 | if (!val || val == -1) | ||
2596 | val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); | ||
2597 | if (!val || val == -1) | ||
2598 | return 0; | ||
2599 | return val; | ||
2600 | } | ||
2601 | |||
2602 | static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid) | ||
2603 | { | ||
2604 | return query_caps_hash(codec, nid, HDA_HASH_PARPCM_KEY(nid), | ||
2605 | get_pcm_param); | ||
2606 | } | ||
2607 | |||
2608 | static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid) | ||
2609 | { | ||
2610 | unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | ||
2611 | if (!streams || streams == -1) | ||
2612 | streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); | ||
2613 | if (!streams || streams == -1) | ||
2614 | return 0; | ||
2615 | return streams; | ||
2616 | } | ||
2617 | |||
2618 | static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid) | ||
2619 | { | ||
2620 | return query_caps_hash(codec, nid, HDA_HASH_PARSTR_KEY(nid), | ||
2621 | get_stream_param); | ||
2622 | } | ||
2623 | |||
2547 | /** | 2624 | /** |
2548 | * snd_hda_query_supported_pcm - query the supported PCM rates and formats | 2625 | * snd_hda_query_supported_pcm - query the supported PCM rates and formats |
2549 | * @codec: the HDA codec | 2626 | * @codec: the HDA codec |
@@ -2562,15 +2639,8 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
2562 | { | 2639 | { |
2563 | unsigned int i, val, wcaps; | 2640 | unsigned int i, val, wcaps; |
2564 | 2641 | ||
2565 | val = 0; | ||
2566 | wcaps = get_wcaps(codec, nid); | 2642 | wcaps = get_wcaps(codec, nid); |
2567 | if (nid != codec->afg && (wcaps & AC_WCAP_FORMAT_OVRD)) { | 2643 | 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 | 2644 | ||
2575 | if (ratesp) { | 2645 | if (ratesp) { |
2576 | u32 rates = 0; | 2646 | u32 rates = 0; |
@@ -2592,15 +2662,9 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
2592 | u64 formats = 0; | 2662 | u64 formats = 0; |
2593 | unsigned int streams, bps; | 2663 | unsigned int streams, bps; |
2594 | 2664 | ||
2595 | streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | 2665 | streams = query_stream_param(codec, nid); |
2596 | if (streams == -1) | 2666 | if (!streams) |
2597 | return -EIO; | 2667 | 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 | 2668 | ||
2605 | bps = 0; | 2669 | bps = 0; |
2606 | if (streams & AC_SUPFMT_PCM) { | 2670 | if (streams & AC_SUPFMT_PCM) { |
@@ -2674,17 +2738,9 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, | |||
2674 | int i; | 2738 | int i; |
2675 | unsigned int val = 0, rate, stream; | 2739 | unsigned int val = 0, rate, stream; |
2676 | 2740 | ||
2677 | if (nid != codec->afg && | 2741 | val = query_pcm_param(codec, nid); |
2678 | (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) { | 2742 | if (!val) |
2679 | val = snd_hda_param_read(codec, nid, AC_PAR_PCM); | 2743 | 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 | 2744 | ||
2689 | rate = format & 0xff00; | 2745 | rate = format & 0xff00; |
2690 | for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) | 2746 | for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) |
@@ -2696,12 +2752,8 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, | |||
2696 | if (i >= AC_PAR_PCM_RATE_BITS) | 2752 | if (i >= AC_PAR_PCM_RATE_BITS) |
2697 | return 0; | 2753 | return 0; |
2698 | 2754 | ||
2699 | stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | 2755 | stream = query_stream_param(codec, nid); |
2700 | if (stream == -1) | 2756 | 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; | 2757 | return 0; |
2706 | 2758 | ||
2707 | if (stream & AC_SUPFMT_PCM) { | 2759 | if (stream & AC_SUPFMT_PCM) { |
@@ -3835,11 +3887,10 @@ EXPORT_SYMBOL_HDA(auto_pin_cfg_labels); | |||
3835 | /** | 3887 | /** |
3836 | * snd_hda_suspend - suspend the codecs | 3888 | * snd_hda_suspend - suspend the codecs |
3837 | * @bus: the HDA bus | 3889 | * @bus: the HDA bus |
3838 | * @state: suspsend state | ||
3839 | * | 3890 | * |
3840 | * Returns 0 if successful. | 3891 | * Returns 0 if successful. |
3841 | */ | 3892 | */ |
3842 | int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) | 3893 | int snd_hda_suspend(struct hda_bus *bus) |
3843 | { | 3894 | { |
3844 | struct hda_codec *codec; | 3895 | struct hda_codec *codec; |
3845 | 3896 | ||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 2fdecf4b0eb6..cad79efaabc9 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -574,6 +574,8 @@ struct hda_bus_ops { | |||
574 | /* attach a PCM stream */ | 574 | /* attach a PCM stream */ |
575 | int (*attach_pcm)(struct hda_bus *bus, struct hda_codec *codec, | 575 | int (*attach_pcm)(struct hda_bus *bus, struct hda_codec *codec, |
576 | struct hda_pcm *pcm); | 576 | struct hda_pcm *pcm); |
577 | /* reset bus for retry verb */ | ||
578 | void (*bus_reset)(struct hda_bus *bus); | ||
577 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 579 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
578 | /* notify power-up/down from codec to controller */ | 580 | /* notify power-up/down from codec to controller */ |
579 | void (*pm_notify)(struct hda_bus *bus); | 581 | void (*pm_notify)(struct hda_bus *bus); |
@@ -622,7 +624,13 @@ struct hda_bus { | |||
622 | 624 | ||
623 | /* misc op flags */ | 625 | /* misc op flags */ |
624 | unsigned int needs_damn_long_delay :1; | 626 | unsigned int needs_damn_long_delay :1; |
627 | unsigned int allow_bus_reset:1; /* allow bus reset at fatal error */ | ||
628 | unsigned int sync_write:1; /* sync after verb write */ | ||
629 | /* status for codec/controller */ | ||
625 | unsigned int shutdown :1; /* being unloaded */ | 630 | unsigned int shutdown :1; /* being unloaded */ |
631 | unsigned int rirb_error:1; /* error in codec communication */ | ||
632 | unsigned int response_reset:1; /* controller was reset */ | ||
633 | unsigned int in_reset:1; /* during reset operation */ | ||
626 | }; | 634 | }; |
627 | 635 | ||
628 | /* | 636 | /* |
@@ -747,7 +755,8 @@ struct hda_codec { | |||
747 | /* detected preset */ | 755 | /* detected preset */ |
748 | const struct hda_codec_preset *preset; | 756 | const struct hda_codec_preset *preset; |
749 | struct module *owner; | 757 | struct module *owner; |
750 | const char *name; /* codec name */ | 758 | const char *vendor_name; /* codec vendor name */ |
759 | const char *chip_name; /* codec chip name */ | ||
751 | const char *modelname; /* model name for preset */ | 760 | const char *modelname; /* model name for preset */ |
752 | 761 | ||
753 | /* set by patch */ | 762 | /* set by patch */ |
@@ -905,7 +914,7 @@ void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); | |||
905 | * power management | 914 | * power management |
906 | */ | 915 | */ |
907 | #ifdef CONFIG_PM | 916 | #ifdef CONFIG_PM |
908 | int snd_hda_suspend(struct hda_bus *bus, pm_message_t state); | 917 | int snd_hda_suspend(struct hda_bus *bus); |
909 | int snd_hda_resume(struct hda_bus *bus); | 918 | int snd_hda_resume(struct hda_bus *bus); |
910 | #endif | 919 | #endif |
911 | 920 | ||
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..4e9ea7080270 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 << 0) /* 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,23 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) | |||
646 | return -1; | 661 | return -1; |
647 | } | 662 | } |
648 | 663 | ||
664 | /* a fatal communication error; need either to reset or to fallback | ||
665 | * to the single_cmd mode | ||
666 | */ | ||
667 | bus->rirb_error = 1; | ||
668 | if (bus->allow_bus_reset && !bus->response_reset && !bus->in_reset) { | ||
669 | bus->response_reset = 1; | ||
670 | return -1; /* give a chance to retry */ | ||
671 | } | ||
672 | |||
649 | snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " | 673 | snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " |
650 | "switching to single_cmd mode: last cmd=0x%08x\n", | 674 | "switching to single_cmd mode: last cmd=0x%08x\n", |
651 | chip->last_cmd); | 675 | chip->last_cmd); |
652 | chip->rirb.rp = azx_readb(chip, RIRBWP); | ||
653 | chip->rirb.cmds = 0; | ||
654 | /* switch to single_cmd mode */ | ||
655 | chip->single_cmd = 1; | 676 | chip->single_cmd = 1; |
677 | bus->response_reset = 0; | ||
678 | /* re-initialize CORB/RIRB */ | ||
656 | azx_free_cmd_io(chip); | 679 | azx_free_cmd_io(chip); |
680 | azx_init_cmd_io(chip); | ||
657 | return -1; | 681 | return -1; |
658 | } | 682 | } |
659 | 683 | ||
@@ -667,12 +691,34 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) | |||
667 | * I left the codes, however, for debugging/testing purposes. | 691 | * I left the codes, however, for debugging/testing purposes. |
668 | */ | 692 | */ |
669 | 693 | ||
694 | /* receive a response */ | ||
695 | static int azx_single_wait_for_response(struct azx *chip) | ||
696 | { | ||
697 | int timeout = 50; | ||
698 | |||
699 | while (timeout--) { | ||
700 | /* check IRV busy bit */ | ||
701 | if (azx_readw(chip, IRS) & ICH6_IRS_VALID) { | ||
702 | /* reuse rirb.res as the response return value */ | ||
703 | chip->rirb.res = azx_readl(chip, IR); | ||
704 | return 0; | ||
705 | } | ||
706 | udelay(1); | ||
707 | } | ||
708 | if (printk_ratelimit()) | ||
709 | snd_printd(SFX "get_response timeout: IRS=0x%x\n", | ||
710 | azx_readw(chip, IRS)); | ||
711 | chip->rirb.res = -1; | ||
712 | return -EIO; | ||
713 | } | ||
714 | |||
670 | /* send a command */ | 715 | /* send a command */ |
671 | static int azx_single_send_cmd(struct hda_bus *bus, u32 val) | 716 | static int azx_single_send_cmd(struct hda_bus *bus, u32 val) |
672 | { | 717 | { |
673 | struct azx *chip = bus->private_data; | 718 | struct azx *chip = bus->private_data; |
674 | int timeout = 50; | 719 | int timeout = 50; |
675 | 720 | ||
721 | bus->rirb_error = 0; | ||
676 | while (timeout--) { | 722 | while (timeout--) { |
677 | /* check ICB busy bit */ | 723 | /* check ICB busy bit */ |
678 | if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) { | 724 | if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) { |
@@ -682,7 +728,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val) | |||
682 | azx_writel(chip, IC, val); | 728 | azx_writel(chip, IC, val); |
683 | azx_writew(chip, IRS, azx_readw(chip, IRS) | | 729 | azx_writew(chip, IRS, azx_readw(chip, IRS) | |
684 | ICH6_IRS_BUSY); | 730 | ICH6_IRS_BUSY); |
685 | return 0; | 731 | return azx_single_wait_for_response(chip); |
686 | } | 732 | } |
687 | udelay(1); | 733 | udelay(1); |
688 | } | 734 | } |
@@ -696,18 +742,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) | 742 | static unsigned int azx_single_get_response(struct hda_bus *bus) |
697 | { | 743 | { |
698 | struct azx *chip = bus->private_data; | 744 | struct azx *chip = bus->private_data; |
699 | int timeout = 50; | 745 | 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 | } | 746 | } |
712 | 747 | ||
713 | /* | 748 | /* |
@@ -775,17 +810,17 @@ static int azx_reset(struct azx *chip) | |||
775 | 810 | ||
776 | /* check to see if controller is ready */ | 811 | /* check to see if controller is ready */ |
777 | if (!azx_readb(chip, GCTL)) { | 812 | if (!azx_readb(chip, GCTL)) { |
778 | snd_printd("azx_reset: controller not ready!\n"); | 813 | snd_printd(SFX "azx_reset: controller not ready!\n"); |
779 | return -EBUSY; | 814 | return -EBUSY; |
780 | } | 815 | } |
781 | 816 | ||
782 | /* Accept unsolicited responses */ | 817 | /* Accept unsolicited responses */ |
783 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UREN); | 818 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UNSOL); |
784 | 819 | ||
785 | /* detect codecs */ | 820 | /* detect codecs */ |
786 | if (!chip->codec_mask) { | 821 | if (!chip->codec_mask) { |
787 | chip->codec_mask = azx_readw(chip, STATESTS); | 822 | chip->codec_mask = azx_readw(chip, STATESTS); |
788 | snd_printdd("codec_mask = 0x%x\n", chip->codec_mask); | 823 | snd_printdd(SFX "codec_mask = 0x%x\n", chip->codec_mask); |
789 | } | 824 | } |
790 | 825 | ||
791 | return 0; | 826 | return 0; |
@@ -895,8 +930,7 @@ static void azx_init_chip(struct azx *chip) | |||
895 | azx_int_enable(chip); | 930 | azx_int_enable(chip); |
896 | 931 | ||
897 | /* initialize the codec command I/O */ | 932 | /* initialize the codec command I/O */ |
898 | if (!chip->single_cmd) | 933 | azx_init_cmd_io(chip); |
899 | azx_init_cmd_io(chip); | ||
900 | 934 | ||
901 | /* program the position buffer */ | 935 | /* program the position buffer */ |
902 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); | 936 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); |
@@ -953,12 +987,12 @@ static void azx_init_pci(struct azx *chip) | |||
953 | case AZX_DRIVER_SCH: | 987 | case AZX_DRIVER_SCH: |
954 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); | 988 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); |
955 | if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { | 989 | if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { |
956 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, \ | 990 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, |
957 | snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP)); | 991 | snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP)); |
958 | pci_read_config_word(chip->pci, | 992 | pci_read_config_word(chip->pci, |
959 | INTEL_SCH_HDA_DEVC, &snoop); | 993 | INTEL_SCH_HDA_DEVC, &snoop); |
960 | snd_printdd("HDA snoop disabled, enabling ... %s\n",\ | 994 | snd_printdd(SFX "HDA snoop disabled, enabling ... %s\n", |
961 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) \ | 995 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) |
962 | ? "Failed" : "OK"); | 996 | ? "Failed" : "OK"); |
963 | } | 997 | } |
964 | break; | 998 | break; |
@@ -1012,7 +1046,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
1012 | /* clear rirb int */ | 1046 | /* clear rirb int */ |
1013 | status = azx_readb(chip, RIRBSTS); | 1047 | status = azx_readb(chip, RIRBSTS); |
1014 | if (status & RIRB_INT_MASK) { | 1048 | if (status & RIRB_INT_MASK) { |
1015 | if (!chip->single_cmd && (status & RIRB_INT_RESPONSE)) | 1049 | if (status & RIRB_INT_RESPONSE) |
1016 | azx_update_rirb(chip); | 1050 | azx_update_rirb(chip); |
1017 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); | 1051 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); |
1018 | } | 1052 | } |
@@ -1098,7 +1132,7 @@ static int azx_setup_periods(struct azx *chip, | |||
1098 | pos_align; | 1132 | pos_align; |
1099 | pos_adj = frames_to_bytes(runtime, pos_adj); | 1133 | pos_adj = frames_to_bytes(runtime, pos_adj); |
1100 | if (pos_adj >= period_bytes) { | 1134 | if (pos_adj >= period_bytes) { |
1101 | snd_printk(KERN_WARNING "Too big adjustment %d\n", | 1135 | snd_printk(KERN_WARNING SFX "Too big adjustment %d\n", |
1102 | bdl_pos_adj[chip->dev_index]); | 1136 | bdl_pos_adj[chip->dev_index]); |
1103 | pos_adj = 0; | 1137 | pos_adj = 0; |
1104 | } else { | 1138 | } else { |
@@ -1122,7 +1156,7 @@ static int azx_setup_periods(struct azx *chip, | |||
1122 | return 0; | 1156 | return 0; |
1123 | 1157 | ||
1124 | error: | 1158 | error: |
1125 | snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n", | 1159 | snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n", |
1126 | azx_dev->bufsize, period_bytes); | 1160 | azx_dev->bufsize, period_bytes); |
1127 | return -EINVAL; | 1161 | return -EINVAL; |
1128 | } | 1162 | } |
@@ -1215,7 +1249,7 @@ static int probe_codec(struct azx *chip, int addr) | |||
1215 | chip->probing = 0; | 1249 | chip->probing = 0; |
1216 | if (res == -1) | 1250 | if (res == -1) |
1217 | return -EIO; | 1251 | return -EIO; |
1218 | snd_printdd("hda_intel: codec #%d probed OK\n", addr); | 1252 | snd_printdd(SFX "codec #%d probed OK\n", addr); |
1219 | return 0; | 1253 | return 0; |
1220 | } | 1254 | } |
1221 | 1255 | ||
@@ -1223,6 +1257,26 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
1223 | struct hda_pcm *cpcm); | 1257 | struct hda_pcm *cpcm); |
1224 | static void azx_stop_chip(struct azx *chip); | 1258 | static void azx_stop_chip(struct azx *chip); |
1225 | 1259 | ||
1260 | static void azx_bus_reset(struct hda_bus *bus) | ||
1261 | { | ||
1262 | struct azx *chip = bus->private_data; | ||
1263 | |||
1264 | bus->in_reset = 1; | ||
1265 | azx_stop_chip(chip); | ||
1266 | azx_init_chip(chip); | ||
1267 | #ifdef CONFIG_PM | ||
1268 | if (chip->initialized) { | ||
1269 | int i; | ||
1270 | |||
1271 | for (i = 0; i < AZX_MAX_PCMS; i++) | ||
1272 | snd_pcm_suspend_all(chip->pcm[i]); | ||
1273 | snd_hda_suspend(chip->bus); | ||
1274 | snd_hda_resume(chip->bus); | ||
1275 | } | ||
1276 | #endif | ||
1277 | bus->in_reset = 0; | ||
1278 | } | ||
1279 | |||
1226 | /* | 1280 | /* |
1227 | * Codec initialization | 1281 | * Codec initialization |
1228 | */ | 1282 | */ |
@@ -1246,6 +1300,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, | |||
1246 | bus_temp.ops.command = azx_send_cmd; | 1300 | bus_temp.ops.command = azx_send_cmd; |
1247 | bus_temp.ops.get_response = azx_get_response; | 1301 | bus_temp.ops.get_response = azx_get_response; |
1248 | bus_temp.ops.attach_pcm = azx_attach_pcm_stream; | 1302 | bus_temp.ops.attach_pcm = azx_attach_pcm_stream; |
1303 | bus_temp.ops.bus_reset = azx_bus_reset; | ||
1249 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1304 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1250 | bus_temp.power_save = &power_save; | 1305 | bus_temp.power_save = &power_save; |
1251 | bus_temp.ops.pm_notify = azx_power_notify; | 1306 | bus_temp.ops.pm_notify = azx_power_notify; |
@@ -1270,8 +1325,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, | |||
1270 | /* Some BIOSen give you wrong codec addresses | 1325 | /* Some BIOSen give you wrong codec addresses |
1271 | * that don't exist | 1326 | * that don't exist |
1272 | */ | 1327 | */ |
1273 | snd_printk(KERN_WARNING | 1328 | snd_printk(KERN_WARNING SFX |
1274 | "hda_intel: Codec #%d probe error; " | 1329 | "Codec #%d probe error; " |
1275 | "disabling it...\n", c); | 1330 | "disabling it...\n", c); |
1276 | chip->codec_mask &= ~(1 << c); | 1331 | chip->codec_mask &= ~(1 << c); |
1277 | /* More badly, accessing to a non-existing | 1332 | /* More badly, accessing to a non-existing |
@@ -1487,7 +1542,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1487 | bufsize = snd_pcm_lib_buffer_bytes(substream); | 1542 | bufsize = snd_pcm_lib_buffer_bytes(substream); |
1488 | period_bytes = snd_pcm_lib_period_bytes(substream); | 1543 | period_bytes = snd_pcm_lib_period_bytes(substream); |
1489 | 1544 | ||
1490 | snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", | 1545 | snd_printdd(SFX "azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", |
1491 | bufsize, format_val); | 1546 | bufsize, format_val); |
1492 | 1547 | ||
1493 | if (bufsize != azx_dev->bufsize || | 1548 | if (bufsize != azx_dev->bufsize || |
@@ -1830,7 +1885,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
1830 | &pcm); | 1885 | &pcm); |
1831 | if (err < 0) | 1886 | if (err < 0) |
1832 | return err; | 1887 | return err; |
1833 | strcpy(pcm->name, cpcm->name); | 1888 | strlcpy(pcm->name, cpcm->name, sizeof(pcm->name)); |
1834 | apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); | 1889 | apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); |
1835 | if (apcm == NULL) | 1890 | if (apcm == NULL) |
1836 | return -ENOMEM; | 1891 | return -ENOMEM; |
@@ -1973,7 +2028,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) | |||
1973 | for (i = 0; i < AZX_MAX_PCMS; i++) | 2028 | for (i = 0; i < AZX_MAX_PCMS; i++) |
1974 | snd_pcm_suspend_all(chip->pcm[i]); | 2029 | snd_pcm_suspend_all(chip->pcm[i]); |
1975 | if (chip->initialized) | 2030 | if (chip->initialized) |
1976 | snd_hda_suspend(chip->bus, state); | 2031 | snd_hda_suspend(chip->bus); |
1977 | azx_stop_chip(chip); | 2032 | azx_stop_chip(chip); |
1978 | if (chip->irq >= 0) { | 2033 | if (chip->irq >= 0) { |
1979 | free_irq(chip->irq, chip); | 2034 | free_irq(chip->irq, chip); |
@@ -2265,14 +2320,14 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2265 | synchronize_irq(chip->irq); | 2320 | synchronize_irq(chip->irq); |
2266 | 2321 | ||
2267 | gcap = azx_readw(chip, GCAP); | 2322 | gcap = azx_readw(chip, GCAP); |
2268 | snd_printdd("chipset global capabilities = 0x%x\n", gcap); | 2323 | snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); |
2269 | 2324 | ||
2270 | /* ATI chips seems buggy about 64bit DMA addresses */ | 2325 | /* ATI chips seems buggy about 64bit DMA addresses */ |
2271 | if (chip->driver_type == AZX_DRIVER_ATI) | 2326 | if (chip->driver_type == AZX_DRIVER_ATI) |
2272 | gcap &= ~0x01; | 2327 | gcap &= ~ICH6_GCAP_64OK; |
2273 | 2328 | ||
2274 | /* allow 64bit DMA address if supported by H/W */ | 2329 | /* allow 64bit DMA address if supported by H/W */ |
2275 | if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 2330 | 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)); | 2331 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); |
2277 | else { | 2332 | else { |
2278 | pci_set_dma_mask(pci, DMA_BIT_MASK(32)); | 2333 | pci_set_dma_mask(pci, DMA_BIT_MASK(32)); |
@@ -2309,7 +2364,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), | 2364 | chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), |
2310 | GFP_KERNEL); | 2365 | GFP_KERNEL); |
2311 | if (!chip->azx_dev) { | 2366 | if (!chip->azx_dev) { |
2312 | snd_printk(KERN_ERR "cannot malloc azx_dev\n"); | 2367 | snd_printk(KERN_ERR SFX "cannot malloc azx_dev\n"); |
2313 | goto errout; | 2368 | goto errout; |
2314 | } | 2369 | } |
2315 | 2370 | ||
@@ -2332,11 +2387,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2332 | goto errout; | 2387 | goto errout; |
2333 | } | 2388 | } |
2334 | /* allocate CORB/RIRB */ | 2389 | /* allocate CORB/RIRB */ |
2335 | if (!chip->single_cmd) { | 2390 | err = azx_alloc_cmd_io(chip); |
2336 | err = azx_alloc_cmd_io(chip); | 2391 | if (err < 0) |
2337 | if (err < 0) | 2392 | goto errout; |
2338 | goto errout; | ||
2339 | } | ||
2340 | 2393 | ||
2341 | /* initialize streams */ | 2394 | /* initialize streams */ |
2342 | azx_init_stream(chip); | 2395 | azx_init_stream(chip); |
@@ -2359,9 +2412,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2359 | } | 2412 | } |
2360 | 2413 | ||
2361 | strcpy(card->driver, "HDA-Intel"); | 2414 | strcpy(card->driver, "HDA-Intel"); |
2362 | strcpy(card->shortname, driver_short_names[chip->driver_type]); | 2415 | strlcpy(card->shortname, driver_short_names[chip->driver_type], |
2363 | sprintf(card->longname, "%s at 0x%lx irq %i", | 2416 | sizeof(card->shortname)); |
2364 | card->shortname, chip->addr, chip->irq); | 2417 | snprintf(card->longname, sizeof(card->longname), |
2418 | "%s at 0x%lx irq %i", | ||
2419 | card->shortname, chip->addr, chip->irq); | ||
2365 | 2420 | ||
2366 | *rchip = chip; | 2421 | *rchip = chip; |
2367 | return 0; | 2422 | return 0; |
@@ -2514,6 +2569,20 @@ static struct pci_device_id azx_ids[] = { | |||
2514 | { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA }, | 2569 | { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA }, |
2515 | /* Teradici */ | 2570 | /* Teradici */ |
2516 | { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, | 2571 | { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, |
2572 | /* Creative X-Fi (CA0110-IBG) */ | ||
2573 | #if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE) | ||
2574 | /* the following entry conflicts with snd-ctxfi driver, | ||
2575 | * as ctxfi driver mutates from HD-audio to native mode with | ||
2576 | * a special command sequence. | ||
2577 | */ | ||
2578 | { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), | ||
2579 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | ||
2580 | .class_mask = 0xffffff, | ||
2581 | .driver_data = AZX_DRIVER_GENERIC }, | ||
2582 | #else | ||
2583 | /* this entry seems still valid -- i.e. without emu20kx chip */ | ||
2584 | { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, | ||
2585 | #endif | ||
2517 | /* AMD Generic, PCI class code and Vendor ID for HD Audio */ | 2586 | /* AMD Generic, PCI class code and Vendor ID for HD Audio */ |
2518 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), | 2587 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), |
2519 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2588 | .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_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index d57d8132a06e..f5792e2eea82 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c | |||
@@ -35,9 +35,28 @@ struct nvhdmi_spec { | |||
35 | struct hda_pcm pcm_rec; | 35 | struct hda_pcm pcm_rec; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #define Nv_VERB_SET_Channel_Allocation 0xF79 | ||
39 | #define Nv_VERB_SET_Info_Frame_Checksum 0xF7A | ||
40 | #define Nv_VERB_SET_Audio_Protection_On 0xF98 | ||
41 | #define Nv_VERB_SET_Audio_Protection_Off 0xF99 | ||
42 | |||
43 | #define Nv_Master_Convert_nid 0x04 | ||
44 | #define Nv_Master_Pin_nid 0x05 | ||
45 | |||
46 | static hda_nid_t nvhdmi_convert_nids[4] = { | ||
47 | /*front, rear, clfe, rear_surr */ | ||
48 | 0x6, 0x8, 0xa, 0xc, | ||
49 | }; | ||
50 | |||
38 | static struct hda_verb nvhdmi_basic_init[] = { | 51 | static struct hda_verb nvhdmi_basic_init[] = { |
52 | /* set audio protect on */ | ||
53 | { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, | ||
39 | /* enable digital output on pin widget */ | 54 | /* enable digital output on pin widget */ |
40 | { 0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 55 | { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, |
56 | { 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, | ||
57 | { 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, | ||
58 | { 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, | ||
59 | { 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, | ||
41 | {} /* terminator */ | 60 | {} /* terminator */ |
42 | }; | 61 | }; |
43 | 62 | ||
@@ -66,48 +85,205 @@ static int nvhdmi_init(struct hda_codec *codec) | |||
66 | * Digital out | 85 | * Digital out |
67 | */ | 86 | */ |
68 | static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | 87 | static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, |
69 | struct hda_codec *codec, | 88 | struct hda_codec *codec, |
70 | struct snd_pcm_substream *substream) | 89 | struct snd_pcm_substream *substream) |
71 | { | 90 | { |
72 | struct nvhdmi_spec *spec = codec->spec; | 91 | struct nvhdmi_spec *spec = codec->spec; |
73 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | 92 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); |
74 | } | 93 | } |
75 | 94 | ||
76 | static int nvhdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | 95 | static int nvhdmi_dig_playback_pcm_close_8ch(struct hda_pcm_stream *hinfo, |
77 | struct hda_codec *codec, | 96 | struct hda_codec *codec, |
78 | struct snd_pcm_substream *substream) | 97 | struct snd_pcm_substream *substream) |
79 | { | 98 | { |
80 | struct nvhdmi_spec *spec = codec->spec; | 99 | struct nvhdmi_spec *spec = codec->spec; |
100 | int i; | ||
101 | |||
102 | snd_hda_codec_write(codec, Nv_Master_Convert_nid, | ||
103 | 0, AC_VERB_SET_CHANNEL_STREAMID, 0); | ||
104 | for (i = 0; i < 4; i++) { | ||
105 | /* set the stream id */ | ||
106 | snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, | ||
107 | AC_VERB_SET_CHANNEL_STREAMID, 0); | ||
108 | /* set the stream format */ | ||
109 | snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, | ||
110 | AC_VERB_SET_STREAM_FORMAT, 0); | ||
111 | } | ||
112 | |||
81 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 113 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
82 | } | 114 | } |
83 | 115 | ||
84 | static int nvhdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 116 | static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo, |
85 | struct hda_codec *codec, | 117 | struct hda_codec *codec, |
86 | unsigned int stream_tag, | 118 | struct snd_pcm_substream *substream) |
87 | unsigned int format, | 119 | { |
88 | struct snd_pcm_substream *substream) | 120 | struct nvhdmi_spec *spec = codec->spec; |
121 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | ||
122 | } | ||
123 | |||
124 | static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, | ||
125 | struct hda_codec *codec, | ||
126 | unsigned int stream_tag, | ||
127 | unsigned int format, | ||
128 | struct snd_pcm_substream *substream) | ||
129 | { | ||
130 | int chs; | ||
131 | unsigned int dataDCC1, dataDCC2, chan, chanmask, channel_id; | ||
132 | int i; | ||
133 | |||
134 | mutex_lock(&codec->spdif_mutex); | ||
135 | |||
136 | chs = substream->runtime->channels; | ||
137 | chan = chs ? (chs - 1) : 1; | ||
138 | |||
139 | switch (chs) { | ||
140 | default: | ||
141 | case 0: | ||
142 | case 2: | ||
143 | chanmask = 0x00; | ||
144 | break; | ||
145 | case 4: | ||
146 | chanmask = 0x08; | ||
147 | break; | ||
148 | case 6: | ||
149 | chanmask = 0x0b; | ||
150 | break; | ||
151 | case 8: | ||
152 | chanmask = 0x13; | ||
153 | break; | ||
154 | } | ||
155 | dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT; | ||
156 | dataDCC2 = 0x2; | ||
157 | |||
158 | /* set the Audio InforFrame Channel Allocation */ | ||
159 | snd_hda_codec_write(codec, 0x1, 0, | ||
160 | Nv_VERB_SET_Channel_Allocation, chanmask); | ||
161 | |||
162 | /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ | ||
163 | if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) | ||
164 | snd_hda_codec_write(codec, | ||
165 | Nv_Master_Convert_nid, | ||
166 | 0, | ||
167 | AC_VERB_SET_DIGI_CONVERT_1, | ||
168 | codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); | ||
169 | |||
170 | /* set the stream id */ | ||
171 | snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, | ||
172 | AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0); | ||
173 | |||
174 | /* set the stream format */ | ||
175 | snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, | ||
176 | AC_VERB_SET_STREAM_FORMAT, format); | ||
177 | |||
178 | /* turn on again (if needed) */ | ||
179 | /* enable and set the channel status audio/data flag */ | ||
180 | if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { | ||
181 | snd_hda_codec_write(codec, | ||
182 | Nv_Master_Convert_nid, | ||
183 | 0, | ||
184 | AC_VERB_SET_DIGI_CONVERT_1, | ||
185 | codec->spdif_ctls & 0xff); | ||
186 | snd_hda_codec_write(codec, | ||
187 | Nv_Master_Convert_nid, | ||
188 | 0, | ||
189 | AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); | ||
190 | } | ||
191 | |||
192 | for (i = 0; i < 4; i++) { | ||
193 | if (chs == 2) | ||
194 | channel_id = 0; | ||
195 | else | ||
196 | channel_id = i * 2; | ||
197 | |||
198 | /* turn off SPDIF once; | ||
199 | *otherwise the IEC958 bits won't be updated | ||
200 | */ | ||
201 | if (codec->spdif_status_reset && | ||
202 | (codec->spdif_ctls & AC_DIG1_ENABLE)) | ||
203 | snd_hda_codec_write(codec, | ||
204 | nvhdmi_convert_nids[i], | ||
205 | 0, | ||
206 | AC_VERB_SET_DIGI_CONVERT_1, | ||
207 | codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); | ||
208 | /* set the stream id */ | ||
209 | snd_hda_codec_write(codec, | ||
210 | nvhdmi_convert_nids[i], | ||
211 | 0, | ||
212 | AC_VERB_SET_CHANNEL_STREAMID, | ||
213 | (stream_tag << 4) | channel_id); | ||
214 | /* set the stream format */ | ||
215 | snd_hda_codec_write(codec, | ||
216 | nvhdmi_convert_nids[i], | ||
217 | 0, | ||
218 | AC_VERB_SET_STREAM_FORMAT, | ||
219 | format); | ||
220 | /* turn on again (if needed) */ | ||
221 | /* enable and set the channel status audio/data flag */ | ||
222 | if (codec->spdif_status_reset && | ||
223 | (codec->spdif_ctls & AC_DIG1_ENABLE)) { | ||
224 | snd_hda_codec_write(codec, | ||
225 | nvhdmi_convert_nids[i], | ||
226 | 0, | ||
227 | AC_VERB_SET_DIGI_CONVERT_1, | ||
228 | codec->spdif_ctls & 0xff); | ||
229 | snd_hda_codec_write(codec, | ||
230 | nvhdmi_convert_nids[i], | ||
231 | 0, | ||
232 | AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | /* set the Audio Info Frame Checksum */ | ||
237 | snd_hda_codec_write(codec, 0x1, 0, | ||
238 | Nv_VERB_SET_Info_Frame_Checksum, | ||
239 | (0x71 - chan - chanmask)); | ||
240 | |||
241 | mutex_unlock(&codec->spdif_mutex); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo, | ||
246 | struct hda_codec *codec, | ||
247 | unsigned int stream_tag, | ||
248 | unsigned int format, | ||
249 | struct snd_pcm_substream *substream) | ||
89 | { | 250 | { |
90 | struct nvhdmi_spec *spec = codec->spec; | 251 | struct nvhdmi_spec *spec = codec->spec; |
91 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | 252 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, |
92 | format, substream); | 253 | format, substream); |
93 | } | 254 | } |
94 | 255 | ||
95 | static struct hda_pcm_stream nvhdmi_pcm_digital_playback = { | 256 | static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch = { |
257 | .substreams = 1, | ||
258 | .channels_min = 2, | ||
259 | .channels_max = 8, | ||
260 | .nid = Nv_Master_Convert_nid, | ||
261 | .rates = SNDRV_PCM_RATE_48000, | ||
262 | .maxbps = 16, | ||
263 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
264 | .ops = { | ||
265 | .open = nvhdmi_dig_playback_pcm_open, | ||
266 | .close = nvhdmi_dig_playback_pcm_close_8ch, | ||
267 | .prepare = nvhdmi_dig_playback_pcm_prepare_8ch | ||
268 | }, | ||
269 | }; | ||
270 | |||
271 | static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = { | ||
96 | .substreams = 1, | 272 | .substreams = 1, |
97 | .channels_min = 2, | 273 | .channels_min = 2, |
98 | .channels_max = 2, | 274 | .channels_max = 2, |
99 | .nid = 0x4, /* NID to query formats and rates and setup streams */ | 275 | .nid = Nv_Master_Convert_nid, |
100 | .rates = SNDRV_PCM_RATE_48000, | 276 | .rates = SNDRV_PCM_RATE_48000, |
101 | .maxbps = 16, | 277 | .maxbps = 16, |
102 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 278 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
103 | .ops = { | 279 | .ops = { |
104 | .open = nvhdmi_dig_playback_pcm_open, | 280 | .open = nvhdmi_dig_playback_pcm_open, |
105 | .close = nvhdmi_dig_playback_pcm_close, | 281 | .close = nvhdmi_dig_playback_pcm_close_2ch, |
106 | .prepare = nvhdmi_dig_playback_pcm_prepare | 282 | .prepare = nvhdmi_dig_playback_pcm_prepare_2ch |
107 | }, | 283 | }, |
108 | }; | 284 | }; |
109 | 285 | ||
110 | static int nvhdmi_build_pcms(struct hda_codec *codec) | 286 | static int nvhdmi_build_pcms_8ch(struct hda_codec *codec) |
111 | { | 287 | { |
112 | struct nvhdmi_spec *spec = codec->spec; | 288 | struct nvhdmi_spec *spec = codec->spec; |
113 | struct hda_pcm *info = &spec->pcm_rec; | 289 | struct hda_pcm *info = &spec->pcm_rec; |
@@ -117,7 +293,24 @@ static int nvhdmi_build_pcms(struct hda_codec *codec) | |||
117 | 293 | ||
118 | info->name = "NVIDIA HDMI"; | 294 | info->name = "NVIDIA HDMI"; |
119 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 295 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
120 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = nvhdmi_pcm_digital_playback; | 296 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] |
297 | = nvhdmi_pcm_digital_playback_8ch; | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static int nvhdmi_build_pcms_2ch(struct hda_codec *codec) | ||
303 | { | ||
304 | struct nvhdmi_spec *spec = codec->spec; | ||
305 | struct hda_pcm *info = &spec->pcm_rec; | ||
306 | |||
307 | codec->num_pcms = 1; | ||
308 | codec->pcm_info = info; | ||
309 | |||
310 | info->name = "NVIDIA HDMI"; | ||
311 | info->pcm_type = HDA_PCM_TYPE_HDMI; | ||
312 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] | ||
313 | = nvhdmi_pcm_digital_playback_2ch; | ||
121 | 314 | ||
122 | return 0; | 315 | return 0; |
123 | } | 316 | } |
@@ -127,14 +320,40 @@ static void nvhdmi_free(struct hda_codec *codec) | |||
127 | kfree(codec->spec); | 320 | kfree(codec->spec); |
128 | } | 321 | } |
129 | 322 | ||
130 | static struct hda_codec_ops nvhdmi_patch_ops = { | 323 | static struct hda_codec_ops nvhdmi_patch_ops_8ch = { |
324 | .build_controls = nvhdmi_build_controls, | ||
325 | .build_pcms = nvhdmi_build_pcms_8ch, | ||
326 | .init = nvhdmi_init, | ||
327 | .free = nvhdmi_free, | ||
328 | }; | ||
329 | |||
330 | static struct hda_codec_ops nvhdmi_patch_ops_2ch = { | ||
131 | .build_controls = nvhdmi_build_controls, | 331 | .build_controls = nvhdmi_build_controls, |
132 | .build_pcms = nvhdmi_build_pcms, | 332 | .build_pcms = nvhdmi_build_pcms_2ch, |
133 | .init = nvhdmi_init, | 333 | .init = nvhdmi_init, |
134 | .free = nvhdmi_free, | 334 | .free = nvhdmi_free, |
135 | }; | 335 | }; |
136 | 336 | ||
137 | static int patch_nvhdmi(struct hda_codec *codec) | 337 | static int patch_nvhdmi_8ch(struct hda_codec *codec) |
338 | { | ||
339 | struct nvhdmi_spec *spec; | ||
340 | |||
341 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
342 | if (spec == NULL) | ||
343 | return -ENOMEM; | ||
344 | |||
345 | codec->spec = spec; | ||
346 | |||
347 | spec->multiout.num_dacs = 0; /* no analog */ | ||
348 | spec->multiout.max_channels = 8; | ||
349 | spec->multiout.dig_out_nid = Nv_Master_Convert_nid; | ||
350 | |||
351 | codec->patch_ops = nvhdmi_patch_ops_8ch; | ||
352 | |||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | static int patch_nvhdmi_2ch(struct hda_codec *codec) | ||
138 | { | 357 | { |
139 | struct nvhdmi_spec *spec; | 358 | struct nvhdmi_spec *spec; |
140 | 359 | ||
@@ -144,13 +363,11 @@ static int patch_nvhdmi(struct hda_codec *codec) | |||
144 | 363 | ||
145 | codec->spec = spec; | 364 | codec->spec = spec; |
146 | 365 | ||
147 | spec->multiout.num_dacs = 0; /* no analog */ | 366 | spec->multiout.num_dacs = 0; /* no analog */ |
148 | spec->multiout.max_channels = 2; | 367 | spec->multiout.max_channels = 2; |
149 | spec->multiout.dig_out_nid = 0x4; /* NID for copying analog to digital, | 368 | spec->multiout.dig_out_nid = Nv_Master_Convert_nid; |
150 | * seems to be unused in pure-digital | ||
151 | * case. */ | ||
152 | 369 | ||
153 | codec->patch_ops = nvhdmi_patch_ops; | 370 | codec->patch_ops = nvhdmi_patch_ops_2ch; |
154 | 371 | ||
155 | return 0; | 372 | return 0; |
156 | } | 373 | } |
@@ -159,11 +376,11 @@ static int patch_nvhdmi(struct hda_codec *codec) | |||
159 | * patch entries | 376 | * patch entries |
160 | */ | 377 | */ |
161 | static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { | 378 | static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { |
162 | { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi }, | 379 | { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, |
163 | { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi }, | 380 | { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, |
164 | { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi }, | 381 | { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch }, |
165 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi }, | 382 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, |
166 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi }, | 383 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, |
167 | {} /* terminator */ | 384 | {} /* terminator */ |
168 | }; | 385 | }; |
169 | 386 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0fd258eba3a5..337d2a59c67e 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, |
@@ -218,9 +220,11 @@ enum { | |||
218 | ALC883_6ST_DIG, | 220 | ALC883_6ST_DIG, |
219 | ALC883_TARGA_DIG, | 221 | ALC883_TARGA_DIG, |
220 | ALC883_TARGA_2ch_DIG, | 222 | ALC883_TARGA_2ch_DIG, |
223 | ALC883_TARGA_8ch_DIG, | ||
221 | ALC883_ACER, | 224 | ALC883_ACER, |
222 | ALC883_ACER_ASPIRE, | 225 | ALC883_ACER_ASPIRE, |
223 | ALC888_ACER_ASPIRE_4930G, | 226 | ALC888_ACER_ASPIRE_4930G, |
227 | ALC888_ACER_ASPIRE_8930G, | ||
224 | ALC883_MEDION, | 228 | ALC883_MEDION, |
225 | ALC883_MEDION_MD2, | 229 | ALC883_MEDION_MD2, |
226 | ALC883_LAPTOP_EAPD, | 230 | ALC883_LAPTOP_EAPD, |
@@ -238,7 +242,9 @@ enum { | |||
238 | ALC883_3ST_6ch_INTEL, | 242 | ALC883_3ST_6ch_INTEL, |
239 | ALC888_ASUS_M90V, | 243 | ALC888_ASUS_M90V, |
240 | ALC888_ASUS_EEE1601, | 244 | ALC888_ASUS_EEE1601, |
245 | ALC889A_MB31, | ||
241 | ALC1200_ASUS_P5Q, | 246 | ALC1200_ASUS_P5Q, |
247 | ALC883_SONY_VAIO_TT, | ||
242 | ALC883_AUTO, | 248 | ALC883_AUTO, |
243 | ALC883_MODEL_LAST, | 249 | ALC883_MODEL_LAST, |
244 | }; | 250 | }; |
@@ -253,6 +259,15 @@ enum { | |||
253 | /* for GPIO Poll */ | 259 | /* for GPIO Poll */ |
254 | #define GPIO_MASK 0x03 | 260 | #define GPIO_MASK 0x03 |
255 | 261 | ||
262 | /* extra amp-initialization sequence types */ | ||
263 | enum { | ||
264 | ALC_INIT_NONE, | ||
265 | ALC_INIT_DEFAULT, | ||
266 | ALC_INIT_GPIO1, | ||
267 | ALC_INIT_GPIO2, | ||
268 | ALC_INIT_GPIO3, | ||
269 | }; | ||
270 | |||
256 | struct alc_spec { | 271 | struct alc_spec { |
257 | /* codec parameterization */ | 272 | /* codec parameterization */ |
258 | struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ | 273 | struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ |
@@ -266,13 +281,13 @@ struct alc_spec { | |||
266 | */ | 281 | */ |
267 | unsigned int num_init_verbs; | 282 | unsigned int num_init_verbs; |
268 | 283 | ||
269 | char *stream_name_analog; /* analog PCM stream */ | 284 | char stream_name_analog[16]; /* analog PCM stream */ |
270 | struct hda_pcm_stream *stream_analog_playback; | 285 | struct hda_pcm_stream *stream_analog_playback; |
271 | struct hda_pcm_stream *stream_analog_capture; | 286 | struct hda_pcm_stream *stream_analog_capture; |
272 | struct hda_pcm_stream *stream_analog_alt_playback; | 287 | struct hda_pcm_stream *stream_analog_alt_playback; |
273 | struct hda_pcm_stream *stream_analog_alt_capture; | 288 | struct hda_pcm_stream *stream_analog_alt_capture; |
274 | 289 | ||
275 | char *stream_name_digital; /* digital PCM stream */ | 290 | char stream_name_digital[16]; /* digital PCM stream */ |
276 | struct hda_pcm_stream *stream_digital_playback; | 291 | struct hda_pcm_stream *stream_digital_playback; |
277 | struct hda_pcm_stream *stream_digital_capture; | 292 | struct hda_pcm_stream *stream_digital_capture; |
278 | 293 | ||
@@ -301,6 +316,8 @@ struct alc_spec { | |||
301 | const struct hda_channel_mode *channel_mode; | 316 | const struct hda_channel_mode *channel_mode; |
302 | int num_channel_mode; | 317 | int num_channel_mode; |
303 | int need_dac_fix; | 318 | int need_dac_fix; |
319 | int const_channel_count; | ||
320 | int ext_channel_count; | ||
304 | 321 | ||
305 | /* PCM information */ | 322 | /* PCM information */ |
306 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ | 323 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ |
@@ -322,6 +339,7 @@ struct alc_spec { | |||
322 | 339 | ||
323 | /* other flags */ | 340 | /* other flags */ |
324 | unsigned int no_analog :1; /* digital I/O only */ | 341 | unsigned int no_analog :1; /* digital I/O only */ |
342 | int init_amp; | ||
325 | 343 | ||
326 | /* for virtual master */ | 344 | /* for virtual master */ |
327 | hda_nid_t vmaster_nid; | 345 | hda_nid_t vmaster_nid; |
@@ -355,6 +373,7 @@ struct alc_config_preset { | |||
355 | unsigned int num_channel_mode; | 373 | unsigned int num_channel_mode; |
356 | const struct hda_channel_mode *channel_mode; | 374 | const struct hda_channel_mode *channel_mode; |
357 | int need_dac_fix; | 375 | int need_dac_fix; |
376 | int const_channel_count; | ||
358 | unsigned int num_mux_defs; | 377 | unsigned int num_mux_defs; |
359 | const struct hda_input_mux *input_mux; | 378 | const struct hda_input_mux *input_mux; |
360 | void (*unsol_event)(struct hda_codec *, unsigned int); | 379 | void (*unsol_event)(struct hda_codec *, unsigned int); |
@@ -449,7 +468,7 @@ static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, | |||
449 | struct alc_spec *spec = codec->spec; | 468 | struct alc_spec *spec = codec->spec; |
450 | return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, | 469 | return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, |
451 | spec->num_channel_mode, | 470 | spec->num_channel_mode, |
452 | spec->multiout.max_channels); | 471 | spec->ext_channel_count); |
453 | } | 472 | } |
454 | 473 | ||
455 | static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, | 474 | static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, |
@@ -459,9 +478,12 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
459 | struct alc_spec *spec = codec->spec; | 478 | struct alc_spec *spec = codec->spec; |
460 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, | 479 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, |
461 | spec->num_channel_mode, | 480 | spec->num_channel_mode, |
462 | &spec->multiout.max_channels); | 481 | &spec->ext_channel_count); |
463 | if (err >= 0 && spec->need_dac_fix) | 482 | if (err >= 0 && !spec->const_channel_count) { |
464 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | 483 | spec->multiout.max_channels = spec->ext_channel_count; |
484 | if (spec->need_dac_fix) | ||
485 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | ||
486 | } | ||
465 | return err; | 487 | return err; |
466 | } | 488 | } |
467 | 489 | ||
@@ -841,8 +863,13 @@ static void setup_preset(struct alc_spec *spec, | |||
841 | spec->channel_mode = preset->channel_mode; | 863 | spec->channel_mode = preset->channel_mode; |
842 | spec->num_channel_mode = preset->num_channel_mode; | 864 | spec->num_channel_mode = preset->num_channel_mode; |
843 | spec->need_dac_fix = preset->need_dac_fix; | 865 | spec->need_dac_fix = preset->need_dac_fix; |
866 | spec->const_channel_count = preset->const_channel_count; | ||
844 | 867 | ||
845 | spec->multiout.max_channels = spec->channel_mode[0].channels; | 868 | if (preset->const_channel_count) |
869 | spec->multiout.max_channels = preset->const_channel_count; | ||
870 | else | ||
871 | spec->multiout.max_channels = spec->channel_mode[0].channels; | ||
872 | spec->ext_channel_count = spec->channel_mode[0].channels; | ||
846 | 873 | ||
847 | spec->multiout.num_dacs = preset->num_dacs; | 874 | spec->multiout.num_dacs = preset->num_dacs; |
848 | spec->multiout.dac_nids = preset->dac_nids; | 875 | spec->multiout.dac_nids = preset->dac_nids; |
@@ -921,20 +948,26 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | |||
921 | alc_fix_pll(codec); | 948 | alc_fix_pll(codec); |
922 | } | 949 | } |
923 | 950 | ||
924 | static void alc_sku_automute(struct hda_codec *codec) | 951 | static void alc_automute_pin(struct hda_codec *codec) |
925 | { | 952 | { |
926 | struct alc_spec *spec = codec->spec; | 953 | struct alc_spec *spec = codec->spec; |
927 | unsigned int present; | 954 | unsigned int present; |
928 | unsigned int hp_nid = spec->autocfg.hp_pins[0]; | 955 | unsigned int nid = spec->autocfg.hp_pins[0]; |
929 | unsigned int sp_nid = spec->autocfg.speaker_pins[0]; | 956 | int i; |
930 | 957 | ||
931 | /* need to execute and sync at first */ | 958 | /* need to execute and sync at first */ |
932 | snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); | 959 | snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); |
933 | present = snd_hda_codec_read(codec, hp_nid, 0, | 960 | present = snd_hda_codec_read(codec, nid, 0, |
934 | AC_VERB_GET_PIN_SENSE, 0); | 961 | AC_VERB_GET_PIN_SENSE, 0); |
935 | spec->jack_present = (present & 0x80000000) != 0; | 962 | spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; |
936 | snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 963 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { |
937 | spec->jack_present ? 0 : PIN_OUT); | 964 | nid = spec->autocfg.speaker_pins[i]; |
965 | if (!nid) | ||
966 | break; | ||
967 | snd_hda_codec_write(codec, nid, 0, | ||
968 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
969 | spec->jack_present ? 0 : PIN_OUT); | ||
970 | } | ||
938 | } | 971 | } |
939 | 972 | ||
940 | #if 0 /* it's broken in some acses -- temporarily disabled */ | 973 | #if 0 /* it's broken in some acses -- temporarily disabled */ |
@@ -969,16 +1002,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | |||
969 | res >>= 28; | 1002 | res >>= 28; |
970 | else | 1003 | else |
971 | res >>= 26; | 1004 | res >>= 26; |
972 | if (res == ALC880_HP_EVENT) | 1005 | switch (res) { |
973 | alc_sku_automute(codec); | 1006 | case ALC880_HP_EVENT: |
974 | 1007 | alc_automute_pin(codec); | |
975 | if (res == ALC880_MIC_EVENT) | 1008 | break; |
1009 | case ALC880_MIC_EVENT: | ||
976 | alc_mic_automute(codec); | 1010 | alc_mic_automute(codec); |
1011 | break; | ||
1012 | } | ||
977 | } | 1013 | } |
978 | 1014 | ||
979 | static void alc_inithook(struct hda_codec *codec) | 1015 | static void alc_inithook(struct hda_codec *codec) |
980 | { | 1016 | { |
981 | alc_sku_automute(codec); | 1017 | alc_automute_pin(codec); |
982 | alc_mic_automute(codec); | 1018 | alc_mic_automute(codec); |
983 | } | 1019 | } |
984 | 1020 | ||
@@ -1000,69 +1036,21 @@ static void alc888_coef_init(struct hda_codec *codec) | |||
1000 | AC_VERB_SET_PROC_COEF, 0x3030); | 1036 | AC_VERB_SET_PROC_COEF, 0x3030); |
1001 | } | 1037 | } |
1002 | 1038 | ||
1003 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. | 1039 | 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 | { | 1040 | { |
1013 | unsigned int ass, tmp, i; | 1041 | 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 | 1042 | ||
1038 | /* check sum */ | 1043 | switch (type) { |
1039 | tmp = 0; | 1044 | 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); | 1045 | snd_hda_sequence_write(codec, alc_gpio1_init_verbs); |
1058 | break; | 1046 | break; |
1059 | case 3: | 1047 | case ALC_INIT_GPIO2: |
1060 | snd_hda_sequence_write(codec, alc_gpio2_init_verbs); | 1048 | snd_hda_sequence_write(codec, alc_gpio2_init_verbs); |
1061 | break; | 1049 | break; |
1062 | case 7: | 1050 | case ALC_INIT_GPIO3: |
1063 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); | 1051 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); |
1064 | break; | 1052 | break; |
1065 | case 5: /* set EAPD output high */ | 1053 | case ALC_INIT_DEFAULT: |
1066 | switch (codec->vendor_id) { | 1054 | switch (codec->vendor_id) { |
1067 | case 0x10ec0260: | 1055 | case 0x10ec0260: |
1068 | snd_hda_codec_write(codec, 0x0f, 0, | 1056 | snd_hda_codec_write(codec, 0x0f, 0, |
@@ -1116,7 +1104,7 @@ do_sku: | |||
1116 | tmp | 0x2010); | 1104 | tmp | 0x2010); |
1117 | break; | 1105 | break; |
1118 | case 0x10ec0888: | 1106 | case 0x10ec0888: |
1119 | /*alc888_coef_init(codec);*/ /* called in alc_init() */ | 1107 | alc888_coef_init(codec); |
1120 | break; | 1108 | break; |
1121 | case 0x10ec0267: | 1109 | case 0x10ec0267: |
1122 | case 0x10ec0268: | 1110 | case 0x10ec0268: |
@@ -1131,7 +1119,107 @@ do_sku: | |||
1131 | tmp | 0x3000); | 1119 | tmp | 0x3000); |
1132 | break; | 1120 | break; |
1133 | } | 1121 | } |
1134 | default: | 1122 | break; |
1123 | } | ||
1124 | } | ||
1125 | |||
1126 | static void alc_init_auto_hp(struct hda_codec *codec) | ||
1127 | { | ||
1128 | struct alc_spec *spec = codec->spec; | ||
1129 | |||
1130 | if (!spec->autocfg.hp_pins[0]) | ||
1131 | return; | ||
1132 | |||
1133 | if (!spec->autocfg.speaker_pins[0]) { | ||
1134 | if (spec->autocfg.line_out_pins[0] && | ||
1135 | spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
1136 | spec->autocfg.speaker_pins[0] = | ||
1137 | spec->autocfg.line_out_pins[0]; | ||
1138 | else | ||
1139 | return; | ||
1140 | } | ||
1141 | |||
1142 | snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", | ||
1143 | spec->autocfg.hp_pins[0]); | ||
1144 | snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0, | ||
1145 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1146 | AC_USRSP_EN | ALC880_HP_EVENT); | ||
1147 | spec->unsol_event = alc_sku_unsol_event; | ||
1148 | } | ||
1149 | |||
1150 | /* check subsystem ID and set up device-specific initialization; | ||
1151 | * return 1 if initialized, 0 if invalid SSID | ||
1152 | */ | ||
1153 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. | ||
1154 | * 31 ~ 16 : Manufacture ID | ||
1155 | * 15 ~ 8 : SKU ID | ||
1156 | * 7 ~ 0 : Assembly ID | ||
1157 | * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 | ||
1158 | */ | ||
1159 | static int alc_subsystem_id(struct hda_codec *codec, | ||
1160 | hda_nid_t porta, hda_nid_t porte, | ||
1161 | hda_nid_t portd) | ||
1162 | { | ||
1163 | unsigned int ass, tmp, i; | ||
1164 | unsigned nid; | ||
1165 | struct alc_spec *spec = codec->spec; | ||
1166 | |||
1167 | ass = codec->subsystem_id & 0xffff; | ||
1168 | if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) | ||
1169 | goto do_sku; | ||
1170 | |||
1171 | /* invalid SSID, check the special NID pin defcfg instead */ | ||
1172 | /* | ||
1173 | * 31~30 : port conetcivity | ||
1174 | * 29~21 : reserve | ||
1175 | * 20 : PCBEEP input | ||
1176 | * 19~16 : Check sum (15:1) | ||
1177 | * 15~1 : Custom | ||
1178 | * 0 : override | ||
1179 | */ | ||
1180 | nid = 0x1d; | ||
1181 | if (codec->vendor_id == 0x10ec0260) | ||
1182 | nid = 0x17; | ||
1183 | ass = snd_hda_codec_get_pincfg(codec, nid); | ||
1184 | snd_printd("realtek: No valid SSID, " | ||
1185 | "checking pincfg 0x%08x for NID 0x%x\n", | ||
1186 | ass, nid); | ||
1187 | if (!(ass & 1) && !(ass & 0x100000)) | ||
1188 | return 0; | ||
1189 | if ((ass >> 30) != 1) /* no physical connection */ | ||
1190 | return 0; | ||
1191 | |||
1192 | /* check sum */ | ||
1193 | tmp = 0; | ||
1194 | for (i = 1; i < 16; i++) { | ||
1195 | if ((ass >> i) & 1) | ||
1196 | tmp++; | ||
1197 | } | ||
1198 | if (((ass >> 16) & 0xf) != tmp) | ||
1199 | return 0; | ||
1200 | do_sku: | ||
1201 | snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", | ||
1202 | ass & 0xffff, codec->vendor_id); | ||
1203 | /* | ||
1204 | * 0 : override | ||
1205 | * 1 : Swap Jack | ||
1206 | * 2 : 0 --> Desktop, 1 --> Laptop | ||
1207 | * 3~5 : External Amplifier control | ||
1208 | * 7~6 : Reserved | ||
1209 | */ | ||
1210 | tmp = (ass & 0x38) >> 3; /* external Amp control */ | ||
1211 | switch (tmp) { | ||
1212 | case 1: | ||
1213 | spec->init_amp = ALC_INIT_GPIO1; | ||
1214 | break; | ||
1215 | case 3: | ||
1216 | spec->init_amp = ALC_INIT_GPIO2; | ||
1217 | break; | ||
1218 | case 7: | ||
1219 | spec->init_amp = ALC_INIT_GPIO3; | ||
1220 | break; | ||
1221 | case 5: | ||
1222 | spec->init_amp = ALC_INIT_DEFAULT; | ||
1135 | break; | 1223 | break; |
1136 | } | 1224 | } |
1137 | 1225 | ||
@@ -1139,7 +1227,7 @@ do_sku: | |||
1139 | * when the external headphone out jack is plugged" | 1227 | * when the external headphone out jack is plugged" |
1140 | */ | 1228 | */ |
1141 | if (!(ass & 0x8000)) | 1229 | if (!(ass & 0x8000)) |
1142 | return; | 1230 | return 1; |
1143 | /* | 1231 | /* |
1144 | * 10~8 : Jack location | 1232 | * 10~8 : Jack location |
1145 | * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered | 1233 | * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered |
@@ -1147,14 +1235,6 @@ do_sku: | |||
1147 | * 15 : 1 --> enable the function "Mute internal speaker | 1235 | * 15 : 1 --> enable the function "Mute internal speaker |
1148 | * when the external headphone out jack is plugged" | 1236 | * when the external headphone out jack is plugged" |
1149 | */ | 1237 | */ |
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]) { | 1238 | if (!spec->autocfg.hp_pins[0]) { |
1159 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ | 1239 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ |
1160 | if (tmp == 0) | 1240 | if (tmp == 0) |
@@ -1164,23 +1244,23 @@ do_sku: | |||
1164 | else if (tmp == 2) | 1244 | else if (tmp == 2) |
1165 | spec->autocfg.hp_pins[0] = portd; | 1245 | spec->autocfg.hp_pins[0] = portd; |
1166 | else | 1246 | else |
1167 | return; | 1247 | return 1; |
1168 | } | 1248 | } |
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 | 1249 | ||
1174 | #if 0 /* it's broken in some acses -- temporarily disabled */ | 1250 | alc_init_auto_hp(codec); |
1175 | if (spec->autocfg.input_pins[AUTO_PIN_MIC] && | 1251 | return 1; |
1176 | spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]) | 1252 | } |
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 | 1253 | ||
1183 | spec->unsol_event = alc_sku_unsol_event; | 1254 | static void alc_ssid_check(struct hda_codec *codec, |
1255 | hda_nid_t porta, hda_nid_t porte, hda_nid_t portd) | ||
1256 | { | ||
1257 | if (!alc_subsystem_id(codec, porta, porte, portd)) { | ||
1258 | struct alc_spec *spec = codec->spec; | ||
1259 | snd_printd("realtek: " | ||
1260 | "Enable default setup for auto mode as fallback\n"); | ||
1261 | spec->init_amp = ALC_INIT_DEFAULT; | ||
1262 | alc_init_auto_hp(codec); | ||
1263 | } | ||
1184 | } | 1264 | } |
1185 | 1265 | ||
1186 | /* | 1266 | /* |
@@ -1315,32 +1395,58 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { | |||
1315 | {} | 1395 | {} |
1316 | }; | 1396 | }; |
1317 | 1397 | ||
1318 | static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec) | 1398 | static void alc_automute_amp(struct hda_codec *codec) |
1319 | { | 1399 | { |
1320 | unsigned int present; | 1400 | struct alc_spec *spec = codec->spec; |
1321 | unsigned int bits; | 1401 | unsigned int val, mute; |
1322 | /* Line out presence */ | 1402 | hda_nid_t nid; |
1323 | present = snd_hda_codec_read(codec, 0x17, 0, | 1403 | int i; |
1324 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1404 | |
1325 | /* HP out presence */ | 1405 | spec->jack_present = 0; |
1326 | present = present || snd_hda_codec_read(codec, 0x1b, 0, | 1406 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { |
1327 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1407 | nid = spec->autocfg.hp_pins[i]; |
1328 | bits = present ? HDA_AMP_MUTE : 0; | 1408 | if (!nid) |
1409 | break; | ||
1410 | val = snd_hda_codec_read(codec, nid, 0, | ||
1411 | AC_VERB_GET_PIN_SENSE, 0); | ||
1412 | if (val & AC_PINSENSE_PRESENCE) { | ||
1413 | spec->jack_present = 1; | ||
1414 | break; | ||
1415 | } | ||
1416 | } | ||
1417 | |||
1418 | mute = spec->jack_present ? HDA_AMP_MUTE : 0; | ||
1329 | /* Toggle internal speakers muting */ | 1419 | /* Toggle internal speakers muting */ |
1330 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 1420 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { |
1331 | HDA_AMP_MUTE, bits); | 1421 | nid = spec->autocfg.speaker_pins[i]; |
1332 | /* Toggle internal bass muting */ | 1422 | if (!nid) |
1333 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 1423 | break; |
1334 | HDA_AMP_MUTE, bits); | 1424 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, |
1425 | HDA_AMP_MUTE, mute); | ||
1426 | } | ||
1335 | } | 1427 | } |
1336 | 1428 | ||
1337 | static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec, | 1429 | static void alc_automute_amp_unsol_event(struct hda_codec *codec, |
1338 | unsigned int res) | 1430 | unsigned int res) |
1339 | { | 1431 | { |
1340 | if (res >> 26 == ALC880_HP_EVENT) | 1432 | if (codec->vendor_id == 0x10ec0880) |
1341 | alc888_fujitsu_xa3530_automute(codec); | 1433 | res >>= 28; |
1434 | else | ||
1435 | res >>= 26; | ||
1436 | if (res == ALC880_HP_EVENT) | ||
1437 | alc_automute_amp(codec); | ||
1342 | } | 1438 | } |
1343 | 1439 | ||
1440 | static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec) | ||
1441 | { | ||
1442 | struct alc_spec *spec = codec->spec; | ||
1443 | |||
1444 | spec->autocfg.hp_pins[0] = 0x17; /* line-out */ | ||
1445 | spec->autocfg.hp_pins[1] = 0x1b; /* hp */ | ||
1446 | spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ | ||
1447 | spec->autocfg.speaker_pins[1] = 0x15; /* bass */ | ||
1448 | alc_automute_amp(codec); | ||
1449 | } | ||
1344 | 1450 | ||
1345 | /* | 1451 | /* |
1346 | * ALC888 Acer Aspire 4930G model | 1452 | * ALC888 Acer Aspire 4930G model |
@@ -1364,6 +1470,59 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { | |||
1364 | { } | 1470 | { } |
1365 | }; | 1471 | }; |
1366 | 1472 | ||
1473 | /* | ||
1474 | * ALC889 Acer Aspire 8930G model | ||
1475 | */ | ||
1476 | |||
1477 | static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { | ||
1478 | /* Front Mic: set to PIN_IN (empty by default) */ | ||
1479 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1480 | /* Unselect Front Mic by default in input mixer 3 */ | ||
1481 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, | ||
1482 | /* Enable unsolicited event for HP jack */ | ||
1483 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
1484 | /* Connect Internal Front to Front */ | ||
1485 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1486 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1487 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1488 | /* Connect Internal Rear to Rear */ | ||
1489 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1490 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1491 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
1492 | /* Connect Internal CLFE to CLFE */ | ||
1493 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1494 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1495 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
1496 | /* Connect HP out to Front */ | ||
1497 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, | ||
1498 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1499 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1500 | /* Enable all DACs */ | ||
1501 | /* DAC DISABLE/MUTE 1? */ | ||
1502 | /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */ | ||
1503 | {0x20, AC_VERB_SET_COEF_INDEX, 0x03}, | ||
1504 | {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, | ||
1505 | /* DAC DISABLE/MUTE 2? */ | ||
1506 | /* some bit here disables the other DACs. Init=0x4900 */ | ||
1507 | {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, | ||
1508 | {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, | ||
1509 | /* Enable amplifiers */ | ||
1510 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
1511 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
1512 | /* DMIC fix | ||
1513 | * This laptop has a stereo digital microphone. The mics are only 1cm apart | ||
1514 | * which makes the stereo useless. However, either the mic or the ALC889 | ||
1515 | * makes the signal become a difference/sum signal instead of standard | ||
1516 | * stereo, which is annoying. So instead we flip this bit which makes the | ||
1517 | * codec replicate the sum signal to both channels, turning it into a | ||
1518 | * normal mono mic. | ||
1519 | */ | ||
1520 | /* DMIC_CONTROL? Init value = 0x0001 */ | ||
1521 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, | ||
1522 | {0x20, AC_VERB_SET_PROC_COEF, 0x0003}, | ||
1523 | { } | ||
1524 | }; | ||
1525 | |||
1367 | static struct hda_input_mux alc888_2_capture_sources[2] = { | 1526 | static struct hda_input_mux alc888_2_capture_sources[2] = { |
1368 | /* Front mic only available on one ADC */ | 1527 | /* Front mic only available on one ADC */ |
1369 | { | 1528 | { |
@@ -1385,6 +1544,38 @@ static struct hda_input_mux alc888_2_capture_sources[2] = { | |||
1385 | } | 1544 | } |
1386 | }; | 1545 | }; |
1387 | 1546 | ||
1547 | static struct hda_input_mux alc889_capture_sources[3] = { | ||
1548 | /* Digital mic only available on first "ADC" */ | ||
1549 | { | ||
1550 | .num_items = 5, | ||
1551 | .items = { | ||
1552 | { "Mic", 0x0 }, | ||
1553 | { "Line", 0x2 }, | ||
1554 | { "CD", 0x4 }, | ||
1555 | { "Front Mic", 0xb }, | ||
1556 | { "Input Mix", 0xa }, | ||
1557 | }, | ||
1558 | }, | ||
1559 | { | ||
1560 | .num_items = 4, | ||
1561 | .items = { | ||
1562 | { "Mic", 0x0 }, | ||
1563 | { "Line", 0x2 }, | ||
1564 | { "CD", 0x4 }, | ||
1565 | { "Input Mix", 0xa }, | ||
1566 | }, | ||
1567 | }, | ||
1568 | { | ||
1569 | .num_items = 4, | ||
1570 | .items = { | ||
1571 | { "Mic", 0x0 }, | ||
1572 | { "Line", 0x2 }, | ||
1573 | { "CD", 0x4 }, | ||
1574 | { "Input Mix", 0xa }, | ||
1575 | }, | ||
1576 | } | ||
1577 | }; | ||
1578 | |||
1388 | static struct snd_kcontrol_new alc888_base_mixer[] = { | 1579 | static struct snd_kcontrol_new alc888_base_mixer[] = { |
1389 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 1580 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
1390 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 1581 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
@@ -1407,22 +1598,24 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { | |||
1407 | { } /* end */ | 1598 | { } /* end */ |
1408 | }; | 1599 | }; |
1409 | 1600 | ||
1410 | static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec) | 1601 | static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec) |
1411 | { | 1602 | { |
1412 | unsigned int present; | 1603 | struct alc_spec *spec = codec->spec; |
1413 | unsigned int bits; | 1604 | |
1414 | present = snd_hda_codec_read(codec, 0x15, 0, | 1605 | spec->autocfg.hp_pins[0] = 0x15; |
1415 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1606 | spec->autocfg.speaker_pins[0] = 0x14; |
1416 | bits = present ? HDA_AMP_MUTE : 0; | 1607 | alc_automute_amp(codec); |
1417 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
1418 | HDA_AMP_MUTE, bits); | ||
1419 | } | 1608 | } |
1420 | 1609 | ||
1421 | static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec, | 1610 | static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec) |
1422 | unsigned int res) | ||
1423 | { | 1611 | { |
1424 | if (res >> 26 == ALC880_HP_EVENT) | 1612 | struct alc_spec *spec = codec->spec; |
1425 | alc888_acer_aspire_4930g_automute(codec); | 1613 | |
1614 | spec->autocfg.hp_pins[0] = 0x15; | ||
1615 | spec->autocfg.speaker_pins[0] = 0x14; | ||
1616 | spec->autocfg.speaker_pins[1] = 0x16; | ||
1617 | spec->autocfg.speaker_pins[2] = 0x1b; | ||
1618 | alc_automute_amp(codec); | ||
1426 | } | 1619 | } |
1427 | 1620 | ||
1428 | /* | 1621 | /* |
@@ -2390,21 +2583,6 @@ static struct hda_verb alc880_beep_init_verbs[] = { | |||
2390 | { } | 2583 | { } |
2391 | }; | 2584 | }; |
2392 | 2585 | ||
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 */ | 2586 | /* auto-toggle front mic */ |
2409 | static void alc880_uniwill_mic_automute(struct hda_codec *codec) | 2587 | static void alc880_uniwill_mic_automute(struct hda_codec *codec) |
2410 | { | 2588 | { |
@@ -2417,9 +2595,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); | 2595 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); |
2418 | } | 2596 | } |
2419 | 2597 | ||
2420 | static void alc880_uniwill_automute(struct hda_codec *codec) | 2598 | static void alc880_uniwill_init_hook(struct hda_codec *codec) |
2421 | { | 2599 | { |
2422 | alc880_uniwill_hp_automute(codec); | 2600 | struct alc_spec *spec = codec->spec; |
2601 | |||
2602 | spec->autocfg.hp_pins[0] = 0x14; | ||
2603 | spec->autocfg.speaker_pins[0] = 0x15; | ||
2604 | spec->autocfg.speaker_pins[0] = 0x16; | ||
2605 | alc_automute_amp(codec); | ||
2423 | alc880_uniwill_mic_automute(codec); | 2606 | alc880_uniwill_mic_automute(codec); |
2424 | } | 2607 | } |
2425 | 2608 | ||
@@ -2430,24 +2613,22 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, | |||
2430 | * definition. 4bit tag is placed at 28 bit! | 2613 | * definition. 4bit tag is placed at 28 bit! |
2431 | */ | 2614 | */ |
2432 | switch (res >> 28) { | 2615 | switch (res >> 28) { |
2433 | case ALC880_HP_EVENT: | ||
2434 | alc880_uniwill_hp_automute(codec); | ||
2435 | break; | ||
2436 | case ALC880_MIC_EVENT: | 2616 | case ALC880_MIC_EVENT: |
2437 | alc880_uniwill_mic_automute(codec); | 2617 | alc880_uniwill_mic_automute(codec); |
2438 | break; | 2618 | break; |
2619 | default: | ||
2620 | alc_automute_amp_unsol_event(codec, res); | ||
2621 | break; | ||
2439 | } | 2622 | } |
2440 | } | 2623 | } |
2441 | 2624 | ||
2442 | static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) | 2625 | static void alc880_uniwill_p53_init_hook(struct hda_codec *codec) |
2443 | { | 2626 | { |
2444 | unsigned int present; | 2627 | struct alc_spec *spec = codec->spec; |
2445 | unsigned char bits; | ||
2446 | 2628 | ||
2447 | present = snd_hda_codec_read(codec, 0x14, 0, | 2629 | spec->autocfg.hp_pins[0] = 0x14; |
2448 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 2630 | spec->autocfg.speaker_pins[0] = 0x15; |
2449 | bits = present ? HDA_AMP_MUTE : 0; | 2631 | alc_automute_amp(codec); |
2450 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits); | ||
2451 | } | 2632 | } |
2452 | 2633 | ||
2453 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) | 2634 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) |
@@ -2469,10 +2650,10 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, | |||
2469 | /* Looks like the unsol event is incompatible with the standard | 2650 | /* Looks like the unsol event is incompatible with the standard |
2470 | * definition. 4bit tag is placed at 28 bit! | 2651 | * definition. 4bit tag is placed at 28 bit! |
2471 | */ | 2652 | */ |
2472 | if ((res >> 28) == ALC880_HP_EVENT) | ||
2473 | alc880_uniwill_p53_hp_automute(codec); | ||
2474 | if ((res >> 28) == ALC880_DCVOL_EVENT) | 2653 | if ((res >> 28) == ALC880_DCVOL_EVENT) |
2475 | alc880_uniwill_p53_dcvol_automute(codec); | 2654 | alc880_uniwill_p53_dcvol_automute(codec); |
2655 | else | ||
2656 | alc_automute_amp_unsol_event(codec, res); | ||
2476 | } | 2657 | } |
2477 | 2658 | ||
2478 | /* | 2659 | /* |
@@ -2542,6 +2723,7 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = { | |||
2542 | /* Enable GPIO mask and set output */ | 2723 | /* Enable GPIO mask and set output */ |
2543 | #define alc880_gpio1_init_verbs alc_gpio1_init_verbs | 2724 | #define alc880_gpio1_init_verbs alc_gpio1_init_verbs |
2544 | #define alc880_gpio2_init_verbs alc_gpio2_init_verbs | 2725 | #define alc880_gpio2_init_verbs alc_gpio2_init_verbs |
2726 | #define alc880_gpio3_init_verbs alc_gpio3_init_verbs | ||
2545 | 2727 | ||
2546 | /* Clevo m520g init */ | 2728 | /* Clevo m520g init */ |
2547 | static struct hda_verb alc880_pin_clevo_init_verbs[] = { | 2729 | static struct hda_verb alc880_pin_clevo_init_verbs[] = { |
@@ -2704,30 +2886,18 @@ static struct hda_verb alc880_lg_init_verbs[] = { | |||
2704 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 2886 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
2705 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2887 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2706 | /* jack sense */ | 2888 | /* jack sense */ |
2707 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, | 2889 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
2708 | { } | 2890 | { } |
2709 | }; | 2891 | }; |
2710 | 2892 | ||
2711 | /* toggle speaker-output according to the hp-jack state */ | 2893 | /* toggle speaker-output according to the hp-jack state */ |
2712 | static void alc880_lg_automute(struct hda_codec *codec) | 2894 | static void alc880_lg_init_hook(struct hda_codec *codec) |
2713 | { | 2895 | { |
2714 | unsigned int present; | 2896 | 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 | 2897 | ||
2724 | static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) | 2898 | spec->autocfg.hp_pins[0] = 0x1b; |
2725 | { | 2899 | spec->autocfg.speaker_pins[0] = 0x17; |
2726 | /* Looks like the unsol event is incompatible with the standard | 2900 | 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 | } | 2901 | } |
2732 | 2902 | ||
2733 | /* | 2903 | /* |
@@ -2801,30 +2971,18 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { | |||
2801 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 2971 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
2802 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2972 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2803 | /* jack sense */ | 2973 | /* jack sense */ |
2804 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, | 2974 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
2805 | { } | 2975 | { } |
2806 | }; | 2976 | }; |
2807 | 2977 | ||
2808 | /* toggle speaker-output according to the hp-jack state */ | 2978 | /* toggle speaker-output according to the hp-jack state */ |
2809 | static void alc880_lg_lw_automute(struct hda_codec *codec) | 2979 | static void alc880_lg_lw_init_hook(struct hda_codec *codec) |
2810 | { | 2980 | { |
2811 | unsigned int present; | 2981 | struct alc_spec *spec = codec->spec; |
2812 | unsigned char bits; | ||
2813 | 2982 | ||
2814 | present = snd_hda_codec_read(codec, 0x1b, 0, | 2983 | spec->autocfg.hp_pins[0] = 0x1b; |
2815 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 2984 | spec->autocfg.speaker_pins[0] = 0x14; |
2816 | bits = present ? HDA_AMP_MUTE : 0; | 2985 | 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 | } | 2986 | } |
2829 | 2987 | ||
2830 | static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { | 2988 | static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { |
@@ -2871,16 +3029,10 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = { | |||
2871 | /* toggle speaker-output according to the hp-jack state */ | 3029 | /* toggle speaker-output according to the hp-jack state */ |
2872 | static void alc880_medion_rim_automute(struct hda_codec *codec) | 3030 | static void alc880_medion_rim_automute(struct hda_codec *codec) |
2873 | { | 3031 | { |
2874 | unsigned int present; | 3032 | struct alc_spec *spec = codec->spec; |
2875 | unsigned char bits; | 3033 | alc_automute_amp(codec); |
2876 | 3034 | /* toggle EAPD */ | |
2877 | present = snd_hda_codec_read(codec, 0x14, 0, | 3035 | 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); | 3036 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); |
2885 | else | 3037 | else |
2886 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); | 3038 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); |
@@ -2896,6 +3048,15 @@ static void alc880_medion_rim_unsol_event(struct hda_codec *codec, | |||
2896 | alc880_medion_rim_automute(codec); | 3048 | alc880_medion_rim_automute(codec); |
2897 | } | 3049 | } |
2898 | 3050 | ||
3051 | static void alc880_medion_rim_init_hook(struct hda_codec *codec) | ||
3052 | { | ||
3053 | struct alc_spec *spec = codec->spec; | ||
3054 | |||
3055 | spec->autocfg.hp_pins[0] = 0x14; | ||
3056 | spec->autocfg.speaker_pins[0] = 0x1b; | ||
3057 | alc880_medion_rim_automute(codec); | ||
3058 | } | ||
3059 | |||
2899 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3060 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2900 | static struct hda_amp_list alc880_loopbacks[] = { | 3061 | static struct hda_amp_list alc880_loopbacks[] = { |
2901 | { 0x0b, HDA_INPUT, 0 }, | 3062 | { 0x0b, HDA_INPUT, 0 }, |
@@ -2924,8 +3085,7 @@ static int alc_init(struct hda_codec *codec) | |||
2924 | unsigned int i; | 3085 | unsigned int i; |
2925 | 3086 | ||
2926 | alc_fix_pll(codec); | 3087 | alc_fix_pll(codec); |
2927 | if (codec->vendor_id == 0x10ec0888) | 3088 | alc_auto_init_amp(codec, spec->init_amp); |
2928 | alc888_coef_init(codec); | ||
2929 | 3089 | ||
2930 | for (i = 0; i < spec->num_init_verbs; i++) | 3090 | for (i = 0; i < spec->num_init_verbs; i++) |
2931 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | 3091 | snd_hda_sequence_write(codec, spec->init_verbs[i]); |
@@ -3127,7 +3287,10 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
3127 | if (spec->no_analog) | 3287 | if (spec->no_analog) |
3128 | goto skip_analog; | 3288 | goto skip_analog; |
3129 | 3289 | ||
3290 | snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), | ||
3291 | "%s Analog", codec->chip_name); | ||
3130 | info->name = spec->stream_name_analog; | 3292 | info->name = spec->stream_name_analog; |
3293 | |||
3131 | if (spec->stream_analog_playback) { | 3294 | if (spec->stream_analog_playback) { |
3132 | if (snd_BUG_ON(!spec->multiout.dac_nids)) | 3295 | if (snd_BUG_ON(!spec->multiout.dac_nids)) |
3133 | return -EINVAL; | 3296 | return -EINVAL; |
@@ -3153,6 +3316,9 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
3153 | skip_analog: | 3316 | skip_analog: |
3154 | /* SPDIF for stream index #1 */ | 3317 | /* SPDIF for stream index #1 */ |
3155 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { | 3318 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { |
3319 | snprintf(spec->stream_name_digital, | ||
3320 | sizeof(spec->stream_name_digital), | ||
3321 | "%s Digital", codec->chip_name); | ||
3156 | codec->num_pcms = 2; | 3322 | codec->num_pcms = 2; |
3157 | codec->slave_dig_outs = spec->multiout.slave_dig_outs; | 3323 | codec->slave_dig_outs = spec->multiout.slave_dig_outs; |
3158 | info = spec->pcm_rec + 1; | 3324 | info = spec->pcm_rec + 1; |
@@ -3755,7 +3921,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3755 | .channel_mode = alc880_2_jack_modes, | 3921 | .channel_mode = alc880_2_jack_modes, |
3756 | .input_mux = &alc880_f1734_capture_source, | 3922 | .input_mux = &alc880_f1734_capture_source, |
3757 | .unsol_event = alc880_uniwill_p53_unsol_event, | 3923 | .unsol_event = alc880_uniwill_p53_unsol_event, |
3758 | .init_hook = alc880_uniwill_p53_hp_automute, | 3924 | .init_hook = alc880_uniwill_p53_init_hook, |
3759 | }, | 3925 | }, |
3760 | [ALC880_ASUS] = { | 3926 | [ALC880_ASUS] = { |
3761 | .mixers = { alc880_asus_mixer }, | 3927 | .mixers = { alc880_asus_mixer }, |
@@ -3832,7 +3998,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3832 | .need_dac_fix = 1, | 3998 | .need_dac_fix = 1, |
3833 | .input_mux = &alc880_capture_source, | 3999 | .input_mux = &alc880_capture_source, |
3834 | .unsol_event = alc880_uniwill_unsol_event, | 4000 | .unsol_event = alc880_uniwill_unsol_event, |
3835 | .init_hook = alc880_uniwill_automute, | 4001 | .init_hook = alc880_uniwill_init_hook, |
3836 | }, | 4002 | }, |
3837 | [ALC880_UNIWILL_P53] = { | 4003 | [ALC880_UNIWILL_P53] = { |
3838 | .mixers = { alc880_uniwill_p53_mixer }, | 4004 | .mixers = { alc880_uniwill_p53_mixer }, |
@@ -3844,7 +4010,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3844 | .channel_mode = alc880_threestack_modes, | 4010 | .channel_mode = alc880_threestack_modes, |
3845 | .input_mux = &alc880_capture_source, | 4011 | .input_mux = &alc880_capture_source, |
3846 | .unsol_event = alc880_uniwill_p53_unsol_event, | 4012 | .unsol_event = alc880_uniwill_p53_unsol_event, |
3847 | .init_hook = alc880_uniwill_p53_hp_automute, | 4013 | .init_hook = alc880_uniwill_p53_init_hook, |
3848 | }, | 4014 | }, |
3849 | [ALC880_FUJITSU] = { | 4015 | [ALC880_FUJITSU] = { |
3850 | .mixers = { alc880_fujitsu_mixer }, | 4016 | .mixers = { alc880_fujitsu_mixer }, |
@@ -3858,7 +4024,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3858 | .channel_mode = alc880_2_jack_modes, | 4024 | .channel_mode = alc880_2_jack_modes, |
3859 | .input_mux = &alc880_capture_source, | 4025 | .input_mux = &alc880_capture_source, |
3860 | .unsol_event = alc880_uniwill_p53_unsol_event, | 4026 | .unsol_event = alc880_uniwill_p53_unsol_event, |
3861 | .init_hook = alc880_uniwill_p53_hp_automute, | 4027 | .init_hook = alc880_uniwill_p53_init_hook, |
3862 | }, | 4028 | }, |
3863 | [ALC880_CLEVO] = { | 4029 | [ALC880_CLEVO] = { |
3864 | .mixers = { alc880_three_stack_mixer }, | 4030 | .mixers = { alc880_three_stack_mixer }, |
@@ -3883,8 +4049,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
3883 | .channel_mode = alc880_lg_ch_modes, | 4049 | .channel_mode = alc880_lg_ch_modes, |
3884 | .need_dac_fix = 1, | 4050 | .need_dac_fix = 1, |
3885 | .input_mux = &alc880_lg_capture_source, | 4051 | .input_mux = &alc880_lg_capture_source, |
3886 | .unsol_event = alc880_lg_unsol_event, | 4052 | .unsol_event = alc_automute_amp_unsol_event, |
3887 | .init_hook = alc880_lg_automute, | 4053 | .init_hook = alc880_lg_init_hook, |
3888 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4054 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3889 | .loopbacks = alc880_lg_loopbacks, | 4055 | .loopbacks = alc880_lg_loopbacks, |
3890 | #endif | 4056 | #endif |
@@ -3899,8 +4065,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
3899 | .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), | 4065 | .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), |
3900 | .channel_mode = alc880_lg_lw_modes, | 4066 | .channel_mode = alc880_lg_lw_modes, |
3901 | .input_mux = &alc880_lg_lw_capture_source, | 4067 | .input_mux = &alc880_lg_lw_capture_source, |
3902 | .unsol_event = alc880_lg_lw_unsol_event, | 4068 | .unsol_event = alc_automute_amp_unsol_event, |
3903 | .init_hook = alc880_lg_lw_automute, | 4069 | .init_hook = alc880_lg_lw_init_hook, |
3904 | }, | 4070 | }, |
3905 | [ALC880_MEDION_RIM] = { | 4071 | [ALC880_MEDION_RIM] = { |
3906 | .mixers = { alc880_medion_rim_mixer }, | 4072 | .mixers = { alc880_medion_rim_mixer }, |
@@ -3914,7 +4080,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3914 | .channel_mode = alc880_2_jack_modes, | 4080 | .channel_mode = alc880_2_jack_modes, |
3915 | .input_mux = &alc880_medion_rim_capture_source, | 4081 | .input_mux = &alc880_medion_rim_capture_source, |
3916 | .unsol_event = alc880_medion_rim_unsol_event, | 4082 | .unsol_event = alc880_medion_rim_unsol_event, |
3917 | .init_hook = alc880_medion_rim_automute, | 4083 | .init_hook = alc880_medion_rim_init_hook, |
3918 | }, | 4084 | }, |
3919 | #ifdef CONFIG_SND_DEBUG | 4085 | #ifdef CONFIG_SND_DEBUG |
3920 | [ALC880_TEST] = { | 4086 | [ALC880_TEST] = { |
@@ -4199,7 +4365,6 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec) | |||
4199 | struct alc_spec *spec = codec->spec; | 4365 | struct alc_spec *spec = codec->spec; |
4200 | int i; | 4366 | int i; |
4201 | 4367 | ||
4202 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
4203 | for (i = 0; i < spec->autocfg.line_outs; i++) { | 4368 | for (i = 0; i < spec->autocfg.line_outs; i++) { |
4204 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 4369 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
4205 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 4370 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -4304,6 +4469,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
4304 | spec->num_mux_defs = 1; | 4469 | spec->num_mux_defs = 1; |
4305 | spec->input_mux = &spec->private_imux[0]; | 4470 | spec->input_mux = &spec->private_imux[0]; |
4306 | 4471 | ||
4472 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); | ||
4473 | |||
4307 | return 1; | 4474 | return 1; |
4308 | } | 4475 | } |
4309 | 4476 | ||
@@ -4361,8 +4528,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
4361 | alc880_models, | 4528 | alc880_models, |
4362 | alc880_cfg_tbl); | 4529 | alc880_cfg_tbl); |
4363 | if (board_config < 0) { | 4530 | if (board_config < 0) { |
4364 | printk(KERN_INFO "hda_codec: Unknown model for ALC880, " | 4531 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
4365 | "trying auto-probe from BIOS...\n"); | 4532 | "trying auto-probe from BIOS...\n", codec->chip_name); |
4366 | board_config = ALC880_AUTO; | 4533 | board_config = ALC880_AUTO; |
4367 | } | 4534 | } |
4368 | 4535 | ||
@@ -4389,12 +4556,10 @@ static int patch_alc880(struct hda_codec *codec) | |||
4389 | if (board_config != ALC880_AUTO) | 4556 | if (board_config != ALC880_AUTO) |
4390 | setup_preset(spec, &alc880_presets[board_config]); | 4557 | setup_preset(spec, &alc880_presets[board_config]); |
4391 | 4558 | ||
4392 | spec->stream_name_analog = "ALC880 Analog"; | ||
4393 | spec->stream_analog_playback = &alc880_pcm_analog_playback; | 4559 | spec->stream_analog_playback = &alc880_pcm_analog_playback; |
4394 | spec->stream_analog_capture = &alc880_pcm_analog_capture; | 4560 | spec->stream_analog_capture = &alc880_pcm_analog_capture; |
4395 | spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; | 4561 | spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; |
4396 | 4562 | ||
4397 | spec->stream_name_digital = "ALC880 Digital"; | ||
4398 | spec->stream_digital_playback = &alc880_pcm_digital_playback; | 4563 | spec->stream_digital_playback = &alc880_pcm_digital_playback; |
4399 | spec->stream_digital_capture = &alc880_pcm_digital_capture; | 4564 | spec->stream_digital_capture = &alc880_pcm_digital_capture; |
4400 | 4565 | ||
@@ -5679,7 +5844,6 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) | |||
5679 | struct alc_spec *spec = codec->spec; | 5844 | struct alc_spec *spec = codec->spec; |
5680 | hda_nid_t nid; | 5845 | hda_nid_t nid; |
5681 | 5846 | ||
5682 | alc_subsystem_id(codec, 0x10, 0x15, 0x0f); | ||
5683 | nid = spec->autocfg.line_out_pins[0]; | 5847 | nid = spec->autocfg.line_out_pins[0]; |
5684 | if (nid) { | 5848 | if (nid) { |
5685 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 5849 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -5789,6 +5953,8 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
5789 | spec->num_mux_defs = 1; | 5953 | spec->num_mux_defs = 1; |
5790 | spec->input_mux = &spec->private_imux[0]; | 5954 | spec->input_mux = &spec->private_imux[0]; |
5791 | 5955 | ||
5956 | alc_ssid_check(codec, 0x10, 0x15, 0x0f); | ||
5957 | |||
5792 | return 1; | 5958 | return 1; |
5793 | } | 5959 | } |
5794 | 5960 | ||
@@ -6006,8 +6172,9 @@ static int patch_alc260(struct hda_codec *codec) | |||
6006 | alc260_models, | 6172 | alc260_models, |
6007 | alc260_cfg_tbl); | 6173 | alc260_cfg_tbl); |
6008 | if (board_config < 0) { | 6174 | if (board_config < 0) { |
6009 | snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " | 6175 | snd_printd(KERN_INFO "hda_codec: Unknown model for %s, " |
6010 | "trying auto-probe from BIOS...\n"); | 6176 | "trying auto-probe from BIOS...\n", |
6177 | codec->chip_name); | ||
6011 | board_config = ALC260_AUTO; | 6178 | board_config = ALC260_AUTO; |
6012 | } | 6179 | } |
6013 | 6180 | ||
@@ -6034,11 +6201,9 @@ static int patch_alc260(struct hda_codec *codec) | |||
6034 | if (board_config != ALC260_AUTO) | 6201 | if (board_config != ALC260_AUTO) |
6035 | setup_preset(spec, &alc260_presets[board_config]); | 6202 | setup_preset(spec, &alc260_presets[board_config]); |
6036 | 6203 | ||
6037 | spec->stream_name_analog = "ALC260 Analog"; | ||
6038 | spec->stream_analog_playback = &alc260_pcm_analog_playback; | 6204 | spec->stream_analog_playback = &alc260_pcm_analog_playback; |
6039 | spec->stream_analog_capture = &alc260_pcm_analog_capture; | 6205 | spec->stream_analog_capture = &alc260_pcm_analog_capture; |
6040 | 6206 | ||
6041 | spec->stream_name_digital = "ALC260 Digital"; | ||
6042 | spec->stream_digital_playback = &alc260_pcm_digital_playback; | 6207 | spec->stream_digital_playback = &alc260_pcm_digital_playback; |
6043 | spec->stream_digital_capture = &alc260_pcm_digital_capture; | 6208 | spec->stream_digital_capture = &alc260_pcm_digital_capture; |
6044 | 6209 | ||
@@ -6115,6 +6280,16 @@ static struct hda_input_mux alc882_capture_source = { | |||
6115 | { "CD", 0x4 }, | 6280 | { "CD", 0x4 }, |
6116 | }, | 6281 | }, |
6117 | }; | 6282 | }; |
6283 | |||
6284 | static struct hda_input_mux mb5_capture_source = { | ||
6285 | .num_items = 3, | ||
6286 | .items = { | ||
6287 | { "Mic", 0x1 }, | ||
6288 | { "Line", 0x2 }, | ||
6289 | { "CD", 0x4 }, | ||
6290 | }, | ||
6291 | }; | ||
6292 | |||
6118 | /* | 6293 | /* |
6119 | * 2ch mode | 6294 | * 2ch mode |
6120 | */ | 6295 | */ |
@@ -6202,6 +6377,34 @@ static struct hda_channel_mode alc885_mbp_6ch_modes[2] = { | |||
6202 | { 6, alc885_mbp_ch6_init }, | 6377 | { 6, alc885_mbp_ch6_init }, |
6203 | }; | 6378 | }; |
6204 | 6379 | ||
6380 | /* | ||
6381 | * 2ch | ||
6382 | * Speakers/Woofer/HP = Front | ||
6383 | * LineIn = Input | ||
6384 | */ | ||
6385 | static struct hda_verb alc885_mb5_ch2_init[] = { | ||
6386 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
6387 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
6388 | { } /* end */ | ||
6389 | }; | ||
6390 | |||
6391 | /* | ||
6392 | * 6ch mode | ||
6393 | * Speakers/HP = Front | ||
6394 | * Woofer = LFE | ||
6395 | * LineIn = Surround | ||
6396 | */ | ||
6397 | static struct hda_verb alc885_mb5_ch6_init[] = { | ||
6398 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
6399 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
6400 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
6401 | { } /* end */ | ||
6402 | }; | ||
6403 | |||
6404 | static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { | ||
6405 | { 2, alc885_mb5_ch2_init }, | ||
6406 | { 6, alc885_mb5_ch6_init }, | ||
6407 | }; | ||
6205 | 6408 | ||
6206 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | 6409 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 |
6207 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | 6410 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b |
@@ -6244,6 +6447,25 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = { | |||
6244 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), | 6447 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), |
6245 | { } /* end */ | 6448 | { } /* end */ |
6246 | }; | 6449 | }; |
6450 | |||
6451 | static struct snd_kcontrol_new alc885_mb5_mixer[] = { | ||
6452 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
6453 | HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), | ||
6454 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
6455 | HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), | ||
6456 | HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), | ||
6457 | HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), | ||
6458 | HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT), | ||
6459 | HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT), | ||
6460 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
6461 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
6462 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
6463 | HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
6464 | HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), | ||
6465 | HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT), | ||
6466 | { } /* end */ | ||
6467 | }; | ||
6468 | |||
6247 | static struct snd_kcontrol_new alc882_w2jc_mixer[] = { | 6469 | static struct snd_kcontrol_new alc882_w2jc_mixer[] = { |
6248 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 6470 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
6249 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 6471 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
@@ -6471,6 +6693,55 @@ static struct hda_verb alc882_macpro_init_verbs[] = { | |||
6471 | { } | 6693 | { } |
6472 | }; | 6694 | }; |
6473 | 6695 | ||
6696 | /* Macbook 5,1 */ | ||
6697 | static struct hda_verb alc885_mb5_init_verbs[] = { | ||
6698 | /* DACs */ | ||
6699 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
6700 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
6701 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
6702 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
6703 | /* Front mixer */ | ||
6704 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
6705 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
6706 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
6707 | /* Surround mixer */ | ||
6708 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
6709 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
6710 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
6711 | /* LFE mixer */ | ||
6712 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
6713 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
6714 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
6715 | /* HP mixer */ | ||
6716 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
6717 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
6718 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
6719 | /* Front Pin (0x0c) */ | ||
6720 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, | ||
6721 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
6722 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
6723 | /* LFE Pin (0x0e) */ | ||
6724 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, | ||
6725 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
6726 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
6727 | /* HP Pin (0x0f) */ | ||
6728 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
6729 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
6730 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
6731 | /* Front Mic pin: input vref at 80% */ | ||
6732 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
6733 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
6734 | /* Line In pin */ | ||
6735 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
6736 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
6737 | |||
6738 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
6739 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
6740 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
6741 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
6742 | { } | ||
6743 | }; | ||
6744 | |||
6474 | /* Macbook Pro rev3 */ | 6745 | /* Macbook Pro rev3 */ |
6475 | static struct hda_verb alc885_mbp3_init_verbs[] = { | 6746 | static struct hda_verb alc885_mbp3_init_verbs[] = { |
6476 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | 6747 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ |
@@ -6560,45 +6831,23 @@ static struct hda_verb alc885_imac24_init_verbs[] = { | |||
6560 | }; | 6831 | }; |
6561 | 6832 | ||
6562 | /* Toggle speaker-output according to the hp-jack state */ | 6833 | /* Toggle speaker-output according to the hp-jack state */ |
6563 | static void alc885_imac24_automute(struct hda_codec *codec) | 6834 | static void alc885_imac24_automute_init_hook(struct hda_codec *codec) |
6564 | { | 6835 | { |
6565 | unsigned int present; | 6836 | 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 | 6837 | ||
6575 | /* Processes unsolicited events. */ | 6838 | spec->autocfg.hp_pins[0] = 0x14; |
6576 | static void alc885_imac24_unsol_event(struct hda_codec *codec, | 6839 | spec->autocfg.speaker_pins[0] = 0x18; |
6577 | unsigned int res) | 6840 | spec->autocfg.speaker_pins[1] = 0x1a; |
6578 | { | 6841 | alc_automute_amp(codec); |
6579 | /* Headphone insertion or removal. */ | ||
6580 | if ((res >> 26) == ALC880_HP_EVENT) | ||
6581 | alc885_imac24_automute(codec); | ||
6582 | } | 6842 | } |
6583 | 6843 | ||
6584 | static void alc885_mbp3_automute(struct hda_codec *codec) | 6844 | static void alc885_mbp3_init_hook(struct hda_codec *codec) |
6585 | { | 6845 | { |
6586 | unsigned int present; | 6846 | 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 | 6847 | ||
6595 | } | 6848 | spec->autocfg.hp_pins[0] = 0x15; |
6596 | static void alc885_mbp3_unsol_event(struct hda_codec *codec, | 6849 | spec->autocfg.speaker_pins[0] = 0x14; |
6597 | unsigned int res) | 6850 | alc_automute_amp(codec); |
6598 | { | ||
6599 | /* Headphone insertion or removal. */ | ||
6600 | if ((res >> 26) == ALC880_HP_EVENT) | ||
6601 | alc885_mbp3_automute(codec); | ||
6602 | } | 6851 | } |
6603 | 6852 | ||
6604 | 6853 | ||
@@ -6623,24 +6872,25 @@ static struct hda_verb alc882_targa_verbs[] = { | |||
6623 | /* toggle speaker-output according to the hp-jack state */ | 6872 | /* toggle speaker-output according to the hp-jack state */ |
6624 | static void alc882_targa_automute(struct hda_codec *codec) | 6873 | static void alc882_targa_automute(struct hda_codec *codec) |
6625 | { | 6874 | { |
6626 | unsigned int present; | 6875 | struct alc_spec *spec = codec->spec; |
6627 | 6876 | 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, | 6877 | snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, |
6633 | present ? 1 : 3); | 6878 | spec->jack_present ? 1 : 3); |
6879 | } | ||
6880 | |||
6881 | static void alc882_targa_init_hook(struct hda_codec *codec) | ||
6882 | { | ||
6883 | struct alc_spec *spec = codec->spec; | ||
6884 | |||
6885 | spec->autocfg.hp_pins[0] = 0x14; | ||
6886 | spec->autocfg.speaker_pins[0] = 0x1b; | ||
6887 | alc882_targa_automute(codec); | ||
6634 | } | 6888 | } |
6635 | 6889 | ||
6636 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) | 6890 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) |
6637 | { | 6891 | { |
6638 | /* Looks like the unsol event is incompatible with the standard | 6892 | 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); | 6893 | alc882_targa_automute(codec); |
6643 | } | ||
6644 | } | 6894 | } |
6645 | 6895 | ||
6646 | static struct hda_verb alc882_asus_a7j_verbs[] = { | 6896 | static struct hda_verb alc882_asus_a7j_verbs[] = { |
@@ -6722,7 +6972,7 @@ static void alc885_macpro_init_hook(struct hda_codec *codec) | |||
6722 | static void alc885_imac24_init_hook(struct hda_codec *codec) | 6972 | static void alc885_imac24_init_hook(struct hda_codec *codec) |
6723 | { | 6973 | { |
6724 | alc885_macpro_init_hook(codec); | 6974 | alc885_macpro_init_hook(codec); |
6725 | alc885_imac24_automute(codec); | 6975 | alc885_imac24_automute_init_hook(codec); |
6726 | } | 6976 | } |
6727 | 6977 | ||
6728 | /* | 6978 | /* |
@@ -6815,6 +7065,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { | |||
6815 | [ALC882_ASUS_A7J] = "asus-a7j", | 7065 | [ALC882_ASUS_A7J] = "asus-a7j", |
6816 | [ALC882_ASUS_A7M] = "asus-a7m", | 7066 | [ALC882_ASUS_A7M] = "asus-a7m", |
6817 | [ALC885_MACPRO] = "macpro", | 7067 | [ALC885_MACPRO] = "macpro", |
7068 | [ALC885_MB5] = "mb5", | ||
6818 | [ALC885_MBP3] = "mbp3", | 7069 | [ALC885_MBP3] = "mbp3", |
6819 | [ALC885_IMAC24] = "imac24", | 7070 | [ALC885_IMAC24] = "imac24", |
6820 | [ALC882_AUTO] = "auto", | 7071 | [ALC882_AUTO] = "auto", |
@@ -6892,8 +7143,20 @@ static struct alc_config_preset alc882_presets[] = { | |||
6892 | .input_mux = &alc882_capture_source, | 7143 | .input_mux = &alc882_capture_source, |
6893 | .dig_out_nid = ALC882_DIGOUT_NID, | 7144 | .dig_out_nid = ALC882_DIGOUT_NID, |
6894 | .dig_in_nid = ALC882_DIGIN_NID, | 7145 | .dig_in_nid = ALC882_DIGIN_NID, |
6895 | .unsol_event = alc885_mbp3_unsol_event, | 7146 | .unsol_event = alc_automute_amp_unsol_event, |
6896 | .init_hook = alc885_mbp3_automute, | 7147 | .init_hook = alc885_mbp3_init_hook, |
7148 | }, | ||
7149 | [ALC885_MB5] = { | ||
7150 | .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, | ||
7151 | .init_verbs = { alc885_mb5_init_verbs, | ||
7152 | alc880_gpio1_init_verbs }, | ||
7153 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
7154 | .dac_nids = alc882_dac_nids, | ||
7155 | .channel_mode = alc885_mb5_6ch_modes, | ||
7156 | .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes), | ||
7157 | .input_mux = &mb5_capture_source, | ||
7158 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
7159 | .dig_in_nid = ALC882_DIGIN_NID, | ||
6897 | }, | 7160 | }, |
6898 | [ALC885_MACPRO] = { | 7161 | [ALC885_MACPRO] = { |
6899 | .mixers = { alc882_macpro_mixer }, | 7162 | .mixers = { alc882_macpro_mixer }, |
@@ -6917,7 +7180,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
6917 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), | 7180 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), |
6918 | .channel_mode = alc882_ch_modes, | 7181 | .channel_mode = alc882_ch_modes, |
6919 | .input_mux = &alc882_capture_source, | 7182 | .input_mux = &alc882_capture_source, |
6920 | .unsol_event = alc885_imac24_unsol_event, | 7183 | .unsol_event = alc_automute_amp_unsol_event, |
6921 | .init_hook = alc885_imac24_init_hook, | 7184 | .init_hook = alc885_imac24_init_hook, |
6922 | }, | 7185 | }, |
6923 | [ALC882_TARGA] = { | 7186 | [ALC882_TARGA] = { |
@@ -6934,7 +7197,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
6934 | .need_dac_fix = 1, | 7197 | .need_dac_fix = 1, |
6935 | .input_mux = &alc882_capture_source, | 7198 | .input_mux = &alc882_capture_source, |
6936 | .unsol_event = alc882_targa_unsol_event, | 7199 | .unsol_event = alc882_targa_unsol_event, |
6937 | .init_hook = alc882_targa_automute, | 7200 | .init_hook = alc882_targa_init_hook, |
6938 | }, | 7201 | }, |
6939 | [ALC882_ASUS_A7J] = { | 7202 | [ALC882_ASUS_A7J] = { |
6940 | .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, | 7203 | .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, |
@@ -7014,7 +7277,6 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec) | |||
7014 | struct alc_spec *spec = codec->spec; | 7277 | struct alc_spec *spec = codec->spec; |
7015 | int i; | 7278 | int i; |
7016 | 7279 | ||
7017 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
7018 | for (i = 0; i <= HDA_SIDE; i++) { | 7280 | for (i = 0; i <= HDA_SIDE; i++) { |
7019 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 7281 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
7020 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 7282 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -7197,10 +7459,17 @@ static int patch_alc882(struct hda_codec *codec) | |||
7197 | case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ | 7459 | case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ |
7198 | case 0x106b00a4: /* MacbookPro4,1 */ | 7460 | case 0x106b00a4: /* MacbookPro4,1 */ |
7199 | case 0x106b2c00: /* Macbook Pro rev3 */ | 7461 | case 0x106b2c00: /* Macbook Pro rev3 */ |
7200 | case 0x106b3600: /* Macbook 3.1 */ | 7462 | /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */ |
7201 | case 0x106b3800: /* MacbookPro4,1 - latter revision */ | 7463 | case 0x106b3800: /* MacbookPro4,1 - latter revision */ |
7202 | board_config = ALC885_MBP3; | 7464 | board_config = ALC885_MBP3; |
7203 | break; | 7465 | break; |
7466 | case 0x106b3f00: /* Macbook 5,1 */ | ||
7467 | case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense | ||
7468 | * seems not working, so apparently | ||
7469 | * no perfect solution yet | ||
7470 | */ | ||
7471 | board_config = ALC885_MB5; | ||
7472 | break; | ||
7204 | default: | 7473 | default: |
7205 | /* ALC889A is handled better as ALC888-compatible */ | 7474 | /* ALC889A is handled better as ALC888-compatible */ |
7206 | if (codec->revision_id == 0x100101 || | 7475 | if (codec->revision_id == 0x100101 || |
@@ -7208,8 +7477,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
7208 | alc_free(codec); | 7477 | alc_free(codec); |
7209 | return patch_alc883(codec); | 7478 | return patch_alc883(codec); |
7210 | } | 7479 | } |
7211 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, " | 7480 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
7212 | "trying auto-probe from BIOS...\n"); | 7481 | "trying auto-probe from BIOS...\n", |
7482 | codec->chip_name); | ||
7213 | board_config = ALC882_AUTO; | 7483 | board_config = ALC882_AUTO; |
7214 | } | 7484 | } |
7215 | } | 7485 | } |
@@ -7239,14 +7509,6 @@ static int patch_alc882(struct hda_codec *codec) | |||
7239 | if (board_config != ALC882_AUTO) | 7509 | if (board_config != ALC882_AUTO) |
7240 | setup_preset(spec, &alc882_presets[board_config]); | 7510 | setup_preset(spec, &alc882_presets[board_config]); |
7241 | 7511 | ||
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; | 7512 | spec->stream_analog_playback = &alc882_pcm_analog_playback; |
7251 | spec->stream_analog_capture = &alc882_pcm_analog_capture; | 7513 | spec->stream_analog_capture = &alc882_pcm_analog_capture; |
7252 | /* FIXME: setup DAC5 */ | 7514 | /* FIXME: setup DAC5 */ |
@@ -7399,6 +7661,17 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = { | |||
7399 | }, | 7661 | }, |
7400 | }; | 7662 | }; |
7401 | 7663 | ||
7664 | static struct hda_input_mux alc889A_mb31_capture_source = { | ||
7665 | .num_items = 2, | ||
7666 | .items = { | ||
7667 | { "Mic", 0x0 }, | ||
7668 | /* Front Mic (0x01) unused */ | ||
7669 | { "Line", 0x2 }, | ||
7670 | /* Line 2 (0x03) unused */ | ||
7671 | /* CD (0x04) unsused? */ | ||
7672 | }, | ||
7673 | }; | ||
7674 | |||
7402 | /* | 7675 | /* |
7403 | * 2ch mode | 7676 | * 2ch mode |
7404 | */ | 7677 | */ |
@@ -7448,6 +7721,73 @@ static struct hda_channel_mode alc883_3ST_6ch_modes[3] = { | |||
7448 | { 6, alc883_3ST_ch6_init }, | 7721 | { 6, alc883_3ST_ch6_init }, |
7449 | }; | 7722 | }; |
7450 | 7723 | ||
7724 | |||
7725 | /* | ||
7726 | * 2ch mode | ||
7727 | */ | ||
7728 | static struct hda_verb alc883_4ST_ch2_init[] = { | ||
7729 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
7730 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
7731 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
7732 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
7733 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
7734 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
7735 | { } /* end */ | ||
7736 | }; | ||
7737 | |||
7738 | /* | ||
7739 | * 4ch mode | ||
7740 | */ | ||
7741 | static struct hda_verb alc883_4ST_ch4_init[] = { | ||
7742 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
7743 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
7744 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
7745 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
7746 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
7747 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
7748 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
7749 | { } /* end */ | ||
7750 | }; | ||
7751 | |||
7752 | /* | ||
7753 | * 6ch mode | ||
7754 | */ | ||
7755 | static struct hda_verb alc883_4ST_ch6_init[] = { | ||
7756 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
7757 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
7758 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
7759 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
7760 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
7761 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
7762 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
7763 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
7764 | { } /* end */ | ||
7765 | }; | ||
7766 | |||
7767 | /* | ||
7768 | * 8ch mode | ||
7769 | */ | ||
7770 | static struct hda_verb alc883_4ST_ch8_init[] = { | ||
7771 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
7772 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
7773 | { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, | ||
7774 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
7775 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
7776 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
7777 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
7778 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
7779 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
7780 | { } /* end */ | ||
7781 | }; | ||
7782 | |||
7783 | static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { | ||
7784 | { 2, alc883_4ST_ch2_init }, | ||
7785 | { 4, alc883_4ST_ch4_init }, | ||
7786 | { 6, alc883_4ST_ch6_init }, | ||
7787 | { 8, alc883_4ST_ch8_init }, | ||
7788 | }; | ||
7789 | |||
7790 | |||
7451 | /* | 7791 | /* |
7452 | * 2ch mode | 7792 | * 2ch mode |
7453 | */ | 7793 | */ |
@@ -7517,6 +7857,49 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = { | |||
7517 | { 8, alc883_sixstack_ch8_init }, | 7857 | { 8, alc883_sixstack_ch8_init }, |
7518 | }; | 7858 | }; |
7519 | 7859 | ||
7860 | /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ | ||
7861 | static struct hda_verb alc889A_mb31_ch2_init[] = { | ||
7862 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ | ||
7863 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
7864 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ | ||
7865 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ | ||
7866 | { } /* end */ | ||
7867 | }; | ||
7868 | |||
7869 | /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ | ||
7870 | static struct hda_verb alc889A_mb31_ch4_init[] = { | ||
7871 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ | ||
7872 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
7873 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ | ||
7874 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ | ||
7875 | { } /* end */ | ||
7876 | }; | ||
7877 | |||
7878 | /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ | ||
7879 | static struct hda_verb alc889A_mb31_ch5_init[] = { | ||
7880 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ | ||
7881 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
7882 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ | ||
7883 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ | ||
7884 | { } /* end */ | ||
7885 | }; | ||
7886 | |||
7887 | /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ | ||
7888 | static struct hda_verb alc889A_mb31_ch6_init[] = { | ||
7889 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ | ||
7890 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ | ||
7891 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ | ||
7892 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ | ||
7893 | { } /* end */ | ||
7894 | }; | ||
7895 | |||
7896 | static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { | ||
7897 | { 2, alc889A_mb31_ch2_init }, | ||
7898 | { 4, alc889A_mb31_ch4_init }, | ||
7899 | { 5, alc889A_mb31_ch5_init }, | ||
7900 | { 6, alc889A_mb31_ch6_init }, | ||
7901 | }; | ||
7902 | |||
7520 | static struct hda_verb alc883_medion_eapd_verbs[] = { | 7903 | static struct hda_verb alc883_medion_eapd_verbs[] = { |
7521 | /* eanable EAPD on medion laptop */ | 7904 | /* eanable EAPD on medion laptop */ |
7522 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | 7905 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, |
@@ -7782,8 +8165,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { | |||
7782 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), | 8165 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), |
7783 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 8166 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
7784 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | 8167 | 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), | 8168 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
7788 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 8169 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
7789 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 8170 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
@@ -7797,6 +8178,42 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { | |||
7797 | { } /* end */ | 8178 | { } /* end */ |
7798 | }; | 8179 | }; |
7799 | 8180 | ||
8181 | static struct snd_kcontrol_new alc889A_mb31_mixer[] = { | ||
8182 | /* Output mixers */ | ||
8183 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
8184 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), | ||
8185 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
8186 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), | ||
8187 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00, | ||
8188 | HDA_OUTPUT), | ||
8189 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT), | ||
8190 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT), | ||
8191 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT), | ||
8192 | /* Output switches */ | ||
8193 | HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT), | ||
8194 | HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), | ||
8195 | HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), | ||
8196 | /* Boost mixers */ | ||
8197 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), | ||
8198 | HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), | ||
8199 | /* Input mixers */ | ||
8200 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), | ||
8201 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), | ||
8202 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
8203 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
8204 | { } /* end */ | ||
8205 | }; | ||
8206 | |||
8207 | static struct snd_kcontrol_new alc883_vaiott_mixer[] = { | ||
8208 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
8209 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
8210 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
8211 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
8212 | HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), | ||
8213 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
8214 | { } /* end */ | ||
8215 | }; | ||
8216 | |||
7800 | static struct hda_bind_ctls alc883_bind_cap_vol = { | 8217 | static struct hda_bind_ctls alc883_bind_cap_vol = { |
7801 | .ops = &snd_hda_bind_vol, | 8218 | .ops = &snd_hda_bind_vol, |
7802 | .values = { | 8219 | .values = { |
@@ -7932,16 +8349,14 @@ static struct hda_verb alc883_init_verbs[] = { | |||
7932 | }; | 8349 | }; |
7933 | 8350 | ||
7934 | /* toggle speaker-output according to the hp-jack state */ | 8351 | /* toggle speaker-output according to the hp-jack state */ |
7935 | static void alc883_mitac_hp_automute(struct hda_codec *codec) | 8352 | static void alc883_mitac_init_hook(struct hda_codec *codec) |
7936 | { | 8353 | { |
7937 | unsigned int present; | 8354 | struct alc_spec *spec = codec->spec; |
7938 | 8355 | ||
7939 | present = snd_hda_codec_read(codec, 0x15, 0, | 8356 | spec->autocfg.hp_pins[0] = 0x15; |
7940 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 8357 | spec->autocfg.speaker_pins[0] = 0x14; |
7941 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 8358 | spec->autocfg.speaker_pins[1] = 0x17; |
7942 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 8359 | 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 | } | 8360 | } |
7946 | 8361 | ||
7947 | /* auto-toggle front mic */ | 8362 | /* auto-toggle front mic */ |
@@ -7958,25 +8373,6 @@ static void alc883_mitac_mic_automute(struct hda_codec *codec) | |||
7958 | } | 8373 | } |
7959 | */ | 8374 | */ |
7960 | 8375 | ||
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[] = { | 8376 | static struct hda_verb alc883_mitac_verbs[] = { |
7981 | /* HP */ | 8377 | /* HP */ |
7982 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 8378 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -8028,14 +8424,24 @@ static struct hda_verb alc883_tagra_verbs[] = { | |||
8028 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 8424 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
8029 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 8425 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
8030 | 8426 | ||
8031 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ | 8427 | /* Connect Line-Out side jack (SPDIF) to Side */ |
8032 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ | 8428 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
8033 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 8429 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
8430 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
8431 | /* Connect Mic jack to CLFE */ | ||
8432 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
8433 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8434 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
8435 | /* Connect Line-in jack to Surround */ | ||
8436 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
8437 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8438 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
8439 | /* Connect HP out jack to Front */ | ||
8440 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
8441 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8442 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8034 | 8443 | ||
8035 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 8444 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
8036 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | ||
8037 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, | ||
8038 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, | ||
8039 | 8445 | ||
8040 | { } /* end */ | 8446 | { } /* end */ |
8041 | }; | 8447 | }; |
@@ -8094,29 +8500,26 @@ static struct hda_verb alc888_6st_dell_verbs[] = { | |||
8094 | { } | 8500 | { } |
8095 | }; | 8501 | }; |
8096 | 8502 | ||
8097 | static void alc888_3st_hp_front_automute(struct hda_codec *codec) | 8503 | static struct hda_verb alc883_vaiott_verbs[] = { |
8098 | { | 8504 | /* HP */ |
8099 | unsigned int present, bits; | 8505 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
8506 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
8100 | 8507 | ||
8101 | present = snd_hda_codec_read(codec, 0x1b, 0, | 8508 | /* enable unsolicited event */ |
8102 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 8509 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
8103 | bits = present ? HDA_AMP_MUTE : 0; | 8510 | |
8104 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 8511 | { } /* end */ |
8105 | HDA_AMP_MUTE, bits); | 8512 | }; |
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 | 8513 | ||
8112 | static void alc888_3st_hp_unsol_event(struct hda_codec *codec, | 8514 | static void alc888_3st_hp_init_hook(struct hda_codec *codec) |
8113 | unsigned int res) | ||
8114 | { | 8515 | { |
8115 | switch (res >> 26) { | 8516 | struct alc_spec *spec = codec->spec; |
8116 | case ALC880_HP_EVENT: | 8517 | |
8117 | alc888_3st_hp_front_automute(codec); | 8518 | spec->autocfg.hp_pins[0] = 0x1b; |
8118 | break; | 8519 | spec->autocfg.speaker_pins[0] = 0x14; |
8119 | } | 8520 | spec->autocfg.speaker_pins[1] = 0x16; |
8521 | spec->autocfg.speaker_pins[2] = 0x18; | ||
8522 | alc_automute_amp(codec); | ||
8120 | } | 8523 | } |
8121 | 8524 | ||
8122 | static struct hda_verb alc888_3st_hp_verbs[] = { | 8525 | static struct hda_verb alc888_3st_hp_verbs[] = { |
@@ -8213,56 +8616,18 @@ static struct hda_verb alc883_medion_md2_verbs[] = { | |||
8213 | }; | 8616 | }; |
8214 | 8617 | ||
8215 | /* toggle speaker-output according to the hp-jack state */ | 8618 | /* toggle speaker-output according to the hp-jack state */ |
8216 | static void alc883_medion_md2_automute(struct hda_codec *codec) | 8619 | static void alc883_medion_md2_init_hook(struct hda_codec *codec) |
8217 | { | 8620 | { |
8218 | unsigned int present; | 8621 | struct alc_spec *spec = codec->spec; |
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 | { | ||
8236 | unsigned int present; | ||
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 | 8622 | ||
8248 | static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) | 8623 | spec->autocfg.hp_pins[0] = 0x14; |
8249 | { | 8624 | spec->autocfg.speaker_pins[0] = 0x15; |
8250 | if ((res >> 26) == ALC880_HP_EVENT) | 8625 | alc_automute_amp(codec); |
8251 | alc883_tagra_automute(codec); | ||
8252 | } | 8626 | } |
8253 | 8627 | ||
8254 | /* toggle speaker-output according to the hp-jack state */ | 8628 | /* toggle speaker-output according to the hp-jack state */ |
8255 | static void alc883_clevo_m720_hp_automute(struct hda_codec *codec) | 8629 | #define alc883_tagra_init_hook alc882_targa_init_hook |
8256 | { | 8630 | #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 | 8631 | ||
8267 | static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) | 8632 | static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) |
8268 | { | 8633 | { |
@@ -8274,9 +8639,13 @@ static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) | |||
8274 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 8639 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
8275 | } | 8640 | } |
8276 | 8641 | ||
8277 | static void alc883_clevo_m720_automute(struct hda_codec *codec) | 8642 | static void alc883_clevo_m720_init_hook(struct hda_codec *codec) |
8278 | { | 8643 | { |
8279 | alc883_clevo_m720_hp_automute(codec); | 8644 | struct alc_spec *spec = codec->spec; |
8645 | |||
8646 | spec->autocfg.hp_pins[0] = 0x15; | ||
8647 | spec->autocfg.speaker_pins[0] = 0x14; | ||
8648 | alc_automute_amp(codec); | ||
8280 | alc883_clevo_m720_mic_automute(codec); | 8649 | alc883_clevo_m720_mic_automute(codec); |
8281 | } | 8650 | } |
8282 | 8651 | ||
@@ -8284,52 +8653,32 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, | |||
8284 | unsigned int res) | 8653 | unsigned int res) |
8285 | { | 8654 | { |
8286 | switch (res >> 26) { | 8655 | switch (res >> 26) { |
8287 | case ALC880_HP_EVENT: | ||
8288 | alc883_clevo_m720_hp_automute(codec); | ||
8289 | break; | ||
8290 | case ALC880_MIC_EVENT: | 8656 | case ALC880_MIC_EVENT: |
8291 | alc883_clevo_m720_mic_automute(codec); | 8657 | alc883_clevo_m720_mic_automute(codec); |
8292 | break; | 8658 | break; |
8659 | default: | ||
8660 | alc_automute_amp_unsol_event(codec, res); | ||
8661 | break; | ||
8293 | } | 8662 | } |
8294 | } | 8663 | } |
8295 | 8664 | ||
8296 | /* toggle speaker-output according to the hp-jack state */ | 8665 | /* toggle speaker-output according to the hp-jack state */ |
8297 | static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec) | 8666 | static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec) |
8298 | { | 8667 | { |
8299 | unsigned int present; | 8668 | 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 | 8669 | ||
8309 | static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec, | 8670 | spec->autocfg.hp_pins[0] = 0x14; |
8310 | unsigned int res) | 8671 | spec->autocfg.speaker_pins[0] = 0x15; |
8311 | { | 8672 | alc_automute_amp(codec); |
8312 | if ((res >> 26) == ALC880_HP_EVENT) | ||
8313 | alc883_2ch_fujitsu_pi2515_automute(codec); | ||
8314 | } | 8673 | } |
8315 | 8674 | ||
8316 | static void alc883_haier_w66_automute(struct hda_codec *codec) | 8675 | static void alc883_haier_w66_init_hook(struct hda_codec *codec) |
8317 | { | 8676 | { |
8318 | unsigned int present; | 8677 | struct alc_spec *spec = codec->spec; |
8319 | unsigned char bits; | ||
8320 | 8678 | ||
8321 | present = snd_hda_codec_read(codec, 0x1b, 0, | 8679 | spec->autocfg.hp_pins[0] = 0x1b; |
8322 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 8680 | spec->autocfg.speaker_pins[0] = 0x14; |
8323 | bits = present ? 0x80 : 0; | 8681 | alc_automute_amp(codec); |
8324 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
8325 | 0x80, bits); | ||
8326 | } | ||
8327 | |||
8328 | static void alc883_haier_w66_unsol_event(struct hda_codec *codec, | ||
8329 | unsigned int res) | ||
8330 | { | ||
8331 | if ((res >> 26) == ALC880_HP_EVENT) | ||
8332 | alc883_haier_w66_automute(codec); | ||
8333 | } | 8682 | } |
8334 | 8683 | ||
8335 | static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | 8684 | static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) |
@@ -8337,8 +8686,8 @@ static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | |||
8337 | unsigned int present; | 8686 | unsigned int present; |
8338 | unsigned char bits; | 8687 | unsigned char bits; |
8339 | 8688 | ||
8340 | present = snd_hda_codec_read(codec, 0x14, 0, | 8689 | present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) |
8341 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 8690 | & AC_PINSENSE_PRESENCE; |
8342 | bits = present ? HDA_AMP_MUTE : 0; | 8691 | bits = present ? HDA_AMP_MUTE : 0; |
8343 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 8692 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, |
8344 | HDA_AMP_MUTE, bits); | 8693 | HDA_AMP_MUTE, bits); |
@@ -8368,23 +8717,14 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, | |||
8368 | } | 8717 | } |
8369 | 8718 | ||
8370 | /* toggle speaker-output according to the hp-jack state */ | 8719 | /* toggle speaker-output according to the hp-jack state */ |
8371 | static void alc883_acer_aspire_automute(struct hda_codec *codec) | 8720 | static void alc883_acer_aspire_init_hook(struct hda_codec *codec) |
8372 | { | 8721 | { |
8373 | unsigned int present; | 8722 | 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 | 8723 | ||
8383 | static void alc883_acer_aspire_unsol_event(struct hda_codec *codec, | 8724 | spec->autocfg.hp_pins[0] = 0x14; |
8384 | unsigned int res) | 8725 | spec->autocfg.speaker_pins[0] = 0x15; |
8385 | { | 8726 | spec->autocfg.speaker_pins[1] = 0x16; |
8386 | if ((res >> 26) == ALC880_HP_EVENT) | 8727 | alc_automute_amp(codec); |
8387 | alc883_acer_aspire_automute(codec); | ||
8388 | } | 8728 | } |
8389 | 8729 | ||
8390 | static struct hda_verb alc883_acer_eapd_verbs[] = { | 8730 | static struct hda_verb alc883_acer_eapd_verbs[] = { |
@@ -8405,75 +8745,39 @@ static struct hda_verb alc883_acer_eapd_verbs[] = { | |||
8405 | { } | 8745 | { } |
8406 | }; | 8746 | }; |
8407 | 8747 | ||
8408 | static void alc888_6st_dell_front_automute(struct hda_codec *codec) | 8748 | static void alc888_6st_dell_init_hook(struct hda_codec *codec) |
8409 | { | 8749 | { |
8410 | unsigned int present; | 8750 | 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 | 8751 | ||
8424 | static void alc888_6st_dell_unsol_event(struct hda_codec *codec, | 8752 | spec->autocfg.hp_pins[0] = 0x1b; |
8425 | unsigned int res) | 8753 | spec->autocfg.speaker_pins[0] = 0x14; |
8426 | { | 8754 | spec->autocfg.speaker_pins[1] = 0x15; |
8427 | switch (res >> 26) { | 8755 | spec->autocfg.speaker_pins[2] = 0x16; |
8428 | case ALC880_HP_EVENT: | 8756 | spec->autocfg.speaker_pins[3] = 0x17; |
8429 | /* printk(KERN_DEBUG "hp_event\n"); */ | 8757 | alc_automute_amp(codec); |
8430 | alc888_6st_dell_front_automute(codec); | ||
8431 | break; | ||
8432 | } | ||
8433 | } | 8758 | } |
8434 | 8759 | ||
8435 | static void alc888_lenovo_sky_front_automute(struct hda_codec *codec) | 8760 | static void alc888_lenovo_sky_init_hook(struct hda_codec *codec) |
8436 | { | 8761 | { |
8437 | unsigned int mute; | 8762 | struct alc_spec *spec = codec->spec; |
8438 | unsigned int present; | ||
8439 | 8763 | ||
8440 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | 8764 | spec->autocfg.hp_pins[0] = 0x1b; |
8441 | present = snd_hda_codec_read(codec, 0x1b, 0, | 8765 | spec->autocfg.speaker_pins[0] = 0x14; |
8442 | AC_VERB_GET_PIN_SENSE, 0); | 8766 | spec->autocfg.speaker_pins[1] = 0x15; |
8443 | present = (present & 0x80000000) != 0; | 8767 | spec->autocfg.speaker_pins[2] = 0x16; |
8444 | if (present) { | 8768 | spec->autocfg.speaker_pins[3] = 0x17; |
8445 | /* mute internal speaker */ | 8769 | spec->autocfg.speaker_pins[4] = 0x1a; |
8446 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | 8770 | alc_automute_amp(codec); |
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 | } | 8771 | } |
8471 | 8772 | ||
8472 | static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec, | 8773 | static void alc883_vaiott_init_hook(struct hda_codec *codec) |
8473 | unsigned int res) | ||
8474 | { | 8774 | { |
8475 | if ((res >> 26) == ALC880_HP_EVENT) | 8775 | struct alc_spec *spec = codec->spec; |
8476 | alc888_lenovo_sky_front_automute(codec); | 8776 | |
8777 | spec->autocfg.hp_pins[0] = 0x15; | ||
8778 | spec->autocfg.speaker_pins[0] = 0x14; | ||
8779 | spec->autocfg.speaker_pins[1] = 0x17; | ||
8780 | alc_automute_amp(codec); | ||
8477 | } | 8781 | } |
8478 | 8782 | ||
8479 | /* | 8783 | /* |
@@ -8561,39 +8865,33 @@ static void alc883_nb_mic_automute(struct hda_codec *codec) | |||
8561 | 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); | 8865 | 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); |
8562 | } | 8866 | } |
8563 | 8867 | ||
8564 | static void alc883_M90V_speaker_automute(struct hda_codec *codec) | 8868 | static void alc883_M90V_init_hook(struct hda_codec *codec) |
8565 | { | 8869 | { |
8566 | unsigned int present; | 8870 | struct alc_spec *spec = codec->spec; |
8567 | unsigned char bits; | ||
8568 | 8871 | ||
8569 | present = snd_hda_codec_read(codec, 0x1b, 0, | 8872 | spec->autocfg.hp_pins[0] = 0x1b; |
8570 | AC_VERB_GET_PIN_SENSE, 0) | 8873 | spec->autocfg.speaker_pins[0] = 0x14; |
8571 | & AC_PINSENSE_PRESENCE; | 8874 | spec->autocfg.speaker_pins[1] = 0x15; |
8572 | bits = present ? 0 : PIN_OUT; | 8875 | spec->autocfg.speaker_pins[2] = 0x16; |
8573 | snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 8876 | 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 | } | 8877 | } |
8580 | 8878 | ||
8581 | static void alc883_mode2_unsol_event(struct hda_codec *codec, | 8879 | static void alc883_mode2_unsol_event(struct hda_codec *codec, |
8582 | unsigned int res) | 8880 | unsigned int res) |
8583 | { | 8881 | { |
8584 | switch (res >> 26) { | 8882 | switch (res >> 26) { |
8585 | case ALC880_HP_EVENT: | ||
8586 | alc883_M90V_speaker_automute(codec); | ||
8587 | break; | ||
8588 | case ALC880_MIC_EVENT: | 8883 | case ALC880_MIC_EVENT: |
8589 | alc883_nb_mic_automute(codec); | 8884 | alc883_nb_mic_automute(codec); |
8590 | break; | 8885 | break; |
8886 | default: | ||
8887 | alc_sku_unsol_event(codec, res); | ||
8888 | break; | ||
8591 | } | 8889 | } |
8592 | } | 8890 | } |
8593 | 8891 | ||
8594 | static void alc883_mode2_inithook(struct hda_codec *codec) | 8892 | static void alc883_mode2_inithook(struct hda_codec *codec) |
8595 | { | 8893 | { |
8596 | alc883_M90V_speaker_automute(codec); | 8894 | alc883_M90V_init_hook(codec); |
8597 | alc883_nb_mic_automute(codec); | 8895 | alc883_nb_mic_automute(codec); |
8598 | } | 8896 | } |
8599 | 8897 | ||
@@ -8610,32 +8908,49 @@ static struct hda_verb alc888_asus_eee1601_verbs[] = { | |||
8610 | { } /* end */ | 8908 | { } /* end */ |
8611 | }; | 8909 | }; |
8612 | 8910 | ||
8613 | static void alc883_eee1601_speaker_automute(struct hda_codec *codec) | 8911 | static void alc883_eee1601_inithook(struct hda_codec *codec) |
8614 | { | 8912 | { |
8615 | unsigned int present; | 8913 | struct alc_spec *spec = codec->spec; |
8616 | unsigned char bits; | ||
8617 | 8914 | ||
8618 | present = snd_hda_codec_read(codec, 0x14, 0, | 8915 | spec->autocfg.hp_pins[0] = 0x14; |
8619 | AC_VERB_GET_PIN_SENSE, 0) | 8916 | spec->autocfg.speaker_pins[0] = 0x1b; |
8620 | & AC_PINSENSE_PRESENCE; | 8917 | 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 | } | 8918 | } |
8625 | 8919 | ||
8626 | static void alc883_eee1601_unsol_event(struct hda_codec *codec, | 8920 | static struct hda_verb alc889A_mb31_verbs[] = { |
8627 | unsigned int res) | 8921 | /* Init rear pin (used as headphone output) */ |
8922 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ | ||
8923 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ | ||
8924 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
8925 | /* Init line pin (used as output in 4ch and 6ch mode) */ | ||
8926 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */ | ||
8927 | /* Init line 2 pin (used as headphone out by default) */ | ||
8928 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */ | ||
8929 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */ | ||
8930 | { } /* end */ | ||
8931 | }; | ||
8932 | |||
8933 | /* Mute speakers according to the headphone jack state */ | ||
8934 | static void alc889A_mb31_automute(struct hda_codec *codec) | ||
8628 | { | 8935 | { |
8629 | switch (res >> 26) { | 8936 | unsigned int present; |
8630 | case ALC880_HP_EVENT: | 8937 | |
8631 | alc883_eee1601_speaker_automute(codec); | 8938 | /* Mute only in 2ch or 4ch mode */ |
8632 | break; | 8939 | if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) |
8940 | == 0x00) { | ||
8941 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
8942 | AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; | ||
8943 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
8944 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8945 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
8946 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
8633 | } | 8947 | } |
8634 | } | 8948 | } |
8635 | 8949 | ||
8636 | static void alc883_eee1601_inithook(struct hda_codec *codec) | 8950 | static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) |
8637 | { | 8951 | { |
8638 | alc883_eee1601_speaker_automute(codec); | 8952 | if ((res >> 26) == ALC880_HP_EVENT) |
8953 | alc889A_mb31_automute(codec); | ||
8639 | } | 8954 | } |
8640 | 8955 | ||
8641 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 8956 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -8659,9 +8974,11 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { | |||
8659 | [ALC883_6ST_DIG] = "6stack-dig", | 8974 | [ALC883_6ST_DIG] = "6stack-dig", |
8660 | [ALC883_TARGA_DIG] = "targa-dig", | 8975 | [ALC883_TARGA_DIG] = "targa-dig", |
8661 | [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", | 8976 | [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", |
8977 | [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", | ||
8662 | [ALC883_ACER] = "acer", | 8978 | [ALC883_ACER] = "acer", |
8663 | [ALC883_ACER_ASPIRE] = "acer-aspire", | 8979 | [ALC883_ACER_ASPIRE] = "acer-aspire", |
8664 | [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", | 8980 | [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", |
8981 | [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", | ||
8665 | [ALC883_MEDION] = "medion", | 8982 | [ALC883_MEDION] = "medion", |
8666 | [ALC883_MEDION_MD2] = "medion-md2", | 8983 | [ALC883_MEDION_MD2] = "medion-md2", |
8667 | [ALC883_LAPTOP_EAPD] = "laptop-eapd", | 8984 | [ALC883_LAPTOP_EAPD] = "laptop-eapd", |
@@ -8678,6 +8995,8 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { | |||
8678 | [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", | 8995 | [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", |
8679 | [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", | 8996 | [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", |
8680 | [ALC1200_ASUS_P5Q] = "asus-p5q", | 8997 | [ALC1200_ASUS_P5Q] = "asus-p5q", |
8998 | [ALC889A_MB31] = "mb31", | ||
8999 | [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", | ||
8681 | [ALC883_AUTO] = "auto", | 9000 | [ALC883_AUTO] = "auto", |
8682 | }; | 9001 | }; |
8683 | 9002 | ||
@@ -8693,14 +9012,18 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8693 | ALC888_ACER_ASPIRE_4930G), | 9012 | ALC888_ACER_ASPIRE_4930G), |
8694 | SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", | 9013 | SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", |
8695 | ALC888_ACER_ASPIRE_4930G), | 9014 | ALC888_ACER_ASPIRE_4930G), |
9015 | SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", | ||
9016 | ALC888_ACER_ASPIRE_8930G), | ||
8696 | SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), | 9017 | SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), |
8697 | SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), | 9018 | SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), |
8698 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", | 9019 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", |
8699 | ALC888_ACER_ASPIRE_4930G), | 9020 | ALC888_ACER_ASPIRE_4930G), |
8700 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", | 9021 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", |
8701 | ALC888_ACER_ASPIRE_4930G), | 9022 | ALC888_ACER_ASPIRE_4930G), |
8702 | /* default Acer */ | 9023 | /* default Acer -- disabled as it causes more problems. |
8703 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), | 9024 | * model=auto should work fine now |
9025 | */ | ||
9026 | /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ | ||
8704 | SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), | 9027 | SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), |
8705 | SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), | 9028 | SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), |
8706 | SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), | 9029 | SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), |
@@ -8736,6 +9059,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8736 | SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), | 9059 | SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), |
8737 | SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), | 9060 | SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), |
8738 | SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), | 9061 | SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), |
9062 | SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), | ||
8739 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), | 9063 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), |
8740 | SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), | 9064 | SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), |
8741 | SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), | 9065 | SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), |
@@ -8768,6 +9092,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8768 | SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), | 9092 | SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), |
8769 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), | 9093 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), |
8770 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), | 9094 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), |
9095 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT), | ||
8771 | {} | 9096 | {} |
8772 | }; | 9097 | }; |
8773 | 9098 | ||
@@ -8848,7 +9173,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
8848 | .need_dac_fix = 1, | 9173 | .need_dac_fix = 1, |
8849 | .input_mux = &alc883_capture_source, | 9174 | .input_mux = &alc883_capture_source, |
8850 | .unsol_event = alc883_tagra_unsol_event, | 9175 | .unsol_event = alc883_tagra_unsol_event, |
8851 | .init_hook = alc883_tagra_automute, | 9176 | .init_hook = alc883_tagra_init_hook, |
8852 | }, | 9177 | }, |
8853 | [ALC883_TARGA_2ch_DIG] = { | 9178 | [ALC883_TARGA_2ch_DIG] = { |
8854 | .mixers = { alc883_tagra_2ch_mixer}, | 9179 | .mixers = { alc883_tagra_2ch_mixer}, |
@@ -8862,7 +9187,25 @@ static struct alc_config_preset alc883_presets[] = { | |||
8862 | .channel_mode = alc883_3ST_2ch_modes, | 9187 | .channel_mode = alc883_3ST_2ch_modes, |
8863 | .input_mux = &alc883_capture_source, | 9188 | .input_mux = &alc883_capture_source, |
8864 | .unsol_event = alc883_tagra_unsol_event, | 9189 | .unsol_event = alc883_tagra_unsol_event, |
8865 | .init_hook = alc883_tagra_automute, | 9190 | .init_hook = alc883_tagra_init_hook, |
9191 | }, | ||
9192 | [ALC883_TARGA_8ch_DIG] = { | ||
9193 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | ||
9194 | .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, | ||
9195 | alc883_tagra_verbs }, | ||
9196 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
9197 | .dac_nids = alc883_dac_nids, | ||
9198 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), | ||
9199 | .adc_nids = alc883_adc_nids_rev, | ||
9200 | .capsrc_nids = alc883_capsrc_nids_rev, | ||
9201 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
9202 | .dig_in_nid = ALC883_DIGIN_NID, | ||
9203 | .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes), | ||
9204 | .channel_mode = alc883_4ST_8ch_modes, | ||
9205 | .need_dac_fix = 1, | ||
9206 | .input_mux = &alc883_capture_source, | ||
9207 | .unsol_event = alc883_tagra_unsol_event, | ||
9208 | .init_hook = alc883_tagra_init_hook, | ||
8866 | }, | 9209 | }, |
8867 | [ALC883_ACER] = { | 9210 | [ALC883_ACER] = { |
8868 | .mixers = { alc883_base_mixer }, | 9211 | .mixers = { alc883_base_mixer }, |
@@ -8887,8 +9230,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
8887 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 9230 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
8888 | .channel_mode = alc883_3ST_2ch_modes, | 9231 | .channel_mode = alc883_3ST_2ch_modes, |
8889 | .input_mux = &alc883_capture_source, | 9232 | .input_mux = &alc883_capture_source, |
8890 | .unsol_event = alc883_acer_aspire_unsol_event, | 9233 | .unsol_event = alc_automute_amp_unsol_event, |
8891 | .init_hook = alc883_acer_aspire_automute, | 9234 | .init_hook = alc883_acer_aspire_init_hook, |
8892 | }, | 9235 | }, |
8893 | [ALC888_ACER_ASPIRE_4930G] = { | 9236 | [ALC888_ACER_ASPIRE_4930G] = { |
8894 | .mixers = { alc888_base_mixer, | 9237 | .mixers = { alc888_base_mixer, |
@@ -8907,8 +9250,29 @@ static struct alc_config_preset alc883_presets[] = { | |||
8907 | .num_mux_defs = | 9250 | .num_mux_defs = |
8908 | ARRAY_SIZE(alc888_2_capture_sources), | 9251 | ARRAY_SIZE(alc888_2_capture_sources), |
8909 | .input_mux = alc888_2_capture_sources, | 9252 | .input_mux = alc888_2_capture_sources, |
8910 | .unsol_event = alc888_acer_aspire_4930g_unsol_event, | 9253 | .unsol_event = alc_automute_amp_unsol_event, |
8911 | .init_hook = alc888_acer_aspire_4930g_automute, | 9254 | .init_hook = alc888_acer_aspire_4930g_init_hook, |
9255 | }, | ||
9256 | [ALC888_ACER_ASPIRE_8930G] = { | ||
9257 | .mixers = { alc888_base_mixer, | ||
9258 | alc883_chmode_mixer }, | ||
9259 | .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, | ||
9260 | alc889_acer_aspire_8930g_verbs }, | ||
9261 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
9262 | .dac_nids = alc883_dac_nids, | ||
9263 | .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), | ||
9264 | .adc_nids = alc889_adc_nids, | ||
9265 | .capsrc_nids = alc889_capsrc_nids, | ||
9266 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
9267 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), | ||
9268 | .channel_mode = alc883_3ST_6ch_modes, | ||
9269 | .need_dac_fix = 1, | ||
9270 | .const_channel_count = 6, | ||
9271 | .num_mux_defs = | ||
9272 | ARRAY_SIZE(alc889_capture_sources), | ||
9273 | .input_mux = alc889_capture_sources, | ||
9274 | .unsol_event = alc_automute_amp_unsol_event, | ||
9275 | .init_hook = alc889_acer_aspire_8930g_init_hook, | ||
8912 | }, | 9276 | }, |
8913 | [ALC883_MEDION] = { | 9277 | [ALC883_MEDION] = { |
8914 | .mixers = { alc883_fivestack_mixer, | 9278 | .mixers = { alc883_fivestack_mixer, |
@@ -8932,8 +9296,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
8932 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 9296 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
8933 | .channel_mode = alc883_3ST_2ch_modes, | 9297 | .channel_mode = alc883_3ST_2ch_modes, |
8934 | .input_mux = &alc883_capture_source, | 9298 | .input_mux = &alc883_capture_source, |
8935 | .unsol_event = alc883_medion_md2_unsol_event, | 9299 | .unsol_event = alc_automute_amp_unsol_event, |
8936 | .init_hook = alc883_medion_md2_automute, | 9300 | .init_hook = alc883_medion_md2_init_hook, |
8937 | }, | 9301 | }, |
8938 | [ALC883_LAPTOP_EAPD] = { | 9302 | [ALC883_LAPTOP_EAPD] = { |
8939 | .mixers = { alc883_base_mixer }, | 9303 | .mixers = { alc883_base_mixer }, |
@@ -8954,7 +9318,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
8954 | .channel_mode = alc883_3ST_2ch_modes, | 9318 | .channel_mode = alc883_3ST_2ch_modes, |
8955 | .input_mux = &alc883_capture_source, | 9319 | .input_mux = &alc883_capture_source, |
8956 | .unsol_event = alc883_clevo_m720_unsol_event, | 9320 | .unsol_event = alc883_clevo_m720_unsol_event, |
8957 | .init_hook = alc883_clevo_m720_automute, | 9321 | .init_hook = alc883_clevo_m720_init_hook, |
8958 | }, | 9322 | }, |
8959 | [ALC883_LENOVO_101E_2ch] = { | 9323 | [ALC883_LENOVO_101E_2ch] = { |
8960 | .mixers = { alc883_lenovo_101e_2ch_mixer}, | 9324 | .mixers = { alc883_lenovo_101e_2ch_mixer}, |
@@ -8978,8 +9342,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
8978 | .channel_mode = alc883_3ST_2ch_modes, | 9342 | .channel_mode = alc883_3ST_2ch_modes, |
8979 | .need_dac_fix = 1, | 9343 | .need_dac_fix = 1, |
8980 | .input_mux = &alc883_lenovo_nb0763_capture_source, | 9344 | .input_mux = &alc883_lenovo_nb0763_capture_source, |
8981 | .unsol_event = alc883_medion_md2_unsol_event, | 9345 | .unsol_event = alc_automute_amp_unsol_event, |
8982 | .init_hook = alc883_medion_md2_automute, | 9346 | .init_hook = alc883_medion_md2_init_hook, |
8983 | }, | 9347 | }, |
8984 | [ALC888_LENOVO_MS7195_DIG] = { | 9348 | [ALC888_LENOVO_MS7195_DIG] = { |
8985 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 9349 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -9003,8 +9367,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9003 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 9367 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
9004 | .channel_mode = alc883_3ST_2ch_modes, | 9368 | .channel_mode = alc883_3ST_2ch_modes, |
9005 | .input_mux = &alc883_capture_source, | 9369 | .input_mux = &alc883_capture_source, |
9006 | .unsol_event = alc883_haier_w66_unsol_event, | 9370 | .unsol_event = alc_automute_amp_unsol_event, |
9007 | .init_hook = alc883_haier_w66_automute, | 9371 | .init_hook = alc883_haier_w66_init_hook, |
9008 | }, | 9372 | }, |
9009 | [ALC888_3ST_HP] = { | 9373 | [ALC888_3ST_HP] = { |
9010 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 9374 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -9015,8 +9379,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9015 | .channel_mode = alc888_3st_hp_modes, | 9379 | .channel_mode = alc888_3st_hp_modes, |
9016 | .need_dac_fix = 1, | 9380 | .need_dac_fix = 1, |
9017 | .input_mux = &alc883_capture_source, | 9381 | .input_mux = &alc883_capture_source, |
9018 | .unsol_event = alc888_3st_hp_unsol_event, | 9382 | .unsol_event = alc_automute_amp_unsol_event, |
9019 | .init_hook = alc888_3st_hp_front_automute, | 9383 | .init_hook = alc888_3st_hp_init_hook, |
9020 | }, | 9384 | }, |
9021 | [ALC888_6ST_DELL] = { | 9385 | [ALC888_6ST_DELL] = { |
9022 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 9386 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
@@ -9028,8 +9392,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9028 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), | 9392 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), |
9029 | .channel_mode = alc883_sixstack_modes, | 9393 | .channel_mode = alc883_sixstack_modes, |
9030 | .input_mux = &alc883_capture_source, | 9394 | .input_mux = &alc883_capture_source, |
9031 | .unsol_event = alc888_6st_dell_unsol_event, | 9395 | .unsol_event = alc_automute_amp_unsol_event, |
9032 | .init_hook = alc888_6st_dell_front_automute, | 9396 | .init_hook = alc888_6st_dell_init_hook, |
9033 | }, | 9397 | }, |
9034 | [ALC883_MITAC] = { | 9398 | [ALC883_MITAC] = { |
9035 | .mixers = { alc883_mitac_mixer }, | 9399 | .mixers = { alc883_mitac_mixer }, |
@@ -9039,8 +9403,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9039 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 9403 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
9040 | .channel_mode = alc883_3ST_2ch_modes, | 9404 | .channel_mode = alc883_3ST_2ch_modes, |
9041 | .input_mux = &alc883_capture_source, | 9405 | .input_mux = &alc883_capture_source, |
9042 | .unsol_event = alc883_mitac_unsol_event, | 9406 | .unsol_event = alc_automute_amp_unsol_event, |
9043 | .init_hook = alc883_mitac_automute, | 9407 | .init_hook = alc883_mitac_init_hook, |
9044 | }, | 9408 | }, |
9045 | [ALC883_FUJITSU_PI2515] = { | 9409 | [ALC883_FUJITSU_PI2515] = { |
9046 | .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, | 9410 | .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, |
@@ -9052,8 +9416,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9052 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 9416 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
9053 | .channel_mode = alc883_3ST_2ch_modes, | 9417 | .channel_mode = alc883_3ST_2ch_modes, |
9054 | .input_mux = &alc883_fujitsu_pi2515_capture_source, | 9418 | .input_mux = &alc883_fujitsu_pi2515_capture_source, |
9055 | .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event, | 9419 | .unsol_event = alc_automute_amp_unsol_event, |
9056 | .init_hook = alc883_2ch_fujitsu_pi2515_automute, | 9420 | .init_hook = alc883_2ch_fujitsu_pi2515_init_hook, |
9057 | }, | 9421 | }, |
9058 | [ALC888_FUJITSU_XA3530] = { | 9422 | [ALC888_FUJITSU_XA3530] = { |
9059 | .mixers = { alc888_base_mixer, alc883_chmode_mixer }, | 9423 | .mixers = { alc888_base_mixer, alc883_chmode_mixer }, |
@@ -9070,8 +9434,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9070 | .num_mux_defs = | 9434 | .num_mux_defs = |
9071 | ARRAY_SIZE(alc888_2_capture_sources), | 9435 | ARRAY_SIZE(alc888_2_capture_sources), |
9072 | .input_mux = alc888_2_capture_sources, | 9436 | .input_mux = alc888_2_capture_sources, |
9073 | .unsol_event = alc888_fujitsu_xa3530_unsol_event, | 9437 | .unsol_event = alc_automute_amp_unsol_event, |
9074 | .init_hook = alc888_fujitsu_xa3530_automute, | 9438 | .init_hook = alc888_fujitsu_xa3530_init_hook, |
9075 | }, | 9439 | }, |
9076 | [ALC888_LENOVO_SKY] = { | 9440 | [ALC888_LENOVO_SKY] = { |
9077 | .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, | 9441 | .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, |
@@ -9083,8 +9447,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9083 | .channel_mode = alc883_sixstack_modes, | 9447 | .channel_mode = alc883_sixstack_modes, |
9084 | .need_dac_fix = 1, | 9448 | .need_dac_fix = 1, |
9085 | .input_mux = &alc883_lenovo_sky_capture_source, | 9449 | .input_mux = &alc883_lenovo_sky_capture_source, |
9086 | .unsol_event = alc883_lenovo_sky_unsol_event, | 9450 | .unsol_event = alc_automute_amp_unsol_event, |
9087 | .init_hook = alc888_lenovo_sky_front_automute, | 9451 | .init_hook = alc888_lenovo_sky_init_hook, |
9088 | }, | 9452 | }, |
9089 | [ALC888_ASUS_M90V] = { | 9453 | [ALC888_ASUS_M90V] = { |
9090 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 9454 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -9112,7 +9476,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
9112 | .channel_mode = alc883_3ST_2ch_modes, | 9476 | .channel_mode = alc883_3ST_2ch_modes, |
9113 | .need_dac_fix = 1, | 9477 | .need_dac_fix = 1, |
9114 | .input_mux = &alc883_asus_eee1601_capture_source, | 9478 | .input_mux = &alc883_asus_eee1601_capture_source, |
9115 | .unsol_event = alc883_eee1601_unsol_event, | 9479 | .unsol_event = alc_sku_unsol_event, |
9116 | .init_hook = alc883_eee1601_inithook, | 9480 | .init_hook = alc883_eee1601_inithook, |
9117 | }, | 9481 | }, |
9118 | [ALC1200_ASUS_P5Q] = { | 9482 | [ALC1200_ASUS_P5Q] = { |
@@ -9127,6 +9491,32 @@ static struct alc_config_preset alc883_presets[] = { | |||
9127 | .channel_mode = alc883_sixstack_modes, | 9491 | .channel_mode = alc883_sixstack_modes, |
9128 | .input_mux = &alc883_capture_source, | 9492 | .input_mux = &alc883_capture_source, |
9129 | }, | 9493 | }, |
9494 | [ALC889A_MB31] = { | ||
9495 | .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, | ||
9496 | .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, | ||
9497 | alc880_gpio1_init_verbs }, | ||
9498 | .adc_nids = alc883_adc_nids, | ||
9499 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
9500 | .dac_nids = alc883_dac_nids, | ||
9501 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
9502 | .channel_mode = alc889A_mb31_6ch_modes, | ||
9503 | .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes), | ||
9504 | .input_mux = &alc889A_mb31_capture_source, | ||
9505 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
9506 | .unsol_event = alc889A_mb31_unsol_event, | ||
9507 | .init_hook = alc889A_mb31_automute, | ||
9508 | }, | ||
9509 | [ALC883_SONY_VAIO_TT] = { | ||
9510 | .mixers = { alc883_vaiott_mixer }, | ||
9511 | .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs }, | ||
9512 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
9513 | .dac_nids = alc883_dac_nids, | ||
9514 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
9515 | .channel_mode = alc883_3ST_2ch_modes, | ||
9516 | .input_mux = &alc883_capture_source, | ||
9517 | .unsol_event = alc_automute_amp_unsol_event, | ||
9518 | .init_hook = alc883_vaiott_init_hook, | ||
9519 | }, | ||
9130 | }; | 9520 | }; |
9131 | 9521 | ||
9132 | 9522 | ||
@@ -9155,7 +9545,6 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec) | |||
9155 | struct alc_spec *spec = codec->spec; | 9545 | struct alc_spec *spec = codec->spec; |
9156 | int i; | 9546 | int i; |
9157 | 9547 | ||
9158 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
9159 | for (i = 0; i <= HDA_SIDE; i++) { | 9548 | for (i = 0; i <= HDA_SIDE; i++) { |
9160 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 9549 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
9161 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 9550 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -9273,10 +9662,18 @@ static int patch_alc883(struct hda_codec *codec) | |||
9273 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, | 9662 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, |
9274 | alc883_models, | 9663 | alc883_models, |
9275 | alc883_cfg_tbl); | 9664 | alc883_cfg_tbl); |
9276 | if (board_config < 0) { | 9665 | if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { |
9277 | printk(KERN_INFO "hda_codec: Unknown model for ALC883, " | 9666 | /* Pick up systems that don't supply PCI SSID */ |
9278 | "trying auto-probe from BIOS...\n"); | 9667 | switch (codec->subsystem_id) { |
9279 | board_config = ALC883_AUTO; | 9668 | case 0x106b3600: /* Macbook 3.1 */ |
9669 | board_config = ALC889A_MB31; | ||
9670 | break; | ||
9671 | default: | ||
9672 | printk(KERN_INFO | ||
9673 | "hda_codec: Unknown model for %s, trying " | ||
9674 | "auto-probe from BIOS...\n", codec->chip_name); | ||
9675 | board_config = ALC883_AUTO; | ||
9676 | } | ||
9280 | } | 9677 | } |
9281 | 9678 | ||
9282 | if (board_config == ALC883_AUTO) { | 9679 | if (board_config == ALC883_AUTO) { |
@@ -9304,13 +9701,6 @@ static int patch_alc883(struct hda_codec *codec) | |||
9304 | 9701 | ||
9305 | switch (codec->vendor_id) { | 9702 | switch (codec->vendor_id) { |
9306 | case 0x10ec0888: | 9703 | 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) { | 9704 | if (!spec->num_adc_nids) { |
9315 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | 9705 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); |
9316 | spec->adc_nids = alc883_adc_nids; | 9706 | spec->adc_nids = alc883_adc_nids; |
@@ -9318,10 +9708,9 @@ static int patch_alc883(struct hda_codec *codec) | |||
9318 | if (!spec->capsrc_nids) | 9708 | if (!spec->capsrc_nids) |
9319 | spec->capsrc_nids = alc883_capsrc_nids; | 9709 | spec->capsrc_nids = alc883_capsrc_nids; |
9320 | spec->capture_style = CAPT_MIX; /* matrix-style capture */ | 9710 | spec->capture_style = CAPT_MIX; /* matrix-style capture */ |
9711 | spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ | ||
9321 | break; | 9712 | break; |
9322 | case 0x10ec0889: | 9713 | case 0x10ec0889: |
9323 | spec->stream_name_analog = "ALC889 Analog"; | ||
9324 | spec->stream_name_digital = "ALC889 Digital"; | ||
9325 | if (!spec->num_adc_nids) { | 9714 | if (!spec->num_adc_nids) { |
9326 | spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids); | 9715 | spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids); |
9327 | spec->adc_nids = alc889_adc_nids; | 9716 | spec->adc_nids = alc889_adc_nids; |
@@ -9332,8 +9721,6 @@ static int patch_alc883(struct hda_codec *codec) | |||
9332 | capture */ | 9721 | capture */ |
9333 | break; | 9722 | break; |
9334 | default: | 9723 | default: |
9335 | spec->stream_name_analog = "ALC883 Analog"; | ||
9336 | spec->stream_name_digital = "ALC883 Digital"; | ||
9337 | if (!spec->num_adc_nids) { | 9724 | if (!spec->num_adc_nids) { |
9338 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | 9725 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); |
9339 | spec->adc_nids = alc883_adc_nids; | 9726 | spec->adc_nids = alc883_adc_nids; |
@@ -9413,24 +9800,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { | |||
9413 | { } /* end */ | 9800 | { } /* end */ |
9414 | }; | 9801 | }; |
9415 | 9802 | ||
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 */ | 9803 | /* update HP, line and mono-out pins according to the master switch */ |
9435 | static void alc262_hp_master_update(struct hda_codec *codec) | 9804 | static void alc262_hp_master_update(struct hda_codec *codec) |
9436 | { | 9805 | { |
@@ -9486,14 +9855,7 @@ static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, | |||
9486 | alc262_hp_wildwest_automute(codec); | 9855 | alc262_hp_wildwest_automute(codec); |
9487 | } | 9856 | } |
9488 | 9857 | ||
9489 | static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol, | 9858 | #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 | 9859 | ||
9498 | static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, | 9860 | static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, |
9499 | struct snd_ctl_elem_value *ucontrol) | 9861 | struct snd_ctl_elem_value *ucontrol) |
@@ -9509,14 +9871,17 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
9509 | return 1; | 9871 | return 1; |
9510 | } | 9872 | } |
9511 | 9873 | ||
9874 | #define ALC262_HP_MASTER_SWITCH \ | ||
9875 | { \ | ||
9876 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
9877 | .name = "Master Playback Switch", \ | ||
9878 | .info = snd_ctl_boolean_mono_info, \ | ||
9879 | .get = alc262_hp_master_sw_get, \ | ||
9880 | .put = alc262_hp_master_sw_put, \ | ||
9881 | } | ||
9882 | |||
9512 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | 9883 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { |
9513 | { | 9884 | 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), | 9885 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9521 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 9886 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
9522 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 9887 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
@@ -9540,13 +9905,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | |||
9540 | }; | 9905 | }; |
9541 | 9906 | ||
9542 | static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { | 9907 | static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { |
9543 | { | 9908 | 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), | 9909 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9551 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 9910 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
9552 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 9911 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -9573,32 +9932,13 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { | |||
9573 | }; | 9932 | }; |
9574 | 9933 | ||
9575 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 9934 | /* 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) | 9935 | static void alc262_hp_t5735_init_hook(struct hda_codec *codec) |
9577 | { | 9936 | { |
9578 | struct alc_spec *spec = codec->spec; | 9937 | struct alc_spec *spec = codec->spec; |
9579 | 9938 | ||
9580 | if (force || !spec->sense_updated) { | 9939 | spec->autocfg.hp_pins[0] = 0x15; |
9581 | unsigned int present; | 9940 | spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */ |
9582 | present = snd_hda_codec_read(codec, 0x15, 0, | 9941 | 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 | } | 9942 | } |
9603 | 9943 | ||
9604 | static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { | 9944 | static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { |
@@ -9651,46 +9991,132 @@ static struct hda_input_mux alc262_hp_rp5700_capture_source = { | |||
9651 | }, | 9991 | }, |
9652 | }; | 9992 | }; |
9653 | 9993 | ||
9654 | /* bind hp and internal speaker mute (with plug check) */ | 9994 | /* bind hp and internal speaker mute (with plug check) as master switch */ |
9655 | static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol, | 9995 | static void alc262_hippo_master_update(struct hda_codec *codec) |
9656 | struct snd_ctl_elem_value *ucontrol) | ||
9657 | { | 9996 | { |
9658 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 9997 | struct alc_spec *spec = codec->spec; |
9659 | long *valp = ucontrol->value.integer.value; | 9998 | hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; |
9660 | int change; | 9999 | hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; |
10000 | hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; | ||
10001 | unsigned int mute; | ||
9661 | 10002 | ||
9662 | /* change hp mute */ | 10003 | /* HP */ |
9663 | change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | 10004 | mute = spec->master_sw ? 0 : HDA_AMP_MUTE; |
9664 | HDA_AMP_MUTE, | 10005 | snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, |
9665 | valp[0] ? 0 : HDA_AMP_MUTE); | 10006 | HDA_AMP_MUTE, mute); |
9666 | change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | 10007 | /* mute internal speaker per jack sense */ |
9667 | HDA_AMP_MUTE, | 10008 | if (spec->jack_present) |
9668 | valp[1] ? 0 : HDA_AMP_MUTE); | 10009 | mute = HDA_AMP_MUTE; |
9669 | if (change) { | 10010 | if (line_nid) |
9670 | /* change speaker according to HP jack state */ | 10011 | snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, |
9671 | struct alc_spec *spec = codec->spec; | ||
9672 | unsigned int mute; | ||
9673 | if (spec->jack_present) | ||
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); | 10012 | HDA_AMP_MUTE, mute); |
10013 | if (speaker_nid && speaker_nid != line_nid) | ||
10014 | snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, | ||
10015 | HDA_AMP_MUTE, mute); | ||
10016 | } | ||
10017 | |||
10018 | #define alc262_hippo_master_sw_get alc262_hp_master_sw_get | ||
10019 | |||
10020 | static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, | ||
10021 | struct snd_ctl_elem_value *ucontrol) | ||
10022 | { | ||
10023 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
10024 | struct alc_spec *spec = codec->spec; | ||
10025 | int val = !!*ucontrol->value.integer.value; | ||
10026 | |||
10027 | if (val == spec->master_sw) | ||
10028 | return 0; | ||
10029 | spec->master_sw = val; | ||
10030 | alc262_hippo_master_update(codec); | ||
10031 | return 1; | ||
10032 | } | ||
10033 | |||
10034 | #define ALC262_HIPPO_MASTER_SWITCH \ | ||
10035 | { \ | ||
10036 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
10037 | .name = "Master Playback Switch", \ | ||
10038 | .info = snd_ctl_boolean_mono_info, \ | ||
10039 | .get = alc262_hippo_master_sw_get, \ | ||
10040 | .put = alc262_hippo_master_sw_put, \ | ||
9680 | } | 10041 | } |
9681 | return change; | 10042 | |
10043 | static struct snd_kcontrol_new alc262_hippo_mixer[] = { | ||
10044 | ALC262_HIPPO_MASTER_SWITCH, | ||
10045 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
10046 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
10047 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
10048 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
10049 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
10050 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
10051 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
10052 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
10053 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
10054 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
10055 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
10056 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
10057 | { } /* end */ | ||
10058 | }; | ||
10059 | |||
10060 | static struct snd_kcontrol_new alc262_hippo1_mixer[] = { | ||
10061 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
10062 | ALC262_HIPPO_MASTER_SWITCH, | ||
10063 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
10064 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
10065 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
10066 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
10067 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
10068 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
10069 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
10070 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
10071 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
10072 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
10073 | { } /* end */ | ||
10074 | }; | ||
10075 | |||
10076 | /* mute/unmute internal speaker according to the hp jack and mute state */ | ||
10077 | static void alc262_hippo_automute(struct hda_codec *codec) | ||
10078 | { | ||
10079 | struct alc_spec *spec = codec->spec; | ||
10080 | hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; | ||
10081 | unsigned int present; | ||
10082 | |||
10083 | /* need to execute and sync at first */ | ||
10084 | snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
10085 | present = snd_hda_codec_read(codec, hp_nid, 0, | ||
10086 | AC_VERB_GET_PIN_SENSE, 0); | ||
10087 | spec->jack_present = (present & 0x80000000) != 0; | ||
10088 | alc262_hippo_master_update(codec); | ||
10089 | } | ||
10090 | |||
10091 | static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) | ||
10092 | { | ||
10093 | if ((res >> 26) != ALC880_HP_EVENT) | ||
10094 | return; | ||
10095 | alc262_hippo_automute(codec); | ||
10096 | } | ||
10097 | |||
10098 | static void alc262_hippo_init_hook(struct hda_codec *codec) | ||
10099 | { | ||
10100 | struct alc_spec *spec = codec->spec; | ||
10101 | |||
10102 | spec->autocfg.hp_pins[0] = 0x15; | ||
10103 | spec->autocfg.speaker_pins[0] = 0x14; | ||
10104 | alc262_hippo_automute(codec); | ||
10105 | } | ||
10106 | |||
10107 | static void alc262_hippo1_init_hook(struct hda_codec *codec) | ||
10108 | { | ||
10109 | struct alc_spec *spec = codec->spec; | ||
10110 | |||
10111 | spec->autocfg.hp_pins[0] = 0x1b; | ||
10112 | spec->autocfg.speaker_pins[0] = 0x14; | ||
10113 | alc262_hippo_automute(codec); | ||
9682 | } | 10114 | } |
9683 | 10115 | ||
10116 | |||
9684 | static struct snd_kcontrol_new alc262_sony_mixer[] = { | 10117 | static struct snd_kcontrol_new alc262_sony_mixer[] = { |
9685 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 10118 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9686 | { | 10119 | 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), | 10120 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
9695 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 10121 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
9696 | HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | 10122 | HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), |
@@ -9699,8 +10125,8 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = { | |||
9699 | }; | 10125 | }; |
9700 | 10126 | ||
9701 | static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { | 10127 | static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { |
9702 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 10128 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9703 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 10129 | ALC262_HIPPO_MASTER_SWITCH, |
9704 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 10130 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
9705 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 10131 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
9706 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 10132 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
@@ -9741,34 +10167,15 @@ static struct hda_verb alc262_tyan_verbs[] = { | |||
9741 | }; | 10167 | }; |
9742 | 10168 | ||
9743 | /* unsolicited event for HP jack sensing */ | 10169 | /* unsolicited event for HP jack sensing */ |
9744 | static void alc262_tyan_automute(struct hda_codec *codec) | 10170 | static void alc262_tyan_init_hook(struct hda_codec *codec) |
9745 | { | 10171 | { |
9746 | unsigned int mute; | 10172 | struct alc_spec *spec = codec->spec; |
9747 | unsigned int present; | ||
9748 | 10173 | ||
9749 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | 10174 | spec->autocfg.hp_pins[0] = 0x1b; |
9750 | present = snd_hda_codec_read(codec, 0x1b, 0, | 10175 | spec->autocfg.speaker_pins[0] = 0x15; |
9751 | AC_VERB_GET_PIN_SENSE, 0); | 10176 | 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 | } | 10177 | } |
9764 | 10178 | ||
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 | 10179 | ||
9773 | #define alc262_capture_mixer alc882_capture_mixer | 10180 | #define alc262_capture_mixer alc882_capture_mixer |
9774 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer | 10181 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer |
@@ -9923,99 +10330,25 @@ static void alc262_dmic_automute(struct hda_codec *codec) | |||
9923 | AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09); | 10330 | AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09); |
9924 | } | 10331 | } |
9925 | 10332 | ||
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 | 10333 | ||
9941 | /* unsolicited event for HP jack sensing */ | 10334 | /* unsolicited event for HP jack sensing */ |
9942 | static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec, | 10335 | static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec, |
9943 | unsigned int res) | 10336 | unsigned int res) |
9944 | { | 10337 | { |
9945 | if ((res >> 26) == ALC880_HP_EVENT) | ||
9946 | alc262_toshiba_s06_speaker_automute(codec); | ||
9947 | if ((res >> 26) == ALC880_MIC_EVENT) | 10338 | if ((res >> 26) == ALC880_MIC_EVENT) |
9948 | alc262_dmic_automute(codec); | 10339 | alc262_dmic_automute(codec); |
9949 | 10340 | else | |
10341 | alc_sku_unsol_event(codec, res); | ||
9950 | } | 10342 | } |
9951 | 10343 | ||
9952 | static void alc262_toshiba_s06_init_hook(struct hda_codec *codec) | 10344 | static void alc262_toshiba_s06_init_hook(struct hda_codec *codec) |
9953 | { | 10345 | { |
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; | 10346 | 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 | 10347 | ||
9996 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | 10348 | spec->autocfg.hp_pins[0] = 0x15; |
9997 | present = snd_hda_codec_read(codec, 0x1b, 0, | 10349 | spec->autocfg.speaker_pins[0] = 0x14; |
9998 | AC_VERB_GET_PIN_SENSE, 0); | 10350 | alc_automute_pin(codec); |
9999 | present = (present & 0x80000000) != 0; | 10351 | alc262_dmic_automute(codec); |
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 | |||
10012 | /* unsolicited event for HP jack sensing */ | ||
10013 | static void alc262_hippo1_unsol_event(struct hda_codec *codec, | ||
10014 | unsigned int res) | ||
10015 | { | ||
10016 | if ((res >> 26) != ALC880_HP_EVENT) | ||
10017 | return; | ||
10018 | alc262_hippo1_automute(codec); | ||
10019 | } | 10352 | } |
10020 | 10353 | ||
10021 | /* | 10354 | /* |
@@ -10285,14 +10618,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { | |||
10285 | 10618 | ||
10286 | static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { | 10619 | static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { |
10287 | HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), | 10620 | HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), |
10288 | { | 10621 | 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), | 10622 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
10297 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 10623 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
10298 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | 10624 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), |
@@ -10639,31 +10965,46 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { | |||
10639 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | 10965 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, |
10640 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | 10966 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, |
10641 | 10967 | ||
10642 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, | 10968 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, |
10643 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | 10969 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, |
10644 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | 10970 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, |
10645 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, | 10971 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, |
10646 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | 10972 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, |
10647 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | 10973 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, |
10648 | 10974 | ||
10649 | 10975 | ||
10650 | /* FIXME: use matrix-type input source selection */ | 10976 | /* FIXME: use matrix-type input source selection */ |
10651 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | 10977 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */ |
10652 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | 10978 | /* Input mixer1: only unmute Mic */ |
10653 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | 10979 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, |
10654 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | 10980 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, |
10655 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | 10981 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, |
10656 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | 10982 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, |
10983 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, | ||
10984 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, | ||
10985 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, | ||
10986 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, | ||
10987 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, | ||
10657 | /* Input mixer2 */ | 10988 | /* Input mixer2 */ |
10658 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | 10989 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, |
10659 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | 10990 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, |
10660 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | 10991 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, |
10661 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | 10992 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, |
10993 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, | ||
10994 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, | ||
10995 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, | ||
10996 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, | ||
10997 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, | ||
10662 | /* Input mixer3 */ | 10998 | /* Input mixer3 */ |
10663 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | 10999 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, |
10664 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | 11000 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, |
10665 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | 11001 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, |
10666 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | 11002 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, |
11003 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, | ||
11004 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, | ||
11005 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, | ||
11006 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, | ||
11007 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, | ||
10667 | 11008 | ||
10668 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 11009 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
10669 | 11010 | ||
@@ -10843,6 +11184,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
10843 | if (err < 0) | 11184 | if (err < 0) |
10844 | return err; | 11185 | return err; |
10845 | 11186 | ||
11187 | alc_ssid_check(codec, 0x15, 0x14, 0x1b); | ||
11188 | |||
10846 | return 1; | 11189 | return 1; |
10847 | } | 11190 | } |
10848 | 11191 | ||
@@ -10945,7 +11288,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
10945 | .input_mux = &alc262_capture_source, | 11288 | .input_mux = &alc262_capture_source, |
10946 | }, | 11289 | }, |
10947 | [ALC262_HIPPO] = { | 11290 | [ALC262_HIPPO] = { |
10948 | .mixers = { alc262_base_mixer }, | 11291 | .mixers = { alc262_hippo_mixer }, |
10949 | .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, | 11292 | .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, |
10950 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | 11293 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), |
10951 | .dac_nids = alc262_dac_nids, | 11294 | .dac_nids = alc262_dac_nids, |
@@ -10955,7 +11298,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
10955 | .channel_mode = alc262_modes, | 11298 | .channel_mode = alc262_modes, |
10956 | .input_mux = &alc262_capture_source, | 11299 | .input_mux = &alc262_capture_source, |
10957 | .unsol_event = alc262_hippo_unsol_event, | 11300 | .unsol_event = alc262_hippo_unsol_event, |
10958 | .init_hook = alc262_hippo_automute, | 11301 | .init_hook = alc262_hippo_init_hook, |
10959 | }, | 11302 | }, |
10960 | [ALC262_HIPPO_1] = { | 11303 | [ALC262_HIPPO_1] = { |
10961 | .mixers = { alc262_hippo1_mixer }, | 11304 | .mixers = { alc262_hippo1_mixer }, |
@@ -10967,8 +11310,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
10967 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 11310 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
10968 | .channel_mode = alc262_modes, | 11311 | .channel_mode = alc262_modes, |
10969 | .input_mux = &alc262_capture_source, | 11312 | .input_mux = &alc262_capture_source, |
10970 | .unsol_event = alc262_hippo1_unsol_event, | 11313 | .unsol_event = alc262_hippo_unsol_event, |
10971 | .init_hook = alc262_hippo1_automute, | 11314 | .init_hook = alc262_hippo1_init_hook, |
10972 | }, | 11315 | }, |
10973 | [ALC262_FUJITSU] = { | 11316 | [ALC262_FUJITSU] = { |
10974 | .mixers = { alc262_fujitsu_mixer }, | 11317 | .mixers = { alc262_fujitsu_mixer }, |
@@ -11030,7 +11373,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
11030 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 11373 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
11031 | .channel_mode = alc262_modes, | 11374 | .channel_mode = alc262_modes, |
11032 | .input_mux = &alc262_capture_source, | 11375 | .input_mux = &alc262_capture_source, |
11033 | .unsol_event = alc262_hp_t5735_unsol_event, | 11376 | .unsol_event = alc_automute_amp_unsol_event, |
11034 | .init_hook = alc262_hp_t5735_init_hook, | 11377 | .init_hook = alc262_hp_t5735_init_hook, |
11035 | }, | 11378 | }, |
11036 | [ALC262_HP_RP5700] = { | 11379 | [ALC262_HP_RP5700] = { |
@@ -11062,7 +11405,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
11062 | .channel_mode = alc262_modes, | 11405 | .channel_mode = alc262_modes, |
11063 | .input_mux = &alc262_capture_source, | 11406 | .input_mux = &alc262_capture_source, |
11064 | .unsol_event = alc262_hippo_unsol_event, | 11407 | .unsol_event = alc262_hippo_unsol_event, |
11065 | .init_hook = alc262_hippo_automute, | 11408 | .init_hook = alc262_hippo_init_hook, |
11066 | }, | 11409 | }, |
11067 | [ALC262_BENQ_T31] = { | 11410 | [ALC262_BENQ_T31] = { |
11068 | .mixers = { alc262_benq_t31_mixer }, | 11411 | .mixers = { alc262_benq_t31_mixer }, |
@@ -11074,7 +11417,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
11074 | .channel_mode = alc262_modes, | 11417 | .channel_mode = alc262_modes, |
11075 | .input_mux = &alc262_capture_source, | 11418 | .input_mux = &alc262_capture_source, |
11076 | .unsol_event = alc262_hippo_unsol_event, | 11419 | .unsol_event = alc262_hippo_unsol_event, |
11077 | .init_hook = alc262_hippo_automute, | 11420 | .init_hook = alc262_hippo_init_hook, |
11078 | }, | 11421 | }, |
11079 | [ALC262_ULTRA] = { | 11422 | [ALC262_ULTRA] = { |
11080 | .mixers = { alc262_ultra_mixer }, | 11423 | .mixers = { alc262_ultra_mixer }, |
@@ -11139,7 +11482,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
11139 | .channel_mode = alc262_modes, | 11482 | .channel_mode = alc262_modes, |
11140 | .input_mux = &alc262_capture_source, | 11483 | .input_mux = &alc262_capture_source, |
11141 | .unsol_event = alc262_hippo_unsol_event, | 11484 | .unsol_event = alc262_hippo_unsol_event, |
11142 | .init_hook = alc262_hippo_automute, | 11485 | .init_hook = alc262_hippo_init_hook, |
11143 | }, | 11486 | }, |
11144 | [ALC262_TYAN] = { | 11487 | [ALC262_TYAN] = { |
11145 | .mixers = { alc262_tyan_mixer }, | 11488 | .mixers = { alc262_tyan_mixer }, |
@@ -11151,8 +11494,8 @@ static struct alc_config_preset alc262_presets[] = { | |||
11151 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 11494 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
11152 | .channel_mode = alc262_modes, | 11495 | .channel_mode = alc262_modes, |
11153 | .input_mux = &alc262_capture_source, | 11496 | .input_mux = &alc262_capture_source, |
11154 | .unsol_event = alc262_tyan_unsol_event, | 11497 | .unsol_event = alc_automute_amp_unsol_event, |
11155 | .init_hook = alc262_tyan_automute, | 11498 | .init_hook = alc262_tyan_init_hook, |
11156 | }, | 11499 | }, |
11157 | }; | 11500 | }; |
11158 | 11501 | ||
@@ -11187,8 +11530,8 @@ static int patch_alc262(struct hda_codec *codec) | |||
11187 | alc262_cfg_tbl); | 11530 | alc262_cfg_tbl); |
11188 | 11531 | ||
11189 | if (board_config < 0) { | 11532 | if (board_config < 0) { |
11190 | printk(KERN_INFO "hda_codec: Unknown model for ALC262, " | 11533 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
11191 | "trying auto-probe from BIOS...\n"); | 11534 | "trying auto-probe from BIOS...\n", codec->chip_name); |
11192 | board_config = ALC262_AUTO; | 11535 | board_config = ALC262_AUTO; |
11193 | } | 11536 | } |
11194 | 11537 | ||
@@ -11217,11 +11560,9 @@ static int patch_alc262(struct hda_codec *codec) | |||
11217 | if (board_config != ALC262_AUTO) | 11560 | if (board_config != ALC262_AUTO) |
11218 | setup_preset(spec, &alc262_presets[board_config]); | 11561 | setup_preset(spec, &alc262_presets[board_config]); |
11219 | 11562 | ||
11220 | spec->stream_name_analog = "ALC262 Analog"; | ||
11221 | spec->stream_analog_playback = &alc262_pcm_analog_playback; | 11563 | spec->stream_analog_playback = &alc262_pcm_analog_playback; |
11222 | spec->stream_analog_capture = &alc262_pcm_analog_capture; | 11564 | spec->stream_analog_capture = &alc262_pcm_analog_capture; |
11223 | 11565 | ||
11224 | spec->stream_name_digital = "ALC262 Digital"; | ||
11225 | spec->stream_digital_playback = &alc262_pcm_digital_playback; | 11566 | spec->stream_digital_playback = &alc262_pcm_digital_playback; |
11226 | spec->stream_digital_capture = &alc262_pcm_digital_capture; | 11567 | spec->stream_digital_capture = &alc262_pcm_digital_capture; |
11227 | 11568 | ||
@@ -11296,6 +11637,17 @@ static struct snd_kcontrol_new alc268_base_mixer[] = { | |||
11296 | { } | 11637 | { } |
11297 | }; | 11638 | }; |
11298 | 11639 | ||
11640 | static struct snd_kcontrol_new alc268_toshiba_mixer[] = { | ||
11641 | /* output mixer control */ | ||
11642 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
11643 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), | ||
11644 | ALC262_HIPPO_MASTER_SWITCH, | ||
11645 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
11646 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
11647 | HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), | ||
11648 | { } | ||
11649 | }; | ||
11650 | |||
11299 | /* bind Beep switches of both NID 0x0f and 0x10 */ | 11651 | /* bind Beep switches of both NID 0x0f and 0x10 */ |
11300 | static struct hda_bind_ctls alc268_bind_beep_sw = { | 11652 | static struct hda_bind_ctls alc268_bind_beep_sw = { |
11301 | .ops = &snd_hda_bind_sw, | 11653 | .ops = &snd_hda_bind_sw, |
@@ -11319,8 +11671,6 @@ static struct hda_verb alc268_eapd_verbs[] = { | |||
11319 | }; | 11671 | }; |
11320 | 11672 | ||
11321 | /* Toshiba specific */ | 11673 | /* Toshiba specific */ |
11322 | #define alc268_toshiba_automute alc262_hippo_automute | ||
11323 | |||
11324 | static struct hda_verb alc268_toshiba_verbs[] = { | 11674 | static struct hda_verb alc268_toshiba_verbs[] = { |
11325 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 11675 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
11326 | { } /* end */ | 11676 | { } /* end */ |
@@ -11456,13 +11806,8 @@ static struct hda_verb alc268_acer_verbs[] = { | |||
11456 | }; | 11806 | }; |
11457 | 11807 | ||
11458 | /* unsolicited event for HP jack sensing */ | 11808 | /* unsolicited event for HP jack sensing */ |
11459 | static void alc268_toshiba_unsol_event(struct hda_codec *codec, | 11809 | #define alc268_toshiba_unsol_event alc262_hippo_unsol_event |
11460 | unsigned int res) | 11810 | #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 | 11811 | ||
11467 | static void alc268_acer_unsol_event(struct hda_codec *codec, | 11812 | static void alc268_acer_unsol_event(struct hda_codec *codec, |
11468 | unsigned int res) | 11813 | unsigned int res) |
@@ -11537,30 +11882,15 @@ static struct hda_verb alc268_dell_verbs[] = { | |||
11537 | }; | 11882 | }; |
11538 | 11883 | ||
11539 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 11884 | /* mute/unmute internal speaker according to the hp jack and mute state */ |
11540 | static void alc268_dell_automute(struct hda_codec *codec) | 11885 | static void alc268_dell_init_hook(struct hda_codec *codec) |
11541 | { | 11886 | { |
11542 | unsigned int present; | 11887 | 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 | 11888 | ||
11554 | static void alc268_dell_unsol_event(struct hda_codec *codec, | 11889 | spec->autocfg.hp_pins[0] = 0x15; |
11555 | unsigned int res) | 11890 | spec->autocfg.speaker_pins[0] = 0x14; |
11556 | { | 11891 | alc_automute_pin(codec); |
11557 | if ((res >> 26) != ALC880_HP_EVENT) | ||
11558 | return; | ||
11559 | alc268_dell_automute(codec); | ||
11560 | } | 11892 | } |
11561 | 11893 | ||
11562 | #define alc268_dell_init_hook alc268_dell_automute | ||
11563 | |||
11564 | static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { | 11894 | static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { |
11565 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), | 11895 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), |
11566 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 11896 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -11579,16 +11909,6 @@ static struct hda_verb alc267_quanta_il1_verbs[] = { | |||
11579 | { } | 11909 | { } |
11580 | }; | 11910 | }; |
11581 | 11911 | ||
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) | 11912 | static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) |
11593 | { | 11913 | { |
11594 | unsigned int present; | 11914 | unsigned int present; |
@@ -11600,9 +11920,13 @@ static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) | |||
11600 | present ? 0x00 : 0x01); | 11920 | present ? 0x00 : 0x01); |
11601 | } | 11921 | } |
11602 | 11922 | ||
11603 | static void alc267_quanta_il1_automute(struct hda_codec *codec) | 11923 | static void alc267_quanta_il1_init_hook(struct hda_codec *codec) |
11604 | { | 11924 | { |
11605 | alc267_quanta_il1_hp_automute(codec); | 11925 | struct alc_spec *spec = codec->spec; |
11926 | |||
11927 | spec->autocfg.hp_pins[0] = 0x15; | ||
11928 | spec->autocfg.speaker_pins[0] = 0x14; | ||
11929 | alc_automute_pin(codec); | ||
11606 | alc267_quanta_il1_mic_automute(codec); | 11930 | alc267_quanta_il1_mic_automute(codec); |
11607 | } | 11931 | } |
11608 | 11932 | ||
@@ -11610,12 +11934,12 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec, | |||
11610 | unsigned int res) | 11934 | unsigned int res) |
11611 | { | 11935 | { |
11612 | switch (res >> 26) { | 11936 | switch (res >> 26) { |
11613 | case ALC880_HP_EVENT: | ||
11614 | alc267_quanta_il1_hp_automute(codec); | ||
11615 | break; | ||
11616 | case ALC880_MIC_EVENT: | 11937 | case ALC880_MIC_EVENT: |
11617 | alc267_quanta_il1_mic_automute(codec); | 11938 | alc267_quanta_il1_mic_automute(codec); |
11618 | break; | 11939 | break; |
11940 | default: | ||
11941 | alc_sku_unsol_event(codec, res); | ||
11942 | break; | ||
11619 | } | 11943 | } |
11620 | } | 11944 | } |
11621 | 11945 | ||
@@ -12063,16 +12387,16 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { | |||
12063 | ALC268_ACER_ASPIRE_ONE), | 12387 | ALC268_ACER_ASPIRE_ONE), |
12064 | SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), | 12388 | SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), |
12065 | SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), | 12389 | SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), |
12066 | SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), | 12390 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series", |
12067 | SND_PCI_QUIRK(0x103c, 0x30f1, "HP TX25xx series", ALC268_TOSHIBA), | 12391 | ALC268_TOSHIBA), |
12068 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), | 12392 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), |
12069 | SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), | 12393 | SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), |
12070 | SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), | 12394 | SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", |
12071 | SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA), | 12395 | ALC268_TOSHIBA), |
12072 | SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), | 12396 | SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), |
12073 | SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), | 12397 | SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), |
12074 | SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), | 12398 | SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), |
12075 | SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), | 12399 | SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL), |
12076 | {} | 12400 | {} |
12077 | }; | 12401 | }; |
12078 | 12402 | ||
@@ -12090,7 +12414,7 @@ static struct alc_config_preset alc268_presets[] = { | |||
12090 | .channel_mode = alc268_modes, | 12414 | .channel_mode = alc268_modes, |
12091 | .input_mux = &alc268_capture_source, | 12415 | .input_mux = &alc268_capture_source, |
12092 | .unsol_event = alc267_quanta_il1_unsol_event, | 12416 | .unsol_event = alc267_quanta_il1_unsol_event, |
12093 | .init_hook = alc267_quanta_il1_automute, | 12417 | .init_hook = alc267_quanta_il1_init_hook, |
12094 | }, | 12418 | }, |
12095 | [ALC268_3ST] = { | 12419 | [ALC268_3ST] = { |
12096 | .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, | 12420 | .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, |
@@ -12108,7 +12432,7 @@ static struct alc_config_preset alc268_presets[] = { | |||
12108 | .input_mux = &alc268_capture_source, | 12432 | .input_mux = &alc268_capture_source, |
12109 | }, | 12433 | }, |
12110 | [ALC268_TOSHIBA] = { | 12434 | [ALC268_TOSHIBA] = { |
12111 | .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, | 12435 | .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer, |
12112 | alc268_beep_mixer }, | 12436 | alc268_beep_mixer }, |
12113 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | 12437 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, |
12114 | alc268_toshiba_verbs }, | 12438 | alc268_toshiba_verbs }, |
@@ -12122,7 +12446,7 @@ static struct alc_config_preset alc268_presets[] = { | |||
12122 | .channel_mode = alc268_modes, | 12446 | .channel_mode = alc268_modes, |
12123 | .input_mux = &alc268_capture_source, | 12447 | .input_mux = &alc268_capture_source, |
12124 | .unsol_event = alc268_toshiba_unsol_event, | 12448 | .unsol_event = alc268_toshiba_unsol_event, |
12125 | .init_hook = alc268_toshiba_automute, | 12449 | .init_hook = alc268_toshiba_init_hook, |
12126 | }, | 12450 | }, |
12127 | [ALC268_ACER] = { | 12451 | [ALC268_ACER] = { |
12128 | .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, | 12452 | .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, |
@@ -12185,7 +12509,7 @@ static struct alc_config_preset alc268_presets[] = { | |||
12185 | .hp_nid = 0x02, | 12509 | .hp_nid = 0x02, |
12186 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 12510 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
12187 | .channel_mode = alc268_modes, | 12511 | .channel_mode = alc268_modes, |
12188 | .unsol_event = alc268_dell_unsol_event, | 12512 | .unsol_event = alc_sku_unsol_event, |
12189 | .init_hook = alc268_dell_init_hook, | 12513 | .init_hook = alc268_dell_init_hook, |
12190 | .input_mux = &alc268_capture_source, | 12514 | .input_mux = &alc268_capture_source, |
12191 | }, | 12515 | }, |
@@ -12205,7 +12529,7 @@ static struct alc_config_preset alc268_presets[] = { | |||
12205 | .channel_mode = alc268_modes, | 12529 | .channel_mode = alc268_modes, |
12206 | .input_mux = &alc268_capture_source, | 12530 | .input_mux = &alc268_capture_source, |
12207 | .unsol_event = alc268_toshiba_unsol_event, | 12531 | .unsol_event = alc268_toshiba_unsol_event, |
12208 | .init_hook = alc268_toshiba_automute | 12532 | .init_hook = alc268_toshiba_init_hook |
12209 | }, | 12533 | }, |
12210 | #ifdef CONFIG_SND_DEBUG | 12534 | #ifdef CONFIG_SND_DEBUG |
12211 | [ALC268_TEST] = { | 12535 | [ALC268_TEST] = { |
@@ -12243,8 +12567,8 @@ static int patch_alc268(struct hda_codec *codec) | |||
12243 | alc268_cfg_tbl); | 12567 | alc268_cfg_tbl); |
12244 | 12568 | ||
12245 | if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { | 12569 | if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { |
12246 | printk(KERN_INFO "hda_codec: Unknown model for ALC268, " | 12570 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
12247 | "trying auto-probe from BIOS...\n"); | 12571 | "trying auto-probe from BIOS...\n", codec->chip_name); |
12248 | board_config = ALC268_AUTO; | 12572 | board_config = ALC268_AUTO; |
12249 | } | 12573 | } |
12250 | 12574 | ||
@@ -12265,14 +12589,6 @@ static int patch_alc268(struct hda_codec *codec) | |||
12265 | if (board_config != ALC268_AUTO) | 12589 | if (board_config != ALC268_AUTO) |
12266 | setup_preset(spec, &alc268_presets[board_config]); | 12590 | setup_preset(spec, &alc268_presets[board_config]); |
12267 | 12591 | ||
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; | 12592 | spec->stream_analog_playback = &alc268_pcm_analog_playback; |
12277 | spec->stream_analog_capture = &alc268_pcm_analog_capture; | 12593 | spec->stream_analog_capture = &alc268_pcm_analog_capture; |
12278 | spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; | 12594 | spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; |
@@ -13099,8 +13415,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
13099 | alc269_cfg_tbl); | 13415 | alc269_cfg_tbl); |
13100 | 13416 | ||
13101 | if (board_config < 0) { | 13417 | if (board_config < 0) { |
13102 | printk(KERN_INFO "hda_codec: Unknown model for ALC269, " | 13418 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
13103 | "trying auto-probe from BIOS...\n"); | 13419 | "trying auto-probe from BIOS...\n", codec->chip_name); |
13104 | board_config = ALC269_AUTO; | 13420 | board_config = ALC269_AUTO; |
13105 | } | 13421 | } |
13106 | 13422 | ||
@@ -13127,7 +13443,6 @@ static int patch_alc269(struct hda_codec *codec) | |||
13127 | if (board_config != ALC269_AUTO) | 13443 | if (board_config != ALC269_AUTO) |
13128 | setup_preset(spec, &alc269_presets[board_config]); | 13444 | setup_preset(spec, &alc269_presets[board_config]); |
13129 | 13445 | ||
13130 | spec->stream_name_analog = "ALC269 Analog"; | ||
13131 | if (codec->subsystem_id == 0x17aa3bf8) { | 13446 | if (codec->subsystem_id == 0x17aa3bf8) { |
13132 | /* Due to a hardware problem on Lenovo Ideadpad, we need to | 13447 | /* Due to a hardware problem on Lenovo Ideadpad, we need to |
13133 | * fix the sample rate of analog I/O to 44.1kHz | 13448 | * fix the sample rate of analog I/O to 44.1kHz |
@@ -13138,7 +13453,6 @@ static int patch_alc269(struct hda_codec *codec) | |||
13138 | spec->stream_analog_playback = &alc269_pcm_analog_playback; | 13453 | spec->stream_analog_playback = &alc269_pcm_analog_playback; |
13139 | spec->stream_analog_capture = &alc269_pcm_analog_capture; | 13454 | spec->stream_analog_capture = &alc269_pcm_analog_capture; |
13140 | } | 13455 | } |
13141 | spec->stream_name_digital = "ALC269 Digital"; | ||
13142 | spec->stream_digital_playback = &alc269_pcm_digital_playback; | 13456 | spec->stream_digital_playback = &alc269_pcm_digital_playback; |
13143 | spec->stream_digital_capture = &alc269_pcm_digital_capture; | 13457 | spec->stream_digital_capture = &alc269_pcm_digital_capture; |
13144 | 13458 | ||
@@ -13927,7 +14241,6 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec) | |||
13927 | struct alc_spec *spec = codec->spec; | 14241 | struct alc_spec *spec = codec->spec; |
13928 | int i; | 14242 | int i; |
13929 | 14243 | ||
13930 | alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); | ||
13931 | for (i = 0; i < spec->autocfg.line_outs; i++) { | 14244 | for (i = 0; i < spec->autocfg.line_outs; i++) { |
13932 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 14245 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
13933 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 14246 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -14010,6 +14323,8 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
14010 | spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); | 14323 | spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); |
14011 | set_capture_mixer(spec); | 14324 | set_capture_mixer(spec); |
14012 | 14325 | ||
14326 | alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); | ||
14327 | |||
14013 | return 1; | 14328 | return 1; |
14014 | } | 14329 | } |
14015 | 14330 | ||
@@ -14199,8 +14514,8 @@ static int patch_alc861(struct hda_codec *codec) | |||
14199 | alc861_cfg_tbl); | 14514 | alc861_cfg_tbl); |
14200 | 14515 | ||
14201 | if (board_config < 0) { | 14516 | if (board_config < 0) { |
14202 | printk(KERN_INFO "hda_codec: Unknown model for ALC861, " | 14517 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
14203 | "trying auto-probe from BIOS...\n"); | 14518 | "trying auto-probe from BIOS...\n", codec->chip_name); |
14204 | board_config = ALC861_AUTO; | 14519 | board_config = ALC861_AUTO; |
14205 | } | 14520 | } |
14206 | 14521 | ||
@@ -14227,11 +14542,9 @@ static int patch_alc861(struct hda_codec *codec) | |||
14227 | if (board_config != ALC861_AUTO) | 14542 | if (board_config != ALC861_AUTO) |
14228 | setup_preset(spec, &alc861_presets[board_config]); | 14543 | setup_preset(spec, &alc861_presets[board_config]); |
14229 | 14544 | ||
14230 | spec->stream_name_analog = "ALC861 Analog"; | ||
14231 | spec->stream_analog_playback = &alc861_pcm_analog_playback; | 14545 | spec->stream_analog_playback = &alc861_pcm_analog_playback; |
14232 | spec->stream_analog_capture = &alc861_pcm_analog_capture; | 14546 | spec->stream_analog_capture = &alc861_pcm_analog_capture; |
14233 | 14547 | ||
14234 | spec->stream_name_digital = "ALC861 Digital"; | ||
14235 | spec->stream_digital_playback = &alc861_pcm_digital_playback; | 14548 | spec->stream_digital_playback = &alc861_pcm_digital_playback; |
14236 | spec->stream_digital_capture = &alc861_pcm_digital_capture; | 14549 | spec->stream_digital_capture = &alc861_pcm_digital_capture; |
14237 | 14550 | ||
@@ -14618,19 +14931,6 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { | |||
14618 | {} | 14931 | {} |
14619 | }; | 14932 | }; |
14620 | 14933 | ||
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) | 14934 | static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) |
14635 | { | 14935 | { |
14636 | unsigned int present; | 14936 | unsigned int present; |
@@ -14643,9 +14943,13 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) | |||
14643 | HDA_AMP_MUTE, bits); | 14943 | HDA_AMP_MUTE, bits); |
14644 | } | 14944 | } |
14645 | 14945 | ||
14646 | static void alc861vd_lenovo_automute(struct hda_codec *codec) | 14946 | static void alc861vd_lenovo_init_hook(struct hda_codec *codec) |
14647 | { | 14947 | { |
14648 | alc861vd_lenovo_hp_automute(codec); | 14948 | struct alc_spec *spec = codec->spec; |
14949 | |||
14950 | spec->autocfg.hp_pins[0] = 0x1b; | ||
14951 | spec->autocfg.speaker_pins[0] = 0x14; | ||
14952 | alc_automute_amp(codec); | ||
14649 | alc861vd_lenovo_mic_automute(codec); | 14953 | alc861vd_lenovo_mic_automute(codec); |
14650 | } | 14954 | } |
14651 | 14955 | ||
@@ -14653,12 +14957,12 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, | |||
14653 | unsigned int res) | 14957 | unsigned int res) |
14654 | { | 14958 | { |
14655 | switch (res >> 26) { | 14959 | switch (res >> 26) { |
14656 | case ALC880_HP_EVENT: | ||
14657 | alc861vd_lenovo_hp_automute(codec); | ||
14658 | break; | ||
14659 | case ALC880_MIC_EVENT: | 14960 | case ALC880_MIC_EVENT: |
14660 | alc861vd_lenovo_mic_automute(codec); | 14961 | alc861vd_lenovo_mic_automute(codec); |
14661 | break; | 14962 | break; |
14963 | default: | ||
14964 | alc_automute_amp_unsol_event(codec, res); | ||
14965 | break; | ||
14662 | } | 14966 | } |
14663 | } | 14967 | } |
14664 | 14968 | ||
@@ -14708,20 +15012,13 @@ static struct hda_verb alc861vd_dallas_verbs[] = { | |||
14708 | }; | 15012 | }; |
14709 | 15013 | ||
14710 | /* toggle speaker-output according to the hp-jack state */ | 15014 | /* toggle speaker-output according to the hp-jack state */ |
14711 | static void alc861vd_dallas_automute(struct hda_codec *codec) | 15015 | static void alc861vd_dallas_init_hook(struct hda_codec *codec) |
14712 | { | 15016 | { |
14713 | unsigned int present; | 15017 | 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 | 15018 | ||
14721 | static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res) | 15019 | spec->autocfg.hp_pins[0] = 0x15; |
14722 | { | 15020 | spec->autocfg.speaker_pins[0] = 0x14; |
14723 | if ((res >> 26) == ALC880_HP_EVENT) | 15021 | alc_automute_amp(codec); |
14724 | alc861vd_dallas_automute(codec); | ||
14725 | } | 15022 | } |
14726 | 15023 | ||
14727 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 15024 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -14835,7 +15132,7 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
14835 | .channel_mode = alc861vd_3stack_2ch_modes, | 15132 | .channel_mode = alc861vd_3stack_2ch_modes, |
14836 | .input_mux = &alc861vd_capture_source, | 15133 | .input_mux = &alc861vd_capture_source, |
14837 | .unsol_event = alc861vd_lenovo_unsol_event, | 15134 | .unsol_event = alc861vd_lenovo_unsol_event, |
14838 | .init_hook = alc861vd_lenovo_automute, | 15135 | .init_hook = alc861vd_lenovo_init_hook, |
14839 | }, | 15136 | }, |
14840 | [ALC861VD_DALLAS] = { | 15137 | [ALC861VD_DALLAS] = { |
14841 | .mixers = { alc861vd_dallas_mixer }, | 15138 | .mixers = { alc861vd_dallas_mixer }, |
@@ -14845,8 +15142,8 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
14845 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | 15142 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), |
14846 | .channel_mode = alc861vd_3stack_2ch_modes, | 15143 | .channel_mode = alc861vd_3stack_2ch_modes, |
14847 | .input_mux = &alc861vd_dallas_capture_source, | 15144 | .input_mux = &alc861vd_dallas_capture_source, |
14848 | .unsol_event = alc861vd_dallas_unsol_event, | 15145 | .unsol_event = alc_automute_amp_unsol_event, |
14849 | .init_hook = alc861vd_dallas_automute, | 15146 | .init_hook = alc861vd_dallas_init_hook, |
14850 | }, | 15147 | }, |
14851 | [ALC861VD_HP] = { | 15148 | [ALC861VD_HP] = { |
14852 | .mixers = { alc861vd_hp_mixer }, | 15149 | .mixers = { alc861vd_hp_mixer }, |
@@ -14857,8 +15154,8 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
14857 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | 15154 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), |
14858 | .channel_mode = alc861vd_3stack_2ch_modes, | 15155 | .channel_mode = alc861vd_3stack_2ch_modes, |
14859 | .input_mux = &alc861vd_hp_capture_source, | 15156 | .input_mux = &alc861vd_hp_capture_source, |
14860 | .unsol_event = alc861vd_dallas_unsol_event, | 15157 | .unsol_event = alc_automute_amp_unsol_event, |
14861 | .init_hook = alc861vd_dallas_automute, | 15158 | .init_hook = alc861vd_dallas_init_hook, |
14862 | }, | 15159 | }, |
14863 | [ALC660VD_ASUS_V1S] = { | 15160 | [ALC660VD_ASUS_V1S] = { |
14864 | .mixers = { alc861vd_lenovo_mixer }, | 15161 | .mixers = { alc861vd_lenovo_mixer }, |
@@ -14873,7 +15170,7 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
14873 | .channel_mode = alc861vd_3stack_2ch_modes, | 15170 | .channel_mode = alc861vd_3stack_2ch_modes, |
14874 | .input_mux = &alc861vd_capture_source, | 15171 | .input_mux = &alc861vd_capture_source, |
14875 | .unsol_event = alc861vd_lenovo_unsol_event, | 15172 | .unsol_event = alc861vd_lenovo_unsol_event, |
14876 | .init_hook = alc861vd_lenovo_automute, | 15173 | .init_hook = alc861vd_lenovo_init_hook, |
14877 | }, | 15174 | }, |
14878 | }; | 15175 | }; |
14879 | 15176 | ||
@@ -14891,7 +15188,6 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec) | |||
14891 | struct alc_spec *spec = codec->spec; | 15188 | struct alc_spec *spec = codec->spec; |
14892 | int i; | 15189 | int i; |
14893 | 15190 | ||
14894 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
14895 | for (i = 0; i <= HDA_SIDE; i++) { | 15191 | for (i = 0; i <= HDA_SIDE; i++) { |
14896 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 15192 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
14897 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 15193 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -15109,6 +15405,8 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
15109 | if (err < 0) | 15405 | if (err < 0) |
15110 | return err; | 15406 | return err; |
15111 | 15407 | ||
15408 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); | ||
15409 | |||
15112 | return 1; | 15410 | return 1; |
15113 | } | 15411 | } |
15114 | 15412 | ||
@@ -15140,8 +15438,8 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
15140 | alc861vd_cfg_tbl); | 15438 | alc861vd_cfg_tbl); |
15141 | 15439 | ||
15142 | if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { | 15440 | if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { |
15143 | printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/" | 15441 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
15144 | "ALC861VD, trying auto-probe from BIOS...\n"); | 15442 | "trying auto-probe from BIOS...\n", codec->chip_name); |
15145 | board_config = ALC861VD_AUTO; | 15443 | board_config = ALC861VD_AUTO; |
15146 | } | 15444 | } |
15147 | 15445 | ||
@@ -15169,13 +15467,8 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
15169 | setup_preset(spec, &alc861vd_presets[board_config]); | 15467 | setup_preset(spec, &alc861vd_presets[board_config]); |
15170 | 15468 | ||
15171 | if (codec->vendor_id == 0x10ec0660) { | 15469 | 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 */ | 15470 | /* always turn on EAPD */ |
15175 | add_verb(spec, alc660vd_eapd_verbs); | 15471 | add_verb(spec, alc660vd_eapd_verbs); |
15176 | } else { | ||
15177 | spec->stream_name_analog = "ALC861VD Analog"; | ||
15178 | spec->stream_name_digital = "ALC861VD Digital"; | ||
15179 | } | 15472 | } |
15180 | 15473 | ||
15181 | spec->stream_analog_playback = &alc861vd_pcm_analog_playback; | 15474 | spec->stream_analog_playback = &alc861vd_pcm_analog_playback; |
@@ -15289,6 +15582,38 @@ static struct hda_input_mux alc663_m51va_capture_source = { | |||
15289 | }, | 15582 | }, |
15290 | }; | 15583 | }; |
15291 | 15584 | ||
15585 | #if 1 /* set to 0 for testing other input sources below */ | ||
15586 | static struct hda_input_mux alc272_nc10_capture_source = { | ||
15587 | .num_items = 2, | ||
15588 | .items = { | ||
15589 | { "Autoselect Mic", 0x0 }, | ||
15590 | { "Internal Mic", 0x1 }, | ||
15591 | }, | ||
15592 | }; | ||
15593 | #else | ||
15594 | static struct hda_input_mux alc272_nc10_capture_source = { | ||
15595 | .num_items = 16, | ||
15596 | .items = { | ||
15597 | { "Autoselect Mic", 0x0 }, | ||
15598 | { "Internal Mic", 0x1 }, | ||
15599 | { "In-0x02", 0x2 }, | ||
15600 | { "In-0x03", 0x3 }, | ||
15601 | { "In-0x04", 0x4 }, | ||
15602 | { "In-0x05", 0x5 }, | ||
15603 | { "In-0x06", 0x6 }, | ||
15604 | { "In-0x07", 0x7 }, | ||
15605 | { "In-0x08", 0x8 }, | ||
15606 | { "In-0x09", 0x9 }, | ||
15607 | { "In-0x0a", 0x0a }, | ||
15608 | { "In-0x0b", 0x0b }, | ||
15609 | { "In-0x0c", 0x0c }, | ||
15610 | { "In-0x0d", 0x0d }, | ||
15611 | { "In-0x0e", 0x0e }, | ||
15612 | { "In-0x0f", 0x0f }, | ||
15613 | }, | ||
15614 | }; | ||
15615 | #endif | ||
15616 | |||
15292 | /* | 15617 | /* |
15293 | * 2ch mode | 15618 | * 2ch mode |
15294 | */ | 15619 | */ |
@@ -15428,10 +15753,8 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { | |||
15428 | }; | 15753 | }; |
15429 | 15754 | ||
15430 | static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { | 15755 | static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { |
15431 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 15756 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
15432 | 15757 | 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 | 15758 | ||
15436 | HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), | 15759 | HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), |
15437 | HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 15760 | HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -15444,15 +15767,11 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { | |||
15444 | }; | 15767 | }; |
15445 | 15768 | ||
15446 | static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { | 15769 | static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { |
15447 | HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 15770 | ALC262_HIPPO_MASTER_SWITCH, |
15448 | HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 15771 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
15449 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 15772 | 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), | 15773 | 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), | 15774 | 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), | 15775 | HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), |
15457 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 15776 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
15458 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 15777 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
@@ -15960,51 +16279,25 @@ static void alc662_eeepc_mic_automute(struct hda_codec *codec) | |||
15960 | static void alc662_eeepc_unsol_event(struct hda_codec *codec, | 16279 | static void alc662_eeepc_unsol_event(struct hda_codec *codec, |
15961 | unsigned int res) | 16280 | unsigned int res) |
15962 | { | 16281 | { |
15963 | if ((res >> 26) == ALC880_HP_EVENT) | ||
15964 | alc262_hippo1_automute( codec ); | ||
15965 | |||
15966 | if ((res >> 26) == ALC880_MIC_EVENT) | 16282 | if ((res >> 26) == ALC880_MIC_EVENT) |
15967 | alc662_eeepc_mic_automute(codec); | 16283 | alc662_eeepc_mic_automute(codec); |
16284 | else | ||
16285 | alc262_hippo_unsol_event(codec, res); | ||
15968 | } | 16286 | } |
15969 | 16287 | ||
15970 | static void alc662_eeepc_inithook(struct hda_codec *codec) | 16288 | static void alc662_eeepc_inithook(struct hda_codec *codec) |
15971 | { | 16289 | { |
15972 | alc262_hippo1_automute( codec ); | 16290 | alc262_hippo1_init_hook(codec); |
15973 | alc662_eeepc_mic_automute(codec); | 16291 | alc662_eeepc_mic_automute(codec); |
15974 | } | 16292 | } |
15975 | 16293 | ||
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) | 16294 | static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) |
16006 | { | 16295 | { |
16007 | alc662_eeepc_ep20_automute(codec); | 16296 | struct alc_spec *spec = codec->spec; |
16297 | |||
16298 | spec->autocfg.hp_pins[0] = 0x14; | ||
16299 | spec->autocfg.speaker_pins[0] = 0x1b; | ||
16300 | alc262_hippo_master_update(codec); | ||
16008 | } | 16301 | } |
16009 | 16302 | ||
16010 | static void alc663_m51va_speaker_automute(struct hda_codec *codec) | 16303 | static void alc663_m51va_speaker_automute(struct hda_codec *codec) |
@@ -16338,35 +16631,9 @@ static void alc663_g50v_inithook(struct hda_codec *codec) | |||
16338 | alc662_eeepc_mic_automute(codec); | 16631 | alc662_eeepc_mic_automute(codec); |
16339 | } | 16632 | } |
16340 | 16633 | ||
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[] = { | 16634 | static struct snd_kcontrol_new alc662_ecs_mixer[] = { |
16361 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 16635 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
16362 | { | 16636 | 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 | 16637 | ||
16371 | HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), | 16638 | HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), |
16372 | HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), | 16639 | HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -16378,6 +16645,23 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = { | |||
16378 | { } /* end */ | 16645 | { } /* end */ |
16379 | }; | 16646 | }; |
16380 | 16647 | ||
16648 | static struct snd_kcontrol_new alc272_nc10_mixer[] = { | ||
16649 | /* Master Playback automatically created from Speaker and Headphone */ | ||
16650 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
16651 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
16652 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
16653 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
16654 | |||
16655 | HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
16656 | HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
16657 | HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), | ||
16658 | |||
16659 | HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
16660 | HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
16661 | HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), | ||
16662 | { } /* end */ | ||
16663 | }; | ||
16664 | |||
16381 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 16665 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
16382 | #define alc662_loopbacks alc880_loopbacks | 16666 | #define alc662_loopbacks alc880_loopbacks |
16383 | #endif | 16667 | #endif |
@@ -16411,6 +16695,9 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { | |||
16411 | [ALC663_ASUS_MODE4] = "asus-mode4", | 16695 | [ALC663_ASUS_MODE4] = "asus-mode4", |
16412 | [ALC663_ASUS_MODE5] = "asus-mode5", | 16696 | [ALC663_ASUS_MODE5] = "asus-mode5", |
16413 | [ALC663_ASUS_MODE6] = "asus-mode6", | 16697 | [ALC663_ASUS_MODE6] = "asus-mode6", |
16698 | [ALC272_DELL] = "dell", | ||
16699 | [ALC272_DELL_ZM1] = "dell-zm1", | ||
16700 | [ALC272_SAMSUNG_NC10] = "samsung-nc10", | ||
16414 | [ALC662_AUTO] = "auto", | 16701 | [ALC662_AUTO] = "auto", |
16415 | }; | 16702 | }; |
16416 | 16703 | ||
@@ -16468,6 +16755,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { | |||
16468 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), | 16755 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), |
16469 | SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", | 16756 | SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", |
16470 | ALC662_3ST_6ch_DIG), | 16757 | ALC662_3ST_6ch_DIG), |
16758 | SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), | ||
16471 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", | 16759 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", |
16472 | ALC662_3ST_6ch_DIG), | 16760 | ALC662_3ST_6ch_DIG), |
16473 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), | 16761 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), |
@@ -16558,7 +16846,7 @@ static struct alc_config_preset alc662_presets[] = { | |||
16558 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | 16846 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), |
16559 | .channel_mode = alc662_3ST_6ch_modes, | 16847 | .channel_mode = alc662_3ST_6ch_modes, |
16560 | .input_mux = &alc662_lenovo_101e_capture_source, | 16848 | .input_mux = &alc662_lenovo_101e_capture_source, |
16561 | .unsol_event = alc662_eeepc_ep20_unsol_event, | 16849 | .unsol_event = alc662_eeepc_unsol_event, |
16562 | .init_hook = alc662_eeepc_ep20_inithook, | 16850 | .init_hook = alc662_eeepc_ep20_inithook, |
16563 | }, | 16851 | }, |
16564 | [ALC662_ECS] = { | 16852 | [ALC662_ECS] = { |
@@ -16739,6 +17027,18 @@ static struct alc_config_preset alc662_presets[] = { | |||
16739 | .unsol_event = alc663_m51va_unsol_event, | 17027 | .unsol_event = alc663_m51va_unsol_event, |
16740 | .init_hook = alc663_m51va_inithook, | 17028 | .init_hook = alc663_m51va_inithook, |
16741 | }, | 17029 | }, |
17030 | [ALC272_SAMSUNG_NC10] = { | ||
17031 | .mixers = { alc272_nc10_mixer }, | ||
17032 | .init_verbs = { alc662_init_verbs, | ||
17033 | alc663_21jd_amic_init_verbs }, | ||
17034 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | ||
17035 | .dac_nids = alc272_dac_nids, | ||
17036 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
17037 | .channel_mode = alc662_3ST_2ch_modes, | ||
17038 | .input_mux = &alc272_nc10_capture_source, | ||
17039 | .unsol_event = alc663_mode4_unsol_event, | ||
17040 | .init_hook = alc663_mode4_inithook, | ||
17041 | }, | ||
16742 | }; | 17042 | }; |
16743 | 17043 | ||
16744 | 17044 | ||
@@ -16933,7 +17233,6 @@ static void alc662_auto_init_multi_out(struct hda_codec *codec) | |||
16933 | struct alc_spec *spec = codec->spec; | 17233 | struct alc_spec *spec = codec->spec; |
16934 | int i; | 17234 | int i; |
16935 | 17235 | ||
16936 | alc_subsystem_id(codec, 0x15, 0x1b, 0x14); | ||
16937 | for (i = 0; i <= HDA_SIDE; i++) { | 17236 | for (i = 0; i <= HDA_SIDE; i++) { |
16938 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 17237 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
16939 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 17238 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -17030,6 +17329,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
17030 | if (err < 0) | 17329 | if (err < 0) |
17031 | return err; | 17330 | return err; |
17032 | 17331 | ||
17332 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); | ||
17333 | |||
17033 | return 1; | 17334 | return 1; |
17034 | } | 17335 | } |
17035 | 17336 | ||
@@ -17062,8 +17363,8 @@ static int patch_alc662(struct hda_codec *codec) | |||
17062 | alc662_models, | 17363 | alc662_models, |
17063 | alc662_cfg_tbl); | 17364 | alc662_cfg_tbl); |
17064 | if (board_config < 0) { | 17365 | if (board_config < 0) { |
17065 | printk(KERN_INFO "hda_codec: Unknown model for ALC662, " | 17366 | printk(KERN_INFO "hda_codec: Unknown model for %s, " |
17066 | "trying auto-probe from BIOS...\n"); | 17367 | "trying auto-probe from BIOS...\n", codec->chip_name); |
17067 | board_config = ALC662_AUTO; | 17368 | board_config = ALC662_AUTO; |
17068 | } | 17369 | } |
17069 | 17370 | ||
@@ -17090,17 +17391,6 @@ static int patch_alc662(struct hda_codec *codec) | |||
17090 | if (board_config != ALC662_AUTO) | 17391 | if (board_config != ALC662_AUTO) |
17091 | setup_preset(spec, &alc662_presets[board_config]); | 17392 | setup_preset(spec, &alc662_presets[board_config]); |
17092 | 17393 | ||
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; | 17394 | spec->stream_analog_playback = &alc662_pcm_analog_playback; |
17105 | spec->stream_analog_capture = &alc662_pcm_analog_capture; | 17395 | spec->stream_analog_capture = &alc662_pcm_analog_capture; |
17106 | 17396 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d2fd8ef6aef8..42f944bb641d 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,40 @@ 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 | |||
637 | static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 673 | static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
638 | { | 674 | { |
639 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 675 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
@@ -995,6 +1031,17 @@ static struct hda_verb stac9205_core_init[] = { | |||
995 | .private_value = verb_read | (verb_write << 16), \ | 1031 | .private_value = verb_read | (verb_write << 16), \ |
996 | } | 1032 | } |
997 | 1033 | ||
1034 | #define DC_BIAS(xname, idx, nid) \ | ||
1035 | { \ | ||
1036 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
1037 | .name = xname, \ | ||
1038 | .index = idx, \ | ||
1039 | .info = stac92xx_dc_bias_info, \ | ||
1040 | .get = stac92xx_dc_bias_get, \ | ||
1041 | .put = stac92xx_dc_bias_put, \ | ||
1042 | .private_value = nid, \ | ||
1043 | } | ||
1044 | |||
998 | static struct snd_kcontrol_new stac9200_mixer[] = { | 1045 | static struct snd_kcontrol_new stac9200_mixer[] = { |
999 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), | 1046 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), |
1000 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), | 1047 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), |
@@ -1837,6 +1884,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | |||
1837 | [STAC_HP_M4] = NULL, | 1884 | [STAC_HP_M4] = NULL, |
1838 | [STAC_HP_DV5] = NULL, | 1885 | [STAC_HP_DV5] = NULL, |
1839 | [STAC_HP_HDX] = NULL, | 1886 | [STAC_HP_HDX] = NULL, |
1887 | [STAC_HP_DV4_1222NR] = NULL, | ||
1840 | }; | 1888 | }; |
1841 | 1889 | ||
1842 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | 1890 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { |
@@ -1848,6 +1896,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | |||
1848 | [STAC_HP_M4] = "hp-m4", | 1896 | [STAC_HP_M4] = "hp-m4", |
1849 | [STAC_HP_DV5] = "hp-dv5", | 1897 | [STAC_HP_DV5] = "hp-dv5", |
1850 | [STAC_HP_HDX] = "hp-hdx", | 1898 | [STAC_HP_HDX] = "hp-hdx", |
1899 | [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", | ||
1851 | }; | 1900 | }; |
1852 | 1901 | ||
1853 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | 1902 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { |
@@ -1856,6 +1905,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |||
1856 | "DFI LanParty", STAC_92HD71BXX_REF), | 1905 | "DFI LanParty", STAC_92HD71BXX_REF), |
1857 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | 1906 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, |
1858 | "DFI LanParty", STAC_92HD71BXX_REF), | 1907 | "DFI LanParty", STAC_92HD71BXX_REF), |
1908 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb, | ||
1909 | "HP dv4-1222nr", STAC_HP_DV4_1222NR), | ||
1859 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, | 1910 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, |
1860 | "HP", STAC_HP_DV5), | 1911 | "HP", STAC_HP_DV5), |
1861 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, | 1912 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, |
@@ -2545,7 +2596,8 @@ static int stac92xx_build_pcms(struct hda_codec *codec) | |||
2545 | return 0; | 2596 | return 0; |
2546 | } | 2597 | } |
2547 | 2598 | ||
2548 | static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid) | 2599 | static unsigned int stac92xx_get_default_vref(struct hda_codec *codec, |
2600 | hda_nid_t nid) | ||
2549 | { | 2601 | { |
2550 | unsigned int pincap = snd_hda_query_pin_caps(codec, nid); | 2602 | unsigned int pincap = snd_hda_query_pin_caps(codec, nid); |
2551 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; | 2603 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; |
@@ -2599,15 +2651,108 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, | |||
2599 | return 1; | 2651 | return 1; |
2600 | } | 2652 | } |
2601 | 2653 | ||
2602 | #define stac92xx_io_switch_info snd_ctl_boolean_mono_info | 2654 | static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol, |
2655 | struct snd_ctl_elem_info *uinfo) | ||
2656 | { | ||
2657 | int i; | ||
2658 | static char *texts[] = { | ||
2659 | "Mic In", "Line In", "Line Out" | ||
2660 | }; | ||
2661 | |||
2662 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2663 | struct sigmatel_spec *spec = codec->spec; | ||
2664 | hda_nid_t nid = kcontrol->private_value; | ||
2665 | |||
2666 | if (nid == spec->mic_switch || nid == spec->line_switch) | ||
2667 | i = 3; | ||
2668 | else | ||
2669 | i = 2; | ||
2670 | |||
2671 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
2672 | uinfo->value.enumerated.items = i; | ||
2673 | uinfo->count = 1; | ||
2674 | if (uinfo->value.enumerated.item >= i) | ||
2675 | uinfo->value.enumerated.item = i-1; | ||
2676 | strcpy(uinfo->value.enumerated.name, | ||
2677 | texts[uinfo->value.enumerated.item]); | ||
2678 | |||
2679 | return 0; | ||
2680 | } | ||
2681 | |||
2682 | static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol, | ||
2683 | struct snd_ctl_elem_value *ucontrol) | ||
2684 | { | ||
2685 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2686 | hda_nid_t nid = kcontrol->private_value; | ||
2687 | unsigned int vref = stac92xx_vref_get(codec, nid); | ||
2688 | |||
2689 | if (vref == stac92xx_get_default_vref(codec, nid)) | ||
2690 | ucontrol->value.enumerated.item[0] = 0; | ||
2691 | else if (vref == AC_PINCTL_VREF_GRD) | ||
2692 | ucontrol->value.enumerated.item[0] = 1; | ||
2693 | else if (vref == AC_PINCTL_VREF_HIZ) | ||
2694 | ucontrol->value.enumerated.item[0] = 2; | ||
2695 | |||
2696 | return 0; | ||
2697 | } | ||
2698 | |||
2699 | static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol, | ||
2700 | struct snd_ctl_elem_value *ucontrol) | ||
2701 | { | ||
2702 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2703 | unsigned int new_vref = 0; | ||
2704 | unsigned int error; | ||
2705 | hda_nid_t nid = kcontrol->private_value; | ||
2706 | |||
2707 | if (ucontrol->value.enumerated.item[0] == 0) | ||
2708 | new_vref = stac92xx_get_default_vref(codec, nid); | ||
2709 | else if (ucontrol->value.enumerated.item[0] == 1) | ||
2710 | new_vref = AC_PINCTL_VREF_GRD; | ||
2711 | else if (ucontrol->value.enumerated.item[0] == 2) | ||
2712 | new_vref = AC_PINCTL_VREF_HIZ; | ||
2713 | else | ||
2714 | return 0; | ||
2715 | |||
2716 | if (new_vref != stac92xx_vref_get(codec, nid)) { | ||
2717 | error = stac92xx_vref_set(codec, nid, new_vref); | ||
2718 | return error; | ||
2719 | } | ||
2720 | |||
2721 | return 0; | ||
2722 | } | ||
2723 | |||
2724 | static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol, | ||
2725 | struct snd_ctl_elem_info *uinfo) | ||
2726 | { | ||
2727 | static char *texts[2]; | ||
2728 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2729 | struct sigmatel_spec *spec = codec->spec; | ||
2730 | |||
2731 | if (kcontrol->private_value == spec->line_switch) | ||
2732 | texts[0] = "Line In"; | ||
2733 | else | ||
2734 | texts[0] = "Mic In"; | ||
2735 | texts[1] = "Line Out"; | ||
2736 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
2737 | uinfo->value.enumerated.items = 2; | ||
2738 | uinfo->count = 1; | ||
2739 | |||
2740 | if (uinfo->value.enumerated.item >= 2) | ||
2741 | uinfo->value.enumerated.item = 1; | ||
2742 | strcpy(uinfo->value.enumerated.name, | ||
2743 | texts[uinfo->value.enumerated.item]); | ||
2744 | |||
2745 | return 0; | ||
2746 | } | ||
2603 | 2747 | ||
2604 | static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2748 | static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
2605 | { | 2749 | { |
2606 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2750 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2607 | struct sigmatel_spec *spec = codec->spec; | 2751 | struct sigmatel_spec *spec = codec->spec; |
2608 | int io_idx = kcontrol-> private_value & 0xff; | 2752 | hda_nid_t nid = kcontrol->private_value; |
2753 | int io_idx = (nid == spec->mic_switch) ? 1 : 0; | ||
2609 | 2754 | ||
2610 | ucontrol->value.integer.value[0] = spec->io_switch[io_idx]; | 2755 | ucontrol->value.enumerated.item[0] = spec->io_switch[io_idx]; |
2611 | return 0; | 2756 | return 0; |
2612 | } | 2757 | } |
2613 | 2758 | ||
@@ -2615,9 +2760,9 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
2615 | { | 2760 | { |
2616 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2761 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2617 | struct sigmatel_spec *spec = codec->spec; | 2762 | struct sigmatel_spec *spec = codec->spec; |
2618 | hda_nid_t nid = kcontrol->private_value >> 8; | 2763 | hda_nid_t nid = kcontrol->private_value; |
2619 | int io_idx = kcontrol-> private_value & 0xff; | 2764 | int io_idx = (nid == spec->mic_switch) ? 1 : 0; |
2620 | unsigned short val = !!ucontrol->value.integer.value[0]; | 2765 | unsigned short val = !!ucontrol->value.enumerated.item[0]; |
2621 | 2766 | ||
2622 | spec->io_switch[io_idx] = val; | 2767 | spec->io_switch[io_idx] = val; |
2623 | 2768 | ||
@@ -2626,7 +2771,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
2626 | else { | 2771 | else { |
2627 | unsigned int pinctl = AC_PINCTL_IN_EN; | 2772 | unsigned int pinctl = AC_PINCTL_IN_EN; |
2628 | if (io_idx) /* set VREF for mic */ | 2773 | if (io_idx) /* set VREF for mic */ |
2629 | pinctl |= stac92xx_get_vref(codec, nid); | 2774 | pinctl |= stac92xx_get_default_vref(codec, nid); |
2630 | stac92xx_auto_set_pinctl(codec, nid, pinctl); | 2775 | stac92xx_auto_set_pinctl(codec, nid, pinctl); |
2631 | } | 2776 | } |
2632 | 2777 | ||
@@ -2707,7 +2852,8 @@ enum { | |||
2707 | STAC_CTL_WIDGET_AMP_VOL, | 2852 | STAC_CTL_WIDGET_AMP_VOL, |
2708 | STAC_CTL_WIDGET_HP_SWITCH, | 2853 | STAC_CTL_WIDGET_HP_SWITCH, |
2709 | STAC_CTL_WIDGET_IO_SWITCH, | 2854 | STAC_CTL_WIDGET_IO_SWITCH, |
2710 | STAC_CTL_WIDGET_CLFE_SWITCH | 2855 | STAC_CTL_WIDGET_CLFE_SWITCH, |
2856 | STAC_CTL_WIDGET_DC_BIAS | ||
2711 | }; | 2857 | }; |
2712 | 2858 | ||
2713 | static struct snd_kcontrol_new stac92xx_control_templates[] = { | 2859 | static struct snd_kcontrol_new stac92xx_control_templates[] = { |
@@ -2719,6 +2865,7 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { | |||
2719 | STAC_CODEC_HP_SWITCH(NULL), | 2865 | STAC_CODEC_HP_SWITCH(NULL), |
2720 | STAC_CODEC_IO_SWITCH(NULL, 0), | 2866 | STAC_CODEC_IO_SWITCH(NULL, 0), |
2721 | STAC_CODEC_CLFE_SWITCH(NULL, 0), | 2867 | STAC_CODEC_CLFE_SWITCH(NULL, 0), |
2868 | DC_BIAS(NULL, 0, 0), | ||
2722 | }; | 2869 | }; |
2723 | 2870 | ||
2724 | /* add dynamic controls */ | 2871 | /* add dynamic controls */ |
@@ -2782,6 +2929,34 @@ static struct snd_kcontrol_new stac_input_src_temp = { | |||
2782 | .put = stac92xx_mux_enum_put, | 2929 | .put = stac92xx_mux_enum_put, |
2783 | }; | 2930 | }; |
2784 | 2931 | ||
2932 | static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec, | ||
2933 | hda_nid_t nid, int idx) | ||
2934 | { | ||
2935 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
2936 | int control = 0; | ||
2937 | struct sigmatel_spec *spec = codec->spec; | ||
2938 | char name[22]; | ||
2939 | |||
2940 | if (!((get_defcfg_connect(def_conf)) & AC_JACK_PORT_FIXED)) { | ||
2941 | if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD | ||
2942 | && nid == spec->line_switch) | ||
2943 | control = STAC_CTL_WIDGET_IO_SWITCH; | ||
2944 | else if (snd_hda_query_pin_caps(codec, nid) | ||
2945 | & (AC_PINCAP_VREF_GRD << AC_PINCAP_VREF_SHIFT)) | ||
2946 | control = STAC_CTL_WIDGET_DC_BIAS; | ||
2947 | else if (nid == spec->mic_switch) | ||
2948 | control = STAC_CTL_WIDGET_IO_SWITCH; | ||
2949 | } | ||
2950 | |||
2951 | if (control) { | ||
2952 | strcpy(name, auto_pin_cfg_labels[idx]); | ||
2953 | return stac92xx_add_control(codec->spec, control, | ||
2954 | strcat(name, " Jack Mode"), nid); | ||
2955 | } | ||
2956 | |||
2957 | return 0; | ||
2958 | } | ||
2959 | |||
2785 | static int stac92xx_add_input_source(struct sigmatel_spec *spec) | 2960 | static int stac92xx_add_input_source(struct sigmatel_spec *spec) |
2786 | { | 2961 | { |
2787 | struct snd_kcontrol_new *knew; | 2962 | struct snd_kcontrol_new *knew; |
@@ -3144,7 +3319,9 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3144 | const struct auto_pin_cfg *cfg) | 3319 | const struct auto_pin_cfg *cfg) |
3145 | { | 3320 | { |
3146 | struct sigmatel_spec *spec = codec->spec; | 3321 | struct sigmatel_spec *spec = codec->spec; |
3322 | hda_nid_t nid; | ||
3147 | int err; | 3323 | int err; |
3324 | int idx; | ||
3148 | 3325 | ||
3149 | err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins, | 3326 | err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins, |
3150 | spec->multiout.dac_nids, | 3327 | spec->multiout.dac_nids, |
@@ -3161,20 +3338,13 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3161 | return err; | 3338 | return err; |
3162 | } | 3339 | } |
3163 | 3340 | ||
3164 | if (spec->line_switch) { | 3341 | for (idx = AUTO_PIN_MIC; idx <= AUTO_PIN_FRONT_LINE; idx++) { |
3165 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, | 3342 | nid = cfg->input_pins[idx]; |
3166 | "Line In as Output Switch", | 3343 | if (nid) { |
3167 | spec->line_switch << 8); | 3344 | err = stac92xx_add_jack_mode_control(codec, nid, idx); |
3168 | if (err < 0) | 3345 | if (err < 0) |
3169 | return err; | 3346 | return err; |
3170 | } | 3347 | } |
3171 | |||
3172 | if (spec->mic_switch) { | ||
3173 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, | ||
3174 | "Mic as Output Switch", | ||
3175 | (spec->mic_switch << 8) | 1); | ||
3176 | if (err < 0) | ||
3177 | return err; | ||
3178 | } | 3348 | } |
3179 | 3349 | ||
3180 | return 0; | 3350 | return 0; |
@@ -3639,6 +3809,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); | 3809 | err = snd_hda_attach_beep_device(codec, nid); |
3640 | if (err < 0) | 3810 | if (err < 0) |
3641 | return err; | 3811 | return err; |
3812 | /* IDT/STAC codecs have linear beep tone parameter */ | ||
3813 | codec->beep->linear_tone = 1; | ||
3642 | /* if no beep switch is available, make its own one */ | 3814 | /* if no beep switch is available, make its own one */ |
3643 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); | 3815 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); |
3644 | if (codec->beep && | 3816 | if (codec->beep && |
@@ -4082,7 +4254,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4082 | unsigned int pinctl, conf; | 4254 | unsigned int pinctl, conf; |
4083 | if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { | 4255 | if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { |
4084 | /* for mic pins, force to initialize */ | 4256 | /* for mic pins, force to initialize */ |
4085 | pinctl = stac92xx_get_vref(codec, nid); | 4257 | pinctl = stac92xx_get_default_vref(codec, nid); |
4086 | pinctl |= AC_PINCTL_IN_EN; | 4258 | pinctl |= AC_PINCTL_IN_EN; |
4087 | stac92xx_auto_set_pinctl(codec, nid, pinctl); | 4259 | stac92xx_auto_set_pinctl(codec, nid, pinctl); |
4088 | } else { | 4260 | } else { |
@@ -4535,17 +4707,19 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4535 | return 0; | 4707 | return 0; |
4536 | } | 4708 | } |
4537 | 4709 | ||
4538 | |||
4539 | /* | 4710 | /* |
4540 | * using power check for controlling mute led of HP HDX notebooks | 4711 | * using power check for controlling mute led of HP notebooks |
4541 | * check for mute state only on Speakers (nid = 0x10) | 4712 | * check for mute state only on Speakers (nid = 0x10) |
4542 | * | 4713 | * |
4543 | * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise | 4714 | * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise |
4544 | * the LED is NOT working properly ! | 4715 | * the LED is NOT working properly ! |
4716 | * | ||
4717 | * Changed name to reflect that it now works for any designated | ||
4718 | * model, not just HP HDX. | ||
4545 | */ | 4719 | */ |
4546 | 4720 | ||
4547 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4721 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4548 | static int stac92xx_hp_hdx_check_power_status(struct hda_codec *codec, | 4722 | static int stac92xx_hp_check_power_status(struct hda_codec *codec, |
4549 | hda_nid_t nid) | 4723 | hda_nid_t nid) |
4550 | { | 4724 | { |
4551 | struct sigmatel_spec *spec = codec->spec; | 4725 | struct sigmatel_spec *spec = codec->spec; |
@@ -4553,9 +4727,9 @@ static int stac92xx_hp_hdx_check_power_status(struct hda_codec *codec, | |||
4553 | if (nid == 0x10) { | 4727 | if (nid == 0x10) { |
4554 | if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & | 4728 | if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & |
4555 | HDA_AMP_MUTE) | 4729 | HDA_AMP_MUTE) |
4556 | spec->gpio_data &= ~0x08; /* orange */ | 4730 | spec->gpio_data &= ~spec->gpio_led; /* orange */ |
4557 | else | 4731 | else |
4558 | spec->gpio_data |= 0x08; /* white */ | 4732 | spec->gpio_data |= spec->gpio_led; /* white */ |
4559 | 4733 | ||
4560 | stac_gpio_set(codec, spec->gpio_mask, | 4734 | stac_gpio_set(codec, spec->gpio_mask, |
4561 | spec->gpio_dir, | 4735 | spec->gpio_dir, |
@@ -5201,6 +5375,15 @@ again: | |||
5201 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | 5375 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) |
5202 | snd_hda_sequence_write_cache(codec, unmute_init); | 5376 | snd_hda_sequence_write_cache(codec, unmute_init); |
5203 | 5377 | ||
5378 | /* Some HP machines seem to have unstable codec communications | ||
5379 | * especially with ATI fglrx driver. For recovering from the | ||
5380 | * CORB/RIRB stall, allow the BUS reset and keep always sync | ||
5381 | */ | ||
5382 | if (spec->board_config == STAC_HP_DV5) { | ||
5383 | codec->bus->sync_write = 1; | ||
5384 | codec->bus->allow_bus_reset = 1; | ||
5385 | } | ||
5386 | |||
5204 | spec->aloopback_ctl = stac92hd71bxx_loopback; | 5387 | spec->aloopback_ctl = stac92hd71bxx_loopback; |
5205 | spec->aloopback_mask = 0x50; | 5388 | spec->aloopback_mask = 0x50; |
5206 | spec->aloopback_shift = 0; | 5389 | spec->aloopback_shift = 0; |
@@ -5234,6 +5417,15 @@ again: | |||
5234 | spec->num_smuxes = 0; | 5417 | spec->num_smuxes = 0; |
5235 | spec->num_dmuxes = 1; | 5418 | spec->num_dmuxes = 1; |
5236 | break; | 5419 | break; |
5420 | case STAC_HP_DV4_1222NR: | ||
5421 | spec->num_dmics = 1; | ||
5422 | /* I don't know if it needs 1 or 2 smuxes - will wait for | ||
5423 | * bug reports to fix if needed | ||
5424 | */ | ||
5425 | spec->num_smuxes = 1; | ||
5426 | spec->num_dmuxes = 1; | ||
5427 | spec->gpio_led = 0x01; | ||
5428 | /* fallthrough */ | ||
5237 | case STAC_HP_DV5: | 5429 | case STAC_HP_DV5: |
5238 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); | 5430 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); |
5239 | stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); | 5431 | stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); |
@@ -5242,22 +5434,21 @@ again: | |||
5242 | spec->num_dmics = 1; | 5434 | spec->num_dmics = 1; |
5243 | spec->num_dmuxes = 1; | 5435 | spec->num_dmuxes = 1; |
5244 | spec->num_smuxes = 1; | 5436 | 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 */ | 5437 | /* orange/white mute led on GPIO3, orange=0, white=1 */ |
5251 | spec->gpio_mask |= 0x08; | 5438 | spec->gpio_led = 0x08; |
5252 | spec->gpio_dir |= 0x08; | 5439 | break; |
5253 | spec->gpio_data |= 0x08; /* set to white */ | 5440 | } |
5254 | 5441 | ||
5442 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
5443 | if (spec->gpio_led) { | ||
5444 | spec->gpio_mask |= spec->gpio_led; | ||
5445 | spec->gpio_dir |= spec->gpio_led; | ||
5446 | spec->gpio_data |= spec->gpio_led; | ||
5255 | /* register check_power_status callback. */ | 5447 | /* register check_power_status callback. */ |
5256 | codec->patch_ops.check_power_status = | 5448 | codec->patch_ops.check_power_status = |
5257 | stac92xx_hp_hdx_check_power_status; | 5449 | stac92xx_hp_check_power_status; |
5450 | } | ||
5258 | #endif | 5451 | #endif |
5259 | break; | ||
5260 | }; | ||
5261 | 5452 | ||
5262 | spec->multiout.dac_nids = spec->dac_nids; | 5453 | spec->multiout.dac_nids = spec->dac_nids; |
5263 | if (spec->dinput_mux) | 5454 | if (spec->dinput_mux) |
@@ -5282,7 +5473,7 @@ again: | |||
5282 | codec->proc_widget_hook = stac92hd7x_proc_hook; | 5473 | codec->proc_widget_hook = stac92hd7x_proc_hook; |
5283 | 5474 | ||
5284 | return 0; | 5475 | return 0; |
5285 | }; | 5476 | } |
5286 | 5477 | ||
5287 | static int patch_stac922x(struct hda_codec *codec) | 5478 | static int patch_stac922x(struct hda_codec *codec) |
5288 | { | 5479 | { |
@@ -5437,7 +5628,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5437 | /* correct the device field to SPDIF out */ | 5628 | /* correct the device field to SPDIF out */ |
5438 | snd_hda_codec_set_pincfg(codec, 0x21, 0x01442070); | 5629 | snd_hda_codec_set_pincfg(codec, 0x21, 0x01442070); |
5439 | break; | 5630 | break; |
5440 | }; | 5631 | } |
5441 | /* configure the analog microphone on some laptops */ | 5632 | /* configure the analog microphone on some laptops */ |
5442 | snd_hda_codec_set_pincfg(codec, 0x0c, 0x90a79130); | 5633 | snd_hda_codec_set_pincfg(codec, 0x0c, 0x90a79130); |
5443 | /* correct the front output jack as a hp out */ | 5634 | /* 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; |