Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/pci/hda/patch_realtek.c
17507 views
1
/*
2
* Universal Interface for Intel High Definition Audio Codec
3
*
4
* HD audio interface patch for ALC 260/880/882 codecs
5
*
6
* Copyright (c) 2004 Kailang Yang <[email protected]>
7
* PeiSen Hou <[email protected]>
8
* Takashi Iwai <[email protected]>
9
* Jonathan Woithe <[email protected]>
10
*
11
* This driver is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
15
*
16
* This driver is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
20
*
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
*/
25
26
#include <linux/init.h>
27
#include <linux/delay.h>
28
#include <linux/slab.h>
29
#include <linux/pci.h>
30
#include <sound/core.h>
31
#include <sound/jack.h>
32
#include "hda_codec.h"
33
#include "hda_local.h"
34
#include "hda_beep.h"
35
36
#define ALC880_FRONT_EVENT 0x01
37
#define ALC880_DCVOL_EVENT 0x02
38
#define ALC880_HP_EVENT 0x04
39
#define ALC880_MIC_EVENT 0x08
40
41
/* ALC880 board config type */
42
enum {
43
ALC880_3ST,
44
ALC880_3ST_DIG,
45
ALC880_5ST,
46
ALC880_5ST_DIG,
47
ALC880_W810,
48
ALC880_Z71V,
49
ALC880_6ST,
50
ALC880_6ST_DIG,
51
ALC880_F1734,
52
ALC880_ASUS,
53
ALC880_ASUS_DIG,
54
ALC880_ASUS_W1V,
55
ALC880_ASUS_DIG2,
56
ALC880_FUJITSU,
57
ALC880_UNIWILL_DIG,
58
ALC880_UNIWILL,
59
ALC880_UNIWILL_P53,
60
ALC880_CLEVO,
61
ALC880_TCL_S700,
62
ALC880_LG,
63
ALC880_LG_LW,
64
ALC880_MEDION_RIM,
65
#ifdef CONFIG_SND_DEBUG
66
ALC880_TEST,
67
#endif
68
ALC880_AUTO,
69
ALC880_MODEL_LAST /* last tag */
70
};
71
72
/* ALC260 models */
73
enum {
74
ALC260_BASIC,
75
ALC260_HP,
76
ALC260_HP_DC7600,
77
ALC260_HP_3013,
78
ALC260_FUJITSU_S702X,
79
ALC260_ACER,
80
ALC260_WILL,
81
ALC260_REPLACER_672V,
82
ALC260_FAVORIT100,
83
#ifdef CONFIG_SND_DEBUG
84
ALC260_TEST,
85
#endif
86
ALC260_AUTO,
87
ALC260_MODEL_LAST /* last tag */
88
};
89
90
/* ALC262 models */
91
enum {
92
ALC262_BASIC,
93
ALC262_HIPPO,
94
ALC262_HIPPO_1,
95
ALC262_FUJITSU,
96
ALC262_HP_BPC,
97
ALC262_HP_BPC_D7000_WL,
98
ALC262_HP_BPC_D7000_WF,
99
ALC262_HP_TC_T5735,
100
ALC262_HP_RP5700,
101
ALC262_BENQ_ED8,
102
ALC262_SONY_ASSAMD,
103
ALC262_BENQ_T31,
104
ALC262_ULTRA,
105
ALC262_LENOVO_3000,
106
ALC262_NEC,
107
ALC262_TOSHIBA_S06,
108
ALC262_TOSHIBA_RX1,
109
ALC262_TYAN,
110
ALC262_AUTO,
111
ALC262_MODEL_LAST /* last tag */
112
};
113
114
/* ALC268 models */
115
enum {
116
ALC267_QUANTA_IL1,
117
ALC268_3ST,
118
ALC268_TOSHIBA,
119
ALC268_ACER,
120
ALC268_ACER_DMIC,
121
ALC268_ACER_ASPIRE_ONE,
122
ALC268_DELL,
123
ALC268_ZEPTO,
124
#ifdef CONFIG_SND_DEBUG
125
ALC268_TEST,
126
#endif
127
ALC268_AUTO,
128
ALC268_MODEL_LAST /* last tag */
129
};
130
131
/* ALC269 models */
132
enum {
133
ALC269_BASIC,
134
ALC269_QUANTA_FL1,
135
ALC269_AMIC,
136
ALC269_DMIC,
137
ALC269VB_AMIC,
138
ALC269VB_DMIC,
139
ALC269_FUJITSU,
140
ALC269_LIFEBOOK,
141
ALC271_ACER,
142
ALC269_AUTO,
143
ALC269_MODEL_LAST /* last tag */
144
};
145
146
/* ALC861 models */
147
enum {
148
ALC861_3ST,
149
ALC660_3ST,
150
ALC861_3ST_DIG,
151
ALC861_6ST_DIG,
152
ALC861_UNIWILL_M31,
153
ALC861_TOSHIBA,
154
ALC861_ASUS,
155
ALC861_ASUS_LAPTOP,
156
ALC861_AUTO,
157
ALC861_MODEL_LAST,
158
};
159
160
/* ALC861-VD models */
161
enum {
162
ALC660VD_3ST,
163
ALC660VD_3ST_DIG,
164
ALC660VD_ASUS_V1S,
165
ALC861VD_3ST,
166
ALC861VD_3ST_DIG,
167
ALC861VD_6ST_DIG,
168
ALC861VD_LENOVO,
169
ALC861VD_DALLAS,
170
ALC861VD_HP,
171
ALC861VD_AUTO,
172
ALC861VD_MODEL_LAST,
173
};
174
175
/* ALC662 models */
176
enum {
177
ALC662_3ST_2ch_DIG,
178
ALC662_3ST_6ch_DIG,
179
ALC662_3ST_6ch,
180
ALC662_5ST_DIG,
181
ALC662_LENOVO_101E,
182
ALC662_ASUS_EEEPC_P701,
183
ALC662_ASUS_EEEPC_EP20,
184
ALC663_ASUS_M51VA,
185
ALC663_ASUS_G71V,
186
ALC663_ASUS_H13,
187
ALC663_ASUS_G50V,
188
ALC662_ECS,
189
ALC663_ASUS_MODE1,
190
ALC662_ASUS_MODE2,
191
ALC663_ASUS_MODE3,
192
ALC663_ASUS_MODE4,
193
ALC663_ASUS_MODE5,
194
ALC663_ASUS_MODE6,
195
ALC663_ASUS_MODE7,
196
ALC663_ASUS_MODE8,
197
ALC272_DELL,
198
ALC272_DELL_ZM1,
199
ALC272_SAMSUNG_NC10,
200
ALC662_AUTO,
201
ALC662_MODEL_LAST,
202
};
203
204
/* ALC882 models */
205
enum {
206
ALC882_3ST_DIG,
207
ALC882_6ST_DIG,
208
ALC882_ARIMA,
209
ALC882_W2JC,
210
ALC882_TARGA,
211
ALC882_ASUS_A7J,
212
ALC882_ASUS_A7M,
213
ALC885_MACPRO,
214
ALC885_MBA21,
215
ALC885_MBP3,
216
ALC885_MB5,
217
ALC885_MACMINI3,
218
ALC885_IMAC24,
219
ALC885_IMAC91,
220
ALC883_3ST_2ch_DIG,
221
ALC883_3ST_6ch_DIG,
222
ALC883_3ST_6ch,
223
ALC883_6ST_DIG,
224
ALC883_TARGA_DIG,
225
ALC883_TARGA_2ch_DIG,
226
ALC883_TARGA_8ch_DIG,
227
ALC883_ACER,
228
ALC883_ACER_ASPIRE,
229
ALC888_ACER_ASPIRE_4930G,
230
ALC888_ACER_ASPIRE_6530G,
231
ALC888_ACER_ASPIRE_8930G,
232
ALC888_ACER_ASPIRE_7730G,
233
ALC883_MEDION,
234
ALC883_MEDION_WIM2160,
235
ALC883_LAPTOP_EAPD,
236
ALC883_LENOVO_101E_2ch,
237
ALC883_LENOVO_NB0763,
238
ALC888_LENOVO_MS7195_DIG,
239
ALC888_LENOVO_SKY,
240
ALC883_HAIER_W66,
241
ALC888_3ST_HP,
242
ALC888_6ST_DELL,
243
ALC883_MITAC,
244
ALC883_CLEVO_M540R,
245
ALC883_CLEVO_M720,
246
ALC883_FUJITSU_PI2515,
247
ALC888_FUJITSU_XA3530,
248
ALC883_3ST_6ch_INTEL,
249
ALC889A_INTEL,
250
ALC889_INTEL,
251
ALC888_ASUS_M90V,
252
ALC888_ASUS_EEE1601,
253
ALC889A_MB31,
254
ALC1200_ASUS_P5Q,
255
ALC883_SONY_VAIO_TT,
256
ALC882_AUTO,
257
ALC882_MODEL_LAST,
258
};
259
260
/* ALC680 models */
261
enum {
262
ALC680_BASE,
263
ALC680_AUTO,
264
ALC680_MODEL_LAST,
265
};
266
267
/* for GPIO Poll */
268
#define GPIO_MASK 0x03
269
270
/* extra amp-initialization sequence types */
271
enum {
272
ALC_INIT_NONE,
273
ALC_INIT_DEFAULT,
274
ALC_INIT_GPIO1,
275
ALC_INIT_GPIO2,
276
ALC_INIT_GPIO3,
277
};
278
279
struct alc_mic_route {
280
hda_nid_t pin;
281
unsigned char mux_idx;
282
unsigned char amix_idx;
283
};
284
285
#define MUX_IDX_UNDEF ((unsigned char)-1)
286
287
struct alc_customize_define {
288
unsigned int sku_cfg;
289
unsigned char port_connectivity;
290
unsigned char check_sum;
291
unsigned char customization;
292
unsigned char external_amp;
293
unsigned int enable_pcbeep:1;
294
unsigned int platform_type:1;
295
unsigned int swap:1;
296
unsigned int override:1;
297
unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
298
};
299
300
struct alc_fixup;
301
302
struct alc_multi_io {
303
hda_nid_t pin; /* multi-io widget pin NID */
304
hda_nid_t dac; /* DAC to be connected */
305
unsigned int ctl_in; /* cached input-pin control value */
306
};
307
308
enum {
309
ALC_AUTOMUTE_PIN, /* change the pin control */
310
ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311
ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
312
};
313
314
struct alc_spec {
315
/* codec parameterization */
316
const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
317
unsigned int num_mixers;
318
const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
319
unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
320
321
const struct hda_verb *init_verbs[10]; /* initialization verbs
322
* don't forget NULL
323
* termination!
324
*/
325
unsigned int num_init_verbs;
326
327
char stream_name_analog[32]; /* analog PCM stream */
328
const struct hda_pcm_stream *stream_analog_playback;
329
const struct hda_pcm_stream *stream_analog_capture;
330
const struct hda_pcm_stream *stream_analog_alt_playback;
331
const struct hda_pcm_stream *stream_analog_alt_capture;
332
333
char stream_name_digital[32]; /* digital PCM stream */
334
const struct hda_pcm_stream *stream_digital_playback;
335
const struct hda_pcm_stream *stream_digital_capture;
336
337
/* playback */
338
struct hda_multi_out multiout; /* playback set-up
339
* max_channels, dacs must be set
340
* dig_out_nid and hp_nid are optional
341
*/
342
hda_nid_t alt_dac_nid;
343
hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
344
int dig_out_type;
345
346
/* capture */
347
unsigned int num_adc_nids;
348
const hda_nid_t *adc_nids;
349
const hda_nid_t *capsrc_nids;
350
hda_nid_t dig_in_nid; /* digital-in NID; optional */
351
352
/* capture setup for dynamic dual-adc switch */
353
unsigned int cur_adc_idx;
354
hda_nid_t cur_adc;
355
unsigned int cur_adc_stream_tag;
356
unsigned int cur_adc_format;
357
358
/* capture source */
359
unsigned int num_mux_defs;
360
const struct hda_input_mux *input_mux;
361
unsigned int cur_mux[3];
362
struct alc_mic_route ext_mic;
363
struct alc_mic_route dock_mic;
364
struct alc_mic_route int_mic;
365
366
/* channel model */
367
const struct hda_channel_mode *channel_mode;
368
int num_channel_mode;
369
int need_dac_fix;
370
int const_channel_count;
371
int ext_channel_count;
372
373
/* PCM information */
374
struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
375
376
/* dynamic controls, init_verbs and input_mux */
377
struct auto_pin_cfg autocfg;
378
struct alc_customize_define cdefine;
379
struct snd_array kctls;
380
struct hda_input_mux private_imux[3];
381
hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
382
hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
383
hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
384
385
/* hooks */
386
void (*init_hook)(struct hda_codec *codec);
387
void (*unsol_event)(struct hda_codec *codec, unsigned int res);
388
#ifdef CONFIG_SND_HDA_POWER_SAVE
389
void (*power_hook)(struct hda_codec *codec);
390
#endif
391
void (*shutup)(struct hda_codec *codec);
392
393
/* for pin sensing */
394
unsigned int jack_present: 1;
395
unsigned int line_jack_present:1;
396
unsigned int master_mute:1;
397
unsigned int auto_mic:1;
398
unsigned int automute:1; /* HP automute enabled */
399
unsigned int detect_line:1; /* Line-out detection enabled */
400
unsigned int automute_lines:1; /* automute line-out as well */
401
unsigned int automute_hp_lo:1; /* both HP and LO available */
402
403
/* other flags */
404
unsigned int no_analog :1; /* digital I/O only */
405
unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
406
unsigned int single_input_src:1;
407
408
/* auto-mute control */
409
int automute_mode;
410
hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
411
412
int init_amp;
413
int codec_variant; /* flag for other variants */
414
415
/* for virtual master */
416
hda_nid_t vmaster_nid;
417
#ifdef CONFIG_SND_HDA_POWER_SAVE
418
struct hda_loopback_check loopback;
419
#endif
420
421
/* for PLL fix */
422
hda_nid_t pll_nid;
423
unsigned int pll_coef_idx, pll_coef_bit;
424
425
/* fix-up list */
426
int fixup_id;
427
const struct alc_fixup *fixup_list;
428
const char *fixup_name;
429
430
/* multi-io */
431
int multi_ios;
432
struct alc_multi_io multi_io[4];
433
};
434
435
/*
436
* configuration template - to be copied to the spec instance
437
*/
438
struct alc_config_preset {
439
const struct snd_kcontrol_new *mixers[5]; /* should be identical size
440
* with spec
441
*/
442
const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
443
const struct hda_verb *init_verbs[5];
444
unsigned int num_dacs;
445
const hda_nid_t *dac_nids;
446
hda_nid_t dig_out_nid; /* optional */
447
hda_nid_t hp_nid; /* optional */
448
const hda_nid_t *slave_dig_outs;
449
unsigned int num_adc_nids;
450
const hda_nid_t *adc_nids;
451
const hda_nid_t *capsrc_nids;
452
hda_nid_t dig_in_nid;
453
unsigned int num_channel_mode;
454
const struct hda_channel_mode *channel_mode;
455
int need_dac_fix;
456
int const_channel_count;
457
unsigned int num_mux_defs;
458
const struct hda_input_mux *input_mux;
459
void (*unsol_event)(struct hda_codec *, unsigned int);
460
void (*setup)(struct hda_codec *);
461
void (*init_hook)(struct hda_codec *);
462
#ifdef CONFIG_SND_HDA_POWER_SAVE
463
const struct hda_amp_list *loopbacks;
464
void (*power_hook)(struct hda_codec *codec);
465
#endif
466
};
467
468
469
/*
470
* input MUX handling
471
*/
472
static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
473
struct snd_ctl_elem_info *uinfo)
474
{
475
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476
struct alc_spec *spec = codec->spec;
477
unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
478
if (mux_idx >= spec->num_mux_defs)
479
mux_idx = 0;
480
if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
481
mux_idx = 0;
482
return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
483
}
484
485
static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
486
struct snd_ctl_elem_value *ucontrol)
487
{
488
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
489
struct alc_spec *spec = codec->spec;
490
unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
491
492
ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
493
return 0;
494
}
495
496
static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
497
struct snd_ctl_elem_value *ucontrol)
498
{
499
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
500
struct alc_spec *spec = codec->spec;
501
const struct hda_input_mux *imux;
502
unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
503
unsigned int mux_idx;
504
hda_nid_t nid = spec->capsrc_nids ?
505
spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
506
unsigned int type;
507
508
mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
509
imux = &spec->input_mux[mux_idx];
510
if (!imux->num_items && mux_idx > 0)
511
imux = &spec->input_mux[0];
512
513
type = get_wcaps_type(get_wcaps(codec, nid));
514
if (type == AC_WID_AUD_MIX) {
515
/* Matrix-mixer style (e.g. ALC882) */
516
unsigned int *cur_val = &spec->cur_mux[adc_idx];
517
unsigned int i, idx;
518
519
idx = ucontrol->value.enumerated.item[0];
520
if (idx >= imux->num_items)
521
idx = imux->num_items - 1;
522
if (*cur_val == idx)
523
return 0;
524
for (i = 0; i < imux->num_items; i++) {
525
unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
526
snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
527
imux->items[i].index,
528
HDA_AMP_MUTE, v);
529
}
530
*cur_val = idx;
531
return 1;
532
} else {
533
/* MUX style (e.g. ALC880) */
534
return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
535
&spec->cur_mux[adc_idx]);
536
}
537
}
538
539
/*
540
* channel mode setting
541
*/
542
static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
543
struct snd_ctl_elem_info *uinfo)
544
{
545
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
546
struct alc_spec *spec = codec->spec;
547
return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
548
spec->num_channel_mode);
549
}
550
551
static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
552
struct snd_ctl_elem_value *ucontrol)
553
{
554
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
555
struct alc_spec *spec = codec->spec;
556
return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
557
spec->num_channel_mode,
558
spec->ext_channel_count);
559
}
560
561
static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
562
struct snd_ctl_elem_value *ucontrol)
563
{
564
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
565
struct alc_spec *spec = codec->spec;
566
int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
567
spec->num_channel_mode,
568
&spec->ext_channel_count);
569
if (err >= 0 && !spec->const_channel_count) {
570
spec->multiout.max_channels = spec->ext_channel_count;
571
if (spec->need_dac_fix)
572
spec->multiout.num_dacs = spec->multiout.max_channels / 2;
573
}
574
return err;
575
}
576
577
/*
578
* Control the mode of pin widget settings via the mixer. "pc" is used
579
* instead of "%" to avoid consequences of accidentally treating the % as
580
* being part of a format specifier. Maximum allowed length of a value is
581
* 63 characters plus NULL terminator.
582
*
583
* Note: some retasking pin complexes seem to ignore requests for input
584
* states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
585
* are requested. Therefore order this list so that this behaviour will not
586
* cause problems when mixer clients move through the enum sequentially.
587
* NIDs 0x0f and 0x10 have been observed to have this behaviour as of
588
* March 2006.
589
*/
590
static const char * const alc_pin_mode_names[] = {
591
"Mic 50pc bias", "Mic 80pc bias",
592
"Line in", "Line out", "Headphone out",
593
};
594
static const unsigned char alc_pin_mode_values[] = {
595
PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
596
};
597
/* The control can present all 5 options, or it can limit the options based
598
* in the pin being assumed to be exclusively an input or an output pin. In
599
* addition, "input" pins may or may not process the mic bias option
600
* depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
601
* accept requests for bias as of chip versions up to March 2006) and/or
602
* wiring in the computer.
603
*/
604
#define ALC_PIN_DIR_IN 0x00
605
#define ALC_PIN_DIR_OUT 0x01
606
#define ALC_PIN_DIR_INOUT 0x02
607
#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
608
#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
609
610
/* Info about the pin modes supported by the different pin direction modes.
611
* For each direction the minimum and maximum values are given.
612
*/
613
static const signed char alc_pin_mode_dir_info[5][2] = {
614
{ 0, 2 }, /* ALC_PIN_DIR_IN */
615
{ 3, 4 }, /* ALC_PIN_DIR_OUT */
616
{ 0, 4 }, /* ALC_PIN_DIR_INOUT */
617
{ 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
618
{ 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
619
};
620
#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
621
#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
622
#define alc_pin_mode_n_items(_dir) \
623
(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
624
625
static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
626
struct snd_ctl_elem_info *uinfo)
627
{
628
unsigned int item_num = uinfo->value.enumerated.item;
629
unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
630
631
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
632
uinfo->count = 1;
633
uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
634
635
if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
636
item_num = alc_pin_mode_min(dir);
637
strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
638
return 0;
639
}
640
641
static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
642
struct snd_ctl_elem_value *ucontrol)
643
{
644
unsigned int i;
645
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
646
hda_nid_t nid = kcontrol->private_value & 0xffff;
647
unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
648
long *valp = ucontrol->value.integer.value;
649
unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
650
AC_VERB_GET_PIN_WIDGET_CONTROL,
651
0x00);
652
653
/* Find enumerated value for current pinctl setting */
654
i = alc_pin_mode_min(dir);
655
while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
656
i++;
657
*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
658
return 0;
659
}
660
661
static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
662
struct snd_ctl_elem_value *ucontrol)
663
{
664
signed int change;
665
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
666
hda_nid_t nid = kcontrol->private_value & 0xffff;
667
unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
668
long val = *ucontrol->value.integer.value;
669
unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
670
AC_VERB_GET_PIN_WIDGET_CONTROL,
671
0x00);
672
673
if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
674
val = alc_pin_mode_min(dir);
675
676
change = pinctl != alc_pin_mode_values[val];
677
if (change) {
678
/* Set pin mode to that requested */
679
snd_hda_codec_write_cache(codec, nid, 0,
680
AC_VERB_SET_PIN_WIDGET_CONTROL,
681
alc_pin_mode_values[val]);
682
683
/* Also enable the retasking pin's input/output as required
684
* for the requested pin mode. Enum values of 2 or less are
685
* input modes.
686
*
687
* Dynamically switching the input/output buffers probably
688
* reduces noise slightly (particularly on input) so we'll
689
* do it. However, having both input and output buffers
690
* enabled simultaneously doesn't seem to be problematic if
691
* this turns out to be necessary in the future.
692
*/
693
if (val <= 2) {
694
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
695
HDA_AMP_MUTE, HDA_AMP_MUTE);
696
snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
697
HDA_AMP_MUTE, 0);
698
} else {
699
snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
700
HDA_AMP_MUTE, HDA_AMP_MUTE);
701
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
702
HDA_AMP_MUTE, 0);
703
}
704
}
705
return change;
706
}
707
708
#define ALC_PIN_MODE(xname, nid, dir) \
709
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
710
.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
711
.info = alc_pin_mode_info, \
712
.get = alc_pin_mode_get, \
713
.put = alc_pin_mode_put, \
714
.private_value = nid | (dir<<16) }
715
716
/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
717
* together using a mask with more than one bit set. This control is
718
* currently used only by the ALC260 test model. At this stage they are not
719
* needed for any "production" models.
720
*/
721
#ifdef CONFIG_SND_DEBUG
722
#define alc_gpio_data_info snd_ctl_boolean_mono_info
723
724
static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
725
struct snd_ctl_elem_value *ucontrol)
726
{
727
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
728
hda_nid_t nid = kcontrol->private_value & 0xffff;
729
unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
730
long *valp = ucontrol->value.integer.value;
731
unsigned int val = snd_hda_codec_read(codec, nid, 0,
732
AC_VERB_GET_GPIO_DATA, 0x00);
733
734
*valp = (val & mask) != 0;
735
return 0;
736
}
737
static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
738
struct snd_ctl_elem_value *ucontrol)
739
{
740
signed int change;
741
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
742
hda_nid_t nid = kcontrol->private_value & 0xffff;
743
unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
744
long val = *ucontrol->value.integer.value;
745
unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
746
AC_VERB_GET_GPIO_DATA,
747
0x00);
748
749
/* Set/unset the masked GPIO bit(s) as needed */
750
change = (val == 0 ? 0 : mask) != (gpio_data & mask);
751
if (val == 0)
752
gpio_data &= ~mask;
753
else
754
gpio_data |= mask;
755
snd_hda_codec_write_cache(codec, nid, 0,
756
AC_VERB_SET_GPIO_DATA, gpio_data);
757
758
return change;
759
}
760
#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
761
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
762
.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
763
.info = alc_gpio_data_info, \
764
.get = alc_gpio_data_get, \
765
.put = alc_gpio_data_put, \
766
.private_value = nid | (mask<<16) }
767
#endif /* CONFIG_SND_DEBUG */
768
769
/* A switch control to allow the enabling of the digital IO pins on the
770
* ALC260. This is incredibly simplistic; the intention of this control is
771
* to provide something in the test model allowing digital outputs to be
772
* identified if present. If models are found which can utilise these
773
* outputs a more complete mixer control can be devised for those models if
774
* necessary.
775
*/
776
#ifdef CONFIG_SND_DEBUG
777
#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
778
779
static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
780
struct snd_ctl_elem_value *ucontrol)
781
{
782
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
783
hda_nid_t nid = kcontrol->private_value & 0xffff;
784
unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
785
long *valp = ucontrol->value.integer.value;
786
unsigned int val = snd_hda_codec_read(codec, nid, 0,
787
AC_VERB_GET_DIGI_CONVERT_1, 0x00);
788
789
*valp = (val & mask) != 0;
790
return 0;
791
}
792
static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
793
struct snd_ctl_elem_value *ucontrol)
794
{
795
signed int change;
796
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
797
hda_nid_t nid = kcontrol->private_value & 0xffff;
798
unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
799
long val = *ucontrol->value.integer.value;
800
unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
801
AC_VERB_GET_DIGI_CONVERT_1,
802
0x00);
803
804
/* Set/unset the masked control bit(s) as needed */
805
change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
806
if (val==0)
807
ctrl_data &= ~mask;
808
else
809
ctrl_data |= mask;
810
snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
811
ctrl_data);
812
813
return change;
814
}
815
#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
816
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
817
.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
818
.info = alc_spdif_ctrl_info, \
819
.get = alc_spdif_ctrl_get, \
820
.put = alc_spdif_ctrl_put, \
821
.private_value = nid | (mask<<16) }
822
#endif /* CONFIG_SND_DEBUG */
823
824
/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
825
* Again, this is only used in the ALC26x test models to help identify when
826
* the EAPD line must be asserted for features to work.
827
*/
828
#ifdef CONFIG_SND_DEBUG
829
#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
830
831
static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
832
struct snd_ctl_elem_value *ucontrol)
833
{
834
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
835
hda_nid_t nid = kcontrol->private_value & 0xffff;
836
unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
837
long *valp = ucontrol->value.integer.value;
838
unsigned int val = snd_hda_codec_read(codec, nid, 0,
839
AC_VERB_GET_EAPD_BTLENABLE, 0x00);
840
841
*valp = (val & mask) != 0;
842
return 0;
843
}
844
845
static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
846
struct snd_ctl_elem_value *ucontrol)
847
{
848
int change;
849
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
850
hda_nid_t nid = kcontrol->private_value & 0xffff;
851
unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
852
long val = *ucontrol->value.integer.value;
853
unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
854
AC_VERB_GET_EAPD_BTLENABLE,
855
0x00);
856
857
/* Set/unset the masked control bit(s) as needed */
858
change = (!val ? 0 : mask) != (ctrl_data & mask);
859
if (!val)
860
ctrl_data &= ~mask;
861
else
862
ctrl_data |= mask;
863
snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
864
ctrl_data);
865
866
return change;
867
}
868
869
#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
870
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
871
.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
872
.info = alc_eapd_ctrl_info, \
873
.get = alc_eapd_ctrl_get, \
874
.put = alc_eapd_ctrl_put, \
875
.private_value = nid | (mask<<16) }
876
#endif /* CONFIG_SND_DEBUG */
877
878
/*
879
* set up the input pin config (depending on the given auto-pin type)
880
*/
881
static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
882
int auto_pin_type)
883
{
884
unsigned int val = PIN_IN;
885
886
if (auto_pin_type == AUTO_PIN_MIC) {
887
unsigned int pincap;
888
unsigned int oldval;
889
oldval = snd_hda_codec_read(codec, nid, 0,
890
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
891
pincap = snd_hda_query_pin_caps(codec, nid);
892
pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
893
/* if the default pin setup is vref50, we give it priority */
894
if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
895
val = PIN_VREF80;
896
else if (pincap & AC_PINCAP_VREF_50)
897
val = PIN_VREF50;
898
else if (pincap & AC_PINCAP_VREF_100)
899
val = PIN_VREF100;
900
else if (pincap & AC_PINCAP_VREF_GRD)
901
val = PIN_VREFGRD;
902
}
903
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
904
}
905
906
static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
907
{
908
struct alc_spec *spec = codec->spec;
909
struct auto_pin_cfg *cfg = &spec->autocfg;
910
911
if (!cfg->line_outs) {
912
while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
913
cfg->line_out_pins[cfg->line_outs])
914
cfg->line_outs++;
915
}
916
if (!cfg->speaker_outs) {
917
while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
918
cfg->speaker_pins[cfg->speaker_outs])
919
cfg->speaker_outs++;
920
}
921
if (!cfg->hp_outs) {
922
while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
923
cfg->hp_pins[cfg->hp_outs])
924
cfg->hp_outs++;
925
}
926
}
927
928
/*
929
*/
930
static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
931
{
932
if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
933
return;
934
spec->mixers[spec->num_mixers++] = mix;
935
}
936
937
static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
938
{
939
if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
940
return;
941
spec->init_verbs[spec->num_init_verbs++] = verb;
942
}
943
944
/*
945
* set up from the preset table
946
*/
947
static void setup_preset(struct hda_codec *codec,
948
const struct alc_config_preset *preset)
949
{
950
struct alc_spec *spec = codec->spec;
951
int i;
952
953
for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
954
add_mixer(spec, preset->mixers[i]);
955
spec->cap_mixer = preset->cap_mixer;
956
for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
957
i++)
958
add_verb(spec, preset->init_verbs[i]);
959
960
spec->channel_mode = preset->channel_mode;
961
spec->num_channel_mode = preset->num_channel_mode;
962
spec->need_dac_fix = preset->need_dac_fix;
963
spec->const_channel_count = preset->const_channel_count;
964
965
if (preset->const_channel_count)
966
spec->multiout.max_channels = preset->const_channel_count;
967
else
968
spec->multiout.max_channels = spec->channel_mode[0].channels;
969
spec->ext_channel_count = spec->channel_mode[0].channels;
970
971
spec->multiout.num_dacs = preset->num_dacs;
972
spec->multiout.dac_nids = preset->dac_nids;
973
spec->multiout.dig_out_nid = preset->dig_out_nid;
974
spec->multiout.slave_dig_outs = preset->slave_dig_outs;
975
spec->multiout.hp_nid = preset->hp_nid;
976
977
spec->num_mux_defs = preset->num_mux_defs;
978
if (!spec->num_mux_defs)
979
spec->num_mux_defs = 1;
980
spec->input_mux = preset->input_mux;
981
982
spec->num_adc_nids = preset->num_adc_nids;
983
spec->adc_nids = preset->adc_nids;
984
spec->capsrc_nids = preset->capsrc_nids;
985
spec->dig_in_nid = preset->dig_in_nid;
986
987
spec->unsol_event = preset->unsol_event;
988
spec->init_hook = preset->init_hook;
989
#ifdef CONFIG_SND_HDA_POWER_SAVE
990
spec->power_hook = preset->power_hook;
991
spec->loopback.amplist = preset->loopbacks;
992
#endif
993
994
if (preset->setup)
995
preset->setup(codec);
996
997
alc_fixup_autocfg_pin_nums(codec);
998
}
999
1000
/* Enable GPIO mask and set output */
1001
static const struct hda_verb alc_gpio1_init_verbs[] = {
1002
{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1003
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1004
{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1005
{ }
1006
};
1007
1008
static const struct hda_verb alc_gpio2_init_verbs[] = {
1009
{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1010
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1011
{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1012
{ }
1013
};
1014
1015
static const struct hda_verb alc_gpio3_init_verbs[] = {
1016
{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1017
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1018
{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1019
{ }
1020
};
1021
1022
/*
1023
* Fix hardware PLL issue
1024
* On some codecs, the analog PLL gating control must be off while
1025
* the default value is 1.
1026
*/
1027
static void alc_fix_pll(struct hda_codec *codec)
1028
{
1029
struct alc_spec *spec = codec->spec;
1030
unsigned int val;
1031
1032
if (!spec->pll_nid)
1033
return;
1034
snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1035
spec->pll_coef_idx);
1036
val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1037
AC_VERB_GET_PROC_COEF, 0);
1038
snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1039
spec->pll_coef_idx);
1040
snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1041
val & ~(1 << spec->pll_coef_bit));
1042
}
1043
1044
static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1045
unsigned int coef_idx, unsigned int coef_bit)
1046
{
1047
struct alc_spec *spec = codec->spec;
1048
spec->pll_nid = nid;
1049
spec->pll_coef_idx = coef_idx;
1050
spec->pll_coef_bit = coef_bit;
1051
alc_fix_pll(codec);
1052
}
1053
1054
static int alc_init_jacks(struct hda_codec *codec)
1055
{
1056
#ifdef CONFIG_SND_HDA_INPUT_JACK
1057
struct alc_spec *spec = codec->spec;
1058
int err;
1059
unsigned int hp_nid = spec->autocfg.hp_pins[0];
1060
unsigned int mic_nid = spec->ext_mic.pin;
1061
unsigned int dock_nid = spec->dock_mic.pin;
1062
1063
if (hp_nid) {
1064
err = snd_hda_input_jack_add(codec, hp_nid,
1065
SND_JACK_HEADPHONE, NULL);
1066
if (err < 0)
1067
return err;
1068
snd_hda_input_jack_report(codec, hp_nid);
1069
}
1070
1071
if (mic_nid) {
1072
err = snd_hda_input_jack_add(codec, mic_nid,
1073
SND_JACK_MICROPHONE, NULL);
1074
if (err < 0)
1075
return err;
1076
snd_hda_input_jack_report(codec, mic_nid);
1077
}
1078
if (dock_nid) {
1079
err = snd_hda_input_jack_add(codec, dock_nid,
1080
SND_JACK_MICROPHONE, NULL);
1081
if (err < 0)
1082
return err;
1083
snd_hda_input_jack_report(codec, dock_nid);
1084
}
1085
#endif /* CONFIG_SND_HDA_INPUT_JACK */
1086
return 0;
1087
}
1088
1089
static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1090
{
1091
int i, present = 0;
1092
1093
for (i = 0; i < num_pins; i++) {
1094
hda_nid_t nid = pins[i];
1095
if (!nid)
1096
break;
1097
snd_hda_input_jack_report(codec, nid);
1098
present |= snd_hda_jack_detect(codec, nid);
1099
}
1100
return present;
1101
}
1102
1103
static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1104
bool mute, bool hp_out)
1105
{
1106
struct alc_spec *spec = codec->spec;
1107
unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
1108
unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
1109
int i;
1110
1111
for (i = 0; i < num_pins; i++) {
1112
hda_nid_t nid = pins[i];
1113
if (!nid)
1114
break;
1115
switch (spec->automute_mode) {
1116
case ALC_AUTOMUTE_PIN:
1117
snd_hda_codec_write(codec, nid, 0,
1118
AC_VERB_SET_PIN_WIDGET_CONTROL,
1119
pin_bits);
1120
break;
1121
case ALC_AUTOMUTE_AMP:
1122
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1123
HDA_AMP_MUTE, mute_bits);
1124
break;
1125
case ALC_AUTOMUTE_MIXER:
1126
nid = spec->automute_mixer_nid[i];
1127
if (!nid)
1128
break;
1129
snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
1130
HDA_AMP_MUTE, mute_bits);
1131
snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
1132
HDA_AMP_MUTE, mute_bits);
1133
break;
1134
}
1135
}
1136
}
1137
1138
/* Toggle internal speakers muting */
1139
static void update_speakers(struct hda_codec *codec)
1140
{
1141
struct alc_spec *spec = codec->spec;
1142
int on;
1143
1144
/* Control HP pins/amps depending on master_mute state;
1145
* in general, HP pins/amps control should be enabled in all cases,
1146
* but currently set only for master_mute, just to be safe
1147
*/
1148
do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1149
spec->autocfg.hp_pins, spec->master_mute, true);
1150
1151
if (!spec->automute)
1152
on = 0;
1153
else
1154
on = spec->jack_present | spec->line_jack_present;
1155
on |= spec->master_mute;
1156
do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1157
spec->autocfg.speaker_pins, on, false);
1158
1159
/* toggle line-out mutes if needed, too */
1160
/* if LO is a copy of either HP or Speaker, don't need to handle it */
1161
if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1162
spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
1163
return;
1164
if (!spec->automute_lines || !spec->automute)
1165
on = 0;
1166
else
1167
on = spec->jack_present;
1168
on |= spec->master_mute;
1169
do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1170
spec->autocfg.line_out_pins, on, false);
1171
}
1172
1173
static void alc_hp_automute(struct hda_codec *codec)
1174
{
1175
struct alc_spec *spec = codec->spec;
1176
1177
if (!spec->automute)
1178
return;
1179
spec->jack_present =
1180
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1181
spec->autocfg.hp_pins);
1182
update_speakers(codec);
1183
}
1184
1185
static void alc_line_automute(struct hda_codec *codec)
1186
{
1187
struct alc_spec *spec = codec->spec;
1188
1189
if (!spec->automute || !spec->detect_line)
1190
return;
1191
spec->line_jack_present =
1192
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1193
spec->autocfg.line_out_pins);
1194
update_speakers(codec);
1195
}
1196
1197
static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1198
hda_nid_t nid)
1199
{
1200
hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1201
int i, nums;
1202
1203
nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1204
for (i = 0; i < nums; i++)
1205
if (conn[i] == nid)
1206
return i;
1207
return -1;
1208
}
1209
1210
/* switch the current ADC according to the jack state */
1211
static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1212
{
1213
struct alc_spec *spec = codec->spec;
1214
unsigned int present;
1215
hda_nid_t new_adc;
1216
1217
present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1218
if (present)
1219
spec->cur_adc_idx = 1;
1220
else
1221
spec->cur_adc_idx = 0;
1222
new_adc = spec->adc_nids[spec->cur_adc_idx];
1223
if (spec->cur_adc && spec->cur_adc != new_adc) {
1224
/* stream is running, let's swap the current ADC */
1225
__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1226
spec->cur_adc = new_adc;
1227
snd_hda_codec_setup_stream(codec, new_adc,
1228
spec->cur_adc_stream_tag, 0,
1229
spec->cur_adc_format);
1230
}
1231
}
1232
1233
static void alc_mic_automute(struct hda_codec *codec)
1234
{
1235
struct alc_spec *spec = codec->spec;
1236
struct alc_mic_route *dead1, *dead2, *alive;
1237
unsigned int present, type;
1238
hda_nid_t cap_nid;
1239
1240
if (!spec->auto_mic)
1241
return;
1242
if (!spec->int_mic.pin || !spec->ext_mic.pin)
1243
return;
1244
if (snd_BUG_ON(!spec->adc_nids))
1245
return;
1246
1247
if (spec->dual_adc_switch) {
1248
alc_dual_mic_adc_auto_switch(codec);
1249
return;
1250
}
1251
1252
cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1253
1254
alive = &spec->int_mic;
1255
dead1 = &spec->ext_mic;
1256
dead2 = &spec->dock_mic;
1257
1258
present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1259
if (present) {
1260
alive = &spec->ext_mic;
1261
dead1 = &spec->int_mic;
1262
dead2 = &spec->dock_mic;
1263
}
1264
if (!present && spec->dock_mic.pin > 0) {
1265
present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1266
if (present) {
1267
alive = &spec->dock_mic;
1268
dead1 = &spec->int_mic;
1269
dead2 = &spec->ext_mic;
1270
}
1271
snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1272
}
1273
1274
type = get_wcaps_type(get_wcaps(codec, cap_nid));
1275
if (type == AC_WID_AUD_MIX) {
1276
/* Matrix-mixer style (e.g. ALC882) */
1277
snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1278
alive->mux_idx,
1279
HDA_AMP_MUTE, 0);
1280
if (dead1->pin > 0)
1281
snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1282
dead1->mux_idx,
1283
HDA_AMP_MUTE, HDA_AMP_MUTE);
1284
if (dead2->pin > 0)
1285
snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1286
dead2->mux_idx,
1287
HDA_AMP_MUTE, HDA_AMP_MUTE);
1288
} else {
1289
/* MUX style (e.g. ALC880) */
1290
snd_hda_codec_write_cache(codec, cap_nid, 0,
1291
AC_VERB_SET_CONNECT_SEL,
1292
alive->mux_idx);
1293
}
1294
snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1295
1296
/* FIXME: analog mixer */
1297
}
1298
1299
/* unsolicited event for HP jack sensing */
1300
static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1301
{
1302
if (codec->vendor_id == 0x10ec0880)
1303
res >>= 28;
1304
else
1305
res >>= 26;
1306
switch (res) {
1307
case ALC880_HP_EVENT:
1308
alc_hp_automute(codec);
1309
break;
1310
case ALC880_FRONT_EVENT:
1311
alc_line_automute(codec);
1312
break;
1313
case ALC880_MIC_EVENT:
1314
alc_mic_automute(codec);
1315
break;
1316
}
1317
}
1318
1319
static void alc_inithook(struct hda_codec *codec)
1320
{
1321
alc_hp_automute(codec);
1322
alc_line_automute(codec);
1323
alc_mic_automute(codec);
1324
}
1325
1326
/* additional initialization for ALC888 variants */
1327
static void alc888_coef_init(struct hda_codec *codec)
1328
{
1329
unsigned int tmp;
1330
1331
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1332
tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1333
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1334
if ((tmp & 0xf0) == 0x20)
1335
/* alc888S-VC */
1336
snd_hda_codec_read(codec, 0x20, 0,
1337
AC_VERB_SET_PROC_COEF, 0x830);
1338
else
1339
/* alc888-VB */
1340
snd_hda_codec_read(codec, 0x20, 0,
1341
AC_VERB_SET_PROC_COEF, 0x3030);
1342
}
1343
1344
static void alc889_coef_init(struct hda_codec *codec)
1345
{
1346
unsigned int tmp;
1347
1348
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1349
tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1350
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1351
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1352
}
1353
1354
/* turn on/off EAPD control (only if available) */
1355
static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1356
{
1357
if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1358
return;
1359
if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1360
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1361
on ? 2 : 0);
1362
}
1363
1364
/* turn on/off EAPD controls of the codec */
1365
static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1366
{
1367
/* We currently only handle front, HP */
1368
switch (codec->vendor_id) {
1369
case 0x10ec0260:
1370
set_eapd(codec, 0x0f, on);
1371
set_eapd(codec, 0x10, on);
1372
break;
1373
case 0x10ec0262:
1374
case 0x10ec0267:
1375
case 0x10ec0268:
1376
case 0x10ec0269:
1377
case 0x10ec0270:
1378
case 0x10ec0272:
1379
case 0x10ec0660:
1380
case 0x10ec0662:
1381
case 0x10ec0663:
1382
case 0x10ec0665:
1383
case 0x10ec0862:
1384
case 0x10ec0889:
1385
case 0x10ec0892:
1386
set_eapd(codec, 0x14, on);
1387
set_eapd(codec, 0x15, on);
1388
break;
1389
}
1390
}
1391
1392
/* generic shutup callback;
1393
* just turning off EPAD and a little pause for avoiding pop-noise
1394
*/
1395
static void alc_eapd_shutup(struct hda_codec *codec)
1396
{
1397
alc_auto_setup_eapd(codec, false);
1398
msleep(200);
1399
}
1400
1401
static void alc_auto_init_amp(struct hda_codec *codec, int type)
1402
{
1403
unsigned int tmp;
1404
1405
switch (type) {
1406
case ALC_INIT_GPIO1:
1407
snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1408
break;
1409
case ALC_INIT_GPIO2:
1410
snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1411
break;
1412
case ALC_INIT_GPIO3:
1413
snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1414
break;
1415
case ALC_INIT_DEFAULT:
1416
alc_auto_setup_eapd(codec, true);
1417
switch (codec->vendor_id) {
1418
case 0x10ec0260:
1419
snd_hda_codec_write(codec, 0x1a, 0,
1420
AC_VERB_SET_COEF_INDEX, 7);
1421
tmp = snd_hda_codec_read(codec, 0x1a, 0,
1422
AC_VERB_GET_PROC_COEF, 0);
1423
snd_hda_codec_write(codec, 0x1a, 0,
1424
AC_VERB_SET_COEF_INDEX, 7);
1425
snd_hda_codec_write(codec, 0x1a, 0,
1426
AC_VERB_SET_PROC_COEF,
1427
tmp | 0x2010);
1428
break;
1429
case 0x10ec0262:
1430
case 0x10ec0880:
1431
case 0x10ec0882:
1432
case 0x10ec0883:
1433
case 0x10ec0885:
1434
case 0x10ec0887:
1435
/*case 0x10ec0889:*/ /* this causes an SPDIF problem */
1436
alc889_coef_init(codec);
1437
break;
1438
case 0x10ec0888:
1439
alc888_coef_init(codec);
1440
break;
1441
#if 0 /* XXX: This may cause the silent output on speaker on some machines */
1442
case 0x10ec0267:
1443
case 0x10ec0268:
1444
snd_hda_codec_write(codec, 0x20, 0,
1445
AC_VERB_SET_COEF_INDEX, 7);
1446
tmp = snd_hda_codec_read(codec, 0x20, 0,
1447
AC_VERB_GET_PROC_COEF, 0);
1448
snd_hda_codec_write(codec, 0x20, 0,
1449
AC_VERB_SET_COEF_INDEX, 7);
1450
snd_hda_codec_write(codec, 0x20, 0,
1451
AC_VERB_SET_PROC_COEF,
1452
tmp | 0x3000);
1453
break;
1454
#endif /* XXX */
1455
}
1456
break;
1457
}
1458
}
1459
1460
static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1461
struct snd_ctl_elem_info *uinfo)
1462
{
1463
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1464
struct alc_spec *spec = codec->spec;
1465
static const char * const texts2[] = {
1466
"Disabled", "Enabled"
1467
};
1468
static const char * const texts3[] = {
1469
"Disabled", "Speaker Only", "Line-Out+Speaker"
1470
};
1471
const char * const *texts;
1472
1473
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1474
uinfo->count = 1;
1475
if (spec->automute_hp_lo) {
1476
uinfo->value.enumerated.items = 3;
1477
texts = texts3;
1478
} else {
1479
uinfo->value.enumerated.items = 2;
1480
texts = texts2;
1481
}
1482
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1483
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1484
strcpy(uinfo->value.enumerated.name,
1485
texts[uinfo->value.enumerated.item]);
1486
return 0;
1487
}
1488
1489
static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1490
struct snd_ctl_elem_value *ucontrol)
1491
{
1492
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1493
struct alc_spec *spec = codec->spec;
1494
unsigned int val;
1495
if (!spec->automute)
1496
val = 0;
1497
else if (!spec->automute_lines)
1498
val = 1;
1499
else
1500
val = 2;
1501
ucontrol->value.enumerated.item[0] = val;
1502
return 0;
1503
}
1504
1505
static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1506
struct snd_ctl_elem_value *ucontrol)
1507
{
1508
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1509
struct alc_spec *spec = codec->spec;
1510
1511
switch (ucontrol->value.enumerated.item[0]) {
1512
case 0:
1513
if (!spec->automute)
1514
return 0;
1515
spec->automute = 0;
1516
break;
1517
case 1:
1518
if (spec->automute && !spec->automute_lines)
1519
return 0;
1520
spec->automute = 1;
1521
spec->automute_lines = 0;
1522
break;
1523
case 2:
1524
if (!spec->automute_hp_lo)
1525
return -EINVAL;
1526
if (spec->automute && spec->automute_lines)
1527
return 0;
1528
spec->automute = 1;
1529
spec->automute_lines = 1;
1530
break;
1531
default:
1532
return -EINVAL;
1533
}
1534
update_speakers(codec);
1535
return 1;
1536
}
1537
1538
static const struct snd_kcontrol_new alc_automute_mode_enum = {
1539
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1540
.name = "Auto-Mute Mode",
1541
.info = alc_automute_mode_info,
1542
.get = alc_automute_mode_get,
1543
.put = alc_automute_mode_put,
1544
};
1545
1546
static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1547
1548
static int alc_add_automute_mode_enum(struct hda_codec *codec)
1549
{
1550
struct alc_spec *spec = codec->spec;
1551
struct snd_kcontrol_new *knew;
1552
1553
knew = alc_kcontrol_new(spec);
1554
if (!knew)
1555
return -ENOMEM;
1556
*knew = alc_automute_mode_enum;
1557
knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1558
if (!knew->name)
1559
return -ENOMEM;
1560
return 0;
1561
}
1562
1563
static void alc_init_auto_hp(struct hda_codec *codec)
1564
{
1565
struct alc_spec *spec = codec->spec;
1566
struct auto_pin_cfg *cfg = &spec->autocfg;
1567
int present = 0;
1568
int i;
1569
1570
if (cfg->hp_pins[0])
1571
present++;
1572
if (cfg->line_out_pins[0])
1573
present++;
1574
if (cfg->speaker_pins[0])
1575
present++;
1576
if (present < 2) /* need two different output types */
1577
return;
1578
if (present == 3)
1579
spec->automute_hp_lo = 1; /* both HP and LO automute */
1580
1581
if (!cfg->speaker_pins[0]) {
1582
memcpy(cfg->speaker_pins, cfg->line_out_pins,
1583
sizeof(cfg->speaker_pins));
1584
cfg->speaker_outs = cfg->line_outs;
1585
}
1586
1587
if (!cfg->hp_pins[0]) {
1588
memcpy(cfg->hp_pins, cfg->line_out_pins,
1589
sizeof(cfg->hp_pins));
1590
cfg->hp_outs = cfg->line_outs;
1591
}
1592
1593
for (i = 0; i < cfg->hp_outs; i++) {
1594
hda_nid_t nid = cfg->hp_pins[i];
1595
if (!is_jack_detectable(codec, nid))
1596
continue;
1597
snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1598
nid);
1599
snd_hda_codec_write_cache(codec, nid, 0,
1600
AC_VERB_SET_UNSOLICITED_ENABLE,
1601
AC_USRSP_EN | ALC880_HP_EVENT);
1602
spec->automute = 1;
1603
spec->automute_mode = ALC_AUTOMUTE_PIN;
1604
}
1605
if (spec->automute && cfg->line_out_pins[0] &&
1606
cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1607
cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1608
for (i = 0; i < cfg->line_outs; i++) {
1609
hda_nid_t nid = cfg->line_out_pins[i];
1610
if (!is_jack_detectable(codec, nid))
1611
continue;
1612
snd_printdd("realtek: Enable Line-Out auto-muting "
1613
"on NID 0x%x\n", nid);
1614
snd_hda_codec_write_cache(codec, nid, 0,
1615
AC_VERB_SET_UNSOLICITED_ENABLE,
1616
AC_USRSP_EN | ALC880_FRONT_EVENT);
1617
spec->detect_line = 1;
1618
}
1619
spec->automute_lines = spec->detect_line;
1620
}
1621
1622
if (spec->automute) {
1623
/* create a control for automute mode */
1624
alc_add_automute_mode_enum(codec);
1625
spec->unsol_event = alc_sku_unsol_event;
1626
}
1627
}
1628
1629
static void alc_init_auto_mic(struct hda_codec *codec)
1630
{
1631
struct alc_spec *spec = codec->spec;
1632
struct auto_pin_cfg *cfg = &spec->autocfg;
1633
hda_nid_t fixed, ext, dock;
1634
int i;
1635
1636
fixed = ext = dock = 0;
1637
for (i = 0; i < cfg->num_inputs; i++) {
1638
hda_nid_t nid = cfg->inputs[i].pin;
1639
unsigned int defcfg;
1640
defcfg = snd_hda_codec_get_pincfg(codec, nid);
1641
switch (snd_hda_get_input_pin_attr(defcfg)) {
1642
case INPUT_PIN_ATTR_INT:
1643
if (fixed)
1644
return; /* already occupied */
1645
if (cfg->inputs[i].type != AUTO_PIN_MIC)
1646
return; /* invalid type */
1647
fixed = nid;
1648
break;
1649
case INPUT_PIN_ATTR_UNUSED:
1650
return; /* invalid entry */
1651
case INPUT_PIN_ATTR_DOCK:
1652
if (dock)
1653
return; /* already occupied */
1654
if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1655
return; /* invalid type */
1656
dock = nid;
1657
break;
1658
default:
1659
if (ext)
1660
return; /* already occupied */
1661
if (cfg->inputs[i].type != AUTO_PIN_MIC)
1662
return; /* invalid type */
1663
ext = nid;
1664
break;
1665
}
1666
}
1667
if (!ext && dock) {
1668
ext = dock;
1669
dock = 0;
1670
}
1671
if (!ext || !fixed)
1672
return;
1673
if (!is_jack_detectable(codec, ext))
1674
return; /* no unsol support */
1675
if (dock && !is_jack_detectable(codec, dock))
1676
return; /* no unsol support */
1677
snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1678
ext, fixed, dock);
1679
spec->ext_mic.pin = ext;
1680
spec->dock_mic.pin = dock;
1681
spec->int_mic.pin = fixed;
1682
spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1683
spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1684
spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1685
spec->auto_mic = 1;
1686
snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1687
AC_VERB_SET_UNSOLICITED_ENABLE,
1688
AC_USRSP_EN | ALC880_MIC_EVENT);
1689
spec->unsol_event = alc_sku_unsol_event;
1690
}
1691
1692
/* Could be any non-zero and even value. When used as fixup, tells
1693
* the driver to ignore any present sku defines.
1694
*/
1695
#define ALC_FIXUP_SKU_IGNORE (2)
1696
1697
static int alc_auto_parse_customize_define(struct hda_codec *codec)
1698
{
1699
unsigned int ass, tmp, i;
1700
unsigned nid = 0;
1701
struct alc_spec *spec = codec->spec;
1702
1703
spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1704
1705
if (spec->cdefine.fixup) {
1706
ass = spec->cdefine.sku_cfg;
1707
if (ass == ALC_FIXUP_SKU_IGNORE)
1708
return -1;
1709
goto do_sku;
1710
}
1711
1712
ass = codec->subsystem_id & 0xffff;
1713
if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1714
goto do_sku;
1715
1716
nid = 0x1d;
1717
if (codec->vendor_id == 0x10ec0260)
1718
nid = 0x17;
1719
ass = snd_hda_codec_get_pincfg(codec, nid);
1720
1721
if (!(ass & 1)) {
1722
printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1723
codec->chip_name, ass);
1724
return -1;
1725
}
1726
1727
/* check sum */
1728
tmp = 0;
1729
for (i = 1; i < 16; i++) {
1730
if ((ass >> i) & 1)
1731
tmp++;
1732
}
1733
if (((ass >> 16) & 0xf) != tmp)
1734
return -1;
1735
1736
spec->cdefine.port_connectivity = ass >> 30;
1737
spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1738
spec->cdefine.check_sum = (ass >> 16) & 0xf;
1739
spec->cdefine.customization = ass >> 8;
1740
do_sku:
1741
spec->cdefine.sku_cfg = ass;
1742
spec->cdefine.external_amp = (ass & 0x38) >> 3;
1743
spec->cdefine.platform_type = (ass & 0x4) >> 2;
1744
spec->cdefine.swap = (ass & 0x2) >> 1;
1745
spec->cdefine.override = ass & 0x1;
1746
1747
snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1748
nid, spec->cdefine.sku_cfg);
1749
snd_printd("SKU: port_connectivity=0x%x\n",
1750
spec->cdefine.port_connectivity);
1751
snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1752
snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1753
snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1754
snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1755
snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1756
snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1757
snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1758
1759
return 0;
1760
}
1761
1762
/* check subsystem ID and set up device-specific initialization;
1763
* return 1 if initialized, 0 if invalid SSID
1764
*/
1765
/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1766
* 31 ~ 16 : Manufacture ID
1767
* 15 ~ 8 : SKU ID
1768
* 7 ~ 0 : Assembly ID
1769
* port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1770
*/
1771
static int alc_subsystem_id(struct hda_codec *codec,
1772
hda_nid_t porta, hda_nid_t porte,
1773
hda_nid_t portd, hda_nid_t porti)
1774
{
1775
unsigned int ass, tmp, i;
1776
unsigned nid;
1777
struct alc_spec *spec = codec->spec;
1778
1779
if (spec->cdefine.fixup) {
1780
ass = spec->cdefine.sku_cfg;
1781
if (ass == ALC_FIXUP_SKU_IGNORE)
1782
return 0;
1783
goto do_sku;
1784
}
1785
1786
ass = codec->subsystem_id & 0xffff;
1787
if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1788
goto do_sku;
1789
1790
/* invalid SSID, check the special NID pin defcfg instead */
1791
/*
1792
* 31~30 : port connectivity
1793
* 29~21 : reserve
1794
* 20 : PCBEEP input
1795
* 19~16 : Check sum (15:1)
1796
* 15~1 : Custom
1797
* 0 : override
1798
*/
1799
nid = 0x1d;
1800
if (codec->vendor_id == 0x10ec0260)
1801
nid = 0x17;
1802
ass = snd_hda_codec_get_pincfg(codec, nid);
1803
snd_printd("realtek: No valid SSID, "
1804
"checking pincfg 0x%08x for NID 0x%x\n",
1805
ass, nid);
1806
if (!(ass & 1))
1807
return 0;
1808
if ((ass >> 30) != 1) /* no physical connection */
1809
return 0;
1810
1811
/* check sum */
1812
tmp = 0;
1813
for (i = 1; i < 16; i++) {
1814
if ((ass >> i) & 1)
1815
tmp++;
1816
}
1817
if (((ass >> 16) & 0xf) != tmp)
1818
return 0;
1819
do_sku:
1820
snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1821
ass & 0xffff, codec->vendor_id);
1822
/*
1823
* 0 : override
1824
* 1 : Swap Jack
1825
* 2 : 0 --> Desktop, 1 --> Laptop
1826
* 3~5 : External Amplifier control
1827
* 7~6 : Reserved
1828
*/
1829
tmp = (ass & 0x38) >> 3; /* external Amp control */
1830
switch (tmp) {
1831
case 1:
1832
spec->init_amp = ALC_INIT_GPIO1;
1833
break;
1834
case 3:
1835
spec->init_amp = ALC_INIT_GPIO2;
1836
break;
1837
case 7:
1838
spec->init_amp = ALC_INIT_GPIO3;
1839
break;
1840
case 5:
1841
default:
1842
spec->init_amp = ALC_INIT_DEFAULT;
1843
break;
1844
}
1845
1846
/* is laptop or Desktop and enable the function "Mute internal speaker
1847
* when the external headphone out jack is plugged"
1848
*/
1849
if (!(ass & 0x8000))
1850
return 1;
1851
/*
1852
* 10~8 : Jack location
1853
* 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1854
* 14~13: Resvered
1855
* 15 : 1 --> enable the function "Mute internal speaker
1856
* when the external headphone out jack is plugged"
1857
*/
1858
if (!spec->autocfg.hp_pins[0]) {
1859
hda_nid_t nid;
1860
tmp = (ass >> 11) & 0x3; /* HP to chassis */
1861
if (tmp == 0)
1862
nid = porta;
1863
else if (tmp == 1)
1864
nid = porte;
1865
else if (tmp == 2)
1866
nid = portd;
1867
else if (tmp == 3)
1868
nid = porti;
1869
else
1870
return 1;
1871
for (i = 0; i < spec->autocfg.line_outs; i++)
1872
if (spec->autocfg.line_out_pins[i] == nid)
1873
return 1;
1874
spec->autocfg.hp_pins[0] = nid;
1875
}
1876
return 1;
1877
}
1878
1879
static void alc_ssid_check(struct hda_codec *codec,
1880
hda_nid_t porta, hda_nid_t porte,
1881
hda_nid_t portd, hda_nid_t porti)
1882
{
1883
if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1884
struct alc_spec *spec = codec->spec;
1885
snd_printd("realtek: "
1886
"Enable default setup for auto mode as fallback\n");
1887
spec->init_amp = ALC_INIT_DEFAULT;
1888
}
1889
1890
alc_init_auto_hp(codec);
1891
alc_init_auto_mic(codec);
1892
}
1893
1894
/*
1895
* Fix-up pin default configurations and add default verbs
1896
*/
1897
1898
struct alc_pincfg {
1899
hda_nid_t nid;
1900
u32 val;
1901
};
1902
1903
struct alc_model_fixup {
1904
const int id;
1905
const char *name;
1906
};
1907
1908
struct alc_fixup {
1909
int type;
1910
bool chained;
1911
int chain_id;
1912
union {
1913
unsigned int sku;
1914
const struct alc_pincfg *pins;
1915
const struct hda_verb *verbs;
1916
void (*func)(struct hda_codec *codec,
1917
const struct alc_fixup *fix,
1918
int action);
1919
} v;
1920
};
1921
1922
enum {
1923
ALC_FIXUP_INVALID,
1924
ALC_FIXUP_SKU,
1925
ALC_FIXUP_PINS,
1926
ALC_FIXUP_VERBS,
1927
ALC_FIXUP_FUNC,
1928
};
1929
1930
enum {
1931
ALC_FIXUP_ACT_PRE_PROBE,
1932
ALC_FIXUP_ACT_PROBE,
1933
ALC_FIXUP_ACT_INIT,
1934
};
1935
1936
static void alc_apply_fixup(struct hda_codec *codec, int action)
1937
{
1938
struct alc_spec *spec = codec->spec;
1939
int id = spec->fixup_id;
1940
#ifdef CONFIG_SND_DEBUG_VERBOSE
1941
const char *modelname = spec->fixup_name;
1942
#endif
1943
int depth = 0;
1944
1945
if (!spec->fixup_list)
1946
return;
1947
1948
while (id >= 0) {
1949
const struct alc_fixup *fix = spec->fixup_list + id;
1950
const struct alc_pincfg *cfg;
1951
1952
switch (fix->type) {
1953
case ALC_FIXUP_SKU:
1954
if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1955
break;;
1956
snd_printdd(KERN_INFO "hda_codec: %s: "
1957
"Apply sku override for %s\n",
1958
codec->chip_name, modelname);
1959
spec->cdefine.sku_cfg = fix->v.sku;
1960
spec->cdefine.fixup = 1;
1961
break;
1962
case ALC_FIXUP_PINS:
1963
cfg = fix->v.pins;
1964
if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1965
break;
1966
snd_printdd(KERN_INFO "hda_codec: %s: "
1967
"Apply pincfg for %s\n",
1968
codec->chip_name, modelname);
1969
for (; cfg->nid; cfg++)
1970
snd_hda_codec_set_pincfg(codec, cfg->nid,
1971
cfg->val);
1972
break;
1973
case ALC_FIXUP_VERBS:
1974
if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1975
break;
1976
snd_printdd(KERN_INFO "hda_codec: %s: "
1977
"Apply fix-verbs for %s\n",
1978
codec->chip_name, modelname);
1979
add_verb(codec->spec, fix->v.verbs);
1980
break;
1981
case ALC_FIXUP_FUNC:
1982
if (!fix->v.func)
1983
break;
1984
snd_printdd(KERN_INFO "hda_codec: %s: "
1985
"Apply fix-func for %s\n",
1986
codec->chip_name, modelname);
1987
fix->v.func(codec, fix, action);
1988
break;
1989
default:
1990
snd_printk(KERN_ERR "hda_codec: %s: "
1991
"Invalid fixup type %d\n",
1992
codec->chip_name, fix->type);
1993
break;
1994
}
1995
if (!fix->chained)
1996
break;
1997
if (++depth > 10)
1998
break;
1999
id = fix->chain_id;
2000
}
2001
}
2002
2003
static void alc_pick_fixup(struct hda_codec *codec,
2004
const struct alc_model_fixup *models,
2005
const struct snd_pci_quirk *quirk,
2006
const struct alc_fixup *fixlist)
2007
{
2008
struct alc_spec *spec = codec->spec;
2009
int id = -1;
2010
const char *name = NULL;
2011
2012
if (codec->modelname && models) {
2013
while (models->name) {
2014
if (!strcmp(codec->modelname, models->name)) {
2015
id = models->id;
2016
name = models->name;
2017
break;
2018
}
2019
models++;
2020
}
2021
}
2022
if (id < 0) {
2023
quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2024
if (quirk) {
2025
id = quirk->value;
2026
#ifdef CONFIG_SND_DEBUG_VERBOSE
2027
name = quirk->name;
2028
#endif
2029
}
2030
}
2031
2032
spec->fixup_id = id;
2033
if (id >= 0) {
2034
spec->fixup_list = fixlist;
2035
spec->fixup_name = name;
2036
}
2037
}
2038
2039
static int alc_read_coef_idx(struct hda_codec *codec,
2040
unsigned int coef_idx)
2041
{
2042
unsigned int val;
2043
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2044
coef_idx);
2045
val = snd_hda_codec_read(codec, 0x20, 0,
2046
AC_VERB_GET_PROC_COEF, 0);
2047
return val;
2048
}
2049
2050
static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2051
unsigned int coef_val)
2052
{
2053
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2054
coef_idx);
2055
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2056
coef_val);
2057
}
2058
2059
/* set right pin controls for digital I/O */
2060
static void alc_auto_init_digital(struct hda_codec *codec)
2061
{
2062
struct alc_spec *spec = codec->spec;
2063
int i;
2064
hda_nid_t pin;
2065
2066
for (i = 0; i < spec->autocfg.dig_outs; i++) {
2067
pin = spec->autocfg.dig_out_pins[i];
2068
if (pin) {
2069
snd_hda_codec_write(codec, pin, 0,
2070
AC_VERB_SET_PIN_WIDGET_CONTROL,
2071
PIN_OUT);
2072
}
2073
}
2074
pin = spec->autocfg.dig_in_pin;
2075
if (pin)
2076
snd_hda_codec_write(codec, pin, 0,
2077
AC_VERB_SET_PIN_WIDGET_CONTROL,
2078
PIN_IN);
2079
}
2080
2081
/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2082
static void alc_auto_parse_digital(struct hda_codec *codec)
2083
{
2084
struct alc_spec *spec = codec->spec;
2085
int i, err;
2086
hda_nid_t dig_nid;
2087
2088
/* support multiple SPDIFs; the secondary is set up as a slave */
2089
for (i = 0; i < spec->autocfg.dig_outs; i++) {
2090
err = snd_hda_get_connections(codec,
2091
spec->autocfg.dig_out_pins[i],
2092
&dig_nid, 1);
2093
if (err < 0)
2094
continue;
2095
if (!i) {
2096
spec->multiout.dig_out_nid = dig_nid;
2097
spec->dig_out_type = spec->autocfg.dig_out_type[0];
2098
} else {
2099
spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2100
if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2101
break;
2102
spec->slave_dig_outs[i - 1] = dig_nid;
2103
}
2104
}
2105
2106
if (spec->autocfg.dig_in_pin) {
2107
dig_nid = codec->start_nid;
2108
for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2109
unsigned int wcaps = get_wcaps(codec, dig_nid);
2110
if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2111
continue;
2112
if (!(wcaps & AC_WCAP_DIGITAL))
2113
continue;
2114
if (!(wcaps & AC_WCAP_CONN_LIST))
2115
continue;
2116
err = get_connection_index(codec, dig_nid,
2117
spec->autocfg.dig_in_pin);
2118
if (err >= 0) {
2119
spec->dig_in_nid = dig_nid;
2120
break;
2121
}
2122
}
2123
}
2124
}
2125
2126
/*
2127
* ALC888
2128
*/
2129
2130
/*
2131
* 2ch mode
2132
*/
2133
static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2134
/* Mic-in jack as mic in */
2135
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2136
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2137
/* Line-in jack as Line in */
2138
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2139
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2140
/* Line-Out as Front */
2141
{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2142
{ } /* end */
2143
};
2144
2145
/*
2146
* 4ch mode
2147
*/
2148
static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2149
/* Mic-in jack as mic in */
2150
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2151
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2152
/* Line-in jack as Surround */
2153
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2154
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2155
/* Line-Out as Front */
2156
{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2157
{ } /* end */
2158
};
2159
2160
/*
2161
* 6ch mode
2162
*/
2163
static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2164
/* Mic-in jack as CLFE */
2165
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2166
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2167
/* Line-in jack as Surround */
2168
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2169
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2170
/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2171
{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2172
{ } /* end */
2173
};
2174
2175
/*
2176
* 8ch mode
2177
*/
2178
static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2179
/* Mic-in jack as CLFE */
2180
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2181
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2182
/* Line-in jack as Surround */
2183
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2184
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2185
/* Line-Out as Side */
2186
{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2187
{ } /* end */
2188
};
2189
2190
static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2191
{ 2, alc888_4ST_ch2_intel_init },
2192
{ 4, alc888_4ST_ch4_intel_init },
2193
{ 6, alc888_4ST_ch6_intel_init },
2194
{ 8, alc888_4ST_ch8_intel_init },
2195
};
2196
2197
/*
2198
* ALC888 Fujitsu Siemens Amillo xa3530
2199
*/
2200
2201
static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2202
/* Front Mic: set to PIN_IN (empty by default) */
2203
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2204
/* Connect Internal HP to Front */
2205
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2206
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2207
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2208
/* Connect Bass HP to Front */
2209
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2210
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2211
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2212
/* Connect Line-Out side jack (SPDIF) to Side */
2213
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2214
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2215
{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2216
/* Connect Mic jack to CLFE */
2217
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2218
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2219
{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2220
/* Connect Line-in jack to Surround */
2221
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2224
/* Connect HP out jack to Front */
2225
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2226
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2228
/* Enable unsolicited event for HP jack and Line-out jack */
2229
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2230
{0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2231
{}
2232
};
2233
2234
static void alc889_automute_setup(struct hda_codec *codec)
2235
{
2236
struct alc_spec *spec = codec->spec;
2237
2238
spec->autocfg.hp_pins[0] = 0x15;
2239
spec->autocfg.speaker_pins[0] = 0x14;
2240
spec->autocfg.speaker_pins[1] = 0x16;
2241
spec->autocfg.speaker_pins[2] = 0x17;
2242
spec->autocfg.speaker_pins[3] = 0x19;
2243
spec->autocfg.speaker_pins[4] = 0x1a;
2244
spec->automute = 1;
2245
spec->automute_mode = ALC_AUTOMUTE_AMP;
2246
}
2247
2248
static void alc889_intel_init_hook(struct hda_codec *codec)
2249
{
2250
alc889_coef_init(codec);
2251
alc_hp_automute(codec);
2252
}
2253
2254
static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2255
{
2256
struct alc_spec *spec = codec->spec;
2257
2258
spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2259
spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2260
spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2261
spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2262
spec->automute = 1;
2263
spec->automute_mode = ALC_AUTOMUTE_AMP;
2264
}
2265
2266
/*
2267
* ALC888 Acer Aspire 4930G model
2268
*/
2269
2270
static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2271
/* Front Mic: set to PIN_IN (empty by default) */
2272
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2273
/* Unselect Front Mic by default in input mixer 3 */
2274
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2275
/* Enable unsolicited event for HP jack */
2276
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2277
/* Connect Internal HP to front */
2278
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2279
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2280
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2281
/* Connect HP out to front */
2282
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2283
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2284
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2285
{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2286
{ }
2287
};
2288
2289
/*
2290
* ALC888 Acer Aspire 6530G model
2291
*/
2292
2293
static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2294
/* Route to built-in subwoofer as well as speakers */
2295
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2296
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2297
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2298
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2299
/* Bias voltage on for external mic port */
2300
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2301
/* Front Mic: set to PIN_IN (empty by default) */
2302
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2303
/* Unselect Front Mic by default in input mixer 3 */
2304
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2305
/* Enable unsolicited event for HP jack */
2306
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2307
/* Enable speaker output */
2308
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2309
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2310
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2311
/* Enable headphone output */
2312
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2313
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2314
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2315
{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2316
{ }
2317
};
2318
2319
/*
2320
*ALC888 Acer Aspire 7730G model
2321
*/
2322
2323
static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2324
/* Bias voltage on for external mic port */
2325
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2326
/* Front Mic: set to PIN_IN (empty by default) */
2327
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2328
/* Unselect Front Mic by default in input mixer 3 */
2329
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2330
/* Enable unsolicited event for HP jack */
2331
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2332
/* Enable speaker output */
2333
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2334
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2335
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2336
/* Enable headphone output */
2337
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2338
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2339
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2340
{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2341
/*Enable internal subwoofer */
2342
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2343
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2344
{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2345
{0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2346
{ }
2347
};
2348
2349
/*
2350
* ALC889 Acer Aspire 8930G model
2351
*/
2352
2353
static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2354
/* Front Mic: set to PIN_IN (empty by default) */
2355
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2356
/* Unselect Front Mic by default in input mixer 3 */
2357
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2358
/* Enable unsolicited event for HP jack */
2359
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2360
/* Connect Internal Front to Front */
2361
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2362
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2363
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2364
/* Connect Internal Rear to Rear */
2365
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2366
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2367
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2368
/* Connect Internal CLFE to CLFE */
2369
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2370
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2371
{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2372
/* Connect HP out to Front */
2373
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2374
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2375
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2376
/* Enable all DACs */
2377
/* DAC DISABLE/MUTE 1? */
2378
/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2379
{0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2380
{0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2381
/* DAC DISABLE/MUTE 2? */
2382
/* some bit here disables the other DACs. Init=0x4900 */
2383
{0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2384
{0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2385
/* DMIC fix
2386
* This laptop has a stereo digital microphone. The mics are only 1cm apart
2387
* which makes the stereo useless. However, either the mic or the ALC889
2388
* makes the signal become a difference/sum signal instead of standard
2389
* stereo, which is annoying. So instead we flip this bit which makes the
2390
* codec replicate the sum signal to both channels, turning it into a
2391
* normal mono mic.
2392
*/
2393
/* DMIC_CONTROL? Init value = 0x0001 */
2394
{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2395
{0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2396
{ }
2397
};
2398
2399
static const struct hda_input_mux alc888_2_capture_sources[2] = {
2400
/* Front mic only available on one ADC */
2401
{
2402
.num_items = 4,
2403
.items = {
2404
{ "Mic", 0x0 },
2405
{ "Line", 0x2 },
2406
{ "CD", 0x4 },
2407
{ "Front Mic", 0xb },
2408
},
2409
},
2410
{
2411
.num_items = 3,
2412
.items = {
2413
{ "Mic", 0x0 },
2414
{ "Line", 0x2 },
2415
{ "CD", 0x4 },
2416
},
2417
}
2418
};
2419
2420
static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2421
/* Interal mic only available on one ADC */
2422
{
2423
.num_items = 5,
2424
.items = {
2425
{ "Mic", 0x0 },
2426
{ "Line In", 0x2 },
2427
{ "CD", 0x4 },
2428
{ "Input Mix", 0xa },
2429
{ "Internal Mic", 0xb },
2430
},
2431
},
2432
{
2433
.num_items = 4,
2434
.items = {
2435
{ "Mic", 0x0 },
2436
{ "Line In", 0x2 },
2437
{ "CD", 0x4 },
2438
{ "Input Mix", 0xa },
2439
},
2440
}
2441
};
2442
2443
static const struct hda_input_mux alc889_capture_sources[3] = {
2444
/* Digital mic only available on first "ADC" */
2445
{
2446
.num_items = 5,
2447
.items = {
2448
{ "Mic", 0x0 },
2449
{ "Line", 0x2 },
2450
{ "CD", 0x4 },
2451
{ "Front Mic", 0xb },
2452
{ "Input Mix", 0xa },
2453
},
2454
},
2455
{
2456
.num_items = 4,
2457
.items = {
2458
{ "Mic", 0x0 },
2459
{ "Line", 0x2 },
2460
{ "CD", 0x4 },
2461
{ "Input Mix", 0xa },
2462
},
2463
},
2464
{
2465
.num_items = 4,
2466
.items = {
2467
{ "Mic", 0x0 },
2468
{ "Line", 0x2 },
2469
{ "CD", 0x4 },
2470
{ "Input Mix", 0xa },
2471
},
2472
}
2473
};
2474
2475
static const struct snd_kcontrol_new alc888_base_mixer[] = {
2476
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2477
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2478
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2479
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2480
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2481
HDA_OUTPUT),
2482
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2483
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2484
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2485
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2486
HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2487
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2488
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2489
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2490
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2491
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2492
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2493
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2494
{ } /* end */
2495
};
2496
2497
static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2498
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2499
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2500
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2501
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2502
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2503
HDA_OUTPUT),
2504
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2505
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2506
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2507
HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2508
HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2509
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2510
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2511
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2512
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2513
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2514
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2515
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2516
{ } /* end */
2517
};
2518
2519
static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2520
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2521
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2522
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2523
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2524
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2525
HDA_OUTPUT),
2526
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2527
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2528
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2529
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2530
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2531
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2532
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2533
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2534
{ } /* end */
2535
};
2536
2537
2538
static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2539
{
2540
struct alc_spec *spec = codec->spec;
2541
2542
spec->autocfg.hp_pins[0] = 0x15;
2543
spec->autocfg.speaker_pins[0] = 0x14;
2544
spec->autocfg.speaker_pins[1] = 0x16;
2545
spec->autocfg.speaker_pins[2] = 0x17;
2546
spec->automute = 1;
2547
spec->automute_mode = ALC_AUTOMUTE_AMP;
2548
}
2549
2550
static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2551
{
2552
struct alc_spec *spec = codec->spec;
2553
2554
spec->autocfg.hp_pins[0] = 0x15;
2555
spec->autocfg.speaker_pins[0] = 0x14;
2556
spec->autocfg.speaker_pins[1] = 0x16;
2557
spec->autocfg.speaker_pins[2] = 0x17;
2558
spec->automute = 1;
2559
spec->automute_mode = ALC_AUTOMUTE_AMP;
2560
}
2561
2562
static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2563
{
2564
struct alc_spec *spec = codec->spec;
2565
2566
spec->autocfg.hp_pins[0] = 0x15;
2567
spec->autocfg.speaker_pins[0] = 0x14;
2568
spec->autocfg.speaker_pins[1] = 0x16;
2569
spec->autocfg.speaker_pins[2] = 0x17;
2570
spec->automute = 1;
2571
spec->automute_mode = ALC_AUTOMUTE_AMP;
2572
}
2573
2574
static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2575
{
2576
struct alc_spec *spec = codec->spec;
2577
2578
spec->autocfg.hp_pins[0] = 0x15;
2579
spec->autocfg.speaker_pins[0] = 0x14;
2580
spec->autocfg.speaker_pins[1] = 0x16;
2581
spec->autocfg.speaker_pins[2] = 0x1b;
2582
spec->automute = 1;
2583
spec->automute_mode = ALC_AUTOMUTE_AMP;
2584
}
2585
2586
/*
2587
* ALC880 3-stack model
2588
*
2589
* DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2590
* Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2591
* F-Mic = 0x1b, HP = 0x19
2592
*/
2593
2594
static const hda_nid_t alc880_dac_nids[4] = {
2595
/* front, rear, clfe, rear_surr */
2596
0x02, 0x05, 0x04, 0x03
2597
};
2598
2599
static const hda_nid_t alc880_adc_nids[3] = {
2600
/* ADC0-2 */
2601
0x07, 0x08, 0x09,
2602
};
2603
2604
/* The datasheet says the node 0x07 is connected from inputs,
2605
* but it shows zero connection in the real implementation on some devices.
2606
* Note: this is a 915GAV bug, fixed on 915GLV
2607
*/
2608
static const hda_nid_t alc880_adc_nids_alt[2] = {
2609
/* ADC1-2 */
2610
0x08, 0x09,
2611
};
2612
2613
#define ALC880_DIGOUT_NID 0x06
2614
#define ALC880_DIGIN_NID 0x0a
2615
2616
static const struct hda_input_mux alc880_capture_source = {
2617
.num_items = 4,
2618
.items = {
2619
{ "Mic", 0x0 },
2620
{ "Front Mic", 0x3 },
2621
{ "Line", 0x2 },
2622
{ "CD", 0x4 },
2623
},
2624
};
2625
2626
/* channel source setting (2/6 channel selection for 3-stack) */
2627
/* 2ch mode */
2628
static const struct hda_verb alc880_threestack_ch2_init[] = {
2629
/* set line-in to input, mute it */
2630
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2631
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2632
/* set mic-in to input vref 80%, mute it */
2633
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2634
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2635
{ } /* end */
2636
};
2637
2638
/* 6ch mode */
2639
static const struct hda_verb alc880_threestack_ch6_init[] = {
2640
/* set line-in to output, unmute it */
2641
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2642
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2643
/* set mic-in to output, unmute it */
2644
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2645
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2646
{ } /* end */
2647
};
2648
2649
static const struct hda_channel_mode alc880_threestack_modes[2] = {
2650
{ 2, alc880_threestack_ch2_init },
2651
{ 6, alc880_threestack_ch6_init },
2652
};
2653
2654
static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2655
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2656
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2657
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2658
HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2659
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2660
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2661
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2662
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2663
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2664
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2665
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2666
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2667
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2668
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2669
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2670
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2671
HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2672
{
2673
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2674
.name = "Channel Mode",
2675
.info = alc_ch_mode_info,
2676
.get = alc_ch_mode_get,
2677
.put = alc_ch_mode_put,
2678
},
2679
{ } /* end */
2680
};
2681
2682
/* capture mixer elements */
2683
static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2684
struct snd_ctl_elem_info *uinfo)
2685
{
2686
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2687
struct alc_spec *spec = codec->spec;
2688
int err;
2689
2690
mutex_lock(&codec->control_mutex);
2691
kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2692
HDA_INPUT);
2693
err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2694
mutex_unlock(&codec->control_mutex);
2695
return err;
2696
}
2697
2698
static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2699
unsigned int size, unsigned int __user *tlv)
2700
{
2701
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2702
struct alc_spec *spec = codec->spec;
2703
int err;
2704
2705
mutex_lock(&codec->control_mutex);
2706
kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2707
HDA_INPUT);
2708
err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2709
mutex_unlock(&codec->control_mutex);
2710
return err;
2711
}
2712
2713
typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2714
struct snd_ctl_elem_value *ucontrol);
2715
2716
static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2717
struct snd_ctl_elem_value *ucontrol,
2718
getput_call_t func, bool check_adc_switch)
2719
{
2720
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2721
struct alc_spec *spec = codec->spec;
2722
int i, err = 0;
2723
2724
mutex_lock(&codec->control_mutex);
2725
if (check_adc_switch && spec->dual_adc_switch) {
2726
for (i = 0; i < spec->num_adc_nids; i++) {
2727
kcontrol->private_value =
2728
HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2729
3, 0, HDA_INPUT);
2730
err = func(kcontrol, ucontrol);
2731
if (err < 0)
2732
goto error;
2733
}
2734
} else {
2735
i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2736
kcontrol->private_value =
2737
HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2738
3, 0, HDA_INPUT);
2739
err = func(kcontrol, ucontrol);
2740
}
2741
error:
2742
mutex_unlock(&codec->control_mutex);
2743
return err;
2744
}
2745
2746
static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2747
struct snd_ctl_elem_value *ucontrol)
2748
{
2749
return alc_cap_getput_caller(kcontrol, ucontrol,
2750
snd_hda_mixer_amp_volume_get, false);
2751
}
2752
2753
static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2754
struct snd_ctl_elem_value *ucontrol)
2755
{
2756
return alc_cap_getput_caller(kcontrol, ucontrol,
2757
snd_hda_mixer_amp_volume_put, true);
2758
}
2759
2760
/* capture mixer elements */
2761
#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2762
2763
static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2764
struct snd_ctl_elem_value *ucontrol)
2765
{
2766
return alc_cap_getput_caller(kcontrol, ucontrol,
2767
snd_hda_mixer_amp_switch_get, false);
2768
}
2769
2770
static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2771
struct snd_ctl_elem_value *ucontrol)
2772
{
2773
return alc_cap_getput_caller(kcontrol, ucontrol,
2774
snd_hda_mixer_amp_switch_put, true);
2775
}
2776
2777
#define _DEFINE_CAPMIX(num) \
2778
{ \
2779
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2780
.name = "Capture Switch", \
2781
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2782
.count = num, \
2783
.info = alc_cap_sw_info, \
2784
.get = alc_cap_sw_get, \
2785
.put = alc_cap_sw_put, \
2786
}, \
2787
{ \
2788
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2789
.name = "Capture Volume", \
2790
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2791
SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2792
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2793
.count = num, \
2794
.info = alc_cap_vol_info, \
2795
.get = alc_cap_vol_get, \
2796
.put = alc_cap_vol_put, \
2797
.tlv = { .c = alc_cap_vol_tlv }, \
2798
}
2799
2800
#define _DEFINE_CAPSRC(num) \
2801
{ \
2802
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2803
/* .name = "Capture Source", */ \
2804
.name = "Input Source", \
2805
.count = num, \
2806
.info = alc_mux_enum_info, \
2807
.get = alc_mux_enum_get, \
2808
.put = alc_mux_enum_put, \
2809
}
2810
2811
#define DEFINE_CAPMIX(num) \
2812
static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2813
_DEFINE_CAPMIX(num), \
2814
_DEFINE_CAPSRC(num), \
2815
{ } /* end */ \
2816
}
2817
2818
#define DEFINE_CAPMIX_NOSRC(num) \
2819
static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2820
_DEFINE_CAPMIX(num), \
2821
{ } /* end */ \
2822
}
2823
2824
/* up to three ADCs */
2825
DEFINE_CAPMIX(1);
2826
DEFINE_CAPMIX(2);
2827
DEFINE_CAPMIX(3);
2828
DEFINE_CAPMIX_NOSRC(1);
2829
DEFINE_CAPMIX_NOSRC(2);
2830
DEFINE_CAPMIX_NOSRC(3);
2831
2832
/*
2833
* ALC880 5-stack model
2834
*
2835
* DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2836
* Side = 0x02 (0xd)
2837
* Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2838
* Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2839
*/
2840
2841
/* additional mixers to alc880_three_stack_mixer */
2842
static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2843
HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2844
HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2845
{ } /* end */
2846
};
2847
2848
/* channel source setting (6/8 channel selection for 5-stack) */
2849
/* 6ch mode */
2850
static const struct hda_verb alc880_fivestack_ch6_init[] = {
2851
/* set line-in to input, mute it */
2852
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2853
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2854
{ } /* end */
2855
};
2856
2857
/* 8ch mode */
2858
static const struct hda_verb alc880_fivestack_ch8_init[] = {
2859
/* set line-in to output, unmute it */
2860
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2861
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2862
{ } /* end */
2863
};
2864
2865
static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2866
{ 6, alc880_fivestack_ch6_init },
2867
{ 8, alc880_fivestack_ch8_init },
2868
};
2869
2870
2871
/*
2872
* ALC880 6-stack model
2873
*
2874
* DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2875
* Side = 0x05 (0x0f)
2876
* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2877
* Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2878
*/
2879
2880
static const hda_nid_t alc880_6st_dac_nids[4] = {
2881
/* front, rear, clfe, rear_surr */
2882
0x02, 0x03, 0x04, 0x05
2883
};
2884
2885
static const struct hda_input_mux alc880_6stack_capture_source = {
2886
.num_items = 4,
2887
.items = {
2888
{ "Mic", 0x0 },
2889
{ "Front Mic", 0x1 },
2890
{ "Line", 0x2 },
2891
{ "CD", 0x4 },
2892
},
2893
};
2894
2895
/* fixed 8-channels */
2896
static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2897
{ 8, NULL },
2898
};
2899
2900
static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2901
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2902
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2903
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2904
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2905
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2906
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2907
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2908
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2909
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2910
HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2911
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2912
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2913
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2914
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2915
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2916
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2917
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2918
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2919
{
2920
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2921
.name = "Channel Mode",
2922
.info = alc_ch_mode_info,
2923
.get = alc_ch_mode_get,
2924
.put = alc_ch_mode_put,
2925
},
2926
{ } /* end */
2927
};
2928
2929
2930
/*
2931
* ALC880 W810 model
2932
*
2933
* W810 has rear IO for:
2934
* Front (DAC 02)
2935
* Surround (DAC 03)
2936
* Center/LFE (DAC 04)
2937
* Digital out (06)
2938
*
2939
* The system also has a pair of internal speakers, and a headphone jack.
2940
* These are both connected to Line2 on the codec, hence to DAC 02.
2941
*
2942
* There is a variable resistor to control the speaker or headphone
2943
* volume. This is a hardware-only device without a software API.
2944
*
2945
* Plugging headphones in will disable the internal speakers. This is
2946
* implemented in hardware, not via the driver using jack sense. In
2947
* a similar fashion, plugging into the rear socket marked "front" will
2948
* disable both the speakers and headphones.
2949
*
2950
* For input, there's a microphone jack, and an "audio in" jack.
2951
* These may not do anything useful with this driver yet, because I
2952
* haven't setup any initialization verbs for these yet...
2953
*/
2954
2955
static const hda_nid_t alc880_w810_dac_nids[3] = {
2956
/* front, rear/surround, clfe */
2957
0x02, 0x03, 0x04
2958
};
2959
2960
/* fixed 6 channels */
2961
static const struct hda_channel_mode alc880_w810_modes[1] = {
2962
{ 6, NULL }
2963
};
2964
2965
/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2966
static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2967
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2968
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2969
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2970
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2971
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2972
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2973
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2974
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2975
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2976
{ } /* end */
2977
};
2978
2979
2980
/*
2981
* Z710V model
2982
*
2983
* DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2984
* Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2985
* Line = 0x1a
2986
*/
2987
2988
static const hda_nid_t alc880_z71v_dac_nids[1] = {
2989
0x02
2990
};
2991
#define ALC880_Z71V_HP_DAC 0x03
2992
2993
/* fixed 2 channels */
2994
static const struct hda_channel_mode alc880_2_jack_modes[1] = {
2995
{ 2, NULL }
2996
};
2997
2998
static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
2999
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3000
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3001
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3002
HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
3003
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3004
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3005
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3006
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3007
{ } /* end */
3008
};
3009
3010
3011
/*
3012
* ALC880 F1734 model
3013
*
3014
* DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3015
* Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3016
*/
3017
3018
static const hda_nid_t alc880_f1734_dac_nids[1] = {
3019
0x03
3020
};
3021
#define ALC880_F1734_HP_DAC 0x02
3022
3023
static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3024
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3025
HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3026
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3027
HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3028
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3029
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3030
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3031
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3032
{ } /* end */
3033
};
3034
3035
static const struct hda_input_mux alc880_f1734_capture_source = {
3036
.num_items = 2,
3037
.items = {
3038
{ "Mic", 0x1 },
3039
{ "CD", 0x4 },
3040
},
3041
};
3042
3043
3044
/*
3045
* ALC880 ASUS model
3046
*
3047
* DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3048
* Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3049
* Mic = 0x18, Line = 0x1a
3050
*/
3051
3052
#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3053
#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3054
3055
static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3056
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3057
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3058
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3059
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3060
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3061
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3062
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3063
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3064
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3065
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3066
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3067
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3068
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3069
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3070
{
3071
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3072
.name = "Channel Mode",
3073
.info = alc_ch_mode_info,
3074
.get = alc_ch_mode_get,
3075
.put = alc_ch_mode_put,
3076
},
3077
{ } /* end */
3078
};
3079
3080
/*
3081
* ALC880 ASUS W1V model
3082
*
3083
* DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3084
* Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3085
* Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3086
*/
3087
3088
/* additional mixers to alc880_asus_mixer */
3089
static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3090
HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3091
HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3092
{ } /* end */
3093
};
3094
3095
/* TCL S700 */
3096
static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3097
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3098
HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3099
HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3100
HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3101
HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3102
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3103
HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3104
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3105
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3106
{ } /* end */
3107
};
3108
3109
/* Uniwill */
3110
static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3111
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3112
HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3113
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3114
HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3115
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3116
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3117
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3118
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3119
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3120
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3121
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3122
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3123
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3124
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3125
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3126
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3127
{
3128
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3129
.name = "Channel Mode",
3130
.info = alc_ch_mode_info,
3131
.get = alc_ch_mode_get,
3132
.put = alc_ch_mode_put,
3133
},
3134
{ } /* end */
3135
};
3136
3137
static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3138
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3139
HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3140
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3141
HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3142
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3143
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3144
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3145
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3146
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3147
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3148
{ } /* end */
3149
};
3150
3151
static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3152
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3153
HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3154
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3155
HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3156
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3157
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3158
{ } /* end */
3159
};
3160
3161
/*
3162
* virtual master controls
3163
*/
3164
3165
/*
3166
* slave controls for virtual master
3167
*/
3168
static const char * const alc_slave_vols[] = {
3169
"Front Playback Volume",
3170
"Surround Playback Volume",
3171
"Center Playback Volume",
3172
"LFE Playback Volume",
3173
"Side Playback Volume",
3174
"Headphone Playback Volume",
3175
"Speaker Playback Volume",
3176
"Mono Playback Volume",
3177
"Line-Out Playback Volume",
3178
NULL,
3179
};
3180
3181
static const char * const alc_slave_sws[] = {
3182
"Front Playback Switch",
3183
"Surround Playback Switch",
3184
"Center Playback Switch",
3185
"LFE Playback Switch",
3186
"Side Playback Switch",
3187
"Headphone Playback Switch",
3188
"Speaker Playback Switch",
3189
"Mono Playback Switch",
3190
"IEC958 Playback Switch",
3191
"Line-Out Playback Switch",
3192
NULL,
3193
};
3194
3195
/*
3196
* build control elements
3197
*/
3198
3199
#define NID_MAPPING (-1)
3200
3201
#define SUBDEV_SPEAKER_ (0 << 6)
3202
#define SUBDEV_HP_ (1 << 6)
3203
#define SUBDEV_LINE_ (2 << 6)
3204
#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3205
#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3206
#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3207
3208
static void alc_free_kctls(struct hda_codec *codec);
3209
3210
#ifdef CONFIG_SND_HDA_INPUT_BEEP
3211
/* additional beep mixers; the actual parameters are overwritten at build */
3212
static const struct snd_kcontrol_new alc_beep_mixer[] = {
3213
HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
3214
HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
3215
{ } /* end */
3216
};
3217
#endif
3218
3219
static int alc_build_controls(struct hda_codec *codec)
3220
{
3221
struct alc_spec *spec = codec->spec;
3222
struct snd_kcontrol *kctl = NULL;
3223
const struct snd_kcontrol_new *knew;
3224
int i, j, err;
3225
unsigned int u;
3226
hda_nid_t nid;
3227
3228
for (i = 0; i < spec->num_mixers; i++) {
3229
err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3230
if (err < 0)
3231
return err;
3232
}
3233
if (spec->cap_mixer) {
3234
err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3235
if (err < 0)
3236
return err;
3237
}
3238
if (spec->multiout.dig_out_nid) {
3239
err = snd_hda_create_spdif_out_ctls(codec,
3240
spec->multiout.dig_out_nid);
3241
if (err < 0)
3242
return err;
3243
if (!spec->no_analog) {
3244
err = snd_hda_create_spdif_share_sw(codec,
3245
&spec->multiout);
3246
if (err < 0)
3247
return err;
3248
spec->multiout.share_spdif = 1;
3249
}
3250
}
3251
if (spec->dig_in_nid) {
3252
err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3253
if (err < 0)
3254
return err;
3255
}
3256
3257
#ifdef CONFIG_SND_HDA_INPUT_BEEP
3258
/* create beep controls if needed */
3259
if (spec->beep_amp) {
3260
const struct snd_kcontrol_new *knew;
3261
for (knew = alc_beep_mixer; knew->name; knew++) {
3262
struct snd_kcontrol *kctl;
3263
kctl = snd_ctl_new1(knew, codec);
3264
if (!kctl)
3265
return -ENOMEM;
3266
kctl->private_value = spec->beep_amp;
3267
err = snd_hda_ctl_add(codec, 0, kctl);
3268
if (err < 0)
3269
return err;
3270
}
3271
}
3272
#endif
3273
3274
/* if we have no master control, let's create it */
3275
if (!spec->no_analog &&
3276
!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3277
unsigned int vmaster_tlv[4];
3278
snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3279
HDA_OUTPUT, vmaster_tlv);
3280
err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3281
vmaster_tlv, alc_slave_vols);
3282
if (err < 0)
3283
return err;
3284
}
3285
if (!spec->no_analog &&
3286
!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3287
err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3288
NULL, alc_slave_sws);
3289
if (err < 0)
3290
return err;
3291
}
3292
3293
/* assign Capture Source enums to NID */
3294
if (spec->capsrc_nids || spec->adc_nids) {
3295
kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3296
if (!kctl)
3297
kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3298
for (i = 0; kctl && i < kctl->count; i++) {
3299
const hda_nid_t *nids = spec->capsrc_nids;
3300
if (!nids)
3301
nids = spec->adc_nids;
3302
err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3303
if (err < 0)
3304
return err;
3305
}
3306
}
3307
if (spec->cap_mixer) {
3308
const char *kname = kctl ? kctl->id.name : NULL;
3309
for (knew = spec->cap_mixer; knew->name; knew++) {
3310
if (kname && strcmp(knew->name, kname) == 0)
3311
continue;
3312
kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3313
for (i = 0; kctl && i < kctl->count; i++) {
3314
err = snd_hda_add_nid(codec, kctl, i,
3315
spec->adc_nids[i]);
3316
if (err < 0)
3317
return err;
3318
}
3319
}
3320
}
3321
3322
/* other nid->control mapping */
3323
for (i = 0; i < spec->num_mixers; i++) {
3324
for (knew = spec->mixers[i]; knew->name; knew++) {
3325
if (knew->iface != NID_MAPPING)
3326
continue;
3327
kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3328
if (kctl == NULL)
3329
continue;
3330
u = knew->subdevice;
3331
for (j = 0; j < 4; j++, u >>= 8) {
3332
nid = u & 0x3f;
3333
if (nid == 0)
3334
continue;
3335
switch (u & 0xc0) {
3336
case SUBDEV_SPEAKER_:
3337
nid = spec->autocfg.speaker_pins[nid];
3338
break;
3339
case SUBDEV_LINE_:
3340
nid = spec->autocfg.line_out_pins[nid];
3341
break;
3342
case SUBDEV_HP_:
3343
nid = spec->autocfg.hp_pins[nid];
3344
break;
3345
default:
3346
continue;
3347
}
3348
err = snd_hda_add_nid(codec, kctl, 0, nid);
3349
if (err < 0)
3350
return err;
3351
}
3352
u = knew->private_value;
3353
for (j = 0; j < 4; j++, u >>= 8) {
3354
nid = u & 0xff;
3355
if (nid == 0)
3356
continue;
3357
err = snd_hda_add_nid(codec, kctl, 0, nid);
3358
if (err < 0)
3359
return err;
3360
}
3361
}
3362
}
3363
3364
alc_free_kctls(codec); /* no longer needed */
3365
3366
return 0;
3367
}
3368
3369
3370
/*
3371
* initialize the codec volumes, etc
3372
*/
3373
3374
/*
3375
* generic initialization of ADC, input mixers and output mixers
3376
*/
3377
static const struct hda_verb alc880_volume_init_verbs[] = {
3378
/*
3379
* Unmute ADC0-2 and set the default input to mic-in
3380
*/
3381
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3382
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3383
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3384
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3385
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3386
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3387
3388
/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3389
* mixer widget
3390
* Note: PASD motherboards uses the Line In 2 as the input for front
3391
* panel mic (mic 2)
3392
*/
3393
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3394
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3395
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3396
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3397
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3398
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3399
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3400
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3401
3402
/*
3403
* Set up output mixers (0x0c - 0x0f)
3404
*/
3405
/* set vol=0 to output mixers */
3406
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3407
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3408
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3409
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3410
/* set up input amps for analog loopback */
3411
/* Amp Indices: DAC = 0, mixer = 1 */
3412
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3413
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3414
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3415
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3416
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3417
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3418
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3419
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3420
3421
{ }
3422
};
3423
3424
/*
3425
* 3-stack pin configuration:
3426
* front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3427
*/
3428
static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3429
/*
3430
* preset connection lists of input pins
3431
* 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3432
*/
3433
{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3434
{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3435
{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3436
3437
/*
3438
* Set pin mode and muting
3439
*/
3440
/* set front pin widgets 0x14 for output */
3441
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3442
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3443
/* Mic1 (rear panel) pin widget for input and vref at 80% */
3444
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3445
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3446
/* Mic2 (as headphone out) for HP output */
3447
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3448
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3449
/* Line In pin widget for input */
3450
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3451
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3452
/* Line2 (as front mic) pin widget for input and vref at 80% */
3453
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3454
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3455
/* CD pin widget for input */
3456
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3457
3458
{ }
3459
};
3460
3461
/*
3462
* 5-stack pin configuration:
3463
* front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3464
* line-in/side = 0x1a, f-mic = 0x1b
3465
*/
3466
static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3467
/*
3468
* preset connection lists of input pins
3469
* 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3470
*/
3471
{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3472
{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3473
3474
/*
3475
* Set pin mode and muting
3476
*/
3477
/* set pin widgets 0x14-0x17 for output */
3478
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3479
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3480
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3481
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3482
/* unmute pins for output (no gain on this amp) */
3483
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3484
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3485
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3486
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3487
3488
/* Mic1 (rear panel) pin widget for input and vref at 80% */
3489
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3490
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3491
/* Mic2 (as headphone out) for HP output */
3492
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3493
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3494
/* Line In pin widget for input */
3495
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3496
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3497
/* Line2 (as front mic) pin widget for input and vref at 80% */
3498
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3499
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3500
/* CD pin widget for input */
3501
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3502
3503
{ }
3504
};
3505
3506
/*
3507
* W810 pin configuration:
3508
* front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3509
*/
3510
static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3511
/* hphone/speaker input selector: front DAC */
3512
{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3513
3514
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3515
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3516
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3517
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3518
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3519
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3520
3521
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3522
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3523
3524
{ }
3525
};
3526
3527
/*
3528
* Z71V pin configuration:
3529
* Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3530
*/
3531
static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3532
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3533
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3534
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3535
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3536
3537
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3538
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3539
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3540
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3541
3542
{ }
3543
};
3544
3545
/*
3546
* 6-stack pin configuration:
3547
* front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3548
* f-mic = 0x19, line = 0x1a, HP = 0x1b
3549
*/
3550
static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3551
{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3552
3553
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3554
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3555
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3556
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3557
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3558
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3559
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3560
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3561
3562
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3563
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3564
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3565
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3566
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3567
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3568
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3569
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3570
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3571
3572
{ }
3573
};
3574
3575
/*
3576
* Uniwill pin configuration:
3577
* HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3578
* line = 0x1a
3579
*/
3580
static const struct hda_verb alc880_uniwill_init_verbs[] = {
3581
{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3582
3583
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3584
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3585
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3586
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3587
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3588
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3589
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3590
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3591
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3592
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3593
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3594
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3595
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3596
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3597
3598
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3599
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3600
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3601
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3602
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3603
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3604
/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3605
/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3606
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3607
3608
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3609
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3610
3611
{ }
3612
};
3613
3614
/*
3615
* Uniwill P53
3616
* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3617
*/
3618
static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3619
{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3620
3621
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3622
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3623
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3624
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3625
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3626
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3627
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3628
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3629
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3630
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3631
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3632
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3633
3634
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3635
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3636
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3637
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3638
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3639
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3640
3641
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3642
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3643
3644
{ }
3645
};
3646
3647
static const struct hda_verb alc880_beep_init_verbs[] = {
3648
{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3649
{ }
3650
};
3651
3652
/* auto-toggle front mic */
3653
static void alc88x_simple_mic_automute(struct hda_codec *codec)
3654
{
3655
unsigned int present;
3656
unsigned char bits;
3657
3658
present = snd_hda_jack_detect(codec, 0x18);
3659
bits = present ? HDA_AMP_MUTE : 0;
3660
snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3661
}
3662
3663
static void alc880_uniwill_setup(struct hda_codec *codec)
3664
{
3665
struct alc_spec *spec = codec->spec;
3666
3667
spec->autocfg.hp_pins[0] = 0x14;
3668
spec->autocfg.speaker_pins[0] = 0x15;
3669
spec->autocfg.speaker_pins[0] = 0x16;
3670
spec->automute = 1;
3671
spec->automute_mode = ALC_AUTOMUTE_AMP;
3672
}
3673
3674
static void alc880_uniwill_init_hook(struct hda_codec *codec)
3675
{
3676
alc_hp_automute(codec);
3677
alc88x_simple_mic_automute(codec);
3678
}
3679
3680
static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3681
unsigned int res)
3682
{
3683
/* Looks like the unsol event is incompatible with the standard
3684
* definition. 4bit tag is placed at 28 bit!
3685
*/
3686
switch (res >> 28) {
3687
case ALC880_MIC_EVENT:
3688
alc88x_simple_mic_automute(codec);
3689
break;
3690
default:
3691
alc_sku_unsol_event(codec, res);
3692
break;
3693
}
3694
}
3695
3696
static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3697
{
3698
struct alc_spec *spec = codec->spec;
3699
3700
spec->autocfg.hp_pins[0] = 0x14;
3701
spec->autocfg.speaker_pins[0] = 0x15;
3702
spec->automute = 1;
3703
spec->automute_mode = ALC_AUTOMUTE_AMP;
3704
}
3705
3706
static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3707
{
3708
unsigned int present;
3709
3710
present = snd_hda_codec_read(codec, 0x21, 0,
3711
AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3712
present &= HDA_AMP_VOLMASK;
3713
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3714
HDA_AMP_VOLMASK, present);
3715
snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3716
HDA_AMP_VOLMASK, present);
3717
}
3718
3719
static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3720
unsigned int res)
3721
{
3722
/* Looks like the unsol event is incompatible with the standard
3723
* definition. 4bit tag is placed at 28 bit!
3724
*/
3725
if ((res >> 28) == ALC880_DCVOL_EVENT)
3726
alc880_uniwill_p53_dcvol_automute(codec);
3727
else
3728
alc_sku_unsol_event(codec, res);
3729
}
3730
3731
/*
3732
* F1734 pin configuration:
3733
* HP = 0x14, speaker-out = 0x15, mic = 0x18
3734
*/
3735
static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3736
{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3737
{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3738
{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3739
{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3740
{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3741
3742
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3743
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3744
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3745
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3746
3747
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3748
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3749
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3750
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3751
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3752
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3753
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3754
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3755
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3756
3757
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3758
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3759
3760
{ }
3761
};
3762
3763
/*
3764
* ASUS pin configuration:
3765
* HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3766
*/
3767
static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3768
{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3769
{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3770
{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3771
{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3772
3773
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3774
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3775
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3776
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3777
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3778
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3779
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3780
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3781
3782
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3783
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3784
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3785
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3786
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3787
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3788
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3789
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3790
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3791
3792
{ }
3793
};
3794
3795
/* Enable GPIO mask and set output */
3796
#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3797
#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3798
#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3799
3800
/* Clevo m520g init */
3801
static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3802
/* headphone output */
3803
{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3804
/* line-out */
3805
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3806
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3807
/* Line-in */
3808
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3809
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3810
/* CD */
3811
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3812
{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3813
/* Mic1 (rear panel) */
3814
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3815
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3816
/* Mic2 (front panel) */
3817
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3818
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3819
/* headphone */
3820
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3821
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3822
/* change to EAPD mode */
3823
{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3824
{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3825
3826
{ }
3827
};
3828
3829
static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3830
/* change to EAPD mode */
3831
{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3832
{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3833
3834
/* Headphone output */
3835
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3836
/* Front output*/
3837
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3838
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3839
3840
/* Line In pin widget for input */
3841
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3842
/* CD pin widget for input */
3843
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3844
/* Mic1 (rear panel) pin widget for input and vref at 80% */
3845
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3846
3847
/* change to EAPD mode */
3848
{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3849
{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3850
3851
{ }
3852
};
3853
3854
/*
3855
* LG m1 express dual
3856
*
3857
* Pin assignment:
3858
* Rear Line-In/Out (blue): 0x14
3859
* Build-in Mic-In: 0x15
3860
* Speaker-out: 0x17
3861
* HP-Out (green): 0x1b
3862
* Mic-In/Out (red): 0x19
3863
* SPDIF-Out: 0x1e
3864
*/
3865
3866
/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3867
static const hda_nid_t alc880_lg_dac_nids[3] = {
3868
0x05, 0x02, 0x03
3869
};
3870
3871
/* seems analog CD is not working */
3872
static const struct hda_input_mux alc880_lg_capture_source = {
3873
.num_items = 3,
3874
.items = {
3875
{ "Mic", 0x1 },
3876
{ "Line", 0x5 },
3877
{ "Internal Mic", 0x6 },
3878
},
3879
};
3880
3881
/* 2,4,6 channel modes */
3882
static const struct hda_verb alc880_lg_ch2_init[] = {
3883
/* set line-in and mic-in to input */
3884
{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3885
{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3886
{ }
3887
};
3888
3889
static const struct hda_verb alc880_lg_ch4_init[] = {
3890
/* set line-in to out and mic-in to input */
3891
{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3892
{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3893
{ }
3894
};
3895
3896
static const struct hda_verb alc880_lg_ch6_init[] = {
3897
/* set line-in and mic-in to output */
3898
{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3899
{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3900
{ }
3901
};
3902
3903
static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3904
{ 2, alc880_lg_ch2_init },
3905
{ 4, alc880_lg_ch4_init },
3906
{ 6, alc880_lg_ch6_init },
3907
};
3908
3909
static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3910
HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3911
HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3912
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3913
HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3914
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3915
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3916
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3917
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3918
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3919
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3920
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3921
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3922
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3923
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3924
{
3925
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3926
.name = "Channel Mode",
3927
.info = alc_ch_mode_info,
3928
.get = alc_ch_mode_get,
3929
.put = alc_ch_mode_put,
3930
},
3931
{ } /* end */
3932
};
3933
3934
static const struct hda_verb alc880_lg_init_verbs[] = {
3935
/* set capture source to mic-in */
3936
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3937
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3938
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3939
/* mute all amp mixer inputs */
3940
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3941
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3942
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3943
/* line-in to input */
3944
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3945
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3946
/* built-in mic */
3947
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3948
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3949
/* speaker-out */
3950
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3951
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3952
/* mic-in to input */
3953
{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3954
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3955
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3956
/* HP-out */
3957
{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3958
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3959
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3960
/* jack sense */
3961
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3962
{ }
3963
};
3964
3965
/* toggle speaker-output according to the hp-jack state */
3966
static void alc880_lg_setup(struct hda_codec *codec)
3967
{
3968
struct alc_spec *spec = codec->spec;
3969
3970
spec->autocfg.hp_pins[0] = 0x1b;
3971
spec->autocfg.speaker_pins[0] = 0x17;
3972
spec->automute = 1;
3973
spec->automute_mode = ALC_AUTOMUTE_AMP;
3974
}
3975
3976
/*
3977
* LG LW20
3978
*
3979
* Pin assignment:
3980
* Speaker-out: 0x14
3981
* Mic-In: 0x18
3982
* Built-in Mic-In: 0x19
3983
* Line-In: 0x1b
3984
* HP-Out: 0x1a
3985
* SPDIF-Out: 0x1e
3986
*/
3987
3988
static const struct hda_input_mux alc880_lg_lw_capture_source = {
3989
.num_items = 3,
3990
.items = {
3991
{ "Mic", 0x0 },
3992
{ "Internal Mic", 0x1 },
3993
{ "Line In", 0x2 },
3994
},
3995
};
3996
3997
#define alc880_lg_lw_modes alc880_threestack_modes
3998
3999
static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
4000
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4001
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4002
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4003
HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
4004
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4005
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4006
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4007
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4008
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4009
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4010
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4011
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4012
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4013
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4014
{
4015
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4016
.name = "Channel Mode",
4017
.info = alc_ch_mode_info,
4018
.get = alc_ch_mode_get,
4019
.put = alc_ch_mode_put,
4020
},
4021
{ } /* end */
4022
};
4023
4024
static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4025
{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4026
{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4027
{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4028
4029
/* set capture source to mic-in */
4030
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4031
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4032
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4033
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4034
/* speaker-out */
4035
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4036
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4037
/* HP-out */
4038
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4039
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4040
/* mic-in to input */
4041
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4042
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4043
/* built-in mic */
4044
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4045
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4046
/* jack sense */
4047
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4048
{ }
4049
};
4050
4051
/* toggle speaker-output according to the hp-jack state */
4052
static void alc880_lg_lw_setup(struct hda_codec *codec)
4053
{
4054
struct alc_spec *spec = codec->spec;
4055
4056
spec->autocfg.hp_pins[0] = 0x1b;
4057
spec->autocfg.speaker_pins[0] = 0x14;
4058
spec->automute = 1;
4059
spec->automute_mode = ALC_AUTOMUTE_AMP;
4060
}
4061
4062
static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4063
HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4064
HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4065
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4066
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4067
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4068
HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4069
{ } /* end */
4070
};
4071
4072
static const struct hda_input_mux alc880_medion_rim_capture_source = {
4073
.num_items = 2,
4074
.items = {
4075
{ "Mic", 0x0 },
4076
{ "Internal Mic", 0x1 },
4077
},
4078
};
4079
4080
static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4081
{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4082
4083
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4084
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4085
4086
/* Mic1 (rear panel) pin widget for input and vref at 80% */
4087
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4088
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4089
/* Mic2 (as headphone out) for HP output */
4090
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4091
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4092
/* Internal Speaker */
4093
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4094
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4095
4096
{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4097
{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4098
4099
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4100
{ }
4101
};
4102
4103
/* toggle speaker-output according to the hp-jack state */
4104
static void alc880_medion_rim_automute(struct hda_codec *codec)
4105
{
4106
struct alc_spec *spec = codec->spec;
4107
alc_hp_automute(codec);
4108
/* toggle EAPD */
4109
if (spec->jack_present)
4110
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4111
else
4112
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4113
}
4114
4115
static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4116
unsigned int res)
4117
{
4118
/* Looks like the unsol event is incompatible with the standard
4119
* definition. 4bit tag is placed at 28 bit!
4120
*/
4121
if ((res >> 28) == ALC880_HP_EVENT)
4122
alc880_medion_rim_automute(codec);
4123
}
4124
4125
static void alc880_medion_rim_setup(struct hda_codec *codec)
4126
{
4127
struct alc_spec *spec = codec->spec;
4128
4129
spec->autocfg.hp_pins[0] = 0x14;
4130
spec->autocfg.speaker_pins[0] = 0x1b;
4131
spec->automute = 1;
4132
spec->automute_mode = ALC_AUTOMUTE_AMP;
4133
}
4134
4135
#ifdef CONFIG_SND_HDA_POWER_SAVE
4136
static const struct hda_amp_list alc880_loopbacks[] = {
4137
{ 0x0b, HDA_INPUT, 0 },
4138
{ 0x0b, HDA_INPUT, 1 },
4139
{ 0x0b, HDA_INPUT, 2 },
4140
{ 0x0b, HDA_INPUT, 3 },
4141
{ 0x0b, HDA_INPUT, 4 },
4142
{ } /* end */
4143
};
4144
4145
static const struct hda_amp_list alc880_lg_loopbacks[] = {
4146
{ 0x0b, HDA_INPUT, 1 },
4147
{ 0x0b, HDA_INPUT, 6 },
4148
{ 0x0b, HDA_INPUT, 7 },
4149
{ } /* end */
4150
};
4151
#endif
4152
4153
/*
4154
* Common callbacks
4155
*/
4156
4157
static void alc_init_special_input_src(struct hda_codec *codec);
4158
4159
static int alc_init(struct hda_codec *codec)
4160
{
4161
struct alc_spec *spec = codec->spec;
4162
unsigned int i;
4163
4164
alc_fix_pll(codec);
4165
alc_auto_init_amp(codec, spec->init_amp);
4166
4167
for (i = 0; i < spec->num_init_verbs; i++)
4168
snd_hda_sequence_write(codec, spec->init_verbs[i]);
4169
alc_init_special_input_src(codec);
4170
4171
if (spec->init_hook)
4172
spec->init_hook(codec);
4173
4174
alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4175
4176
hda_call_check_power_status(codec, 0x01);
4177
return 0;
4178
}
4179
4180
static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4181
{
4182
struct alc_spec *spec = codec->spec;
4183
4184
if (spec->unsol_event)
4185
spec->unsol_event(codec, res);
4186
}
4187
4188
#ifdef CONFIG_SND_HDA_POWER_SAVE
4189
static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4190
{
4191
struct alc_spec *spec = codec->spec;
4192
return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4193
}
4194
#endif
4195
4196
/*
4197
* Analog playback callbacks
4198
*/
4199
static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4200
struct hda_codec *codec,
4201
struct snd_pcm_substream *substream)
4202
{
4203
struct alc_spec *spec = codec->spec;
4204
return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4205
hinfo);
4206
}
4207
4208
static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4209
struct hda_codec *codec,
4210
unsigned int stream_tag,
4211
unsigned int format,
4212
struct snd_pcm_substream *substream)
4213
{
4214
struct alc_spec *spec = codec->spec;
4215
return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4216
stream_tag, format, substream);
4217
}
4218
4219
static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4220
struct hda_codec *codec,
4221
struct snd_pcm_substream *substream)
4222
{
4223
struct alc_spec *spec = codec->spec;
4224
return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4225
}
4226
4227
/*
4228
* Digital out
4229
*/
4230
static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4231
struct hda_codec *codec,
4232
struct snd_pcm_substream *substream)
4233
{
4234
struct alc_spec *spec = codec->spec;
4235
return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4236
}
4237
4238
static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4239
struct hda_codec *codec,
4240
unsigned int stream_tag,
4241
unsigned int format,
4242
struct snd_pcm_substream *substream)
4243
{
4244
struct alc_spec *spec = codec->spec;
4245
return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4246
stream_tag, format, substream);
4247
}
4248
4249
static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4250
struct hda_codec *codec,
4251
struct snd_pcm_substream *substream)
4252
{
4253
struct alc_spec *spec = codec->spec;
4254
return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4255
}
4256
4257
static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4258
struct hda_codec *codec,
4259
struct snd_pcm_substream *substream)
4260
{
4261
struct alc_spec *spec = codec->spec;
4262
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4263
}
4264
4265
/*
4266
* Analog capture
4267
*/
4268
static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4269
struct hda_codec *codec,
4270
unsigned int stream_tag,
4271
unsigned int format,
4272
struct snd_pcm_substream *substream)
4273
{
4274
struct alc_spec *spec = codec->spec;
4275
4276
snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
4277
stream_tag, 0, format);
4278
return 0;
4279
}
4280
4281
static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4282
struct hda_codec *codec,
4283
struct snd_pcm_substream *substream)
4284
{
4285
struct alc_spec *spec = codec->spec;
4286
4287
snd_hda_codec_cleanup_stream(codec,
4288
spec->adc_nids[substream->number + 1]);
4289
return 0;
4290
}
4291
4292
/* analog capture with dynamic dual-adc changes */
4293
static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4294
struct hda_codec *codec,
4295
unsigned int stream_tag,
4296
unsigned int format,
4297
struct snd_pcm_substream *substream)
4298
{
4299
struct alc_spec *spec = codec->spec;
4300
spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4301
spec->cur_adc_stream_tag = stream_tag;
4302
spec->cur_adc_format = format;
4303
snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4304
return 0;
4305
}
4306
4307
static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4308
struct hda_codec *codec,
4309
struct snd_pcm_substream *substream)
4310
{
4311
struct alc_spec *spec = codec->spec;
4312
snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4313
spec->cur_adc = 0;
4314
return 0;
4315
}
4316
4317
static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
4318
.substreams = 1,
4319
.channels_min = 2,
4320
.channels_max = 2,
4321
.nid = 0, /* fill later */
4322
.ops = {
4323
.prepare = dualmic_capture_pcm_prepare,
4324
.cleanup = dualmic_capture_pcm_cleanup
4325
},
4326
};
4327
4328
/*
4329
*/
4330
static const struct hda_pcm_stream alc880_pcm_analog_playback = {
4331
.substreams = 1,
4332
.channels_min = 2,
4333
.channels_max = 8,
4334
/* NID is set in alc_build_pcms */
4335
.ops = {
4336
.open = alc880_playback_pcm_open,
4337
.prepare = alc880_playback_pcm_prepare,
4338
.cleanup = alc880_playback_pcm_cleanup
4339
},
4340
};
4341
4342
static const struct hda_pcm_stream alc880_pcm_analog_capture = {
4343
.substreams = 1,
4344
.channels_min = 2,
4345
.channels_max = 2,
4346
/* NID is set in alc_build_pcms */
4347
};
4348
4349
static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4350
.substreams = 1,
4351
.channels_min = 2,
4352
.channels_max = 2,
4353
/* NID is set in alc_build_pcms */
4354
};
4355
4356
static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4357
.substreams = 2, /* can be overridden */
4358
.channels_min = 2,
4359
.channels_max = 2,
4360
/* NID is set in alc_build_pcms */
4361
.ops = {
4362
.prepare = alc880_alt_capture_pcm_prepare,
4363
.cleanup = alc880_alt_capture_pcm_cleanup
4364
},
4365
};
4366
4367
static const struct hda_pcm_stream alc880_pcm_digital_playback = {
4368
.substreams = 1,
4369
.channels_min = 2,
4370
.channels_max = 2,
4371
/* NID is set in alc_build_pcms */
4372
.ops = {
4373
.open = alc880_dig_playback_pcm_open,
4374
.close = alc880_dig_playback_pcm_close,
4375
.prepare = alc880_dig_playback_pcm_prepare,
4376
.cleanup = alc880_dig_playback_pcm_cleanup
4377
},
4378
};
4379
4380
static const struct hda_pcm_stream alc880_pcm_digital_capture = {
4381
.substreams = 1,
4382
.channels_min = 2,
4383
.channels_max = 2,
4384
/* NID is set in alc_build_pcms */
4385
};
4386
4387
/* Used by alc_build_pcms to flag that a PCM has no playback stream */
4388
static const struct hda_pcm_stream alc_pcm_null_stream = {
4389
.substreams = 0,
4390
.channels_min = 0,
4391
.channels_max = 0,
4392
};
4393
4394
static int alc_build_pcms(struct hda_codec *codec)
4395
{
4396
struct alc_spec *spec = codec->spec;
4397
struct hda_pcm *info = spec->pcm_rec;
4398
int i;
4399
4400
codec->num_pcms = 1;
4401
codec->pcm_info = info;
4402
4403
if (spec->no_analog)
4404
goto skip_analog;
4405
4406
snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4407
"%s Analog", codec->chip_name);
4408
info->name = spec->stream_name_analog;
4409
4410
if (spec->stream_analog_playback) {
4411
if (snd_BUG_ON(!spec->multiout.dac_nids))
4412
return -EINVAL;
4413
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4414
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4415
}
4416
if (spec->stream_analog_capture) {
4417
if (snd_BUG_ON(!spec->adc_nids))
4418
return -EINVAL;
4419
info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4420
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4421
}
4422
4423
if (spec->channel_mode) {
4424
info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4425
for (i = 0; i < spec->num_channel_mode; i++) {
4426
if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4427
info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4428
}
4429
}
4430
}
4431
4432
skip_analog:
4433
/* SPDIF for stream index #1 */
4434
if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4435
snprintf(spec->stream_name_digital,
4436
sizeof(spec->stream_name_digital),
4437
"%s Digital", codec->chip_name);
4438
codec->num_pcms = 2;
4439
codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4440
info = spec->pcm_rec + 1;
4441
info->name = spec->stream_name_digital;
4442
if (spec->dig_out_type)
4443
info->pcm_type = spec->dig_out_type;
4444
else
4445
info->pcm_type = HDA_PCM_TYPE_SPDIF;
4446
if (spec->multiout.dig_out_nid &&
4447
spec->stream_digital_playback) {
4448
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4449
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4450
}
4451
if (spec->dig_in_nid &&
4452
spec->stream_digital_capture) {
4453
info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4454
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4455
}
4456
/* FIXME: do we need this for all Realtek codec models? */
4457
codec->spdif_status_reset = 1;
4458
}
4459
4460
if (spec->no_analog)
4461
return 0;
4462
4463
/* If the use of more than one ADC is requested for the current
4464
* model, configure a second analog capture-only PCM.
4465
*/
4466
/* Additional Analaog capture for index #2 */
4467
if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4468
(spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4469
codec->num_pcms = 3;
4470
info = spec->pcm_rec + 2;
4471
info->name = spec->stream_name_analog;
4472
if (spec->alt_dac_nid) {
4473
info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4474
*spec->stream_analog_alt_playback;
4475
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4476
spec->alt_dac_nid;
4477
} else {
4478
info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4479
alc_pcm_null_stream;
4480
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4481
}
4482
if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
4483
info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4484
*spec->stream_analog_alt_capture;
4485
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4486
spec->adc_nids[1];
4487
info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4488
spec->num_adc_nids - 1;
4489
} else {
4490
info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4491
alc_pcm_null_stream;
4492
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4493
}
4494
}
4495
4496
return 0;
4497
}
4498
4499
static inline void alc_shutup(struct hda_codec *codec)
4500
{
4501
struct alc_spec *spec = codec->spec;
4502
4503
if (spec && spec->shutup)
4504
spec->shutup(codec);
4505
snd_hda_shutup_pins(codec);
4506
}
4507
4508
static void alc_free_kctls(struct hda_codec *codec)
4509
{
4510
struct alc_spec *spec = codec->spec;
4511
4512
if (spec->kctls.list) {
4513
struct snd_kcontrol_new *kctl = spec->kctls.list;
4514
int i;
4515
for (i = 0; i < spec->kctls.used; i++)
4516
kfree(kctl[i].name);
4517
}
4518
snd_array_free(&spec->kctls);
4519
}
4520
4521
static void alc_free(struct hda_codec *codec)
4522
{
4523
struct alc_spec *spec = codec->spec;
4524
4525
if (!spec)
4526
return;
4527
4528
alc_shutup(codec);
4529
snd_hda_input_jack_free(codec);
4530
alc_free_kctls(codec);
4531
kfree(spec);
4532
snd_hda_detach_beep_device(codec);
4533
}
4534
4535
#ifdef CONFIG_SND_HDA_POWER_SAVE
4536
static void alc_power_eapd(struct hda_codec *codec)
4537
{
4538
alc_auto_setup_eapd(codec, false);
4539
}
4540
4541
static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4542
{
4543
struct alc_spec *spec = codec->spec;
4544
alc_shutup(codec);
4545
if (spec && spec->power_hook)
4546
spec->power_hook(codec);
4547
return 0;
4548
}
4549
#endif
4550
4551
#ifdef SND_HDA_NEEDS_RESUME
4552
static int alc_resume(struct hda_codec *codec)
4553
{
4554
msleep(150); /* to avoid pop noise */
4555
codec->patch_ops.init(codec);
4556
snd_hda_codec_resume_amp(codec);
4557
snd_hda_codec_resume_cache(codec);
4558
hda_call_check_power_status(codec, 0x01);
4559
return 0;
4560
}
4561
#endif
4562
4563
/*
4564
*/
4565
static const struct hda_codec_ops alc_patch_ops = {
4566
.build_controls = alc_build_controls,
4567
.build_pcms = alc_build_pcms,
4568
.init = alc_init,
4569
.free = alc_free,
4570
.unsol_event = alc_unsol_event,
4571
#ifdef SND_HDA_NEEDS_RESUME
4572
.resume = alc_resume,
4573
#endif
4574
#ifdef CONFIG_SND_HDA_POWER_SAVE
4575
.suspend = alc_suspend,
4576
.check_power_status = alc_check_power_status,
4577
#endif
4578
.reboot_notify = alc_shutup,
4579
};
4580
4581
/* replace the codec chip_name with the given string */
4582
static int alc_codec_rename(struct hda_codec *codec, const char *name)
4583
{
4584
kfree(codec->chip_name);
4585
codec->chip_name = kstrdup(name, GFP_KERNEL);
4586
if (!codec->chip_name) {
4587
alc_free(codec);
4588
return -ENOMEM;
4589
}
4590
return 0;
4591
}
4592
4593
/*
4594
* Test configuration for debugging
4595
*
4596
* Almost all inputs/outputs are enabled. I/O pins can be configured via
4597
* enum controls.
4598
*/
4599
#ifdef CONFIG_SND_DEBUG
4600
static const hda_nid_t alc880_test_dac_nids[4] = {
4601
0x02, 0x03, 0x04, 0x05
4602
};
4603
4604
static const struct hda_input_mux alc880_test_capture_source = {
4605
.num_items = 7,
4606
.items = {
4607
{ "In-1", 0x0 },
4608
{ "In-2", 0x1 },
4609
{ "In-3", 0x2 },
4610
{ "In-4", 0x3 },
4611
{ "CD", 0x4 },
4612
{ "Front", 0x5 },
4613
{ "Surround", 0x6 },
4614
},
4615
};
4616
4617
static const struct hda_channel_mode alc880_test_modes[4] = {
4618
{ 2, NULL },
4619
{ 4, NULL },
4620
{ 6, NULL },
4621
{ 8, NULL },
4622
};
4623
4624
static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4625
struct snd_ctl_elem_info *uinfo)
4626
{
4627
static const char * const texts[] = {
4628
"N/A", "Line Out", "HP Out",
4629
"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4630
};
4631
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4632
uinfo->count = 1;
4633
uinfo->value.enumerated.items = 8;
4634
if (uinfo->value.enumerated.item >= 8)
4635
uinfo->value.enumerated.item = 7;
4636
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4637
return 0;
4638
}
4639
4640
static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4641
struct snd_ctl_elem_value *ucontrol)
4642
{
4643
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4644
hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4645
unsigned int pin_ctl, item = 0;
4646
4647
pin_ctl = snd_hda_codec_read(codec, nid, 0,
4648
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4649
if (pin_ctl & AC_PINCTL_OUT_EN) {
4650
if (pin_ctl & AC_PINCTL_HP_EN)
4651
item = 2;
4652
else
4653
item = 1;
4654
} else if (pin_ctl & AC_PINCTL_IN_EN) {
4655
switch (pin_ctl & AC_PINCTL_VREFEN) {
4656
case AC_PINCTL_VREF_HIZ: item = 3; break;
4657
case AC_PINCTL_VREF_50: item = 4; break;
4658
case AC_PINCTL_VREF_GRD: item = 5; break;
4659
case AC_PINCTL_VREF_80: item = 6; break;
4660
case AC_PINCTL_VREF_100: item = 7; break;
4661
}
4662
}
4663
ucontrol->value.enumerated.item[0] = item;
4664
return 0;
4665
}
4666
4667
static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4668
struct snd_ctl_elem_value *ucontrol)
4669
{
4670
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4671
hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4672
static const unsigned int ctls[] = {
4673
0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4674
AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4675
AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4676
AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4677
AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4678
AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4679
};
4680
unsigned int old_ctl, new_ctl;
4681
4682
old_ctl = snd_hda_codec_read(codec, nid, 0,
4683
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4684
new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4685
if (old_ctl != new_ctl) {
4686
int val;
4687
snd_hda_codec_write_cache(codec, nid, 0,
4688
AC_VERB_SET_PIN_WIDGET_CONTROL,
4689
new_ctl);
4690
val = ucontrol->value.enumerated.item[0] >= 3 ?
4691
HDA_AMP_MUTE : 0;
4692
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4693
HDA_AMP_MUTE, val);
4694
return 1;
4695
}
4696
return 0;
4697
}
4698
4699
static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4700
struct snd_ctl_elem_info *uinfo)
4701
{
4702
static const char * const texts[] = {
4703
"Front", "Surround", "CLFE", "Side"
4704
};
4705
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4706
uinfo->count = 1;
4707
uinfo->value.enumerated.items = 4;
4708
if (uinfo->value.enumerated.item >= 4)
4709
uinfo->value.enumerated.item = 3;
4710
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4711
return 0;
4712
}
4713
4714
static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4715
struct snd_ctl_elem_value *ucontrol)
4716
{
4717
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4718
hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4719
unsigned int sel;
4720
4721
sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4722
ucontrol->value.enumerated.item[0] = sel & 3;
4723
return 0;
4724
}
4725
4726
static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4727
struct snd_ctl_elem_value *ucontrol)
4728
{
4729
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4730
hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4731
unsigned int sel;
4732
4733
sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4734
if (ucontrol->value.enumerated.item[0] != sel) {
4735
sel = ucontrol->value.enumerated.item[0] & 3;
4736
snd_hda_codec_write_cache(codec, nid, 0,
4737
AC_VERB_SET_CONNECT_SEL, sel);
4738
return 1;
4739
}
4740
return 0;
4741
}
4742
4743
#define PIN_CTL_TEST(xname,nid) { \
4744
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4745
.name = xname, \
4746
.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4747
.info = alc_test_pin_ctl_info, \
4748
.get = alc_test_pin_ctl_get, \
4749
.put = alc_test_pin_ctl_put, \
4750
.private_value = nid \
4751
}
4752
4753
#define PIN_SRC_TEST(xname,nid) { \
4754
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4755
.name = xname, \
4756
.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4757
.info = alc_test_pin_src_info, \
4758
.get = alc_test_pin_src_get, \
4759
.put = alc_test_pin_src_put, \
4760
.private_value = nid \
4761
}
4762
4763
static const struct snd_kcontrol_new alc880_test_mixer[] = {
4764
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4765
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4766
HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4767
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4768
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4769
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4770
HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4771
HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4772
PIN_CTL_TEST("Front Pin Mode", 0x14),
4773
PIN_CTL_TEST("Surround Pin Mode", 0x15),
4774
PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4775
PIN_CTL_TEST("Side Pin Mode", 0x17),
4776
PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4777
PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4778
PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4779
PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4780
PIN_SRC_TEST("In-1 Pin Source", 0x18),
4781
PIN_SRC_TEST("In-2 Pin Source", 0x19),
4782
PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4783
PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4784
HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4785
HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4786
HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4787
HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4788
HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4789
HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4790
HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4791
HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4792
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4793
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4794
{
4795
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4796
.name = "Channel Mode",
4797
.info = alc_ch_mode_info,
4798
.get = alc_ch_mode_get,
4799
.put = alc_ch_mode_put,
4800
},
4801
{ } /* end */
4802
};
4803
4804
static const struct hda_verb alc880_test_init_verbs[] = {
4805
/* Unmute inputs of 0x0c - 0x0f */
4806
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4807
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4808
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4809
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4810
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4811
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4812
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4813
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4814
/* Vol output for 0x0c-0x0f */
4815
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4816
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4817
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4818
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4819
/* Set output pins 0x14-0x17 */
4820
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4821
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4822
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4823
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4824
/* Unmute output pins 0x14-0x17 */
4825
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4826
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4827
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4828
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4829
/* Set input pins 0x18-0x1c */
4830
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4831
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4832
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4833
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4834
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4835
/* Mute input pins 0x18-0x1b */
4836
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4837
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4838
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4839
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4840
/* ADC set up */
4841
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4842
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4843
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4844
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4845
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4846
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4847
/* Analog input/passthru */
4848
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4849
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4850
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4851
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4852
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4853
{ }
4854
};
4855
#endif
4856
4857
/*
4858
*/
4859
4860
static const char * const alc880_models[ALC880_MODEL_LAST] = {
4861
[ALC880_3ST] = "3stack",
4862
[ALC880_TCL_S700] = "tcl",
4863
[ALC880_3ST_DIG] = "3stack-digout",
4864
[ALC880_CLEVO] = "clevo",
4865
[ALC880_5ST] = "5stack",
4866
[ALC880_5ST_DIG] = "5stack-digout",
4867
[ALC880_W810] = "w810",
4868
[ALC880_Z71V] = "z71v",
4869
[ALC880_6ST] = "6stack",
4870
[ALC880_6ST_DIG] = "6stack-digout",
4871
[ALC880_ASUS] = "asus",
4872
[ALC880_ASUS_W1V] = "asus-w1v",
4873
[ALC880_ASUS_DIG] = "asus-dig",
4874
[ALC880_ASUS_DIG2] = "asus-dig2",
4875
[ALC880_UNIWILL_DIG] = "uniwill",
4876
[ALC880_UNIWILL_P53] = "uniwill-p53",
4877
[ALC880_FUJITSU] = "fujitsu",
4878
[ALC880_F1734] = "F1734",
4879
[ALC880_LG] = "lg",
4880
[ALC880_LG_LW] = "lg-lw",
4881
[ALC880_MEDION_RIM] = "medion",
4882
#ifdef CONFIG_SND_DEBUG
4883
[ALC880_TEST] = "test",
4884
#endif
4885
[ALC880_AUTO] = "auto",
4886
};
4887
4888
static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4889
SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4890
SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4891
SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4892
SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4893
SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4894
SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4895
SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4896
SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4897
SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4898
SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4899
SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4900
SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4901
SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4902
SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4903
SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4904
SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4905
SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4906
/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4907
SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4908
SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4909
SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4910
SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4911
SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4912
SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4913
SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4914
SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4915
SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4916
SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4917
SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4918
SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4919
SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4920
SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4921
SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4922
SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4923
SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4924
SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4925
SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4926
SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4927
SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4928
SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4929
SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4930
SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4931
SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4932
SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4933
SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4934
SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4935
SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4936
SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4937
SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4938
SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4939
SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4940
SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4941
SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4942
SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4943
SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4944
SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4945
SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4946
SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4947
SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4948
SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4949
SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4950
SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4951
SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4952
SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4953
SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4954
SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4955
SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4956
SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4957
/* default Intel */
4958
SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4959
SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4960
SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4961
{}
4962
};
4963
4964
/*
4965
* ALC880 codec presets
4966
*/
4967
static const struct alc_config_preset alc880_presets[] = {
4968
[ALC880_3ST] = {
4969
.mixers = { alc880_three_stack_mixer },
4970
.init_verbs = { alc880_volume_init_verbs,
4971
alc880_pin_3stack_init_verbs },
4972
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
4973
.dac_nids = alc880_dac_nids,
4974
.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4975
.channel_mode = alc880_threestack_modes,
4976
.need_dac_fix = 1,
4977
.input_mux = &alc880_capture_source,
4978
},
4979
[ALC880_3ST_DIG] = {
4980
.mixers = { alc880_three_stack_mixer },
4981
.init_verbs = { alc880_volume_init_verbs,
4982
alc880_pin_3stack_init_verbs },
4983
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
4984
.dac_nids = alc880_dac_nids,
4985
.dig_out_nid = ALC880_DIGOUT_NID,
4986
.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4987
.channel_mode = alc880_threestack_modes,
4988
.need_dac_fix = 1,
4989
.input_mux = &alc880_capture_source,
4990
},
4991
[ALC880_TCL_S700] = {
4992
.mixers = { alc880_tcl_s700_mixer },
4993
.init_verbs = { alc880_volume_init_verbs,
4994
alc880_pin_tcl_S700_init_verbs,
4995
alc880_gpio2_init_verbs },
4996
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
4997
.dac_nids = alc880_dac_nids,
4998
.adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4999
.num_adc_nids = 1, /* single ADC */
5000
.hp_nid = 0x03,
5001
.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5002
.channel_mode = alc880_2_jack_modes,
5003
.input_mux = &alc880_capture_source,
5004
},
5005
[ALC880_5ST] = {
5006
.mixers = { alc880_three_stack_mixer,
5007
alc880_five_stack_mixer},
5008
.init_verbs = { alc880_volume_init_verbs,
5009
alc880_pin_5stack_init_verbs },
5010
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5011
.dac_nids = alc880_dac_nids,
5012
.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5013
.channel_mode = alc880_fivestack_modes,
5014
.input_mux = &alc880_capture_source,
5015
},
5016
[ALC880_5ST_DIG] = {
5017
.mixers = { alc880_three_stack_mixer,
5018
alc880_five_stack_mixer },
5019
.init_verbs = { alc880_volume_init_verbs,
5020
alc880_pin_5stack_init_verbs },
5021
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5022
.dac_nids = alc880_dac_nids,
5023
.dig_out_nid = ALC880_DIGOUT_NID,
5024
.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5025
.channel_mode = alc880_fivestack_modes,
5026
.input_mux = &alc880_capture_source,
5027
},
5028
[ALC880_6ST] = {
5029
.mixers = { alc880_six_stack_mixer },
5030
.init_verbs = { alc880_volume_init_verbs,
5031
alc880_pin_6stack_init_verbs },
5032
.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5033
.dac_nids = alc880_6st_dac_nids,
5034
.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5035
.channel_mode = alc880_sixstack_modes,
5036
.input_mux = &alc880_6stack_capture_source,
5037
},
5038
[ALC880_6ST_DIG] = {
5039
.mixers = { alc880_six_stack_mixer },
5040
.init_verbs = { alc880_volume_init_verbs,
5041
alc880_pin_6stack_init_verbs },
5042
.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5043
.dac_nids = alc880_6st_dac_nids,
5044
.dig_out_nid = ALC880_DIGOUT_NID,
5045
.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5046
.channel_mode = alc880_sixstack_modes,
5047
.input_mux = &alc880_6stack_capture_source,
5048
},
5049
[ALC880_W810] = {
5050
.mixers = { alc880_w810_base_mixer },
5051
.init_verbs = { alc880_volume_init_verbs,
5052
alc880_pin_w810_init_verbs,
5053
alc880_gpio2_init_verbs },
5054
.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5055
.dac_nids = alc880_w810_dac_nids,
5056
.dig_out_nid = ALC880_DIGOUT_NID,
5057
.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5058
.channel_mode = alc880_w810_modes,
5059
.input_mux = &alc880_capture_source,
5060
},
5061
[ALC880_Z71V] = {
5062
.mixers = { alc880_z71v_mixer },
5063
.init_verbs = { alc880_volume_init_verbs,
5064
alc880_pin_z71v_init_verbs },
5065
.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5066
.dac_nids = alc880_z71v_dac_nids,
5067
.dig_out_nid = ALC880_DIGOUT_NID,
5068
.hp_nid = 0x03,
5069
.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5070
.channel_mode = alc880_2_jack_modes,
5071
.input_mux = &alc880_capture_source,
5072
},
5073
[ALC880_F1734] = {
5074
.mixers = { alc880_f1734_mixer },
5075
.init_verbs = { alc880_volume_init_verbs,
5076
alc880_pin_f1734_init_verbs },
5077
.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5078
.dac_nids = alc880_f1734_dac_nids,
5079
.hp_nid = 0x02,
5080
.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5081
.channel_mode = alc880_2_jack_modes,
5082
.input_mux = &alc880_f1734_capture_source,
5083
.unsol_event = alc880_uniwill_p53_unsol_event,
5084
.setup = alc880_uniwill_p53_setup,
5085
.init_hook = alc_hp_automute,
5086
},
5087
[ALC880_ASUS] = {
5088
.mixers = { alc880_asus_mixer },
5089
.init_verbs = { alc880_volume_init_verbs,
5090
alc880_pin_asus_init_verbs,
5091
alc880_gpio1_init_verbs },
5092
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5093
.dac_nids = alc880_asus_dac_nids,
5094
.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5095
.channel_mode = alc880_asus_modes,
5096
.need_dac_fix = 1,
5097
.input_mux = &alc880_capture_source,
5098
},
5099
[ALC880_ASUS_DIG] = {
5100
.mixers = { alc880_asus_mixer },
5101
.init_verbs = { alc880_volume_init_verbs,
5102
alc880_pin_asus_init_verbs,
5103
alc880_gpio1_init_verbs },
5104
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5105
.dac_nids = alc880_asus_dac_nids,
5106
.dig_out_nid = ALC880_DIGOUT_NID,
5107
.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5108
.channel_mode = alc880_asus_modes,
5109
.need_dac_fix = 1,
5110
.input_mux = &alc880_capture_source,
5111
},
5112
[ALC880_ASUS_DIG2] = {
5113
.mixers = { alc880_asus_mixer },
5114
.init_verbs = { alc880_volume_init_verbs,
5115
alc880_pin_asus_init_verbs,
5116
alc880_gpio2_init_verbs }, /* use GPIO2 */
5117
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5118
.dac_nids = alc880_asus_dac_nids,
5119
.dig_out_nid = ALC880_DIGOUT_NID,
5120
.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5121
.channel_mode = alc880_asus_modes,
5122
.need_dac_fix = 1,
5123
.input_mux = &alc880_capture_source,
5124
},
5125
[ALC880_ASUS_W1V] = {
5126
.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5127
.init_verbs = { alc880_volume_init_verbs,
5128
alc880_pin_asus_init_verbs,
5129
alc880_gpio1_init_verbs },
5130
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5131
.dac_nids = alc880_asus_dac_nids,
5132
.dig_out_nid = ALC880_DIGOUT_NID,
5133
.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5134
.channel_mode = alc880_asus_modes,
5135
.need_dac_fix = 1,
5136
.input_mux = &alc880_capture_source,
5137
},
5138
[ALC880_UNIWILL_DIG] = {
5139
.mixers = { alc880_asus_mixer },
5140
.init_verbs = { alc880_volume_init_verbs,
5141
alc880_pin_asus_init_verbs },
5142
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5143
.dac_nids = alc880_asus_dac_nids,
5144
.dig_out_nid = ALC880_DIGOUT_NID,
5145
.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5146
.channel_mode = alc880_asus_modes,
5147
.need_dac_fix = 1,
5148
.input_mux = &alc880_capture_source,
5149
},
5150
[ALC880_UNIWILL] = {
5151
.mixers = { alc880_uniwill_mixer },
5152
.init_verbs = { alc880_volume_init_verbs,
5153
alc880_uniwill_init_verbs },
5154
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5155
.dac_nids = alc880_asus_dac_nids,
5156
.dig_out_nid = ALC880_DIGOUT_NID,
5157
.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5158
.channel_mode = alc880_threestack_modes,
5159
.need_dac_fix = 1,
5160
.input_mux = &alc880_capture_source,
5161
.unsol_event = alc880_uniwill_unsol_event,
5162
.setup = alc880_uniwill_setup,
5163
.init_hook = alc880_uniwill_init_hook,
5164
},
5165
[ALC880_UNIWILL_P53] = {
5166
.mixers = { alc880_uniwill_p53_mixer },
5167
.init_verbs = { alc880_volume_init_verbs,
5168
alc880_uniwill_p53_init_verbs },
5169
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5170
.dac_nids = alc880_asus_dac_nids,
5171
.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5172
.channel_mode = alc880_threestack_modes,
5173
.input_mux = &alc880_capture_source,
5174
.unsol_event = alc880_uniwill_p53_unsol_event,
5175
.setup = alc880_uniwill_p53_setup,
5176
.init_hook = alc_hp_automute,
5177
},
5178
[ALC880_FUJITSU] = {
5179
.mixers = { alc880_fujitsu_mixer },
5180
.init_verbs = { alc880_volume_init_verbs,
5181
alc880_uniwill_p53_init_verbs,
5182
alc880_beep_init_verbs },
5183
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5184
.dac_nids = alc880_dac_nids,
5185
.dig_out_nid = ALC880_DIGOUT_NID,
5186
.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5187
.channel_mode = alc880_2_jack_modes,
5188
.input_mux = &alc880_capture_source,
5189
.unsol_event = alc880_uniwill_p53_unsol_event,
5190
.setup = alc880_uniwill_p53_setup,
5191
.init_hook = alc_hp_automute,
5192
},
5193
[ALC880_CLEVO] = {
5194
.mixers = { alc880_three_stack_mixer },
5195
.init_verbs = { alc880_volume_init_verbs,
5196
alc880_pin_clevo_init_verbs },
5197
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5198
.dac_nids = alc880_dac_nids,
5199
.hp_nid = 0x03,
5200
.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5201
.channel_mode = alc880_threestack_modes,
5202
.need_dac_fix = 1,
5203
.input_mux = &alc880_capture_source,
5204
},
5205
[ALC880_LG] = {
5206
.mixers = { alc880_lg_mixer },
5207
.init_verbs = { alc880_volume_init_verbs,
5208
alc880_lg_init_verbs },
5209
.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5210
.dac_nids = alc880_lg_dac_nids,
5211
.dig_out_nid = ALC880_DIGOUT_NID,
5212
.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5213
.channel_mode = alc880_lg_ch_modes,
5214
.need_dac_fix = 1,
5215
.input_mux = &alc880_lg_capture_source,
5216
.unsol_event = alc_sku_unsol_event,
5217
.setup = alc880_lg_setup,
5218
.init_hook = alc_hp_automute,
5219
#ifdef CONFIG_SND_HDA_POWER_SAVE
5220
.loopbacks = alc880_lg_loopbacks,
5221
#endif
5222
},
5223
[ALC880_LG_LW] = {
5224
.mixers = { alc880_lg_lw_mixer },
5225
.init_verbs = { alc880_volume_init_verbs,
5226
alc880_lg_lw_init_verbs },
5227
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5228
.dac_nids = alc880_dac_nids,
5229
.dig_out_nid = ALC880_DIGOUT_NID,
5230
.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5231
.channel_mode = alc880_lg_lw_modes,
5232
.input_mux = &alc880_lg_lw_capture_source,
5233
.unsol_event = alc_sku_unsol_event,
5234
.setup = alc880_lg_lw_setup,
5235
.init_hook = alc_hp_automute,
5236
},
5237
[ALC880_MEDION_RIM] = {
5238
.mixers = { alc880_medion_rim_mixer },
5239
.init_verbs = { alc880_volume_init_verbs,
5240
alc880_medion_rim_init_verbs,
5241
alc_gpio2_init_verbs },
5242
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5243
.dac_nids = alc880_dac_nids,
5244
.dig_out_nid = ALC880_DIGOUT_NID,
5245
.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5246
.channel_mode = alc880_2_jack_modes,
5247
.input_mux = &alc880_medion_rim_capture_source,
5248
.unsol_event = alc880_medion_rim_unsol_event,
5249
.setup = alc880_medion_rim_setup,
5250
.init_hook = alc880_medion_rim_automute,
5251
},
5252
#ifdef CONFIG_SND_DEBUG
5253
[ALC880_TEST] = {
5254
.mixers = { alc880_test_mixer },
5255
.init_verbs = { alc880_test_init_verbs },
5256
.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5257
.dac_nids = alc880_test_dac_nids,
5258
.dig_out_nid = ALC880_DIGOUT_NID,
5259
.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5260
.channel_mode = alc880_test_modes,
5261
.input_mux = &alc880_test_capture_source,
5262
},
5263
#endif
5264
};
5265
5266
/*
5267
* Automatic parse of I/O pins from the BIOS configuration
5268
*/
5269
5270
enum {
5271
ALC_CTL_WIDGET_VOL,
5272
ALC_CTL_WIDGET_MUTE,
5273
ALC_CTL_BIND_MUTE,
5274
};
5275
static const struct snd_kcontrol_new alc880_control_templates[] = {
5276
HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5277
HDA_CODEC_MUTE(NULL, 0, 0, 0),
5278
HDA_BIND_MUTE(NULL, 0, 0, 0),
5279
};
5280
5281
static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5282
{
5283
snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5284
return snd_array_new(&spec->kctls);
5285
}
5286
5287
/* add dynamic controls */
5288
static int add_control(struct alc_spec *spec, int type, const char *name,
5289
int cidx, unsigned long val)
5290
{
5291
struct snd_kcontrol_new *knew;
5292
5293
knew = alc_kcontrol_new(spec);
5294
if (!knew)
5295
return -ENOMEM;
5296
*knew = alc880_control_templates[type];
5297
knew->name = kstrdup(name, GFP_KERNEL);
5298
if (!knew->name)
5299
return -ENOMEM;
5300
knew->index = cidx;
5301
if (get_amp_nid_(val))
5302
knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5303
knew->private_value = val;
5304
return 0;
5305
}
5306
5307
static int add_control_with_pfx(struct alc_spec *spec, int type,
5308
const char *pfx, const char *dir,
5309
const char *sfx, int cidx, unsigned long val)
5310
{
5311
char name[32];
5312
snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5313
return add_control(spec, type, name, cidx, val);
5314
}
5315
5316
#define add_pb_vol_ctrl(spec, type, pfx, val) \
5317
add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5318
#define add_pb_sw_ctrl(spec, type, pfx, val) \
5319
add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5320
#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5321
add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5322
#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5323
add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5324
5325
#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5326
#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5327
#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5328
#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5329
#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5330
#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5331
#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5332
#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5333
#define ALC880_PIN_CD_NID 0x1c
5334
5335
/* fill in the dac_nids table from the parsed pin configuration */
5336
static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5337
const struct auto_pin_cfg *cfg)
5338
{
5339
hda_nid_t nid;
5340
int assigned[4];
5341
int i, j;
5342
5343
memset(assigned, 0, sizeof(assigned));
5344
spec->multiout.dac_nids = spec->private_dac_nids;
5345
5346
/* check the pins hardwired to audio widget */
5347
for (i = 0; i < cfg->line_outs; i++) {
5348
nid = cfg->line_out_pins[i];
5349
if (alc880_is_fixed_pin(nid)) {
5350
int idx = alc880_fixed_pin_idx(nid);
5351
spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
5352
assigned[idx] = 1;
5353
}
5354
}
5355
/* left pins can be connect to any audio widget */
5356
for (i = 0; i < cfg->line_outs; i++) {
5357
nid = cfg->line_out_pins[i];
5358
if (alc880_is_fixed_pin(nid))
5359
continue;
5360
/* search for an empty channel */
5361
for (j = 0; j < cfg->line_outs; j++) {
5362
if (!assigned[j]) {
5363
spec->private_dac_nids[i] =
5364
alc880_idx_to_dac(j);
5365
assigned[j] = 1;
5366
break;
5367
}
5368
}
5369
}
5370
spec->multiout.num_dacs = cfg->line_outs;
5371
return 0;
5372
}
5373
5374
static const char *alc_get_line_out_pfx(struct alc_spec *spec,
5375
bool can_be_master)
5376
{
5377
struct auto_pin_cfg *cfg = &spec->autocfg;
5378
5379
if (cfg->line_outs == 1 && !spec->multi_ios &&
5380
!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5381
return "Master";
5382
5383
switch (cfg->line_out_type) {
5384
case AUTO_PIN_SPEAKER_OUT:
5385
if (cfg->line_outs == 1)
5386
return "Speaker";
5387
break;
5388
case AUTO_PIN_HP_OUT:
5389
return "Headphone";
5390
default:
5391
if (cfg->line_outs == 1 && !spec->multi_ios)
5392
return "PCM";
5393
break;
5394
}
5395
return NULL;
5396
}
5397
5398
/* add playback controls from the parsed DAC table */
5399
static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5400
const struct auto_pin_cfg *cfg)
5401
{
5402
static const char * const chname[4] = {
5403
"Front", "Surround", NULL /*CLFE*/, "Side"
5404
};
5405
const char *pfx = alc_get_line_out_pfx(spec, false);
5406
hda_nid_t nid;
5407
int i, err, noutputs;
5408
5409
noutputs = cfg->line_outs;
5410
if (spec->multi_ios > 0)
5411
noutputs += spec->multi_ios;
5412
5413
for (i = 0; i < noutputs; i++) {
5414
if (!spec->multiout.dac_nids[i])
5415
continue;
5416
nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5417
if (!pfx && i == 2) {
5418
/* Center/LFE */
5419
err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5420
"Center",
5421
HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5422
HDA_OUTPUT));
5423
if (err < 0)
5424
return err;
5425
err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5426
"LFE",
5427
HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5428
HDA_OUTPUT));
5429
if (err < 0)
5430
return err;
5431
err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5432
"Center",
5433
HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5434
HDA_INPUT));
5435
if (err < 0)
5436
return err;
5437
err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5438
"LFE",
5439
HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5440
HDA_INPUT));
5441
if (err < 0)
5442
return err;
5443
} else {
5444
const char *name = pfx;
5445
int index = i;
5446
if (!name) {
5447
name = chname[i];
5448
index = 0;
5449
}
5450
err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5451
name, index,
5452
HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5453
HDA_OUTPUT));
5454
if (err < 0)
5455
return err;
5456
err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5457
name, index,
5458
HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5459
HDA_INPUT));
5460
if (err < 0)
5461
return err;
5462
}
5463
}
5464
return 0;
5465
}
5466
5467
/* add playback controls for speaker and HP outputs */
5468
static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5469
const char *pfx)
5470
{
5471
hda_nid_t nid;
5472
int err;
5473
5474
if (!pin)
5475
return 0;
5476
5477
if (alc880_is_fixed_pin(pin)) {
5478
nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5479
/* specify the DAC as the extra output */
5480
if (!spec->multiout.hp_nid)
5481
spec->multiout.hp_nid = nid;
5482
else
5483
spec->multiout.extra_out_nid[0] = nid;
5484
/* control HP volume/switch on the output mixer amp */
5485
nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5486
err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5487
HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5488
if (err < 0)
5489
return err;
5490
err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5491
HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5492
if (err < 0)
5493
return err;
5494
} else if (alc880_is_multi_pin(pin)) {
5495
/* set manual connection */
5496
/* we have only a switch on HP-out PIN */
5497
err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5498
HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5499
if (err < 0)
5500
return err;
5501
}
5502
return 0;
5503
}
5504
5505
/* create input playback/capture controls for the given pin */
5506
static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5507
const char *ctlname, int ctlidx,
5508
int idx, hda_nid_t mix_nid)
5509
{
5510
int err;
5511
5512
err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5513
HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5514
if (err < 0)
5515
return err;
5516
err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5517
HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5518
if (err < 0)
5519
return err;
5520
return 0;
5521
}
5522
5523
static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5524
{
5525
unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5526
return (pincap & AC_PINCAP_IN) != 0;
5527
}
5528
5529
/* create playback/capture controls for input pins */
5530
static int alc_auto_create_input_ctls(struct hda_codec *codec,
5531
const struct auto_pin_cfg *cfg,
5532
hda_nid_t mixer,
5533
hda_nid_t cap1, hda_nid_t cap2)
5534
{
5535
struct alc_spec *spec = codec->spec;
5536
struct hda_input_mux *imux = &spec->private_imux[0];
5537
int i, err, idx, type_idx = 0;
5538
const char *prev_label = NULL;
5539
5540
for (i = 0; i < cfg->num_inputs; i++) {
5541
hda_nid_t pin;
5542
const char *label;
5543
5544
pin = cfg->inputs[i].pin;
5545
if (!alc_is_input_pin(codec, pin))
5546
continue;
5547
5548
label = hda_get_autocfg_input_label(codec, cfg, i);
5549
if (prev_label && !strcmp(label, prev_label))
5550
type_idx++;
5551
else
5552
type_idx = 0;
5553
prev_label = label;
5554
5555
if (mixer) {
5556
idx = get_connection_index(codec, mixer, pin);
5557
if (idx >= 0) {
5558
err = new_analog_input(spec, pin,
5559
label, type_idx,
5560
idx, mixer);
5561
if (err < 0)
5562
return err;
5563
}
5564
}
5565
5566
if (!cap1)
5567
continue;
5568
idx = get_connection_index(codec, cap1, pin);
5569
if (idx < 0 && cap2)
5570
idx = get_connection_index(codec, cap2, pin);
5571
if (idx >= 0)
5572
snd_hda_add_imux_item(imux, label, idx, NULL);
5573
}
5574
return 0;
5575
}
5576
5577
static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5578
const struct auto_pin_cfg *cfg)
5579
{
5580
return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5581
}
5582
5583
static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5584
unsigned int pin_type)
5585
{
5586
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5587
pin_type);
5588
/* unmute pin */
5589
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5590
AMP_OUT_UNMUTE);
5591
}
5592
5593
static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5594
hda_nid_t nid, int pin_type,
5595
int dac_idx)
5596
{
5597
alc_set_pin_output(codec, nid, pin_type);
5598
/* need the manual connection? */
5599
if (alc880_is_multi_pin(nid)) {
5600
struct alc_spec *spec = codec->spec;
5601
int idx = alc880_multi_pin_idx(nid);
5602
snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5603
AC_VERB_SET_CONNECT_SEL,
5604
alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5605
}
5606
}
5607
5608
static int get_pin_type(int line_out_type)
5609
{
5610
if (line_out_type == AUTO_PIN_HP_OUT)
5611
return PIN_HP;
5612
else
5613
return PIN_OUT;
5614
}
5615
5616
static void alc880_auto_init_multi_out(struct hda_codec *codec)
5617
{
5618
struct alc_spec *spec = codec->spec;
5619
int i;
5620
5621
for (i = 0; i < spec->autocfg.line_outs; i++) {
5622
hda_nid_t nid = spec->autocfg.line_out_pins[i];
5623
int pin_type = get_pin_type(spec->autocfg.line_out_type);
5624
alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5625
}
5626
}
5627
5628
static void alc880_auto_init_extra_out(struct hda_codec *codec)
5629
{
5630
struct alc_spec *spec = codec->spec;
5631
hda_nid_t pin;
5632
5633
pin = spec->autocfg.speaker_pins[0];
5634
if (pin) /* connect to front */
5635
alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5636
pin = spec->autocfg.hp_pins[0];
5637
if (pin) /* connect to front */
5638
alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5639
}
5640
5641
static void alc880_auto_init_analog_input(struct hda_codec *codec)
5642
{
5643
struct alc_spec *spec = codec->spec;
5644
struct auto_pin_cfg *cfg = &spec->autocfg;
5645
int i;
5646
5647
for (i = 0; i < cfg->num_inputs; i++) {
5648
hda_nid_t nid = cfg->inputs[i].pin;
5649
if (alc_is_input_pin(codec, nid)) {
5650
alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5651
if (nid != ALC880_PIN_CD_NID &&
5652
(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5653
snd_hda_codec_write(codec, nid, 0,
5654
AC_VERB_SET_AMP_GAIN_MUTE,
5655
AMP_OUT_MUTE);
5656
}
5657
}
5658
}
5659
5660
static void alc880_auto_init_input_src(struct hda_codec *codec)
5661
{
5662
struct alc_spec *spec = codec->spec;
5663
int c;
5664
5665
for (c = 0; c < spec->num_adc_nids; c++) {
5666
unsigned int mux_idx;
5667
const struct hda_input_mux *imux;
5668
mux_idx = c >= spec->num_mux_defs ? 0 : c;
5669
imux = &spec->input_mux[mux_idx];
5670
if (!imux->num_items && mux_idx > 0)
5671
imux = &spec->input_mux[0];
5672
if (imux)
5673
snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5674
AC_VERB_SET_CONNECT_SEL,
5675
imux->items[0].index);
5676
}
5677
}
5678
5679
static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5680
5681
/* parse the BIOS configuration and set up the alc_spec */
5682
/* return 1 if successful, 0 if the proper config is not found,
5683
* or a negative error code
5684
*/
5685
static int alc880_parse_auto_config(struct hda_codec *codec)
5686
{
5687
struct alc_spec *spec = codec->spec;
5688
int err;
5689
static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5690
5691
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5692
alc880_ignore);
5693
if (err < 0)
5694
return err;
5695
if (!spec->autocfg.line_outs)
5696
return 0; /* can't find valid BIOS pin config */
5697
5698
err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5699
if (err < 0)
5700
return err;
5701
err = alc_auto_add_multi_channel_mode(codec);
5702
if (err < 0)
5703
return err;
5704
err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5705
if (err < 0)
5706
return err;
5707
err = alc880_auto_create_extra_out(spec,
5708
spec->autocfg.speaker_pins[0],
5709
"Speaker");
5710
if (err < 0)
5711
return err;
5712
err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5713
"Headphone");
5714
if (err < 0)
5715
return err;
5716
err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5717
if (err < 0)
5718
return err;
5719
5720
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5721
5722
alc_auto_parse_digital(codec);
5723
5724
if (spec->kctls.list)
5725
add_mixer(spec, spec->kctls.list);
5726
5727
add_verb(spec, alc880_volume_init_verbs);
5728
5729
spec->num_mux_defs = 1;
5730
spec->input_mux = &spec->private_imux[0];
5731
5732
alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5733
5734
return 1;
5735
}
5736
5737
/* additional initialization for auto-configuration model */
5738
static void alc880_auto_init(struct hda_codec *codec)
5739
{
5740
struct alc_spec *spec = codec->spec;
5741
alc880_auto_init_multi_out(codec);
5742
alc880_auto_init_extra_out(codec);
5743
alc880_auto_init_analog_input(codec);
5744
alc880_auto_init_input_src(codec);
5745
alc_auto_init_digital(codec);
5746
if (spec->unsol_event)
5747
alc_inithook(codec);
5748
}
5749
5750
/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5751
* one of two digital mic pins, e.g. on ALC272
5752
*/
5753
static void fixup_automic_adc(struct hda_codec *codec)
5754
{
5755
struct alc_spec *spec = codec->spec;
5756
int i;
5757
5758
for (i = 0; i < spec->num_adc_nids; i++) {
5759
hda_nid_t cap = spec->capsrc_nids ?
5760
spec->capsrc_nids[i] : spec->adc_nids[i];
5761
int iidx, eidx;
5762
5763
iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5764
if (iidx < 0)
5765
continue;
5766
eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5767
if (eidx < 0)
5768
continue;
5769
spec->int_mic.mux_idx = iidx;
5770
spec->ext_mic.mux_idx = eidx;
5771
if (spec->capsrc_nids)
5772
spec->capsrc_nids += i;
5773
spec->adc_nids += i;
5774
spec->num_adc_nids = 1;
5775
/* optional dock-mic */
5776
eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5777
if (eidx < 0)
5778
spec->dock_mic.pin = 0;
5779
else
5780
spec->dock_mic.mux_idx = eidx;
5781
return;
5782
}
5783
snd_printd(KERN_INFO "hda_codec: %s: "
5784
"No ADC/MUX containing both 0x%x and 0x%x pins\n",
5785
codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5786
spec->auto_mic = 0; /* disable auto-mic to be sure */
5787
}
5788
5789
/* select or unmute the given capsrc route */
5790
static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5791
int idx)
5792
{
5793
if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5794
snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5795
HDA_AMP_MUTE, 0);
5796
} else {
5797
snd_hda_codec_write_cache(codec, cap, 0,
5798
AC_VERB_SET_CONNECT_SEL, idx);
5799
}
5800
}
5801
5802
/* set the default connection to that pin */
5803
static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5804
{
5805
struct alc_spec *spec = codec->spec;
5806
int i;
5807
5808
if (!pin)
5809
return 0;
5810
for (i = 0; i < spec->num_adc_nids; i++) {
5811
hda_nid_t cap = spec->capsrc_nids ?
5812
spec->capsrc_nids[i] : spec->adc_nids[i];
5813
int idx;
5814
5815
idx = get_connection_index(codec, cap, pin);
5816
if (idx < 0)
5817
continue;
5818
select_or_unmute_capsrc(codec, cap, idx);
5819
return i; /* return the found index */
5820
}
5821
return -1; /* not found */
5822
}
5823
5824
/* choose the ADC/MUX containing the input pin and initialize the setup */
5825
static void fixup_single_adc(struct hda_codec *codec)
5826
{
5827
struct alc_spec *spec = codec->spec;
5828
struct auto_pin_cfg *cfg = &spec->autocfg;
5829
int i;
5830
5831
/* search for the input pin; there must be only one */
5832
if (cfg->num_inputs != 1)
5833
return;
5834
i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5835
if (i >= 0) {
5836
/* use only this ADC */
5837
if (spec->capsrc_nids)
5838
spec->capsrc_nids += i;
5839
spec->adc_nids += i;
5840
spec->num_adc_nids = 1;
5841
spec->single_input_src = 1;
5842
}
5843
}
5844
5845
/* initialize dual adcs */
5846
static void fixup_dual_adc_switch(struct hda_codec *codec)
5847
{
5848
struct alc_spec *spec = codec->spec;
5849
init_capsrc_for_pin(codec, spec->ext_mic.pin);
5850
init_capsrc_for_pin(codec, spec->dock_mic.pin);
5851
init_capsrc_for_pin(codec, spec->int_mic.pin);
5852
}
5853
5854
/* initialize some special cases for input sources */
5855
static void alc_init_special_input_src(struct hda_codec *codec)
5856
{
5857
struct alc_spec *spec = codec->spec;
5858
if (spec->dual_adc_switch)
5859
fixup_dual_adc_switch(codec);
5860
else if (spec->single_input_src)
5861
init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5862
}
5863
5864
static void set_capture_mixer(struct hda_codec *codec)
5865
{
5866
struct alc_spec *spec = codec->spec;
5867
static const struct snd_kcontrol_new *caps[2][3] = {
5868
{ alc_capture_mixer_nosrc1,
5869
alc_capture_mixer_nosrc2,
5870
alc_capture_mixer_nosrc3 },
5871
{ alc_capture_mixer1,
5872
alc_capture_mixer2,
5873
alc_capture_mixer3 },
5874
};
5875
if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5876
int mux = 0;
5877
int num_adcs = spec->num_adc_nids;
5878
if (spec->dual_adc_switch)
5879
num_adcs = 1;
5880
else if (spec->auto_mic)
5881
fixup_automic_adc(codec);
5882
else if (spec->input_mux) {
5883
if (spec->input_mux->num_items > 1)
5884
mux = 1;
5885
else if (spec->input_mux->num_items == 1)
5886
fixup_single_adc(codec);
5887
}
5888
spec->cap_mixer = caps[mux][num_adcs - 1];
5889
}
5890
}
5891
5892
/* fill adc_nids (and capsrc_nids) containing all active input pins */
5893
static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
5894
int num_nids)
5895
{
5896
struct alc_spec *spec = codec->spec;
5897
struct auto_pin_cfg *cfg = &spec->autocfg;
5898
int n;
5899
hda_nid_t fallback_adc = 0, fallback_cap = 0;
5900
5901
for (n = 0; n < num_nids; n++) {
5902
hda_nid_t adc, cap;
5903
hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5904
int nconns, i, j;
5905
5906
adc = nids[n];
5907
if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5908
continue;
5909
cap = adc;
5910
nconns = snd_hda_get_connections(codec, cap, conn,
5911
ARRAY_SIZE(conn));
5912
if (nconns == 1) {
5913
cap = conn[0];
5914
nconns = snd_hda_get_connections(codec, cap, conn,
5915
ARRAY_SIZE(conn));
5916
}
5917
if (nconns <= 0)
5918
continue;
5919
if (!fallback_adc) {
5920
fallback_adc = adc;
5921
fallback_cap = cap;
5922
}
5923
for (i = 0; i < cfg->num_inputs; i++) {
5924
hda_nid_t nid = cfg->inputs[i].pin;
5925
for (j = 0; j < nconns; j++) {
5926
if (conn[j] == nid)
5927
break;
5928
}
5929
if (j >= nconns)
5930
break;
5931
}
5932
if (i >= cfg->num_inputs) {
5933
int num_adcs = spec->num_adc_nids;
5934
spec->private_adc_nids[num_adcs] = adc;
5935
spec->private_capsrc_nids[num_adcs] = cap;
5936
spec->num_adc_nids++;
5937
spec->adc_nids = spec->private_adc_nids;
5938
if (adc != cap)
5939
spec->capsrc_nids = spec->private_capsrc_nids;
5940
}
5941
}
5942
if (!spec->num_adc_nids) {
5943
printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5944
" using fallback 0x%x\n",
5945
codec->chip_name, fallback_adc);
5946
spec->private_adc_nids[0] = fallback_adc;
5947
spec->adc_nids = spec->private_adc_nids;
5948
if (fallback_adc != fallback_cap) {
5949
spec->private_capsrc_nids[0] = fallback_cap;
5950
spec->capsrc_nids = spec->private_adc_nids;
5951
}
5952
}
5953
}
5954
5955
#ifdef CONFIG_SND_HDA_INPUT_BEEP
5956
#define set_beep_amp(spec, nid, idx, dir) \
5957
((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5958
5959
static const struct snd_pci_quirk beep_white_list[] = {
5960
SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5961
SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5962
SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
5963
SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
5964
SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5965
{}
5966
};
5967
5968
static inline int has_cdefine_beep(struct hda_codec *codec)
5969
{
5970
struct alc_spec *spec = codec->spec;
5971
const struct snd_pci_quirk *q;
5972
q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5973
if (q)
5974
return q->value;
5975
return spec->cdefine.enable_pcbeep;
5976
}
5977
#else
5978
#define set_beep_amp(spec, nid, idx, dir) /* NOP */
5979
#define has_cdefine_beep(codec) 0
5980
#endif
5981
5982
/*
5983
* OK, here we have finally the patch for ALC880
5984
*/
5985
5986
static int patch_alc880(struct hda_codec *codec)
5987
{
5988
struct alc_spec *spec;
5989
int board_config;
5990
int err;
5991
5992
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5993
if (spec == NULL)
5994
return -ENOMEM;
5995
5996
codec->spec = spec;
5997
5998
board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5999
alc880_models,
6000
alc880_cfg_tbl);
6001
if (board_config < 0) {
6002
printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6003
codec->chip_name);
6004
board_config = ALC880_AUTO;
6005
}
6006
6007
if (board_config == ALC880_AUTO) {
6008
/* automatic parse from the BIOS config */
6009
err = alc880_parse_auto_config(codec);
6010
if (err < 0) {
6011
alc_free(codec);
6012
return err;
6013
} else if (!err) {
6014
printk(KERN_INFO
6015
"hda_codec: Cannot set up configuration "
6016
"from BIOS. Using 3-stack mode...\n");
6017
board_config = ALC880_3ST;
6018
}
6019
}
6020
6021
err = snd_hda_attach_beep_device(codec, 0x1);
6022
if (err < 0) {
6023
alc_free(codec);
6024
return err;
6025
}
6026
6027
if (board_config != ALC880_AUTO)
6028
setup_preset(codec, &alc880_presets[board_config]);
6029
6030
spec->stream_analog_playback = &alc880_pcm_analog_playback;
6031
spec->stream_analog_capture = &alc880_pcm_analog_capture;
6032
spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6033
6034
spec->stream_digital_playback = &alc880_pcm_digital_playback;
6035
spec->stream_digital_capture = &alc880_pcm_digital_capture;
6036
6037
if (!spec->adc_nids && spec->input_mux) {
6038
/* check whether NID 0x07 is valid */
6039
unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
6040
/* get type */
6041
wcap = get_wcaps_type(wcap);
6042
if (wcap != AC_WID_AUD_IN) {
6043
spec->adc_nids = alc880_adc_nids_alt;
6044
spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
6045
} else {
6046
spec->adc_nids = alc880_adc_nids;
6047
spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
6048
}
6049
}
6050
set_capture_mixer(codec);
6051
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6052
6053
spec->vmaster_nid = 0x0c;
6054
6055
codec->patch_ops = alc_patch_ops;
6056
if (board_config == ALC880_AUTO)
6057
spec->init_hook = alc880_auto_init;
6058
#ifdef CONFIG_SND_HDA_POWER_SAVE
6059
if (!spec->loopback.amplist)
6060
spec->loopback.amplist = alc880_loopbacks;
6061
#endif
6062
6063
return 0;
6064
}
6065
6066
6067
/*
6068
* ALC260 support
6069
*/
6070
6071
static const hda_nid_t alc260_dac_nids[1] = {
6072
/* front */
6073
0x02,
6074
};
6075
6076
static const hda_nid_t alc260_adc_nids[1] = {
6077
/* ADC0 */
6078
0x04,
6079
};
6080
6081
static const hda_nid_t alc260_adc_nids_alt[1] = {
6082
/* ADC1 */
6083
0x05,
6084
};
6085
6086
/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6087
* alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6088
*/
6089
static const hda_nid_t alc260_dual_adc_nids[2] = {
6090
/* ADC0, ADC1 */
6091
0x04, 0x05
6092
};
6093
6094
#define ALC260_DIGOUT_NID 0x03
6095
#define ALC260_DIGIN_NID 0x06
6096
6097
static const struct hda_input_mux alc260_capture_source = {
6098
.num_items = 4,
6099
.items = {
6100
{ "Mic", 0x0 },
6101
{ "Front Mic", 0x1 },
6102
{ "Line", 0x2 },
6103
{ "CD", 0x4 },
6104
},
6105
};
6106
6107
/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
6108
* headphone jack and the internal CD lines since these are the only pins at
6109
* which audio can appear. For flexibility, also allow the option of
6110
* recording the mixer output on the second ADC (ADC0 doesn't have a
6111
* connection to the mixer output).
6112
*/
6113
static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
6114
{
6115
.num_items = 3,
6116
.items = {
6117
{ "Mic/Line", 0x0 },
6118
{ "CD", 0x4 },
6119
{ "Headphone", 0x2 },
6120
},
6121
},
6122
{
6123
.num_items = 4,
6124
.items = {
6125
{ "Mic/Line", 0x0 },
6126
{ "CD", 0x4 },
6127
{ "Headphone", 0x2 },
6128
{ "Mixer", 0x5 },
6129
},
6130
},
6131
6132
};
6133
6134
/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6135
* the Fujitsu S702x, but jacks are marked differently.
6136
*/
6137
static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6138
{
6139
.num_items = 4,
6140
.items = {
6141
{ "Mic", 0x0 },
6142
{ "Line", 0x2 },
6143
{ "CD", 0x4 },
6144
{ "Headphone", 0x5 },
6145
},
6146
},
6147
{
6148
.num_items = 5,
6149
.items = {
6150
{ "Mic", 0x0 },
6151
{ "Line", 0x2 },
6152
{ "CD", 0x4 },
6153
{ "Headphone", 0x6 },
6154
{ "Mixer", 0x5 },
6155
},
6156
},
6157
};
6158
6159
/* Maxdata Favorit 100XS */
6160
static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6161
{
6162
.num_items = 2,
6163
.items = {
6164
{ "Line/Mic", 0x0 },
6165
{ "CD", 0x4 },
6166
},
6167
},
6168
{
6169
.num_items = 3,
6170
.items = {
6171
{ "Line/Mic", 0x0 },
6172
{ "CD", 0x4 },
6173
{ "Mixer", 0x5 },
6174
},
6175
},
6176
};
6177
6178
/*
6179
* This is just place-holder, so there's something for alc_build_pcms to look
6180
* at when it calculates the maximum number of channels. ALC260 has no mixer
6181
* element which allows changing the channel mode, so the verb list is
6182
* never used.
6183
*/
6184
static const struct hda_channel_mode alc260_modes[1] = {
6185
{ 2, NULL },
6186
};
6187
6188
6189
/* Mixer combinations
6190
*
6191
* basic: base_output + input + pc_beep + capture
6192
* HP: base_output + input + capture_alt
6193
* HP_3013: hp_3013 + input + capture
6194
* fujitsu: fujitsu + capture
6195
* acer: acer + capture
6196
*/
6197
6198
static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
6199
HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6200
HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6201
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6202
HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6203
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6204
HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6205
{ } /* end */
6206
};
6207
6208
static const struct snd_kcontrol_new alc260_input_mixer[] = {
6209
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6210
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6211
HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6212
HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6213
HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6214
HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6215
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6216
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6217
{ } /* end */
6218
};
6219
6220
/* update HP, line and mono out pins according to the master switch */
6221
static void alc260_hp_master_update(struct hda_codec *codec)
6222
{
6223
update_speakers(codec);
6224
}
6225
6226
static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6227
struct snd_ctl_elem_value *ucontrol)
6228
{
6229
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6230
struct alc_spec *spec = codec->spec;
6231
*ucontrol->value.integer.value = !spec->master_mute;
6232
return 0;
6233
}
6234
6235
static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6236
struct snd_ctl_elem_value *ucontrol)
6237
{
6238
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6239
struct alc_spec *spec = codec->spec;
6240
int val = !*ucontrol->value.integer.value;
6241
6242
if (val == spec->master_mute)
6243
return 0;
6244
spec->master_mute = val;
6245
alc260_hp_master_update(codec);
6246
return 1;
6247
}
6248
6249
static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6250
{
6251
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6252
.name = "Master Playback Switch",
6253
.subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6254
.info = snd_ctl_boolean_mono_info,
6255
.get = alc260_hp_master_sw_get,
6256
.put = alc260_hp_master_sw_put,
6257
},
6258
HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6259
HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6260
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6261
HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6262
HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6263
HDA_OUTPUT),
6264
HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6265
{ } /* end */
6266
};
6267
6268
static const struct hda_verb alc260_hp_unsol_verbs[] = {
6269
{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6270
{},
6271
};
6272
6273
static void alc260_hp_setup(struct hda_codec *codec)
6274
{
6275
struct alc_spec *spec = codec->spec;
6276
6277
spec->autocfg.hp_pins[0] = 0x0f;
6278
spec->autocfg.speaker_pins[0] = 0x10;
6279
spec->autocfg.speaker_pins[1] = 0x11;
6280
spec->automute = 1;
6281
spec->automute_mode = ALC_AUTOMUTE_PIN;
6282
}
6283
6284
static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6285
{
6286
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6287
.name = "Master Playback Switch",
6288
.subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6289
.info = snd_ctl_boolean_mono_info,
6290
.get = alc260_hp_master_sw_get,
6291
.put = alc260_hp_master_sw_put,
6292
},
6293
HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6294
HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6295
HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6296
HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6297
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6298
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6299
HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6300
HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6301
{ } /* end */
6302
};
6303
6304
static void alc260_hp_3013_setup(struct hda_codec *codec)
6305
{
6306
struct alc_spec *spec = codec->spec;
6307
6308
spec->autocfg.hp_pins[0] = 0x15;
6309
spec->autocfg.speaker_pins[0] = 0x10;
6310
spec->autocfg.speaker_pins[1] = 0x11;
6311
spec->automute = 1;
6312
spec->automute_mode = ALC_AUTOMUTE_PIN;
6313
}
6314
6315
static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6316
.ops = &snd_hda_bind_vol,
6317
.values = {
6318
HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6319
HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6320
HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6321
0
6322
},
6323
};
6324
6325
static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6326
.ops = &snd_hda_bind_sw,
6327
.values = {
6328
HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6329
HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6330
0
6331
},
6332
};
6333
6334
static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6335
HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6336
HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6337
HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6338
HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6339
{ } /* end */
6340
};
6341
6342
static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6343
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6344
{},
6345
};
6346
6347
static void alc260_hp_3012_setup(struct hda_codec *codec)
6348
{
6349
struct alc_spec *spec = codec->spec;
6350
6351
spec->autocfg.hp_pins[0] = 0x10;
6352
spec->autocfg.speaker_pins[0] = 0x0f;
6353
spec->autocfg.speaker_pins[1] = 0x11;
6354
spec->autocfg.speaker_pins[2] = 0x15;
6355
spec->automute = 1;
6356
spec->automute_mode = ALC_AUTOMUTE_PIN;
6357
}
6358
6359
/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6360
* HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6361
*/
6362
static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6363
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6364
HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6365
ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6366
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6367
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6368
HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6369
HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6370
ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6371
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6372
HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6373
{ } /* end */
6374
};
6375
6376
/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6377
* versions of the ALC260 don't act on requests to enable mic bias from NID
6378
* 0x0f (used to drive the headphone jack in these laptops). The ALC260
6379
* datasheet doesn't mention this restriction. At this stage it's not clear
6380
* whether this behaviour is intentional or is a hardware bug in chip
6381
* revisions available in early 2006. Therefore for now allow the
6382
* "Headphone Jack Mode" control to span all choices, but if it turns out
6383
* that the lack of mic bias for this NID is intentional we could change the
6384
* mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6385
*
6386
* In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6387
* don't appear to make the mic bias available from the "line" jack, even
6388
* though the NID used for this jack (0x14) can supply it. The theory is
6389
* that perhaps Acer have included blocking capacitors between the ALC260
6390
* and the output jack. If this turns out to be the case for all such
6391
* models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6392
* to ALC_PIN_DIR_INOUT_NOMICBIAS.
6393
*
6394
* The C20x Tablet series have a mono internal speaker which is controlled
6395
* via the chip's Mono sum widget and pin complex, so include the necessary
6396
* controls for such models. On models without a "mono speaker" the control
6397
* won't do anything.
6398
*/
6399
static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6400
HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6401
HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6402
ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6403
HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6404
HDA_OUTPUT),
6405
HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6406
HDA_INPUT),
6407
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6408
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6409
HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6410
HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6411
ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6412
HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6413
HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6414
ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6415
{ } /* end */
6416
};
6417
6418
/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6419
*/
6420
static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6421
HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6422
HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6423
ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6424
HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6425
HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6426
ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6427
{ } /* end */
6428
};
6429
6430
/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6431
* Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6432
*/
6433
static const struct snd_kcontrol_new alc260_will_mixer[] = {
6434
HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6435
HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6436
HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6437
HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6438
ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6439
HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6440
HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6441
ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6442
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6443
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6444
{ } /* end */
6445
};
6446
6447
/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6448
* Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6449
*/
6450
static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6451
HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6452
HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6453
HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6454
HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6455
ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6456
HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6457
HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6458
HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6459
HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6460
ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6461
{ } /* end */
6462
};
6463
6464
/*
6465
* initialization verbs
6466
*/
6467
static const struct hda_verb alc260_init_verbs[] = {
6468
/* Line In pin widget for input */
6469
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6470
/* CD pin widget for input */
6471
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6472
/* Mic1 (rear panel) pin widget for input and vref at 80% */
6473
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6474
/* Mic2 (front panel) pin widget for input and vref at 80% */
6475
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6476
/* LINE-2 is used for line-out in rear */
6477
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6478
/* select line-out */
6479
{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6480
/* LINE-OUT pin */
6481
{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6482
/* enable HP */
6483
{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6484
/* enable Mono */
6485
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6486
/* mute capture amp left and right */
6487
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6488
/* set connection select to line in (default select for this ADC) */
6489
{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6490
/* mute capture amp left and right */
6491
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6492
/* set connection select to line in (default select for this ADC) */
6493
{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6494
/* set vol=0 Line-Out mixer amp left and right */
6495
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6496
/* unmute pin widget amp left and right (no gain on this amp) */
6497
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6498
/* set vol=0 HP mixer amp left and right */
6499
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6500
/* unmute pin widget amp left and right (no gain on this amp) */
6501
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6502
/* set vol=0 Mono mixer amp left and right */
6503
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6504
/* unmute pin widget amp left and right (no gain on this amp) */
6505
{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6506
/* unmute LINE-2 out pin */
6507
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6508
/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6509
* Line In 2 = 0x03
6510
*/
6511
/* mute analog inputs */
6512
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6513
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6514
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6515
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6516
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6517
/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6518
/* mute Front out path */
6519
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6520
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6521
/* mute Headphone out path */
6522
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6523
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6524
/* mute Mono out path */
6525
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6526
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6527
{ }
6528
};
6529
6530
#if 0 /* should be identical with alc260_init_verbs? */
6531
static const struct hda_verb alc260_hp_init_verbs[] = {
6532
/* Headphone and output */
6533
{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6534
/* mono output */
6535
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6536
/* Mic1 (rear panel) pin widget for input and vref at 80% */
6537
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6538
/* Mic2 (front panel) pin widget for input and vref at 80% */
6539
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6540
/* Line In pin widget for input */
6541
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6542
/* Line-2 pin widget for output */
6543
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6544
/* CD pin widget for input */
6545
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6546
/* unmute amp left and right */
6547
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6548
/* set connection select to line in (default select for this ADC) */
6549
{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6550
/* unmute Line-Out mixer amp left and right (volume = 0) */
6551
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6552
/* mute pin widget amp left and right (no gain on this amp) */
6553
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6554
/* unmute HP mixer amp left and right (volume = 0) */
6555
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6556
/* mute pin widget amp left and right (no gain on this amp) */
6557
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6558
/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6559
* Line In 2 = 0x03
6560
*/
6561
/* mute analog inputs */
6562
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6563
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6564
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6565
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6566
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6567
/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6568
/* Unmute Front out path */
6569
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6570
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6571
/* Unmute Headphone out path */
6572
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6573
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6574
/* Unmute Mono out path */
6575
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6576
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6577
{ }
6578
};
6579
#endif
6580
6581
static const struct hda_verb alc260_hp_3013_init_verbs[] = {
6582
/* Line out and output */
6583
{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6584
/* mono output */
6585
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6586
/* Mic1 (rear panel) pin widget for input and vref at 80% */
6587
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6588
/* Mic2 (front panel) pin widget for input and vref at 80% */
6589
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6590
/* Line In pin widget for input */
6591
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6592
/* Headphone pin widget for output */
6593
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6594
/* CD pin widget for input */
6595
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6596
/* unmute amp left and right */
6597
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6598
/* set connection select to line in (default select for this ADC) */
6599
{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6600
/* unmute Line-Out mixer amp left and right (volume = 0) */
6601
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6602
/* mute pin widget amp left and right (no gain on this amp) */
6603
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6604
/* unmute HP mixer amp left and right (volume = 0) */
6605
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6606
/* mute pin widget amp left and right (no gain on this amp) */
6607
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6608
/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6609
* Line In 2 = 0x03
6610
*/
6611
/* mute analog inputs */
6612
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6613
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6614
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6615
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6616
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6617
/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6618
/* Unmute Front out path */
6619
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6620
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6621
/* Unmute Headphone out path */
6622
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6623
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6624
/* Unmute Mono out path */
6625
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6626
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6627
{ }
6628
};
6629
6630
/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6631
* laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6632
* audio = 0x16, internal speaker = 0x10.
6633
*/
6634
static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6635
/* Disable all GPIOs */
6636
{0x01, AC_VERB_SET_GPIO_MASK, 0},
6637
/* Internal speaker is connected to headphone pin */
6638
{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6639
/* Headphone/Line-out jack connects to Line1 pin; make it an output */
6640
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6641
/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6642
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6643
/* Ensure all other unused pins are disabled and muted. */
6644
{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6645
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6646
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6647
{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6648
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6649
{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6650
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6651
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6652
6653
/* Disable digital (SPDIF) pins */
6654
{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6655
{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6656
6657
/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6658
* when acting as an output.
6659
*/
6660
{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6661
6662
/* Start with output sum widgets muted and their output gains at min */
6663
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6664
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6665
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6666
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6667
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6668
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6669
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6670
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6671
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6672
6673
/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6674
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6675
/* Unmute Line1 pin widget output buffer since it starts as an output.
6676
* If the pin mode is changed by the user the pin mode control will
6677
* take care of enabling the pin's input/output buffers as needed.
6678
* Therefore there's no need to enable the input buffer at this
6679
* stage.
6680
*/
6681
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6682
/* Unmute input buffer of pin widget used for Line-in (no equiv
6683
* mixer ctrl)
6684
*/
6685
{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6686
6687
/* Mute capture amp left and right */
6688
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6689
/* Set ADC connection select to match default mixer setting - line
6690
* in (on mic1 pin)
6691
*/
6692
{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6693
6694
/* Do the same for the second ADC: mute capture input amp and
6695
* set ADC connection to line in (on mic1 pin)
6696
*/
6697
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6698
{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6699
6700
/* Mute all inputs to mixer widget (even unconnected ones) */
6701
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6702
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6703
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6704
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6705
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6706
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6707
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6708
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6709
6710
{ }
6711
};
6712
6713
/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6714
* similar laptops (adapted from Fujitsu init verbs).
6715
*/
6716
static const struct hda_verb alc260_acer_init_verbs[] = {
6717
/* On TravelMate laptops, GPIO 0 enables the internal speaker and
6718
* the headphone jack. Turn this on and rely on the standard mute
6719
* methods whenever the user wants to turn these outputs off.
6720
*/
6721
{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6722
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6723
{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6724
/* Internal speaker/Headphone jack is connected to Line-out pin */
6725
{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6726
/* Internal microphone/Mic jack is connected to Mic1 pin */
6727
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6728
/* Line In jack is connected to Line1 pin */
6729
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6730
/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6731
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6732
/* Ensure all other unused pins are disabled and muted. */
6733
{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6734
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6735
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6736
{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6737
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6738
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6739
/* Disable digital (SPDIF) pins */
6740
{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6741
{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6742
6743
/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6744
* bus when acting as outputs.
6745
*/
6746
{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6747
{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6748
6749
/* Start with output sum widgets muted and their output gains at min */
6750
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6751
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6752
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6753
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6754
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6755
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6756
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6757
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6758
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6759
6760
/* Unmute Line-out pin widget amp left and right
6761
* (no equiv mixer ctrl)
6762
*/
6763
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6764
/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6765
{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6766
/* Unmute Mic1 and Line1 pin widget input buffers since they start as
6767
* inputs. If the pin mode is changed by the user the pin mode control
6768
* will take care of enabling the pin's input/output buffers as needed.
6769
* Therefore there's no need to enable the input buffer at this
6770
* stage.
6771
*/
6772
{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6773
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6774
6775
/* Mute capture amp left and right */
6776
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6777
/* Set ADC connection select to match default mixer setting - mic
6778
* (on mic1 pin)
6779
*/
6780
{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6781
6782
/* Do similar with the second ADC: mute capture input amp and
6783
* set ADC connection to mic to match ALSA's default state.
6784
*/
6785
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6786
{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6787
6788
/* Mute all inputs to mixer widget (even unconnected ones) */
6789
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6790
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6791
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6792
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6793
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6794
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6795
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6796
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6797
6798
{ }
6799
};
6800
6801
/* Initialisation sequence for Maxdata Favorit 100XS
6802
* (adapted from Acer init verbs).
6803
*/
6804
static const struct hda_verb alc260_favorit100_init_verbs[] = {
6805
/* GPIO 0 enables the output jack.
6806
* Turn this on and rely on the standard mute
6807
* methods whenever the user wants to turn these outputs off.
6808
*/
6809
{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6810
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6811
{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6812
/* Line/Mic input jack is connected to Mic1 pin */
6813
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6814
/* Ensure all other unused pins are disabled and muted. */
6815
{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6816
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6817
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6818
{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6819
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6820
{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6821
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6822
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6823
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6824
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6825
/* Disable digital (SPDIF) pins */
6826
{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6827
{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6828
6829
/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6830
* bus when acting as outputs.
6831
*/
6832
{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6833
{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6834
6835
/* Start with output sum widgets muted and their output gains at min */
6836
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6837
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6838
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6839
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6840
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6841
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6842
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6843
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6844
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6845
6846
/* Unmute Line-out pin widget amp left and right
6847
* (no equiv mixer ctrl)
6848
*/
6849
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6850
/* Unmute Mic1 and Line1 pin widget input buffers since they start as
6851
* inputs. If the pin mode is changed by the user the pin mode control
6852
* will take care of enabling the pin's input/output buffers as needed.
6853
* Therefore there's no need to enable the input buffer at this
6854
* stage.
6855
*/
6856
{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6857
6858
/* Mute capture amp left and right */
6859
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6860
/* Set ADC connection select to match default mixer setting - mic
6861
* (on mic1 pin)
6862
*/
6863
{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6864
6865
/* Do similar with the second ADC: mute capture input amp and
6866
* set ADC connection to mic to match ALSA's default state.
6867
*/
6868
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6869
{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6870
6871
/* Mute all inputs to mixer widget (even unconnected ones) */
6872
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6873
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6874
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6875
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6876
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6877
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6878
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6879
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6880
6881
{ }
6882
};
6883
6884
static const struct hda_verb alc260_will_verbs[] = {
6885
{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6886
{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6887
{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6888
{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6889
{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6890
{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6891
{}
6892
};
6893
6894
static const struct hda_verb alc260_replacer_672v_verbs[] = {
6895
{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6896
{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6897
{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6898
6899
{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6900
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6901
{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6902
6903
{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6904
{}
6905
};
6906
6907
/* toggle speaker-output according to the hp-jack state */
6908
static void alc260_replacer_672v_automute(struct hda_codec *codec)
6909
{
6910
unsigned int present;
6911
6912
/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6913
present = snd_hda_jack_detect(codec, 0x0f);
6914
if (present) {
6915
snd_hda_codec_write_cache(codec, 0x01, 0,
6916
AC_VERB_SET_GPIO_DATA, 1);
6917
snd_hda_codec_write_cache(codec, 0x0f, 0,
6918
AC_VERB_SET_PIN_WIDGET_CONTROL,
6919
PIN_HP);
6920
} else {
6921
snd_hda_codec_write_cache(codec, 0x01, 0,
6922
AC_VERB_SET_GPIO_DATA, 0);
6923
snd_hda_codec_write_cache(codec, 0x0f, 0,
6924
AC_VERB_SET_PIN_WIDGET_CONTROL,
6925
PIN_OUT);
6926
}
6927
}
6928
6929
static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6930
unsigned int res)
6931
{
6932
if ((res >> 26) == ALC880_HP_EVENT)
6933
alc260_replacer_672v_automute(codec);
6934
}
6935
6936
static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6937
{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6938
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6939
{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6940
{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6941
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6942
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6943
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6944
{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6945
{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6946
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6947
{}
6948
};
6949
6950
/* Test configuration for debugging, modelled after the ALC880 test
6951
* configuration.
6952
*/
6953
#ifdef CONFIG_SND_DEBUG
6954
static const hda_nid_t alc260_test_dac_nids[1] = {
6955
0x02,
6956
};
6957
static const hda_nid_t alc260_test_adc_nids[2] = {
6958
0x04, 0x05,
6959
};
6960
/* For testing the ALC260, each input MUX needs its own definition since
6961
* the signal assignments are different. This assumes that the first ADC
6962
* is NID 0x04.
6963
*/
6964
static const struct hda_input_mux alc260_test_capture_sources[2] = {
6965
{
6966
.num_items = 7,
6967
.items = {
6968
{ "MIC1 pin", 0x0 },
6969
{ "MIC2 pin", 0x1 },
6970
{ "LINE1 pin", 0x2 },
6971
{ "LINE2 pin", 0x3 },
6972
{ "CD pin", 0x4 },
6973
{ "LINE-OUT pin", 0x5 },
6974
{ "HP-OUT pin", 0x6 },
6975
},
6976
},
6977
{
6978
.num_items = 8,
6979
.items = {
6980
{ "MIC1 pin", 0x0 },
6981
{ "MIC2 pin", 0x1 },
6982
{ "LINE1 pin", 0x2 },
6983
{ "LINE2 pin", 0x3 },
6984
{ "CD pin", 0x4 },
6985
{ "Mixer", 0x5 },
6986
{ "LINE-OUT pin", 0x6 },
6987
{ "HP-OUT pin", 0x7 },
6988
},
6989
},
6990
};
6991
static const struct snd_kcontrol_new alc260_test_mixer[] = {
6992
/* Output driver widgets */
6993
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6994
HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6995
HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6996
HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6997
HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6998
HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6999
7000
/* Modes for retasking pin widgets
7001
* Note: the ALC260 doesn't seem to act on requests to enable mic
7002
* bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
7003
* mention this restriction. At this stage it's not clear whether
7004
* this behaviour is intentional or is a hardware bug in chip
7005
* revisions available at least up until early 2006. Therefore for
7006
* now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
7007
* choices, but if it turns out that the lack of mic bias for these
7008
* NIDs is intentional we could change their modes from
7009
* ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
7010
*/
7011
ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
7012
ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
7013
ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7014
ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7015
ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7016
ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7017
7018
/* Loopback mixer controls */
7019
HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7020
HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7021
HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7022
HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7023
HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7024
HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7025
HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7026
HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7027
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7028
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7029
HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7030
HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7031
HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7032
HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
7033
7034
/* Controls for GPIO pins, assuming they are configured as outputs */
7035
ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7036
ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7037
ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7038
ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7039
7040
/* Switches to allow the digital IO pins to be enabled. The datasheet
7041
* is ambigious as to which NID is which; testing on laptops which
7042
* make this output available should provide clarification.
7043
*/
7044
ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7045
ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7046
7047
/* A switch allowing EAPD to be enabled. Some laptops seem to use
7048
* this output to turn on an external amplifier.
7049
*/
7050
ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7051
ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7052
7053
{ } /* end */
7054
};
7055
static const struct hda_verb alc260_test_init_verbs[] = {
7056
/* Enable all GPIOs as outputs with an initial value of 0 */
7057
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7058
{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7059
{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7060
7061
/* Enable retasking pins as output, initially without power amp */
7062
{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7063
{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7064
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7065
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7066
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7067
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7068
7069
/* Disable digital (SPDIF) pins initially, but users can enable
7070
* them via a mixer switch. In the case of SPDIF-out, this initverb
7071
* payload also sets the generation to 0, output to be in "consumer"
7072
* PCM format, copyright asserted, no pre-emphasis and no validity
7073
* control.
7074
*/
7075
{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7076
{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7077
7078
/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7079
* OUT1 sum bus when acting as an output.
7080
*/
7081
{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7082
{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7083
{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7084
{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7085
7086
/* Start with output sum widgets muted and their output gains at min */
7087
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7088
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7089
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7090
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7091
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7092
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7093
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7094
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7095
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7096
7097
/* Unmute retasking pin widget output buffers since the default
7098
* state appears to be output. As the pin mode is changed by the
7099
* user the pin mode control will take care of enabling the pin's
7100
* input/output buffers as needed.
7101
*/
7102
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7103
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7104
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7105
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7106
{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7107
{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7108
/* Also unmute the mono-out pin widget */
7109
{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7110
7111
/* Mute capture amp left and right */
7112
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7113
/* Set ADC connection select to match default mixer setting (mic1
7114
* pin)
7115
*/
7116
{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7117
7118
/* Do the same for the second ADC: mute capture input amp and
7119
* set ADC connection to mic1 pin
7120
*/
7121
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7122
{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7123
7124
/* Mute all inputs to mixer widget (even unconnected ones) */
7125
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7126
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7127
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7128
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7129
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7130
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7131
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7132
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7133
7134
{ }
7135
};
7136
#endif
7137
7138
#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7139
#define alc260_pcm_analog_capture alc880_pcm_analog_capture
7140
7141
#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7142
#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7143
7144
/*
7145
* for BIOS auto-configuration
7146
*/
7147
7148
static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
7149
const char *pfx, int *vol_bits)
7150
{
7151
hda_nid_t nid_vol;
7152
unsigned long vol_val, sw_val;
7153
int err;
7154
7155
if (nid >= 0x0f && nid < 0x11) {
7156
nid_vol = nid - 0x7;
7157
vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7158
sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7159
} else if (nid == 0x11) {
7160
nid_vol = nid - 0x7;
7161
vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7162
sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7163
} else if (nid >= 0x12 && nid <= 0x15) {
7164
nid_vol = 0x08;
7165
vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7166
sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7167
} else
7168
return 0; /* N/A */
7169
7170
if (!(*vol_bits & (1 << nid_vol))) {
7171
/* first control for the volume widget */
7172
err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
7173
if (err < 0)
7174
return err;
7175
*vol_bits |= (1 << nid_vol);
7176
}
7177
err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
7178
if (err < 0)
7179
return err;
7180
return 1;
7181
}
7182
7183
/* add playback controls from the parsed DAC table */
7184
static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7185
const struct auto_pin_cfg *cfg)
7186
{
7187
hda_nid_t nid;
7188
int err;
7189
int vols = 0;
7190
7191
spec->multiout.num_dacs = 1;
7192
spec->multiout.dac_nids = spec->private_dac_nids;
7193
spec->private_dac_nids[0] = 0x02;
7194
7195
nid = cfg->line_out_pins[0];
7196
if (nid) {
7197
const char *pfx;
7198
if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7199
pfx = "Master";
7200
else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7201
pfx = "Speaker";
7202
else
7203
pfx = "Front";
7204
err = alc260_add_playback_controls(spec, nid, pfx, &vols);
7205
if (err < 0)
7206
return err;
7207
}
7208
7209
nid = cfg->speaker_pins[0];
7210
if (nid) {
7211
err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
7212
if (err < 0)
7213
return err;
7214
}
7215
7216
nid = cfg->hp_pins[0];
7217
if (nid) {
7218
err = alc260_add_playback_controls(spec, nid, "Headphone",
7219
&vols);
7220
if (err < 0)
7221
return err;
7222
}
7223
return 0;
7224
}
7225
7226
/* create playback/capture controls for input pins */
7227
static int alc260_auto_create_input_ctls(struct hda_codec *codec,
7228
const struct auto_pin_cfg *cfg)
7229
{
7230
return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
7231
}
7232
7233
static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7234
hda_nid_t nid, int pin_type,
7235
int sel_idx)
7236
{
7237
alc_set_pin_output(codec, nid, pin_type);
7238
/* need the manual connection? */
7239
if (nid >= 0x12) {
7240
int idx = nid - 0x12;
7241
snd_hda_codec_write(codec, idx + 0x0b, 0,
7242
AC_VERB_SET_CONNECT_SEL, sel_idx);
7243
}
7244
}
7245
7246
static void alc260_auto_init_multi_out(struct hda_codec *codec)
7247
{
7248
struct alc_spec *spec = codec->spec;
7249
hda_nid_t nid;
7250
7251
nid = spec->autocfg.line_out_pins[0];
7252
if (nid) {
7253
int pin_type = get_pin_type(spec->autocfg.line_out_type);
7254
alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7255
}
7256
7257
nid = spec->autocfg.speaker_pins[0];
7258
if (nid)
7259
alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7260
7261
nid = spec->autocfg.hp_pins[0];
7262
if (nid)
7263
alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7264
}
7265
7266
#define ALC260_PIN_CD_NID 0x16
7267
static void alc260_auto_init_analog_input(struct hda_codec *codec)
7268
{
7269
struct alc_spec *spec = codec->spec;
7270
struct auto_pin_cfg *cfg = &spec->autocfg;
7271
int i;
7272
7273
for (i = 0; i < cfg->num_inputs; i++) {
7274
hda_nid_t nid = cfg->inputs[i].pin;
7275
if (nid >= 0x12) {
7276
alc_set_input_pin(codec, nid, cfg->inputs[i].type);
7277
if (nid != ALC260_PIN_CD_NID &&
7278
(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
7279
snd_hda_codec_write(codec, nid, 0,
7280
AC_VERB_SET_AMP_GAIN_MUTE,
7281
AMP_OUT_MUTE);
7282
}
7283
}
7284
}
7285
7286
#define alc260_auto_init_input_src alc880_auto_init_input_src
7287
7288
/*
7289
* generic initialization of ADC, input mixers and output mixers
7290
*/
7291
static const struct hda_verb alc260_volume_init_verbs[] = {
7292
/*
7293
* Unmute ADC0-1 and set the default input to mic-in
7294
*/
7295
{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7296
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7297
{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7298
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7299
7300
/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7301
* mixer widget
7302
* Note: PASD motherboards uses the Line In 2 as the input for
7303
* front panel mic (mic 2)
7304
*/
7305
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7306
/* mute analog inputs */
7307
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7308
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7309
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7310
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7311
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7312
7313
/*
7314
* Set up output mixers (0x08 - 0x0a)
7315
*/
7316
/* set vol=0 to output mixers */
7317
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7318
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7319
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7320
/* set up input amps for analog loopback */
7321
/* Amp Indices: DAC = 0, mixer = 1 */
7322
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7323
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7324
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7325
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7326
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7327
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7328
7329
{ }
7330
};
7331
7332
static int alc260_parse_auto_config(struct hda_codec *codec)
7333
{
7334
struct alc_spec *spec = codec->spec;
7335
int err;
7336
static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7337
7338
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7339
alc260_ignore);
7340
if (err < 0)
7341
return err;
7342
err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7343
if (err < 0)
7344
return err;
7345
if (!spec->kctls.list)
7346
return 0; /* can't find valid BIOS pin config */
7347
err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7348
if (err < 0)
7349
return err;
7350
7351
spec->multiout.max_channels = 2;
7352
7353
if (spec->autocfg.dig_outs)
7354
spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7355
if (spec->kctls.list)
7356
add_mixer(spec, spec->kctls.list);
7357
7358
add_verb(spec, alc260_volume_init_verbs);
7359
7360
spec->num_mux_defs = 1;
7361
spec->input_mux = &spec->private_imux[0];
7362
7363
alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7364
7365
return 1;
7366
}
7367
7368
/* additional initialization for auto-configuration model */
7369
static void alc260_auto_init(struct hda_codec *codec)
7370
{
7371
struct alc_spec *spec = codec->spec;
7372
alc260_auto_init_multi_out(codec);
7373
alc260_auto_init_analog_input(codec);
7374
alc260_auto_init_input_src(codec);
7375
alc_auto_init_digital(codec);
7376
if (spec->unsol_event)
7377
alc_inithook(codec);
7378
}
7379
7380
#ifdef CONFIG_SND_HDA_POWER_SAVE
7381
static const struct hda_amp_list alc260_loopbacks[] = {
7382
{ 0x07, HDA_INPUT, 0 },
7383
{ 0x07, HDA_INPUT, 1 },
7384
{ 0x07, HDA_INPUT, 2 },
7385
{ 0x07, HDA_INPUT, 3 },
7386
{ 0x07, HDA_INPUT, 4 },
7387
{ } /* end */
7388
};
7389
#endif
7390
7391
/*
7392
* Pin config fixes
7393
*/
7394
enum {
7395
PINFIX_HP_DC5750,
7396
};
7397
7398
static const struct alc_fixup alc260_fixups[] = {
7399
[PINFIX_HP_DC5750] = {
7400
.type = ALC_FIXUP_PINS,
7401
.v.pins = (const struct alc_pincfg[]) {
7402
{ 0x11, 0x90130110 }, /* speaker */
7403
{ }
7404
}
7405
},
7406
};
7407
7408
static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7409
SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7410
{}
7411
};
7412
7413
/*
7414
* ALC260 configurations
7415
*/
7416
static const char * const alc260_models[ALC260_MODEL_LAST] = {
7417
[ALC260_BASIC] = "basic",
7418
[ALC260_HP] = "hp",
7419
[ALC260_HP_3013] = "hp-3013",
7420
[ALC260_HP_DC7600] = "hp-dc7600",
7421
[ALC260_FUJITSU_S702X] = "fujitsu",
7422
[ALC260_ACER] = "acer",
7423
[ALC260_WILL] = "will",
7424
[ALC260_REPLACER_672V] = "replacer",
7425
[ALC260_FAVORIT100] = "favorit100",
7426
#ifdef CONFIG_SND_DEBUG
7427
[ALC260_TEST] = "test",
7428
#endif
7429
[ALC260_AUTO] = "auto",
7430
};
7431
7432
static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7433
SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7434
SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7435
SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7436
SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7437
SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7438
SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7439
SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7440
SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7441
SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7442
SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7443
SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7444
SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7445
SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7446
SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7447
SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7448
SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7449
SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7450
SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7451
SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7452
SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7453
{}
7454
};
7455
7456
static const struct alc_config_preset alc260_presets[] = {
7457
[ALC260_BASIC] = {
7458
.mixers = { alc260_base_output_mixer,
7459
alc260_input_mixer },
7460
.init_verbs = { alc260_init_verbs },
7461
.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7462
.dac_nids = alc260_dac_nids,
7463
.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7464
.adc_nids = alc260_dual_adc_nids,
7465
.num_channel_mode = ARRAY_SIZE(alc260_modes),
7466
.channel_mode = alc260_modes,
7467
.input_mux = &alc260_capture_source,
7468
},
7469
[ALC260_HP] = {
7470
.mixers = { alc260_hp_output_mixer,
7471
alc260_input_mixer },
7472
.init_verbs = { alc260_init_verbs,
7473
alc260_hp_unsol_verbs },
7474
.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7475
.dac_nids = alc260_dac_nids,
7476
.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7477
.adc_nids = alc260_adc_nids_alt,
7478
.num_channel_mode = ARRAY_SIZE(alc260_modes),
7479
.channel_mode = alc260_modes,
7480
.input_mux = &alc260_capture_source,
7481
.unsol_event = alc_sku_unsol_event,
7482
.setup = alc260_hp_setup,
7483
.init_hook = alc_inithook,
7484
},
7485
[ALC260_HP_DC7600] = {
7486
.mixers = { alc260_hp_dc7600_mixer,
7487
alc260_input_mixer },
7488
.init_verbs = { alc260_init_verbs,
7489
alc260_hp_dc7600_verbs },
7490
.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7491
.dac_nids = alc260_dac_nids,
7492
.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7493
.adc_nids = alc260_adc_nids_alt,
7494
.num_channel_mode = ARRAY_SIZE(alc260_modes),
7495
.channel_mode = alc260_modes,
7496
.input_mux = &alc260_capture_source,
7497
.unsol_event = alc_sku_unsol_event,
7498
.setup = alc260_hp_3012_setup,
7499
.init_hook = alc_inithook,
7500
},
7501
[ALC260_HP_3013] = {
7502
.mixers = { alc260_hp_3013_mixer,
7503
alc260_input_mixer },
7504
.init_verbs = { alc260_hp_3013_init_verbs,
7505
alc260_hp_3013_unsol_verbs },
7506
.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7507
.dac_nids = alc260_dac_nids,
7508
.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7509
.adc_nids = alc260_adc_nids_alt,
7510
.num_channel_mode = ARRAY_SIZE(alc260_modes),
7511
.channel_mode = alc260_modes,
7512
.input_mux = &alc260_capture_source,
7513
.unsol_event = alc_sku_unsol_event,
7514
.setup = alc260_hp_3013_setup,
7515
.init_hook = alc_inithook,
7516
},
7517
[ALC260_FUJITSU_S702X] = {
7518
.mixers = { alc260_fujitsu_mixer },
7519
.init_verbs = { alc260_fujitsu_init_verbs },
7520
.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7521
.dac_nids = alc260_dac_nids,
7522
.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7523
.adc_nids = alc260_dual_adc_nids,
7524
.num_channel_mode = ARRAY_SIZE(alc260_modes),
7525
.channel_mode = alc260_modes,
7526
.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7527
.input_mux = alc260_fujitsu_capture_sources,
7528
},
7529
[ALC260_ACER] = {
7530
.mixers = { alc260_acer_mixer },
7531
.init_verbs = { alc260_acer_init_verbs },
7532
.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7533
.dac_nids = alc260_dac_nids,
7534
.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7535
.adc_nids = alc260_dual_adc_nids,
7536
.num_channel_mode = ARRAY_SIZE(alc260_modes),
7537
.channel_mode = alc260_modes,
7538
.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7539
.input_mux = alc260_acer_capture_sources,
7540
},
7541
[ALC260_FAVORIT100] = {
7542
.mixers = { alc260_favorit100_mixer },
7543
.init_verbs = { alc260_favorit100_init_verbs },
7544
.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7545
.dac_nids = alc260_dac_nids,
7546
.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7547
.adc_nids = alc260_dual_adc_nids,
7548
.num_channel_mode = ARRAY_SIZE(alc260_modes),
7549
.channel_mode = alc260_modes,
7550
.num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7551
.input_mux = alc260_favorit100_capture_sources,
7552
},
7553
[ALC260_WILL] = {
7554
.mixers = { alc260_will_mixer },
7555
.init_verbs = { alc260_init_verbs, alc260_will_verbs },
7556
.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7557
.dac_nids = alc260_dac_nids,
7558
.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7559
.adc_nids = alc260_adc_nids,
7560
.dig_out_nid = ALC260_DIGOUT_NID,
7561
.num_channel_mode = ARRAY_SIZE(alc260_modes),
7562
.channel_mode = alc260_modes,
7563
.input_mux = &alc260_capture_source,
7564
},
7565
[ALC260_REPLACER_672V] = {
7566
.mixers = { alc260_replacer_672v_mixer },
7567
.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7568
.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7569
.dac_nids = alc260_dac_nids,
7570
.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7571
.adc_nids = alc260_adc_nids,
7572
.dig_out_nid = ALC260_DIGOUT_NID,
7573
.num_channel_mode = ARRAY_SIZE(alc260_modes),
7574
.channel_mode = alc260_modes,
7575
.input_mux = &alc260_capture_source,
7576
.unsol_event = alc260_replacer_672v_unsol_event,
7577
.init_hook = alc260_replacer_672v_automute,
7578
},
7579
#ifdef CONFIG_SND_DEBUG
7580
[ALC260_TEST] = {
7581
.mixers = { alc260_test_mixer },
7582
.init_verbs = { alc260_test_init_verbs },
7583
.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7584
.dac_nids = alc260_test_dac_nids,
7585
.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7586
.adc_nids = alc260_test_adc_nids,
7587
.num_channel_mode = ARRAY_SIZE(alc260_modes),
7588
.channel_mode = alc260_modes,
7589
.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7590
.input_mux = alc260_test_capture_sources,
7591
},
7592
#endif
7593
};
7594
7595
static int patch_alc260(struct hda_codec *codec)
7596
{
7597
struct alc_spec *spec;
7598
int err, board_config;
7599
7600
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7601
if (spec == NULL)
7602
return -ENOMEM;
7603
7604
codec->spec = spec;
7605
7606
board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7607
alc260_models,
7608
alc260_cfg_tbl);
7609
if (board_config < 0) {
7610
snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7611
codec->chip_name);
7612
board_config = ALC260_AUTO;
7613
}
7614
7615
if (board_config == ALC260_AUTO) {
7616
alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7617
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7618
}
7619
7620
if (board_config == ALC260_AUTO) {
7621
/* automatic parse from the BIOS config */
7622
err = alc260_parse_auto_config(codec);
7623
if (err < 0) {
7624
alc_free(codec);
7625
return err;
7626
} else if (!err) {
7627
printk(KERN_INFO
7628
"hda_codec: Cannot set up configuration "
7629
"from BIOS. Using base mode...\n");
7630
board_config = ALC260_BASIC;
7631
}
7632
}
7633
7634
err = snd_hda_attach_beep_device(codec, 0x1);
7635
if (err < 0) {
7636
alc_free(codec);
7637
return err;
7638
}
7639
7640
if (board_config != ALC260_AUTO)
7641
setup_preset(codec, &alc260_presets[board_config]);
7642
7643
spec->stream_analog_playback = &alc260_pcm_analog_playback;
7644
spec->stream_analog_capture = &alc260_pcm_analog_capture;
7645
spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
7646
7647
spec->stream_digital_playback = &alc260_pcm_digital_playback;
7648
spec->stream_digital_capture = &alc260_pcm_digital_capture;
7649
7650
if (!spec->adc_nids && spec->input_mux) {
7651
/* check whether NID 0x04 is valid */
7652
unsigned int wcap = get_wcaps(codec, 0x04);
7653
wcap = get_wcaps_type(wcap);
7654
/* get type */
7655
if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7656
spec->adc_nids = alc260_adc_nids_alt;
7657
spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7658
} else {
7659
spec->adc_nids = alc260_adc_nids;
7660
spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7661
}
7662
}
7663
set_capture_mixer(codec);
7664
set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7665
7666
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7667
7668
spec->vmaster_nid = 0x08;
7669
7670
codec->patch_ops = alc_patch_ops;
7671
if (board_config == ALC260_AUTO)
7672
spec->init_hook = alc260_auto_init;
7673
spec->shutup = alc_eapd_shutup;
7674
#ifdef CONFIG_SND_HDA_POWER_SAVE
7675
if (!spec->loopback.amplist)
7676
spec->loopback.amplist = alc260_loopbacks;
7677
#endif
7678
7679
return 0;
7680
}
7681
7682
7683
/*
7684
* ALC882/883/885/888/889 support
7685
*
7686
* ALC882 is almost identical with ALC880 but has cleaner and more flexible
7687
* configuration. Each pin widget can choose any input DACs and a mixer.
7688
* Each ADC is connected from a mixer of all inputs. This makes possible
7689
* 6-channel independent captures.
7690
*
7691
* In addition, an independent DAC for the multi-playback (not used in this
7692
* driver yet).
7693
*/
7694
#define ALC882_DIGOUT_NID 0x06
7695
#define ALC882_DIGIN_NID 0x0a
7696
#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7697
#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7698
#define ALC1200_DIGOUT_NID 0x10
7699
7700
7701
static const struct hda_channel_mode alc882_ch_modes[1] = {
7702
{ 8, NULL }
7703
};
7704
7705
/* DACs */
7706
static const hda_nid_t alc882_dac_nids[4] = {
7707
/* front, rear, clfe, rear_surr */
7708
0x02, 0x03, 0x04, 0x05
7709
};
7710
#define alc883_dac_nids alc882_dac_nids
7711
7712
/* ADCs */
7713
#define alc882_adc_nids alc880_adc_nids
7714
#define alc882_adc_nids_alt alc880_adc_nids_alt
7715
#define alc883_adc_nids alc882_adc_nids_alt
7716
static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7717
static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7718
#define alc889_adc_nids alc880_adc_nids
7719
7720
static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7721
static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7722
#define alc883_capsrc_nids alc882_capsrc_nids_alt
7723
static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7724
#define alc889_capsrc_nids alc882_capsrc_nids
7725
7726
/* input MUX */
7727
/* FIXME: should be a matrix-type input source selection */
7728
7729
static const struct hda_input_mux alc882_capture_source = {
7730
.num_items = 4,
7731
.items = {
7732
{ "Mic", 0x0 },
7733
{ "Front Mic", 0x1 },
7734
{ "Line", 0x2 },
7735
{ "CD", 0x4 },
7736
},
7737
};
7738
7739
#define alc883_capture_source alc882_capture_source
7740
7741
static const struct hda_input_mux alc889_capture_source = {
7742
.num_items = 3,
7743
.items = {
7744
{ "Front Mic", 0x0 },
7745
{ "Mic", 0x3 },
7746
{ "Line", 0x2 },
7747
},
7748
};
7749
7750
static const struct hda_input_mux mb5_capture_source = {
7751
.num_items = 3,
7752
.items = {
7753
{ "Mic", 0x1 },
7754
{ "Line", 0x7 },
7755
{ "CD", 0x4 },
7756
},
7757
};
7758
7759
static const struct hda_input_mux macmini3_capture_source = {
7760
.num_items = 2,
7761
.items = {
7762
{ "Line", 0x2 },
7763
{ "CD", 0x4 },
7764
},
7765
};
7766
7767
static const struct hda_input_mux alc883_3stack_6ch_intel = {
7768
.num_items = 4,
7769
.items = {
7770
{ "Mic", 0x1 },
7771
{ "Front Mic", 0x0 },
7772
{ "Line", 0x2 },
7773
{ "CD", 0x4 },
7774
},
7775
};
7776
7777
static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7778
.num_items = 2,
7779
.items = {
7780
{ "Mic", 0x1 },
7781
{ "Line", 0x2 },
7782
},
7783
};
7784
7785
static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7786
.num_items = 4,
7787
.items = {
7788
{ "Mic", 0x0 },
7789
{ "Internal Mic", 0x1 },
7790
{ "Line", 0x2 },
7791
{ "CD", 0x4 },
7792
},
7793
};
7794
7795
static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7796
.num_items = 2,
7797
.items = {
7798
{ "Mic", 0x0 },
7799
{ "Internal Mic", 0x1 },
7800
},
7801
};
7802
7803
static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7804
.num_items = 3,
7805
.items = {
7806
{ "Mic", 0x0 },
7807
{ "Front Mic", 0x1 },
7808
{ "Line", 0x4 },
7809
},
7810
};
7811
7812
static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7813
.num_items = 2,
7814
.items = {
7815
{ "Mic", 0x0 },
7816
{ "Line", 0x2 },
7817
},
7818
};
7819
7820
static const struct hda_input_mux alc889A_mb31_capture_source = {
7821
.num_items = 2,
7822
.items = {
7823
{ "Mic", 0x0 },
7824
/* Front Mic (0x01) unused */
7825
{ "Line", 0x2 },
7826
/* Line 2 (0x03) unused */
7827
/* CD (0x04) unused? */
7828
},
7829
};
7830
7831
static const struct hda_input_mux alc889A_imac91_capture_source = {
7832
.num_items = 2,
7833
.items = {
7834
{ "Mic", 0x01 },
7835
{ "Line", 0x2 }, /* Not sure! */
7836
},
7837
};
7838
7839
/*
7840
* 2ch mode
7841
*/
7842
static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7843
{ 2, NULL }
7844
};
7845
7846
/*
7847
* 2ch mode
7848
*/
7849
static const struct hda_verb alc882_3ST_ch2_init[] = {
7850
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7851
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7852
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7853
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7854
{ } /* end */
7855
};
7856
7857
/*
7858
* 4ch mode
7859
*/
7860
static const struct hda_verb alc882_3ST_ch4_init[] = {
7861
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7862
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7863
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7864
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7865
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7866
{ } /* end */
7867
};
7868
7869
/*
7870
* 6ch mode
7871
*/
7872
static const struct hda_verb alc882_3ST_ch6_init[] = {
7873
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7874
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7875
{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7876
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7877
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7878
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7879
{ } /* end */
7880
};
7881
7882
static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7883
{ 2, alc882_3ST_ch2_init },
7884
{ 4, alc882_3ST_ch4_init },
7885
{ 6, alc882_3ST_ch6_init },
7886
};
7887
7888
#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7889
7890
/*
7891
* 2ch mode
7892
*/
7893
static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7894
{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7895
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7896
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7897
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7898
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7899
{ } /* end */
7900
};
7901
7902
/*
7903
* 4ch mode
7904
*/
7905
static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7906
{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7908
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7909
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7910
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7911
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7912
{ } /* end */
7913
};
7914
7915
/*
7916
* 6ch mode
7917
*/
7918
static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7919
{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7920
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7921
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7922
{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7923
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7924
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7925
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7926
{ } /* end */
7927
};
7928
7929
static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7930
{ 2, alc883_3ST_ch2_clevo_init },
7931
{ 4, alc883_3ST_ch4_clevo_init },
7932
{ 6, alc883_3ST_ch6_clevo_init },
7933
};
7934
7935
7936
/*
7937
* 6ch mode
7938
*/
7939
static const struct hda_verb alc882_sixstack_ch6_init[] = {
7940
{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7941
{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7942
{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7943
{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7944
{ } /* end */
7945
};
7946
7947
/*
7948
* 8ch mode
7949
*/
7950
static const struct hda_verb alc882_sixstack_ch8_init[] = {
7951
{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7952
{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7953
{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7954
{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7955
{ } /* end */
7956
};
7957
7958
static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7959
{ 6, alc882_sixstack_ch6_init },
7960
{ 8, alc882_sixstack_ch8_init },
7961
};
7962
7963
7964
/* Macbook Air 2,1 */
7965
7966
static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7967
{ 2, NULL },
7968
};
7969
7970
/*
7971
* macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7972
*/
7973
7974
/*
7975
* 2ch mode
7976
*/
7977
static const struct hda_verb alc885_mbp_ch2_init[] = {
7978
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7979
{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7980
{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7981
{ } /* end */
7982
};
7983
7984
/*
7985
* 4ch mode
7986
*/
7987
static const struct hda_verb alc885_mbp_ch4_init[] = {
7988
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7989
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7990
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7991
{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7992
{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7993
{ } /* end */
7994
};
7995
7996
static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7997
{ 2, alc885_mbp_ch2_init },
7998
{ 4, alc885_mbp_ch4_init },
7999
};
8000
8001
/*
8002
* 2ch
8003
* Speakers/Woofer/HP = Front
8004
* LineIn = Input
8005
*/
8006
static const struct hda_verb alc885_mb5_ch2_init[] = {
8007
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8008
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8009
{ } /* end */
8010
};
8011
8012
/*
8013
* 6ch mode
8014
* Speakers/HP = Front
8015
* Woofer = LFE
8016
* LineIn = Surround
8017
*/
8018
static const struct hda_verb alc885_mb5_ch6_init[] = {
8019
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8020
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8021
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8022
{ } /* end */
8023
};
8024
8025
static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
8026
{ 2, alc885_mb5_ch2_init },
8027
{ 6, alc885_mb5_ch6_init },
8028
};
8029
8030
#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
8031
8032
/*
8033
* 2ch mode
8034
*/
8035
static const struct hda_verb alc883_4ST_ch2_init[] = {
8036
{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8037
{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8038
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8039
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8040
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8041
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8042
{ } /* end */
8043
};
8044
8045
/*
8046
* 4ch mode
8047
*/
8048
static const struct hda_verb alc883_4ST_ch4_init[] = {
8049
{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8050
{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8051
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8052
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8053
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8054
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8055
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8056
{ } /* end */
8057
};
8058
8059
/*
8060
* 6ch mode
8061
*/
8062
static const struct hda_verb alc883_4ST_ch6_init[] = {
8063
{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8064
{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8065
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8066
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8067
{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8068
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8069
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8070
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8071
{ } /* end */
8072
};
8073
8074
/*
8075
* 8ch mode
8076
*/
8077
static const struct hda_verb alc883_4ST_ch8_init[] = {
8078
{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8079
{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8080
{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8081
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8082
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8083
{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8084
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8085
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8086
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8087
{ } /* end */
8088
};
8089
8090
static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
8091
{ 2, alc883_4ST_ch2_init },
8092
{ 4, alc883_4ST_ch4_init },
8093
{ 6, alc883_4ST_ch6_init },
8094
{ 8, alc883_4ST_ch8_init },
8095
};
8096
8097
8098
/*
8099
* 2ch mode
8100
*/
8101
static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
8102
{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8103
{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8104
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8105
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8106
{ } /* end */
8107
};
8108
8109
/*
8110
* 4ch mode
8111
*/
8112
static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
8113
{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8114
{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8115
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8116
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8117
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8118
{ } /* end */
8119
};
8120
8121
/*
8122
* 6ch mode
8123
*/
8124
static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
8125
{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8126
{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8127
{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8128
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8129
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8130
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8131
{ } /* end */
8132
};
8133
8134
static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
8135
{ 2, alc883_3ST_ch2_intel_init },
8136
{ 4, alc883_3ST_ch4_intel_init },
8137
{ 6, alc883_3ST_ch6_intel_init },
8138
};
8139
8140
/*
8141
* 2ch mode
8142
*/
8143
static const struct hda_verb alc889_ch2_intel_init[] = {
8144
{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8145
{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8146
{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8147
{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8148
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8149
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8150
{ } /* end */
8151
};
8152
8153
/*
8154
* 6ch mode
8155
*/
8156
static const struct hda_verb alc889_ch6_intel_init[] = {
8157
{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8158
{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8159
{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8160
{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8161
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8162
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8163
{ } /* end */
8164
};
8165
8166
/*
8167
* 8ch mode
8168
*/
8169
static const struct hda_verb alc889_ch8_intel_init[] = {
8170
{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8171
{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8172
{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8173
{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8174
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
8175
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8176
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8177
{ } /* end */
8178
};
8179
8180
static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
8181
{ 2, alc889_ch2_intel_init },
8182
{ 6, alc889_ch6_intel_init },
8183
{ 8, alc889_ch8_intel_init },
8184
};
8185
8186
/*
8187
* 6ch mode
8188
*/
8189
static const struct hda_verb alc883_sixstack_ch6_init[] = {
8190
{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8191
{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8192
{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8193
{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8194
{ } /* end */
8195
};
8196
8197
/*
8198
* 8ch mode
8199
*/
8200
static const struct hda_verb alc883_sixstack_ch8_init[] = {
8201
{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8202
{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8203
{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8204
{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8205
{ } /* end */
8206
};
8207
8208
static const struct hda_channel_mode alc883_sixstack_modes[2] = {
8209
{ 6, alc883_sixstack_ch6_init },
8210
{ 8, alc883_sixstack_ch8_init },
8211
};
8212
8213
8214
/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8215
* Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8216
*/
8217
static const struct snd_kcontrol_new alc882_base_mixer[] = {
8218
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8219
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8220
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8221
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8222
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8223
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8224
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8225
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8226
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8227
HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8228
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8229
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8230
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8231
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8232
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8233
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8234
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8235
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8236
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8237
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8238
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8239
{ } /* end */
8240
};
8241
8242
/* Macbook Air 2,1 same control for HP and internal Speaker */
8243
8244
static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8245
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8246
HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8247
{ }
8248
};
8249
8250
8251
static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8252
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8253
HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8254
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8255
HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8256
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8257
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8258
HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8259
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8260
HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8261
HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8262
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8263
{ } /* end */
8264
};
8265
8266
static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8267
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8268
HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8269
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8270
HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8271
HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8272
HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8273
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8274
HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8275
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8276
HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8277
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8278
HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8279
HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8280
HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8281
{ } /* end */
8282
};
8283
8284
static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8285
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8286
HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8287
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8288
HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8289
HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8290
HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8291
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8292
HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8293
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8294
HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8295
HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8296
{ } /* end */
8297
};
8298
8299
static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8300
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8301
HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8302
{ } /* end */
8303
};
8304
8305
8306
static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8307
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8308
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8309
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8310
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8311
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8312
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8313
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8314
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8315
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8316
{ } /* end */
8317
};
8318
8319
static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8320
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8321
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8322
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8323
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8324
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8325
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8326
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8327
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8328
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8329
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8330
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8331
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8332
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8333
{ } /* end */
8334
};
8335
8336
/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8337
* Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8338
*/
8339
static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8340
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8341
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8342
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8343
HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8344
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8345
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8346
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8347
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8348
HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8349
HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8350
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8351
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8352
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8353
{ } /* end */
8354
};
8355
8356
static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8357
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8358
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8359
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8360
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8361
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8362
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8363
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8364
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8365
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8366
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8367
{ } /* end */
8368
};
8369
8370
static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8371
{
8372
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8373
.name = "Channel Mode",
8374
.info = alc_ch_mode_info,
8375
.get = alc_ch_mode_get,
8376
.put = alc_ch_mode_put,
8377
},
8378
{ } /* end */
8379
};
8380
8381
static const struct hda_verb alc882_base_init_verbs[] = {
8382
/* Front mixer: unmute input/output amp left and right (volume = 0) */
8383
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8384
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8385
/* Rear mixer */
8386
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8387
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8388
/* CLFE mixer */
8389
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8390
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8391
/* Side mixer */
8392
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8393
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8394
8395
/* Front Pin: output 0 (0x0c) */
8396
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8397
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8398
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8399
/* Rear Pin: output 1 (0x0d) */
8400
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8401
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8402
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8403
/* CLFE Pin: output 2 (0x0e) */
8404
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8405
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8406
{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8407
/* Side Pin: output 3 (0x0f) */
8408
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8409
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8410
{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8411
/* Mic (rear) pin: input vref at 80% */
8412
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8413
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8414
/* Front Mic pin: input vref at 80% */
8415
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8416
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8417
/* Line In pin: input */
8418
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8419
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8420
/* Line-2 In: Headphone output (output 0 - 0x0c) */
8421
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8422
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8423
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8424
/* CD pin widget for input */
8425
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8426
8427
/* FIXME: use matrix-type input source selection */
8428
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8429
/* Input mixer2 */
8430
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8431
/* Input mixer3 */
8432
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8433
/* ADC2: mute amp left and right */
8434
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8435
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8436
/* ADC3: mute amp left and right */
8437
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8438
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8439
8440
{ }
8441
};
8442
8443
static const struct hda_verb alc882_adc1_init_verbs[] = {
8444
/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8445
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8446
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8447
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8448
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8449
/* ADC1: mute amp left and right */
8450
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8451
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8452
{ }
8453
};
8454
8455
static const struct hda_verb alc882_eapd_verbs[] = {
8456
/* change to EAPD mode */
8457
{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8458
{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8459
{ }
8460
};
8461
8462
static const struct hda_verb alc889_eapd_verbs[] = {
8463
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8464
{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8465
{ }
8466
};
8467
8468
static const struct hda_verb alc_hp15_unsol_verbs[] = {
8469
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8470
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8471
{}
8472
};
8473
8474
static const struct hda_verb alc885_init_verbs[] = {
8475
/* Front mixer: unmute input/output amp left and right (volume = 0) */
8476
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8477
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8478
/* Rear mixer */
8479
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8480
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8481
/* CLFE mixer */
8482
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8483
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8484
/* Side mixer */
8485
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8486
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8487
8488
/* Front HP Pin: output 0 (0x0c) */
8489
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8490
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8491
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8492
/* Front Pin: output 0 (0x0c) */
8493
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8494
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8495
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8496
/* Rear Pin: output 1 (0x0d) */
8497
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8498
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8499
{0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8500
/* CLFE Pin: output 2 (0x0e) */
8501
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8502
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8503
{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8504
/* Side Pin: output 3 (0x0f) */
8505
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8506
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8507
{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8508
/* Mic (rear) pin: input vref at 80% */
8509
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8510
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8511
/* Front Mic pin: input vref at 80% */
8512
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8513
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8514
/* Line In pin: input */
8515
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8516
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8517
8518
/* Mixer elements: 0x18, , 0x1a, 0x1b */
8519
/* Input mixer1 */
8520
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521
/* Input mixer2 */
8522
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8523
/* Input mixer3 */
8524
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8525
/* ADC2: mute amp left and right */
8526
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8527
/* ADC3: mute amp left and right */
8528
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8529
8530
{ }
8531
};
8532
8533
static const struct hda_verb alc885_init_input_verbs[] = {
8534
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8535
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8536
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8537
{ }
8538
};
8539
8540
8541
/* Unmute Selector 24h and set the default input to front mic */
8542
static const struct hda_verb alc889_init_input_verbs[] = {
8543
{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8544
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8545
{ }
8546
};
8547
8548
8549
#define alc883_init_verbs alc882_base_init_verbs
8550
8551
/* Mac Pro test */
8552
static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8553
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8554
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8555
HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8556
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8557
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8558
/* FIXME: this looks suspicious...
8559
HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8560
HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8561
*/
8562
{ } /* end */
8563
};
8564
8565
static const struct hda_verb alc882_macpro_init_verbs[] = {
8566
/* Front mixer: unmute input/output amp left and right (volume = 0) */
8567
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8568
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8569
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8570
/* Front Pin: output 0 (0x0c) */
8571
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8572
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8573
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8574
/* Front Mic pin: input vref at 80% */
8575
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8576
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8577
/* Speaker: output */
8578
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8579
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8580
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8581
/* Headphone output (output 0 - 0x0c) */
8582
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8583
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8584
{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8585
8586
/* FIXME: use matrix-type input source selection */
8587
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8588
/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8589
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8590
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8591
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8592
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8593
/* Input mixer2 */
8594
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8595
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8596
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8597
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8598
/* Input mixer3 */
8599
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8600
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8601
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8602
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8603
/* ADC1: mute amp left and right */
8604
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8605
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8606
/* ADC2: mute amp left and right */
8607
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8608
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8609
/* ADC3: mute amp left and right */
8610
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8611
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8612
8613
{ }
8614
};
8615
8616
/* Macbook 5,1 */
8617
static const struct hda_verb alc885_mb5_init_verbs[] = {
8618
/* DACs */
8619
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8620
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8621
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8622
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8623
/* Front mixer */
8624
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8625
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8626
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8627
/* Surround mixer */
8628
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8629
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8630
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8631
/* LFE mixer */
8632
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8633
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8634
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8635
/* HP mixer */
8636
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8637
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8638
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8639
/* Front Pin (0x0c) */
8640
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8641
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8642
{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8643
/* LFE Pin (0x0e) */
8644
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8645
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8646
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8647
/* HP Pin (0x0f) */
8648
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8649
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8650
{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8651
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8652
/* Front Mic pin: input vref at 80% */
8653
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8654
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8655
/* Line In pin */
8656
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8657
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8658
8659
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8660
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8661
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8662
{ }
8663
};
8664
8665
/* Macmini 3,1 */
8666
static const struct hda_verb alc885_macmini3_init_verbs[] = {
8667
/* DACs */
8668
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8669
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8670
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8671
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8672
/* Front mixer */
8673
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8674
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8675
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8676
/* Surround mixer */
8677
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8678
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8679
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8680
/* LFE mixer */
8681
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8682
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8683
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8684
/* HP mixer */
8685
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8686
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8687
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8688
/* Front Pin (0x0c) */
8689
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8690
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8691
{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8692
/* LFE Pin (0x0e) */
8693
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8694
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8695
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8696
/* HP Pin (0x0f) */
8697
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8698
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8699
{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8700
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8701
/* Line In pin */
8702
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8703
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8704
8705
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8706
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8707
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8708
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8709
{ }
8710
};
8711
8712
8713
static const struct hda_verb alc885_mba21_init_verbs[] = {
8714
/*Internal and HP Speaker Mixer*/
8715
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8716
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8717
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8718
/*Internal Speaker Pin (0x0c)*/
8719
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8720
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8721
{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8722
/* HP Pin: output 0 (0x0e) */
8723
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8724
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8725
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8726
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8727
/* Line in (is hp when jack connected)*/
8728
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8729
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8730
8731
{ }
8732
};
8733
8734
8735
/* Macbook Pro rev3 */
8736
static const struct hda_verb alc885_mbp3_init_verbs[] = {
8737
/* Front mixer: unmute input/output amp left and right (volume = 0) */
8738
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8739
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8740
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8741
/* Rear mixer */
8742
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8743
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8744
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8745
/* HP mixer */
8746
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8747
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8748
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8749
/* Front Pin: output 0 (0x0c) */
8750
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8751
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8752
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8753
/* HP Pin: output 0 (0x0e) */
8754
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8755
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8756
{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8757
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8758
/* Mic (rear) pin: input vref at 80% */
8759
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8760
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8761
/* Front Mic pin: input vref at 80% */
8762
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8763
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8764
/* Line In pin: use output 1 when in LineOut mode */
8765
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8766
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8767
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8768
8769
/* FIXME: use matrix-type input source selection */
8770
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8771
/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8772
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8773
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8774
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8775
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8776
/* Input mixer2 */
8777
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8778
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8779
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8780
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8781
/* Input mixer3 */
8782
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8783
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8784
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8785
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8786
/* ADC1: mute amp left and right */
8787
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8788
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8789
/* ADC2: mute amp left and right */
8790
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8791
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8792
/* ADC3: mute amp left and right */
8793
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8794
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8795
8796
{ }
8797
};
8798
8799
/* iMac 9,1 */
8800
static const struct hda_verb alc885_imac91_init_verbs[] = {
8801
/* Internal Speaker Pin (0x0c) */
8802
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8803
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8804
{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8805
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8806
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8807
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8808
/* HP Pin: Rear */
8809
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8810
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8811
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8812
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8813
/* Line in Rear */
8814
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8815
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8816
/* Front Mic pin: input vref at 80% */
8817
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8818
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8819
/* Rear mixer */
8820
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8821
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8822
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8823
/* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8824
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8825
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8826
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8827
/* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8828
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8829
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8830
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8831
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8832
/* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8833
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8834
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8835
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8836
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8837
/* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8838
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8839
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8840
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8841
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8842
/* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8843
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8844
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8845
/* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8846
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8847
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8848
/* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8849
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8850
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8851
{ }
8852
};
8853
8854
/* iMac 24 mixer. */
8855
static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8856
HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8857
HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8858
{ } /* end */
8859
};
8860
8861
/* iMac 24 init verbs. */
8862
static const struct hda_verb alc885_imac24_init_verbs[] = {
8863
/* Internal speakers: output 0 (0x0c) */
8864
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8865
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8866
{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8867
/* Internal speakers: output 0 (0x0c) */
8868
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8869
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8870
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8871
/* Headphone: output 0 (0x0c) */
8872
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8873
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8874
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8875
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8876
/* Front Mic: input vref at 80% */
8877
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8878
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8879
{ }
8880
};
8881
8882
/* Toggle speaker-output according to the hp-jack state */
8883
static void alc885_imac24_setup(struct hda_codec *codec)
8884
{
8885
struct alc_spec *spec = codec->spec;
8886
8887
spec->autocfg.hp_pins[0] = 0x14;
8888
spec->autocfg.speaker_pins[0] = 0x18;
8889
spec->autocfg.speaker_pins[1] = 0x1a;
8890
spec->automute = 1;
8891
spec->automute_mode = ALC_AUTOMUTE_AMP;
8892
}
8893
8894
#define alc885_mb5_setup alc885_imac24_setup
8895
#define alc885_macmini3_setup alc885_imac24_setup
8896
8897
/* Macbook Air 2,1 */
8898
static void alc885_mba21_setup(struct hda_codec *codec)
8899
{
8900
struct alc_spec *spec = codec->spec;
8901
8902
spec->autocfg.hp_pins[0] = 0x14;
8903
spec->autocfg.speaker_pins[0] = 0x18;
8904
spec->automute = 1;
8905
spec->automute_mode = ALC_AUTOMUTE_AMP;
8906
}
8907
8908
8909
8910
static void alc885_mbp3_setup(struct hda_codec *codec)
8911
{
8912
struct alc_spec *spec = codec->spec;
8913
8914
spec->autocfg.hp_pins[0] = 0x15;
8915
spec->autocfg.speaker_pins[0] = 0x14;
8916
spec->automute = 1;
8917
spec->automute_mode = ALC_AUTOMUTE_AMP;
8918
}
8919
8920
static void alc885_imac91_setup(struct hda_codec *codec)
8921
{
8922
struct alc_spec *spec = codec->spec;
8923
8924
spec->autocfg.hp_pins[0] = 0x14;
8925
spec->autocfg.speaker_pins[0] = 0x18;
8926
spec->autocfg.speaker_pins[1] = 0x1a;
8927
spec->automute = 1;
8928
spec->automute_mode = ALC_AUTOMUTE_AMP;
8929
}
8930
8931
static const struct hda_verb alc882_targa_verbs[] = {
8932
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8933
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8934
8935
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8936
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8937
8938
{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8939
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8940
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8941
8942
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8943
{ } /* end */
8944
};
8945
8946
/* toggle speaker-output according to the hp-jack state */
8947
static void alc882_targa_automute(struct hda_codec *codec)
8948
{
8949
struct alc_spec *spec = codec->spec;
8950
alc_hp_automute(codec);
8951
snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8952
spec->jack_present ? 1 : 3);
8953
}
8954
8955
static void alc882_targa_setup(struct hda_codec *codec)
8956
{
8957
struct alc_spec *spec = codec->spec;
8958
8959
spec->autocfg.hp_pins[0] = 0x14;
8960
spec->autocfg.speaker_pins[0] = 0x1b;
8961
spec->automute = 1;
8962
spec->automute_mode = ALC_AUTOMUTE_AMP;
8963
}
8964
8965
static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8966
{
8967
if ((res >> 26) == ALC880_HP_EVENT)
8968
alc882_targa_automute(codec);
8969
}
8970
8971
static const struct hda_verb alc882_asus_a7j_verbs[] = {
8972
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8973
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8974
8975
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8976
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8977
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8978
8979
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8980
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8981
{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8982
8983
{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8984
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8985
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8986
{ } /* end */
8987
};
8988
8989
static const struct hda_verb alc882_asus_a7m_verbs[] = {
8990
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8991
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8992
8993
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8994
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8995
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8996
8997
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8998
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8999
{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
9000
9001
{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
9002
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
9003
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
9004
{ } /* end */
9005
};
9006
9007
static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
9008
{
9009
unsigned int gpiostate, gpiomask, gpiodir;
9010
9011
gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
9012
AC_VERB_GET_GPIO_DATA, 0);
9013
9014
if (!muted)
9015
gpiostate |= (1 << pin);
9016
else
9017
gpiostate &= ~(1 << pin);
9018
9019
gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9020
AC_VERB_GET_GPIO_MASK, 0);
9021
gpiomask |= (1 << pin);
9022
9023
gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9024
AC_VERB_GET_GPIO_DIRECTION, 0);
9025
gpiodir |= (1 << pin);
9026
9027
9028
snd_hda_codec_write(codec, codec->afg, 0,
9029
AC_VERB_SET_GPIO_MASK, gpiomask);
9030
snd_hda_codec_write(codec, codec->afg, 0,
9031
AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9032
9033
msleep(1);
9034
9035
snd_hda_codec_write(codec, codec->afg, 0,
9036
AC_VERB_SET_GPIO_DATA, gpiostate);
9037
}
9038
9039
/* set up GPIO at initialization */
9040
static void alc885_macpro_init_hook(struct hda_codec *codec)
9041
{
9042
alc882_gpio_mute(codec, 0, 0);
9043
alc882_gpio_mute(codec, 1, 0);
9044
}
9045
9046
/* set up GPIO and update auto-muting at initialization */
9047
static void alc885_imac24_init_hook(struct hda_codec *codec)
9048
{
9049
alc885_macpro_init_hook(codec);
9050
alc_hp_automute(codec);
9051
}
9052
9053
/*
9054
* generic initialization of ADC, input mixers and output mixers
9055
*/
9056
static const struct hda_verb alc883_auto_init_verbs[] = {
9057
/*
9058
* Unmute ADC0-2 and set the default input to mic-in
9059
*/
9060
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9061
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9062
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9063
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9064
9065
/*
9066
* Set up output mixers (0x0c - 0x0f)
9067
*/
9068
/* set vol=0 to output mixers */
9069
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9070
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9071
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9072
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9073
/* set up input amps for analog loopback */
9074
/* Amp Indices: DAC = 0, mixer = 1 */
9075
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9076
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9077
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9078
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9079
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9080
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9081
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9082
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9083
{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9084
{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9085
9086
/* FIXME: use matrix-type input source selection */
9087
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9088
/* Input mixer2 */
9089
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9090
/* Input mixer3 */
9091
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9092
{ }
9093
};
9094
9095
/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
9096
static const struct hda_verb alc889A_mb31_ch2_init[] = {
9097
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9098
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9099
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9100
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9101
{ } /* end */
9102
};
9103
9104
/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
9105
static const struct hda_verb alc889A_mb31_ch4_init[] = {
9106
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9107
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9108
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9109
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9110
{ } /* end */
9111
};
9112
9113
/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
9114
static const struct hda_verb alc889A_mb31_ch5_init[] = {
9115
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9116
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9117
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9118
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9119
{ } /* end */
9120
};
9121
9122
/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
9123
static const struct hda_verb alc889A_mb31_ch6_init[] = {
9124
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9125
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9126
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9127
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9128
{ } /* end */
9129
};
9130
9131
static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
9132
{ 2, alc889A_mb31_ch2_init },
9133
{ 4, alc889A_mb31_ch4_init },
9134
{ 5, alc889A_mb31_ch5_init },
9135
{ 6, alc889A_mb31_ch6_init },
9136
};
9137
9138
static const struct hda_verb alc883_medion_eapd_verbs[] = {
9139
/* eanable EAPD on medion laptop */
9140
{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9141
{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9142
{ }
9143
};
9144
9145
#define alc883_base_mixer alc882_base_mixer
9146
9147
static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
9148
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9149
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9150
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9151
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9152
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9153
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9154
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9155
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9156
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9157
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9158
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9159
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9160
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9161
{ } /* end */
9162
};
9163
9164
static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
9165
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9166
HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9167
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9168
HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9169
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9170
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9171
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9172
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9173
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9174
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9175
{ } /* end */
9176
};
9177
9178
static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
9179
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9180
HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9181
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9182
HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9183
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9184
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9185
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9186
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9187
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9188
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9189
{ } /* end */
9190
};
9191
9192
static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9193
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9194
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9195
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9196
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9197
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9198
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9199
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9200
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9201
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9202
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9203
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9204
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9205
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9206
{ } /* end */
9207
};
9208
9209
static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9210
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9211
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9212
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9213
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9214
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9215
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9216
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9217
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9218
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9219
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9220
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9221
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9222
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9223
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9224
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9225
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9226
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9227
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9228
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9229
{ } /* end */
9230
};
9231
9232
static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
9233
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9234
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9235
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9236
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9237
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9238
HDA_OUTPUT),
9239
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9240
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9241
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9242
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9243
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9244
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9245
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9246
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9247
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9248
HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9249
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9250
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9251
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9252
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9253
{ } /* end */
9254
};
9255
9256
static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9257
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9258
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9259
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9260
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9261
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9262
HDA_OUTPUT),
9263
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9264
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9265
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9266
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9267
HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9268
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9269
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9270
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9271
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9272
HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9273
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9274
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9275
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9276
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9277
{ } /* end */
9278
};
9279
9280
static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9281
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9282
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9283
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9284
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9285
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9286
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9287
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9288
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9289
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9290
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9291
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9292
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9293
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9294
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9295
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9296
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9297
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9298
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9299
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9300
{ } /* end */
9301
};
9302
9303
static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9304
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9305
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9306
HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9307
HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9308
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9309
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9310
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9311
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9312
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9313
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9314
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9315
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9316
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9317
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9318
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9319
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9320
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9321
{ } /* end */
9322
};
9323
9324
static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9325
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9326
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9327
HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9328
HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9329
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9330
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9331
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9332
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9333
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9334
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9335
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9336
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9337
{ } /* end */
9338
};
9339
9340
static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9341
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9342
HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9343
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9344
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9345
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9346
{ } /* end */
9347
};
9348
9349
static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9350
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9351
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9352
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9353
HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9354
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9355
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9356
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9357
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9358
{ } /* end */
9359
};
9360
9361
static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9362
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9363
HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9364
HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9365
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9366
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9367
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9368
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9369
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9370
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9371
{ } /* end */
9372
};
9373
9374
static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9375
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9376
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9377
HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9378
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9379
HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9380
HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9381
{ } /* end */
9382
};
9383
9384
static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9385
/* Unmute front mixer */
9386
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9387
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9388
9389
/* Set speaker pin to front mixer */
9390
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9391
9392
/* Init headphone pin */
9393
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9394
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9395
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9396
{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9397
9398
{ } /* end */
9399
};
9400
9401
/* toggle speaker-output according to the hp-jack state */
9402
static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9403
{
9404
struct alc_spec *spec = codec->spec;
9405
9406
spec->autocfg.hp_pins[0] = 0x1a;
9407
spec->autocfg.speaker_pins[0] = 0x15;
9408
spec->automute = 1;
9409
spec->automute_mode = ALC_AUTOMUTE_AMP;
9410
}
9411
9412
static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9413
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9414
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9415
HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9416
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9417
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9418
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9419
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9420
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9421
{ } /* end */
9422
};
9423
9424
static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9425
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9426
HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9427
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9428
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9429
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9430
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9431
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9432
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9433
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9434
{ } /* end */
9435
};
9436
9437
static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9438
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9439
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9440
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9441
HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9442
HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9443
0x0d, 1, 0x0, HDA_OUTPUT),
9444
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9445
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9446
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9447
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9448
HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9449
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9450
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9451
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9452
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9453
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9454
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9455
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9456
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9457
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9458
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9459
{ } /* end */
9460
};
9461
9462
static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9463
/* Output mixers */
9464
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9465
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9466
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9467
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9468
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9469
HDA_OUTPUT),
9470
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9471
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9472
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9473
/* Output switches */
9474
HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9475
HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9476
HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9477
/* Boost mixers */
9478
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9479
HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9480
/* Input mixers */
9481
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9482
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9483
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9484
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9485
{ } /* end */
9486
};
9487
9488
static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9489
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9490
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9491
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9492
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9493
HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9494
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9495
{ } /* end */
9496
};
9497
9498
static const struct hda_bind_ctls alc883_bind_cap_vol = {
9499
.ops = &snd_hda_bind_vol,
9500
.values = {
9501
HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9502
HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9503
0
9504
},
9505
};
9506
9507
static const struct hda_bind_ctls alc883_bind_cap_switch = {
9508
.ops = &snd_hda_bind_sw,
9509
.values = {
9510
HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9511
HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9512
0
9513
},
9514
};
9515
9516
static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9517
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9518
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9519
HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9520
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9521
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9522
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9523
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9524
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9525
{ } /* end */
9526
};
9527
9528
static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9529
HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9530
HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9531
{
9532
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9533
/* .name = "Capture Source", */
9534
.name = "Input Source",
9535
.count = 1,
9536
.info = alc_mux_enum_info,
9537
.get = alc_mux_enum_get,
9538
.put = alc_mux_enum_put,
9539
},
9540
{ } /* end */
9541
};
9542
9543
static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9544
{
9545
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9546
.name = "Channel Mode",
9547
.info = alc_ch_mode_info,
9548
.get = alc_ch_mode_get,
9549
.put = alc_ch_mode_put,
9550
},
9551
{ } /* end */
9552
};
9553
9554
/* toggle speaker-output according to the hp-jack state */
9555
static void alc883_mitac_setup(struct hda_codec *codec)
9556
{
9557
struct alc_spec *spec = codec->spec;
9558
9559
spec->autocfg.hp_pins[0] = 0x15;
9560
spec->autocfg.speaker_pins[0] = 0x14;
9561
spec->autocfg.speaker_pins[1] = 0x17;
9562
spec->automute = 1;
9563
spec->automute_mode = ALC_AUTOMUTE_AMP;
9564
}
9565
9566
static const struct hda_verb alc883_mitac_verbs[] = {
9567
/* HP */
9568
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9569
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9570
/* Subwoofer */
9571
{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9572
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9573
9574
/* enable unsolicited event */
9575
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9576
/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9577
9578
{ } /* end */
9579
};
9580
9581
static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9582
/* HP */
9583
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9584
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9585
/* Int speaker */
9586
/*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9587
9588
/* enable unsolicited event */
9589
/*
9590
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9591
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9592
*/
9593
9594
{ } /* end */
9595
};
9596
9597
static const struct hda_verb alc883_clevo_m720_verbs[] = {
9598
/* HP */
9599
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9600
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9601
/* Int speaker */
9602
{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9603
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9604
9605
/* enable unsolicited event */
9606
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9607
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9608
9609
{ } /* end */
9610
};
9611
9612
static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9613
/* HP */
9614
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9615
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9616
/* Subwoofer */
9617
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9618
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9619
9620
/* enable unsolicited event */
9621
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9622
9623
{ } /* end */
9624
};
9625
9626
static const struct hda_verb alc883_targa_verbs[] = {
9627
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9628
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9629
9630
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9631
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9632
9633
/* Connect Line-Out side jack (SPDIF) to Side */
9634
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9635
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9636
{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9637
/* Connect Mic jack to CLFE */
9638
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9639
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9640
{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9641
/* Connect Line-in jack to Surround */
9642
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9643
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9644
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9645
/* Connect HP out jack to Front */
9646
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9647
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9648
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9649
9650
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9651
9652
{ } /* end */
9653
};
9654
9655
static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9656
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9657
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9658
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9659
{ } /* end */
9660
};
9661
9662
static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9663
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9664
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9665
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9666
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9667
{ } /* end */
9668
};
9669
9670
static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9671
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9672
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9673
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9674
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9675
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9676
{ } /* end */
9677
};
9678
9679
static const struct hda_verb alc883_haier_w66_verbs[] = {
9680
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9681
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9682
9683
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9684
9685
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9686
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9687
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9688
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9689
{ } /* end */
9690
};
9691
9692
static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9693
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9694
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9695
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9696
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9697
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9698
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9699
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9700
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9701
{ } /* end */
9702
};
9703
9704
static const struct hda_verb alc888_6st_dell_verbs[] = {
9705
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9706
{ }
9707
};
9708
9709
static const struct hda_verb alc883_vaiott_verbs[] = {
9710
/* HP */
9711
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9712
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9713
9714
/* enable unsolicited event */
9715
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9716
9717
{ } /* end */
9718
};
9719
9720
static void alc888_3st_hp_setup(struct hda_codec *codec)
9721
{
9722
struct alc_spec *spec = codec->spec;
9723
9724
spec->autocfg.hp_pins[0] = 0x1b;
9725
spec->autocfg.speaker_pins[0] = 0x14;
9726
spec->autocfg.speaker_pins[1] = 0x16;
9727
spec->autocfg.speaker_pins[2] = 0x18;
9728
spec->automute = 1;
9729
spec->automute_mode = ALC_AUTOMUTE_AMP;
9730
}
9731
9732
static const struct hda_verb alc888_3st_hp_verbs[] = {
9733
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9734
{0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9735
{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9736
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9737
{ } /* end */
9738
};
9739
9740
/*
9741
* 2ch mode
9742
*/
9743
static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9744
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9745
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9746
{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9747
{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9748
{ } /* end */
9749
};
9750
9751
/*
9752
* 4ch mode
9753
*/
9754
static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9755
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9756
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9757
{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9758
{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9759
{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9760
{ } /* end */
9761
};
9762
9763
/*
9764
* 6ch mode
9765
*/
9766
static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9767
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9768
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9769
{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9770
{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9771
{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9772
{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9773
{ } /* end */
9774
};
9775
9776
static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9777
{ 2, alc888_3st_hp_2ch_init },
9778
{ 4, alc888_3st_hp_4ch_init },
9779
{ 6, alc888_3st_hp_6ch_init },
9780
};
9781
9782
static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9783
{
9784
struct alc_spec *spec = codec->spec;
9785
9786
spec->autocfg.hp_pins[0] = 0x1b;
9787
spec->autocfg.line_out_pins[0] = 0x14;
9788
spec->autocfg.speaker_pins[0] = 0x15;
9789
spec->automute = 1;
9790
spec->automute_mode = ALC_AUTOMUTE_AMP;
9791
}
9792
9793
/* toggle speaker-output according to the hp-jack state */
9794
static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9795
{
9796
struct alc_spec *spec = codec->spec;
9797
9798
spec->autocfg.hp_pins[0] = 0x14;
9799
spec->autocfg.speaker_pins[0] = 0x15;
9800
spec->automute = 1;
9801
spec->automute_mode = ALC_AUTOMUTE_AMP;
9802
}
9803
9804
/* toggle speaker-output according to the hp-jack state */
9805
#define alc883_targa_init_hook alc882_targa_init_hook
9806
#define alc883_targa_unsol_event alc882_targa_unsol_event
9807
9808
static void alc883_clevo_m720_setup(struct hda_codec *codec)
9809
{
9810
struct alc_spec *spec = codec->spec;
9811
9812
spec->autocfg.hp_pins[0] = 0x15;
9813
spec->autocfg.speaker_pins[0] = 0x14;
9814
spec->automute = 1;
9815
spec->automute_mode = ALC_AUTOMUTE_AMP;
9816
}
9817
9818
static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9819
{
9820
alc_hp_automute(codec);
9821
alc88x_simple_mic_automute(codec);
9822
}
9823
9824
static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9825
unsigned int res)
9826
{
9827
switch (res >> 26) {
9828
case ALC880_MIC_EVENT:
9829
alc88x_simple_mic_automute(codec);
9830
break;
9831
default:
9832
alc_sku_unsol_event(codec, res);
9833
break;
9834
}
9835
}
9836
9837
/* toggle speaker-output according to the hp-jack state */
9838
static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9839
{
9840
struct alc_spec *spec = codec->spec;
9841
9842
spec->autocfg.hp_pins[0] = 0x14;
9843
spec->autocfg.speaker_pins[0] = 0x15;
9844
spec->automute = 1;
9845
spec->automute_mode = ALC_AUTOMUTE_AMP;
9846
}
9847
9848
static void alc883_haier_w66_setup(struct hda_codec *codec)
9849
{
9850
struct alc_spec *spec = codec->spec;
9851
9852
spec->autocfg.hp_pins[0] = 0x1b;
9853
spec->autocfg.speaker_pins[0] = 0x14;
9854
spec->automute = 1;
9855
spec->automute_mode = ALC_AUTOMUTE_AMP;
9856
}
9857
9858
static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9859
{
9860
struct alc_spec *spec = codec->spec;
9861
9862
spec->autocfg.hp_pins[0] = 0x1b;
9863
spec->autocfg.line_out_pins[0] = 0x14;
9864
spec->autocfg.speaker_pins[0] = 0x15;
9865
spec->automute = 1;
9866
spec->detect_line = 1;
9867
spec->automute_lines = 1;
9868
spec->automute_mode = ALC_AUTOMUTE_AMP;
9869
}
9870
9871
/* toggle speaker-output according to the hp-jack state */
9872
static void alc883_acer_aspire_setup(struct hda_codec *codec)
9873
{
9874
struct alc_spec *spec = codec->spec;
9875
9876
spec->autocfg.hp_pins[0] = 0x14;
9877
spec->autocfg.speaker_pins[0] = 0x15;
9878
spec->autocfg.speaker_pins[1] = 0x16;
9879
spec->automute = 1;
9880
spec->automute_mode = ALC_AUTOMUTE_AMP;
9881
}
9882
9883
static const struct hda_verb alc883_acer_eapd_verbs[] = {
9884
/* HP Pin: output 0 (0x0c) */
9885
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9886
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9887
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9888
/* Front Pin: output 0 (0x0c) */
9889
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9890
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9891
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9892
{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9893
/* eanable EAPD on medion laptop */
9894
{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9895
{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9896
/* enable unsolicited event */
9897
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9898
{ }
9899
};
9900
9901
static void alc888_6st_dell_setup(struct hda_codec *codec)
9902
{
9903
struct alc_spec *spec = codec->spec;
9904
9905
spec->autocfg.hp_pins[0] = 0x1b;
9906
spec->autocfg.speaker_pins[0] = 0x14;
9907
spec->autocfg.speaker_pins[1] = 0x15;
9908
spec->autocfg.speaker_pins[2] = 0x16;
9909
spec->autocfg.speaker_pins[3] = 0x17;
9910
spec->automute = 1;
9911
spec->automute_mode = ALC_AUTOMUTE_AMP;
9912
}
9913
9914
static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9915
{
9916
struct alc_spec *spec = codec->spec;
9917
9918
spec->autocfg.hp_pins[0] = 0x1b;
9919
spec->autocfg.speaker_pins[0] = 0x14;
9920
spec->autocfg.speaker_pins[1] = 0x15;
9921
spec->autocfg.speaker_pins[2] = 0x16;
9922
spec->autocfg.speaker_pins[3] = 0x17;
9923
spec->autocfg.speaker_pins[4] = 0x1a;
9924
spec->automute = 1;
9925
spec->automute_mode = ALC_AUTOMUTE_AMP;
9926
}
9927
9928
static void alc883_vaiott_setup(struct hda_codec *codec)
9929
{
9930
struct alc_spec *spec = codec->spec;
9931
9932
spec->autocfg.hp_pins[0] = 0x15;
9933
spec->autocfg.speaker_pins[0] = 0x14;
9934
spec->autocfg.speaker_pins[1] = 0x17;
9935
spec->automute = 1;
9936
spec->automute_mode = ALC_AUTOMUTE_AMP;
9937
}
9938
9939
static const struct hda_verb alc888_asus_m90v_verbs[] = {
9940
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9941
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9942
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9943
/* enable unsolicited event */
9944
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9945
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9946
{ } /* end */
9947
};
9948
9949
static void alc883_mode2_setup(struct hda_codec *codec)
9950
{
9951
struct alc_spec *spec = codec->spec;
9952
9953
spec->autocfg.hp_pins[0] = 0x1b;
9954
spec->autocfg.speaker_pins[0] = 0x14;
9955
spec->autocfg.speaker_pins[1] = 0x15;
9956
spec->autocfg.speaker_pins[2] = 0x16;
9957
spec->ext_mic.pin = 0x18;
9958
spec->int_mic.pin = 0x19;
9959
spec->ext_mic.mux_idx = 0;
9960
spec->int_mic.mux_idx = 1;
9961
spec->auto_mic = 1;
9962
spec->automute = 1;
9963
spec->automute_mode = ALC_AUTOMUTE_AMP;
9964
}
9965
9966
static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9967
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9968
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9969
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9970
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9971
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9972
{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9973
{0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9974
/* enable unsolicited event */
9975
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9976
{ } /* end */
9977
};
9978
9979
static void alc883_eee1601_inithook(struct hda_codec *codec)
9980
{
9981
struct alc_spec *spec = codec->spec;
9982
9983
spec->autocfg.hp_pins[0] = 0x14;
9984
spec->autocfg.speaker_pins[0] = 0x1b;
9985
alc_hp_automute(codec);
9986
}
9987
9988
static const struct hda_verb alc889A_mb31_verbs[] = {
9989
/* Init rear pin (used as headphone output) */
9990
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9991
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9992
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9993
/* Init line pin (used as output in 4ch and 6ch mode) */
9994
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9995
/* Init line 2 pin (used as headphone out by default) */
9996
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9997
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9998
{ } /* end */
9999
};
10000
10001
/* Mute speakers according to the headphone jack state */
10002
static void alc889A_mb31_automute(struct hda_codec *codec)
10003
{
10004
unsigned int present;
10005
10006
/* Mute only in 2ch or 4ch mode */
10007
if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
10008
== 0x00) {
10009
present = snd_hda_jack_detect(codec, 0x15);
10010
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10011
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10012
snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10013
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10014
}
10015
}
10016
10017
static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
10018
{
10019
if ((res >> 26) == ALC880_HP_EVENT)
10020
alc889A_mb31_automute(codec);
10021
}
10022
10023
10024
#ifdef CONFIG_SND_HDA_POWER_SAVE
10025
#define alc882_loopbacks alc880_loopbacks
10026
#endif
10027
10028
/* pcm configuration: identical with ALC880 */
10029
#define alc882_pcm_analog_playback alc880_pcm_analog_playback
10030
#define alc882_pcm_analog_capture alc880_pcm_analog_capture
10031
#define alc882_pcm_digital_playback alc880_pcm_digital_playback
10032
#define alc882_pcm_digital_capture alc880_pcm_digital_capture
10033
10034
static const hda_nid_t alc883_slave_dig_outs[] = {
10035
ALC1200_DIGOUT_NID, 0,
10036
};
10037
10038
static const hda_nid_t alc1200_slave_dig_outs[] = {
10039
ALC883_DIGOUT_NID, 0,
10040
};
10041
10042
/*
10043
* configuration and preset
10044
*/
10045
static const char * const alc882_models[ALC882_MODEL_LAST] = {
10046
[ALC882_3ST_DIG] = "3stack-dig",
10047
[ALC882_6ST_DIG] = "6stack-dig",
10048
[ALC882_ARIMA] = "arima",
10049
[ALC882_W2JC] = "w2jc",
10050
[ALC882_TARGA] = "targa",
10051
[ALC882_ASUS_A7J] = "asus-a7j",
10052
[ALC882_ASUS_A7M] = "asus-a7m",
10053
[ALC885_MACPRO] = "macpro",
10054
[ALC885_MB5] = "mb5",
10055
[ALC885_MACMINI3] = "macmini3",
10056
[ALC885_MBA21] = "mba21",
10057
[ALC885_MBP3] = "mbp3",
10058
[ALC885_IMAC24] = "imac24",
10059
[ALC885_IMAC91] = "imac91",
10060
[ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
10061
[ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10062
[ALC883_3ST_6ch] = "3stack-6ch",
10063
[ALC883_6ST_DIG] = "alc883-6stack-dig",
10064
[ALC883_TARGA_DIG] = "targa-dig",
10065
[ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
10066
[ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
10067
[ALC883_ACER] = "acer",
10068
[ALC883_ACER_ASPIRE] = "acer-aspire",
10069
[ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
10070
[ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
10071
[ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
10072
[ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
10073
[ALC883_MEDION] = "medion",
10074
[ALC883_MEDION_WIM2160] = "medion-wim2160",
10075
[ALC883_LAPTOP_EAPD] = "laptop-eapd",
10076
[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
10077
[ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10078
[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
10079
[ALC888_LENOVO_SKY] = "lenovo-sky",
10080
[ALC883_HAIER_W66] = "haier-w66",
10081
[ALC888_3ST_HP] = "3stack-hp",
10082
[ALC888_6ST_DELL] = "6stack-dell",
10083
[ALC883_MITAC] = "mitac",
10084
[ALC883_CLEVO_M540R] = "clevo-m540r",
10085
[ALC883_CLEVO_M720] = "clevo-m720",
10086
[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
10087
[ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
10088
[ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
10089
[ALC889A_INTEL] = "intel-alc889a",
10090
[ALC889_INTEL] = "intel-x58",
10091
[ALC1200_ASUS_P5Q] = "asus-p5q",
10092
[ALC889A_MB31] = "mb31",
10093
[ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
10094
[ALC882_AUTO] = "auto",
10095
};
10096
10097
static const struct snd_pci_quirk alc882_cfg_tbl[] = {
10098
SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10099
10100
SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
10101
SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
10102
SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
10103
SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10104
SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
10105
SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
10106
SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10107
ALC888_ACER_ASPIRE_4930G),
10108
SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
10109
ALC888_ACER_ASPIRE_4930G),
10110
SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10111
ALC888_ACER_ASPIRE_8930G),
10112
SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10113
ALC888_ACER_ASPIRE_8930G),
10114
SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10115
SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
10116
SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
10117
ALC888_ACER_ASPIRE_6530G),
10118
SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
10119
ALC888_ACER_ASPIRE_6530G),
10120
SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10121
ALC888_ACER_ASPIRE_7730G),
10122
/* default Acer -- disabled as it causes more problems.
10123
* model=auto should work fine now
10124
*/
10125
/* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
10126
10127
SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
10128
10129
SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
10130
SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10131
SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
10132
SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
10133
SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
10134
SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
10135
10136
SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10137
SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10138
SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
10139
SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
10140
SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10141
SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10142
SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
10143
SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
10144
SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
10145
SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
10146
SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
10147
10148
SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
10149
SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
10150
SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
10151
SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
10152
SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10153
SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
10154
SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
10155
SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
10156
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
10157
10158
SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
10159
SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
10160
SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
10161
SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
10162
SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
10163
SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
10164
SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
10165
SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
10166
SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
10167
SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
10168
SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10169
SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
10170
SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
10171
SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
10172
SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
10173
SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10174
SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10175
SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
10176
SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
10177
SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
10178
SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10179
SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10180
SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
10181
SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
10182
SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
10183
SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10184
SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
10185
SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
10186
SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
10187
SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
10188
SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
10189
10190
SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
10191
SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
10192
SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10193
SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
10194
SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
10195
SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
10196
SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
10197
/* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
10198
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
10199
SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
10200
ALC883_FUJITSU_PI2515),
10201
SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
10202
ALC888_FUJITSU_XA3530),
10203
SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
10204
SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10205
SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10206
SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10207
SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
10208
SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
10209
SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
10210
SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
10211
10212
SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10213
SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
10214
SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
10215
SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10216
SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10217
SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
10218
SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
10219
10220
{}
10221
};
10222
10223
/* codec SSID table for Intel Mac */
10224
static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
10225
SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10226
SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10227
SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10228
SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10229
SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10230
SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10231
SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
10232
SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
10233
SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
10234
SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
10235
SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
10236
SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10237
SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10238
SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
10239
SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
10240
SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
10241
SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
10242
/* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10243
* so apparently no perfect solution yet
10244
*/
10245
SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
10246
SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
10247
SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
10248
{} /* terminator */
10249
};
10250
10251
static const struct alc_config_preset alc882_presets[] = {
10252
[ALC882_3ST_DIG] = {
10253
.mixers = { alc882_base_mixer },
10254
.init_verbs = { alc882_base_init_verbs,
10255
alc882_adc1_init_verbs },
10256
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10257
.dac_nids = alc882_dac_nids,
10258
.dig_out_nid = ALC882_DIGOUT_NID,
10259
.dig_in_nid = ALC882_DIGIN_NID,
10260
.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10261
.channel_mode = alc882_ch_modes,
10262
.need_dac_fix = 1,
10263
.input_mux = &alc882_capture_source,
10264
},
10265
[ALC882_6ST_DIG] = {
10266
.mixers = { alc882_base_mixer, alc882_chmode_mixer },
10267
.init_verbs = { alc882_base_init_verbs,
10268
alc882_adc1_init_verbs },
10269
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10270
.dac_nids = alc882_dac_nids,
10271
.dig_out_nid = ALC882_DIGOUT_NID,
10272
.dig_in_nid = ALC882_DIGIN_NID,
10273
.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10274
.channel_mode = alc882_sixstack_modes,
10275
.input_mux = &alc882_capture_source,
10276
},
10277
[ALC882_ARIMA] = {
10278
.mixers = { alc882_base_mixer, alc882_chmode_mixer },
10279
.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10280
alc882_eapd_verbs },
10281
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10282
.dac_nids = alc882_dac_nids,
10283
.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10284
.channel_mode = alc882_sixstack_modes,
10285
.input_mux = &alc882_capture_source,
10286
},
10287
[ALC882_W2JC] = {
10288
.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10289
.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10290
alc882_eapd_verbs, alc880_gpio1_init_verbs },
10291
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10292
.dac_nids = alc882_dac_nids,
10293
.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10294
.channel_mode = alc880_threestack_modes,
10295
.need_dac_fix = 1,
10296
.input_mux = &alc882_capture_source,
10297
.dig_out_nid = ALC882_DIGOUT_NID,
10298
},
10299
[ALC885_MBA21] = {
10300
.mixers = { alc885_mba21_mixer },
10301
.init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10302
.num_dacs = 2,
10303
.dac_nids = alc882_dac_nids,
10304
.channel_mode = alc885_mba21_ch_modes,
10305
.num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10306
.input_mux = &alc882_capture_source,
10307
.unsol_event = alc_sku_unsol_event,
10308
.setup = alc885_mba21_setup,
10309
.init_hook = alc_hp_automute,
10310
},
10311
[ALC885_MBP3] = {
10312
.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10313
.init_verbs = { alc885_mbp3_init_verbs,
10314
alc880_gpio1_init_verbs },
10315
.num_dacs = 2,
10316
.dac_nids = alc882_dac_nids,
10317
.hp_nid = 0x04,
10318
.channel_mode = alc885_mbp_4ch_modes,
10319
.num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10320
.input_mux = &alc882_capture_source,
10321
.dig_out_nid = ALC882_DIGOUT_NID,
10322
.dig_in_nid = ALC882_DIGIN_NID,
10323
.unsol_event = alc_sku_unsol_event,
10324
.setup = alc885_mbp3_setup,
10325
.init_hook = alc_hp_automute,
10326
},
10327
[ALC885_MB5] = {
10328
.mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10329
.init_verbs = { alc885_mb5_init_verbs,
10330
alc880_gpio1_init_verbs },
10331
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10332
.dac_nids = alc882_dac_nids,
10333
.channel_mode = alc885_mb5_6ch_modes,
10334
.num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10335
.input_mux = &mb5_capture_source,
10336
.dig_out_nid = ALC882_DIGOUT_NID,
10337
.dig_in_nid = ALC882_DIGIN_NID,
10338
.unsol_event = alc_sku_unsol_event,
10339
.setup = alc885_mb5_setup,
10340
.init_hook = alc_hp_automute,
10341
},
10342
[ALC885_MACMINI3] = {
10343
.mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10344
.init_verbs = { alc885_macmini3_init_verbs,
10345
alc880_gpio1_init_verbs },
10346
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10347
.dac_nids = alc882_dac_nids,
10348
.channel_mode = alc885_macmini3_6ch_modes,
10349
.num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10350
.input_mux = &macmini3_capture_source,
10351
.dig_out_nid = ALC882_DIGOUT_NID,
10352
.dig_in_nid = ALC882_DIGIN_NID,
10353
.unsol_event = alc_sku_unsol_event,
10354
.setup = alc885_macmini3_setup,
10355
.init_hook = alc_hp_automute,
10356
},
10357
[ALC885_MACPRO] = {
10358
.mixers = { alc882_macpro_mixer },
10359
.init_verbs = { alc882_macpro_init_verbs },
10360
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10361
.dac_nids = alc882_dac_nids,
10362
.dig_out_nid = ALC882_DIGOUT_NID,
10363
.dig_in_nid = ALC882_DIGIN_NID,
10364
.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10365
.channel_mode = alc882_ch_modes,
10366
.input_mux = &alc882_capture_source,
10367
.init_hook = alc885_macpro_init_hook,
10368
},
10369
[ALC885_IMAC24] = {
10370
.mixers = { alc885_imac24_mixer },
10371
.init_verbs = { alc885_imac24_init_verbs },
10372
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10373
.dac_nids = alc882_dac_nids,
10374
.dig_out_nid = ALC882_DIGOUT_NID,
10375
.dig_in_nid = ALC882_DIGIN_NID,
10376
.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10377
.channel_mode = alc882_ch_modes,
10378
.input_mux = &alc882_capture_source,
10379
.unsol_event = alc_sku_unsol_event,
10380
.setup = alc885_imac24_setup,
10381
.init_hook = alc885_imac24_init_hook,
10382
},
10383
[ALC885_IMAC91] = {
10384
.mixers = {alc885_imac91_mixer},
10385
.init_verbs = { alc885_imac91_init_verbs,
10386
alc880_gpio1_init_verbs },
10387
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10388
.dac_nids = alc882_dac_nids,
10389
.channel_mode = alc885_mba21_ch_modes,
10390
.num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10391
.input_mux = &alc889A_imac91_capture_source,
10392
.dig_out_nid = ALC882_DIGOUT_NID,
10393
.dig_in_nid = ALC882_DIGIN_NID,
10394
.unsol_event = alc_sku_unsol_event,
10395
.setup = alc885_imac91_setup,
10396
.init_hook = alc_hp_automute,
10397
},
10398
[ALC882_TARGA] = {
10399
.mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10400
.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10401
alc880_gpio3_init_verbs, alc882_targa_verbs},
10402
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10403
.dac_nids = alc882_dac_nids,
10404
.dig_out_nid = ALC882_DIGOUT_NID,
10405
.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10406
.adc_nids = alc882_adc_nids,
10407
.capsrc_nids = alc882_capsrc_nids,
10408
.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10409
.channel_mode = alc882_3ST_6ch_modes,
10410
.need_dac_fix = 1,
10411
.input_mux = &alc882_capture_source,
10412
.unsol_event = alc_sku_unsol_event,
10413
.setup = alc882_targa_setup,
10414
.init_hook = alc882_targa_automute,
10415
},
10416
[ALC882_ASUS_A7J] = {
10417
.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10418
.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10419
alc882_asus_a7j_verbs},
10420
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10421
.dac_nids = alc882_dac_nids,
10422
.dig_out_nid = ALC882_DIGOUT_NID,
10423
.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10424
.adc_nids = alc882_adc_nids,
10425
.capsrc_nids = alc882_capsrc_nids,
10426
.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10427
.channel_mode = alc882_3ST_6ch_modes,
10428
.need_dac_fix = 1,
10429
.input_mux = &alc882_capture_source,
10430
},
10431
[ALC882_ASUS_A7M] = {
10432
.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10433
.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10434
alc882_eapd_verbs, alc880_gpio1_init_verbs,
10435
alc882_asus_a7m_verbs },
10436
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10437
.dac_nids = alc882_dac_nids,
10438
.dig_out_nid = ALC882_DIGOUT_NID,
10439
.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10440
.channel_mode = alc880_threestack_modes,
10441
.need_dac_fix = 1,
10442
.input_mux = &alc882_capture_source,
10443
},
10444
[ALC883_3ST_2ch_DIG] = {
10445
.mixers = { alc883_3ST_2ch_mixer },
10446
.init_verbs = { alc883_init_verbs },
10447
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10448
.dac_nids = alc883_dac_nids,
10449
.dig_out_nid = ALC883_DIGOUT_NID,
10450
.dig_in_nid = ALC883_DIGIN_NID,
10451
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10452
.channel_mode = alc883_3ST_2ch_modes,
10453
.input_mux = &alc883_capture_source,
10454
},
10455
[ALC883_3ST_6ch_DIG] = {
10456
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10457
.init_verbs = { alc883_init_verbs },
10458
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10459
.dac_nids = alc883_dac_nids,
10460
.dig_out_nid = ALC883_DIGOUT_NID,
10461
.dig_in_nid = ALC883_DIGIN_NID,
10462
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10463
.channel_mode = alc883_3ST_6ch_modes,
10464
.need_dac_fix = 1,
10465
.input_mux = &alc883_capture_source,
10466
},
10467
[ALC883_3ST_6ch] = {
10468
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10469
.init_verbs = { alc883_init_verbs },
10470
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10471
.dac_nids = alc883_dac_nids,
10472
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10473
.channel_mode = alc883_3ST_6ch_modes,
10474
.need_dac_fix = 1,
10475
.input_mux = &alc883_capture_source,
10476
},
10477
[ALC883_3ST_6ch_INTEL] = {
10478
.mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10479
.init_verbs = { alc883_init_verbs },
10480
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10481
.dac_nids = alc883_dac_nids,
10482
.dig_out_nid = ALC883_DIGOUT_NID,
10483
.dig_in_nid = ALC883_DIGIN_NID,
10484
.slave_dig_outs = alc883_slave_dig_outs,
10485
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10486
.channel_mode = alc883_3ST_6ch_intel_modes,
10487
.need_dac_fix = 1,
10488
.input_mux = &alc883_3stack_6ch_intel,
10489
},
10490
[ALC889A_INTEL] = {
10491
.mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10492
.init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10493
alc_hp15_unsol_verbs },
10494
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10495
.dac_nids = alc883_dac_nids,
10496
.num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10497
.adc_nids = alc889_adc_nids,
10498
.dig_out_nid = ALC883_DIGOUT_NID,
10499
.dig_in_nid = ALC883_DIGIN_NID,
10500
.slave_dig_outs = alc883_slave_dig_outs,
10501
.num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10502
.channel_mode = alc889_8ch_intel_modes,
10503
.capsrc_nids = alc889_capsrc_nids,
10504
.input_mux = &alc889_capture_source,
10505
.setup = alc889_automute_setup,
10506
.init_hook = alc_hp_automute,
10507
.unsol_event = alc_sku_unsol_event,
10508
.need_dac_fix = 1,
10509
},
10510
[ALC889_INTEL] = {
10511
.mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10512
.init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10513
alc889_eapd_verbs, alc_hp15_unsol_verbs},
10514
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10515
.dac_nids = alc883_dac_nids,
10516
.num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10517
.adc_nids = alc889_adc_nids,
10518
.dig_out_nid = ALC883_DIGOUT_NID,
10519
.dig_in_nid = ALC883_DIGIN_NID,
10520
.slave_dig_outs = alc883_slave_dig_outs,
10521
.num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10522
.channel_mode = alc889_8ch_intel_modes,
10523
.capsrc_nids = alc889_capsrc_nids,
10524
.input_mux = &alc889_capture_source,
10525
.setup = alc889_automute_setup,
10526
.init_hook = alc889_intel_init_hook,
10527
.unsol_event = alc_sku_unsol_event,
10528
.need_dac_fix = 1,
10529
},
10530
[ALC883_6ST_DIG] = {
10531
.mixers = { alc883_base_mixer, alc883_chmode_mixer },
10532
.init_verbs = { alc883_init_verbs },
10533
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10534
.dac_nids = alc883_dac_nids,
10535
.dig_out_nid = ALC883_DIGOUT_NID,
10536
.dig_in_nid = ALC883_DIGIN_NID,
10537
.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10538
.channel_mode = alc883_sixstack_modes,
10539
.input_mux = &alc883_capture_source,
10540
},
10541
[ALC883_TARGA_DIG] = {
10542
.mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10543
.init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10544
alc883_targa_verbs},
10545
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10546
.dac_nids = alc883_dac_nids,
10547
.dig_out_nid = ALC883_DIGOUT_NID,
10548
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10549
.channel_mode = alc883_3ST_6ch_modes,
10550
.need_dac_fix = 1,
10551
.input_mux = &alc883_capture_source,
10552
.unsol_event = alc883_targa_unsol_event,
10553
.setup = alc882_targa_setup,
10554
.init_hook = alc882_targa_automute,
10555
},
10556
[ALC883_TARGA_2ch_DIG] = {
10557
.mixers = { alc883_targa_2ch_mixer},
10558
.init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10559
alc883_targa_verbs},
10560
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10561
.dac_nids = alc883_dac_nids,
10562
.adc_nids = alc883_adc_nids_alt,
10563
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10564
.capsrc_nids = alc883_capsrc_nids,
10565
.dig_out_nid = ALC883_DIGOUT_NID,
10566
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10567
.channel_mode = alc883_3ST_2ch_modes,
10568
.input_mux = &alc883_capture_source,
10569
.unsol_event = alc883_targa_unsol_event,
10570
.setup = alc882_targa_setup,
10571
.init_hook = alc882_targa_automute,
10572
},
10573
[ALC883_TARGA_8ch_DIG] = {
10574
.mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10575
alc883_chmode_mixer },
10576
.init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10577
alc883_targa_verbs },
10578
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10579
.dac_nids = alc883_dac_nids,
10580
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10581
.adc_nids = alc883_adc_nids_rev,
10582
.capsrc_nids = alc883_capsrc_nids_rev,
10583
.dig_out_nid = ALC883_DIGOUT_NID,
10584
.dig_in_nid = ALC883_DIGIN_NID,
10585
.num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10586
.channel_mode = alc883_4ST_8ch_modes,
10587
.need_dac_fix = 1,
10588
.input_mux = &alc883_capture_source,
10589
.unsol_event = alc883_targa_unsol_event,
10590
.setup = alc882_targa_setup,
10591
.init_hook = alc882_targa_automute,
10592
},
10593
[ALC883_ACER] = {
10594
.mixers = { alc883_base_mixer },
10595
/* On TravelMate laptops, GPIO 0 enables the internal speaker
10596
* and the headphone jack. Turn this on and rely on the
10597
* standard mute methods whenever the user wants to turn
10598
* these outputs off.
10599
*/
10600
.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10601
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10602
.dac_nids = alc883_dac_nids,
10603
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10604
.channel_mode = alc883_3ST_2ch_modes,
10605
.input_mux = &alc883_capture_source,
10606
},
10607
[ALC883_ACER_ASPIRE] = {
10608
.mixers = { alc883_acer_aspire_mixer },
10609
.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10610
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10611
.dac_nids = alc883_dac_nids,
10612
.dig_out_nid = ALC883_DIGOUT_NID,
10613
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10614
.channel_mode = alc883_3ST_2ch_modes,
10615
.input_mux = &alc883_capture_source,
10616
.unsol_event = alc_sku_unsol_event,
10617
.setup = alc883_acer_aspire_setup,
10618
.init_hook = alc_hp_automute,
10619
},
10620
[ALC888_ACER_ASPIRE_4930G] = {
10621
.mixers = { alc888_acer_aspire_4930g_mixer,
10622
alc883_chmode_mixer },
10623
.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10624
alc888_acer_aspire_4930g_verbs },
10625
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10626
.dac_nids = alc883_dac_nids,
10627
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10628
.adc_nids = alc883_adc_nids_rev,
10629
.capsrc_nids = alc883_capsrc_nids_rev,
10630
.dig_out_nid = ALC883_DIGOUT_NID,
10631
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10632
.channel_mode = alc883_3ST_6ch_modes,
10633
.need_dac_fix = 1,
10634
.const_channel_count = 6,
10635
.num_mux_defs =
10636
ARRAY_SIZE(alc888_2_capture_sources),
10637
.input_mux = alc888_2_capture_sources,
10638
.unsol_event = alc_sku_unsol_event,
10639
.setup = alc888_acer_aspire_4930g_setup,
10640
.init_hook = alc_hp_automute,
10641
},
10642
[ALC888_ACER_ASPIRE_6530G] = {
10643
.mixers = { alc888_acer_aspire_6530_mixer },
10644
.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10645
alc888_acer_aspire_6530g_verbs },
10646
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10647
.dac_nids = alc883_dac_nids,
10648
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10649
.adc_nids = alc883_adc_nids_rev,
10650
.capsrc_nids = alc883_capsrc_nids_rev,
10651
.dig_out_nid = ALC883_DIGOUT_NID,
10652
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10653
.channel_mode = alc883_3ST_2ch_modes,
10654
.num_mux_defs =
10655
ARRAY_SIZE(alc888_2_capture_sources),
10656
.input_mux = alc888_acer_aspire_6530_sources,
10657
.unsol_event = alc_sku_unsol_event,
10658
.setup = alc888_acer_aspire_6530g_setup,
10659
.init_hook = alc_hp_automute,
10660
},
10661
[ALC888_ACER_ASPIRE_8930G] = {
10662
.mixers = { alc889_acer_aspire_8930g_mixer,
10663
alc883_chmode_mixer },
10664
.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10665
alc889_acer_aspire_8930g_verbs,
10666
alc889_eapd_verbs},
10667
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10668
.dac_nids = alc883_dac_nids,
10669
.num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10670
.adc_nids = alc889_adc_nids,
10671
.capsrc_nids = alc889_capsrc_nids,
10672
.dig_out_nid = ALC883_DIGOUT_NID,
10673
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10674
.channel_mode = alc883_3ST_6ch_modes,
10675
.need_dac_fix = 1,
10676
.const_channel_count = 6,
10677
.num_mux_defs =
10678
ARRAY_SIZE(alc889_capture_sources),
10679
.input_mux = alc889_capture_sources,
10680
.unsol_event = alc_sku_unsol_event,
10681
.setup = alc889_acer_aspire_8930g_setup,
10682
.init_hook = alc_hp_automute,
10683
#ifdef CONFIG_SND_HDA_POWER_SAVE
10684
.power_hook = alc_power_eapd,
10685
#endif
10686
},
10687
[ALC888_ACER_ASPIRE_7730G] = {
10688
.mixers = { alc883_3ST_6ch_mixer,
10689
alc883_chmode_mixer },
10690
.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10691
alc888_acer_aspire_7730G_verbs },
10692
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10693
.dac_nids = alc883_dac_nids,
10694
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10695
.adc_nids = alc883_adc_nids_rev,
10696
.capsrc_nids = alc883_capsrc_nids_rev,
10697
.dig_out_nid = ALC883_DIGOUT_NID,
10698
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10699
.channel_mode = alc883_3ST_6ch_modes,
10700
.need_dac_fix = 1,
10701
.const_channel_count = 6,
10702
.input_mux = &alc883_capture_source,
10703
.unsol_event = alc_sku_unsol_event,
10704
.setup = alc888_acer_aspire_7730g_setup,
10705
.init_hook = alc_hp_automute,
10706
},
10707
[ALC883_MEDION] = {
10708
.mixers = { alc883_fivestack_mixer,
10709
alc883_chmode_mixer },
10710
.init_verbs = { alc883_init_verbs,
10711
alc883_medion_eapd_verbs },
10712
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10713
.dac_nids = alc883_dac_nids,
10714
.adc_nids = alc883_adc_nids_alt,
10715
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10716
.capsrc_nids = alc883_capsrc_nids,
10717
.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10718
.channel_mode = alc883_sixstack_modes,
10719
.input_mux = &alc883_capture_source,
10720
},
10721
[ALC883_MEDION_WIM2160] = {
10722
.mixers = { alc883_medion_wim2160_mixer },
10723
.init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10724
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10725
.dac_nids = alc883_dac_nids,
10726
.dig_out_nid = ALC883_DIGOUT_NID,
10727
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10728
.adc_nids = alc883_adc_nids,
10729
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10730
.channel_mode = alc883_3ST_2ch_modes,
10731
.input_mux = &alc883_capture_source,
10732
.unsol_event = alc_sku_unsol_event,
10733
.setup = alc883_medion_wim2160_setup,
10734
.init_hook = alc_hp_automute,
10735
},
10736
[ALC883_LAPTOP_EAPD] = {
10737
.mixers = { alc883_base_mixer },
10738
.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10739
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10740
.dac_nids = alc883_dac_nids,
10741
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10742
.channel_mode = alc883_3ST_2ch_modes,
10743
.input_mux = &alc883_capture_source,
10744
},
10745
[ALC883_CLEVO_M540R] = {
10746
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10747
.init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10748
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10749
.dac_nids = alc883_dac_nids,
10750
.dig_out_nid = ALC883_DIGOUT_NID,
10751
.dig_in_nid = ALC883_DIGIN_NID,
10752
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10753
.channel_mode = alc883_3ST_6ch_clevo_modes,
10754
.need_dac_fix = 1,
10755
.input_mux = &alc883_capture_source,
10756
/* This machine has the hardware HP auto-muting, thus
10757
* we need no software mute via unsol event
10758
*/
10759
},
10760
[ALC883_CLEVO_M720] = {
10761
.mixers = { alc883_clevo_m720_mixer },
10762
.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10763
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10764
.dac_nids = alc883_dac_nids,
10765
.dig_out_nid = ALC883_DIGOUT_NID,
10766
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10767
.channel_mode = alc883_3ST_2ch_modes,
10768
.input_mux = &alc883_capture_source,
10769
.unsol_event = alc883_clevo_m720_unsol_event,
10770
.setup = alc883_clevo_m720_setup,
10771
.init_hook = alc883_clevo_m720_init_hook,
10772
},
10773
[ALC883_LENOVO_101E_2ch] = {
10774
.mixers = { alc883_lenovo_101e_2ch_mixer},
10775
.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10776
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10777
.dac_nids = alc883_dac_nids,
10778
.adc_nids = alc883_adc_nids_alt,
10779
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10780
.capsrc_nids = alc883_capsrc_nids,
10781
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10782
.channel_mode = alc883_3ST_2ch_modes,
10783
.input_mux = &alc883_lenovo_101e_capture_source,
10784
.setup = alc883_lenovo_101e_setup,
10785
.unsol_event = alc_sku_unsol_event,
10786
.init_hook = alc_inithook,
10787
},
10788
[ALC883_LENOVO_NB0763] = {
10789
.mixers = { alc883_lenovo_nb0763_mixer },
10790
.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10791
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10792
.dac_nids = alc883_dac_nids,
10793
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10794
.channel_mode = alc883_3ST_2ch_modes,
10795
.need_dac_fix = 1,
10796
.input_mux = &alc883_lenovo_nb0763_capture_source,
10797
.unsol_event = alc_sku_unsol_event,
10798
.setup = alc883_lenovo_nb0763_setup,
10799
.init_hook = alc_hp_automute,
10800
},
10801
[ALC888_LENOVO_MS7195_DIG] = {
10802
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10803
.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10804
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10805
.dac_nids = alc883_dac_nids,
10806
.dig_out_nid = ALC883_DIGOUT_NID,
10807
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10808
.channel_mode = alc883_3ST_6ch_modes,
10809
.need_dac_fix = 1,
10810
.input_mux = &alc883_capture_source,
10811
.unsol_event = alc_sku_unsol_event,
10812
.setup = alc888_lenovo_ms7195_setup,
10813
.init_hook = alc_inithook,
10814
},
10815
[ALC883_HAIER_W66] = {
10816
.mixers = { alc883_targa_2ch_mixer},
10817
.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10818
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10819
.dac_nids = alc883_dac_nids,
10820
.dig_out_nid = ALC883_DIGOUT_NID,
10821
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10822
.channel_mode = alc883_3ST_2ch_modes,
10823
.input_mux = &alc883_capture_source,
10824
.unsol_event = alc_sku_unsol_event,
10825
.setup = alc883_haier_w66_setup,
10826
.init_hook = alc_hp_automute,
10827
},
10828
[ALC888_3ST_HP] = {
10829
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10830
.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10831
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10832
.dac_nids = alc883_dac_nids,
10833
.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10834
.channel_mode = alc888_3st_hp_modes,
10835
.need_dac_fix = 1,
10836
.input_mux = &alc883_capture_source,
10837
.unsol_event = alc_sku_unsol_event,
10838
.setup = alc888_3st_hp_setup,
10839
.init_hook = alc_hp_automute,
10840
},
10841
[ALC888_6ST_DELL] = {
10842
.mixers = { alc883_base_mixer, alc883_chmode_mixer },
10843
.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10844
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10845
.dac_nids = alc883_dac_nids,
10846
.dig_out_nid = ALC883_DIGOUT_NID,
10847
.dig_in_nid = ALC883_DIGIN_NID,
10848
.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10849
.channel_mode = alc883_sixstack_modes,
10850
.input_mux = &alc883_capture_source,
10851
.unsol_event = alc_sku_unsol_event,
10852
.setup = alc888_6st_dell_setup,
10853
.init_hook = alc_hp_automute,
10854
},
10855
[ALC883_MITAC] = {
10856
.mixers = { alc883_mitac_mixer },
10857
.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10858
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10859
.dac_nids = alc883_dac_nids,
10860
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10861
.channel_mode = alc883_3ST_2ch_modes,
10862
.input_mux = &alc883_capture_source,
10863
.unsol_event = alc_sku_unsol_event,
10864
.setup = alc883_mitac_setup,
10865
.init_hook = alc_hp_automute,
10866
},
10867
[ALC883_FUJITSU_PI2515] = {
10868
.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10869
.init_verbs = { alc883_init_verbs,
10870
alc883_2ch_fujitsu_pi2515_verbs},
10871
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10872
.dac_nids = alc883_dac_nids,
10873
.dig_out_nid = ALC883_DIGOUT_NID,
10874
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10875
.channel_mode = alc883_3ST_2ch_modes,
10876
.input_mux = &alc883_fujitsu_pi2515_capture_source,
10877
.unsol_event = alc_sku_unsol_event,
10878
.setup = alc883_2ch_fujitsu_pi2515_setup,
10879
.init_hook = alc_hp_automute,
10880
},
10881
[ALC888_FUJITSU_XA3530] = {
10882
.mixers = { alc888_base_mixer, alc883_chmode_mixer },
10883
.init_verbs = { alc883_init_verbs,
10884
alc888_fujitsu_xa3530_verbs },
10885
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10886
.dac_nids = alc883_dac_nids,
10887
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10888
.adc_nids = alc883_adc_nids_rev,
10889
.capsrc_nids = alc883_capsrc_nids_rev,
10890
.dig_out_nid = ALC883_DIGOUT_NID,
10891
.num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10892
.channel_mode = alc888_4ST_8ch_intel_modes,
10893
.num_mux_defs =
10894
ARRAY_SIZE(alc888_2_capture_sources),
10895
.input_mux = alc888_2_capture_sources,
10896
.unsol_event = alc_sku_unsol_event,
10897
.setup = alc888_fujitsu_xa3530_setup,
10898
.init_hook = alc_hp_automute,
10899
},
10900
[ALC888_LENOVO_SKY] = {
10901
.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10902
.init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10903
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10904
.dac_nids = alc883_dac_nids,
10905
.dig_out_nid = ALC883_DIGOUT_NID,
10906
.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10907
.channel_mode = alc883_sixstack_modes,
10908
.need_dac_fix = 1,
10909
.input_mux = &alc883_lenovo_sky_capture_source,
10910
.unsol_event = alc_sku_unsol_event,
10911
.setup = alc888_lenovo_sky_setup,
10912
.init_hook = alc_hp_automute,
10913
},
10914
[ALC888_ASUS_M90V] = {
10915
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10916
.init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10917
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10918
.dac_nids = alc883_dac_nids,
10919
.dig_out_nid = ALC883_DIGOUT_NID,
10920
.dig_in_nid = ALC883_DIGIN_NID,
10921
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10922
.channel_mode = alc883_3ST_6ch_modes,
10923
.need_dac_fix = 1,
10924
.input_mux = &alc883_fujitsu_pi2515_capture_source,
10925
.unsol_event = alc_sku_unsol_event,
10926
.setup = alc883_mode2_setup,
10927
.init_hook = alc_inithook,
10928
},
10929
[ALC888_ASUS_EEE1601] = {
10930
.mixers = { alc883_asus_eee1601_mixer },
10931
.cap_mixer = alc883_asus_eee1601_cap_mixer,
10932
.init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10933
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10934
.dac_nids = alc883_dac_nids,
10935
.dig_out_nid = ALC883_DIGOUT_NID,
10936
.dig_in_nid = ALC883_DIGIN_NID,
10937
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10938
.channel_mode = alc883_3ST_2ch_modes,
10939
.need_dac_fix = 1,
10940
.input_mux = &alc883_asus_eee1601_capture_source,
10941
.unsol_event = alc_sku_unsol_event,
10942
.init_hook = alc883_eee1601_inithook,
10943
},
10944
[ALC1200_ASUS_P5Q] = {
10945
.mixers = { alc883_base_mixer, alc883_chmode_mixer },
10946
.init_verbs = { alc883_init_verbs },
10947
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10948
.dac_nids = alc883_dac_nids,
10949
.dig_out_nid = ALC1200_DIGOUT_NID,
10950
.dig_in_nid = ALC883_DIGIN_NID,
10951
.slave_dig_outs = alc1200_slave_dig_outs,
10952
.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10953
.channel_mode = alc883_sixstack_modes,
10954
.input_mux = &alc883_capture_source,
10955
},
10956
[ALC889A_MB31] = {
10957
.mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10958
.init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10959
alc880_gpio1_init_verbs },
10960
.adc_nids = alc883_adc_nids,
10961
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10962
.capsrc_nids = alc883_capsrc_nids,
10963
.dac_nids = alc883_dac_nids,
10964
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10965
.channel_mode = alc889A_mb31_6ch_modes,
10966
.num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10967
.input_mux = &alc889A_mb31_capture_source,
10968
.dig_out_nid = ALC883_DIGOUT_NID,
10969
.unsol_event = alc889A_mb31_unsol_event,
10970
.init_hook = alc889A_mb31_automute,
10971
},
10972
[ALC883_SONY_VAIO_TT] = {
10973
.mixers = { alc883_vaiott_mixer },
10974
.init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10975
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10976
.dac_nids = alc883_dac_nids,
10977
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10978
.channel_mode = alc883_3ST_2ch_modes,
10979
.input_mux = &alc883_capture_source,
10980
.unsol_event = alc_sku_unsol_event,
10981
.setup = alc883_vaiott_setup,
10982
.init_hook = alc_hp_automute,
10983
},
10984
};
10985
10986
10987
/*
10988
* Pin config fixes
10989
*/
10990
enum {
10991
PINFIX_ABIT_AW9D_MAX,
10992
PINFIX_LENOVO_Y530,
10993
PINFIX_PB_M5210,
10994
PINFIX_ACER_ASPIRE_7736,
10995
};
10996
10997
static const struct alc_fixup alc882_fixups[] = {
10998
[PINFIX_ABIT_AW9D_MAX] = {
10999
.type = ALC_FIXUP_PINS,
11000
.v.pins = (const struct alc_pincfg[]) {
11001
{ 0x15, 0x01080104 }, /* side */
11002
{ 0x16, 0x01011012 }, /* rear */
11003
{ 0x17, 0x01016011 }, /* clfe */
11004
{ }
11005
}
11006
},
11007
[PINFIX_LENOVO_Y530] = {
11008
.type = ALC_FIXUP_PINS,
11009
.v.pins = (const struct alc_pincfg[]) {
11010
{ 0x15, 0x99130112 }, /* rear int speakers */
11011
{ 0x16, 0x99130111 }, /* subwoofer */
11012
{ }
11013
}
11014
},
11015
[PINFIX_PB_M5210] = {
11016
.type = ALC_FIXUP_VERBS,
11017
.v.verbs = (const struct hda_verb[]) {
11018
{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
11019
{}
11020
}
11021
},
11022
[PINFIX_ACER_ASPIRE_7736] = {
11023
.type = ALC_FIXUP_SKU,
11024
.v.sku = ALC_FIXUP_SKU_IGNORE,
11025
},
11026
};
11027
11028
static const struct snd_pci_quirk alc882_fixup_tbl[] = {
11029
SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
11030
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
11031
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
11032
SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
11033
{}
11034
};
11035
11036
/*
11037
* BIOS auto configuration
11038
*/
11039
static int alc882_auto_create_input_ctls(struct hda_codec *codec,
11040
const struct auto_pin_cfg *cfg)
11041
{
11042
return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
11043
}
11044
11045
static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
11046
hda_nid_t nid, int pin_type,
11047
hda_nid_t dac)
11048
{
11049
int idx;
11050
11051
/* set as output */
11052
alc_set_pin_output(codec, nid, pin_type);
11053
11054
if (dac == 0x25)
11055
idx = 4;
11056
else if (dac >= 0x02 && dac <= 0x05)
11057
idx = dac - 2;
11058
else
11059
return;
11060
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
11061
}
11062
11063
static void alc882_auto_init_multi_out(struct hda_codec *codec)
11064
{
11065
struct alc_spec *spec = codec->spec;
11066
int i;
11067
11068
for (i = 0; i <= HDA_SIDE; i++) {
11069
hda_nid_t nid = spec->autocfg.line_out_pins[i];
11070
int pin_type = get_pin_type(spec->autocfg.line_out_type);
11071
if (nid)
11072
alc882_auto_set_output_and_unmute(codec, nid, pin_type,
11073
spec->multiout.dac_nids[i]);
11074
}
11075
}
11076
11077
static void alc882_auto_init_hp_out(struct hda_codec *codec)
11078
{
11079
struct alc_spec *spec = codec->spec;
11080
hda_nid_t pin, dac;
11081
int i;
11082
11083
if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11084
for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11085
pin = spec->autocfg.hp_pins[i];
11086
if (!pin)
11087
break;
11088
dac = spec->multiout.hp_nid;
11089
if (!dac)
11090
dac = spec->multiout.dac_nids[0]; /* to front */
11091
alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11092
}
11093
}
11094
11095
if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11096
for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11097
pin = spec->autocfg.speaker_pins[i];
11098
if (!pin)
11099
break;
11100
dac = spec->multiout.extra_out_nid[0];
11101
if (!dac)
11102
dac = spec->multiout.dac_nids[0]; /* to front */
11103
alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11104
}
11105
}
11106
}
11107
11108
static void alc882_auto_init_analog_input(struct hda_codec *codec)
11109
{
11110
struct alc_spec *spec = codec->spec;
11111
struct auto_pin_cfg *cfg = &spec->autocfg;
11112
int i;
11113
11114
for (i = 0; i < cfg->num_inputs; i++) {
11115
hda_nid_t nid = cfg->inputs[i].pin;
11116
alc_set_input_pin(codec, nid, cfg->inputs[i].type);
11117
if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11118
snd_hda_codec_write(codec, nid, 0,
11119
AC_VERB_SET_AMP_GAIN_MUTE,
11120
AMP_OUT_MUTE);
11121
}
11122
}
11123
11124
static void alc882_auto_init_input_src(struct hda_codec *codec)
11125
{
11126
struct alc_spec *spec = codec->spec;
11127
int c;
11128
11129
for (c = 0; c < spec->num_adc_nids; c++) {
11130
hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11131
hda_nid_t nid = spec->capsrc_nids[c];
11132
unsigned int mux_idx;
11133
const struct hda_input_mux *imux;
11134
int conns, mute, idx, item;
11135
11136
/* mute ADC */
11137
snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11138
AC_VERB_SET_AMP_GAIN_MUTE,
11139
AMP_IN_MUTE(0));
11140
11141
conns = snd_hda_get_connections(codec, nid, conn_list,
11142
ARRAY_SIZE(conn_list));
11143
if (conns < 0)
11144
continue;
11145
mux_idx = c >= spec->num_mux_defs ? 0 : c;
11146
imux = &spec->input_mux[mux_idx];
11147
if (!imux->num_items && mux_idx > 0)
11148
imux = &spec->input_mux[0];
11149
for (idx = 0; idx < conns; idx++) {
11150
/* if the current connection is the selected one,
11151
* unmute it as default - otherwise mute it
11152
*/
11153
mute = AMP_IN_MUTE(idx);
11154
for (item = 0; item < imux->num_items; item++) {
11155
if (imux->items[item].index == idx) {
11156
if (spec->cur_mux[c] == item)
11157
mute = AMP_IN_UNMUTE(idx);
11158
break;
11159
}
11160
}
11161
/* check if we have a selector or mixer
11162
* we could check for the widget type instead, but
11163
* just check for Amp-In presence (in case of mixer
11164
* without amp-in there is something wrong, this
11165
* function shouldn't be used or capsrc nid is wrong)
11166
*/
11167
if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
11168
snd_hda_codec_write(codec, nid, 0,
11169
AC_VERB_SET_AMP_GAIN_MUTE,
11170
mute);
11171
else if (mute != AMP_IN_MUTE(idx))
11172
snd_hda_codec_write(codec, nid, 0,
11173
AC_VERB_SET_CONNECT_SEL,
11174
idx);
11175
}
11176
}
11177
}
11178
11179
/* add mic boosts if needed */
11180
static int alc_auto_add_mic_boost(struct hda_codec *codec)
11181
{
11182
struct alc_spec *spec = codec->spec;
11183
struct auto_pin_cfg *cfg = &spec->autocfg;
11184
int i, err;
11185
int type_idx = 0;
11186
hda_nid_t nid;
11187
const char *prev_label = NULL;
11188
11189
for (i = 0; i < cfg->num_inputs; i++) {
11190
if (cfg->inputs[i].type > AUTO_PIN_MIC)
11191
break;
11192
nid = cfg->inputs[i].pin;
11193
if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
11194
const char *label;
11195
char boost_label[32];
11196
11197
label = hda_get_autocfg_input_label(codec, cfg, i);
11198
if (prev_label && !strcmp(label, prev_label))
11199
type_idx++;
11200
else
11201
type_idx = 0;
11202
prev_label = label;
11203
11204
snprintf(boost_label, sizeof(boost_label),
11205
"%s Boost Volume", label);
11206
err = add_control(spec, ALC_CTL_WIDGET_VOL,
11207
boost_label, type_idx,
11208
HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11209
if (err < 0)
11210
return err;
11211
}
11212
}
11213
return 0;
11214
}
11215
11216
/* almost identical with ALC880 parser... */
11217
static int alc882_parse_auto_config(struct hda_codec *codec)
11218
{
11219
struct alc_spec *spec = codec->spec;
11220
static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
11221
int err;
11222
11223
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11224
alc882_ignore);
11225
if (err < 0)
11226
return err;
11227
if (!spec->autocfg.line_outs)
11228
return 0; /* can't find valid BIOS pin config */
11229
11230
err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11231
if (err < 0)
11232
return err;
11233
err = alc_auto_add_multi_channel_mode(codec);
11234
if (err < 0)
11235
return err;
11236
err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
11237
if (err < 0)
11238
return err;
11239
err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11240
"Headphone");
11241
if (err < 0)
11242
return err;
11243
err = alc880_auto_create_extra_out(spec,
11244
spec->autocfg.speaker_pins[0],
11245
"Speaker");
11246
if (err < 0)
11247
return err;
11248
err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
11249
if (err < 0)
11250
return err;
11251
11252
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11253
11254
alc_auto_parse_digital(codec);
11255
11256
if (spec->kctls.list)
11257
add_mixer(spec, spec->kctls.list);
11258
11259
add_verb(spec, alc883_auto_init_verbs);
11260
/* if ADC 0x07 is available, initialize it, too */
11261
if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
11262
add_verb(spec, alc882_adc1_init_verbs);
11263
11264
spec->num_mux_defs = 1;
11265
spec->input_mux = &spec->private_imux[0];
11266
11267
alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11268
11269
err = alc_auto_add_mic_boost(codec);
11270
if (err < 0)
11271
return err;
11272
11273
return 1; /* config found */
11274
}
11275
11276
/* additional initialization for auto-configuration model */
11277
static void alc882_auto_init(struct hda_codec *codec)
11278
{
11279
struct alc_spec *spec = codec->spec;
11280
alc882_auto_init_multi_out(codec);
11281
alc882_auto_init_hp_out(codec);
11282
alc882_auto_init_analog_input(codec);
11283
alc882_auto_init_input_src(codec);
11284
alc_auto_init_digital(codec);
11285
if (spec->unsol_event)
11286
alc_inithook(codec);
11287
}
11288
11289
static int patch_alc882(struct hda_codec *codec)
11290
{
11291
struct alc_spec *spec;
11292
int err, board_config;
11293
11294
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11295
if (spec == NULL)
11296
return -ENOMEM;
11297
11298
codec->spec = spec;
11299
11300
switch (codec->vendor_id) {
11301
case 0x10ec0882:
11302
case 0x10ec0885:
11303
break;
11304
default:
11305
/* ALC883 and variants */
11306
alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11307
break;
11308
}
11309
11310
board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11311
alc882_models,
11312
alc882_cfg_tbl);
11313
11314
if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11315
board_config = snd_hda_check_board_codec_sid_config(codec,
11316
ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11317
11318
if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
11319
printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11320
codec->chip_name);
11321
board_config = ALC882_AUTO;
11322
}
11323
11324
if (board_config == ALC882_AUTO) {
11325
alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11326
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11327
}
11328
11329
alc_auto_parse_customize_define(codec);
11330
11331
if (board_config == ALC882_AUTO) {
11332
/* automatic parse from the BIOS config */
11333
err = alc882_parse_auto_config(codec);
11334
if (err < 0) {
11335
alc_free(codec);
11336
return err;
11337
} else if (!err) {
11338
printk(KERN_INFO
11339
"hda_codec: Cannot set up configuration "
11340
"from BIOS. Using base mode...\n");
11341
board_config = ALC882_3ST_DIG;
11342
}
11343
}
11344
11345
if (has_cdefine_beep(codec)) {
11346
err = snd_hda_attach_beep_device(codec, 0x1);
11347
if (err < 0) {
11348
alc_free(codec);
11349
return err;
11350
}
11351
}
11352
11353
if (board_config != ALC882_AUTO)
11354
setup_preset(codec, &alc882_presets[board_config]);
11355
11356
spec->stream_analog_playback = &alc882_pcm_analog_playback;
11357
spec->stream_analog_capture = &alc882_pcm_analog_capture;
11358
/* FIXME: setup DAC5 */
11359
/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11360
spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11361
11362
spec->stream_digital_playback = &alc882_pcm_digital_playback;
11363
spec->stream_digital_capture = &alc882_pcm_digital_capture;
11364
11365
if (!spec->adc_nids && spec->input_mux) {
11366
int i, j;
11367
spec->num_adc_nids = 0;
11368
for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11369
const struct hda_input_mux *imux = spec->input_mux;
11370
hda_nid_t cap;
11371
hda_nid_t items[16];
11372
hda_nid_t nid = alc882_adc_nids[i];
11373
unsigned int wcap = get_wcaps(codec, nid);
11374
/* get type */
11375
wcap = get_wcaps_type(wcap);
11376
if (wcap != AC_WID_AUD_IN)
11377
continue;
11378
spec->private_adc_nids[spec->num_adc_nids] = nid;
11379
err = snd_hda_get_connections(codec, nid, &cap, 1);
11380
if (err < 0)
11381
continue;
11382
err = snd_hda_get_connections(codec, cap, items,
11383
ARRAY_SIZE(items));
11384
if (err < 0)
11385
continue;
11386
for (j = 0; j < imux->num_items; j++)
11387
if (imux->items[j].index >= err)
11388
break;
11389
if (j < imux->num_items)
11390
continue;
11391
spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11392
spec->num_adc_nids++;
11393
}
11394
spec->adc_nids = spec->private_adc_nids;
11395
spec->capsrc_nids = spec->private_capsrc_nids;
11396
}
11397
11398
set_capture_mixer(codec);
11399
11400
if (has_cdefine_beep(codec))
11401
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11402
11403
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11404
11405
spec->vmaster_nid = 0x0c;
11406
11407
codec->patch_ops = alc_patch_ops;
11408
if (board_config == ALC882_AUTO)
11409
spec->init_hook = alc882_auto_init;
11410
11411
alc_init_jacks(codec);
11412
#ifdef CONFIG_SND_HDA_POWER_SAVE
11413
if (!spec->loopback.amplist)
11414
spec->loopback.amplist = alc882_loopbacks;
11415
#endif
11416
11417
return 0;
11418
}
11419
11420
11421
/*
11422
* ALC262 support
11423
*/
11424
11425
#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11426
#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11427
11428
#define alc262_dac_nids alc260_dac_nids
11429
#define alc262_adc_nids alc882_adc_nids
11430
#define alc262_adc_nids_alt alc882_adc_nids_alt
11431
#define alc262_capsrc_nids alc882_capsrc_nids
11432
#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11433
11434
#define alc262_modes alc260_modes
11435
#define alc262_capture_source alc882_capture_source
11436
11437
static const hda_nid_t alc262_dmic_adc_nids[1] = {
11438
/* ADC0 */
11439
0x09
11440
};
11441
11442
static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11443
11444
static const struct snd_kcontrol_new alc262_base_mixer[] = {
11445
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11446
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11447
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11448
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11449
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11450
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11451
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11452
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11453
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11454
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11455
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11456
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11457
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11458
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11459
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11460
HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11461
{ } /* end */
11462
};
11463
11464
/* update HP, line and mono-out pins according to the master switch */
11465
#define alc262_hp_master_update alc260_hp_master_update
11466
11467
static void alc262_hp_bpc_setup(struct hda_codec *codec)
11468
{
11469
struct alc_spec *spec = codec->spec;
11470
11471
spec->autocfg.hp_pins[0] = 0x1b;
11472
spec->autocfg.speaker_pins[0] = 0x16;
11473
spec->automute = 1;
11474
spec->automute_mode = ALC_AUTOMUTE_PIN;
11475
}
11476
11477
static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11478
{
11479
struct alc_spec *spec = codec->spec;
11480
11481
spec->autocfg.hp_pins[0] = 0x15;
11482
spec->autocfg.speaker_pins[0] = 0x16;
11483
spec->automute = 1;
11484
spec->automute_mode = ALC_AUTOMUTE_PIN;
11485
}
11486
11487
#define alc262_hp_master_sw_get alc260_hp_master_sw_get
11488
#define alc262_hp_master_sw_put alc260_hp_master_sw_put
11489
11490
#define ALC262_HP_MASTER_SWITCH \
11491
{ \
11492
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11493
.name = "Master Playback Switch", \
11494
.info = snd_ctl_boolean_mono_info, \
11495
.get = alc262_hp_master_sw_get, \
11496
.put = alc262_hp_master_sw_put, \
11497
}, \
11498
{ \
11499
.iface = NID_MAPPING, \
11500
.name = "Master Playback Switch", \
11501
.private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11502
}
11503
11504
11505
static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11506
ALC262_HP_MASTER_SWITCH,
11507
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11508
HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11509
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11510
HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11511
HDA_OUTPUT),
11512
HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11513
HDA_OUTPUT),
11514
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11515
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11516
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11517
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11518
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11519
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11520
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11521
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11522
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11523
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11524
HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11525
HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11526
{ } /* end */
11527
};
11528
11529
static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11530
ALC262_HP_MASTER_SWITCH,
11531
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11532
HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11533
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11534
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11535
HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11536
HDA_OUTPUT),
11537
HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11538
HDA_OUTPUT),
11539
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11540
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11541
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11542
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11543
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11544
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11545
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11546
{ } /* end */
11547
};
11548
11549
static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11550
HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11551
HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11552
HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11553
{ } /* end */
11554
};
11555
11556
/* mute/unmute internal speaker according to the hp jack and mute state */
11557
static void alc262_hp_t5735_setup(struct hda_codec *codec)
11558
{
11559
struct alc_spec *spec = codec->spec;
11560
11561
spec->autocfg.hp_pins[0] = 0x15;
11562
spec->autocfg.speaker_pins[0] = 0x14;
11563
spec->automute = 1;
11564
spec->automute_mode = ALC_AUTOMUTE_PIN;
11565
}
11566
11567
static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11568
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11569
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11570
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11571
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11572
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11573
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11574
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11575
{ } /* end */
11576
};
11577
11578
static const struct hda_verb alc262_hp_t5735_verbs[] = {
11579
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11580
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11581
11582
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11583
{ }
11584
};
11585
11586
static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11587
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11588
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11589
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11590
HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11591
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11592
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11593
{ } /* end */
11594
};
11595
11596
static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11597
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11598
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11599
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11600
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11601
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11602
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11603
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11604
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11605
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11606
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11607
{}
11608
};
11609
11610
static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11611
.num_items = 1,
11612
.items = {
11613
{ "Line", 0x1 },
11614
},
11615
};
11616
11617
/* bind hp and internal speaker mute (with plug check) as master switch */
11618
#define alc262_hippo_master_update alc262_hp_master_update
11619
#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11620
#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11621
11622
#define ALC262_HIPPO_MASTER_SWITCH \
11623
{ \
11624
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11625
.name = "Master Playback Switch", \
11626
.info = snd_ctl_boolean_mono_info, \
11627
.get = alc262_hippo_master_sw_get, \
11628
.put = alc262_hippo_master_sw_put, \
11629
}, \
11630
{ \
11631
.iface = NID_MAPPING, \
11632
.name = "Master Playback Switch", \
11633
.subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11634
(SUBDEV_SPEAKER(0) << 16), \
11635
}
11636
11637
static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11638
ALC262_HIPPO_MASTER_SWITCH,
11639
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11640
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11641
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11642
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11643
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11644
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11645
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11646
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11647
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11648
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11649
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11650
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11651
{ } /* end */
11652
};
11653
11654
static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11655
HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11656
ALC262_HIPPO_MASTER_SWITCH,
11657
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11658
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11659
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11660
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11661
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11662
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11663
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11664
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11665
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11666
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11667
{ } /* end */
11668
};
11669
11670
/* mute/unmute internal speaker according to the hp jack and mute state */
11671
static void alc262_hippo_setup(struct hda_codec *codec)
11672
{
11673
struct alc_spec *spec = codec->spec;
11674
11675
spec->autocfg.hp_pins[0] = 0x15;
11676
spec->autocfg.speaker_pins[0] = 0x14;
11677
spec->automute = 1;
11678
spec->automute_mode = ALC_AUTOMUTE_AMP;
11679
}
11680
11681
static void alc262_hippo1_setup(struct hda_codec *codec)
11682
{
11683
struct alc_spec *spec = codec->spec;
11684
11685
spec->autocfg.hp_pins[0] = 0x1b;
11686
spec->autocfg.speaker_pins[0] = 0x14;
11687
spec->automute = 1;
11688
spec->automute_mode = ALC_AUTOMUTE_AMP;
11689
}
11690
11691
11692
static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11693
HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11694
ALC262_HIPPO_MASTER_SWITCH,
11695
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11696
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11697
HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11698
HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11699
{ } /* end */
11700
};
11701
11702
static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11703
HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11704
ALC262_HIPPO_MASTER_SWITCH,
11705
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11706
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11707
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11708
HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11709
HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11710
{ } /* end */
11711
};
11712
11713
static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11714
HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11715
HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11716
HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11717
HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11718
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11719
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11720
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11721
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11722
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11723
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11724
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11725
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11726
{ } /* end */
11727
};
11728
11729
static const struct hda_verb alc262_tyan_verbs[] = {
11730
/* Headphone automute */
11731
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11732
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11733
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11734
11735
/* P11 AUX_IN, white 4-pin connector */
11736
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11737
{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11738
{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11739
{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11740
11741
{}
11742
};
11743
11744
/* unsolicited event for HP jack sensing */
11745
static void alc262_tyan_setup(struct hda_codec *codec)
11746
{
11747
struct alc_spec *spec = codec->spec;
11748
11749
spec->autocfg.hp_pins[0] = 0x1b;
11750
spec->autocfg.speaker_pins[0] = 0x15;
11751
spec->automute = 1;
11752
spec->automute_mode = ALC_AUTOMUTE_AMP;
11753
}
11754
11755
11756
#define alc262_capture_mixer alc882_capture_mixer
11757
#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11758
11759
/*
11760
* generic initialization of ADC, input mixers and output mixers
11761
*/
11762
static const struct hda_verb alc262_init_verbs[] = {
11763
/*
11764
* Unmute ADC0-2 and set the default input to mic-in
11765
*/
11766
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11767
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11768
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11769
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11770
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11771
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11772
11773
/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11774
* mixer widget
11775
* Note: PASD motherboards uses the Line In 2 as the input for
11776
* front panel mic (mic 2)
11777
*/
11778
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11779
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11780
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11781
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11782
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11783
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11784
11785
/*
11786
* Set up output mixers (0x0c - 0x0e)
11787
*/
11788
/* set vol=0 to output mixers */
11789
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11790
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11791
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11792
/* set up input amps for analog loopback */
11793
/* Amp Indices: DAC = 0, mixer = 1 */
11794
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11795
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11796
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11797
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11798
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11799
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11800
11801
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11802
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11803
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11804
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11805
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11806
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11807
11808
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11809
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11810
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11811
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11812
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11813
11814
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11815
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11816
11817
/* FIXME: use matrix-type input source selection */
11818
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11819
/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11820
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11821
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11822
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11823
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11824
/* Input mixer2 */
11825
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11826
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11827
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11828
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11829
/* Input mixer3 */
11830
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11831
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11832
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11833
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11834
11835
{ }
11836
};
11837
11838
static const struct hda_verb alc262_eapd_verbs[] = {
11839
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11840
{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11841
{ }
11842
};
11843
11844
static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11845
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11846
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11847
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11848
11849
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11850
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11851
{}
11852
};
11853
11854
static const struct hda_verb alc262_sony_unsol_verbs[] = {
11855
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11856
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11857
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11858
11859
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11860
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11861
{}
11862
};
11863
11864
static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11865
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11866
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11867
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11868
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11869
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11870
{ } /* end */
11871
};
11872
11873
static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11874
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11875
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11876
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11877
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11878
{0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11879
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11880
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11881
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11882
{}
11883
};
11884
11885
static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11886
{
11887
struct alc_spec *spec = codec->spec;
11888
11889
spec->autocfg.hp_pins[0] = 0x15;
11890
spec->autocfg.speaker_pins[0] = 0x14;
11891
spec->ext_mic.pin = 0x18;
11892
spec->ext_mic.mux_idx = 0;
11893
spec->int_mic.pin = 0x12;
11894
spec->int_mic.mux_idx = 9;
11895
spec->auto_mic = 1;
11896
spec->automute = 1;
11897
spec->automute_mode = ALC_AUTOMUTE_PIN;
11898
}
11899
11900
/*
11901
* nec model
11902
* 0x15 = headphone
11903
* 0x16 = internal speaker
11904
* 0x18 = external mic
11905
*/
11906
11907
static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11908
HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11909
HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11910
11911
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11912
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11913
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11914
11915
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11916
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11917
{ } /* end */
11918
};
11919
11920
static const struct hda_verb alc262_nec_verbs[] = {
11921
/* Unmute Speaker */
11922
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11923
11924
/* Headphone */
11925
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11926
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11927
11928
/* External mic to headphone */
11929
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11930
/* External mic to speaker */
11931
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11932
{}
11933
};
11934
11935
/*
11936
* fujitsu model
11937
* 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11938
* 0x1b = port replicator headphone out
11939
*/
11940
11941
#define ALC_HP_EVENT ALC880_HP_EVENT
11942
11943
static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11944
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11945
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11946
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11947
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11948
{}
11949
};
11950
11951
static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11952
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11953
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11954
{}
11955
};
11956
11957
static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11958
/* Front Mic pin: input vref at 50% */
11959
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11960
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11961
{}
11962
};
11963
11964
static const struct hda_input_mux alc262_fujitsu_capture_source = {
11965
.num_items = 3,
11966
.items = {
11967
{ "Mic", 0x0 },
11968
{ "Internal Mic", 0x1 },
11969
{ "CD", 0x4 },
11970
},
11971
};
11972
11973
static const struct hda_input_mux alc262_HP_capture_source = {
11974
.num_items = 5,
11975
.items = {
11976
{ "Mic", 0x0 },
11977
{ "Front Mic", 0x1 },
11978
{ "Line", 0x2 },
11979
{ "CD", 0x4 },
11980
{ "AUX IN", 0x6 },
11981
},
11982
};
11983
11984
static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11985
.num_items = 4,
11986
.items = {
11987
{ "Mic", 0x0 },
11988
{ "Front Mic", 0x2 },
11989
{ "Line", 0x1 },
11990
{ "CD", 0x4 },
11991
},
11992
};
11993
11994
static void alc262_fujitsu_setup(struct hda_codec *codec)
11995
{
11996
struct alc_spec *spec = codec->spec;
11997
11998
spec->autocfg.hp_pins[0] = 0x14;
11999
spec->autocfg.hp_pins[1] = 0x1b;
12000
spec->autocfg.speaker_pins[0] = 0x15;
12001
spec->automute = 1;
12002
spec->automute_mode = ALC_AUTOMUTE_AMP;
12003
}
12004
12005
/* bind volumes of both NID 0x0c and 0x0d */
12006
static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
12007
.ops = &snd_hda_bind_vol,
12008
.values = {
12009
HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
12010
HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
12011
0
12012
},
12013
};
12014
12015
static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
12016
HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12017
{
12018
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12019
.name = "Master Playback Switch",
12020
.subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12021
.info = snd_ctl_boolean_mono_info,
12022
.get = alc262_hp_master_sw_get,
12023
.put = alc262_hp_master_sw_put,
12024
},
12025
{
12026
.iface = NID_MAPPING,
12027
.name = "Master Playback Switch",
12028
.private_value = 0x1b,
12029
},
12030
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12031
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12032
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12033
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12034
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12035
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12036
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12037
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12038
{ } /* end */
12039
};
12040
12041
static void alc262_lenovo_3000_setup(struct hda_codec *codec)
12042
{
12043
struct alc_spec *spec = codec->spec;
12044
12045
spec->autocfg.hp_pins[0] = 0x1b;
12046
spec->autocfg.speaker_pins[0] = 0x14;
12047
spec->autocfg.speaker_pins[1] = 0x16;
12048
spec->automute = 1;
12049
spec->automute_mode = ALC_AUTOMUTE_AMP;
12050
}
12051
12052
static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
12053
HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12054
{
12055
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12056
.name = "Master Playback Switch",
12057
.subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
12058
.info = snd_ctl_boolean_mono_info,
12059
.get = alc262_hp_master_sw_get,
12060
.put = alc262_hp_master_sw_put,
12061
},
12062
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12063
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12064
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12065
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12066
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12067
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12068
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12069
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12070
{ } /* end */
12071
};
12072
12073
static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
12074
HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12075
ALC262_HIPPO_MASTER_SWITCH,
12076
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12077
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12078
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12079
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12080
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12081
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12082
{ } /* end */
12083
};
12084
12085
/* additional init verbs for Benq laptops */
12086
static const struct hda_verb alc262_EAPD_verbs[] = {
12087
{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12088
{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12089
{}
12090
};
12091
12092
static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
12093
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12094
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12095
12096
{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12097
{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12098
{}
12099
};
12100
12101
/* Samsung Q1 Ultra Vista model setup */
12102
static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
12103
HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12104
HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
12105
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12106
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12107
HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12108
HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
12109
{ } /* end */
12110
};
12111
12112
static const struct hda_verb alc262_ultra_verbs[] = {
12113
/* output mixer */
12114
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12115
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12116
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12117
/* speaker */
12118
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12119
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12120
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12121
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12122
/* HP */
12123
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12124
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12125
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12126
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12127
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12128
/* internal mic */
12129
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12130
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12131
/* ADC, choose mic */
12132
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12133
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12134
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12135
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12136
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12137
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12138
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12139
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12140
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12141
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12142
{}
12143
};
12144
12145
/* mute/unmute internal speaker according to the hp jack and mute state */
12146
static void alc262_ultra_automute(struct hda_codec *codec)
12147
{
12148
struct alc_spec *spec = codec->spec;
12149
unsigned int mute;
12150
12151
mute = 0;
12152
/* auto-mute only when HP is used as HP */
12153
if (!spec->cur_mux[0]) {
12154
spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12155
if (spec->jack_present)
12156
mute = HDA_AMP_MUTE;
12157
}
12158
/* mute/unmute internal speaker */
12159
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12160
HDA_AMP_MUTE, mute);
12161
/* mute/unmute HP */
12162
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12163
HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12164
}
12165
12166
/* unsolicited event for HP jack sensing */
12167
static void alc262_ultra_unsol_event(struct hda_codec *codec,
12168
unsigned int res)
12169
{
12170
if ((res >> 26) != ALC880_HP_EVENT)
12171
return;
12172
alc262_ultra_automute(codec);
12173
}
12174
12175
static const struct hda_input_mux alc262_ultra_capture_source = {
12176
.num_items = 2,
12177
.items = {
12178
{ "Mic", 0x1 },
12179
{ "Headphone", 0x7 },
12180
},
12181
};
12182
12183
static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12184
struct snd_ctl_elem_value *ucontrol)
12185
{
12186
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12187
struct alc_spec *spec = codec->spec;
12188
int ret;
12189
12190
ret = alc_mux_enum_put(kcontrol, ucontrol);
12191
if (!ret)
12192
return 0;
12193
/* reprogram the HP pin as mic or HP according to the input source */
12194
snd_hda_codec_write_cache(codec, 0x15, 0,
12195
AC_VERB_SET_PIN_WIDGET_CONTROL,
12196
spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12197
alc262_ultra_automute(codec); /* mute/unmute HP */
12198
return ret;
12199
}
12200
12201
static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12202
HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12203
HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12204
{
12205
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12206
.name = "Capture Source",
12207
.info = alc_mux_enum_info,
12208
.get = alc_mux_enum_get,
12209
.put = alc262_ultra_mux_enum_put,
12210
},
12211
{
12212
.iface = NID_MAPPING,
12213
.name = "Capture Source",
12214
.private_value = 0x15,
12215
},
12216
{ } /* end */
12217
};
12218
12219
/* We use two mixers depending on the output pin; 0x16 is a mono output
12220
* and thus it's bound with a different mixer.
12221
* This function returns which mixer amp should be used.
12222
*/
12223
static int alc262_check_volbit(hda_nid_t nid)
12224
{
12225
if (!nid)
12226
return 0;
12227
else if (nid == 0x16)
12228
return 2;
12229
else
12230
return 1;
12231
}
12232
12233
static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12234
const char *pfx, int *vbits, int idx)
12235
{
12236
unsigned long val;
12237
int vbit;
12238
12239
vbit = alc262_check_volbit(nid);
12240
if (!vbit)
12241
return 0;
12242
if (*vbits & vbit) /* a volume control for this mixer already there */
12243
return 0;
12244
*vbits |= vbit;
12245
if (vbit == 2)
12246
val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12247
else
12248
val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12249
return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12250
}
12251
12252
static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12253
const char *pfx, int idx)
12254
{
12255
unsigned long val;
12256
12257
if (!nid)
12258
return 0;
12259
if (nid == 0x16)
12260
val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12261
else
12262
val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12263
return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12264
}
12265
12266
/* add playback controls from the parsed DAC table */
12267
static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12268
const struct auto_pin_cfg *cfg)
12269
{
12270
const char *pfx;
12271
int vbits;
12272
int i, err;
12273
12274
spec->multiout.num_dacs = 1; /* only use one dac */
12275
spec->multiout.dac_nids = spec->private_dac_nids;
12276
spec->private_dac_nids[0] = 2;
12277
12278
pfx = alc_get_line_out_pfx(spec, true);
12279
if (!pfx)
12280
pfx = "Front";
12281
for (i = 0; i < 2; i++) {
12282
err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12283
if (err < 0)
12284
return err;
12285
if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12286
err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12287
"Speaker", i);
12288
if (err < 0)
12289
return err;
12290
}
12291
if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12292
err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12293
"Headphone", i);
12294
if (err < 0)
12295
return err;
12296
}
12297
}
12298
12299
vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12300
alc262_check_volbit(cfg->speaker_pins[0]) |
12301
alc262_check_volbit(cfg->hp_pins[0]);
12302
if (vbits == 1 || vbits == 2)
12303
pfx = "Master"; /* only one mixer is used */
12304
vbits = 0;
12305
for (i = 0; i < 2; i++) {
12306
err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12307
&vbits, i);
12308
if (err < 0)
12309
return err;
12310
if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12311
err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12312
"Speaker", &vbits, i);
12313
if (err < 0)
12314
return err;
12315
}
12316
if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12317
err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12318
"Headphone", &vbits, i);
12319
if (err < 0)
12320
return err;
12321
}
12322
}
12323
return 0;
12324
}
12325
12326
#define alc262_auto_create_input_ctls \
12327
alc882_auto_create_input_ctls
12328
12329
/*
12330
* generic initialization of ADC, input mixers and output mixers
12331
*/
12332
static const struct hda_verb alc262_volume_init_verbs[] = {
12333
/*
12334
* Unmute ADC0-2 and set the default input to mic-in
12335
*/
12336
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12337
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12338
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12339
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12340
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12341
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12342
12343
/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12344
* mixer widget
12345
* Note: PASD motherboards uses the Line In 2 as the input for
12346
* front panel mic (mic 2)
12347
*/
12348
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12349
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12350
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12351
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12352
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12353
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12354
12355
/*
12356
* Set up output mixers (0x0c - 0x0f)
12357
*/
12358
/* set vol=0 to output mixers */
12359
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12360
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12361
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12362
12363
/* set up input amps for analog loopback */
12364
/* Amp Indices: DAC = 0, mixer = 1 */
12365
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12366
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12367
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12368
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12369
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12370
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12371
12372
/* FIXME: use matrix-type input source selection */
12373
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12374
/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12375
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12376
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12377
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12378
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12379
/* Input mixer2 */
12380
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12381
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12382
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12383
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12384
/* Input mixer3 */
12385
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12386
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12387
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12388
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12389
12390
{ }
12391
};
12392
12393
static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
12394
/*
12395
* Unmute ADC0-2 and set the default input to mic-in
12396
*/
12397
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12398
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12399
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12400
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12401
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12402
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12403
12404
/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12405
* mixer widget
12406
* Note: PASD motherboards uses the Line In 2 as the input for
12407
* front panel mic (mic 2)
12408
*/
12409
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12410
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12411
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12412
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12413
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12414
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12415
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12416
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12417
12418
/*
12419
* Set up output mixers (0x0c - 0x0e)
12420
*/
12421
/* set vol=0 to output mixers */
12422
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12423
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12424
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12425
12426
/* set up input amps for analog loopback */
12427
/* Amp Indices: DAC = 0, mixer = 1 */
12428
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12429
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12430
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12431
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12432
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12433
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12434
12435
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12436
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12437
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12438
12439
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12440
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12441
12442
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12443
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12444
12445
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12446
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12447
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12448
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12449
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12450
12451
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12452
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12453
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12454
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12455
{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12456
{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12457
12458
12459
/* FIXME: use matrix-type input source selection */
12460
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12461
/* Input mixer1: only unmute Mic */
12462
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12463
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12464
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12465
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12466
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12467
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12468
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12469
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12470
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12471
/* Input mixer2 */
12472
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12473
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12474
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12475
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12476
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12477
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12478
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12479
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12480
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12481
/* Input mixer3 */
12482
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12483
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12484
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12485
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12486
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12487
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12488
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12489
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12490
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12491
12492
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12493
12494
{ }
12495
};
12496
12497
static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12498
/*
12499
* Unmute ADC0-2 and set the default input to mic-in
12500
*/
12501
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12502
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12503
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12504
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12505
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12506
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12507
12508
/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12509
* mixer widget
12510
* Note: PASD motherboards uses the Line In 2 as the input for front
12511
* panel mic (mic 2)
12512
*/
12513
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12514
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12515
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12516
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12517
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12518
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12519
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12520
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12521
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12522
/*
12523
* Set up output mixers (0x0c - 0x0e)
12524
*/
12525
/* set vol=0 to output mixers */
12526
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12527
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12528
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12529
12530
/* set up input amps for analog loopback */
12531
/* Amp Indices: DAC = 0, mixer = 1 */
12532
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12533
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12534
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12535
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12536
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12537
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12538
12539
12540
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12541
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12542
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12543
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12544
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12545
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12546
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12547
12548
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12549
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12550
12551
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12552
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12553
12554
/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12555
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12556
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12557
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12558
{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12559
{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12560
12561
/* FIXME: use matrix-type input source selection */
12562
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12563
/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12564
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12565
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12566
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12567
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12568
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12569
/* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12570
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12571
/* Input mixer2 */
12572
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12573
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12574
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12575
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12576
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12577
/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12578
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12579
/* Input mixer3 */
12580
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12581
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12582
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12583
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12584
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12585
/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12586
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12587
12588
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12589
12590
{ }
12591
};
12592
12593
static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12594
12595
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12596
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12597
{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12598
12599
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12600
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12601
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12602
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12603
12604
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12605
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12606
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12607
{}
12608
};
12609
12610
/*
12611
* Pin config fixes
12612
*/
12613
enum {
12614
PINFIX_FSC_H270,
12615
PINFIX_HP_Z200,
12616
};
12617
12618
static const struct alc_fixup alc262_fixups[] = {
12619
[PINFIX_FSC_H270] = {
12620
.type = ALC_FIXUP_PINS,
12621
.v.pins = (const struct alc_pincfg[]) {
12622
{ 0x14, 0x99130110 }, /* speaker */
12623
{ 0x15, 0x0221142f }, /* front HP */
12624
{ 0x1b, 0x0121141f }, /* rear HP */
12625
{ }
12626
}
12627
},
12628
[PINFIX_HP_Z200] = {
12629
.type = ALC_FIXUP_PINS,
12630
.v.pins = (const struct alc_pincfg[]) {
12631
{ 0x16, 0x99130120 }, /* internal speaker */
12632
{ }
12633
}
12634
},
12635
};
12636
12637
static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12638
SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
12639
SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12640
{}
12641
};
12642
12643
12644
#ifdef CONFIG_SND_HDA_POWER_SAVE
12645
#define alc262_loopbacks alc880_loopbacks
12646
#endif
12647
12648
/* pcm configuration: identical with ALC880 */
12649
#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12650
#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12651
#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12652
#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12653
12654
/*
12655
* BIOS auto configuration
12656
*/
12657
static int alc262_parse_auto_config(struct hda_codec *codec)
12658
{
12659
struct alc_spec *spec = codec->spec;
12660
int err;
12661
static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12662
12663
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12664
alc262_ignore);
12665
if (err < 0)
12666
return err;
12667
if (!spec->autocfg.line_outs) {
12668
if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12669
spec->multiout.max_channels = 2;
12670
spec->no_analog = 1;
12671
goto dig_only;
12672
}
12673
return 0; /* can't find valid BIOS pin config */
12674
}
12675
err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12676
if (err < 0)
12677
return err;
12678
err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12679
if (err < 0)
12680
return err;
12681
12682
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12683
12684
dig_only:
12685
alc_auto_parse_digital(codec);
12686
12687
if (spec->kctls.list)
12688
add_mixer(spec, spec->kctls.list);
12689
12690
add_verb(spec, alc262_volume_init_verbs);
12691
spec->num_mux_defs = 1;
12692
spec->input_mux = &spec->private_imux[0];
12693
12694
err = alc_auto_add_mic_boost(codec);
12695
if (err < 0)
12696
return err;
12697
12698
alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12699
12700
return 1;
12701
}
12702
12703
#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12704
#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12705
#define alc262_auto_init_analog_input alc882_auto_init_analog_input
12706
#define alc262_auto_init_input_src alc882_auto_init_input_src
12707
12708
12709
/* init callback for auto-configuration model -- overriding the default init */
12710
static void alc262_auto_init(struct hda_codec *codec)
12711
{
12712
struct alc_spec *spec = codec->spec;
12713
alc262_auto_init_multi_out(codec);
12714
alc262_auto_init_hp_out(codec);
12715
alc262_auto_init_analog_input(codec);
12716
alc262_auto_init_input_src(codec);
12717
alc_auto_init_digital(codec);
12718
if (spec->unsol_event)
12719
alc_inithook(codec);
12720
}
12721
12722
/*
12723
* configuration and preset
12724
*/
12725
static const char * const alc262_models[ALC262_MODEL_LAST] = {
12726
[ALC262_BASIC] = "basic",
12727
[ALC262_HIPPO] = "hippo",
12728
[ALC262_HIPPO_1] = "hippo_1",
12729
[ALC262_FUJITSU] = "fujitsu",
12730
[ALC262_HP_BPC] = "hp-bpc",
12731
[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12732
[ALC262_HP_TC_T5735] = "hp-tc-t5735",
12733
[ALC262_HP_RP5700] = "hp-rp5700",
12734
[ALC262_BENQ_ED8] = "benq",
12735
[ALC262_BENQ_T31] = "benq-t31",
12736
[ALC262_SONY_ASSAMD] = "sony-assamd",
12737
[ALC262_TOSHIBA_S06] = "toshiba-s06",
12738
[ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12739
[ALC262_ULTRA] = "ultra",
12740
[ALC262_LENOVO_3000] = "lenovo-3000",
12741
[ALC262_NEC] = "nec",
12742
[ALC262_TYAN] = "tyan",
12743
[ALC262_AUTO] = "auto",
12744
};
12745
12746
static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12747
SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12748
SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12749
SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12750
ALC262_HP_BPC),
12751
SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12752
ALC262_HP_BPC),
12753
SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12754
ALC262_HP_BPC),
12755
SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12756
ALC262_AUTO),
12757
SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12758
ALC262_HP_BPC),
12759
SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12760
SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12761
SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12762
SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12763
SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12764
SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12765
SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12766
SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12767
SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12768
SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12769
SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12770
SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12771
ALC262_HP_TC_T5735),
12772
SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12773
SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12774
SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12775
SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12776
SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12777
SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12778
SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12779
SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12780
#if 0 /* disable the quirk since model=auto works better in recent versions */
12781
SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12782
ALC262_SONY_ASSAMD),
12783
#endif
12784
SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12785
ALC262_TOSHIBA_RX1),
12786
SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12787
SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12788
SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12789
SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12790
SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12791
ALC262_ULTRA),
12792
SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12793
SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12794
SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12795
SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12796
SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12797
{}
12798
};
12799
12800
static const struct alc_config_preset alc262_presets[] = {
12801
[ALC262_BASIC] = {
12802
.mixers = { alc262_base_mixer },
12803
.init_verbs = { alc262_init_verbs },
12804
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12805
.dac_nids = alc262_dac_nids,
12806
.hp_nid = 0x03,
12807
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12808
.channel_mode = alc262_modes,
12809
.input_mux = &alc262_capture_source,
12810
},
12811
[ALC262_HIPPO] = {
12812
.mixers = { alc262_hippo_mixer },
12813
.init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12814
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12815
.dac_nids = alc262_dac_nids,
12816
.hp_nid = 0x03,
12817
.dig_out_nid = ALC262_DIGOUT_NID,
12818
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12819
.channel_mode = alc262_modes,
12820
.input_mux = &alc262_capture_source,
12821
.unsol_event = alc_sku_unsol_event,
12822
.setup = alc262_hippo_setup,
12823
.init_hook = alc_inithook,
12824
},
12825
[ALC262_HIPPO_1] = {
12826
.mixers = { alc262_hippo1_mixer },
12827
.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12828
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12829
.dac_nids = alc262_dac_nids,
12830
.hp_nid = 0x02,
12831
.dig_out_nid = ALC262_DIGOUT_NID,
12832
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12833
.channel_mode = alc262_modes,
12834
.input_mux = &alc262_capture_source,
12835
.unsol_event = alc_sku_unsol_event,
12836
.setup = alc262_hippo1_setup,
12837
.init_hook = alc_inithook,
12838
},
12839
[ALC262_FUJITSU] = {
12840
.mixers = { alc262_fujitsu_mixer },
12841
.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12842
alc262_fujitsu_unsol_verbs },
12843
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12844
.dac_nids = alc262_dac_nids,
12845
.hp_nid = 0x03,
12846
.dig_out_nid = ALC262_DIGOUT_NID,
12847
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12848
.channel_mode = alc262_modes,
12849
.input_mux = &alc262_fujitsu_capture_source,
12850
.unsol_event = alc_sku_unsol_event,
12851
.setup = alc262_fujitsu_setup,
12852
.init_hook = alc_inithook,
12853
},
12854
[ALC262_HP_BPC] = {
12855
.mixers = { alc262_HP_BPC_mixer },
12856
.init_verbs = { alc262_HP_BPC_init_verbs },
12857
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12858
.dac_nids = alc262_dac_nids,
12859
.hp_nid = 0x03,
12860
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12861
.channel_mode = alc262_modes,
12862
.input_mux = &alc262_HP_capture_source,
12863
.unsol_event = alc_sku_unsol_event,
12864
.setup = alc262_hp_bpc_setup,
12865
.init_hook = alc_inithook,
12866
},
12867
[ALC262_HP_BPC_D7000_WF] = {
12868
.mixers = { alc262_HP_BPC_WildWest_mixer },
12869
.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12870
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12871
.dac_nids = alc262_dac_nids,
12872
.hp_nid = 0x03,
12873
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12874
.channel_mode = alc262_modes,
12875
.input_mux = &alc262_HP_D7000_capture_source,
12876
.unsol_event = alc_sku_unsol_event,
12877
.setup = alc262_hp_wildwest_setup,
12878
.init_hook = alc_inithook,
12879
},
12880
[ALC262_HP_BPC_D7000_WL] = {
12881
.mixers = { alc262_HP_BPC_WildWest_mixer,
12882
alc262_HP_BPC_WildWest_option_mixer },
12883
.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12884
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12885
.dac_nids = alc262_dac_nids,
12886
.hp_nid = 0x03,
12887
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12888
.channel_mode = alc262_modes,
12889
.input_mux = &alc262_HP_D7000_capture_source,
12890
.unsol_event = alc_sku_unsol_event,
12891
.setup = alc262_hp_wildwest_setup,
12892
.init_hook = alc_inithook,
12893
},
12894
[ALC262_HP_TC_T5735] = {
12895
.mixers = { alc262_hp_t5735_mixer },
12896
.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12897
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12898
.dac_nids = alc262_dac_nids,
12899
.hp_nid = 0x03,
12900
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12901
.channel_mode = alc262_modes,
12902
.input_mux = &alc262_capture_source,
12903
.unsol_event = alc_sku_unsol_event,
12904
.setup = alc262_hp_t5735_setup,
12905
.init_hook = alc_inithook,
12906
},
12907
[ALC262_HP_RP5700] = {
12908
.mixers = { alc262_hp_rp5700_mixer },
12909
.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12910
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12911
.dac_nids = alc262_dac_nids,
12912
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12913
.channel_mode = alc262_modes,
12914
.input_mux = &alc262_hp_rp5700_capture_source,
12915
},
12916
[ALC262_BENQ_ED8] = {
12917
.mixers = { alc262_base_mixer },
12918
.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12919
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12920
.dac_nids = alc262_dac_nids,
12921
.hp_nid = 0x03,
12922
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12923
.channel_mode = alc262_modes,
12924
.input_mux = &alc262_capture_source,
12925
},
12926
[ALC262_SONY_ASSAMD] = {
12927
.mixers = { alc262_sony_mixer },
12928
.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12929
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12930
.dac_nids = alc262_dac_nids,
12931
.hp_nid = 0x02,
12932
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12933
.channel_mode = alc262_modes,
12934
.input_mux = &alc262_capture_source,
12935
.unsol_event = alc_sku_unsol_event,
12936
.setup = alc262_hippo_setup,
12937
.init_hook = alc_inithook,
12938
},
12939
[ALC262_BENQ_T31] = {
12940
.mixers = { alc262_benq_t31_mixer },
12941
.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12942
alc_hp15_unsol_verbs },
12943
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12944
.dac_nids = alc262_dac_nids,
12945
.hp_nid = 0x03,
12946
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12947
.channel_mode = alc262_modes,
12948
.input_mux = &alc262_capture_source,
12949
.unsol_event = alc_sku_unsol_event,
12950
.setup = alc262_hippo_setup,
12951
.init_hook = alc_inithook,
12952
},
12953
[ALC262_ULTRA] = {
12954
.mixers = { alc262_ultra_mixer },
12955
.cap_mixer = alc262_ultra_capture_mixer,
12956
.init_verbs = { alc262_ultra_verbs },
12957
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12958
.dac_nids = alc262_dac_nids,
12959
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12960
.channel_mode = alc262_modes,
12961
.input_mux = &alc262_ultra_capture_source,
12962
.adc_nids = alc262_adc_nids, /* ADC0 */
12963
.capsrc_nids = alc262_capsrc_nids,
12964
.num_adc_nids = 1, /* single ADC */
12965
.unsol_event = alc262_ultra_unsol_event,
12966
.init_hook = alc262_ultra_automute,
12967
},
12968
[ALC262_LENOVO_3000] = {
12969
.mixers = { alc262_lenovo_3000_mixer },
12970
.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12971
alc262_lenovo_3000_unsol_verbs,
12972
alc262_lenovo_3000_init_verbs },
12973
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12974
.dac_nids = alc262_dac_nids,
12975
.hp_nid = 0x03,
12976
.dig_out_nid = ALC262_DIGOUT_NID,
12977
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12978
.channel_mode = alc262_modes,
12979
.input_mux = &alc262_fujitsu_capture_source,
12980
.unsol_event = alc_sku_unsol_event,
12981
.setup = alc262_lenovo_3000_setup,
12982
.init_hook = alc_inithook,
12983
},
12984
[ALC262_NEC] = {
12985
.mixers = { alc262_nec_mixer },
12986
.init_verbs = { alc262_nec_verbs },
12987
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12988
.dac_nids = alc262_dac_nids,
12989
.hp_nid = 0x03,
12990
.num_channel_mode = ARRAY_SIZE(alc262_modes),
12991
.channel_mode = alc262_modes,
12992
.input_mux = &alc262_capture_source,
12993
},
12994
[ALC262_TOSHIBA_S06] = {
12995
.mixers = { alc262_toshiba_s06_mixer },
12996
.init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12997
alc262_eapd_verbs },
12998
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12999
.capsrc_nids = alc262_dmic_capsrc_nids,
13000
.dac_nids = alc262_dac_nids,
13001
.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
13002
.num_adc_nids = 1, /* single ADC */
13003
.dig_out_nid = ALC262_DIGOUT_NID,
13004
.num_channel_mode = ARRAY_SIZE(alc262_modes),
13005
.channel_mode = alc262_modes,
13006
.unsol_event = alc_sku_unsol_event,
13007
.setup = alc262_toshiba_s06_setup,
13008
.init_hook = alc_inithook,
13009
},
13010
[ALC262_TOSHIBA_RX1] = {
13011
.mixers = { alc262_toshiba_rx1_mixer },
13012
.init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
13013
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
13014
.dac_nids = alc262_dac_nids,
13015
.hp_nid = 0x03,
13016
.num_channel_mode = ARRAY_SIZE(alc262_modes),
13017
.channel_mode = alc262_modes,
13018
.input_mux = &alc262_capture_source,
13019
.unsol_event = alc_sku_unsol_event,
13020
.setup = alc262_hippo_setup,
13021
.init_hook = alc_inithook,
13022
},
13023
[ALC262_TYAN] = {
13024
.mixers = { alc262_tyan_mixer },
13025
.init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
13026
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
13027
.dac_nids = alc262_dac_nids,
13028
.hp_nid = 0x02,
13029
.dig_out_nid = ALC262_DIGOUT_NID,
13030
.num_channel_mode = ARRAY_SIZE(alc262_modes),
13031
.channel_mode = alc262_modes,
13032
.input_mux = &alc262_capture_source,
13033
.unsol_event = alc_sku_unsol_event,
13034
.setup = alc262_tyan_setup,
13035
.init_hook = alc_hp_automute,
13036
},
13037
};
13038
13039
static int patch_alc262(struct hda_codec *codec)
13040
{
13041
struct alc_spec *spec;
13042
int board_config;
13043
int err;
13044
13045
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13046
if (spec == NULL)
13047
return -ENOMEM;
13048
13049
codec->spec = spec;
13050
#if 0
13051
/* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
13052
* under-run
13053
*/
13054
{
13055
int tmp;
13056
snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13057
tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
13058
snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13059
snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
13060
}
13061
#endif
13062
alc_auto_parse_customize_define(codec);
13063
13064
alc_fix_pll_init(codec, 0x20, 0x0a, 10);
13065
13066
board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
13067
alc262_models,
13068
alc262_cfg_tbl);
13069
13070
if (board_config < 0) {
13071
printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13072
codec->chip_name);
13073
board_config = ALC262_AUTO;
13074
}
13075
13076
if (board_config == ALC262_AUTO) {
13077
alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13078
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13079
}
13080
13081
if (board_config == ALC262_AUTO) {
13082
/* automatic parse from the BIOS config */
13083
err = alc262_parse_auto_config(codec);
13084
if (err < 0) {
13085
alc_free(codec);
13086
return err;
13087
} else if (!err) {
13088
printk(KERN_INFO
13089
"hda_codec: Cannot set up configuration "
13090
"from BIOS. Using base mode...\n");
13091
board_config = ALC262_BASIC;
13092
}
13093
}
13094
13095
if (!spec->no_analog && has_cdefine_beep(codec)) {
13096
err = snd_hda_attach_beep_device(codec, 0x1);
13097
if (err < 0) {
13098
alc_free(codec);
13099
return err;
13100
}
13101
}
13102
13103
if (board_config != ALC262_AUTO)
13104
setup_preset(codec, &alc262_presets[board_config]);
13105
13106
spec->stream_analog_playback = &alc262_pcm_analog_playback;
13107
spec->stream_analog_capture = &alc262_pcm_analog_capture;
13108
13109
spec->stream_digital_playback = &alc262_pcm_digital_playback;
13110
spec->stream_digital_capture = &alc262_pcm_digital_capture;
13111
13112
if (!spec->adc_nids && spec->input_mux) {
13113
int i;
13114
/* check whether the digital-mic has to be supported */
13115
for (i = 0; i < spec->input_mux->num_items; i++) {
13116
if (spec->input_mux->items[i].index >= 9)
13117
break;
13118
}
13119
if (i < spec->input_mux->num_items) {
13120
/* use only ADC0 */
13121
spec->adc_nids = alc262_dmic_adc_nids;
13122
spec->num_adc_nids = 1;
13123
spec->capsrc_nids = alc262_dmic_capsrc_nids;
13124
} else {
13125
/* all analog inputs */
13126
/* check whether NID 0x07 is valid */
13127
unsigned int wcap = get_wcaps(codec, 0x07);
13128
13129
/* get type */
13130
wcap = get_wcaps_type(wcap);
13131
if (wcap != AC_WID_AUD_IN) {
13132
spec->adc_nids = alc262_adc_nids_alt;
13133
spec->num_adc_nids =
13134
ARRAY_SIZE(alc262_adc_nids_alt);
13135
spec->capsrc_nids = alc262_capsrc_nids_alt;
13136
} else {
13137
spec->adc_nids = alc262_adc_nids;
13138
spec->num_adc_nids =
13139
ARRAY_SIZE(alc262_adc_nids);
13140
spec->capsrc_nids = alc262_capsrc_nids;
13141
}
13142
}
13143
}
13144
if (!spec->cap_mixer && !spec->no_analog)
13145
set_capture_mixer(codec);
13146
if (!spec->no_analog && has_cdefine_beep(codec))
13147
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
13148
13149
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13150
13151
spec->vmaster_nid = 0x0c;
13152
13153
codec->patch_ops = alc_patch_ops;
13154
if (board_config == ALC262_AUTO)
13155
spec->init_hook = alc262_auto_init;
13156
spec->shutup = alc_eapd_shutup;
13157
13158
alc_init_jacks(codec);
13159
#ifdef CONFIG_SND_HDA_POWER_SAVE
13160
if (!spec->loopback.amplist)
13161
spec->loopback.amplist = alc262_loopbacks;
13162
#endif
13163
13164
return 0;
13165
}
13166
13167
/*
13168
* ALC268 channel source setting (2 channel)
13169
*/
13170
#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13171
#define alc268_modes alc260_modes
13172
13173
static const hda_nid_t alc268_dac_nids[2] = {
13174
/* front, hp */
13175
0x02, 0x03
13176
};
13177
13178
static const hda_nid_t alc268_adc_nids[2] = {
13179
/* ADC0-1 */
13180
0x08, 0x07
13181
};
13182
13183
static const hda_nid_t alc268_adc_nids_alt[1] = {
13184
/* ADC0 */
13185
0x08
13186
};
13187
13188
static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13189
13190
static const struct snd_kcontrol_new alc268_base_mixer[] = {
13191
/* output mixer control */
13192
HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13193
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13194
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13195
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13196
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13197
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13198
HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13199
{ }
13200
};
13201
13202
static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13203
/* output mixer control */
13204
HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13205
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13206
ALC262_HIPPO_MASTER_SWITCH,
13207
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13208
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13209
HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13210
{ }
13211
};
13212
13213
/* bind Beep switches of both NID 0x0f and 0x10 */
13214
static const struct hda_bind_ctls alc268_bind_beep_sw = {
13215
.ops = &snd_hda_bind_sw,
13216
.values = {
13217
HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13218
HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13219
0
13220
},
13221
};
13222
13223
static const struct snd_kcontrol_new alc268_beep_mixer[] = {
13224
HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13225
HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13226
{ }
13227
};
13228
13229
static const struct hda_verb alc268_eapd_verbs[] = {
13230
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13231
{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13232
{ }
13233
};
13234
13235
/* Toshiba specific */
13236
static const struct hda_verb alc268_toshiba_verbs[] = {
13237
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13238
{ } /* end */
13239
};
13240
13241
/* Acer specific */
13242
/* bind volumes of both NID 0x02 and 0x03 */
13243
static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
13244
.ops = &snd_hda_bind_vol,
13245
.values = {
13246
HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13247
HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13248
0
13249
},
13250
};
13251
13252
static void alc268_acer_setup(struct hda_codec *codec)
13253
{
13254
struct alc_spec *spec = codec->spec;
13255
13256
spec->autocfg.hp_pins[0] = 0x14;
13257
spec->autocfg.speaker_pins[0] = 0x15;
13258
spec->automute = 1;
13259
spec->automute_mode = ALC_AUTOMUTE_AMP;
13260
}
13261
13262
#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13263
#define alc268_acer_master_sw_put alc262_hp_master_sw_put
13264
13265
static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13266
/* output mixer control */
13267
HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13268
{
13269
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13270
.name = "Master Playback Switch",
13271
.subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13272
.info = snd_ctl_boolean_mono_info,
13273
.get = alc268_acer_master_sw_get,
13274
.put = alc268_acer_master_sw_put,
13275
},
13276
HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13277
{ }
13278
};
13279
13280
static const struct snd_kcontrol_new alc268_acer_mixer[] = {
13281
/* output mixer control */
13282
HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13283
{
13284
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13285
.name = "Master Playback Switch",
13286
.subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13287
.info = snd_ctl_boolean_mono_info,
13288
.get = alc268_acer_master_sw_get,
13289
.put = alc268_acer_master_sw_put,
13290
},
13291
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13292
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13293
HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13294
{ }
13295
};
13296
13297
static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13298
/* output mixer control */
13299
HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13300
{
13301
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13302
.name = "Master Playback Switch",
13303
.subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13304
.info = snd_ctl_boolean_mono_info,
13305
.get = alc268_acer_master_sw_get,
13306
.put = alc268_acer_master_sw_put,
13307
},
13308
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13309
HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13310
{ }
13311
};
13312
13313
static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
13314
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13315
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13316
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13317
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13318
{0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13319
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13320
{ }
13321
};
13322
13323
static const struct hda_verb alc268_acer_verbs[] = {
13324
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13325
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13326
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13327
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13328
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13329
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13330
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13331
{ }
13332
};
13333
13334
/* unsolicited event for HP jack sensing */
13335
#define alc268_toshiba_setup alc262_hippo_setup
13336
13337
static void alc268_acer_lc_setup(struct hda_codec *codec)
13338
{
13339
struct alc_spec *spec = codec->spec;
13340
spec->autocfg.hp_pins[0] = 0x15;
13341
spec->autocfg.speaker_pins[0] = 0x14;
13342
spec->automute = 1;
13343
spec->automute_mode = ALC_AUTOMUTE_AMP;
13344
spec->ext_mic.pin = 0x18;
13345
spec->ext_mic.mux_idx = 0;
13346
spec->int_mic.pin = 0x12;
13347
spec->int_mic.mux_idx = 6;
13348
spec->auto_mic = 1;
13349
}
13350
13351
static const struct snd_kcontrol_new alc268_dell_mixer[] = {
13352
/* output mixer control */
13353
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13354
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13355
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13356
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13357
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13358
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13359
{ }
13360
};
13361
13362
static const struct hda_verb alc268_dell_verbs[] = {
13363
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13364
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13365
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13366
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13367
{ }
13368
};
13369
13370
/* mute/unmute internal speaker according to the hp jack and mute state */
13371
static void alc268_dell_setup(struct hda_codec *codec)
13372
{
13373
struct alc_spec *spec = codec->spec;
13374
13375
spec->autocfg.hp_pins[0] = 0x15;
13376
spec->autocfg.speaker_pins[0] = 0x14;
13377
spec->ext_mic.pin = 0x18;
13378
spec->ext_mic.mux_idx = 0;
13379
spec->int_mic.pin = 0x19;
13380
spec->int_mic.mux_idx = 1;
13381
spec->auto_mic = 1;
13382
spec->automute = 1;
13383
spec->automute_mode = ALC_AUTOMUTE_PIN;
13384
}
13385
13386
static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13387
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13388
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13389
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13390
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13391
HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13392
HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13393
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13394
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13395
{ }
13396
};
13397
13398
static const struct hda_verb alc267_quanta_il1_verbs[] = {
13399
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13400
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13401
{ }
13402
};
13403
13404
static void alc267_quanta_il1_setup(struct hda_codec *codec)
13405
{
13406
struct alc_spec *spec = codec->spec;
13407
spec->autocfg.hp_pins[0] = 0x15;
13408
spec->autocfg.speaker_pins[0] = 0x14;
13409
spec->ext_mic.pin = 0x18;
13410
spec->ext_mic.mux_idx = 0;
13411
spec->int_mic.pin = 0x19;
13412
spec->int_mic.mux_idx = 1;
13413
spec->auto_mic = 1;
13414
spec->automute = 1;
13415
spec->automute_mode = ALC_AUTOMUTE_PIN;
13416
}
13417
13418
/*
13419
* generic initialization of ADC, input mixers and output mixers
13420
*/
13421
static const struct hda_verb alc268_base_init_verbs[] = {
13422
/* Unmute DAC0-1 and set vol = 0 */
13423
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13424
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13425
13426
/*
13427
* Set up output mixers (0x0c - 0x0e)
13428
*/
13429
/* set vol=0 to output mixers */
13430
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13431
{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13432
13433
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13434
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13435
13436
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13437
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13438
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13439
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13440
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13441
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13442
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13443
{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13444
13445
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13446
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13447
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13448
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13449
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13450
13451
/* set PCBEEP vol = 0, mute connections */
13452
{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13453
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13454
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13455
13456
/* Unmute Selector 23h,24h and set the default input to mic-in */
13457
13458
{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13459
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13460
{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13461
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13462
13463
{ }
13464
};
13465
13466
/*
13467
* generic initialization of ADC, input mixers and output mixers
13468
*/
13469
static const struct hda_verb alc268_volume_init_verbs[] = {
13470
/* set output DAC */
13471
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13472
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13473
13474
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13475
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13476
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13477
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13478
{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13479
13480
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13481
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13482
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13483
13484
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13485
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13486
13487
/* set PCBEEP vol = 0, mute connections */
13488
{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13489
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13490
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13491
13492
{ }
13493
};
13494
13495
static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13496
HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13497
HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13498
{ } /* end */
13499
};
13500
13501
static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13502
HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13503
HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13504
_DEFINE_CAPSRC(1),
13505
{ } /* end */
13506
};
13507
13508
static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13509
HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13510
HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13511
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13512
HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13513
_DEFINE_CAPSRC(2),
13514
{ } /* end */
13515
};
13516
13517
static const struct hda_input_mux alc268_capture_source = {
13518
.num_items = 4,
13519
.items = {
13520
{ "Mic", 0x0 },
13521
{ "Front Mic", 0x1 },
13522
{ "Line", 0x2 },
13523
{ "CD", 0x3 },
13524
},
13525
};
13526
13527
static const struct hda_input_mux alc268_acer_capture_source = {
13528
.num_items = 3,
13529
.items = {
13530
{ "Mic", 0x0 },
13531
{ "Internal Mic", 0x1 },
13532
{ "Line", 0x2 },
13533
},
13534
};
13535
13536
static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13537
.num_items = 3,
13538
.items = {
13539
{ "Mic", 0x0 },
13540
{ "Internal Mic", 0x6 },
13541
{ "Line", 0x2 },
13542
},
13543
};
13544
13545
#ifdef CONFIG_SND_DEBUG
13546
static const struct snd_kcontrol_new alc268_test_mixer[] = {
13547
/* Volume widgets */
13548
HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13549
HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13550
HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13551
HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13552
HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13553
HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13554
HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13555
HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13556
HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13557
HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13558
HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13559
HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13560
HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13561
/* The below appears problematic on some hardwares */
13562
/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13563
HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13564
HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13565
HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13566
HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13567
13568
/* Modes for retasking pin widgets */
13569
ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13570
ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13571
ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13572
ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13573
13574
/* Controls for GPIO pins, assuming they are configured as outputs */
13575
ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13576
ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13577
ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13578
ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13579
13580
/* Switches to allow the digital SPDIF output pin to be enabled.
13581
* The ALC268 does not have an SPDIF input.
13582
*/
13583
ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13584
13585
/* A switch allowing EAPD to be enabled. Some laptops seem to use
13586
* this output to turn on an external amplifier.
13587
*/
13588
ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13589
ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13590
13591
{ } /* end */
13592
};
13593
#endif
13594
13595
/* create input playback/capture controls for the given pin */
13596
static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13597
const char *ctlname, int idx)
13598
{
13599
hda_nid_t dac;
13600
int err;
13601
13602
switch (nid) {
13603
case 0x14:
13604
case 0x16:
13605
dac = 0x02;
13606
break;
13607
case 0x15:
13608
case 0x1a: /* ALC259/269 only */
13609
case 0x1b: /* ALC259/269 only */
13610
case 0x21: /* ALC269vb has this pin, too */
13611
dac = 0x03;
13612
break;
13613
default:
13614
snd_printd(KERN_WARNING "hda_codec: "
13615
"ignoring pin 0x%x as unknown\n", nid);
13616
return 0;
13617
}
13618
if (spec->multiout.dac_nids[0] != dac &&
13619
spec->multiout.dac_nids[1] != dac) {
13620
err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13621
HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13622
HDA_OUTPUT));
13623
if (err < 0)
13624
return err;
13625
spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13626
}
13627
13628
if (nid != 0x16)
13629
err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13630
HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13631
else /* mono */
13632
err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13633
HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13634
if (err < 0)
13635
return err;
13636
return 0;
13637
}
13638
13639
/* add playback controls from the parsed DAC table */
13640
static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13641
const struct auto_pin_cfg *cfg)
13642
{
13643
hda_nid_t nid;
13644
int err;
13645
13646
spec->multiout.dac_nids = spec->private_dac_nids;
13647
13648
nid = cfg->line_out_pins[0];
13649
if (nid) {
13650
const char *name;
13651
if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13652
name = "Speaker";
13653
else
13654
name = "Front";
13655
err = alc268_new_analog_output(spec, nid, name, 0);
13656
if (err < 0)
13657
return err;
13658
}
13659
13660
nid = cfg->speaker_pins[0];
13661
if (nid == 0x1d) {
13662
err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13663
HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13664
if (err < 0)
13665
return err;
13666
} else if (nid) {
13667
err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13668
if (err < 0)
13669
return err;
13670
}
13671
nid = cfg->hp_pins[0];
13672
if (nid) {
13673
err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13674
if (err < 0)
13675
return err;
13676
}
13677
13678
nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13679
if (nid == 0x16) {
13680
err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13681
HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13682
if (err < 0)
13683
return err;
13684
}
13685
return 0;
13686
}
13687
13688
/* create playback/capture controls for input pins */
13689
static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13690
const struct auto_pin_cfg *cfg)
13691
{
13692
return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13693
}
13694
13695
static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13696
hda_nid_t nid, int pin_type)
13697
{
13698
int idx;
13699
13700
alc_set_pin_output(codec, nid, pin_type);
13701
if (nid == 0x14 || nid == 0x16)
13702
idx = 0;
13703
else
13704
idx = 1;
13705
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13706
}
13707
13708
static void alc268_auto_init_multi_out(struct hda_codec *codec)
13709
{
13710
struct alc_spec *spec = codec->spec;
13711
int i;
13712
13713
for (i = 0; i < spec->autocfg.line_outs; i++) {
13714
hda_nid_t nid = spec->autocfg.line_out_pins[i];
13715
int pin_type = get_pin_type(spec->autocfg.line_out_type);
13716
alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13717
}
13718
}
13719
13720
static void alc268_auto_init_hp_out(struct hda_codec *codec)
13721
{
13722
struct alc_spec *spec = codec->spec;
13723
hda_nid_t pin;
13724
int i;
13725
13726
for (i = 0; i < spec->autocfg.hp_outs; i++) {
13727
pin = spec->autocfg.hp_pins[i];
13728
alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13729
}
13730
for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13731
pin = spec->autocfg.speaker_pins[i];
13732
alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13733
}
13734
if (spec->autocfg.mono_out_pin)
13735
snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13736
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13737
}
13738
13739
static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13740
{
13741
struct alc_spec *spec = codec->spec;
13742
hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13743
hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13744
hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13745
unsigned int dac_vol1, dac_vol2;
13746
13747
if (line_nid == 0x1d || speaker_nid == 0x1d) {
13748
snd_hda_codec_write(codec, speaker_nid, 0,
13749
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13750
/* mute mixer inputs from 0x1d */
13751
snd_hda_codec_write(codec, 0x0f, 0,
13752
AC_VERB_SET_AMP_GAIN_MUTE,
13753
AMP_IN_UNMUTE(1));
13754
snd_hda_codec_write(codec, 0x10, 0,
13755
AC_VERB_SET_AMP_GAIN_MUTE,
13756
AMP_IN_UNMUTE(1));
13757
} else {
13758
/* unmute mixer inputs from 0x1d */
13759
snd_hda_codec_write(codec, 0x0f, 0,
13760
AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13761
snd_hda_codec_write(codec, 0x10, 0,
13762
AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13763
}
13764
13765
dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13766
if (line_nid == 0x14)
13767
dac_vol2 = AMP_OUT_ZERO;
13768
else if (line_nid == 0x15)
13769
dac_vol1 = AMP_OUT_ZERO;
13770
if (hp_nid == 0x14)
13771
dac_vol2 = AMP_OUT_ZERO;
13772
else if (hp_nid == 0x15)
13773
dac_vol1 = AMP_OUT_ZERO;
13774
if (line_nid != 0x16 || hp_nid != 0x16 ||
13775
spec->autocfg.line_out_pins[1] != 0x16 ||
13776
spec->autocfg.line_out_pins[2] != 0x16)
13777
dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13778
13779
snd_hda_codec_write(codec, 0x02, 0,
13780
AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13781
snd_hda_codec_write(codec, 0x03, 0,
13782
AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13783
}
13784
13785
/* pcm configuration: identical with ALC880 */
13786
#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13787
#define alc268_pcm_analog_capture alc880_pcm_analog_capture
13788
#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13789
#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13790
13791
/*
13792
* BIOS auto configuration
13793
*/
13794
static int alc268_parse_auto_config(struct hda_codec *codec)
13795
{
13796
struct alc_spec *spec = codec->spec;
13797
int err;
13798
static const hda_nid_t alc268_ignore[] = { 0 };
13799
13800
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13801
alc268_ignore);
13802
if (err < 0)
13803
return err;
13804
if (!spec->autocfg.line_outs) {
13805
if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13806
spec->multiout.max_channels = 2;
13807
spec->no_analog = 1;
13808
goto dig_only;
13809
}
13810
return 0; /* can't find valid BIOS pin config */
13811
}
13812
err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13813
if (err < 0)
13814
return err;
13815
err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13816
if (err < 0)
13817
return err;
13818
13819
spec->multiout.max_channels = 2;
13820
13821
dig_only:
13822
/* digital only support output */
13823
alc_auto_parse_digital(codec);
13824
if (spec->kctls.list)
13825
add_mixer(spec, spec->kctls.list);
13826
13827
if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13828
add_mixer(spec, alc268_beep_mixer);
13829
13830
add_verb(spec, alc268_volume_init_verbs);
13831
spec->num_mux_defs = 2;
13832
spec->input_mux = &spec->private_imux[0];
13833
13834
err = alc_auto_add_mic_boost(codec);
13835
if (err < 0)
13836
return err;
13837
13838
alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13839
13840
return 1;
13841
}
13842
13843
#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13844
#define alc268_auto_init_input_src alc882_auto_init_input_src
13845
13846
/* init callback for auto-configuration model -- overriding the default init */
13847
static void alc268_auto_init(struct hda_codec *codec)
13848
{
13849
struct alc_spec *spec = codec->spec;
13850
alc268_auto_init_multi_out(codec);
13851
alc268_auto_init_hp_out(codec);
13852
alc268_auto_init_mono_speaker_out(codec);
13853
alc268_auto_init_analog_input(codec);
13854
alc268_auto_init_input_src(codec);
13855
alc_auto_init_digital(codec);
13856
if (spec->unsol_event)
13857
alc_inithook(codec);
13858
}
13859
13860
/*
13861
* configuration and preset
13862
*/
13863
static const char * const alc268_models[ALC268_MODEL_LAST] = {
13864
[ALC267_QUANTA_IL1] = "quanta-il1",
13865
[ALC268_3ST] = "3stack",
13866
[ALC268_TOSHIBA] = "toshiba",
13867
[ALC268_ACER] = "acer",
13868
[ALC268_ACER_DMIC] = "acer-dmic",
13869
[ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13870
[ALC268_DELL] = "dell",
13871
[ALC268_ZEPTO] = "zepto",
13872
#ifdef CONFIG_SND_DEBUG
13873
[ALC268_TEST] = "test",
13874
#endif
13875
[ALC268_AUTO] = "auto",
13876
};
13877
13878
static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13879
SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13880
SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13881
SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13882
SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13883
SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13884
SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13885
ALC268_ACER_ASPIRE_ONE),
13886
SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13887
SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13888
SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13889
"Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13890
/* almost compatible with toshiba but with optional digital outs;
13891
* auto-probing seems working fine
13892
*/
13893
SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13894
ALC268_AUTO),
13895
SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13896
SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13897
SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13898
SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13899
{}
13900
};
13901
13902
/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13903
static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13904
SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13905
SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13906
SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13907
ALC268_TOSHIBA),
13908
{}
13909
};
13910
13911
static const struct alc_config_preset alc268_presets[] = {
13912
[ALC267_QUANTA_IL1] = {
13913
.mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13914
alc268_capture_nosrc_mixer },
13915
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13916
alc267_quanta_il1_verbs },
13917
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13918
.dac_nids = alc268_dac_nids,
13919
.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13920
.adc_nids = alc268_adc_nids_alt,
13921
.hp_nid = 0x03,
13922
.num_channel_mode = ARRAY_SIZE(alc268_modes),
13923
.channel_mode = alc268_modes,
13924
.unsol_event = alc_sku_unsol_event,
13925
.setup = alc267_quanta_il1_setup,
13926
.init_hook = alc_inithook,
13927
},
13928
[ALC268_3ST] = {
13929
.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13930
alc268_beep_mixer },
13931
.init_verbs = { alc268_base_init_verbs },
13932
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13933
.dac_nids = alc268_dac_nids,
13934
.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13935
.adc_nids = alc268_adc_nids_alt,
13936
.capsrc_nids = alc268_capsrc_nids,
13937
.hp_nid = 0x03,
13938
.dig_out_nid = ALC268_DIGOUT_NID,
13939
.num_channel_mode = ARRAY_SIZE(alc268_modes),
13940
.channel_mode = alc268_modes,
13941
.input_mux = &alc268_capture_source,
13942
},
13943
[ALC268_TOSHIBA] = {
13944
.mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13945
alc268_beep_mixer },
13946
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13947
alc268_toshiba_verbs },
13948
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13949
.dac_nids = alc268_dac_nids,
13950
.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13951
.adc_nids = alc268_adc_nids_alt,
13952
.capsrc_nids = alc268_capsrc_nids,
13953
.hp_nid = 0x03,
13954
.num_channel_mode = ARRAY_SIZE(alc268_modes),
13955
.channel_mode = alc268_modes,
13956
.input_mux = &alc268_capture_source,
13957
.unsol_event = alc_sku_unsol_event,
13958
.setup = alc268_toshiba_setup,
13959
.init_hook = alc_inithook,
13960
},
13961
[ALC268_ACER] = {
13962
.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13963
alc268_beep_mixer },
13964
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13965
alc268_acer_verbs },
13966
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13967
.dac_nids = alc268_dac_nids,
13968
.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13969
.adc_nids = alc268_adc_nids_alt,
13970
.capsrc_nids = alc268_capsrc_nids,
13971
.hp_nid = 0x02,
13972
.num_channel_mode = ARRAY_SIZE(alc268_modes),
13973
.channel_mode = alc268_modes,
13974
.input_mux = &alc268_acer_capture_source,
13975
.unsol_event = alc_sku_unsol_event,
13976
.setup = alc268_acer_setup,
13977
.init_hook = alc_inithook,
13978
},
13979
[ALC268_ACER_DMIC] = {
13980
.mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13981
alc268_beep_mixer },
13982
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13983
alc268_acer_verbs },
13984
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13985
.dac_nids = alc268_dac_nids,
13986
.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13987
.adc_nids = alc268_adc_nids_alt,
13988
.capsrc_nids = alc268_capsrc_nids,
13989
.hp_nid = 0x02,
13990
.num_channel_mode = ARRAY_SIZE(alc268_modes),
13991
.channel_mode = alc268_modes,
13992
.input_mux = &alc268_acer_dmic_capture_source,
13993
.unsol_event = alc_sku_unsol_event,
13994
.setup = alc268_acer_setup,
13995
.init_hook = alc_inithook,
13996
},
13997
[ALC268_ACER_ASPIRE_ONE] = {
13998
.mixers = { alc268_acer_aspire_one_mixer,
13999
alc268_beep_mixer,
14000
alc268_capture_nosrc_mixer },
14001
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14002
alc268_acer_aspire_one_verbs },
14003
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14004
.dac_nids = alc268_dac_nids,
14005
.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14006
.adc_nids = alc268_adc_nids_alt,
14007
.capsrc_nids = alc268_capsrc_nids,
14008
.hp_nid = 0x03,
14009
.num_channel_mode = ARRAY_SIZE(alc268_modes),
14010
.channel_mode = alc268_modes,
14011
.unsol_event = alc_sku_unsol_event,
14012
.setup = alc268_acer_lc_setup,
14013
.init_hook = alc_inithook,
14014
},
14015
[ALC268_DELL] = {
14016
.mixers = { alc268_dell_mixer, alc268_beep_mixer,
14017
alc268_capture_nosrc_mixer },
14018
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14019
alc268_dell_verbs },
14020
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14021
.dac_nids = alc268_dac_nids,
14022
.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14023
.adc_nids = alc268_adc_nids_alt,
14024
.capsrc_nids = alc268_capsrc_nids,
14025
.hp_nid = 0x02,
14026
.num_channel_mode = ARRAY_SIZE(alc268_modes),
14027
.channel_mode = alc268_modes,
14028
.unsol_event = alc_sku_unsol_event,
14029
.setup = alc268_dell_setup,
14030
.init_hook = alc_inithook,
14031
},
14032
[ALC268_ZEPTO] = {
14033
.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
14034
alc268_beep_mixer },
14035
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14036
alc268_toshiba_verbs },
14037
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14038
.dac_nids = alc268_dac_nids,
14039
.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14040
.adc_nids = alc268_adc_nids_alt,
14041
.capsrc_nids = alc268_capsrc_nids,
14042
.hp_nid = 0x03,
14043
.dig_out_nid = ALC268_DIGOUT_NID,
14044
.num_channel_mode = ARRAY_SIZE(alc268_modes),
14045
.channel_mode = alc268_modes,
14046
.input_mux = &alc268_capture_source,
14047
.unsol_event = alc_sku_unsol_event,
14048
.setup = alc268_toshiba_setup,
14049
.init_hook = alc_inithook,
14050
},
14051
#ifdef CONFIG_SND_DEBUG
14052
[ALC268_TEST] = {
14053
.mixers = { alc268_test_mixer, alc268_capture_mixer },
14054
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14055
alc268_volume_init_verbs },
14056
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14057
.dac_nids = alc268_dac_nids,
14058
.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14059
.adc_nids = alc268_adc_nids_alt,
14060
.capsrc_nids = alc268_capsrc_nids,
14061
.hp_nid = 0x03,
14062
.dig_out_nid = ALC268_DIGOUT_NID,
14063
.num_channel_mode = ARRAY_SIZE(alc268_modes),
14064
.channel_mode = alc268_modes,
14065
.input_mux = &alc268_capture_source,
14066
},
14067
#endif
14068
};
14069
14070
static int patch_alc268(struct hda_codec *codec)
14071
{
14072
struct alc_spec *spec;
14073
int board_config;
14074
int i, has_beep, err;
14075
14076
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14077
if (spec == NULL)
14078
return -ENOMEM;
14079
14080
codec->spec = spec;
14081
14082
board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14083
alc268_models,
14084
alc268_cfg_tbl);
14085
14086
if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14087
board_config = snd_hda_check_board_codec_sid_config(codec,
14088
ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
14089
14090
if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
14091
printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14092
codec->chip_name);
14093
board_config = ALC268_AUTO;
14094
}
14095
14096
if (board_config == ALC268_AUTO) {
14097
/* automatic parse from the BIOS config */
14098
err = alc268_parse_auto_config(codec);
14099
if (err < 0) {
14100
alc_free(codec);
14101
return err;
14102
} else if (!err) {
14103
printk(KERN_INFO
14104
"hda_codec: Cannot set up configuration "
14105
"from BIOS. Using base mode...\n");
14106
board_config = ALC268_3ST;
14107
}
14108
}
14109
14110
if (board_config != ALC268_AUTO)
14111
setup_preset(codec, &alc268_presets[board_config]);
14112
14113
spec->stream_analog_playback = &alc268_pcm_analog_playback;
14114
spec->stream_analog_capture = &alc268_pcm_analog_capture;
14115
spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14116
14117
spec->stream_digital_playback = &alc268_pcm_digital_playback;
14118
14119
has_beep = 0;
14120
for (i = 0; i < spec->num_mixers; i++) {
14121
if (spec->mixers[i] == alc268_beep_mixer) {
14122
has_beep = 1;
14123
break;
14124
}
14125
}
14126
14127
if (has_beep) {
14128
err = snd_hda_attach_beep_device(codec, 0x1);
14129
if (err < 0) {
14130
alc_free(codec);
14131
return err;
14132
}
14133
if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14134
/* override the amp caps for beep generator */
14135
snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
14136
(0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14137
(0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14138
(0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14139
(0 << AC_AMPCAP_MUTE_SHIFT));
14140
}
14141
14142
if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14143
/* check whether NID 0x07 is valid */
14144
unsigned int wcap = get_wcaps(codec, 0x07);
14145
14146
spec->capsrc_nids = alc268_capsrc_nids;
14147
/* get type */
14148
wcap = get_wcaps_type(wcap);
14149
if (spec->auto_mic ||
14150
wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14151
spec->adc_nids = alc268_adc_nids_alt;
14152
spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14153
if (spec->auto_mic)
14154
fixup_automic_adc(codec);
14155
if (spec->auto_mic || spec->input_mux->num_items == 1)
14156
add_mixer(spec, alc268_capture_nosrc_mixer);
14157
else
14158
add_mixer(spec, alc268_capture_alt_mixer);
14159
} else {
14160
spec->adc_nids = alc268_adc_nids;
14161
spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14162
add_mixer(spec, alc268_capture_mixer);
14163
}
14164
}
14165
14166
spec->vmaster_nid = 0x02;
14167
14168
codec->patch_ops = alc_patch_ops;
14169
if (board_config == ALC268_AUTO)
14170
spec->init_hook = alc268_auto_init;
14171
spec->shutup = alc_eapd_shutup;
14172
14173
alc_init_jacks(codec);
14174
14175
return 0;
14176
}
14177
14178
/*
14179
* ALC269 channel source setting (2 channel)
14180
*/
14181
#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14182
14183
#define alc269_dac_nids alc260_dac_nids
14184
14185
static const hda_nid_t alc269_adc_nids[1] = {
14186
/* ADC1 */
14187
0x08,
14188
};
14189
14190
static const hda_nid_t alc269_capsrc_nids[1] = {
14191
0x23,
14192
};
14193
14194
static const hda_nid_t alc269vb_adc_nids[1] = {
14195
/* ADC1 */
14196
0x09,
14197
};
14198
14199
static const hda_nid_t alc269vb_capsrc_nids[1] = {
14200
0x22,
14201
};
14202
14203
static const hda_nid_t alc269_adc_candidates[] = {
14204
0x08, 0x09, 0x07, 0x11,
14205
};
14206
14207
#define alc269_modes alc260_modes
14208
#define alc269_capture_source alc880_lg_lw_capture_source
14209
14210
static const struct snd_kcontrol_new alc269_base_mixer[] = {
14211
HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14212
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14213
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14214
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14215
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14216
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14217
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14218
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14219
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14220
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14221
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14222
HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14223
{ } /* end */
14224
};
14225
14226
static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14227
/* output mixer control */
14228
HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14229
{
14230
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14231
.name = "Master Playback Switch",
14232
.subdevice = HDA_SUBDEV_AMP_FLAG,
14233
.info = snd_hda_mixer_amp_switch_info,
14234
.get = snd_hda_mixer_amp_switch_get,
14235
.put = alc268_acer_master_sw_put,
14236
.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14237
},
14238
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14239
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14240
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14241
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14242
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14243
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14244
{ }
14245
};
14246
14247
static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14248
/* output mixer control */
14249
HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14250
{
14251
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14252
.name = "Master Playback Switch",
14253
.subdevice = HDA_SUBDEV_AMP_FLAG,
14254
.info = snd_hda_mixer_amp_switch_info,
14255
.get = snd_hda_mixer_amp_switch_get,
14256
.put = alc268_acer_master_sw_put,
14257
.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14258
},
14259
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14260
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14261
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14262
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14263
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14264
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14265
HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14266
HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14267
HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14268
{ }
14269
};
14270
14271
static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
14272
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14273
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14274
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14275
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14276
{ } /* end */
14277
};
14278
14279
static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14280
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14281
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14282
HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14283
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14284
{ } /* end */
14285
};
14286
14287
static const struct snd_kcontrol_new alc269_asus_mixer[] = {
14288
HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14289
HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14290
{ } /* end */
14291
};
14292
14293
/* capture mixer elements */
14294
static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14295
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14296
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14297
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14298
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14299
{ } /* end */
14300
};
14301
14302
static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14303
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14304
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14305
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14306
{ } /* end */
14307
};
14308
14309
static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14310
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14311
HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14312
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14313
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14314
{ } /* end */
14315
};
14316
14317
static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14318
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14319
HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14320
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14321
{ } /* end */
14322
};
14323
14324
/* FSC amilo */
14325
#define alc269_fujitsu_mixer alc269_laptop_mixer
14326
14327
static const struct hda_verb alc269_quanta_fl1_verbs[] = {
14328
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14329
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14330
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14331
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14332
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14333
{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14334
{ }
14335
};
14336
14337
static const struct hda_verb alc269_lifebook_verbs[] = {
14338
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14339
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14340
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14341
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14342
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14343
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14344
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14345
{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14346
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14347
{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14348
{ }
14349
};
14350
14351
/* toggle speaker-output according to the hp-jack state */
14352
static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14353
{
14354
alc_hp_automute(codec);
14355
14356
snd_hda_codec_write(codec, 0x20, 0,
14357
AC_VERB_SET_COEF_INDEX, 0x0c);
14358
snd_hda_codec_write(codec, 0x20, 0,
14359
AC_VERB_SET_PROC_COEF, 0x680);
14360
14361
snd_hda_codec_write(codec, 0x20, 0,
14362
AC_VERB_SET_COEF_INDEX, 0x0c);
14363
snd_hda_codec_write(codec, 0x20, 0,
14364
AC_VERB_SET_PROC_COEF, 0x480);
14365
}
14366
14367
#define alc269_lifebook_speaker_automute \
14368
alc269_quanta_fl1_speaker_automute
14369
14370
static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14371
{
14372
unsigned int present_laptop;
14373
unsigned int present_dock;
14374
14375
present_laptop = snd_hda_jack_detect(codec, 0x18);
14376
present_dock = snd_hda_jack_detect(codec, 0x1b);
14377
14378
/* Laptop mic port overrides dock mic port, design decision */
14379
if (present_dock)
14380
snd_hda_codec_write(codec, 0x23, 0,
14381
AC_VERB_SET_CONNECT_SEL, 0x3);
14382
if (present_laptop)
14383
snd_hda_codec_write(codec, 0x23, 0,
14384
AC_VERB_SET_CONNECT_SEL, 0x0);
14385
if (!present_dock && !present_laptop)
14386
snd_hda_codec_write(codec, 0x23, 0,
14387
AC_VERB_SET_CONNECT_SEL, 0x1);
14388
}
14389
14390
static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14391
unsigned int res)
14392
{
14393
switch (res >> 26) {
14394
case ALC880_HP_EVENT:
14395
alc269_quanta_fl1_speaker_automute(codec);
14396
break;
14397
case ALC880_MIC_EVENT:
14398
alc_mic_automute(codec);
14399
break;
14400
}
14401
}
14402
14403
static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14404
unsigned int res)
14405
{
14406
if ((res >> 26) == ALC880_HP_EVENT)
14407
alc269_lifebook_speaker_automute(codec);
14408
if ((res >> 26) == ALC880_MIC_EVENT)
14409
alc269_lifebook_mic_autoswitch(codec);
14410
}
14411
14412
static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14413
{
14414
struct alc_spec *spec = codec->spec;
14415
spec->autocfg.hp_pins[0] = 0x15;
14416
spec->autocfg.speaker_pins[0] = 0x14;
14417
spec->automute_mixer_nid[0] = 0x0c;
14418
spec->automute = 1;
14419
spec->automute_mode = ALC_AUTOMUTE_MIXER;
14420
spec->ext_mic.pin = 0x18;
14421
spec->ext_mic.mux_idx = 0;
14422
spec->int_mic.pin = 0x19;
14423
spec->int_mic.mux_idx = 1;
14424
spec->auto_mic = 1;
14425
}
14426
14427
static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14428
{
14429
alc269_quanta_fl1_speaker_automute(codec);
14430
alc_mic_automute(codec);
14431
}
14432
14433
static void alc269_lifebook_setup(struct hda_codec *codec)
14434
{
14435
struct alc_spec *spec = codec->spec;
14436
spec->autocfg.hp_pins[0] = 0x15;
14437
spec->autocfg.hp_pins[1] = 0x1a;
14438
spec->autocfg.speaker_pins[0] = 0x14;
14439
spec->automute_mixer_nid[0] = 0x0c;
14440
spec->automute = 1;
14441
spec->automute_mode = ALC_AUTOMUTE_MIXER;
14442
}
14443
14444
static void alc269_lifebook_init_hook(struct hda_codec *codec)
14445
{
14446
alc269_lifebook_speaker_automute(codec);
14447
alc269_lifebook_mic_autoswitch(codec);
14448
}
14449
14450
static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14451
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14452
{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14453
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14454
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14455
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14456
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14457
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14458
{}
14459
};
14460
14461
static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
14462
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14463
{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14464
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14465
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14466
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14467
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14468
{}
14469
};
14470
14471
static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14472
{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14473
{0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14474
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14475
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14476
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14477
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14478
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14479
{}
14480
};
14481
14482
static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14483
{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14484
{0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14485
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14486
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14487
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14488
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14489
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14490
{}
14491
};
14492
14493
static const struct hda_verb alc271_acer_dmic_verbs[] = {
14494
{0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14495
{0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14496
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14497
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14498
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14499
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14500
{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14501
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14502
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14503
{0x22, AC_VERB_SET_CONNECT_SEL, 6},
14504
{ }
14505
};
14506
14507
static void alc269_laptop_amic_setup(struct hda_codec *codec)
14508
{
14509
struct alc_spec *spec = codec->spec;
14510
spec->autocfg.hp_pins[0] = 0x15;
14511
spec->autocfg.speaker_pins[0] = 0x14;
14512
spec->automute_mixer_nid[0] = 0x0c;
14513
spec->automute = 1;
14514
spec->automute_mode = ALC_AUTOMUTE_MIXER;
14515
spec->ext_mic.pin = 0x18;
14516
spec->ext_mic.mux_idx = 0;
14517
spec->int_mic.pin = 0x19;
14518
spec->int_mic.mux_idx = 1;
14519
spec->auto_mic = 1;
14520
}
14521
14522
static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14523
{
14524
struct alc_spec *spec = codec->spec;
14525
spec->autocfg.hp_pins[0] = 0x15;
14526
spec->autocfg.speaker_pins[0] = 0x14;
14527
spec->automute_mixer_nid[0] = 0x0c;
14528
spec->automute = 1;
14529
spec->automute_mode = ALC_AUTOMUTE_MIXER;
14530
spec->ext_mic.pin = 0x18;
14531
spec->ext_mic.mux_idx = 0;
14532
spec->int_mic.pin = 0x12;
14533
spec->int_mic.mux_idx = 5;
14534
spec->auto_mic = 1;
14535
}
14536
14537
static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14538
{
14539
struct alc_spec *spec = codec->spec;
14540
spec->autocfg.hp_pins[0] = 0x21;
14541
spec->autocfg.speaker_pins[0] = 0x14;
14542
spec->automute_mixer_nid[0] = 0x0c;
14543
spec->automute = 1;
14544
spec->automute_mode = ALC_AUTOMUTE_MIXER;
14545
spec->ext_mic.pin = 0x18;
14546
spec->ext_mic.mux_idx = 0;
14547
spec->int_mic.pin = 0x19;
14548
spec->int_mic.mux_idx = 1;
14549
spec->auto_mic = 1;
14550
}
14551
14552
static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14553
{
14554
struct alc_spec *spec = codec->spec;
14555
spec->autocfg.hp_pins[0] = 0x21;
14556
spec->autocfg.speaker_pins[0] = 0x14;
14557
spec->automute_mixer_nid[0] = 0x0c;
14558
spec->automute = 1;
14559
spec->automute_mode = ALC_AUTOMUTE_MIXER;
14560
spec->ext_mic.pin = 0x18;
14561
spec->ext_mic.mux_idx = 0;
14562
spec->int_mic.pin = 0x12;
14563
spec->int_mic.mux_idx = 6;
14564
spec->auto_mic = 1;
14565
}
14566
14567
/*
14568
* generic initialization of ADC, input mixers and output mixers
14569
*/
14570
static const struct hda_verb alc269_init_verbs[] = {
14571
/*
14572
* Unmute ADC0 and set the default input to mic-in
14573
*/
14574
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14575
14576
/*
14577
* Set up output mixers (0x02 - 0x03)
14578
*/
14579
/* set vol=0 to output mixers */
14580
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14581
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14582
14583
/* set up input amps for analog loopback */
14584
/* Amp Indices: DAC = 0, mixer = 1 */
14585
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14586
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14587
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14588
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14589
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14590
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14591
14592
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14593
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14594
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14595
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14596
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14597
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14598
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14599
14600
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14601
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14602
14603
/* FIXME: use Mux-type input source selection */
14604
/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14605
/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14606
{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14607
14608
/* set EAPD */
14609
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14610
{ }
14611
};
14612
14613
static const struct hda_verb alc269vb_init_verbs[] = {
14614
/*
14615
* Unmute ADC0 and set the default input to mic-in
14616
*/
14617
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14618
14619
/*
14620
* Set up output mixers (0x02 - 0x03)
14621
*/
14622
/* set vol=0 to output mixers */
14623
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14624
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14625
14626
/* set up input amps for analog loopback */
14627
/* Amp Indices: DAC = 0, mixer = 1 */
14628
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14629
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14630
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14631
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14632
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14633
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14634
14635
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14636
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14637
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14638
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14639
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14640
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14641
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14642
14643
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14644
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14645
14646
/* FIXME: use Mux-type input source selection */
14647
/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14648
/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14649
{0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14650
14651
/* set EAPD */
14652
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14653
{ }
14654
};
14655
14656
#define alc269_auto_create_multi_out_ctls \
14657
alc268_auto_create_multi_out_ctls
14658
#define alc269_auto_create_input_ctls \
14659
alc268_auto_create_input_ctls
14660
14661
#ifdef CONFIG_SND_HDA_POWER_SAVE
14662
#define alc269_loopbacks alc880_loopbacks
14663
#endif
14664
14665
/* pcm configuration: identical with ALC880 */
14666
#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14667
#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14668
#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14669
#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14670
14671
static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14672
.substreams = 1,
14673
.channels_min = 2,
14674
.channels_max = 8,
14675
.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14676
/* NID is set in alc_build_pcms */
14677
.ops = {
14678
.open = alc880_playback_pcm_open,
14679
.prepare = alc880_playback_pcm_prepare,
14680
.cleanup = alc880_playback_pcm_cleanup
14681
},
14682
};
14683
14684
static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14685
.substreams = 1,
14686
.channels_min = 2,
14687
.channels_max = 2,
14688
.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14689
/* NID is set in alc_build_pcms */
14690
};
14691
14692
#ifdef CONFIG_SND_HDA_POWER_SAVE
14693
static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14694
{
14695
switch (codec->subsystem_id) {
14696
case 0x103c1586:
14697
return 1;
14698
}
14699
return 0;
14700
}
14701
14702
static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14703
{
14704
/* update mute-LED according to the speaker mute state */
14705
if (nid == 0x01 || nid == 0x14) {
14706
int pinval;
14707
if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14708
HDA_AMP_MUTE)
14709
pinval = 0x24;
14710
else
14711
pinval = 0x20;
14712
/* mic2 vref pin is used for mute LED control */
14713
snd_hda_codec_update_cache(codec, 0x19, 0,
14714
AC_VERB_SET_PIN_WIDGET_CONTROL,
14715
pinval);
14716
}
14717
return alc_check_power_status(codec, nid);
14718
}
14719
#endif /* CONFIG_SND_HDA_POWER_SAVE */
14720
14721
static int alc275_setup_dual_adc(struct hda_codec *codec)
14722
{
14723
struct alc_spec *spec = codec->spec;
14724
14725
if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14726
return 0;
14727
if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14728
(spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14729
if (spec->ext_mic.pin <= 0x12) {
14730
spec->private_adc_nids[0] = 0x08;
14731
spec->private_adc_nids[1] = 0x11;
14732
spec->private_capsrc_nids[0] = 0x23;
14733
spec->private_capsrc_nids[1] = 0x22;
14734
} else {
14735
spec->private_adc_nids[0] = 0x11;
14736
spec->private_adc_nids[1] = 0x08;
14737
spec->private_capsrc_nids[0] = 0x22;
14738
spec->private_capsrc_nids[1] = 0x23;
14739
}
14740
spec->adc_nids = spec->private_adc_nids;
14741
spec->capsrc_nids = spec->private_capsrc_nids;
14742
spec->num_adc_nids = 2;
14743
spec->dual_adc_switch = 1;
14744
snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14745
spec->adc_nids[0], spec->adc_nids[1]);
14746
return 1;
14747
}
14748
return 0;
14749
}
14750
14751
/* different alc269-variants */
14752
enum {
14753
ALC269_TYPE_NORMAL,
14754
ALC269_TYPE_ALC258,
14755
ALC269_TYPE_ALC259,
14756
ALC269_TYPE_ALC269VB,
14757
ALC269_TYPE_ALC270,
14758
ALC269_TYPE_ALC271X,
14759
};
14760
14761
/*
14762
* BIOS auto configuration
14763
*/
14764
static int alc269_parse_auto_config(struct hda_codec *codec)
14765
{
14766
struct alc_spec *spec = codec->spec;
14767
int err;
14768
static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14769
14770
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14771
alc269_ignore);
14772
if (err < 0)
14773
return err;
14774
14775
err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14776
if (err < 0)
14777
return err;
14778
if (spec->codec_variant == ALC269_TYPE_NORMAL)
14779
err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14780
else
14781
err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14782
0x22, 0);
14783
if (err < 0)
14784
return err;
14785
14786
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14787
14788
alc_auto_parse_digital(codec);
14789
14790
if (spec->kctls.list)
14791
add_mixer(spec, spec->kctls.list);
14792
14793
if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14794
add_verb(spec, alc269vb_init_verbs);
14795
alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14796
} else {
14797
add_verb(spec, alc269_init_verbs);
14798
alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14799
}
14800
14801
spec->num_mux_defs = 1;
14802
spec->input_mux = &spec->private_imux[0];
14803
14804
if (!alc275_setup_dual_adc(codec))
14805
fillup_priv_adc_nids(codec, alc269_adc_candidates,
14806
sizeof(alc269_adc_candidates));
14807
14808
err = alc_auto_add_mic_boost(codec);
14809
if (err < 0)
14810
return err;
14811
14812
if (!spec->cap_mixer && !spec->no_analog)
14813
set_capture_mixer(codec);
14814
14815
return 1;
14816
}
14817
14818
#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14819
#define alc269_auto_init_hp_out alc268_auto_init_hp_out
14820
#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14821
#define alc269_auto_init_input_src alc882_auto_init_input_src
14822
14823
14824
/* init callback for auto-configuration model -- overriding the default init */
14825
static void alc269_auto_init(struct hda_codec *codec)
14826
{
14827
struct alc_spec *spec = codec->spec;
14828
alc269_auto_init_multi_out(codec);
14829
alc269_auto_init_hp_out(codec);
14830
alc269_auto_init_analog_input(codec);
14831
if (!spec->dual_adc_switch)
14832
alc269_auto_init_input_src(codec);
14833
alc_auto_init_digital(codec);
14834
if (spec->unsol_event)
14835
alc_inithook(codec);
14836
}
14837
14838
static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14839
{
14840
int val = alc_read_coef_idx(codec, 0x04);
14841
if (power_up)
14842
val |= 1 << 11;
14843
else
14844
val &= ~(1 << 11);
14845
alc_write_coef_idx(codec, 0x04, val);
14846
}
14847
14848
static void alc269_shutup(struct hda_codec *codec)
14849
{
14850
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14851
alc269_toggle_power_output(codec, 0);
14852
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14853
alc269_toggle_power_output(codec, 0);
14854
msleep(150);
14855
}
14856
}
14857
14858
#ifdef SND_HDA_NEEDS_RESUME
14859
static int alc269_resume(struct hda_codec *codec)
14860
{
14861
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14862
alc269_toggle_power_output(codec, 0);
14863
msleep(150);
14864
}
14865
14866
codec->patch_ops.init(codec);
14867
14868
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14869
alc269_toggle_power_output(codec, 1);
14870
msleep(200);
14871
}
14872
14873
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14874
alc269_toggle_power_output(codec, 1);
14875
14876
snd_hda_codec_resume_amp(codec);
14877
snd_hda_codec_resume_cache(codec);
14878
hda_call_check_power_status(codec, 0x01);
14879
return 0;
14880
}
14881
#endif /* SND_HDA_NEEDS_RESUME */
14882
14883
static void alc269_fixup_hweq(struct hda_codec *codec,
14884
const struct alc_fixup *fix, int action)
14885
{
14886
int coef;
14887
14888
if (action != ALC_FIXUP_ACT_INIT)
14889
return;
14890
coef = alc_read_coef_idx(codec, 0x1e);
14891
alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14892
}
14893
14894
static void alc271_fixup_dmic(struct hda_codec *codec,
14895
const struct alc_fixup *fix, int action)
14896
{
14897
static const struct hda_verb verbs[] = {
14898
{0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14899
{0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14900
{}
14901
};
14902
unsigned int cfg;
14903
14904
if (strcmp(codec->chip_name, "ALC271X"))
14905
return;
14906
cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14907
if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14908
snd_hda_sequence_write(codec, verbs);
14909
}
14910
14911
enum {
14912
ALC269_FIXUP_SONY_VAIO,
14913
ALC275_FIXUP_SONY_VAIO_GPIO2,
14914
ALC269_FIXUP_DELL_M101Z,
14915
ALC269_FIXUP_SKU_IGNORE,
14916
ALC269_FIXUP_ASUS_G73JW,
14917
ALC269_FIXUP_LENOVO_EAPD,
14918
ALC275_FIXUP_SONY_HWEQ,
14919
ALC271_FIXUP_DMIC,
14920
};
14921
14922
static const struct alc_fixup alc269_fixups[] = {
14923
[ALC269_FIXUP_SONY_VAIO] = {
14924
.type = ALC_FIXUP_VERBS,
14925
.v.verbs = (const struct hda_verb[]) {
14926
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14927
{}
14928
}
14929
},
14930
[ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14931
.type = ALC_FIXUP_VERBS,
14932
.v.verbs = (const struct hda_verb[]) {
14933
{0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14934
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14935
{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14936
{ }
14937
},
14938
.chained = true,
14939
.chain_id = ALC269_FIXUP_SONY_VAIO
14940
},
14941
[ALC269_FIXUP_DELL_M101Z] = {
14942
.type = ALC_FIXUP_VERBS,
14943
.v.verbs = (const struct hda_verb[]) {
14944
/* Enables internal speaker */
14945
{0x20, AC_VERB_SET_COEF_INDEX, 13},
14946
{0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14947
{}
14948
}
14949
},
14950
[ALC269_FIXUP_SKU_IGNORE] = {
14951
.type = ALC_FIXUP_SKU,
14952
.v.sku = ALC_FIXUP_SKU_IGNORE,
14953
},
14954
[ALC269_FIXUP_ASUS_G73JW] = {
14955
.type = ALC_FIXUP_PINS,
14956
.v.pins = (const struct alc_pincfg[]) {
14957
{ 0x17, 0x99130111 }, /* subwoofer */
14958
{ }
14959
}
14960
},
14961
[ALC269_FIXUP_LENOVO_EAPD] = {
14962
.type = ALC_FIXUP_VERBS,
14963
.v.verbs = (const struct hda_verb[]) {
14964
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14965
{}
14966
}
14967
},
14968
[ALC275_FIXUP_SONY_HWEQ] = {
14969
.type = ALC_FIXUP_FUNC,
14970
.v.func = alc269_fixup_hweq,
14971
.chained = true,
14972
.chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14973
},
14974
[ALC271_FIXUP_DMIC] = {
14975
.type = ALC_FIXUP_FUNC,
14976
.v.func = alc271_fixup_dmic,
14977
},
14978
};
14979
14980
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14981
SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14982
SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14983
SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14984
SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14985
SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14986
SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
14987
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14988
SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14989
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14990
SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14991
SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14992
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14993
SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14994
{}
14995
};
14996
14997
14998
/*
14999
* configuration and preset
15000
*/
15001
static const char * const alc269_models[ALC269_MODEL_LAST] = {
15002
[ALC269_BASIC] = "basic",
15003
[ALC269_QUANTA_FL1] = "quanta",
15004
[ALC269_AMIC] = "laptop-amic",
15005
[ALC269_DMIC] = "laptop-dmic",
15006
[ALC269_FUJITSU] = "fujitsu",
15007
[ALC269_LIFEBOOK] = "lifebook",
15008
[ALC269_AUTO] = "auto",
15009
};
15010
15011
static const struct snd_pci_quirk alc269_cfg_tbl[] = {
15012
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
15013
SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
15014
SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
15015
ALC269_AMIC),
15016
SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
15017
SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
15018
SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
15019
SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
15020
SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
15021
SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
15022
SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
15023
SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15024
SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
15025
SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
15026
SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15027
SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15028
SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15029
SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15030
SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15031
SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15032
SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15033
SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15034
SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15035
SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15036
SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15037
SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15038
SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15039
SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15040
SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15041
SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15042
SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15043
SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15044
SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15045
SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15046
SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15047
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15048
SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15049
SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15050
SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15051
SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
15052
SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
15053
ALC269_DMIC),
15054
SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
15055
ALC269_DMIC),
15056
SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15057
SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
15058
SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
15059
SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
15060
SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15061
SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15062
SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15063
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15064
SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15065
SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
15066
{}
15067
};
15068
15069
static const struct alc_config_preset alc269_presets[] = {
15070
[ALC269_BASIC] = {
15071
.mixers = { alc269_base_mixer },
15072
.init_verbs = { alc269_init_verbs },
15073
.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15074
.dac_nids = alc269_dac_nids,
15075
.hp_nid = 0x03,
15076
.num_channel_mode = ARRAY_SIZE(alc269_modes),
15077
.channel_mode = alc269_modes,
15078
.input_mux = &alc269_capture_source,
15079
},
15080
[ALC269_QUANTA_FL1] = {
15081
.mixers = { alc269_quanta_fl1_mixer },
15082
.init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15083
.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15084
.dac_nids = alc269_dac_nids,
15085
.hp_nid = 0x03,
15086
.num_channel_mode = ARRAY_SIZE(alc269_modes),
15087
.channel_mode = alc269_modes,
15088
.input_mux = &alc269_capture_source,
15089
.unsol_event = alc269_quanta_fl1_unsol_event,
15090
.setup = alc269_quanta_fl1_setup,
15091
.init_hook = alc269_quanta_fl1_init_hook,
15092
},
15093
[ALC269_AMIC] = {
15094
.mixers = { alc269_laptop_mixer },
15095
.cap_mixer = alc269_laptop_analog_capture_mixer,
15096
.init_verbs = { alc269_init_verbs,
15097
alc269_laptop_amic_init_verbs },
15098
.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15099
.dac_nids = alc269_dac_nids,
15100
.hp_nid = 0x03,
15101
.num_channel_mode = ARRAY_SIZE(alc269_modes),
15102
.channel_mode = alc269_modes,
15103
.unsol_event = alc_sku_unsol_event,
15104
.setup = alc269_laptop_amic_setup,
15105
.init_hook = alc_inithook,
15106
},
15107
[ALC269_DMIC] = {
15108
.mixers = { alc269_laptop_mixer },
15109
.cap_mixer = alc269_laptop_digital_capture_mixer,
15110
.init_verbs = { alc269_init_verbs,
15111
alc269_laptop_dmic_init_verbs },
15112
.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15113
.dac_nids = alc269_dac_nids,
15114
.hp_nid = 0x03,
15115
.num_channel_mode = ARRAY_SIZE(alc269_modes),
15116
.channel_mode = alc269_modes,
15117
.unsol_event = alc_sku_unsol_event,
15118
.setup = alc269_laptop_dmic_setup,
15119
.init_hook = alc_inithook,
15120
},
15121
[ALC269VB_AMIC] = {
15122
.mixers = { alc269vb_laptop_mixer },
15123
.cap_mixer = alc269vb_laptop_analog_capture_mixer,
15124
.init_verbs = { alc269vb_init_verbs,
15125
alc269vb_laptop_amic_init_verbs },
15126
.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15127
.dac_nids = alc269_dac_nids,
15128
.hp_nid = 0x03,
15129
.num_channel_mode = ARRAY_SIZE(alc269_modes),
15130
.channel_mode = alc269_modes,
15131
.unsol_event = alc_sku_unsol_event,
15132
.setup = alc269vb_laptop_amic_setup,
15133
.init_hook = alc_inithook,
15134
},
15135
[ALC269VB_DMIC] = {
15136
.mixers = { alc269vb_laptop_mixer },
15137
.cap_mixer = alc269vb_laptop_digital_capture_mixer,
15138
.init_verbs = { alc269vb_init_verbs,
15139
alc269vb_laptop_dmic_init_verbs },
15140
.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15141
.dac_nids = alc269_dac_nids,
15142
.hp_nid = 0x03,
15143
.num_channel_mode = ARRAY_SIZE(alc269_modes),
15144
.channel_mode = alc269_modes,
15145
.unsol_event = alc_sku_unsol_event,
15146
.setup = alc269vb_laptop_dmic_setup,
15147
.init_hook = alc_inithook,
15148
},
15149
[ALC269_FUJITSU] = {
15150
.mixers = { alc269_fujitsu_mixer },
15151
.cap_mixer = alc269_laptop_digital_capture_mixer,
15152
.init_verbs = { alc269_init_verbs,
15153
alc269_laptop_dmic_init_verbs },
15154
.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15155
.dac_nids = alc269_dac_nids,
15156
.hp_nid = 0x03,
15157
.num_channel_mode = ARRAY_SIZE(alc269_modes),
15158
.channel_mode = alc269_modes,
15159
.unsol_event = alc_sku_unsol_event,
15160
.setup = alc269_laptop_dmic_setup,
15161
.init_hook = alc_inithook,
15162
},
15163
[ALC269_LIFEBOOK] = {
15164
.mixers = { alc269_lifebook_mixer },
15165
.init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15166
.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15167
.dac_nids = alc269_dac_nids,
15168
.hp_nid = 0x03,
15169
.num_channel_mode = ARRAY_SIZE(alc269_modes),
15170
.channel_mode = alc269_modes,
15171
.input_mux = &alc269_capture_source,
15172
.unsol_event = alc269_lifebook_unsol_event,
15173
.setup = alc269_lifebook_setup,
15174
.init_hook = alc269_lifebook_init_hook,
15175
},
15176
[ALC271_ACER] = {
15177
.mixers = { alc269_asus_mixer },
15178
.cap_mixer = alc269vb_laptop_digital_capture_mixer,
15179
.init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15180
.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15181
.dac_nids = alc269_dac_nids,
15182
.adc_nids = alc262_dmic_adc_nids,
15183
.num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15184
.capsrc_nids = alc262_dmic_capsrc_nids,
15185
.num_channel_mode = ARRAY_SIZE(alc269_modes),
15186
.channel_mode = alc269_modes,
15187
.input_mux = &alc269_capture_source,
15188
.dig_out_nid = ALC880_DIGOUT_NID,
15189
.unsol_event = alc_sku_unsol_event,
15190
.setup = alc269vb_laptop_dmic_setup,
15191
.init_hook = alc_inithook,
15192
},
15193
};
15194
15195
static int alc269_fill_coef(struct hda_codec *codec)
15196
{
15197
int val;
15198
15199
if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15200
alc_write_coef_idx(codec, 0xf, 0x960b);
15201
alc_write_coef_idx(codec, 0xe, 0x8817);
15202
}
15203
15204
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15205
alc_write_coef_idx(codec, 0xf, 0x960b);
15206
alc_write_coef_idx(codec, 0xe, 0x8814);
15207
}
15208
15209
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15210
val = alc_read_coef_idx(codec, 0x04);
15211
/* Power up output pin */
15212
alc_write_coef_idx(codec, 0x04, val | (1<<11));
15213
}
15214
15215
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15216
val = alc_read_coef_idx(codec, 0xd);
15217
if ((val & 0x0c00) >> 10 != 0x1) {
15218
/* Capless ramp up clock control */
15219
alc_write_coef_idx(codec, 0xd, val | (1<<10));
15220
}
15221
val = alc_read_coef_idx(codec, 0x17);
15222
if ((val & 0x01c0) >> 6 != 0x4) {
15223
/* Class D power on reset */
15224
alc_write_coef_idx(codec, 0x17, val | (1<<7));
15225
}
15226
}
15227
15228
val = alc_read_coef_idx(codec, 0xd); /* Class D */
15229
alc_write_coef_idx(codec, 0xd, val | (1<<14));
15230
15231
val = alc_read_coef_idx(codec, 0x4); /* HP */
15232
alc_write_coef_idx(codec, 0x4, val | (1<<11));
15233
15234
return 0;
15235
}
15236
15237
static int patch_alc269(struct hda_codec *codec)
15238
{
15239
struct alc_spec *spec;
15240
int board_config, coef;
15241
int err;
15242
15243
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15244
if (spec == NULL)
15245
return -ENOMEM;
15246
15247
codec->spec = spec;
15248
15249
alc_auto_parse_customize_define(codec);
15250
15251
if (codec->vendor_id == 0x10ec0269) {
15252
coef = alc_read_coef_idx(codec, 0);
15253
if ((coef & 0x00f0) == 0x0010) {
15254
if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15255
spec->cdefine.platform_type == 1) {
15256
alc_codec_rename(codec, "ALC271X");
15257
spec->codec_variant = ALC269_TYPE_ALC271X;
15258
} else if ((coef & 0xf000) == 0x1000) {
15259
spec->codec_variant = ALC269_TYPE_ALC270;
15260
} else if ((coef & 0xf000) == 0x2000) {
15261
alc_codec_rename(codec, "ALC259");
15262
spec->codec_variant = ALC269_TYPE_ALC259;
15263
} else if ((coef & 0xf000) == 0x3000) {
15264
alc_codec_rename(codec, "ALC258");
15265
spec->codec_variant = ALC269_TYPE_ALC258;
15266
} else {
15267
alc_codec_rename(codec, "ALC269VB");
15268
spec->codec_variant = ALC269_TYPE_ALC269VB;
15269
}
15270
} else
15271
alc_fix_pll_init(codec, 0x20, 0x04, 15);
15272
alc269_fill_coef(codec);
15273
}
15274
15275
board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15276
alc269_models,
15277
alc269_cfg_tbl);
15278
15279
if (board_config < 0) {
15280
printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15281
codec->chip_name);
15282
board_config = ALC269_AUTO;
15283
}
15284
15285
if (board_config == ALC269_AUTO) {
15286
alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15287
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15288
}
15289
15290
if (board_config == ALC269_AUTO) {
15291
/* automatic parse from the BIOS config */
15292
err = alc269_parse_auto_config(codec);
15293
if (err < 0) {
15294
alc_free(codec);
15295
return err;
15296
} else if (!err) {
15297
printk(KERN_INFO
15298
"hda_codec: Cannot set up configuration "
15299
"from BIOS. Using base mode...\n");
15300
board_config = ALC269_BASIC;
15301
}
15302
}
15303
15304
if (has_cdefine_beep(codec)) {
15305
err = snd_hda_attach_beep_device(codec, 0x1);
15306
if (err < 0) {
15307
alc_free(codec);
15308
return err;
15309
}
15310
}
15311
15312
if (board_config != ALC269_AUTO)
15313
setup_preset(codec, &alc269_presets[board_config]);
15314
15315
if (board_config == ALC269_QUANTA_FL1) {
15316
/* Due to a hardware problem on Lenovo Ideadpad, we need to
15317
* fix the sample rate of analog I/O to 44.1kHz
15318
*/
15319
spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15320
spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15321
} else if (spec->dual_adc_switch) {
15322
spec->stream_analog_playback = &alc269_pcm_analog_playback;
15323
/* switch ADC dynamically */
15324
spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15325
} else {
15326
spec->stream_analog_playback = &alc269_pcm_analog_playback;
15327
spec->stream_analog_capture = &alc269_pcm_analog_capture;
15328
}
15329
spec->stream_digital_playback = &alc269_pcm_digital_playback;
15330
spec->stream_digital_capture = &alc269_pcm_digital_capture;
15331
15332
if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15333
if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15334
spec->adc_nids = alc269_adc_nids;
15335
spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15336
spec->capsrc_nids = alc269_capsrc_nids;
15337
} else {
15338
spec->adc_nids = alc269vb_adc_nids;
15339
spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15340
spec->capsrc_nids = alc269vb_capsrc_nids;
15341
}
15342
}
15343
15344
if (!spec->cap_mixer)
15345
set_capture_mixer(codec);
15346
if (has_cdefine_beep(codec))
15347
set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15348
15349
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15350
15351
spec->vmaster_nid = 0x02;
15352
15353
codec->patch_ops = alc_patch_ops;
15354
#ifdef SND_HDA_NEEDS_RESUME
15355
codec->patch_ops.resume = alc269_resume;
15356
#endif
15357
if (board_config == ALC269_AUTO)
15358
spec->init_hook = alc269_auto_init;
15359
spec->shutup = alc269_shutup;
15360
15361
alc_init_jacks(codec);
15362
#ifdef CONFIG_SND_HDA_POWER_SAVE
15363
if (!spec->loopback.amplist)
15364
spec->loopback.amplist = alc269_loopbacks;
15365
if (alc269_mic2_for_mute_led(codec))
15366
codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
15367
#endif
15368
15369
return 0;
15370
}
15371
15372
/*
15373
* ALC861 channel source setting (2/6 channel selection for 3-stack)
15374
*/
15375
15376
/*
15377
* set the path ways for 2 channel output
15378
* need to set the codec line out and mic 1 pin widgets to inputs
15379
*/
15380
static const struct hda_verb alc861_threestack_ch2_init[] = {
15381
/* set pin widget 1Ah (line in) for input */
15382
{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15383
/* set pin widget 18h (mic1/2) for input, for mic also enable
15384
* the vref
15385
*/
15386
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15387
15388
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15389
#if 0
15390
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15391
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15392
#endif
15393
{ } /* end */
15394
};
15395
/*
15396
* 6ch mode
15397
* need to set the codec line out and mic 1 pin widgets to outputs
15398
*/
15399
static const struct hda_verb alc861_threestack_ch6_init[] = {
15400
/* set pin widget 1Ah (line in) for output (Back Surround)*/
15401
{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15402
/* set pin widget 18h (mic1) for output (CLFE)*/
15403
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15404
15405
{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15406
{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15407
15408
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15409
#if 0
15410
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15411
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15412
#endif
15413
{ } /* end */
15414
};
15415
15416
static const struct hda_channel_mode alc861_threestack_modes[2] = {
15417
{ 2, alc861_threestack_ch2_init },
15418
{ 6, alc861_threestack_ch6_init },
15419
};
15420
/* Set mic1 as input and unmute the mixer */
15421
static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15422
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15423
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15424
{ } /* end */
15425
};
15426
/* Set mic1 as output and mute mixer */
15427
static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15428
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15429
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15430
{ } /* end */
15431
};
15432
15433
static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15434
{ 2, alc861_uniwill_m31_ch2_init },
15435
{ 4, alc861_uniwill_m31_ch4_init },
15436
};
15437
15438
/* Set mic1 and line-in as input and unmute the mixer */
15439
static const struct hda_verb alc861_asus_ch2_init[] = {
15440
/* set pin widget 1Ah (line in) for input */
15441
{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15442
/* set pin widget 18h (mic1/2) for input, for mic also enable
15443
* the vref
15444
*/
15445
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15446
15447
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15448
#if 0
15449
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15450
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15451
#endif
15452
{ } /* end */
15453
};
15454
/* Set mic1 nad line-in as output and mute mixer */
15455
static const struct hda_verb alc861_asus_ch6_init[] = {
15456
/* set pin widget 1Ah (line in) for output (Back Surround)*/
15457
{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15458
/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15459
/* set pin widget 18h (mic1) for output (CLFE)*/
15460
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15461
/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15462
{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15463
{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15464
15465
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15466
#if 0
15467
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15468
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15469
#endif
15470
{ } /* end */
15471
};
15472
15473
static const struct hda_channel_mode alc861_asus_modes[2] = {
15474
{ 2, alc861_asus_ch2_init },
15475
{ 6, alc861_asus_ch6_init },
15476
};
15477
15478
/* patch-ALC861 */
15479
15480
static const struct snd_kcontrol_new alc861_base_mixer[] = {
15481
/* output mixer control */
15482
HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15483
HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15484
HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15485
HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15486
HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15487
15488
/*Input mixer control */
15489
/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15490
HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15491
HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15492
HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15493
HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15494
HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15495
HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15496
HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15497
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15498
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15499
15500
{ } /* end */
15501
};
15502
15503
static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
15504
/* output mixer control */
15505
HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15506
HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15507
HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15508
HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15509
/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15510
15511
/* Input mixer control */
15512
/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15513
HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15514
HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15515
HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15516
HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15517
HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15518
HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15519
HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15520
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15521
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15522
15523
{
15524
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15525
.name = "Channel Mode",
15526
.info = alc_ch_mode_info,
15527
.get = alc_ch_mode_get,
15528
.put = alc_ch_mode_put,
15529
.private_value = ARRAY_SIZE(alc861_threestack_modes),
15530
},
15531
{ } /* end */
15532
};
15533
15534
static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15535
/* output mixer control */
15536
HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15537
HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15538
HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15539
15540
{ } /* end */
15541
};
15542
15543
static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15544
/* output mixer control */
15545
HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15546
HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15547
HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15548
HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15549
/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15550
15551
/* Input mixer control */
15552
/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15553
HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15554
HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15555
HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15556
HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15557
HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15558
HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15559
HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15560
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15561
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15562
15563
{
15564
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15565
.name = "Channel Mode",
15566
.info = alc_ch_mode_info,
15567
.get = alc_ch_mode_get,
15568
.put = alc_ch_mode_put,
15569
.private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15570
},
15571
{ } /* end */
15572
};
15573
15574
static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15575
/* output mixer control */
15576
HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15577
HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15578
HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15579
HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15580
HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15581
15582
/* Input mixer control */
15583
HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15584
HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15585
HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15586
HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15587
HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15588
HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15589
HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15590
HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15591
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15592
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15593
15594
{
15595
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15596
.name = "Channel Mode",
15597
.info = alc_ch_mode_info,
15598
.get = alc_ch_mode_get,
15599
.put = alc_ch_mode_put,
15600
.private_value = ARRAY_SIZE(alc861_asus_modes),
15601
},
15602
{ }
15603
};
15604
15605
/* additional mixer */
15606
static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15607
HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15608
HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15609
{ }
15610
};
15611
15612
/*
15613
* generic initialization of ADC, input mixers and output mixers
15614
*/
15615
static const struct hda_verb alc861_base_init_verbs[] = {
15616
/*
15617
* Unmute ADC0 and set the default input to mic-in
15618
*/
15619
/* port-A for surround (rear panel) */
15620
{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15621
{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15622
/* port-B for mic-in (rear panel) with vref */
15623
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15624
/* port-C for line-in (rear panel) */
15625
{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15626
/* port-D for Front */
15627
{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15628
{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15629
/* port-E for HP out (front panel) */
15630
{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15631
/* route front PCM to HP */
15632
{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15633
/* port-F for mic-in (front panel) with vref */
15634
{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15635
/* port-G for CLFE (rear panel) */
15636
{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15637
{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15638
/* port-H for side (rear panel) */
15639
{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15640
{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15641
/* CD-in */
15642
{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15643
/* route front mic to ADC1*/
15644
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15645
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15646
15647
/* Unmute DAC0~3 & spdif out*/
15648
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15649
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15650
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15651
{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15652
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15653
15654
/* Unmute Mixer 14 (mic) 1c (Line in)*/
15655
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15656
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15657
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15658
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15659
15660
/* Unmute Stereo Mixer 15 */
15661
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15662
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15663
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15664
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15665
15666
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15667
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15668
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15669
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15670
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15671
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15672
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15673
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15674
/* hp used DAC 3 (Front) */
15675
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15676
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15677
15678
{ }
15679
};
15680
15681
static const struct hda_verb alc861_threestack_init_verbs[] = {
15682
/*
15683
* Unmute ADC0 and set the default input to mic-in
15684
*/
15685
/* port-A for surround (rear panel) */
15686
{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15687
/* port-B for mic-in (rear panel) with vref */
15688
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15689
/* port-C for line-in (rear panel) */
15690
{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15691
/* port-D for Front */
15692
{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15693
{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15694
/* port-E for HP out (front panel) */
15695
{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15696
/* route front PCM to HP */
15697
{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15698
/* port-F for mic-in (front panel) with vref */
15699
{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15700
/* port-G for CLFE (rear panel) */
15701
{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15702
/* port-H for side (rear panel) */
15703
{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15704
/* CD-in */
15705
{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15706
/* route front mic to ADC1*/
15707
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15708
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15709
/* Unmute DAC0~3 & spdif out*/
15710
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15711
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15712
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15713
{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15714
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15715
15716
/* Unmute Mixer 14 (mic) 1c (Line in)*/
15717
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15718
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15719
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15720
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15721
15722
/* Unmute Stereo Mixer 15 */
15723
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15724
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15725
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15726
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15727
15728
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15729
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15730
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15731
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15732
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15733
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15734
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15735
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15736
/* hp used DAC 3 (Front) */
15737
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15738
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15739
{ }
15740
};
15741
15742
static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15743
/*
15744
* Unmute ADC0 and set the default input to mic-in
15745
*/
15746
/* port-A for surround (rear panel) */
15747
{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15748
/* port-B for mic-in (rear panel) with vref */
15749
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15750
/* port-C for line-in (rear panel) */
15751
{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15752
/* port-D for Front */
15753
{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15754
{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15755
/* port-E for HP out (front panel) */
15756
/* this has to be set to VREF80 */
15757
{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15758
/* route front PCM to HP */
15759
{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15760
/* port-F for mic-in (front panel) with vref */
15761
{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15762
/* port-G for CLFE (rear panel) */
15763
{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15764
/* port-H for side (rear panel) */
15765
{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15766
/* CD-in */
15767
{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15768
/* route front mic to ADC1*/
15769
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15770
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15771
/* Unmute DAC0~3 & spdif out*/
15772
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15773
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15774
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15775
{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15776
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15777
15778
/* Unmute Mixer 14 (mic) 1c (Line in)*/
15779
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15780
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15781
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15782
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15783
15784
/* Unmute Stereo Mixer 15 */
15785
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15786
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15787
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15788
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15789
15790
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15791
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15792
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15793
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15794
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15795
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15796
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15797
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15798
/* hp used DAC 3 (Front) */
15799
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15800
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15801
{ }
15802
};
15803
15804
static const struct hda_verb alc861_asus_init_verbs[] = {
15805
/*
15806
* Unmute ADC0 and set the default input to mic-in
15807
*/
15808
/* port-A for surround (rear panel)
15809
* according to codec#0 this is the HP jack
15810
*/
15811
{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15812
/* route front PCM to HP */
15813
{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15814
/* port-B for mic-in (rear panel) with vref */
15815
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15816
/* port-C for line-in (rear panel) */
15817
{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15818
/* port-D for Front */
15819
{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15820
{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15821
/* port-E for HP out (front panel) */
15822
/* this has to be set to VREF80 */
15823
{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15824
/* route front PCM to HP */
15825
{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15826
/* port-F for mic-in (front panel) with vref */
15827
{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15828
/* port-G for CLFE (rear panel) */
15829
{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15830
/* port-H for side (rear panel) */
15831
{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15832
/* CD-in */
15833
{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15834
/* route front mic to ADC1*/
15835
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15836
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15837
/* Unmute DAC0~3 & spdif out*/
15838
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15839
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15840
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15841
{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15842
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15843
/* Unmute Mixer 14 (mic) 1c (Line in)*/
15844
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15845
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15846
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15847
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15848
15849
/* Unmute Stereo Mixer 15 */
15850
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15851
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15852
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15853
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15854
15855
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15856
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15857
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15858
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15859
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15860
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15861
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15862
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15863
/* hp used DAC 3 (Front) */
15864
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15865
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15866
{ }
15867
};
15868
15869
/* additional init verbs for ASUS laptops */
15870
static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15871
{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15872
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15873
{ }
15874
};
15875
15876
/*
15877
* generic initialization of ADC, input mixers and output mixers
15878
*/
15879
static const struct hda_verb alc861_auto_init_verbs[] = {
15880
/*
15881
* Unmute ADC0 and set the default input to mic-in
15882
*/
15883
/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15884
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15885
15886
/* Unmute DAC0~3 & spdif out*/
15887
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15888
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15889
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15890
{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15891
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15892
15893
/* Unmute Mixer 14 (mic) 1c (Line in)*/
15894
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15895
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15896
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15897
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15898
15899
/* Unmute Stereo Mixer 15 */
15900
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15901
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15902
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15903
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15904
15905
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15906
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15907
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15908
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15909
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15910
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15911
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15912
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15913
15914
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15915
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15916
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15917
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15918
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15919
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15920
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15921
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15922
15923
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
15924
15925
{ }
15926
};
15927
15928
static const struct hda_verb alc861_toshiba_init_verbs[] = {
15929
{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15930
15931
{ }
15932
};
15933
15934
/* toggle speaker-output according to the hp-jack state */
15935
static void alc861_toshiba_automute(struct hda_codec *codec)
15936
{
15937
unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15938
15939
snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15940
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15941
snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15942
HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15943
}
15944
15945
static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15946
unsigned int res)
15947
{
15948
if ((res >> 26) == ALC880_HP_EVENT)
15949
alc861_toshiba_automute(codec);
15950
}
15951
15952
/* pcm configuration: identical with ALC880 */
15953
#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15954
#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15955
#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15956
#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15957
15958
15959
#define ALC861_DIGOUT_NID 0x07
15960
15961
static const struct hda_channel_mode alc861_8ch_modes[1] = {
15962
{ 8, NULL }
15963
};
15964
15965
static const hda_nid_t alc861_dac_nids[4] = {
15966
/* front, surround, clfe, side */
15967
0x03, 0x06, 0x05, 0x04
15968
};
15969
15970
static const hda_nid_t alc660_dac_nids[3] = {
15971
/* front, clfe, surround */
15972
0x03, 0x05, 0x06
15973
};
15974
15975
static const hda_nid_t alc861_adc_nids[1] = {
15976
/* ADC0-2 */
15977
0x08,
15978
};
15979
15980
static const struct hda_input_mux alc861_capture_source = {
15981
.num_items = 5,
15982
.items = {
15983
{ "Mic", 0x0 },
15984
{ "Front Mic", 0x3 },
15985
{ "Line", 0x1 },
15986
{ "CD", 0x4 },
15987
{ "Mixer", 0x5 },
15988
},
15989
};
15990
15991
static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15992
{
15993
struct alc_spec *spec = codec->spec;
15994
hda_nid_t mix, srcs[5];
15995
int i, j, num;
15996
15997
if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15998
return 0;
15999
num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16000
if (num < 0)
16001
return 0;
16002
for (i = 0; i < num; i++) {
16003
unsigned int type;
16004
type = get_wcaps_type(get_wcaps(codec, srcs[i]));
16005
if (type != AC_WID_AUD_OUT)
16006
continue;
16007
for (j = 0; j < spec->multiout.num_dacs; j++)
16008
if (spec->multiout.dac_nids[j] == srcs[i])
16009
break;
16010
if (j >= spec->multiout.num_dacs)
16011
return srcs[i];
16012
}
16013
return 0;
16014
}
16015
16016
/* fill in the dac_nids table from the parsed pin configuration */
16017
static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
16018
const struct auto_pin_cfg *cfg)
16019
{
16020
struct alc_spec *spec = codec->spec;
16021
int i;
16022
hda_nid_t nid, dac;
16023
16024
spec->multiout.dac_nids = spec->private_dac_nids;
16025
for (i = 0; i < cfg->line_outs; i++) {
16026
nid = cfg->line_out_pins[i];
16027
dac = alc861_look_for_dac(codec, nid);
16028
if (!dac)
16029
continue;
16030
spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
16031
}
16032
return 0;
16033
}
16034
16035
static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16036
hda_nid_t nid, int idx, unsigned int chs)
16037
{
16038
return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
16039
HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16040
}
16041
16042
#define alc861_create_out_sw(codec, pfx, nid, chs) \
16043
__alc861_create_out_sw(codec, pfx, nid, 0, chs)
16044
16045
/* add playback controls from the parsed DAC table */
16046
static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
16047
const struct auto_pin_cfg *cfg)
16048
{
16049
struct alc_spec *spec = codec->spec;
16050
static const char * const chname[4] = {
16051
"Front", "Surround", NULL /*CLFE*/, "Side"
16052
};
16053
const char *pfx = alc_get_line_out_pfx(spec, true);
16054
hda_nid_t nid;
16055
int i, err, noutputs;
16056
16057
noutputs = cfg->line_outs;
16058
if (spec->multi_ios > 0)
16059
noutputs += spec->multi_ios;
16060
16061
for (i = 0; i < noutputs; i++) {
16062
nid = spec->multiout.dac_nids[i];
16063
if (!nid)
16064
continue;
16065
if (!pfx && i == 2) {
16066
/* Center/LFE */
16067
err = alc861_create_out_sw(codec, "Center", nid, 1);
16068
if (err < 0)
16069
return err;
16070
err = alc861_create_out_sw(codec, "LFE", nid, 2);
16071
if (err < 0)
16072
return err;
16073
} else {
16074
const char *name = pfx;
16075
int index = i;
16076
if (!name) {
16077
name = chname[i];
16078
index = 0;
16079
}
16080
err = __alc861_create_out_sw(codec, name, nid, index, 3);
16081
if (err < 0)
16082
return err;
16083
}
16084
}
16085
return 0;
16086
}
16087
16088
static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
16089
{
16090
struct alc_spec *spec = codec->spec;
16091
int err;
16092
hda_nid_t nid;
16093
16094
if (!pin)
16095
return 0;
16096
16097
if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
16098
nid = alc861_look_for_dac(codec, pin);
16099
if (nid) {
16100
err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16101
if (err < 0)
16102
return err;
16103
spec->multiout.hp_nid = nid;
16104
}
16105
}
16106
return 0;
16107
}
16108
16109
/* create playback/capture controls for input pins */
16110
static int alc861_auto_create_input_ctls(struct hda_codec *codec,
16111
const struct auto_pin_cfg *cfg)
16112
{
16113
return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
16114
}
16115
16116
static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16117
hda_nid_t nid,
16118
int pin_type, hda_nid_t dac)
16119
{
16120
hda_nid_t mix, srcs[5];
16121
int i, num;
16122
16123
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16124
pin_type);
16125
snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16126
AMP_OUT_UNMUTE);
16127
if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16128
return;
16129
num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16130
if (num < 0)
16131
return;
16132
for (i = 0; i < num; i++) {
16133
unsigned int mute;
16134
if (srcs[i] == dac || srcs[i] == 0x15)
16135
mute = AMP_IN_UNMUTE(i);
16136
else
16137
mute = AMP_IN_MUTE(i);
16138
snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16139
mute);
16140
}
16141
}
16142
16143
static void alc861_auto_init_multi_out(struct hda_codec *codec)
16144
{
16145
struct alc_spec *spec = codec->spec;
16146
int i;
16147
16148
for (i = 0; i < spec->autocfg.line_outs; i++) {
16149
hda_nid_t nid = spec->autocfg.line_out_pins[i];
16150
int pin_type = get_pin_type(spec->autocfg.line_out_type);
16151
if (nid)
16152
alc861_auto_set_output_and_unmute(codec, nid, pin_type,
16153
spec->multiout.dac_nids[i]);
16154
}
16155
}
16156
16157
static void alc861_auto_init_hp_out(struct hda_codec *codec)
16158
{
16159
struct alc_spec *spec = codec->spec;
16160
16161
if (spec->autocfg.hp_outs)
16162
alc861_auto_set_output_and_unmute(codec,
16163
spec->autocfg.hp_pins[0],
16164
PIN_HP,
16165
spec->multiout.hp_nid);
16166
if (spec->autocfg.speaker_outs)
16167
alc861_auto_set_output_and_unmute(codec,
16168
spec->autocfg.speaker_pins[0],
16169
PIN_OUT,
16170
spec->multiout.dac_nids[0]);
16171
}
16172
16173
static void alc861_auto_init_analog_input(struct hda_codec *codec)
16174
{
16175
struct alc_spec *spec = codec->spec;
16176
struct auto_pin_cfg *cfg = &spec->autocfg;
16177
int i;
16178
16179
for (i = 0; i < cfg->num_inputs; i++) {
16180
hda_nid_t nid = cfg->inputs[i].pin;
16181
if (nid >= 0x0c && nid <= 0x11)
16182
alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16183
}
16184
}
16185
16186
/* parse the BIOS configuration and set up the alc_spec */
16187
/* return 1 if successful, 0 if the proper config is not found,
16188
* or a negative error code
16189
*/
16190
static int alc861_parse_auto_config(struct hda_codec *codec)
16191
{
16192
struct alc_spec *spec = codec->spec;
16193
int err;
16194
static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16195
16196
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16197
alc861_ignore);
16198
if (err < 0)
16199
return err;
16200
if (!spec->autocfg.line_outs)
16201
return 0; /* can't find valid BIOS pin config */
16202
16203
err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16204
if (err < 0)
16205
return err;
16206
err = alc_auto_add_multi_channel_mode(codec);
16207
if (err < 0)
16208
return err;
16209
err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16210
if (err < 0)
16211
return err;
16212
err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16213
if (err < 0)
16214
return err;
16215
err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16216
if (err < 0)
16217
return err;
16218
16219
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16220
16221
alc_auto_parse_digital(codec);
16222
16223
if (spec->kctls.list)
16224
add_mixer(spec, spec->kctls.list);
16225
16226
add_verb(spec, alc861_auto_init_verbs);
16227
16228
spec->num_mux_defs = 1;
16229
spec->input_mux = &spec->private_imux[0];
16230
16231
spec->adc_nids = alc861_adc_nids;
16232
spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16233
set_capture_mixer(codec);
16234
16235
alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16236
16237
return 1;
16238
}
16239
16240
/* additional initialization for auto-configuration model */
16241
static void alc861_auto_init(struct hda_codec *codec)
16242
{
16243
struct alc_spec *spec = codec->spec;
16244
alc861_auto_init_multi_out(codec);
16245
alc861_auto_init_hp_out(codec);
16246
alc861_auto_init_analog_input(codec);
16247
alc_auto_init_digital(codec);
16248
if (spec->unsol_event)
16249
alc_inithook(codec);
16250
}
16251
16252
#ifdef CONFIG_SND_HDA_POWER_SAVE
16253
static const struct hda_amp_list alc861_loopbacks[] = {
16254
{ 0x15, HDA_INPUT, 0 },
16255
{ 0x15, HDA_INPUT, 1 },
16256
{ 0x15, HDA_INPUT, 2 },
16257
{ 0x15, HDA_INPUT, 3 },
16258
{ } /* end */
16259
};
16260
#endif
16261
16262
16263
/*
16264
* configuration and preset
16265
*/
16266
static const char * const alc861_models[ALC861_MODEL_LAST] = {
16267
[ALC861_3ST] = "3stack",
16268
[ALC660_3ST] = "3stack-660",
16269
[ALC861_3ST_DIG] = "3stack-dig",
16270
[ALC861_6ST_DIG] = "6stack-dig",
16271
[ALC861_UNIWILL_M31] = "uniwill-m31",
16272
[ALC861_TOSHIBA] = "toshiba",
16273
[ALC861_ASUS] = "asus",
16274
[ALC861_ASUS_LAPTOP] = "asus-laptop",
16275
[ALC861_AUTO] = "auto",
16276
};
16277
16278
static const struct snd_pci_quirk alc861_cfg_tbl[] = {
16279
SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16280
SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16281
SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16282
SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16283
SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16284
SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16285
SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16286
/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16287
* Any other models that need this preset?
16288
*/
16289
/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16290
SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16291
SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16292
SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16293
SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16294
SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16295
/* FIXME: the below seems conflict */
16296
/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16297
SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16298
SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16299
{}
16300
};
16301
16302
static const struct alc_config_preset alc861_presets[] = {
16303
[ALC861_3ST] = {
16304
.mixers = { alc861_3ST_mixer },
16305
.init_verbs = { alc861_threestack_init_verbs },
16306
.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16307
.dac_nids = alc861_dac_nids,
16308
.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16309
.channel_mode = alc861_threestack_modes,
16310
.need_dac_fix = 1,
16311
.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16312
.adc_nids = alc861_adc_nids,
16313
.input_mux = &alc861_capture_source,
16314
},
16315
[ALC861_3ST_DIG] = {
16316
.mixers = { alc861_base_mixer },
16317
.init_verbs = { alc861_threestack_init_verbs },
16318
.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16319
.dac_nids = alc861_dac_nids,
16320
.dig_out_nid = ALC861_DIGOUT_NID,
16321
.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16322
.channel_mode = alc861_threestack_modes,
16323
.need_dac_fix = 1,
16324
.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16325
.adc_nids = alc861_adc_nids,
16326
.input_mux = &alc861_capture_source,
16327
},
16328
[ALC861_6ST_DIG] = {
16329
.mixers = { alc861_base_mixer },
16330
.init_verbs = { alc861_base_init_verbs },
16331
.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16332
.dac_nids = alc861_dac_nids,
16333
.dig_out_nid = ALC861_DIGOUT_NID,
16334
.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16335
.channel_mode = alc861_8ch_modes,
16336
.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16337
.adc_nids = alc861_adc_nids,
16338
.input_mux = &alc861_capture_source,
16339
},
16340
[ALC660_3ST] = {
16341
.mixers = { alc861_3ST_mixer },
16342
.init_verbs = { alc861_threestack_init_verbs },
16343
.num_dacs = ARRAY_SIZE(alc660_dac_nids),
16344
.dac_nids = alc660_dac_nids,
16345
.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16346
.channel_mode = alc861_threestack_modes,
16347
.need_dac_fix = 1,
16348
.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16349
.adc_nids = alc861_adc_nids,
16350
.input_mux = &alc861_capture_source,
16351
},
16352
[ALC861_UNIWILL_M31] = {
16353
.mixers = { alc861_uniwill_m31_mixer },
16354
.init_verbs = { alc861_uniwill_m31_init_verbs },
16355
.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16356
.dac_nids = alc861_dac_nids,
16357
.dig_out_nid = ALC861_DIGOUT_NID,
16358
.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16359
.channel_mode = alc861_uniwill_m31_modes,
16360
.need_dac_fix = 1,
16361
.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16362
.adc_nids = alc861_adc_nids,
16363
.input_mux = &alc861_capture_source,
16364
},
16365
[ALC861_TOSHIBA] = {
16366
.mixers = { alc861_toshiba_mixer },
16367
.init_verbs = { alc861_base_init_verbs,
16368
alc861_toshiba_init_verbs },
16369
.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16370
.dac_nids = alc861_dac_nids,
16371
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16372
.channel_mode = alc883_3ST_2ch_modes,
16373
.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16374
.adc_nids = alc861_adc_nids,
16375
.input_mux = &alc861_capture_source,
16376
.unsol_event = alc861_toshiba_unsol_event,
16377
.init_hook = alc861_toshiba_automute,
16378
},
16379
[ALC861_ASUS] = {
16380
.mixers = { alc861_asus_mixer },
16381
.init_verbs = { alc861_asus_init_verbs },
16382
.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16383
.dac_nids = alc861_dac_nids,
16384
.dig_out_nid = ALC861_DIGOUT_NID,
16385
.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16386
.channel_mode = alc861_asus_modes,
16387
.need_dac_fix = 1,
16388
.hp_nid = 0x06,
16389
.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16390
.adc_nids = alc861_adc_nids,
16391
.input_mux = &alc861_capture_source,
16392
},
16393
[ALC861_ASUS_LAPTOP] = {
16394
.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16395
.init_verbs = { alc861_asus_init_verbs,
16396
alc861_asus_laptop_init_verbs },
16397
.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16398
.dac_nids = alc861_dac_nids,
16399
.dig_out_nid = ALC861_DIGOUT_NID,
16400
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16401
.channel_mode = alc883_3ST_2ch_modes,
16402
.need_dac_fix = 1,
16403
.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16404
.adc_nids = alc861_adc_nids,
16405
.input_mux = &alc861_capture_source,
16406
},
16407
};
16408
16409
/* Pin config fixes */
16410
enum {
16411
PINFIX_FSC_AMILO_PI1505,
16412
};
16413
16414
static const struct alc_fixup alc861_fixups[] = {
16415
[PINFIX_FSC_AMILO_PI1505] = {
16416
.type = ALC_FIXUP_PINS,
16417
.v.pins = (const struct alc_pincfg[]) {
16418
{ 0x0b, 0x0221101f }, /* HP */
16419
{ 0x0f, 0x90170310 }, /* speaker */
16420
{ }
16421
}
16422
},
16423
};
16424
16425
static const struct snd_pci_quirk alc861_fixup_tbl[] = {
16426
SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16427
{}
16428
};
16429
16430
static int patch_alc861(struct hda_codec *codec)
16431
{
16432
struct alc_spec *spec;
16433
int board_config;
16434
int err;
16435
16436
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16437
if (spec == NULL)
16438
return -ENOMEM;
16439
16440
codec->spec = spec;
16441
16442
board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16443
alc861_models,
16444
alc861_cfg_tbl);
16445
16446
if (board_config < 0) {
16447
printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16448
codec->chip_name);
16449
board_config = ALC861_AUTO;
16450
}
16451
16452
if (board_config == ALC861_AUTO) {
16453
alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16454
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16455
}
16456
16457
if (board_config == ALC861_AUTO) {
16458
/* automatic parse from the BIOS config */
16459
err = alc861_parse_auto_config(codec);
16460
if (err < 0) {
16461
alc_free(codec);
16462
return err;
16463
} else if (!err) {
16464
printk(KERN_INFO
16465
"hda_codec: Cannot set up configuration "
16466
"from BIOS. Using base mode...\n");
16467
board_config = ALC861_3ST_DIG;
16468
}
16469
}
16470
16471
err = snd_hda_attach_beep_device(codec, 0x23);
16472
if (err < 0) {
16473
alc_free(codec);
16474
return err;
16475
}
16476
16477
if (board_config != ALC861_AUTO)
16478
setup_preset(codec, &alc861_presets[board_config]);
16479
16480
spec->stream_analog_playback = &alc861_pcm_analog_playback;
16481
spec->stream_analog_capture = &alc861_pcm_analog_capture;
16482
16483
spec->stream_digital_playback = &alc861_pcm_digital_playback;
16484
spec->stream_digital_capture = &alc861_pcm_digital_capture;
16485
16486
if (!spec->cap_mixer)
16487
set_capture_mixer(codec);
16488
set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16489
16490
spec->vmaster_nid = 0x03;
16491
16492
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16493
16494
codec->patch_ops = alc_patch_ops;
16495
if (board_config == ALC861_AUTO) {
16496
spec->init_hook = alc861_auto_init;
16497
#ifdef CONFIG_SND_HDA_POWER_SAVE
16498
spec->power_hook = alc_power_eapd;
16499
#endif
16500
}
16501
#ifdef CONFIG_SND_HDA_POWER_SAVE
16502
if (!spec->loopback.amplist)
16503
spec->loopback.amplist = alc861_loopbacks;
16504
#endif
16505
16506
return 0;
16507
}
16508
16509
/*
16510
* ALC861-VD support
16511
*
16512
* Based on ALC882
16513
*
16514
* In addition, an independent DAC
16515
*/
16516
#define ALC861VD_DIGOUT_NID 0x06
16517
16518
static const hda_nid_t alc861vd_dac_nids[4] = {
16519
/* front, surr, clfe, side surr */
16520
0x02, 0x03, 0x04, 0x05
16521
};
16522
16523
/* dac_nids for ALC660vd are in a different order - according to
16524
* Realtek's driver.
16525
* This should probably result in a different mixer for 6stack models
16526
* of ALC660vd codecs, but for now there is only 3stack mixer
16527
* - and it is the same as in 861vd.
16528
* adc_nids in ALC660vd are (is) the same as in 861vd
16529
*/
16530
static const hda_nid_t alc660vd_dac_nids[3] = {
16531
/* front, rear, clfe, rear_surr */
16532
0x02, 0x04, 0x03
16533
};
16534
16535
static const hda_nid_t alc861vd_adc_nids[1] = {
16536
/* ADC0 */
16537
0x09,
16538
};
16539
16540
static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16541
16542
/* input MUX */
16543
/* FIXME: should be a matrix-type input source selection */
16544
static const struct hda_input_mux alc861vd_capture_source = {
16545
.num_items = 4,
16546
.items = {
16547
{ "Mic", 0x0 },
16548
{ "Front Mic", 0x1 },
16549
{ "Line", 0x2 },
16550
{ "CD", 0x4 },
16551
},
16552
};
16553
16554
static const struct hda_input_mux alc861vd_dallas_capture_source = {
16555
.num_items = 2,
16556
.items = {
16557
{ "Mic", 0x0 },
16558
{ "Internal Mic", 0x1 },
16559
},
16560
};
16561
16562
static const struct hda_input_mux alc861vd_hp_capture_source = {
16563
.num_items = 2,
16564
.items = {
16565
{ "Front Mic", 0x0 },
16566
{ "ATAPI Mic", 0x1 },
16567
},
16568
};
16569
16570
/*
16571
* 2ch mode
16572
*/
16573
static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16574
{ 2, NULL }
16575
};
16576
16577
/*
16578
* 6ch mode
16579
*/
16580
static const struct hda_verb alc861vd_6stack_ch6_init[] = {
16581
{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16582
{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16583
{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16584
{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16585
{ } /* end */
16586
};
16587
16588
/*
16589
* 8ch mode
16590
*/
16591
static const struct hda_verb alc861vd_6stack_ch8_init[] = {
16592
{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16593
{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16594
{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16595
{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16596
{ } /* end */
16597
};
16598
16599
static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
16600
{ 6, alc861vd_6stack_ch6_init },
16601
{ 8, alc861vd_6stack_ch8_init },
16602
};
16603
16604
static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16605
{
16606
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16607
.name = "Channel Mode",
16608
.info = alc_ch_mode_info,
16609
.get = alc_ch_mode_get,
16610
.put = alc_ch_mode_put,
16611
},
16612
{ } /* end */
16613
};
16614
16615
/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16616
* Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16617
*/
16618
static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16619
HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16620
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16621
16622
HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16623
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16624
16625
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16626
HDA_OUTPUT),
16627
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16628
HDA_OUTPUT),
16629
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16630
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16631
16632
HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16633
HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16634
16635
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16636
16637
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16638
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16639
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16640
16641
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16642
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16643
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16644
16645
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16646
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16647
16648
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16649
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16650
16651
{ } /* end */
16652
};
16653
16654
static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16655
HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16656
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16657
16658
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16659
16660
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16661
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16662
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16663
16664
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16665
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16666
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16667
16668
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16669
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16670
16671
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16672
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16673
16674
{ } /* end */
16675
};
16676
16677
static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16678
HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16679
/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16680
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16681
16682
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16683
16684
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16685
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16686
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16687
16688
HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16689
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16690
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16691
16692
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16693
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16694
16695
{ } /* end */
16696
};
16697
16698
/* Pin assignment: Speaker=0x14, HP = 0x15,
16699
* Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16700
*/
16701
static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16702
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16703
HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16704
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16705
HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16706
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16707
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16708
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16709
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16710
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16711
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16712
{ } /* end */
16713
};
16714
16715
/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16716
* Front Mic=0x18, ATAPI Mic = 0x19,
16717
*/
16718
static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16719
HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16720
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16721
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16722
HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16723
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16724
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16725
HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16726
HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16727
16728
{ } /* end */
16729
};
16730
16731
/*
16732
* generic initialization of ADC, input mixers and output mixers
16733
*/
16734
static const struct hda_verb alc861vd_volume_init_verbs[] = {
16735
/*
16736
* Unmute ADC0 and set the default input to mic-in
16737
*/
16738
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16739
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16740
16741
/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16742
* the analog-loopback mixer widget
16743
*/
16744
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16745
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16746
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16747
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16748
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16749
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16750
16751
/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16752
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16753
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16754
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16755
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16756
16757
/*
16758
* Set up output mixers (0x02 - 0x05)
16759
*/
16760
/* set vol=0 to output mixers */
16761
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16762
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16763
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16764
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16765
16766
/* set up input amps for analog loopback */
16767
/* Amp Indices: DAC = 0, mixer = 1 */
16768
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16769
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16770
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16771
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16772
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16773
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16774
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16775
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16776
16777
{ }
16778
};
16779
16780
/*
16781
* 3-stack pin configuration:
16782
* front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16783
*/
16784
static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16785
/*
16786
* Set pin mode and muting
16787
*/
16788
/* set front pin widgets 0x14 for output */
16789
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16790
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16791
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16792
16793
/* Mic (rear) pin: input vref at 80% */
16794
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16795
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16796
/* Front Mic pin: input vref at 80% */
16797
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16798
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16799
/* Line In pin: input */
16800
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16801
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16802
/* Line-2 In: Headphone output (output 0 - 0x0c) */
16803
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16804
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16805
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16806
/* CD pin widget for input */
16807
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16808
16809
{ }
16810
};
16811
16812
/*
16813
* 6-stack pin configuration:
16814
*/
16815
static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16816
/*
16817
* Set pin mode and muting
16818
*/
16819
/* set front pin widgets 0x14 for output */
16820
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16821
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16822
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16823
16824
/* Rear Pin: output 1 (0x0d) */
16825
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16826
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16827
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16828
/* CLFE Pin: output 2 (0x0e) */
16829
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16830
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16831
{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16832
/* Side Pin: output 3 (0x0f) */
16833
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16834
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16835
{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16836
16837
/* Mic (rear) pin: input vref at 80% */
16838
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16839
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16840
/* Front Mic pin: input vref at 80% */
16841
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16842
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16843
/* Line In pin: input */
16844
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16845
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16846
/* Line-2 In: Headphone output (output 0 - 0x0c) */
16847
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16848
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16849
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16850
/* CD pin widget for input */
16851
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16852
16853
{ }
16854
};
16855
16856
static const struct hda_verb alc861vd_eapd_verbs[] = {
16857
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16858
{ }
16859
};
16860
16861
static const struct hda_verb alc660vd_eapd_verbs[] = {
16862
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16863
{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16864
{ }
16865
};
16866
16867
static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16868
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16869
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16870
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16871
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16872
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16873
{}
16874
};
16875
16876
static void alc861vd_lenovo_setup(struct hda_codec *codec)
16877
{
16878
struct alc_spec *spec = codec->spec;
16879
spec->autocfg.hp_pins[0] = 0x1b;
16880
spec->autocfg.speaker_pins[0] = 0x14;
16881
spec->automute = 1;
16882
spec->automute_mode = ALC_AUTOMUTE_AMP;
16883
}
16884
16885
static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16886
{
16887
alc_hp_automute(codec);
16888
alc88x_simple_mic_automute(codec);
16889
}
16890
16891
static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16892
unsigned int res)
16893
{
16894
switch (res >> 26) {
16895
case ALC880_MIC_EVENT:
16896
alc88x_simple_mic_automute(codec);
16897
break;
16898
default:
16899
alc_sku_unsol_event(codec, res);
16900
break;
16901
}
16902
}
16903
16904
static const struct hda_verb alc861vd_dallas_verbs[] = {
16905
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16906
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16907
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16908
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16909
16910
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16911
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16912
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16913
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16914
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16915
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16916
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16917
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16918
16919
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16920
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16921
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16922
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16923
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16924
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16925
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16926
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16927
16928
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16929
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16930
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16931
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16932
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16933
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16934
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16935
{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16936
16937
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16938
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16939
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16940
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16941
16942
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16943
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16944
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16945
16946
{ } /* end */
16947
};
16948
16949
/* toggle speaker-output according to the hp-jack state */
16950
static void alc861vd_dallas_setup(struct hda_codec *codec)
16951
{
16952
struct alc_spec *spec = codec->spec;
16953
16954
spec->autocfg.hp_pins[0] = 0x15;
16955
spec->autocfg.speaker_pins[0] = 0x14;
16956
spec->automute = 1;
16957
spec->automute_mode = ALC_AUTOMUTE_AMP;
16958
}
16959
16960
#ifdef CONFIG_SND_HDA_POWER_SAVE
16961
#define alc861vd_loopbacks alc880_loopbacks
16962
#endif
16963
16964
/* pcm configuration: identical with ALC880 */
16965
#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16966
#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16967
#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16968
#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16969
16970
/*
16971
* configuration and preset
16972
*/
16973
static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16974
[ALC660VD_3ST] = "3stack-660",
16975
[ALC660VD_3ST_DIG] = "3stack-660-digout",
16976
[ALC660VD_ASUS_V1S] = "asus-v1s",
16977
[ALC861VD_3ST] = "3stack",
16978
[ALC861VD_3ST_DIG] = "3stack-digout",
16979
[ALC861VD_6ST_DIG] = "6stack-digout",
16980
[ALC861VD_LENOVO] = "lenovo",
16981
[ALC861VD_DALLAS] = "dallas",
16982
[ALC861VD_HP] = "hp",
16983
[ALC861VD_AUTO] = "auto",
16984
};
16985
16986
static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16987
SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16988
SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16989
SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16990
/*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16991
SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16992
SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16993
SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16994
SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16995
/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16996
SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16997
SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16998
SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16999
SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
17000
SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
17001
SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
17002
{}
17003
};
17004
17005
static const struct alc_config_preset alc861vd_presets[] = {
17006
[ALC660VD_3ST] = {
17007
.mixers = { alc861vd_3st_mixer },
17008
.init_verbs = { alc861vd_volume_init_verbs,
17009
alc861vd_3stack_init_verbs },
17010
.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17011
.dac_nids = alc660vd_dac_nids,
17012
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17013
.channel_mode = alc861vd_3stack_2ch_modes,
17014
.input_mux = &alc861vd_capture_source,
17015
},
17016
[ALC660VD_3ST_DIG] = {
17017
.mixers = { alc861vd_3st_mixer },
17018
.init_verbs = { alc861vd_volume_init_verbs,
17019
alc861vd_3stack_init_verbs },
17020
.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17021
.dac_nids = alc660vd_dac_nids,
17022
.dig_out_nid = ALC861VD_DIGOUT_NID,
17023
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17024
.channel_mode = alc861vd_3stack_2ch_modes,
17025
.input_mux = &alc861vd_capture_source,
17026
},
17027
[ALC861VD_3ST] = {
17028
.mixers = { alc861vd_3st_mixer },
17029
.init_verbs = { alc861vd_volume_init_verbs,
17030
alc861vd_3stack_init_verbs },
17031
.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17032
.dac_nids = alc861vd_dac_nids,
17033
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17034
.channel_mode = alc861vd_3stack_2ch_modes,
17035
.input_mux = &alc861vd_capture_source,
17036
},
17037
[ALC861VD_3ST_DIG] = {
17038
.mixers = { alc861vd_3st_mixer },
17039
.init_verbs = { alc861vd_volume_init_verbs,
17040
alc861vd_3stack_init_verbs },
17041
.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17042
.dac_nids = alc861vd_dac_nids,
17043
.dig_out_nid = ALC861VD_DIGOUT_NID,
17044
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17045
.channel_mode = alc861vd_3stack_2ch_modes,
17046
.input_mux = &alc861vd_capture_source,
17047
},
17048
[ALC861VD_6ST_DIG] = {
17049
.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17050
.init_verbs = { alc861vd_volume_init_verbs,
17051
alc861vd_6stack_init_verbs },
17052
.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17053
.dac_nids = alc861vd_dac_nids,
17054
.dig_out_nid = ALC861VD_DIGOUT_NID,
17055
.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17056
.channel_mode = alc861vd_6stack_modes,
17057
.input_mux = &alc861vd_capture_source,
17058
},
17059
[ALC861VD_LENOVO] = {
17060
.mixers = { alc861vd_lenovo_mixer },
17061
.init_verbs = { alc861vd_volume_init_verbs,
17062
alc861vd_3stack_init_verbs,
17063
alc861vd_eapd_verbs,
17064
alc861vd_lenovo_unsol_verbs },
17065
.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17066
.dac_nids = alc660vd_dac_nids,
17067
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17068
.channel_mode = alc861vd_3stack_2ch_modes,
17069
.input_mux = &alc861vd_capture_source,
17070
.unsol_event = alc861vd_lenovo_unsol_event,
17071
.setup = alc861vd_lenovo_setup,
17072
.init_hook = alc861vd_lenovo_init_hook,
17073
},
17074
[ALC861VD_DALLAS] = {
17075
.mixers = { alc861vd_dallas_mixer },
17076
.init_verbs = { alc861vd_dallas_verbs },
17077
.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17078
.dac_nids = alc861vd_dac_nids,
17079
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17080
.channel_mode = alc861vd_3stack_2ch_modes,
17081
.input_mux = &alc861vd_dallas_capture_source,
17082
.unsol_event = alc_sku_unsol_event,
17083
.setup = alc861vd_dallas_setup,
17084
.init_hook = alc_hp_automute,
17085
},
17086
[ALC861VD_HP] = {
17087
.mixers = { alc861vd_hp_mixer },
17088
.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17089
.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17090
.dac_nids = alc861vd_dac_nids,
17091
.dig_out_nid = ALC861VD_DIGOUT_NID,
17092
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17093
.channel_mode = alc861vd_3stack_2ch_modes,
17094
.input_mux = &alc861vd_hp_capture_source,
17095
.unsol_event = alc_sku_unsol_event,
17096
.setup = alc861vd_dallas_setup,
17097
.init_hook = alc_hp_automute,
17098
},
17099
[ALC660VD_ASUS_V1S] = {
17100
.mixers = { alc861vd_lenovo_mixer },
17101
.init_verbs = { alc861vd_volume_init_verbs,
17102
alc861vd_3stack_init_verbs,
17103
alc861vd_eapd_verbs,
17104
alc861vd_lenovo_unsol_verbs },
17105
.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17106
.dac_nids = alc660vd_dac_nids,
17107
.dig_out_nid = ALC861VD_DIGOUT_NID,
17108
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17109
.channel_mode = alc861vd_3stack_2ch_modes,
17110
.input_mux = &alc861vd_capture_source,
17111
.unsol_event = alc861vd_lenovo_unsol_event,
17112
.setup = alc861vd_lenovo_setup,
17113
.init_hook = alc861vd_lenovo_init_hook,
17114
},
17115
};
17116
17117
/*
17118
* BIOS auto configuration
17119
*/
17120
static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17121
const struct auto_pin_cfg *cfg)
17122
{
17123
return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
17124
}
17125
17126
17127
static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17128
hda_nid_t nid, int pin_type, int dac_idx)
17129
{
17130
alc_set_pin_output(codec, nid, pin_type);
17131
}
17132
17133
static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17134
{
17135
struct alc_spec *spec = codec->spec;
17136
int i;
17137
17138
for (i = 0; i <= HDA_SIDE; i++) {
17139
hda_nid_t nid = spec->autocfg.line_out_pins[i];
17140
int pin_type = get_pin_type(spec->autocfg.line_out_type);
17141
if (nid)
17142
alc861vd_auto_set_output_and_unmute(codec, nid,
17143
pin_type, i);
17144
}
17145
}
17146
17147
17148
static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17149
{
17150
struct alc_spec *spec = codec->spec;
17151
hda_nid_t pin;
17152
17153
pin = spec->autocfg.hp_pins[0];
17154
if (pin) /* connect to front and use dac 0 */
17155
alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17156
pin = spec->autocfg.speaker_pins[0];
17157
if (pin)
17158
alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17159
}
17160
17161
#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17162
17163
static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17164
{
17165
struct alc_spec *spec = codec->spec;
17166
struct auto_pin_cfg *cfg = &spec->autocfg;
17167
int i;
17168
17169
for (i = 0; i < cfg->num_inputs; i++) {
17170
hda_nid_t nid = cfg->inputs[i].pin;
17171
if (alc_is_input_pin(codec, nid)) {
17172
alc_set_input_pin(codec, nid, cfg->inputs[i].type);
17173
if (nid != ALC861VD_PIN_CD_NID &&
17174
(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17175
snd_hda_codec_write(codec, nid, 0,
17176
AC_VERB_SET_AMP_GAIN_MUTE,
17177
AMP_OUT_MUTE);
17178
}
17179
}
17180
}
17181
17182
#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17183
17184
#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17185
#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17186
17187
/* add playback controls from the parsed DAC table */
17188
/* Based on ALC880 version. But ALC861VD has separate,
17189
* different NIDs for mute/unmute switch and volume control */
17190
static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17191
const struct auto_pin_cfg *cfg)
17192
{
17193
static const char * const chname[4] = {
17194
"Front", "Surround", "CLFE", "Side"
17195
};
17196
const char *pfx = alc_get_line_out_pfx(spec, true);
17197
hda_nid_t nid_v, nid_s;
17198
int i, err, noutputs;
17199
17200
noutputs = cfg->line_outs;
17201
if (spec->multi_ios > 0)
17202
noutputs += spec->multi_ios;
17203
17204
for (i = 0; i < noutputs; i++) {
17205
if (!spec->multiout.dac_nids[i])
17206
continue;
17207
nid_v = alc861vd_idx_to_mixer_vol(
17208
alc880_dac_to_idx(
17209
spec->multiout.dac_nids[i]));
17210
nid_s = alc861vd_idx_to_mixer_switch(
17211
alc880_dac_to_idx(
17212
spec->multiout.dac_nids[i]));
17213
17214
if (!pfx && i == 2) {
17215
/* Center/LFE */
17216
err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17217
"Center",
17218
HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17219
HDA_OUTPUT));
17220
if (err < 0)
17221
return err;
17222
err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17223
"LFE",
17224
HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17225
HDA_OUTPUT));
17226
if (err < 0)
17227
return err;
17228
err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17229
"Center",
17230
HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17231
HDA_INPUT));
17232
if (err < 0)
17233
return err;
17234
err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17235
"LFE",
17236
HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17237
HDA_INPUT));
17238
if (err < 0)
17239
return err;
17240
} else {
17241
const char *name = pfx;
17242
int index = i;
17243
if (!name) {
17244
name = chname[i];
17245
index = 0;
17246
}
17247
err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17248
name, index,
17249
HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17250
HDA_OUTPUT));
17251
if (err < 0)
17252
return err;
17253
err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17254
name, index,
17255
HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17256
HDA_INPUT));
17257
if (err < 0)
17258
return err;
17259
}
17260
}
17261
return 0;
17262
}
17263
17264
/* add playback controls for speaker and HP outputs */
17265
/* Based on ALC880 version. But ALC861VD has separate,
17266
* different NIDs for mute/unmute switch and volume control */
17267
static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17268
hda_nid_t pin, const char *pfx)
17269
{
17270
hda_nid_t nid_v, nid_s;
17271
int err;
17272
17273
if (!pin)
17274
return 0;
17275
17276
if (alc880_is_fixed_pin(pin)) {
17277
nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17278
/* specify the DAC as the extra output */
17279
if (!spec->multiout.hp_nid)
17280
spec->multiout.hp_nid = nid_v;
17281
else
17282
spec->multiout.extra_out_nid[0] = nid_v;
17283
/* control HP volume/switch on the output mixer amp */
17284
nid_v = alc861vd_idx_to_mixer_vol(
17285
alc880_fixed_pin_idx(pin));
17286
nid_s = alc861vd_idx_to_mixer_switch(
17287
alc880_fixed_pin_idx(pin));
17288
17289
err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17290
HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17291
if (err < 0)
17292
return err;
17293
err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17294
HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17295
if (err < 0)
17296
return err;
17297
} else if (alc880_is_multi_pin(pin)) {
17298
/* set manual connection */
17299
/* we have only a switch on HP-out PIN */
17300
err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17301
HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17302
if (err < 0)
17303
return err;
17304
}
17305
return 0;
17306
}
17307
17308
/* parse the BIOS configuration and set up the alc_spec
17309
* return 1 if successful, 0 if the proper config is not found,
17310
* or a negative error code
17311
* Based on ALC880 version - had to change it to override
17312
* alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17313
static int alc861vd_parse_auto_config(struct hda_codec *codec)
17314
{
17315
struct alc_spec *spec = codec->spec;
17316
int err;
17317
static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17318
17319
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17320
alc861vd_ignore);
17321
if (err < 0)
17322
return err;
17323
if (!spec->autocfg.line_outs)
17324
return 0; /* can't find valid BIOS pin config */
17325
17326
err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17327
if (err < 0)
17328
return err;
17329
err = alc_auto_add_multi_channel_mode(codec);
17330
if (err < 0)
17331
return err;
17332
err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17333
if (err < 0)
17334
return err;
17335
err = alc861vd_auto_create_extra_out(spec,
17336
spec->autocfg.speaker_pins[0],
17337
"Speaker");
17338
if (err < 0)
17339
return err;
17340
err = alc861vd_auto_create_extra_out(spec,
17341
spec->autocfg.hp_pins[0],
17342
"Headphone");
17343
if (err < 0)
17344
return err;
17345
err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17346
if (err < 0)
17347
return err;
17348
17349
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17350
17351
alc_auto_parse_digital(codec);
17352
17353
if (spec->kctls.list)
17354
add_mixer(spec, spec->kctls.list);
17355
17356
add_verb(spec, alc861vd_volume_init_verbs);
17357
17358
spec->num_mux_defs = 1;
17359
spec->input_mux = &spec->private_imux[0];
17360
17361
err = alc_auto_add_mic_boost(codec);
17362
if (err < 0)
17363
return err;
17364
17365
alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17366
17367
return 1;
17368
}
17369
17370
/* additional initialization for auto-configuration model */
17371
static void alc861vd_auto_init(struct hda_codec *codec)
17372
{
17373
struct alc_spec *spec = codec->spec;
17374
alc861vd_auto_init_multi_out(codec);
17375
alc861vd_auto_init_hp_out(codec);
17376
alc861vd_auto_init_analog_input(codec);
17377
alc861vd_auto_init_input_src(codec);
17378
alc_auto_init_digital(codec);
17379
if (spec->unsol_event)
17380
alc_inithook(codec);
17381
}
17382
17383
enum {
17384
ALC660VD_FIX_ASUS_GPIO1
17385
};
17386
17387
/* reset GPIO1 */
17388
static const struct alc_fixup alc861vd_fixups[] = {
17389
[ALC660VD_FIX_ASUS_GPIO1] = {
17390
.type = ALC_FIXUP_VERBS,
17391
.v.verbs = (const struct hda_verb[]) {
17392
{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17393
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17394
{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17395
{ }
17396
}
17397
},
17398
};
17399
17400
static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17401
SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17402
{}
17403
};
17404
17405
static int patch_alc861vd(struct hda_codec *codec)
17406
{
17407
struct alc_spec *spec;
17408
int err, board_config;
17409
17410
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17411
if (spec == NULL)
17412
return -ENOMEM;
17413
17414
codec->spec = spec;
17415
17416
board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17417
alc861vd_models,
17418
alc861vd_cfg_tbl);
17419
17420
if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
17421
printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17422
codec->chip_name);
17423
board_config = ALC861VD_AUTO;
17424
}
17425
17426
if (board_config == ALC861VD_AUTO) {
17427
alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17428
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17429
}
17430
17431
if (board_config == ALC861VD_AUTO) {
17432
/* automatic parse from the BIOS config */
17433
err = alc861vd_parse_auto_config(codec);
17434
if (err < 0) {
17435
alc_free(codec);
17436
return err;
17437
} else if (!err) {
17438
printk(KERN_INFO
17439
"hda_codec: Cannot set up configuration "
17440
"from BIOS. Using base mode...\n");
17441
board_config = ALC861VD_3ST;
17442
}
17443
}
17444
17445
err = snd_hda_attach_beep_device(codec, 0x23);
17446
if (err < 0) {
17447
alc_free(codec);
17448
return err;
17449
}
17450
17451
if (board_config != ALC861VD_AUTO)
17452
setup_preset(codec, &alc861vd_presets[board_config]);
17453
17454
if (codec->vendor_id == 0x10ec0660) {
17455
/* always turn on EAPD */
17456
add_verb(spec, alc660vd_eapd_verbs);
17457
}
17458
17459
spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17460
spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17461
17462
spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17463
spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17464
17465
if (!spec->adc_nids) {
17466
spec->adc_nids = alc861vd_adc_nids;
17467
spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17468
}
17469
if (!spec->capsrc_nids)
17470
spec->capsrc_nids = alc861vd_capsrc_nids;
17471
17472
set_capture_mixer(codec);
17473
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17474
17475
spec->vmaster_nid = 0x02;
17476
17477
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
17478
17479
codec->patch_ops = alc_patch_ops;
17480
17481
if (board_config == ALC861VD_AUTO)
17482
spec->init_hook = alc861vd_auto_init;
17483
spec->shutup = alc_eapd_shutup;
17484
#ifdef CONFIG_SND_HDA_POWER_SAVE
17485
if (!spec->loopback.amplist)
17486
spec->loopback.amplist = alc861vd_loopbacks;
17487
#endif
17488
17489
return 0;
17490
}
17491
17492
/*
17493
* ALC662 support
17494
*
17495
* ALC662 is almost identical with ALC880 but has cleaner and more flexible
17496
* configuration. Each pin widget can choose any input DACs and a mixer.
17497
* Each ADC is connected from a mixer of all inputs. This makes possible
17498
* 6-channel independent captures.
17499
*
17500
* In addition, an independent DAC for the multi-playback (not used in this
17501
* driver yet).
17502
*/
17503
#define ALC662_DIGOUT_NID 0x06
17504
#define ALC662_DIGIN_NID 0x0a
17505
17506
static const hda_nid_t alc662_dac_nids[3] = {
17507
/* front, rear, clfe */
17508
0x02, 0x03, 0x04
17509
};
17510
17511
static const hda_nid_t alc272_dac_nids[2] = {
17512
0x02, 0x03
17513
};
17514
17515
static const hda_nid_t alc662_adc_nids[2] = {
17516
/* ADC1-2 */
17517
0x09, 0x08
17518
};
17519
17520
static const hda_nid_t alc272_adc_nids[1] = {
17521
/* ADC1-2 */
17522
0x08,
17523
};
17524
17525
static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17526
static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17527
17528
17529
/* input MUX */
17530
/* FIXME: should be a matrix-type input source selection */
17531
static const struct hda_input_mux alc662_capture_source = {
17532
.num_items = 4,
17533
.items = {
17534
{ "Mic", 0x0 },
17535
{ "Front Mic", 0x1 },
17536
{ "Line", 0x2 },
17537
{ "CD", 0x4 },
17538
},
17539
};
17540
17541
static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
17542
.num_items = 2,
17543
.items = {
17544
{ "Mic", 0x1 },
17545
{ "Line", 0x2 },
17546
},
17547
};
17548
17549
static const struct hda_input_mux alc663_capture_source = {
17550
.num_items = 3,
17551
.items = {
17552
{ "Mic", 0x0 },
17553
{ "Front Mic", 0x1 },
17554
{ "Line", 0x2 },
17555
},
17556
};
17557
17558
#if 0 /* set to 1 for testing other input sources below */
17559
static const struct hda_input_mux alc272_nc10_capture_source = {
17560
.num_items = 16,
17561
.items = {
17562
{ "Autoselect Mic", 0x0 },
17563
{ "Internal Mic", 0x1 },
17564
{ "In-0x02", 0x2 },
17565
{ "In-0x03", 0x3 },
17566
{ "In-0x04", 0x4 },
17567
{ "In-0x05", 0x5 },
17568
{ "In-0x06", 0x6 },
17569
{ "In-0x07", 0x7 },
17570
{ "In-0x08", 0x8 },
17571
{ "In-0x09", 0x9 },
17572
{ "In-0x0a", 0x0a },
17573
{ "In-0x0b", 0x0b },
17574
{ "In-0x0c", 0x0c },
17575
{ "In-0x0d", 0x0d },
17576
{ "In-0x0e", 0x0e },
17577
{ "In-0x0f", 0x0f },
17578
},
17579
};
17580
#endif
17581
17582
/*
17583
* 2ch mode
17584
*/
17585
static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17586
{ 2, NULL }
17587
};
17588
17589
/*
17590
* 2ch mode
17591
*/
17592
static const struct hda_verb alc662_3ST_ch2_init[] = {
17593
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17594
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17595
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17596
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17597
{ } /* end */
17598
};
17599
17600
/*
17601
* 6ch mode
17602
*/
17603
static const struct hda_verb alc662_3ST_ch6_init[] = {
17604
{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17605
{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17606
{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17607
{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17608
{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17609
{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17610
{ } /* end */
17611
};
17612
17613
static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17614
{ 2, alc662_3ST_ch2_init },
17615
{ 6, alc662_3ST_ch6_init },
17616
};
17617
17618
/*
17619
* 2ch mode
17620
*/
17621
static const struct hda_verb alc662_sixstack_ch6_init[] = {
17622
{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17623
{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17624
{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17625
{ } /* end */
17626
};
17627
17628
/*
17629
* 6ch mode
17630
*/
17631
static const struct hda_verb alc662_sixstack_ch8_init[] = {
17632
{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17633
{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17634
{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17635
{ } /* end */
17636
};
17637
17638
static const struct hda_channel_mode alc662_5stack_modes[2] = {
17639
{ 2, alc662_sixstack_ch6_init },
17640
{ 6, alc662_sixstack_ch8_init },
17641
};
17642
17643
/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17644
* Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17645
*/
17646
17647
static const struct snd_kcontrol_new alc662_base_mixer[] = {
17648
/* output mixer control */
17649
HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17650
HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17651
HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17652
HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17653
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17654
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17655
HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17656
HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17657
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17658
17659
/*Input mixer control */
17660
HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17661
HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17662
HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17663
HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17664
HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17665
HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17666
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17667
HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17668
{ } /* end */
17669
};
17670
17671
static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17672
HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17673
HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17674
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17675
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17676
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17677
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17678
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17679
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17680
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17681
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17682
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17683
{ } /* end */
17684
};
17685
17686
static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17687
HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17688
HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17689
HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17690
HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17691
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17692
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17693
HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17694
HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17695
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17696
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17697
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17698
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17699
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17700
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17701
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17702
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17703
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17704
{ } /* end */
17705
};
17706
17707
static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17708
HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17709
HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17710
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17711
HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17712
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17713
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17714
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17715
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17716
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17717
{ } /* end */
17718
};
17719
17720
static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17721
HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17722
ALC262_HIPPO_MASTER_SWITCH,
17723
17724
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17725
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17726
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17727
17728
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17729
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17730
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17731
{ } /* end */
17732
};
17733
17734
static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17735
ALC262_HIPPO_MASTER_SWITCH,
17736
HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17737
HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17738
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17739
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17740
HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17741
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17742
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17743
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17744
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17745
{ } /* end */
17746
};
17747
17748
static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17749
.ops = &snd_hda_bind_vol,
17750
.values = {
17751
HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17752
HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17753
0
17754
},
17755
};
17756
17757
static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17758
.ops = &snd_hda_bind_sw,
17759
.values = {
17760
HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17761
HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17762
0
17763
},
17764
};
17765
17766
static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17767
HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17768
HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17769
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17770
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17771
{ } /* end */
17772
};
17773
17774
static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17775
.ops = &snd_hda_bind_sw,
17776
.values = {
17777
HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17778
HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17779
HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17780
0
17781
},
17782
};
17783
17784
static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17785
HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17786
HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17787
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17788
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17789
HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17790
HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17791
17792
{ } /* end */
17793
};
17794
17795
static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17796
.ops = &snd_hda_bind_sw,
17797
.values = {
17798
HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17799
HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17800
HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17801
0
17802
},
17803
};
17804
17805
static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17806
HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17807
HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17808
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17809
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17810
HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17811
HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17812
{ } /* end */
17813
};
17814
17815
static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17816
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17817
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17818
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17819
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17820
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17821
HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17822
HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17823
{ } /* end */
17824
};
17825
17826
static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17827
.ops = &snd_hda_bind_vol,
17828
.values = {
17829
HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17830
HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17831
0
17832
},
17833
};
17834
17835
static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17836
.ops = &snd_hda_bind_sw,
17837
.values = {
17838
HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17839
HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17840
0
17841
},
17842
};
17843
17844
static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17845
HDA_BIND_VOL("Master Playback Volume",
17846
&alc663_asus_two_bind_master_vol),
17847
HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17848
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17849
HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17850
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17851
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17852
{ } /* end */
17853
};
17854
17855
static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17856
HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17857
HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17858
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17859
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17860
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17861
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17862
{ } /* end */
17863
};
17864
17865
static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17866
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17867
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17868
HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17869
HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17870
HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17871
17872
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17873
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17874
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17875
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17876
{ } /* end */
17877
};
17878
17879
static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17880
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17881
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17882
HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17883
17884
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17885
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17886
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17887
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17888
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17889
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17890
{ } /* end */
17891
};
17892
17893
static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17894
.ops = &snd_hda_bind_sw,
17895
.values = {
17896
HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17897
HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17898
HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17899
HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17900
HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17901
0
17902
},
17903
};
17904
17905
static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17906
.ops = &snd_hda_bind_sw,
17907
.values = {
17908
HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17909
HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17910
0
17911
},
17912
};
17913
17914
static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17915
HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17916
HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17917
HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17918
HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17919
HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17920
HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17921
HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17922
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17923
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17924
{ } /* end */
17925
};
17926
17927
static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17928
HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17929
HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17930
HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17931
HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17932
HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17933
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17934
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17935
{ } /* end */
17936
};
17937
17938
17939
static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17940
{
17941
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17942
.name = "Channel Mode",
17943
.info = alc_ch_mode_info,
17944
.get = alc_ch_mode_get,
17945
.put = alc_ch_mode_put,
17946
},
17947
{ } /* end */
17948
};
17949
17950
static const struct hda_verb alc662_init_verbs[] = {
17951
/* ADC: mute amp left and right */
17952
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17953
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17954
17955
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17956
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17957
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17958
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17959
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17960
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17961
17962
/* Front Pin: output 0 (0x0c) */
17963
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17964
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17965
17966
/* Rear Pin: output 1 (0x0d) */
17967
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17968
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17969
17970
/* CLFE Pin: output 2 (0x0e) */
17971
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17972
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17973
17974
/* Mic (rear) pin: input vref at 80% */
17975
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17976
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17977
/* Front Mic pin: input vref at 80% */
17978
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17979
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17980
/* Line In pin: input */
17981
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17982
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17983
/* Line-2 In: Headphone output (output 0 - 0x0c) */
17984
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17985
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17986
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17987
/* CD pin widget for input */
17988
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17989
17990
/* FIXME: use matrix-type input source selection */
17991
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17992
/* Input mixer */
17993
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17994
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17995
17996
{ }
17997
};
17998
17999
static const struct hda_verb alc662_eapd_init_verbs[] = {
18000
/* always trun on EAPD */
18001
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
18002
{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
18003
{ }
18004
};
18005
18006
static const struct hda_verb alc662_sue_init_verbs[] = {
18007
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18008
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18009
{}
18010
};
18011
18012
static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
18013
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18014
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18015
{}
18016
};
18017
18018
/* Set Unsolicited Event*/
18019
static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
18020
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18021
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18022
{}
18023
};
18024
18025
static const struct hda_verb alc663_m51va_init_verbs[] = {
18026
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18027
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18028
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18029
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18030
{0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18031
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18032
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18033
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18034
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18035
{}
18036
};
18037
18038
static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
18039
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18040
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18041
{0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18042
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18043
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18044
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18045
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18046
{}
18047
};
18048
18049
static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18050
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18051
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18052
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18053
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18054
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18055
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18056
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18057
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18058
{}
18059
};
18060
18061
static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
18062
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18063
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18064
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18065
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18066
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18067
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18068
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18069
{}
18070
};
18071
18072
static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18073
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18074
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18075
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18076
{0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18077
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18078
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18079
{0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18080
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18081
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18082
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18083
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18084
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18085
{}
18086
};
18087
18088
static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18089
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18090
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18091
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18092
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18093
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18094
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18095
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18096
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18097
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18098
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18099
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18100
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18101
{}
18102
};
18103
18104
static const struct hda_verb alc663_g71v_init_verbs[] = {
18105
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18106
/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18107
/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18108
18109
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18110
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18111
{0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18112
18113
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18114
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18115
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18116
{}
18117
};
18118
18119
static const struct hda_verb alc663_g50v_init_verbs[] = {
18120
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18121
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18122
{0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18123
18124
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18125
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18126
{}
18127
};
18128
18129
static const struct hda_verb alc662_ecs_init_verbs[] = {
18130
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18131
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18132
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18133
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18134
{}
18135
};
18136
18137
static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
18138
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18139
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18140
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18141
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18142
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18143
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18144
{0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18145
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18146
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18147
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18148
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18149
{}
18150
};
18151
18152
static const struct hda_verb alc272_dell_init_verbs[] = {
18153
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18154
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18155
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18156
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18157
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18158
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18159
{0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18160
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18161
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18162
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18163
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18164
{}
18165
};
18166
18167
static const struct hda_verb alc663_mode7_init_verbs[] = {
18168
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18169
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18170
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18171
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18172
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18173
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18174
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18175
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18176
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18177
{0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18178
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18179
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18180
{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18181
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18182
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18183
{}
18184
};
18185
18186
static const struct hda_verb alc663_mode8_init_verbs[] = {
18187
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18188
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18189
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18190
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18191
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18192
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18193
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18194
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18195
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18196
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18197
{0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18198
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18199
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18200
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18201
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18202
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18203
{}
18204
};
18205
18206
static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18207
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18208
HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18209
{ } /* end */
18210
};
18211
18212
static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18213
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18214
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18215
{ } /* end */
18216
};
18217
18218
static void alc662_lenovo_101e_setup(struct hda_codec *codec)
18219
{
18220
struct alc_spec *spec = codec->spec;
18221
18222
spec->autocfg.hp_pins[0] = 0x1b;
18223
spec->autocfg.line_out_pins[0] = 0x14;
18224
spec->autocfg.speaker_pins[0] = 0x15;
18225
spec->automute = 1;
18226
spec->detect_line = 1;
18227
spec->automute_lines = 1;
18228
spec->automute_mode = ALC_AUTOMUTE_AMP;
18229
}
18230
18231
static void alc662_eeepc_setup(struct hda_codec *codec)
18232
{
18233
struct alc_spec *spec = codec->spec;
18234
18235
alc262_hippo1_setup(codec);
18236
spec->ext_mic.pin = 0x18;
18237
spec->ext_mic.mux_idx = 0;
18238
spec->int_mic.pin = 0x19;
18239
spec->int_mic.mux_idx = 1;
18240
spec->auto_mic = 1;
18241
}
18242
18243
static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18244
{
18245
struct alc_spec *spec = codec->spec;
18246
18247
spec->autocfg.hp_pins[0] = 0x14;
18248
spec->autocfg.speaker_pins[0] = 0x1b;
18249
spec->automute = 1;
18250
spec->automute_mode = ALC_AUTOMUTE_AMP;
18251
}
18252
18253
static void alc663_m51va_setup(struct hda_codec *codec)
18254
{
18255
struct alc_spec *spec = codec->spec;
18256
spec->autocfg.hp_pins[0] = 0x21;
18257
spec->autocfg.speaker_pins[0] = 0x14;
18258
spec->automute_mixer_nid[0] = 0x0c;
18259
spec->automute = 1;
18260
spec->automute_mode = ALC_AUTOMUTE_MIXER;
18261
spec->ext_mic.pin = 0x18;
18262
spec->ext_mic.mux_idx = 0;
18263
spec->int_mic.pin = 0x12;
18264
spec->int_mic.mux_idx = 9;
18265
spec->auto_mic = 1;
18266
}
18267
18268
/* ***************** Mode1 ******************************/
18269
static void alc663_mode1_setup(struct hda_codec *codec)
18270
{
18271
struct alc_spec *spec = codec->spec;
18272
spec->autocfg.hp_pins[0] = 0x21;
18273
spec->autocfg.speaker_pins[0] = 0x14;
18274
spec->automute_mixer_nid[0] = 0x0c;
18275
spec->automute = 1;
18276
spec->automute_mode = ALC_AUTOMUTE_MIXER;
18277
spec->ext_mic.pin = 0x18;
18278
spec->ext_mic.mux_idx = 0;
18279
spec->int_mic.pin = 0x19;
18280
spec->int_mic.mux_idx = 1;
18281
spec->auto_mic = 1;
18282
}
18283
18284
/* ***************** Mode2 ******************************/
18285
static void alc662_mode2_setup(struct hda_codec *codec)
18286
{
18287
struct alc_spec *spec = codec->spec;
18288
spec->autocfg.hp_pins[0] = 0x1b;
18289
spec->autocfg.speaker_pins[0] = 0x14;
18290
spec->automute = 1;
18291
spec->automute_mode = ALC_AUTOMUTE_PIN;
18292
spec->ext_mic.pin = 0x18;
18293
spec->ext_mic.mux_idx = 0;
18294
spec->int_mic.pin = 0x19;
18295
spec->int_mic.mux_idx = 1;
18296
spec->auto_mic = 1;
18297
}
18298
18299
/* ***************** Mode3 ******************************/
18300
static void alc663_mode3_setup(struct hda_codec *codec)
18301
{
18302
struct alc_spec *spec = codec->spec;
18303
spec->autocfg.hp_pins[0] = 0x21;
18304
spec->autocfg.hp_pins[0] = 0x15;
18305
spec->autocfg.speaker_pins[0] = 0x14;
18306
spec->automute = 1;
18307
spec->automute_mode = ALC_AUTOMUTE_PIN;
18308
spec->ext_mic.pin = 0x18;
18309
spec->ext_mic.mux_idx = 0;
18310
spec->int_mic.pin = 0x19;
18311
spec->int_mic.mux_idx = 1;
18312
spec->auto_mic = 1;
18313
}
18314
18315
/* ***************** Mode4 ******************************/
18316
static void alc663_mode4_setup(struct hda_codec *codec)
18317
{
18318
struct alc_spec *spec = codec->spec;
18319
spec->autocfg.hp_pins[0] = 0x21;
18320
spec->autocfg.speaker_pins[0] = 0x14;
18321
spec->autocfg.speaker_pins[1] = 0x16;
18322
spec->automute_mixer_nid[0] = 0x0c;
18323
spec->automute_mixer_nid[1] = 0x0e;
18324
spec->automute = 1;
18325
spec->automute_mode = ALC_AUTOMUTE_MIXER;
18326
spec->ext_mic.pin = 0x18;
18327
spec->ext_mic.mux_idx = 0;
18328
spec->int_mic.pin = 0x19;
18329
spec->int_mic.mux_idx = 1;
18330
spec->auto_mic = 1;
18331
}
18332
18333
/* ***************** Mode5 ******************************/
18334
static void alc663_mode5_setup(struct hda_codec *codec)
18335
{
18336
struct alc_spec *spec = codec->spec;
18337
spec->autocfg.hp_pins[0] = 0x15;
18338
spec->autocfg.speaker_pins[0] = 0x14;
18339
spec->autocfg.speaker_pins[1] = 0x16;
18340
spec->automute_mixer_nid[0] = 0x0c;
18341
spec->automute_mixer_nid[1] = 0x0e;
18342
spec->automute = 1;
18343
spec->automute_mode = ALC_AUTOMUTE_MIXER;
18344
spec->ext_mic.pin = 0x18;
18345
spec->ext_mic.mux_idx = 0;
18346
spec->int_mic.pin = 0x19;
18347
spec->int_mic.mux_idx = 1;
18348
spec->auto_mic = 1;
18349
}
18350
18351
/* ***************** Mode6 ******************************/
18352
static void alc663_mode6_setup(struct hda_codec *codec)
18353
{
18354
struct alc_spec *spec = codec->spec;
18355
spec->autocfg.hp_pins[0] = 0x1b;
18356
spec->autocfg.hp_pins[0] = 0x15;
18357
spec->autocfg.speaker_pins[0] = 0x14;
18358
spec->automute_mixer_nid[0] = 0x0c;
18359
spec->automute = 1;
18360
spec->automute_mode = ALC_AUTOMUTE_MIXER;
18361
spec->ext_mic.pin = 0x18;
18362
spec->ext_mic.mux_idx = 0;
18363
spec->int_mic.pin = 0x19;
18364
spec->int_mic.mux_idx = 1;
18365
spec->auto_mic = 1;
18366
}
18367
18368
/* ***************** Mode7 ******************************/
18369
static void alc663_mode7_setup(struct hda_codec *codec)
18370
{
18371
struct alc_spec *spec = codec->spec;
18372
spec->autocfg.hp_pins[0] = 0x1b;
18373
spec->autocfg.hp_pins[0] = 0x21;
18374
spec->autocfg.speaker_pins[0] = 0x14;
18375
spec->autocfg.speaker_pins[0] = 0x17;
18376
spec->automute = 1;
18377
spec->automute_mode = ALC_AUTOMUTE_PIN;
18378
spec->ext_mic.pin = 0x18;
18379
spec->ext_mic.mux_idx = 0;
18380
spec->int_mic.pin = 0x19;
18381
spec->int_mic.mux_idx = 1;
18382
spec->auto_mic = 1;
18383
}
18384
18385
/* ***************** Mode8 ******************************/
18386
static void alc663_mode8_setup(struct hda_codec *codec)
18387
{
18388
struct alc_spec *spec = codec->spec;
18389
spec->autocfg.hp_pins[0] = 0x21;
18390
spec->autocfg.hp_pins[1] = 0x15;
18391
spec->autocfg.speaker_pins[0] = 0x14;
18392
spec->autocfg.speaker_pins[0] = 0x17;
18393
spec->automute = 1;
18394
spec->automute_mode = ALC_AUTOMUTE_PIN;
18395
spec->ext_mic.pin = 0x18;
18396
spec->ext_mic.mux_idx = 0;
18397
spec->int_mic.pin = 0x12;
18398
spec->int_mic.mux_idx = 9;
18399
spec->auto_mic = 1;
18400
}
18401
18402
static void alc663_g71v_setup(struct hda_codec *codec)
18403
{
18404
struct alc_spec *spec = codec->spec;
18405
spec->autocfg.hp_pins[0] = 0x21;
18406
spec->autocfg.line_out_pins[0] = 0x15;
18407
spec->autocfg.speaker_pins[0] = 0x14;
18408
spec->automute = 1;
18409
spec->automute_mode = ALC_AUTOMUTE_AMP;
18410
spec->detect_line = 1;
18411
spec->automute_lines = 1;
18412
spec->ext_mic.pin = 0x18;
18413
spec->ext_mic.mux_idx = 0;
18414
spec->int_mic.pin = 0x12;
18415
spec->int_mic.mux_idx = 9;
18416
spec->auto_mic = 1;
18417
}
18418
18419
#define alc663_g50v_setup alc663_m51va_setup
18420
18421
static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
18422
HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18423
ALC262_HIPPO_MASTER_SWITCH,
18424
18425
HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18426
HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18427
HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18428
18429
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18430
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18431
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18432
{ } /* end */
18433
};
18434
18435
static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
18436
/* Master Playback automatically created from Speaker and Headphone */
18437
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18438
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18439
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18440
HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18441
18442
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18443
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18444
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18445
18446
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18447
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18448
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18449
{ } /* end */
18450
};
18451
18452
#ifdef CONFIG_SND_HDA_POWER_SAVE
18453
#define alc662_loopbacks alc880_loopbacks
18454
#endif
18455
18456
18457
/* pcm configuration: identical with ALC880 */
18458
#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18459
#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18460
#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18461
#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18462
18463
/*
18464
* configuration and preset
18465
*/
18466
static const char * const alc662_models[ALC662_MODEL_LAST] = {
18467
[ALC662_3ST_2ch_DIG] = "3stack-dig",
18468
[ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18469
[ALC662_3ST_6ch] = "3stack-6ch",
18470
[ALC662_5ST_DIG] = "5stack-dig",
18471
[ALC662_LENOVO_101E] = "lenovo-101e",
18472
[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18473
[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18474
[ALC662_ECS] = "ecs",
18475
[ALC663_ASUS_M51VA] = "m51va",
18476
[ALC663_ASUS_G71V] = "g71v",
18477
[ALC663_ASUS_H13] = "h13",
18478
[ALC663_ASUS_G50V] = "g50v",
18479
[ALC663_ASUS_MODE1] = "asus-mode1",
18480
[ALC662_ASUS_MODE2] = "asus-mode2",
18481
[ALC663_ASUS_MODE3] = "asus-mode3",
18482
[ALC663_ASUS_MODE4] = "asus-mode4",
18483
[ALC663_ASUS_MODE5] = "asus-mode5",
18484
[ALC663_ASUS_MODE6] = "asus-mode6",
18485
[ALC663_ASUS_MODE7] = "asus-mode7",
18486
[ALC663_ASUS_MODE8] = "asus-mode8",
18487
[ALC272_DELL] = "dell",
18488
[ALC272_DELL_ZM1] = "dell-zm1",
18489
[ALC272_SAMSUNG_NC10] = "samsung-nc10",
18490
[ALC662_AUTO] = "auto",
18491
};
18492
18493
static const struct snd_pci_quirk alc662_cfg_tbl[] = {
18494
SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18495
SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18496
SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18497
SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18498
SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18499
SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18500
SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18501
SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18502
SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18503
SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18504
SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18505
SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18506
SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18507
SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18508
SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18509
SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18510
SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18511
SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18512
SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18513
SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18514
SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18515
SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18516
SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18517
SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18518
SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18519
SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18520
SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18521
SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18522
SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18523
SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18524
SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18525
SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18526
SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18527
SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18528
SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18529
SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18530
SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18531
/*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18532
SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18533
SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18534
SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18535
SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18536
SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18537
SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18538
SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18539
SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18540
SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18541
SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18542
SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18543
SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18544
SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18545
SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18546
SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18547
/*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18548
SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18549
SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18550
SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18551
SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18552
SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18553
SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18554
SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18555
SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18556
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18557
SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18558
ALC662_3ST_6ch_DIG),
18559
SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18560
SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18561
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18562
ALC662_3ST_6ch_DIG),
18563
SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18564
SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18565
SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18566
SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18567
SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18568
ALC662_3ST_6ch_DIG),
18569
SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18570
ALC663_ASUS_H13),
18571
SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
18572
{}
18573
};
18574
18575
static const struct alc_config_preset alc662_presets[] = {
18576
[ALC662_3ST_2ch_DIG] = {
18577
.mixers = { alc662_3ST_2ch_mixer },
18578
.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18579
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18580
.dac_nids = alc662_dac_nids,
18581
.dig_out_nid = ALC662_DIGOUT_NID,
18582
.dig_in_nid = ALC662_DIGIN_NID,
18583
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18584
.channel_mode = alc662_3ST_2ch_modes,
18585
.input_mux = &alc662_capture_source,
18586
},
18587
[ALC662_3ST_6ch_DIG] = {
18588
.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18589
.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18590
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18591
.dac_nids = alc662_dac_nids,
18592
.dig_out_nid = ALC662_DIGOUT_NID,
18593
.dig_in_nid = ALC662_DIGIN_NID,
18594
.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18595
.channel_mode = alc662_3ST_6ch_modes,
18596
.need_dac_fix = 1,
18597
.input_mux = &alc662_capture_source,
18598
},
18599
[ALC662_3ST_6ch] = {
18600
.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18601
.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18602
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18603
.dac_nids = alc662_dac_nids,
18604
.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18605
.channel_mode = alc662_3ST_6ch_modes,
18606
.need_dac_fix = 1,
18607
.input_mux = &alc662_capture_source,
18608
},
18609
[ALC662_5ST_DIG] = {
18610
.mixers = { alc662_base_mixer, alc662_chmode_mixer },
18611
.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18612
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18613
.dac_nids = alc662_dac_nids,
18614
.dig_out_nid = ALC662_DIGOUT_NID,
18615
.dig_in_nid = ALC662_DIGIN_NID,
18616
.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18617
.channel_mode = alc662_5stack_modes,
18618
.input_mux = &alc662_capture_source,
18619
},
18620
[ALC662_LENOVO_101E] = {
18621
.mixers = { alc662_lenovo_101e_mixer },
18622
.init_verbs = { alc662_init_verbs,
18623
alc662_eapd_init_verbs,
18624
alc662_sue_init_verbs },
18625
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18626
.dac_nids = alc662_dac_nids,
18627
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18628
.channel_mode = alc662_3ST_2ch_modes,
18629
.input_mux = &alc662_lenovo_101e_capture_source,
18630
.unsol_event = alc_sku_unsol_event,
18631
.setup = alc662_lenovo_101e_setup,
18632
.init_hook = alc_inithook,
18633
},
18634
[ALC662_ASUS_EEEPC_P701] = {
18635
.mixers = { alc662_eeepc_p701_mixer },
18636
.init_verbs = { alc662_init_verbs,
18637
alc662_eapd_init_verbs,
18638
alc662_eeepc_sue_init_verbs },
18639
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18640
.dac_nids = alc662_dac_nids,
18641
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18642
.channel_mode = alc662_3ST_2ch_modes,
18643
.unsol_event = alc_sku_unsol_event,
18644
.setup = alc662_eeepc_setup,
18645
.init_hook = alc_inithook,
18646
},
18647
[ALC662_ASUS_EEEPC_EP20] = {
18648
.mixers = { alc662_eeepc_ep20_mixer,
18649
alc662_chmode_mixer },
18650
.init_verbs = { alc662_init_verbs,
18651
alc662_eapd_init_verbs,
18652
alc662_eeepc_ep20_sue_init_verbs },
18653
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18654
.dac_nids = alc662_dac_nids,
18655
.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18656
.channel_mode = alc662_3ST_6ch_modes,
18657
.input_mux = &alc662_lenovo_101e_capture_source,
18658
.unsol_event = alc_sku_unsol_event,
18659
.setup = alc662_eeepc_ep20_setup,
18660
.init_hook = alc_inithook,
18661
},
18662
[ALC662_ECS] = {
18663
.mixers = { alc662_ecs_mixer },
18664
.init_verbs = { alc662_init_verbs,
18665
alc662_eapd_init_verbs,
18666
alc662_ecs_init_verbs },
18667
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18668
.dac_nids = alc662_dac_nids,
18669
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18670
.channel_mode = alc662_3ST_2ch_modes,
18671
.unsol_event = alc_sku_unsol_event,
18672
.setup = alc662_eeepc_setup,
18673
.init_hook = alc_inithook,
18674
},
18675
[ALC663_ASUS_M51VA] = {
18676
.mixers = { alc663_m51va_mixer },
18677
.init_verbs = { alc662_init_verbs,
18678
alc662_eapd_init_verbs,
18679
alc663_m51va_init_verbs },
18680
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18681
.dac_nids = alc662_dac_nids,
18682
.dig_out_nid = ALC662_DIGOUT_NID,
18683
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18684
.channel_mode = alc662_3ST_2ch_modes,
18685
.unsol_event = alc_sku_unsol_event,
18686
.setup = alc663_m51va_setup,
18687
.init_hook = alc_inithook,
18688
},
18689
[ALC663_ASUS_G71V] = {
18690
.mixers = { alc663_g71v_mixer },
18691
.init_verbs = { alc662_init_verbs,
18692
alc662_eapd_init_verbs,
18693
alc663_g71v_init_verbs },
18694
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18695
.dac_nids = alc662_dac_nids,
18696
.dig_out_nid = ALC662_DIGOUT_NID,
18697
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18698
.channel_mode = alc662_3ST_2ch_modes,
18699
.unsol_event = alc_sku_unsol_event,
18700
.setup = alc663_g71v_setup,
18701
.init_hook = alc_inithook,
18702
},
18703
[ALC663_ASUS_H13] = {
18704
.mixers = { alc663_m51va_mixer },
18705
.init_verbs = { alc662_init_verbs,
18706
alc662_eapd_init_verbs,
18707
alc663_m51va_init_verbs },
18708
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18709
.dac_nids = alc662_dac_nids,
18710
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18711
.channel_mode = alc662_3ST_2ch_modes,
18712
.setup = alc663_m51va_setup,
18713
.unsol_event = alc_sku_unsol_event,
18714
.init_hook = alc_inithook,
18715
},
18716
[ALC663_ASUS_G50V] = {
18717
.mixers = { alc663_g50v_mixer },
18718
.init_verbs = { alc662_init_verbs,
18719
alc662_eapd_init_verbs,
18720
alc663_g50v_init_verbs },
18721
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18722
.dac_nids = alc662_dac_nids,
18723
.dig_out_nid = ALC662_DIGOUT_NID,
18724
.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18725
.channel_mode = alc662_3ST_6ch_modes,
18726
.input_mux = &alc663_capture_source,
18727
.unsol_event = alc_sku_unsol_event,
18728
.setup = alc663_g50v_setup,
18729
.init_hook = alc_inithook,
18730
},
18731
[ALC663_ASUS_MODE1] = {
18732
.mixers = { alc663_m51va_mixer },
18733
.cap_mixer = alc662_auto_capture_mixer,
18734
.init_verbs = { alc662_init_verbs,
18735
alc662_eapd_init_verbs,
18736
alc663_21jd_amic_init_verbs },
18737
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18738
.hp_nid = 0x03,
18739
.dac_nids = alc662_dac_nids,
18740
.dig_out_nid = ALC662_DIGOUT_NID,
18741
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18742
.channel_mode = alc662_3ST_2ch_modes,
18743
.unsol_event = alc_sku_unsol_event,
18744
.setup = alc663_mode1_setup,
18745
.init_hook = alc_inithook,
18746
},
18747
[ALC662_ASUS_MODE2] = {
18748
.mixers = { alc662_1bjd_mixer },
18749
.cap_mixer = alc662_auto_capture_mixer,
18750
.init_verbs = { alc662_init_verbs,
18751
alc662_eapd_init_verbs,
18752
alc662_1bjd_amic_init_verbs },
18753
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18754
.dac_nids = alc662_dac_nids,
18755
.dig_out_nid = ALC662_DIGOUT_NID,
18756
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18757
.channel_mode = alc662_3ST_2ch_modes,
18758
.unsol_event = alc_sku_unsol_event,
18759
.setup = alc662_mode2_setup,
18760
.init_hook = alc_inithook,
18761
},
18762
[ALC663_ASUS_MODE3] = {
18763
.mixers = { alc663_two_hp_m1_mixer },
18764
.cap_mixer = alc662_auto_capture_mixer,
18765
.init_verbs = { alc662_init_verbs,
18766
alc662_eapd_init_verbs,
18767
alc663_two_hp_amic_m1_init_verbs },
18768
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18769
.hp_nid = 0x03,
18770
.dac_nids = alc662_dac_nids,
18771
.dig_out_nid = ALC662_DIGOUT_NID,
18772
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18773
.channel_mode = alc662_3ST_2ch_modes,
18774
.unsol_event = alc_sku_unsol_event,
18775
.setup = alc663_mode3_setup,
18776
.init_hook = alc_inithook,
18777
},
18778
[ALC663_ASUS_MODE4] = {
18779
.mixers = { alc663_asus_21jd_clfe_mixer },
18780
.cap_mixer = alc662_auto_capture_mixer,
18781
.init_verbs = { alc662_init_verbs,
18782
alc662_eapd_init_verbs,
18783
alc663_21jd_amic_init_verbs},
18784
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18785
.hp_nid = 0x03,
18786
.dac_nids = alc662_dac_nids,
18787
.dig_out_nid = ALC662_DIGOUT_NID,
18788
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18789
.channel_mode = alc662_3ST_2ch_modes,
18790
.unsol_event = alc_sku_unsol_event,
18791
.setup = alc663_mode4_setup,
18792
.init_hook = alc_inithook,
18793
},
18794
[ALC663_ASUS_MODE5] = {
18795
.mixers = { alc663_asus_15jd_clfe_mixer },
18796
.cap_mixer = alc662_auto_capture_mixer,
18797
.init_verbs = { alc662_init_verbs,
18798
alc662_eapd_init_verbs,
18799
alc663_15jd_amic_init_verbs },
18800
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18801
.hp_nid = 0x03,
18802
.dac_nids = alc662_dac_nids,
18803
.dig_out_nid = ALC662_DIGOUT_NID,
18804
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18805
.channel_mode = alc662_3ST_2ch_modes,
18806
.unsol_event = alc_sku_unsol_event,
18807
.setup = alc663_mode5_setup,
18808
.init_hook = alc_inithook,
18809
},
18810
[ALC663_ASUS_MODE6] = {
18811
.mixers = { alc663_two_hp_m2_mixer },
18812
.cap_mixer = alc662_auto_capture_mixer,
18813
.init_verbs = { alc662_init_verbs,
18814
alc662_eapd_init_verbs,
18815
alc663_two_hp_amic_m2_init_verbs },
18816
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18817
.hp_nid = 0x03,
18818
.dac_nids = alc662_dac_nids,
18819
.dig_out_nid = ALC662_DIGOUT_NID,
18820
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18821
.channel_mode = alc662_3ST_2ch_modes,
18822
.unsol_event = alc_sku_unsol_event,
18823
.setup = alc663_mode6_setup,
18824
.init_hook = alc_inithook,
18825
},
18826
[ALC663_ASUS_MODE7] = {
18827
.mixers = { alc663_mode7_mixer },
18828
.cap_mixer = alc662_auto_capture_mixer,
18829
.init_verbs = { alc662_init_verbs,
18830
alc662_eapd_init_verbs,
18831
alc663_mode7_init_verbs },
18832
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18833
.hp_nid = 0x03,
18834
.dac_nids = alc662_dac_nids,
18835
.dig_out_nid = ALC662_DIGOUT_NID,
18836
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18837
.channel_mode = alc662_3ST_2ch_modes,
18838
.unsol_event = alc_sku_unsol_event,
18839
.setup = alc663_mode7_setup,
18840
.init_hook = alc_inithook,
18841
},
18842
[ALC663_ASUS_MODE8] = {
18843
.mixers = { alc663_mode8_mixer },
18844
.cap_mixer = alc662_auto_capture_mixer,
18845
.init_verbs = { alc662_init_verbs,
18846
alc662_eapd_init_verbs,
18847
alc663_mode8_init_verbs },
18848
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18849
.hp_nid = 0x03,
18850
.dac_nids = alc662_dac_nids,
18851
.dig_out_nid = ALC662_DIGOUT_NID,
18852
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18853
.channel_mode = alc662_3ST_2ch_modes,
18854
.unsol_event = alc_sku_unsol_event,
18855
.setup = alc663_mode8_setup,
18856
.init_hook = alc_inithook,
18857
},
18858
[ALC272_DELL] = {
18859
.mixers = { alc663_m51va_mixer },
18860
.cap_mixer = alc272_auto_capture_mixer,
18861
.init_verbs = { alc662_init_verbs,
18862
alc662_eapd_init_verbs,
18863
alc272_dell_init_verbs },
18864
.num_dacs = ARRAY_SIZE(alc272_dac_nids),
18865
.dac_nids = alc272_dac_nids,
18866
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18867
.adc_nids = alc272_adc_nids,
18868
.num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18869
.capsrc_nids = alc272_capsrc_nids,
18870
.channel_mode = alc662_3ST_2ch_modes,
18871
.unsol_event = alc_sku_unsol_event,
18872
.setup = alc663_m51va_setup,
18873
.init_hook = alc_inithook,
18874
},
18875
[ALC272_DELL_ZM1] = {
18876
.mixers = { alc663_m51va_mixer },
18877
.cap_mixer = alc662_auto_capture_mixer,
18878
.init_verbs = { alc662_init_verbs,
18879
alc662_eapd_init_verbs,
18880
alc272_dell_zm1_init_verbs },
18881
.num_dacs = ARRAY_SIZE(alc272_dac_nids),
18882
.dac_nids = alc272_dac_nids,
18883
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18884
.adc_nids = alc662_adc_nids,
18885
.num_adc_nids = 1,
18886
.capsrc_nids = alc662_capsrc_nids,
18887
.channel_mode = alc662_3ST_2ch_modes,
18888
.unsol_event = alc_sku_unsol_event,
18889
.setup = alc663_m51va_setup,
18890
.init_hook = alc_inithook,
18891
},
18892
[ALC272_SAMSUNG_NC10] = {
18893
.mixers = { alc272_nc10_mixer },
18894
.init_verbs = { alc662_init_verbs,
18895
alc662_eapd_init_verbs,
18896
alc663_21jd_amic_init_verbs },
18897
.num_dacs = ARRAY_SIZE(alc272_dac_nids),
18898
.dac_nids = alc272_dac_nids,
18899
.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18900
.channel_mode = alc662_3ST_2ch_modes,
18901
/*.input_mux = &alc272_nc10_capture_source,*/
18902
.unsol_event = alc_sku_unsol_event,
18903
.setup = alc663_mode4_setup,
18904
.init_hook = alc_inithook,
18905
},
18906
};
18907
18908
18909
/*
18910
* BIOS auto configuration
18911
*/
18912
18913
/* convert from MIX nid to DAC */
18914
static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18915
{
18916
hda_nid_t list[5];
18917
int i, num;
18918
18919
num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18920
for (i = 0; i < num; i++) {
18921
if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18922
return list[i];
18923
}
18924
return 0;
18925
}
18926
18927
/* go down to the selector widget before the mixer */
18928
static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18929
{
18930
hda_nid_t srcs[5];
18931
int num = snd_hda_get_connections(codec, pin, srcs,
18932
ARRAY_SIZE(srcs));
18933
if (num != 1 ||
18934
get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18935
return pin;
18936
return srcs[0];
18937
}
18938
18939
/* get MIX nid connected to the given pin targeted to DAC */
18940
static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18941
hda_nid_t dac)
18942
{
18943
hda_nid_t mix[5];
18944
int i, num;
18945
18946
pin = alc_go_down_to_selector(codec, pin);
18947
num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18948
for (i = 0; i < num; i++) {
18949
if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18950
return mix[i];
18951
}
18952
return 0;
18953
}
18954
18955
/* select the connection from pin to DAC if needed */
18956
static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18957
hda_nid_t dac)
18958
{
18959
hda_nid_t mix[5];
18960
int i, num;
18961
18962
pin = alc_go_down_to_selector(codec, pin);
18963
num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18964
if (num < 2)
18965
return 0;
18966
for (i = 0; i < num; i++) {
18967
if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18968
snd_hda_codec_update_cache(codec, pin, 0,
18969
AC_VERB_SET_CONNECT_SEL, i);
18970
return 0;
18971
}
18972
}
18973
return 0;
18974
}
18975
18976
/* look for an empty DAC slot */
18977
static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18978
{
18979
struct alc_spec *spec = codec->spec;
18980
hda_nid_t srcs[5];
18981
int i, j, num;
18982
18983
pin = alc_go_down_to_selector(codec, pin);
18984
num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18985
for (i = 0; i < num; i++) {
18986
hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18987
if (!nid)
18988
continue;
18989
for (j = 0; j < spec->multiout.num_dacs; j++)
18990
if (spec->multiout.dac_nids[j] == nid)
18991
break;
18992
if (j >= spec->multiout.num_dacs)
18993
return nid;
18994
}
18995
return 0;
18996
}
18997
18998
/* fill in the dac_nids table from the parsed pin configuration */
18999
static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19000
const struct auto_pin_cfg *cfg)
19001
{
19002
struct alc_spec *spec = codec->spec;
19003
int i;
19004
hda_nid_t dac;
19005
19006
spec->multiout.dac_nids = spec->private_dac_nids;
19007
for (i = 0; i < cfg->line_outs; i++) {
19008
dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
19009
if (!dac)
19010
continue;
19011
spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19012
}
19013
return 0;
19014
}
19015
19016
static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19017
hda_nid_t nid, int idx, unsigned int chs)
19018
{
19019
return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
19020
HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19021
}
19022
19023
static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19024
hda_nid_t nid, int idx, unsigned int chs)
19025
{
19026
return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19027
HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19028
}
19029
19030
#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19031
__alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19032
#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19033
__alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19034
#define alc662_add_stereo_vol(spec, pfx, nid) \
19035
alc662_add_vol_ctl(spec, pfx, nid, 3)
19036
#define alc662_add_stereo_sw(spec, pfx, nid) \
19037
alc662_add_sw_ctl(spec, pfx, nid, 3)
19038
19039
/* add playback controls from the parsed DAC table */
19040
static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19041
const struct auto_pin_cfg *cfg)
19042
{
19043
struct alc_spec *spec = codec->spec;
19044
static const char * const chname[4] = {
19045
"Front", "Surround", NULL /*CLFE*/, "Side"
19046
};
19047
const char *pfx = alc_get_line_out_pfx(spec, true);
19048
hda_nid_t nid, mix, pin;
19049
int i, err, noutputs;
19050
19051
noutputs = cfg->line_outs;
19052
if (spec->multi_ios > 0)
19053
noutputs += spec->multi_ios;
19054
19055
for (i = 0; i < noutputs; i++) {
19056
nid = spec->multiout.dac_nids[i];
19057
if (!nid)
19058
continue;
19059
if (i >= cfg->line_outs)
19060
pin = spec->multi_io[i - 1].pin;
19061
else
19062
pin = cfg->line_out_pins[i];
19063
mix = alc_auto_dac_to_mix(codec, pin, nid);
19064
if (!mix)
19065
continue;
19066
if (!pfx && i == 2) {
19067
/* Center/LFE */
19068
err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19069
if (err < 0)
19070
return err;
19071
err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
19072
if (err < 0)
19073
return err;
19074
err = alc662_add_sw_ctl(spec, "Center", mix, 1);
19075
if (err < 0)
19076
return err;
19077
err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
19078
if (err < 0)
19079
return err;
19080
} else {
19081
const char *name = pfx;
19082
int index = i;
19083
if (!name) {
19084
name = chname[i];
19085
index = 0;
19086
}
19087
err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
19088
if (err < 0)
19089
return err;
19090
err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
19091
if (err < 0)
19092
return err;
19093
}
19094
}
19095
return 0;
19096
}
19097
19098
/* add playback controls for speaker and HP outputs */
19099
/* return DAC nid if any new DAC is assigned */
19100
static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19101
const char *pfx)
19102
{
19103
struct alc_spec *spec = codec->spec;
19104
hda_nid_t nid, mix;
19105
int err;
19106
19107
if (!pin)
19108
return 0;
19109
nid = alc_auto_look_for_dac(codec, pin);
19110
if (!nid) {
19111
/* the corresponding DAC is already occupied */
19112
if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19113
return 0; /* no way */
19114
/* create a switch only */
19115
return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
19116
HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19117
}
19118
19119
mix = alc_auto_dac_to_mix(codec, pin, nid);
19120
if (!mix)
19121
return 0;
19122
err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19123
if (err < 0)
19124
return err;
19125
err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19126
if (err < 0)
19127
return err;
19128
return nid;
19129
}
19130
19131
/* create playback/capture controls for input pins */
19132
#define alc662_auto_create_input_ctls \
19133
alc882_auto_create_input_ctls
19134
19135
static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19136
hda_nid_t nid, int pin_type,
19137
hda_nid_t dac)
19138
{
19139
int i, num;
19140
hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19141
19142
alc_set_pin_output(codec, nid, pin_type);
19143
num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19144
for (i = 0; i < num; i++) {
19145
if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
19146
continue;
19147
/* need the manual connection? */
19148
if (num > 1)
19149
snd_hda_codec_write(codec, nid, 0,
19150
AC_VERB_SET_CONNECT_SEL, i);
19151
/* unmute mixer widget inputs */
19152
snd_hda_codec_write(codec, srcs[i], 0,
19153
AC_VERB_SET_AMP_GAIN_MUTE,
19154
AMP_IN_UNMUTE(0));
19155
snd_hda_codec_write(codec, srcs[i], 0,
19156
AC_VERB_SET_AMP_GAIN_MUTE,
19157
AMP_IN_UNMUTE(1));
19158
return;
19159
}
19160
}
19161
19162
static void alc662_auto_init_multi_out(struct hda_codec *codec)
19163
{
19164
struct alc_spec *spec = codec->spec;
19165
int pin_type = get_pin_type(spec->autocfg.line_out_type);
19166
int i;
19167
19168
for (i = 0; i <= HDA_SIDE; i++) {
19169
hda_nid_t nid = spec->autocfg.line_out_pins[i];
19170
if (nid)
19171
alc662_auto_set_output_and_unmute(codec, nid, pin_type,
19172
spec->multiout.dac_nids[i]);
19173
}
19174
}
19175
19176
static void alc662_auto_init_hp_out(struct hda_codec *codec)
19177
{
19178
struct alc_spec *spec = codec->spec;
19179
hda_nid_t pin;
19180
19181
pin = spec->autocfg.hp_pins[0];
19182
if (pin)
19183
alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19184
spec->multiout.hp_nid);
19185
pin = spec->autocfg.speaker_pins[0];
19186
if (pin)
19187
alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19188
spec->multiout.extra_out_nid[0]);
19189
}
19190
19191
#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19192
19193
static void alc662_auto_init_analog_input(struct hda_codec *codec)
19194
{
19195
struct alc_spec *spec = codec->spec;
19196
struct auto_pin_cfg *cfg = &spec->autocfg;
19197
int i;
19198
19199
for (i = 0; i < cfg->num_inputs; i++) {
19200
hda_nid_t nid = cfg->inputs[i].pin;
19201
if (alc_is_input_pin(codec, nid)) {
19202
alc_set_input_pin(codec, nid, cfg->inputs[i].type);
19203
if (nid != ALC662_PIN_CD_NID &&
19204
(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
19205
snd_hda_codec_write(codec, nid, 0,
19206
AC_VERB_SET_AMP_GAIN_MUTE,
19207
AMP_OUT_MUTE);
19208
}
19209
}
19210
}
19211
19212
#define alc662_auto_init_input_src alc882_auto_init_input_src
19213
19214
/*
19215
* multi-io helper
19216
*/
19217
static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19218
unsigned int location)
19219
{
19220
struct alc_spec *spec = codec->spec;
19221
struct auto_pin_cfg *cfg = &spec->autocfg;
19222
int type, i, num_pins = 0;
19223
19224
for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19225
for (i = 0; i < cfg->num_inputs; i++) {
19226
hda_nid_t nid = cfg->inputs[i].pin;
19227
hda_nid_t dac;
19228
unsigned int defcfg, caps;
19229
if (cfg->inputs[i].type != type)
19230
continue;
19231
defcfg = snd_hda_codec_get_pincfg(codec, nid);
19232
if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19233
continue;
19234
if (location && get_defcfg_location(defcfg) != location)
19235
continue;
19236
caps = snd_hda_query_pin_caps(codec, nid);
19237
if (!(caps & AC_PINCAP_OUT))
19238
continue;
19239
dac = alc_auto_look_for_dac(codec, nid);
19240
if (!dac)
19241
continue;
19242
spec->multi_io[num_pins].pin = nid;
19243
spec->multi_io[num_pins].dac = dac;
19244
num_pins++;
19245
spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19246
}
19247
}
19248
spec->multiout.num_dacs = 1;
19249
if (num_pins < 2)
19250
return 0;
19251
return num_pins;
19252
}
19253
19254
static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19255
struct snd_ctl_elem_info *uinfo)
19256
{
19257
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19258
struct alc_spec *spec = codec->spec;
19259
19260
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19261
uinfo->count = 1;
19262
uinfo->value.enumerated.items = spec->multi_ios + 1;
19263
if (uinfo->value.enumerated.item > spec->multi_ios)
19264
uinfo->value.enumerated.item = spec->multi_ios;
19265
sprintf(uinfo->value.enumerated.name, "%dch",
19266
(uinfo->value.enumerated.item + 1) * 2);
19267
return 0;
19268
}
19269
19270
static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19271
struct snd_ctl_elem_value *ucontrol)
19272
{
19273
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19274
struct alc_spec *spec = codec->spec;
19275
ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19276
return 0;
19277
}
19278
19279
static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19280
{
19281
struct alc_spec *spec = codec->spec;
19282
hda_nid_t nid = spec->multi_io[idx].pin;
19283
19284
if (!spec->multi_io[idx].ctl_in)
19285
spec->multi_io[idx].ctl_in =
19286
snd_hda_codec_read(codec, nid, 0,
19287
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19288
if (output) {
19289
snd_hda_codec_update_cache(codec, nid, 0,
19290
AC_VERB_SET_PIN_WIDGET_CONTROL,
19291
PIN_OUT);
19292
if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19293
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19294
HDA_AMP_MUTE, 0);
19295
alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19296
} else {
19297
if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19298
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19299
HDA_AMP_MUTE, HDA_AMP_MUTE);
19300
snd_hda_codec_update_cache(codec, nid, 0,
19301
AC_VERB_SET_PIN_WIDGET_CONTROL,
19302
spec->multi_io[idx].ctl_in);
19303
}
19304
return 0;
19305
}
19306
19307
static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19308
struct snd_ctl_elem_value *ucontrol)
19309
{
19310
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19311
struct alc_spec *spec = codec->spec;
19312
int i, ch;
19313
19314
ch = ucontrol->value.enumerated.item[0];
19315
if (ch < 0 || ch > spec->multi_ios)
19316
return -EINVAL;
19317
if (ch == (spec->ext_channel_count - 1) / 2)
19318
return 0;
19319
spec->ext_channel_count = (ch + 1) * 2;
19320
for (i = 0; i < spec->multi_ios; i++)
19321
alc_set_multi_io(codec, i, i < ch);
19322
spec->multiout.max_channels = spec->ext_channel_count;
19323
return 1;
19324
}
19325
19326
static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
19327
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19328
.name = "Channel Mode",
19329
.info = alc_auto_ch_mode_info,
19330
.get = alc_auto_ch_mode_get,
19331
.put = alc_auto_ch_mode_put,
19332
};
19333
19334
static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19335
{
19336
struct alc_spec *spec = codec->spec;
19337
struct auto_pin_cfg *cfg = &spec->autocfg;
19338
unsigned int location, defcfg;
19339
int num_pins;
19340
19341
if (cfg->line_outs != 1 ||
19342
cfg->line_out_type != AUTO_PIN_LINE_OUT)
19343
return 0;
19344
19345
defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19346
location = get_defcfg_location(defcfg);
19347
19348
num_pins = alc_auto_fill_multi_ios(codec, location);
19349
if (num_pins > 0) {
19350
struct snd_kcontrol_new *knew;
19351
19352
knew = alc_kcontrol_new(spec);
19353
if (!knew)
19354
return -ENOMEM;
19355
*knew = alc_auto_channel_mode_enum;
19356
knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19357
if (!knew->name)
19358
return -ENOMEM;
19359
19360
spec->multi_ios = num_pins;
19361
spec->ext_channel_count = 2;
19362
spec->multiout.num_dacs = num_pins + 1;
19363
}
19364
return 0;
19365
}
19366
19367
static int alc662_parse_auto_config(struct hda_codec *codec)
19368
{
19369
struct alc_spec *spec = codec->spec;
19370
int err;
19371
static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19372
19373
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19374
alc662_ignore);
19375
if (err < 0)
19376
return err;
19377
if (!spec->autocfg.line_outs)
19378
return 0; /* can't find valid BIOS pin config */
19379
19380
err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19381
if (err < 0)
19382
return err;
19383
err = alc_auto_add_multi_channel_mode(codec);
19384
if (err < 0)
19385
return err;
19386
err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19387
if (err < 0)
19388
return err;
19389
err = alc662_auto_create_extra_out(codec,
19390
spec->autocfg.speaker_pins[0],
19391
"Speaker");
19392
if (err < 0)
19393
return err;
19394
if (err)
19395
spec->multiout.extra_out_nid[0] = err;
19396
err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19397
"Headphone");
19398
if (err < 0)
19399
return err;
19400
if (err)
19401
spec->multiout.hp_nid = err;
19402
err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19403
if (err < 0)
19404
return err;
19405
19406
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19407
19408
alc_auto_parse_digital(codec);
19409
19410
if (spec->kctls.list)
19411
add_mixer(spec, spec->kctls.list);
19412
19413
spec->num_mux_defs = 1;
19414
spec->input_mux = &spec->private_imux[0];
19415
19416
err = alc_auto_add_mic_boost(codec);
19417
if (err < 0)
19418
return err;
19419
19420
if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19421
codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19422
alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19423
else
19424
alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
19425
19426
return 1;
19427
}
19428
19429
/* additional initialization for auto-configuration model */
19430
static void alc662_auto_init(struct hda_codec *codec)
19431
{
19432
struct alc_spec *spec = codec->spec;
19433
alc662_auto_init_multi_out(codec);
19434
alc662_auto_init_hp_out(codec);
19435
alc662_auto_init_analog_input(codec);
19436
alc662_auto_init_input_src(codec);
19437
alc_auto_init_digital(codec);
19438
if (spec->unsol_event)
19439
alc_inithook(codec);
19440
}
19441
19442
static void alc272_fixup_mario(struct hda_codec *codec,
19443
const struct alc_fixup *fix, int action)
19444
{
19445
if (action != ALC_FIXUP_ACT_PROBE)
19446
return;
19447
if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19448
(0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19449
(0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19450
(0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19451
(0 << AC_AMPCAP_MUTE_SHIFT)))
19452
printk(KERN_WARNING
19453
"hda_codec: failed to override amp caps for NID 0x2\n");
19454
}
19455
19456
enum {
19457
ALC662_FIXUP_ASPIRE,
19458
ALC662_FIXUP_IDEAPAD,
19459
ALC272_FIXUP_MARIO,
19460
ALC662_FIXUP_CZC_P10T,
19461
ALC662_FIXUP_SKU_IGNORE,
19462
};
19463
19464
static const struct alc_fixup alc662_fixups[] = {
19465
[ALC662_FIXUP_ASPIRE] = {
19466
.type = ALC_FIXUP_PINS,
19467
.v.pins = (const struct alc_pincfg[]) {
19468
{ 0x15, 0x99130112 }, /* subwoofer */
19469
{ }
19470
}
19471
},
19472
[ALC662_FIXUP_IDEAPAD] = {
19473
.type = ALC_FIXUP_PINS,
19474
.v.pins = (const struct alc_pincfg[]) {
19475
{ 0x17, 0x99130112 }, /* subwoofer */
19476
{ }
19477
}
19478
},
19479
[ALC272_FIXUP_MARIO] = {
19480
.type = ALC_FIXUP_FUNC,
19481
.v.func = alc272_fixup_mario,
19482
},
19483
[ALC662_FIXUP_CZC_P10T] = {
19484
.type = ALC_FIXUP_VERBS,
19485
.v.verbs = (const struct hda_verb[]) {
19486
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19487
{}
19488
}
19489
},
19490
[ALC662_FIXUP_SKU_IGNORE] = {
19491
.type = ALC_FIXUP_SKU,
19492
.v.sku = ALC_FIXUP_SKU_IGNORE,
19493
},
19494
};
19495
19496
static const struct snd_pci_quirk alc662_fixup_tbl[] = {
19497
SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19498
SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
19499
SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
19500
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19501
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19502
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19503
SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
19504
{}
19505
};
19506
19507
static const struct alc_model_fixup alc662_fixup_models[] = {
19508
{.id = ALC272_FIXUP_MARIO, .name = "mario"},
19509
{}
19510
};
19511
19512
19513
static int patch_alc662(struct hda_codec *codec)
19514
{
19515
struct alc_spec *spec;
19516
int err, board_config;
19517
int coef;
19518
19519
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19520
if (!spec)
19521
return -ENOMEM;
19522
19523
codec->spec = spec;
19524
19525
alc_auto_parse_customize_define(codec);
19526
19527
alc_fix_pll_init(codec, 0x20, 0x04, 15);
19528
19529
coef = alc_read_coef_idx(codec, 0);
19530
if (coef == 0x8020 || coef == 0x8011)
19531
alc_codec_rename(codec, "ALC661");
19532
else if (coef & (1 << 14) &&
19533
codec->bus->pci->subsystem_vendor == 0x1025 &&
19534
spec->cdefine.platform_type == 1)
19535
alc_codec_rename(codec, "ALC272X");
19536
else if (coef == 0x4011)
19537
alc_codec_rename(codec, "ALC656");
19538
19539
board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19540
alc662_models,
19541
alc662_cfg_tbl);
19542
if (board_config < 0) {
19543
printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19544
codec->chip_name);
19545
board_config = ALC662_AUTO;
19546
}
19547
19548
if (board_config == ALC662_AUTO) {
19549
alc_pick_fixup(codec, alc662_fixup_models,
19550
alc662_fixup_tbl, alc662_fixups);
19551
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
19552
/* automatic parse from the BIOS config */
19553
err = alc662_parse_auto_config(codec);
19554
if (err < 0) {
19555
alc_free(codec);
19556
return err;
19557
} else if (!err) {
19558
printk(KERN_INFO
19559
"hda_codec: Cannot set up configuration "
19560
"from BIOS. Using base mode...\n");
19561
board_config = ALC662_3ST_2ch_DIG;
19562
}
19563
}
19564
19565
if (has_cdefine_beep(codec)) {
19566
err = snd_hda_attach_beep_device(codec, 0x1);
19567
if (err < 0) {
19568
alc_free(codec);
19569
return err;
19570
}
19571
}
19572
19573
if (board_config != ALC662_AUTO)
19574
setup_preset(codec, &alc662_presets[board_config]);
19575
19576
spec->stream_analog_playback = &alc662_pcm_analog_playback;
19577
spec->stream_analog_capture = &alc662_pcm_analog_capture;
19578
19579
spec->stream_digital_playback = &alc662_pcm_digital_playback;
19580
spec->stream_digital_capture = &alc662_pcm_digital_capture;
19581
19582
if (!spec->adc_nids) {
19583
spec->adc_nids = alc662_adc_nids;
19584
spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19585
}
19586
if (!spec->capsrc_nids)
19587
spec->capsrc_nids = alc662_capsrc_nids;
19588
19589
if (!spec->cap_mixer)
19590
set_capture_mixer(codec);
19591
19592
if (has_cdefine_beep(codec)) {
19593
switch (codec->vendor_id) {
19594
case 0x10ec0662:
19595
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19596
break;
19597
case 0x10ec0272:
19598
case 0x10ec0663:
19599
case 0x10ec0665:
19600
set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19601
break;
19602
case 0x10ec0273:
19603
set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19604
break;
19605
}
19606
}
19607
spec->vmaster_nid = 0x02;
19608
19609
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19610
19611
codec->patch_ops = alc_patch_ops;
19612
if (board_config == ALC662_AUTO)
19613
spec->init_hook = alc662_auto_init;
19614
spec->shutup = alc_eapd_shutup;
19615
19616
alc_init_jacks(codec);
19617
19618
#ifdef CONFIG_SND_HDA_POWER_SAVE
19619
if (!spec->loopback.amplist)
19620
spec->loopback.amplist = alc662_loopbacks;
19621
#endif
19622
19623
return 0;
19624
}
19625
19626
static int patch_alc888(struct hda_codec *codec)
19627
{
19628
if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19629
kfree(codec->chip_name);
19630
if (codec->vendor_id == 0x10ec0887)
19631
codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19632
else
19633
codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19634
if (!codec->chip_name) {
19635
alc_free(codec);
19636
return -ENOMEM;
19637
}
19638
return patch_alc662(codec);
19639
}
19640
return patch_alc882(codec);
19641
}
19642
19643
static int patch_alc899(struct hda_codec *codec)
19644
{
19645
if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19646
kfree(codec->chip_name);
19647
codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19648
}
19649
return patch_alc882(codec);
19650
}
19651
19652
/*
19653
* ALC680 support
19654
*/
19655
#define ALC680_DIGIN_NID ALC880_DIGIN_NID
19656
#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19657
#define alc680_modes alc260_modes
19658
19659
static const hda_nid_t alc680_dac_nids[3] = {
19660
/* Lout1, Lout2, hp */
19661
0x02, 0x03, 0x04
19662
};
19663
19664
static const hda_nid_t alc680_adc_nids[3] = {
19665
/* ADC0-2 */
19666
/* DMIC, MIC, Line-in*/
19667
0x07, 0x08, 0x09
19668
};
19669
19670
/*
19671
* Analog capture ADC cgange
19672
*/
19673
static void alc680_rec_autoswitch(struct hda_codec *codec)
19674
{
19675
struct alc_spec *spec = codec->spec;
19676
struct auto_pin_cfg *cfg = &spec->autocfg;
19677
int pin_found = 0;
19678
int type_found = AUTO_PIN_LAST;
19679
hda_nid_t nid;
19680
int i;
19681
19682
for (i = 0; i < cfg->num_inputs; i++) {
19683
nid = cfg->inputs[i].pin;
19684
if (!is_jack_detectable(codec, nid))
19685
continue;
19686
if (snd_hda_jack_detect(codec, nid)) {
19687
if (cfg->inputs[i].type < type_found) {
19688
type_found = cfg->inputs[i].type;
19689
pin_found = nid;
19690
}
19691
}
19692
}
19693
19694
nid = 0x07;
19695
if (pin_found)
19696
snd_hda_get_connections(codec, pin_found, &nid, 1);
19697
19698
if (nid != spec->cur_adc)
19699
__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19700
spec->cur_adc = nid;
19701
snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19702
spec->cur_adc_format);
19703
}
19704
19705
static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19706
struct hda_codec *codec,
19707
unsigned int stream_tag,
19708
unsigned int format,
19709
struct snd_pcm_substream *substream)
19710
{
19711
struct alc_spec *spec = codec->spec;
19712
19713
spec->cur_adc = 0x07;
19714
spec->cur_adc_stream_tag = stream_tag;
19715
spec->cur_adc_format = format;
19716
19717
alc680_rec_autoswitch(codec);
19718
return 0;
19719
}
19720
19721
static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19722
struct hda_codec *codec,
19723
struct snd_pcm_substream *substream)
19724
{
19725
snd_hda_codec_cleanup_stream(codec, 0x07);
19726
snd_hda_codec_cleanup_stream(codec, 0x08);
19727
snd_hda_codec_cleanup_stream(codec, 0x09);
19728
return 0;
19729
}
19730
19731
static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19732
.substreams = 1, /* can be overridden */
19733
.channels_min = 2,
19734
.channels_max = 2,
19735
/* NID is set in alc_build_pcms */
19736
.ops = {
19737
.prepare = alc680_capture_pcm_prepare,
19738
.cleanup = alc680_capture_pcm_cleanup
19739
},
19740
};
19741
19742
static const struct snd_kcontrol_new alc680_base_mixer[] = {
19743
/* output mixer control */
19744
HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19745
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19746
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19747
HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19748
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19749
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19750
HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19751
{ }
19752
};
19753
19754
static const struct hda_bind_ctls alc680_bind_cap_vol = {
19755
.ops = &snd_hda_bind_vol,
19756
.values = {
19757
HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19758
HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19759
HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19760
0
19761
},
19762
};
19763
19764
static const struct hda_bind_ctls alc680_bind_cap_switch = {
19765
.ops = &snd_hda_bind_sw,
19766
.values = {
19767
HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19768
HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19769
HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19770
0
19771
},
19772
};
19773
19774
static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19775
HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19776
HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19777
{ } /* end */
19778
};
19779
19780
/*
19781
* generic initialization of ADC, input mixers and output mixers
19782
*/
19783
static const struct hda_verb alc680_init_verbs[] = {
19784
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19785
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19786
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19787
19788
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19789
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19790
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19791
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19792
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19793
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19794
19795
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19796
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19797
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19798
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19799
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19800
19801
{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19802
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19803
{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19804
19805
{ }
19806
};
19807
19808
/* toggle speaker-output according to the hp-jack state */
19809
static void alc680_base_setup(struct hda_codec *codec)
19810
{
19811
struct alc_spec *spec = codec->spec;
19812
19813
spec->autocfg.hp_pins[0] = 0x16;
19814
spec->autocfg.speaker_pins[0] = 0x14;
19815
spec->autocfg.speaker_pins[1] = 0x15;
19816
spec->autocfg.num_inputs = 2;
19817
spec->autocfg.inputs[0].pin = 0x18;
19818
spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19819
spec->autocfg.inputs[1].pin = 0x19;
19820
spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19821
spec->automute = 1;
19822
spec->automute_mode = ALC_AUTOMUTE_AMP;
19823
}
19824
19825
static void alc680_unsol_event(struct hda_codec *codec,
19826
unsigned int res)
19827
{
19828
if ((res >> 26) == ALC880_HP_EVENT)
19829
alc_hp_automute(codec);
19830
if ((res >> 26) == ALC880_MIC_EVENT)
19831
alc680_rec_autoswitch(codec);
19832
}
19833
19834
static void alc680_inithook(struct hda_codec *codec)
19835
{
19836
alc_hp_automute(codec);
19837
alc680_rec_autoswitch(codec);
19838
}
19839
19840
/* create input playback/capture controls for the given pin */
19841
static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19842
const char *ctlname, int idx)
19843
{
19844
hda_nid_t dac;
19845
int err;
19846
19847
switch (nid) {
19848
case 0x14:
19849
dac = 0x02;
19850
break;
19851
case 0x15:
19852
dac = 0x03;
19853
break;
19854
case 0x16:
19855
dac = 0x04;
19856
break;
19857
default:
19858
return 0;
19859
}
19860
if (spec->multiout.dac_nids[0] != dac &&
19861
spec->multiout.dac_nids[1] != dac) {
19862
err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19863
HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19864
HDA_OUTPUT));
19865
if (err < 0)
19866
return err;
19867
19868
err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19869
HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19870
19871
if (err < 0)
19872
return err;
19873
spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19874
}
19875
19876
return 0;
19877
}
19878
19879
/* add playback controls from the parsed DAC table */
19880
static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19881
const struct auto_pin_cfg *cfg)
19882
{
19883
hda_nid_t nid;
19884
int err;
19885
19886
spec->multiout.dac_nids = spec->private_dac_nids;
19887
19888
nid = cfg->line_out_pins[0];
19889
if (nid) {
19890
const char *name;
19891
if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19892
name = "Speaker";
19893
else
19894
name = "Front";
19895
err = alc680_new_analog_output(spec, nid, name, 0);
19896
if (err < 0)
19897
return err;
19898
}
19899
19900
nid = cfg->speaker_pins[0];
19901
if (nid) {
19902
err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19903
if (err < 0)
19904
return err;
19905
}
19906
nid = cfg->hp_pins[0];
19907
if (nid) {
19908
err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19909
if (err < 0)
19910
return err;
19911
}
19912
19913
return 0;
19914
}
19915
19916
static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19917
hda_nid_t nid, int pin_type)
19918
{
19919
alc_set_pin_output(codec, nid, pin_type);
19920
}
19921
19922
static void alc680_auto_init_multi_out(struct hda_codec *codec)
19923
{
19924
struct alc_spec *spec = codec->spec;
19925
hda_nid_t nid = spec->autocfg.line_out_pins[0];
19926
if (nid) {
19927
int pin_type = get_pin_type(spec->autocfg.line_out_type);
19928
alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19929
}
19930
}
19931
19932
static void alc680_auto_init_hp_out(struct hda_codec *codec)
19933
{
19934
struct alc_spec *spec = codec->spec;
19935
hda_nid_t pin;
19936
19937
pin = spec->autocfg.hp_pins[0];
19938
if (pin)
19939
alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19940
pin = spec->autocfg.speaker_pins[0];
19941
if (pin)
19942
alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19943
}
19944
19945
/* pcm configuration: identical with ALC880 */
19946
#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19947
#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19948
#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19949
#define alc680_pcm_digital_playback alc880_pcm_digital_playback
19950
#define alc680_pcm_digital_capture alc880_pcm_digital_capture
19951
19952
/*
19953
* BIOS auto configuration
19954
*/
19955
static int alc680_parse_auto_config(struct hda_codec *codec)
19956
{
19957
struct alc_spec *spec = codec->spec;
19958
int err;
19959
static const hda_nid_t alc680_ignore[] = { 0 };
19960
19961
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19962
alc680_ignore);
19963
if (err < 0)
19964
return err;
19965
19966
if (!spec->autocfg.line_outs) {
19967
if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19968
spec->multiout.max_channels = 2;
19969
spec->no_analog = 1;
19970
goto dig_only;
19971
}
19972
return 0; /* can't find valid BIOS pin config */
19973
}
19974
err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19975
if (err < 0)
19976
return err;
19977
19978
spec->multiout.max_channels = 2;
19979
19980
dig_only:
19981
/* digital only support output */
19982
alc_auto_parse_digital(codec);
19983
if (spec->kctls.list)
19984
add_mixer(spec, spec->kctls.list);
19985
19986
add_verb(spec, alc680_init_verbs);
19987
19988
err = alc_auto_add_mic_boost(codec);
19989
if (err < 0)
19990
return err;
19991
19992
return 1;
19993
}
19994
19995
#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19996
19997
/* init callback for auto-configuration model -- overriding the default init */
19998
static void alc680_auto_init(struct hda_codec *codec)
19999
{
20000
struct alc_spec *spec = codec->spec;
20001
alc680_auto_init_multi_out(codec);
20002
alc680_auto_init_hp_out(codec);
20003
alc680_auto_init_analog_input(codec);
20004
alc_auto_init_digital(codec);
20005
if (spec->unsol_event)
20006
alc_inithook(codec);
20007
}
20008
20009
/*
20010
* configuration and preset
20011
*/
20012
static const char * const alc680_models[ALC680_MODEL_LAST] = {
20013
[ALC680_BASE] = "base",
20014
[ALC680_AUTO] = "auto",
20015
};
20016
20017
static const struct snd_pci_quirk alc680_cfg_tbl[] = {
20018
SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
20019
{}
20020
};
20021
20022
static const struct alc_config_preset alc680_presets[] = {
20023
[ALC680_BASE] = {
20024
.mixers = { alc680_base_mixer },
20025
.cap_mixer = alc680_master_capture_mixer,
20026
.init_verbs = { alc680_init_verbs },
20027
.num_dacs = ARRAY_SIZE(alc680_dac_nids),
20028
.dac_nids = alc680_dac_nids,
20029
.dig_out_nid = ALC680_DIGOUT_NID,
20030
.num_channel_mode = ARRAY_SIZE(alc680_modes),
20031
.channel_mode = alc680_modes,
20032
.unsol_event = alc680_unsol_event,
20033
.setup = alc680_base_setup,
20034
.init_hook = alc680_inithook,
20035
20036
},
20037
};
20038
20039
static int patch_alc680(struct hda_codec *codec)
20040
{
20041
struct alc_spec *spec;
20042
int board_config;
20043
int err;
20044
20045
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20046
if (spec == NULL)
20047
return -ENOMEM;
20048
20049
codec->spec = spec;
20050
20051
board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20052
alc680_models,
20053
alc680_cfg_tbl);
20054
20055
if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20056
printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20057
codec->chip_name);
20058
board_config = ALC680_AUTO;
20059
}
20060
20061
if (board_config == ALC680_AUTO) {
20062
/* automatic parse from the BIOS config */
20063
err = alc680_parse_auto_config(codec);
20064
if (err < 0) {
20065
alc_free(codec);
20066
return err;
20067
} else if (!err) {
20068
printk(KERN_INFO
20069
"hda_codec: Cannot set up configuration "
20070
"from BIOS. Using base mode...\n");
20071
board_config = ALC680_BASE;
20072
}
20073
}
20074
20075
if (board_config != ALC680_AUTO)
20076
setup_preset(codec, &alc680_presets[board_config]);
20077
20078
spec->stream_analog_playback = &alc680_pcm_analog_playback;
20079
spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
20080
spec->stream_digital_playback = &alc680_pcm_digital_playback;
20081
spec->stream_digital_capture = &alc680_pcm_digital_capture;
20082
20083
if (!spec->adc_nids) {
20084
spec->adc_nids = alc680_adc_nids;
20085
spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20086
}
20087
20088
if (!spec->cap_mixer)
20089
set_capture_mixer(codec);
20090
20091
spec->vmaster_nid = 0x02;
20092
20093
codec->patch_ops = alc_patch_ops;
20094
if (board_config == ALC680_AUTO)
20095
spec->init_hook = alc680_auto_init;
20096
20097
return 0;
20098
}
20099
20100
/*
20101
* patch entries
20102
*/
20103
static const struct hda_codec_preset snd_hda_preset_realtek[] = {
20104
{ .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
20105
{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
20106
{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
20107
{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
20108
{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
20109
{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
20110
{ .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
20111
{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
20112
{ .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
20113
{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
20114
{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
20115
.patch = patch_alc861 },
20116
{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20117
{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20118
{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
20119
{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
20120
.patch = patch_alc882 },
20121
{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20122
.patch = patch_alc662 },
20123
{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
20124
{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
20125
{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
20126
{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
20127
{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
20128
{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
20129
{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
20130
{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
20131
.patch = patch_alc882 },
20132
{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
20133
.patch = patch_alc882 },
20134
{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
20135
{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
20136
{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
20137
.patch = patch_alc882 },
20138
{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
20139
{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
20140
{ .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
20141
{ .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
20142
{} /* terminator */
20143
};
20144
20145
MODULE_ALIAS("snd-hda-codec-id:10ec*");
20146
20147
MODULE_LICENSE("GPL");
20148
MODULE_DESCRIPTION("Realtek HD-audio codec");
20149
20150
static struct hda_codec_preset_list realtek_list = {
20151
.preset = snd_hda_preset_realtek,
20152
.owner = THIS_MODULE,
20153
};
20154
20155
static int __init patch_realtek_init(void)
20156
{
20157
return snd_hda_add_codec_preset(&realtek_list);
20158
}
20159
20160
static void __exit patch_realtek_exit(void)
20161
{
20162
snd_hda_delete_codec_preset(&realtek_list);
20163
}
20164
20165
module_init(patch_realtek_init)
20166
module_exit(patch_realtek_exit)
20167
20168