Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/hda/codecs/realtek/alc662.c
26530 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
//
3
// Realtek ALC662 and compatible codecs
4
//
5
6
#include <linux/init.h>
7
#include <linux/module.h>
8
#include "realtek.h"
9
10
/*
11
* ALC662 support
12
*
13
* ALC662 is almost identical with ALC880 but has cleaner and more flexible
14
* configuration. Each pin widget can choose any input DACs and a mixer.
15
* Each ADC is connected from a mixer of all inputs. This makes possible
16
* 6-channel independent captures.
17
*
18
* In addition, an independent DAC for the multi-playback (not used in this
19
* driver yet).
20
*/
21
22
/*
23
* BIOS auto configuration
24
*/
25
26
static int alc662_parse_auto_config(struct hda_codec *codec)
27
{
28
static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
29
static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
30
static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
31
const hda_nid_t *ssids;
32
33
if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
34
codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
35
codec->core.vendor_id == 0x10ec0671)
36
ssids = alc663_ssids;
37
else
38
ssids = alc662_ssids;
39
return alc_parse_auto_config(codec, alc662_ignore, ssids);
40
}
41
42
static void alc272_fixup_mario(struct hda_codec *codec,
43
const struct hda_fixup *fix, int action)
44
{
45
if (action != HDA_FIXUP_ACT_PRE_PROBE)
46
return;
47
if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
48
(0x3b << AC_AMPCAP_OFFSET_SHIFT) |
49
(0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
50
(0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
51
(0 << AC_AMPCAP_MUTE_SHIFT)))
52
codec_warn(codec, "failed to override amp caps for NID 0x2\n");
53
}
54
55
/* avoid D3 for keeping GPIO up */
56
static unsigned int gpio_led_power_filter(struct hda_codec *codec,
57
hda_nid_t nid,
58
unsigned int power_state)
59
{
60
struct alc_spec *spec = codec->spec;
61
if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
62
return AC_PWRST_D0;
63
return power_state;
64
}
65
66
static void alc662_fixup_led_gpio1(struct hda_codec *codec,
67
const struct hda_fixup *fix, int action)
68
{
69
struct alc_spec *spec = codec->spec;
70
71
alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
72
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
73
spec->mute_led_polarity = 1;
74
codec->power_filter = gpio_led_power_filter;
75
}
76
}
77
78
static void alc662_usi_automute_hook(struct hda_codec *codec,
79
struct hda_jack_callback *jack)
80
{
81
struct alc_spec *spec = codec->spec;
82
int vref;
83
msleep(200);
84
snd_hda_gen_hp_automute(codec, jack);
85
86
vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
87
msleep(100);
88
snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
89
vref);
90
}
91
92
static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
93
const struct hda_fixup *fix, int action)
94
{
95
struct alc_spec *spec = codec->spec;
96
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
97
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
98
spec->gen.hp_automute_hook = alc662_usi_automute_hook;
99
}
100
}
101
102
static void alc662_aspire_ethos_mute_speakers(struct hda_codec *codec,
103
struct hda_jack_callback *cb)
104
{
105
/* surround speakers at 0x1b already get muted automatically when
106
* headphones are plugged in, but we have to mute/unmute the remaining
107
* channels manually:
108
* 0x15 - front left/front right
109
* 0x18 - front center/ LFE
110
*/
111
if (snd_hda_jack_detect_state(codec, 0x1b) == HDA_JACK_PRESENT) {
112
snd_hda_set_pin_ctl_cache(codec, 0x15, 0);
113
snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
114
} else {
115
snd_hda_set_pin_ctl_cache(codec, 0x15, PIN_OUT);
116
snd_hda_set_pin_ctl_cache(codec, 0x18, PIN_OUT);
117
}
118
}
119
120
static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
121
const struct hda_fixup *fix, int action)
122
{
123
/* Pin 0x1b: shared headphones jack and surround speakers */
124
if (!is_jack_detectable(codec, 0x1b))
125
return;
126
127
switch (action) {
128
case HDA_FIXUP_ACT_PRE_PROBE:
129
snd_hda_jack_detect_enable_callback(codec, 0x1b,
130
alc662_aspire_ethos_mute_speakers);
131
/* subwoofer needs an extra GPIO setting to become audible */
132
alc_setup_gpio(codec, 0x02);
133
break;
134
case HDA_FIXUP_ACT_INIT:
135
/* Make sure to start in a correct state, i.e. if
136
* headphones have been plugged in before powering up the system
137
*/
138
alc662_aspire_ethos_mute_speakers(codec, NULL);
139
break;
140
}
141
}
142
143
static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec,
144
const struct hda_fixup *fix, int action)
145
{
146
struct alc_spec *spec = codec->spec;
147
148
static const struct hda_pintbl pincfgs[] = {
149
{ 0x19, 0x02a11040 }, /* use as headset mic, with its own jack detect */
150
{ 0x1b, 0x0181304f },
151
{ }
152
};
153
154
switch (action) {
155
case HDA_FIXUP_ACT_PRE_PROBE:
156
spec->gen.mixer_nid = 0;
157
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
158
snd_hda_apply_pincfgs(codec, pincfgs);
159
break;
160
case HDA_FIXUP_ACT_INIT:
161
alc_write_coef_idx(codec, 0x19, 0xa054);
162
break;
163
}
164
}
165
166
static void alc897_hp_automute_hook(struct hda_codec *codec,
167
struct hda_jack_callback *jack)
168
{
169
struct alc_spec *spec = codec->spec;
170
int vref;
171
172
snd_hda_gen_hp_automute(codec, jack);
173
vref = spec->gen.hp_jack_present ? (PIN_HP | AC_PINCTL_VREF_100) : PIN_HP;
174
snd_hda_set_pin_ctl(codec, 0x1b, vref);
175
}
176
177
static void alc897_fixup_lenovo_headset_mic(struct hda_codec *codec,
178
const struct hda_fixup *fix, int action)
179
{
180
struct alc_spec *spec = codec->spec;
181
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
182
spec->gen.hp_automute_hook = alc897_hp_automute_hook;
183
spec->no_shutup_pins = 1;
184
}
185
if (action == HDA_FIXUP_ACT_PROBE) {
186
snd_hda_set_pin_ctl_cache(codec, 0x1a, PIN_IN | AC_PINCTL_VREF_100);
187
}
188
}
189
190
static void alc897_fixup_lenovo_headset_mode(struct hda_codec *codec,
191
const struct hda_fixup *fix, int action)
192
{
193
struct alc_spec *spec = codec->spec;
194
195
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
196
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
197
spec->gen.hp_automute_hook = alc897_hp_automute_hook;
198
}
199
}
200
201
static const struct coef_fw alc668_coefs[] = {
202
WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
203
WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
204
WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
205
WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
206
WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
207
WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
208
WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
209
WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
210
WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
211
WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
212
WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
213
WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
214
WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
215
WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
216
WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
217
WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
218
WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
219
WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
220
WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
221
WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
222
{}
223
};
224
225
static void alc668_restore_default_value(struct hda_codec *codec)
226
{
227
alc_process_coef_fw(codec, alc668_coefs);
228
}
229
230
static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
231
const struct hda_fixup *fix, int action)
232
{
233
struct alc_spec *spec = codec->spec;
234
235
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
236
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
237
spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
238
239
/* Disable boost for mic-in permanently. (This code is only called
240
from quirks that guarantee that the headphone is at NID 0x1b.) */
241
snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
242
snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
243
} else
244
alc_fixup_headset_mode(codec, fix, action);
245
}
246
247
static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
248
const struct hda_fixup *fix, int action)
249
{
250
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
251
alc_write_coef_idx(codec, 0xc4, 0x8000);
252
alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
253
snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
254
}
255
alc_fixup_headset_mode(codec, fix, action);
256
}
257
258
enum {
259
ALC662_FIXUP_ASPIRE,
260
ALC662_FIXUP_LED_GPIO1,
261
ALC662_FIXUP_IDEAPAD,
262
ALC272_FIXUP_MARIO,
263
ALC662_FIXUP_CZC_ET26,
264
ALC662_FIXUP_CZC_P10T,
265
ALC662_FIXUP_SKU_IGNORE,
266
ALC662_FIXUP_HP_RP5800,
267
ALC662_FIXUP_ASUS_MODE1,
268
ALC662_FIXUP_ASUS_MODE2,
269
ALC662_FIXUP_ASUS_MODE3,
270
ALC662_FIXUP_ASUS_MODE4,
271
ALC662_FIXUP_ASUS_MODE5,
272
ALC662_FIXUP_ASUS_MODE6,
273
ALC662_FIXUP_ASUS_MODE7,
274
ALC662_FIXUP_ASUS_MODE8,
275
ALC662_FIXUP_NO_JACK_DETECT,
276
ALC662_FIXUP_ZOTAC_Z68,
277
ALC662_FIXUP_INV_DMIC,
278
ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
279
ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
280
ALC662_FIXUP_HEADSET_MODE,
281
ALC668_FIXUP_HEADSET_MODE,
282
ALC662_FIXUP_BASS_MODE4_CHMAP,
283
ALC662_FIXUP_BASS_16,
284
ALC662_FIXUP_BASS_1A,
285
ALC662_FIXUP_BASS_CHMAP,
286
ALC668_FIXUP_AUTO_MUTE,
287
ALC668_FIXUP_DELL_DISABLE_AAMIX,
288
ALC668_FIXUP_DELL_XPS13,
289
ALC662_FIXUP_ASUS_Nx50,
290
ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
291
ALC668_FIXUP_ASUS_Nx51,
292
ALC668_FIXUP_MIC_COEF,
293
ALC668_FIXUP_ASUS_G751,
294
ALC891_FIXUP_HEADSET_MODE,
295
ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
296
ALC662_FIXUP_ACER_VERITON,
297
ALC892_FIXUP_ASROCK_MOBO,
298
ALC662_FIXUP_USI_FUNC,
299
ALC662_FIXUP_USI_HEADSET_MODE,
300
ALC662_FIXUP_LENOVO_MULTI_CODECS,
301
ALC669_FIXUP_ACER_ASPIRE_ETHOS,
302
ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
303
ALC671_FIXUP_HP_HEADSET_MIC2,
304
ALC662_FIXUP_ACER_X2660G_HEADSET_MODE,
305
ALC662_FIXUP_ACER_NITRO_HEADSET_MODE,
306
ALC668_FIXUP_ASUS_NO_HEADSET_MIC,
307
ALC668_FIXUP_HEADSET_MIC,
308
ALC668_FIXUP_MIC_DET_COEF,
309
ALC897_FIXUP_LENOVO_HEADSET_MIC,
310
ALC897_FIXUP_HEADSET_MIC_PIN,
311
ALC897_FIXUP_HP_HSMIC_VERB,
312
ALC897_FIXUP_LENOVO_HEADSET_MODE,
313
ALC897_FIXUP_HEADSET_MIC_PIN2,
314
ALC897_FIXUP_UNIS_H3C_X500S,
315
ALC897_FIXUP_HEADSET_MIC_PIN3,
316
};
317
318
static const struct hda_fixup alc662_fixups[] = {
319
[ALC662_FIXUP_ASPIRE] = {
320
.type = HDA_FIXUP_PINS,
321
.v.pins = (const struct hda_pintbl[]) {
322
{ 0x15, 0x99130112 }, /* subwoofer */
323
{ }
324
}
325
},
326
[ALC662_FIXUP_LED_GPIO1] = {
327
.type = HDA_FIXUP_FUNC,
328
.v.func = alc662_fixup_led_gpio1,
329
},
330
[ALC662_FIXUP_IDEAPAD] = {
331
.type = HDA_FIXUP_PINS,
332
.v.pins = (const struct hda_pintbl[]) {
333
{ 0x17, 0x99130112 }, /* subwoofer */
334
{ }
335
},
336
.chained = true,
337
.chain_id = ALC662_FIXUP_LED_GPIO1,
338
},
339
[ALC272_FIXUP_MARIO] = {
340
.type = HDA_FIXUP_FUNC,
341
.v.func = alc272_fixup_mario,
342
},
343
[ALC662_FIXUP_CZC_ET26] = {
344
.type = HDA_FIXUP_PINS,
345
.v.pins = (const struct hda_pintbl[]) {
346
{0x12, 0x403cc000},
347
{0x14, 0x90170110}, /* speaker */
348
{0x15, 0x411111f0},
349
{0x16, 0x411111f0},
350
{0x18, 0x01a19030}, /* mic */
351
{0x19, 0x90a7013f}, /* int-mic */
352
{0x1a, 0x01014020},
353
{0x1b, 0x0121401f},
354
{0x1c, 0x411111f0},
355
{0x1d, 0x411111f0},
356
{0x1e, 0x40478e35},
357
{}
358
},
359
.chained = true,
360
.chain_id = ALC662_FIXUP_SKU_IGNORE
361
},
362
[ALC662_FIXUP_CZC_P10T] = {
363
.type = HDA_FIXUP_VERBS,
364
.v.verbs = (const struct hda_verb[]) {
365
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
366
{}
367
}
368
},
369
[ALC662_FIXUP_SKU_IGNORE] = {
370
.type = HDA_FIXUP_FUNC,
371
.v.func = alc_fixup_sku_ignore,
372
},
373
[ALC662_FIXUP_HP_RP5800] = {
374
.type = HDA_FIXUP_PINS,
375
.v.pins = (const struct hda_pintbl[]) {
376
{ 0x14, 0x0221201f }, /* HP out */
377
{ }
378
},
379
.chained = true,
380
.chain_id = ALC662_FIXUP_SKU_IGNORE
381
},
382
[ALC662_FIXUP_ASUS_MODE1] = {
383
.type = HDA_FIXUP_PINS,
384
.v.pins = (const struct hda_pintbl[]) {
385
{ 0x14, 0x99130110 }, /* speaker */
386
{ 0x18, 0x01a19c20 }, /* mic */
387
{ 0x19, 0x99a3092f }, /* int-mic */
388
{ 0x21, 0x0121401f }, /* HP out */
389
{ }
390
},
391
.chained = true,
392
.chain_id = ALC662_FIXUP_SKU_IGNORE
393
},
394
[ALC662_FIXUP_ASUS_MODE2] = {
395
.type = HDA_FIXUP_PINS,
396
.v.pins = (const struct hda_pintbl[]) {
397
{ 0x14, 0x99130110 }, /* speaker */
398
{ 0x18, 0x01a19820 }, /* mic */
399
{ 0x19, 0x99a3092f }, /* int-mic */
400
{ 0x1b, 0x0121401f }, /* HP out */
401
{ }
402
},
403
.chained = true,
404
.chain_id = ALC662_FIXUP_SKU_IGNORE
405
},
406
[ALC662_FIXUP_ASUS_MODE3] = {
407
.type = HDA_FIXUP_PINS,
408
.v.pins = (const struct hda_pintbl[]) {
409
{ 0x14, 0x99130110 }, /* speaker */
410
{ 0x15, 0x0121441f }, /* HP */
411
{ 0x18, 0x01a19840 }, /* mic */
412
{ 0x19, 0x99a3094f }, /* int-mic */
413
{ 0x21, 0x01211420 }, /* HP2 */
414
{ }
415
},
416
.chained = true,
417
.chain_id = ALC662_FIXUP_SKU_IGNORE
418
},
419
[ALC662_FIXUP_ASUS_MODE4] = {
420
.type = HDA_FIXUP_PINS,
421
.v.pins = (const struct hda_pintbl[]) {
422
{ 0x14, 0x99130110 }, /* speaker */
423
{ 0x16, 0x99130111 }, /* speaker */
424
{ 0x18, 0x01a19840 }, /* mic */
425
{ 0x19, 0x99a3094f }, /* int-mic */
426
{ 0x21, 0x0121441f }, /* HP */
427
{ }
428
},
429
.chained = true,
430
.chain_id = ALC662_FIXUP_SKU_IGNORE
431
},
432
[ALC662_FIXUP_ASUS_MODE5] = {
433
.type = HDA_FIXUP_PINS,
434
.v.pins = (const struct hda_pintbl[]) {
435
{ 0x14, 0x99130110 }, /* speaker */
436
{ 0x15, 0x0121441f }, /* HP */
437
{ 0x16, 0x99130111 }, /* speaker */
438
{ 0x18, 0x01a19840 }, /* mic */
439
{ 0x19, 0x99a3094f }, /* int-mic */
440
{ }
441
},
442
.chained = true,
443
.chain_id = ALC662_FIXUP_SKU_IGNORE
444
},
445
[ALC662_FIXUP_ASUS_MODE6] = {
446
.type = HDA_FIXUP_PINS,
447
.v.pins = (const struct hda_pintbl[]) {
448
{ 0x14, 0x99130110 }, /* speaker */
449
{ 0x15, 0x01211420 }, /* HP2 */
450
{ 0x18, 0x01a19840 }, /* mic */
451
{ 0x19, 0x99a3094f }, /* int-mic */
452
{ 0x1b, 0x0121441f }, /* HP */
453
{ }
454
},
455
.chained = true,
456
.chain_id = ALC662_FIXUP_SKU_IGNORE
457
},
458
[ALC662_FIXUP_ASUS_MODE7] = {
459
.type = HDA_FIXUP_PINS,
460
.v.pins = (const struct hda_pintbl[]) {
461
{ 0x14, 0x99130110 }, /* speaker */
462
{ 0x17, 0x99130111 }, /* speaker */
463
{ 0x18, 0x01a19840 }, /* mic */
464
{ 0x19, 0x99a3094f }, /* int-mic */
465
{ 0x1b, 0x01214020 }, /* HP */
466
{ 0x21, 0x0121401f }, /* HP */
467
{ }
468
},
469
.chained = true,
470
.chain_id = ALC662_FIXUP_SKU_IGNORE
471
},
472
[ALC662_FIXUP_ASUS_MODE8] = {
473
.type = HDA_FIXUP_PINS,
474
.v.pins = (const struct hda_pintbl[]) {
475
{ 0x14, 0x99130110 }, /* speaker */
476
{ 0x12, 0x99a30970 }, /* int-mic */
477
{ 0x15, 0x01214020 }, /* HP */
478
{ 0x17, 0x99130111 }, /* speaker */
479
{ 0x18, 0x01a19840 }, /* mic */
480
{ 0x21, 0x0121401f }, /* HP */
481
{ }
482
},
483
.chained = true,
484
.chain_id = ALC662_FIXUP_SKU_IGNORE
485
},
486
[ALC662_FIXUP_NO_JACK_DETECT] = {
487
.type = HDA_FIXUP_FUNC,
488
.v.func = alc_fixup_no_jack_detect,
489
},
490
[ALC662_FIXUP_ZOTAC_Z68] = {
491
.type = HDA_FIXUP_PINS,
492
.v.pins = (const struct hda_pintbl[]) {
493
{ 0x1b, 0x02214020 }, /* Front HP */
494
{ }
495
}
496
},
497
[ALC662_FIXUP_INV_DMIC] = {
498
.type = HDA_FIXUP_FUNC,
499
.v.func = alc_fixup_inv_dmic,
500
},
501
[ALC668_FIXUP_DELL_XPS13] = {
502
.type = HDA_FIXUP_FUNC,
503
.v.func = alc_fixup_dell_xps13,
504
.chained = true,
505
.chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
506
},
507
[ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
508
.type = HDA_FIXUP_FUNC,
509
.v.func = alc_fixup_disable_aamix,
510
.chained = true,
511
.chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
512
},
513
[ALC668_FIXUP_AUTO_MUTE] = {
514
.type = HDA_FIXUP_FUNC,
515
.v.func = alc_fixup_auto_mute_via_amp,
516
.chained = true,
517
.chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
518
},
519
[ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
520
.type = HDA_FIXUP_PINS,
521
.v.pins = (const struct hda_pintbl[]) {
522
{ 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
523
/* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
524
{ }
525
},
526
.chained = true,
527
.chain_id = ALC662_FIXUP_HEADSET_MODE
528
},
529
[ALC662_FIXUP_HEADSET_MODE] = {
530
.type = HDA_FIXUP_FUNC,
531
.v.func = alc_fixup_headset_mode_alc662,
532
},
533
[ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
534
.type = HDA_FIXUP_PINS,
535
.v.pins = (const struct hda_pintbl[]) {
536
{ 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
537
{ 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
538
{ }
539
},
540
.chained = true,
541
.chain_id = ALC668_FIXUP_HEADSET_MODE
542
},
543
[ALC668_FIXUP_HEADSET_MODE] = {
544
.type = HDA_FIXUP_FUNC,
545
.v.func = alc_fixup_headset_mode_alc668,
546
},
547
[ALC662_FIXUP_BASS_MODE4_CHMAP] = {
548
.type = HDA_FIXUP_FUNC,
549
.v.func = alc_fixup_bass_chmap,
550
.chained = true,
551
.chain_id = ALC662_FIXUP_ASUS_MODE4
552
},
553
[ALC662_FIXUP_BASS_16] = {
554
.type = HDA_FIXUP_PINS,
555
.v.pins = (const struct hda_pintbl[]) {
556
{0x16, 0x80106111}, /* bass speaker */
557
{}
558
},
559
.chained = true,
560
.chain_id = ALC662_FIXUP_BASS_CHMAP,
561
},
562
[ALC662_FIXUP_BASS_1A] = {
563
.type = HDA_FIXUP_PINS,
564
.v.pins = (const struct hda_pintbl[]) {
565
{0x1a, 0x80106111}, /* bass speaker */
566
{}
567
},
568
.chained = true,
569
.chain_id = ALC662_FIXUP_BASS_CHMAP,
570
},
571
[ALC662_FIXUP_BASS_CHMAP] = {
572
.type = HDA_FIXUP_FUNC,
573
.v.func = alc_fixup_bass_chmap,
574
},
575
[ALC662_FIXUP_ASUS_Nx50] = {
576
.type = HDA_FIXUP_FUNC,
577
.v.func = alc_fixup_auto_mute_via_amp,
578
.chained = true,
579
.chain_id = ALC662_FIXUP_BASS_1A
580
},
581
[ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
582
.type = HDA_FIXUP_FUNC,
583
.v.func = alc_fixup_headset_mode_alc668,
584
.chain_id = ALC662_FIXUP_BASS_CHMAP
585
},
586
[ALC668_FIXUP_ASUS_Nx51] = {
587
.type = HDA_FIXUP_PINS,
588
.v.pins = (const struct hda_pintbl[]) {
589
{ 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
590
{ 0x1a, 0x90170151 }, /* bass speaker */
591
{ 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
592
{}
593
},
594
.chained = true,
595
.chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
596
},
597
[ALC668_FIXUP_MIC_COEF] = {
598
.type = HDA_FIXUP_VERBS,
599
.v.verbs = (const struct hda_verb[]) {
600
{ 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
601
{ 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
602
{}
603
},
604
},
605
[ALC668_FIXUP_ASUS_G751] = {
606
.type = HDA_FIXUP_PINS,
607
.v.pins = (const struct hda_pintbl[]) {
608
{ 0x16, 0x0421101f }, /* HP */
609
{}
610
},
611
.chained = true,
612
.chain_id = ALC668_FIXUP_MIC_COEF
613
},
614
[ALC891_FIXUP_HEADSET_MODE] = {
615
.type = HDA_FIXUP_FUNC,
616
.v.func = alc_fixup_headset_mode,
617
},
618
[ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
619
.type = HDA_FIXUP_PINS,
620
.v.pins = (const struct hda_pintbl[]) {
621
{ 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
622
{ 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
623
{ }
624
},
625
.chained = true,
626
.chain_id = ALC891_FIXUP_HEADSET_MODE
627
},
628
[ALC662_FIXUP_ACER_VERITON] = {
629
.type = HDA_FIXUP_PINS,
630
.v.pins = (const struct hda_pintbl[]) {
631
{ 0x15, 0x50170120 }, /* no internal speaker */
632
{ }
633
}
634
},
635
[ALC892_FIXUP_ASROCK_MOBO] = {
636
.type = HDA_FIXUP_PINS,
637
.v.pins = (const struct hda_pintbl[]) {
638
{ 0x15, 0x40f000f0 }, /* disabled */
639
{ 0x16, 0x40f000f0 }, /* disabled */
640
{ }
641
}
642
},
643
[ALC662_FIXUP_USI_FUNC] = {
644
.type = HDA_FIXUP_FUNC,
645
.v.func = alc662_fixup_usi_headset_mic,
646
},
647
[ALC662_FIXUP_USI_HEADSET_MODE] = {
648
.type = HDA_FIXUP_PINS,
649
.v.pins = (const struct hda_pintbl[]) {
650
{ 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
651
{ 0x18, 0x01a1903d },
652
{ }
653
},
654
.chained = true,
655
.chain_id = ALC662_FIXUP_USI_FUNC
656
},
657
[ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
658
.type = HDA_FIXUP_FUNC,
659
.v.func = alc233_alc662_fixup_lenovo_dual_codecs,
660
},
661
[ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET] = {
662
.type = HDA_FIXUP_FUNC,
663
.v.func = alc662_fixup_aspire_ethos_hp,
664
},
665
[ALC669_FIXUP_ACER_ASPIRE_ETHOS] = {
666
.type = HDA_FIXUP_PINS,
667
.v.pins = (const struct hda_pintbl[]) {
668
{ 0x15, 0x92130110 }, /* front speakers */
669
{ 0x18, 0x99130111 }, /* center/subwoofer */
670
{ 0x1b, 0x11130012 }, /* surround plus jack for HP */
671
{ }
672
},
673
.chained = true,
674
.chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
675
},
676
[ALC671_FIXUP_HP_HEADSET_MIC2] = {
677
.type = HDA_FIXUP_FUNC,
678
.v.func = alc671_fixup_hp_headset_mic2,
679
},
680
[ALC662_FIXUP_ACER_X2660G_HEADSET_MODE] = {
681
.type = HDA_FIXUP_PINS,
682
.v.pins = (const struct hda_pintbl[]) {
683
{ 0x1a, 0x02a1113c }, /* use as headset mic, without its own jack detect */
684
{ }
685
},
686
.chained = true,
687
.chain_id = ALC662_FIXUP_USI_FUNC
688
},
689
[ALC662_FIXUP_ACER_NITRO_HEADSET_MODE] = {
690
.type = HDA_FIXUP_PINS,
691
.v.pins = (const struct hda_pintbl[]) {
692
{ 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
693
{ 0x1b, 0x0221144f },
694
{ }
695
},
696
.chained = true,
697
.chain_id = ALC662_FIXUP_USI_FUNC
698
},
699
[ALC668_FIXUP_ASUS_NO_HEADSET_MIC] = {
700
.type = HDA_FIXUP_PINS,
701
.v.pins = (const struct hda_pintbl[]) {
702
{ 0x1b, 0x04a1112c },
703
{ }
704
},
705
.chained = true,
706
.chain_id = ALC668_FIXUP_HEADSET_MIC
707
},
708
[ALC668_FIXUP_HEADSET_MIC] = {
709
.type = HDA_FIXUP_FUNC,
710
.v.func = alc_fixup_headset_mic,
711
.chained = true,
712
.chain_id = ALC668_FIXUP_MIC_DET_COEF
713
},
714
[ALC668_FIXUP_MIC_DET_COEF] = {
715
.type = HDA_FIXUP_VERBS,
716
.v.verbs = (const struct hda_verb[]) {
717
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x15 },
718
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0d60 },
719
{}
720
},
721
},
722
[ALC897_FIXUP_LENOVO_HEADSET_MIC] = {
723
.type = HDA_FIXUP_FUNC,
724
.v.func = alc897_fixup_lenovo_headset_mic,
725
},
726
[ALC897_FIXUP_HEADSET_MIC_PIN] = {
727
.type = HDA_FIXUP_PINS,
728
.v.pins = (const struct hda_pintbl[]) {
729
{ 0x1a, 0x03a11050 },
730
{ }
731
},
732
.chained = true,
733
.chain_id = ALC897_FIXUP_LENOVO_HEADSET_MIC
734
},
735
[ALC897_FIXUP_HP_HSMIC_VERB] = {
736
.type = HDA_FIXUP_PINS,
737
.v.pins = (const struct hda_pintbl[]) {
738
{ 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
739
{ }
740
},
741
},
742
[ALC897_FIXUP_LENOVO_HEADSET_MODE] = {
743
.type = HDA_FIXUP_FUNC,
744
.v.func = alc897_fixup_lenovo_headset_mode,
745
},
746
[ALC897_FIXUP_HEADSET_MIC_PIN2] = {
747
.type = HDA_FIXUP_PINS,
748
.v.pins = (const struct hda_pintbl[]) {
749
{ 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
750
{ }
751
},
752
.chained = true,
753
.chain_id = ALC897_FIXUP_LENOVO_HEADSET_MODE
754
},
755
[ALC897_FIXUP_UNIS_H3C_X500S] = {
756
.type = HDA_FIXUP_VERBS,
757
.v.verbs = (const struct hda_verb[]) {
758
{ 0x14, AC_VERB_SET_EAPD_BTLENABLE, 0 },
759
{}
760
},
761
},
762
[ALC897_FIXUP_HEADSET_MIC_PIN3] = {
763
.type = HDA_FIXUP_PINS,
764
.v.pins = (const struct hda_pintbl[]) {
765
{ 0x19, 0x03a11050 }, /* use as headset mic */
766
{ }
767
},
768
},
769
};
770
771
static const struct hda_quirk alc662_fixup_tbl[] = {
772
SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
773
SND_PCI_QUIRK(0x1019, 0x9859, "JP-IK LEAP W502", ALC897_FIXUP_HEADSET_MIC_PIN3),
774
SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
775
SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
776
SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
777
SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
778
SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
779
SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
780
SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
781
SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
782
SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE),
783
SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE),
784
SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
785
SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
786
SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
787
SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
788
SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
789
SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
790
SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
791
SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
792
SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
793
SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
794
SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
795
SND_PCI_QUIRK(0x103c, 0x870c, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
796
SND_PCI_QUIRK(0x103c, 0x8719, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
797
SND_PCI_QUIRK(0x103c, 0x872b, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
798
SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
799
SND_PCI_QUIRK(0x103c, 0x8768, "HP Slim Desktop S01", ALC671_FIXUP_HP_HEADSET_MIC2),
800
SND_PCI_QUIRK(0x103c, 0x877e, "HP 288 Pro G6", ALC671_FIXUP_HP_HEADSET_MIC2),
801
SND_PCI_QUIRK(0x103c, 0x885f, "HP 288 Pro G8", ALC671_FIXUP_HP_HEADSET_MIC2),
802
SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
803
SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
804
SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
805
SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
806
SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
807
SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
808
SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
809
SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
810
SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
811
SND_PCI_QUIRK(0x1043, 0x185d, "ASUS G551JW", ALC668_FIXUP_ASUS_NO_HEADSET_MIC),
812
SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
813
SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
814
SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
815
SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
816
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
817
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
818
SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
819
SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
820
SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN),
821
SND_PCI_QUIRK(0x17aa, 0x1064, "Lenovo P3 Tower", ALC897_FIXUP_HEADSET_MIC_PIN),
822
SND_PCI_QUIRK(0x17aa, 0x32ca, "Lenovo ThinkCentre M80", ALC897_FIXUP_HEADSET_MIC_PIN),
823
SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN),
824
SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN),
825
SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN),
826
SND_PCI_QUIRK(0x17aa, 0x3321, "Lenovo ThinkCentre M70 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN),
827
SND_PCI_QUIRK(0x17aa, 0x331b, "Lenovo ThinkCentre M90 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN),
828
SND_PCI_QUIRK(0x17aa, 0x3364, "Lenovo ThinkCentre M90 Gen5", ALC897_FIXUP_HEADSET_MIC_PIN),
829
SND_PCI_QUIRK(0x17aa, 0x3742, "Lenovo TianYi510Pro-14IOB", ALC897_FIXUP_HEADSET_MIC_PIN2),
830
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
831
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
832
SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
833
SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
834
SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
835
SND_PCI_QUIRK(0x1b35, 0x1234, "CZC ET26", ALC662_FIXUP_CZC_ET26),
836
SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
837
SND_PCI_QUIRK(0x1c6c, 0x1239, "Compaq N14JP6-V2", ALC897_FIXUP_HP_HSMIC_VERB),
838
839
#if 0
840
/* Below is a quirk table taken from the old code.
841
* Basically the device should work as is without the fixup table.
842
* If BIOS doesn't give a proper info, enable the corresponding
843
* fixup entry.
844
*/
845
SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
846
SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
847
SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
848
SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
849
SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
850
SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
851
SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
852
SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
853
SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
854
SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
855
SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
856
SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
857
SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
858
SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
859
SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
860
SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
861
SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
862
SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
863
SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
864
SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
865
SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
866
SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
867
SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
868
SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
869
SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
870
SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
871
SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
872
SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
873
SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
874
SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
875
SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
876
SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
877
SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
878
SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
879
SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
880
SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
881
SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
882
SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
883
SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
884
SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
885
SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
886
SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
887
SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
888
SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
889
SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
890
SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
891
SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
892
SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
893
SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
894
SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
895
#endif
896
{}
897
};
898
899
static const struct hda_model_fixup alc662_fixup_models[] = {
900
{.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
901
{.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
902
{.id = ALC272_FIXUP_MARIO, .name = "mario"},
903
{.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
904
{.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
905
{.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
906
{.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
907
{.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
908
{.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
909
{.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
910
{.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
911
{.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
912
{.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
913
{.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
914
{.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
915
{.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
916
{.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
917
{.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
918
{.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
919
{.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
920
{.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
921
{.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
922
{.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
923
{.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
924
{.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
925
{.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
926
{.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
927
{.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
928
{.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
929
{.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
930
{.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
931
{.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
932
{.id = ALC897_FIXUP_UNIS_H3C_X500S, .name = "unis-h3c-x500s"},
933
{}
934
};
935
936
static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
937
SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
938
{0x17, 0x02211010},
939
{0x18, 0x01a19030},
940
{0x1a, 0x01813040},
941
{0x21, 0x01014020}),
942
SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
943
{0x16, 0x01813030},
944
{0x17, 0x02211010},
945
{0x18, 0x01a19040},
946
{0x21, 0x01014020}),
947
SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
948
{0x14, 0x01014010},
949
{0x18, 0x01a19020},
950
{0x1a, 0x0181302f},
951
{0x1b, 0x0221401f}),
952
SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
953
{0x12, 0x99a30130},
954
{0x14, 0x90170110},
955
{0x15, 0x0321101f},
956
{0x16, 0x03011020}),
957
SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
958
{0x12, 0x99a30140},
959
{0x14, 0x90170110},
960
{0x15, 0x0321101f},
961
{0x16, 0x03011020}),
962
SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
963
{0x12, 0x99a30150},
964
{0x14, 0x90170110},
965
{0x15, 0x0321101f},
966
{0x16, 0x03011020}),
967
SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
968
{0x14, 0x90170110},
969
{0x15, 0x0321101f},
970
{0x16, 0x03011020}),
971
SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
972
{0x12, 0x90a60130},
973
{0x14, 0x90170110},
974
{0x15, 0x0321101f}),
975
SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
976
{0x14, 0x01014010},
977
{0x17, 0x90170150},
978
{0x19, 0x02a11060},
979
{0x1b, 0x01813030},
980
{0x21, 0x02211020}),
981
SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
982
{0x14, 0x01014010},
983
{0x18, 0x01a19040},
984
{0x1b, 0x01813030},
985
{0x21, 0x02211020}),
986
SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
987
{0x14, 0x01014020},
988
{0x17, 0x90170110},
989
{0x18, 0x01a19050},
990
{0x1b, 0x01813040},
991
{0x21, 0x02211030}),
992
{}
993
};
994
995
/*
996
*/
997
static int alc662_probe(struct hda_codec *codec, const struct hda_device_id *id)
998
{
999
struct alc_spec *spec;
1000
int err;
1001
1002
err = alc_alloc_spec(codec, 0x0b);
1003
if (err < 0)
1004
return err;
1005
1006
spec = codec->spec;
1007
1008
spec->shutup = alc_eapd_shutup;
1009
1010
/* handle multiple HPs as is */
1011
spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
1012
1013
alc_fix_pll_init(codec, 0x20, 0x04, 15);
1014
1015
switch (codec->core.vendor_id) {
1016
case 0x10ec0668:
1017
spec->init_hook = alc668_restore_default_value;
1018
break;
1019
}
1020
1021
alc_pre_init(codec);
1022
1023
snd_hda_pick_fixup(codec, alc662_fixup_models,
1024
alc662_fixup_tbl, alc662_fixups);
1025
snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups, true);
1026
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1027
1028
alc_auto_parse_customize_define(codec);
1029
1030
if (has_cdefine_beep(codec))
1031
spec->gen.beep_nid = 0x01;
1032
1033
if ((alc_get_coef0(codec) & (1 << 14)) &&
1034
codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
1035
spec->cdefine.platform_type == 1) {
1036
err = alc_codec_rename(codec, "ALC272X");
1037
if (err < 0)
1038
goto error;
1039
}
1040
1041
/* automatic parse from the BIOS config */
1042
err = alc662_parse_auto_config(codec);
1043
if (err < 0)
1044
goto error;
1045
1046
if (!spec->gen.no_analog && spec->gen.beep_nid) {
1047
switch (codec->core.vendor_id) {
1048
case 0x10ec0662:
1049
err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1050
break;
1051
case 0x10ec0272:
1052
case 0x10ec0663:
1053
case 0x10ec0665:
1054
case 0x10ec0668:
1055
err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
1056
break;
1057
case 0x10ec0273:
1058
err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
1059
break;
1060
}
1061
if (err < 0)
1062
goto error;
1063
}
1064
1065
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1066
1067
return 0;
1068
1069
error:
1070
snd_hda_gen_remove(codec);
1071
return err;
1072
}
1073
1074
static const struct hda_codec_ops alc662_codec_ops = {
1075
.probe = alc662_probe,
1076
.remove = snd_hda_gen_remove,
1077
.build_controls = alc_build_controls,
1078
.build_pcms = snd_hda_gen_build_pcms,
1079
.init = alc_init,
1080
.unsol_event = snd_hda_jack_unsol_event,
1081
.resume = alc_resume,
1082
.suspend = alc_suspend,
1083
.check_power_status = snd_hda_gen_check_power_status,
1084
.stream_pm = snd_hda_gen_stream_pm,
1085
};
1086
1087
/*
1088
* driver entries
1089
*/
1090
static const struct hda_device_id snd_hda_id_alc662[] = {
1091
HDA_CODEC_ID(0x10ec0272, "ALC272"),
1092
HDA_CODEC_ID_REV(0x10ec0662, 0x100101, "ALC662 rev1"),
1093
HDA_CODEC_ID_REV(0x10ec0662, 0x100300, "ALC662 rev3"),
1094
HDA_CODEC_ID(0x10ec0663, "ALC663"),
1095
HDA_CODEC_ID(0x10ec0665, "ALC665"),
1096
HDA_CODEC_ID(0x10ec0667, "ALC667"),
1097
HDA_CODEC_ID(0x10ec0668, "ALC668"),
1098
HDA_CODEC_ID(0x10ec0670, "ALC670"),
1099
HDA_CODEC_ID(0x10ec0671, "ALC671"),
1100
HDA_CODEC_ID(0x10ec0867, "ALC891"),
1101
HDA_CODEC_ID(0x10ec0892, "ALC892"),
1102
HDA_CODEC_ID(0x10ec0897, "ALC897"),
1103
{} /* terminator */
1104
};
1105
MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_alc662);
1106
1107
MODULE_LICENSE("GPL");
1108
MODULE_DESCRIPTION("Realtek ALC662 and compatible HD-audio codec");
1109
MODULE_IMPORT_NS("SND_HDA_CODEC_REALTEK");
1110
1111
static struct hda_codec_driver alc662_driver = {
1112
.id = snd_hda_id_alc662,
1113
.ops = &alc662_codec_ops,
1114
};
1115
1116
module_hda_codec_driver(alc662_driver);
1117
1118