aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/atmel/abdac.c2
-rw-r--r--sound/atmel/ac97c.c2
-rw-r--r--sound/core/misc.c40
-rw-r--r--sound/core/pcm_compat.c2
-rw-r--r--sound/core/pcm_lib.c13
-rw-r--r--sound/core/rawmidi.c45
-rw-r--r--sound/core/rtctimer.c2
-rw-r--r--sound/firewire/isight.c1
-rw-r--r--sound/firewire/speakers.c2
-rw-r--r--sound/oss/ad1848.c6
-rw-r--r--sound/oss/sb_mixer.c6
-rw-r--r--sound/pci/ad1889.c4
-rw-r--r--sound/pci/ali5451/ali5451.c4
-rw-r--r--sound/pci/als300.c4
-rw-r--r--sound/pci/als4000.c2
-rw-r--r--sound/pci/asihpi/asihpi.c87
-rw-r--r--sound/pci/asihpi/hpi.h24
-rw-r--r--sound/pci/asihpi/hpi6000.c11
-rw-r--r--sound/pci/asihpi/hpi6205.c52
-rw-r--r--sound/pci/asihpi/hpi6205.h25
-rw-r--r--sound/pci/asihpi/hpi_internal.h155
-rw-r--r--sound/pci/asihpi/hpicmn.c17
-rw-r--r--sound/pci/asihpi/hpidspcd.c141
-rw-r--r--sound/pci/asihpi/hpidspcd.h72
-rw-r--r--sound/pci/asihpi/hpifunc.c86
-rw-r--r--sound/pci/asihpi/hpimsginit.c4
-rw-r--r--sound/pci/asihpi/hpimsgx.c6
-rw-r--r--sound/pci/asihpi/hpioctl.c34
-rw-r--r--sound/pci/asihpi/hpios.c8
-rw-r--r--sound/pci/asihpi/hpios.h1
-rw-r--r--sound/pci/atiixp.c4
-rw-r--r--sound/pci/atiixp_modem.c4
-rw-r--r--sound/pci/au88x0/au88x0.c4
-rw-r--r--sound/pci/aw2/aw2-alsa.c4
-rw-r--r--sound/pci/azt3328.c4
-rw-r--r--sound/pci/bt87x.c4
-rw-r--r--sound/pci/ca0106/ca0106_main.c4
-rw-r--r--sound/pci/cmipci.c4
-rw-r--r--sound/pci/cs4281.c4
-rw-r--r--sound/pci/cs46xx/cs46xx.c2
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c2
-rw-r--r--sound/pci/cs5530.c2
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c4
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c4
-rw-r--r--sound/pci/ctxfi/ct20k2reg.h1
-rw-r--r--sound/pci/ctxfi/ctatc.c107
-rw-r--r--sound/pci/ctxfi/ctatc.h8
-rw-r--r--sound/pci/ctxfi/ctdaio.c23
-rw-r--r--sound/pci/ctxfi/ctdaio.h1
-rw-r--r--sound/pci/ctxfi/cthardware.h14
-rw-r--r--sound/pci/ctxfi/cthw20k1.c15
-rw-r--r--sound/pci/ctxfi/cthw20k2.c337
-rw-r--r--sound/pci/ctxfi/ctmixer.c145
-rw-r--r--sound/pci/ctxfi/xfi.c6
-rw-r--r--sound/pci/echoaudio/echoaudio.c6
-rw-r--r--sound/pci/emu10k1/emu10k1.c2
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c10
-rw-r--r--sound/pci/emu10k1/emu10k1x.c4
-rw-r--r--sound/pci/ens1370.c4
-rw-r--r--sound/pci/es1938.c6
-rw-r--r--sound/pci/es1968.c68
-rw-r--r--sound/pci/fm801.c17
-rw-r--r--sound/pci/hda/Kconfig40
-rw-r--r--sound/pci/hda/Makefile4
-rw-r--r--sound/pci/hda/alc260_quirks.c1272
-rw-r--r--sound/pci/hda/alc262_quirks.c1353
-rw-r--r--sound/pci/hda/alc268_quirks.c636
-rw-r--r--sound/pci/hda/alc269_quirks.c681
-rw-r--r--sound/pci/hda/alc662_quirks.c1408
-rw-r--r--sound/pci/hda/alc680_quirks.c222
-rw-r--r--sound/pci/hda/alc861_quirks.c725
-rw-r--r--sound/pci/hda/alc861vd_quirks.c605
-rw-r--r--sound/pci/hda/alc880_quirks.c1898
-rw-r--r--sound/pci/hda/alc882_quirks.c3755
-rw-r--r--sound/pci/hda/alc_quirks.c467
-rw-r--r--sound/pci/hda/hda_beep.h9
-rw-r--r--sound/pci/hda/hda_codec.c477
-rw-r--r--sound/pci/hda/hda_codec.h45
-rw-r--r--sound/pci/hda/hda_eld.c48
-rw-r--r--sound/pci/hda/hda_intel.c80
-rw-r--r--sound/pci/hda/hda_local.h12
-rw-r--r--sound/pci/hda/hda_proc.c2
-rw-r--r--sound/pci/hda/patch_analog.c27
-rw-r--r--sound/pci/hda/patch_ca0110.c3
-rw-r--r--sound/pci/hda/patch_ca0132.c1097
-rw-r--r--sound/pci/hda/patch_cirrus.c754
-rw-r--r--sound/pci/hda/patch_cmedia.c17
-rw-r--r--sound/pci/hda/patch_conexant.c90
-rw-r--r--sound/pci/hda/patch_hdmi.c704
-rw-r--r--sound/pci/hda/patch_realtek.c18260
-rw-r--r--sound/pci/hda/patch_sigmatel.c318
-rw-r--r--sound/pci/hda/patch_via.c6077
-rw-r--r--sound/pci/ice1712/ice1712.c4
-rw-r--r--sound/pci/ice1712/ice1724.c4
-rw-r--r--sound/pci/intel8x0.c12
-rw-r--r--sound/pci/intel8x0m.c6
-rw-r--r--sound/pci/korg1212/korg1212.c4
-rw-r--r--sound/pci/lola/lola.c6
-rw-r--r--sound/pci/lola/lola.h2
-rw-r--r--sound/pci/lola/lola_mixer.c130
-rw-r--r--sound/pci/lx6464es/lx6464es.c25
-rw-r--r--sound/pci/lx6464es/lx6464es.h2
-rw-r--r--sound/pci/lx6464es/lx_core.c14
-rw-r--r--sound/pci/lx6464es/lx_core.h2
-rw-r--r--sound/pci/maestro3.c75
-rw-r--r--sound/pci/mixart/mixart.c4
-rw-r--r--sound/pci/nm256/nm256.c4
-rw-r--r--sound/pci/oxygen/oxygen.c2
-rw-r--r--sound/pci/oxygen/oxygen_lib.c2
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c6
-rw-r--r--sound/pci/oxygen/virtuoso.c2
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c5
-rw-r--r--sound/pci/pcxhr/pcxhr.c4
-rw-r--r--sound/pci/riptide/riptide.c6
-rw-r--r--sound/pci/rme32.c4
-rw-r--r--sound/pci/rme96.c4
-rw-r--r--sound/pci/rme9652/hdsp.c4
-rw-r--r--sound/pci/rme9652/hdspm.c129
-rw-r--r--sound/pci/rme9652/rme9652.c4
-rw-r--r--sound/pci/sis7019.c6
-rw-r--r--sound/pci/sonicvibes.c4
-rw-r--r--sound/pci/trident/trident.c2
-rw-r--r--sound/pci/trident/trident_main.c2
-rw-r--r--sound/pci/via82xx.c4
-rw-r--r--sound/pci/via82xx_modem.c4
-rw-r--r--sound/pci/vx222/vx222.c4
-rw-r--r--sound/pci/ymfpci/ymfpci.c2
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c2
-rw-r--r--sound/pcmcia/vx/vxpocket.c2
-rw-r--r--sound/soc/codecs/cx20442.c8
-rw-r--r--sound/soc/codecs/wm8991.c1
-rw-r--r--sound/spi/at73c213.c2
-rw-r--r--sound/usb/6fire/firmware.c2
-rw-r--r--sound/usb/6fire/pcm.c4
-rw-r--r--sound/usb/card.c16
-rw-r--r--sound/usb/endpoint.c2
-rw-r--r--sound/usb/misc/ua101.c2
-rw-r--r--sound/usb/quirks-table.h30
-rw-r--r--sound/usb/quirks.c161
140 files changed, 21114 insertions, 22382 deletions
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c
index 6e240918189..bfee60c4d4c 100644
--- a/sound/atmel/abdac.c
+++ b/sound/atmel/abdac.c
@@ -599,4 +599,4 @@ module_exit(atmel_abdac_exit);
599 599
600MODULE_LICENSE("GPL"); 600MODULE_LICENSE("GPL");
601MODULE_DESCRIPTION("Driver for Atmel Audio Bitstream DAC (ABDAC)"); 601MODULE_DESCRIPTION("Driver for Atmel Audio Bitstream DAC (ABDAC)");
602MODULE_AUTHOR("Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>"); 602MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index b310702c646..ac35222ad0d 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -1199,4 +1199,4 @@ module_exit(atmel_ac97c_exit);
1199 1199
1200MODULE_LICENSE("GPL"); 1200MODULE_LICENSE("GPL");
1201MODULE_DESCRIPTION("Driver for Atmel AC97 controller"); 1201MODULE_DESCRIPTION("Driver for Atmel AC97 controller");
1202MODULE_AUTHOR("Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>"); 1202MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 2c41825c836..eb9fe2e1d29 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -58,26 +58,6 @@ static const char *sanity_file_name(const char *path)
58 else 58 else
59 return path; 59 return path;
60} 60}
61
62/* print file and line with a certain printk prefix */
63static int print_snd_pfx(unsigned int level, const char *path, int line,
64 const char *format)
65{
66 const char *file = sanity_file_name(path);
67 char tmp[] = "<0>";
68 const char *pfx = level ? KERN_DEBUG : KERN_DEFAULT;
69 int ret = 0;
70
71 if (format[0] == '<' && format[2] == '>') {
72 tmp[1] = format[1];
73 pfx = tmp;
74 ret = 1;
75 }
76 printk("%sALSA %s:%d: ", pfx, file, line);
77 return ret;
78}
79#else
80#define print_snd_pfx(level, path, line, format) 0
81#endif 61#endif
82 62
83#if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK) 63#if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK)
@@ -85,15 +65,29 @@ void __snd_printk(unsigned int level, const char *path, int line,
85 const char *format, ...) 65 const char *format, ...)
86{ 66{
87 va_list args; 67 va_list args;
88 68#ifdef CONFIG_SND_VERBOSE_PRINTK
69 struct va_format vaf;
70 char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV";
71#endif
72
89#ifdef CONFIG_SND_DEBUG 73#ifdef CONFIG_SND_DEBUG
90 if (debug < level) 74 if (debug < level)
91 return; 75 return;
92#endif 76#endif
77
93 va_start(args, format); 78 va_start(args, format);
94 if (print_snd_pfx(level, path, line, format)) 79#ifdef CONFIG_SND_VERBOSE_PRINTK
95 format += 3; /* skip the printk level-prefix */ 80 vaf.fmt = format;
81 vaf.va = &args;
82 if (format[0] == '<' && format[2] == '>') {
83 memcpy(verbose_fmt, format, 3);
84 vaf.fmt = format + 3;
85 } else if (level)
86 memcpy(verbose_fmt, KERN_DEBUG, 3);
87 printk(verbose_fmt, sanity_file_name(path), line, &vaf);
88#else
96 vprintk(format, args); 89 vprintk(format, args);
90#endif
97 va_end(args); 91 va_end(args);
98} 92}
99EXPORT_SYMBOL_GPL(__snd_printk); 93EXPORT_SYMBOL_GPL(__snd_printk);
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 5fb2e28e796..91cdf9435fe 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -342,7 +342,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
342 kfree(bufs); 342 kfree(bufs);
343 return -EFAULT; 343 return -EFAULT;
344 } 344 }
345 bufs[ch] = compat_ptr(ptr); 345 bufs[i] = compat_ptr(ptr);
346 bufptr++; 346 bufptr++;
347 } 347 }
348 if (dir == SNDRV_PCM_STREAM_PLAYBACK) 348 if (dir == SNDRV_PCM_STREAM_PLAYBACK)
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index f1341308bed..86d0caf91b3 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -128,7 +128,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
128 } 128 }
129} 129}
130 130
131static void pcm_debug_name(struct snd_pcm_substream *substream, 131#ifdef CONFIG_SND_DEBUG
132void snd_pcm_debug_name(struct snd_pcm_substream *substream,
132 char *name, size_t len) 133 char *name, size_t len)
133{ 134{
134 snprintf(name, len, "pcmC%dD%d%c:%d", 135 snprintf(name, len, "pcmC%dD%d%c:%d",
@@ -137,6 +138,8 @@ static void pcm_debug_name(struct snd_pcm_substream *substream,
137 substream->stream ? 'c' : 'p', 138 substream->stream ? 'c' : 'p',
138 substream->number); 139 substream->number);
139} 140}
141EXPORT_SYMBOL(snd_pcm_debug_name);
142#endif
140 143
141#define XRUN_DEBUG_BASIC (1<<0) 144#define XRUN_DEBUG_BASIC (1<<0)
142#define XRUN_DEBUG_STACK (1<<1) /* dump also stack */ 145#define XRUN_DEBUG_STACK (1<<1) /* dump also stack */
@@ -168,7 +171,7 @@ static void xrun(struct snd_pcm_substream *substream)
168 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 171 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
169 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { 172 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {
170 char name[16]; 173 char name[16];
171 pcm_debug_name(substream, name, sizeof(name)); 174 snd_pcm_debug_name(substream, name, sizeof(name));
172 snd_printd(KERN_DEBUG "XRUN: %s\n", name); 175 snd_printd(KERN_DEBUG "XRUN: %s\n", name);
173 dump_stack_on_xrun(substream); 176 dump_stack_on_xrun(substream);
174 } 177 }
@@ -243,7 +246,7 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
243 return; 246 return;
244 if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit) 247 if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
245 return; 248 return;
246 pcm_debug_name(substream, name, sizeof(name)); 249 snd_pcm_debug_name(substream, name, sizeof(name));
247 for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) { 250 for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) {
248 entry = &log->entries[idx]; 251 entry = &log->entries[idx];
249 if (entry->period_size == 0) 252 if (entry->period_size == 0)
@@ -319,7 +322,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
319 if (pos >= runtime->buffer_size) { 322 if (pos >= runtime->buffer_size) {
320 if (printk_ratelimit()) { 323 if (printk_ratelimit()) {
321 char name[16]; 324 char name[16];
322 pcm_debug_name(substream, name, sizeof(name)); 325 snd_pcm_debug_name(substream, name, sizeof(name));
323 xrun_log_show(substream); 326 xrun_log_show(substream);
324 snd_printd(KERN_ERR "BUG: %s, pos = %ld, " 327 snd_printd(KERN_ERR "BUG: %s, pos = %ld, "
325 "buffer size = %ld, period size = %ld\n", 328 "buffer size = %ld, period size = %ld\n",
@@ -364,7 +367,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
364 if (xrun_debug(substream, in_interrupt ? 367 if (xrun_debug(substream, in_interrupt ?
365 XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) { 368 XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) {
366 char name[16]; 369 char name[16];
367 pcm_debug_name(substream, name, sizeof(name)); 370 snd_pcm_debug_name(substream, name, sizeof(name));
368 snd_printd("%s_update: %s: pos=%u/%u/%u, " 371 snd_printd("%s_update: %s: pos=%u/%u/%u, "
369 "hwptr=%ld/%ld/%ld/%ld\n", 372 "hwptr=%ld/%ld/%ld/%ld\n",
370 in_interrupt ? "period" : "hwptr", 373 in_interrupt ? "period" : "hwptr",
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index cbbed0db9e5..849a0ed9505 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -92,16 +92,12 @@ static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substre
92 (!substream->append || runtime->avail >= count); 92 (!substream->append || runtime->avail >= count);
93} 93}
94 94
95static void snd_rawmidi_input_event_tasklet(unsigned long data) 95static void snd_rawmidi_input_event_work(struct work_struct *work)
96{ 96{
97 struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data; 97 struct snd_rawmidi_runtime *runtime =
98 substream->runtime->event(substream); 98 container_of(work, struct snd_rawmidi_runtime, event_work);
99} 99 if (runtime->event)
100 100 runtime->event(runtime->substream);
101static void snd_rawmidi_output_trigger_tasklet(unsigned long data)
102{
103 struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
104 substream->ops->trigger(substream, 1);
105} 101}
106 102
107static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) 103static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
@@ -110,16 +106,10 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
110 106
111 if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL) 107 if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
112 return -ENOMEM; 108 return -ENOMEM;
109 runtime->substream = substream;
113 spin_lock_init(&runtime->lock); 110 spin_lock_init(&runtime->lock);
114 init_waitqueue_head(&runtime->sleep); 111 init_waitqueue_head(&runtime->sleep);
115 if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT) 112 INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work);
116 tasklet_init(&runtime->tasklet,
117 snd_rawmidi_input_event_tasklet,
118 (unsigned long)substream);
119 else
120 tasklet_init(&runtime->tasklet,
121 snd_rawmidi_output_trigger_tasklet,
122 (unsigned long)substream);
123 runtime->event = NULL; 113 runtime->event = NULL;
124 runtime->buffer_size = PAGE_SIZE; 114 runtime->buffer_size = PAGE_SIZE;
125 runtime->avail_min = 1; 115 runtime->avail_min = 1;
@@ -150,12 +140,7 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs
150{ 140{
151 if (!substream->opened) 141 if (!substream->opened)
152 return; 142 return;
153 if (up) { 143 substream->ops->trigger(substream, up);
154 tasklet_schedule(&substream->runtime->tasklet);
155 } else {
156 tasklet_kill(&substream->runtime->tasklet);
157 substream->ops->trigger(substream, 0);
158 }
159} 144}
160 145
161static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up) 146static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
@@ -163,8 +148,8 @@ static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, i
163 if (!substream->opened) 148 if (!substream->opened)
164 return; 149 return;
165 substream->ops->trigger(substream, up); 150 substream->ops->trigger(substream, up);
166 if (!up && substream->runtime->event) 151 if (!up)
167 tasklet_kill(&substream->runtime->tasklet); 152 cancel_work_sync(&substream->runtime->event_work);
168} 153}
169 154
170int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream) 155int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
@@ -641,10 +626,10 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
641 return -EINVAL; 626 return -EINVAL;
642 } 627 }
643 if (params->buffer_size != runtime->buffer_size) { 628 if (params->buffer_size != runtime->buffer_size) {
644 newbuf = kmalloc(params->buffer_size, GFP_KERNEL); 629 newbuf = krealloc(runtime->buffer, params->buffer_size,
630 GFP_KERNEL);
645 if (!newbuf) 631 if (!newbuf)
646 return -ENOMEM; 632 return -ENOMEM;
647 kfree(runtime->buffer);
648 runtime->buffer = newbuf; 633 runtime->buffer = newbuf;
649 runtime->buffer_size = params->buffer_size; 634 runtime->buffer_size = params->buffer_size;
650 runtime->avail = runtime->buffer_size; 635 runtime->avail = runtime->buffer_size;
@@ -668,10 +653,10 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
668 return -EINVAL; 653 return -EINVAL;
669 } 654 }
670 if (params->buffer_size != runtime->buffer_size) { 655 if (params->buffer_size != runtime->buffer_size) {
671 newbuf = kmalloc(params->buffer_size, GFP_KERNEL); 656 newbuf = krealloc(runtime->buffer, params->buffer_size,
657 GFP_KERNEL);
672 if (!newbuf) 658 if (!newbuf)
673 return -ENOMEM; 659 return -ENOMEM;
674 kfree(runtime->buffer);
675 runtime->buffer = newbuf; 660 runtime->buffer = newbuf;
676 runtime->buffer_size = params->buffer_size; 661 runtime->buffer_size = params->buffer_size;
677 } 662 }
@@ -926,7 +911,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
926 } 911 }
927 if (result > 0) { 912 if (result > 0) {
928 if (runtime->event) 913 if (runtime->event)
929 tasklet_schedule(&runtime->tasklet); 914 schedule_work(&runtime->event_work);
930 else if (snd_rawmidi_ready(substream)) 915 else if (snd_rawmidi_ready(substream))
931 wake_up(&runtime->sleep); 916 wake_up(&runtime->sleep);
932 } 917 }
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index 0851cd13e30..e85e72baff9 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -22,7 +22,7 @@
22 22
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/moduleparam.h> 25#include <linux/module.h>
26#include <linux/log2.h> 26#include <linux/log2.h>
27#include <sound/core.h> 27#include <sound/core.h>
28#include <sound/timer.h> 28#include <sound/timer.h>
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
index 86ee16ca365..440030818db 100644
--- a/sound/firewire/isight.c
+++ b/sound/firewire/isight.c
@@ -209,6 +209,7 @@ static void isight_packet(struct fw_iso_context *context, u32 cycle,
209 isight->packet_index = -1; 209 isight->packet_index = -1;
210 return; 210 return;
211 } 211 }
212 fw_iso_context_queue_flush(isight->context);
212 213
213 if (++index >= QUEUE_LENGTH) 214 if (++index >= QUEUE_LENGTH)
214 index = 0; 215 index = 0;
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
index 5466de8527b..3fc257da180 100644
--- a/sound/firewire/speakers.c
+++ b/sound/firewire/speakers.c
@@ -171,7 +171,7 @@ static int fwspk_open(struct snd_pcm_substream *substream)
171 171
172 err = snd_pcm_hw_constraint_minmax(runtime, 172 err = snd_pcm_hw_constraint_minmax(runtime,
173 SNDRV_PCM_HW_PARAM_PERIOD_TIME, 173 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
174 5000, 8192000); 174 5000, UINT_MAX);
175 if (err < 0) 175 if (err < 0)
176 return err; 176 return err;
177 177
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index 4d2a6ae978f..8a197fd3c57 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -458,7 +458,7 @@ static int ad1848_set_recmask(ad1848_info * devc, int mask)
458 return mask; 458 return mask;
459} 459}
460 460
461static void change_bits(ad1848_info * devc, unsigned char *regval, 461static void oss_change_bits(ad1848_info *devc, unsigned char *regval,
462 unsigned char *muteval, int dev, int chn, int newval) 462 unsigned char *muteval, int dev, int chn, int newval)
463{ 463{
464 unsigned char mask; 464 unsigned char mask;
@@ -516,10 +516,10 @@ static void ad1848_mixer_set_channel(ad1848_info *devc, int dev, int value, int
516 516
517 if (muteregoffs != regoffs) { 517 if (muteregoffs != regoffs) {
518 muteval = ad_read(devc, muteregoffs); 518 muteval = ad_read(devc, muteregoffs);
519 change_bits(devc, &val, &muteval, dev, channel, value); 519 oss_change_bits(devc, &val, &muteval, dev, channel, value);
520 } 520 }
521 else 521 else
522 change_bits(devc, &val, &val, dev, channel, value); 522 oss_change_bits(devc, &val, &val, dev, channel, value);
523 523
524 spin_lock_irqsave(&devc->lock,flags); 524 spin_lock_irqsave(&devc->lock,flags);
525 ad_write(devc, regoffs, val); 525 ad_write(devc, regoffs, val);
diff --git a/sound/oss/sb_mixer.c b/sound/oss/sb_mixer.c
index 2039d31b7e2..f8f3b7a66b7 100644
--- a/sound/oss/sb_mixer.c
+++ b/sound/oss/sb_mixer.c
@@ -232,7 +232,7 @@ static int detect_mixer(sb_devc * devc)
232 return 1; 232 return 1;
233} 233}
234 234
235static void change_bits(sb_devc * devc, unsigned char *regval, int dev, int chn, int newval) 235static void oss_change_bits(sb_devc *devc, unsigned char *regval, int dev, int chn, int newval)
236{ 236{
237 unsigned char mask; 237 unsigned char mask;
238 int shift; 238 int shift;
@@ -284,7 +284,7 @@ int sb_common_mixer_set(sb_devc * devc, int dev, int left, int right)
284 return -EINVAL; 284 return -EINVAL;
285 285
286 val = sb_getmixer(devc, regoffs); 286 val = sb_getmixer(devc, regoffs);
287 change_bits(devc, &val, dev, LEFT_CHN, left); 287 oss_change_bits(devc, &val, dev, LEFT_CHN, left);
288 288
289 if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs) /* 289 if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs) /*
290 * Change register 290 * Change register
@@ -304,7 +304,7 @@ int sb_common_mixer_set(sb_devc * devc, int dev, int left, int right)
304 * Read the new one 304 * Read the new one
305 */ 305 */
306 } 306 }
307 change_bits(devc, &val, dev, RIGHT_CHN, right); 307 oss_change_bits(devc, &val, dev, RIGHT_CHN, right);
308 308
309 sb_setmixer(devc, regoffs, val); 309 sb_setmixer(devc, regoffs, val);
310 310
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index d8f6fd65ebb..201503673f2 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -944,7 +944,7 @@ snd_ad1889_create(struct snd_card *card,
944 spin_lock_init(&chip->lock); /* only now can we call ad1889_free */ 944 spin_lock_init(&chip->lock); /* only now can we call ad1889_free */
945 945
946 if (request_irq(pci->irq, snd_ad1889_interrupt, 946 if (request_irq(pci->irq, snd_ad1889_interrupt,
947 IRQF_SHARED, card->driver, chip)) { 947 IRQF_SHARED, KBUILD_MODNAME, chip)) {
948 printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq); 948 printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
949 snd_ad1889_free(chip); 949 snd_ad1889_free(chip);
950 return -EBUSY; 950 return -EBUSY;
@@ -1055,7 +1055,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = {
1055MODULE_DEVICE_TABLE(pci, snd_ad1889_ids); 1055MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
1056 1056
1057static struct pci_driver ad1889_pci_driver = { 1057static struct pci_driver ad1889_pci_driver = {
1058 .name = "AD1889 Audio", 1058 .name = KBUILD_MODNAME,
1059 .id_table = snd_ad1889_ids, 1059 .id_table = snd_ad1889_ids,
1060 .probe = snd_ad1889_probe, 1060 .probe = snd_ad1889_probe,
1061 .remove = __devexit_p(snd_ad1889_remove), 1061 .remove = __devexit_p(snd_ad1889_remove),
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 5c6e322a48f..b444b74d9dc 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -2090,7 +2090,7 @@ static int __devinit snd_ali_resources(struct snd_ali *codec)
2090 codec->port = pci_resource_start(codec->pci, 0); 2090 codec->port = pci_resource_start(codec->pci, 0);
2091 2091
2092 if (request_irq(codec->pci->irq, snd_ali_card_interrupt, 2092 if (request_irq(codec->pci->irq, snd_ali_card_interrupt,
2093 IRQF_SHARED, "ALI 5451", codec)) { 2093 IRQF_SHARED, KBUILD_MODNAME, codec)) {
2094 snd_printk(KERN_ERR "Unable to request irq.\n"); 2094 snd_printk(KERN_ERR "Unable to request irq.\n");
2095 return -EBUSY; 2095 return -EBUSY;
2096 } 2096 }
@@ -2295,7 +2295,7 @@ static void __devexit snd_ali_remove(struct pci_dev *pci)
2295} 2295}
2296 2296
2297static struct pci_driver driver = { 2297static struct pci_driver driver = {
2298 .name = "ALI 5451", 2298 .name = KBUILD_MODNAME,
2299 .id_table = snd_ali_ids, 2299 .id_table = snd_ali_ids,
2300 .probe = snd_ali_probe, 2300 .probe = snd_ali_probe,
2301 .remove = __devexit_p(snd_ali_remove), 2301 .remove = __devexit_p(snd_ali_remove),
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index d7653cb7ac6..736c8e93db1 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -722,7 +722,7 @@ static int __devinit snd_als300_create(struct snd_card *card,
722 irq_handler = snd_als300_interrupt; 722 irq_handler = snd_als300_interrupt;
723 723
724 if (request_irq(pci->irq, irq_handler, IRQF_SHARED, 724 if (request_irq(pci->irq, irq_handler, IRQF_SHARED,
725 card->shortname, chip)) { 725 KBUILD_MODNAME, chip)) {
726 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 726 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
727 snd_als300_free(chip); 727 snd_als300_free(chip);
728 return -EBUSY; 728 return -EBUSY;
@@ -846,7 +846,7 @@ static int __devinit snd_als300_probe(struct pci_dev *pci,
846} 846}
847 847
848static struct pci_driver driver = { 848static struct pci_driver driver = {
849 .name = "ALS300", 849 .name = KBUILD_MODNAME,
850 .id_table = snd_als300_ids, 850 .id_table = snd_als300_ids,
851 .probe = snd_als300_probe, 851 .probe = snd_als300_probe,
852 .remove = __devexit_p(snd_als300_remove), 852 .remove = __devexit_p(snd_als300_remove),
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 0e247cb90ec..a9c1af33f27 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -1036,7 +1036,7 @@ static int snd_als4000_resume(struct pci_dev *pci)
1036 1036
1037 1037
1038static struct pci_driver driver = { 1038static struct pci_driver driver = {
1039 .name = "ALS4000", 1039 .name = KBUILD_MODNAME,
1040 .id_table = snd_als4000_ids, 1040 .id_table = snd_als4000_ids,
1041 .probe = snd_card_als4000_probe, 1041 .probe = snd_card_als4000_probe,
1042 .remove = __devexit_p(snd_card_als4000_remove), 1042 .remove = __devexit_p(snd_card_als4000_remove),
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index 2ca6f4f85b4..eae62ebbd29 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -27,7 +27,6 @@
27#include "hpioctl.h" 27#include "hpioctl.h"
28 28
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/version.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/jiffies.h> 31#include <linux/jiffies.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
@@ -42,29 +41,10 @@
42#include <sound/tlv.h> 41#include <sound/tlv.h>
43#include <sound/hwdep.h> 42#include <sound/hwdep.h>
44 43
45
46MODULE_LICENSE("GPL"); 44MODULE_LICENSE("GPL");
47MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); 45MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
48MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); 46MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
49 47
50#if defined CONFIG_SND_DEBUG
51/* copied from pcm_lib.c, hope later patch will make that version public
52and this copy can be removed */
53static void pcm_debug_name(struct snd_pcm_substream *substream,
54 char *name, size_t len)
55{
56 snprintf(name, len, "pcmC%dD%d%c:%d",
57 substream->pcm->card->number,
58 substream->pcm->device,
59 substream->stream ? 'c' : 'p',
60 substream->number);
61}
62#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name))
63#else
64#define pcm_debug_name(s, n, l) do { } while (0)
65#define DEBUG_NAME(name, substream) do { } while (0)
66#endif
67
68#if defined CONFIG_SND_DEBUG_VERBOSE 48#if defined CONFIG_SND_DEBUG_VERBOSE
69/** 49/**
70 * snd_printddd - very verbose debug printk 50 * snd_printddd - very verbose debug printk
@@ -305,7 +285,8 @@ static u16 handle_error(u16 err, int line, char *filename)
305static void print_hwparams(struct snd_pcm_substream *substream, 285static void print_hwparams(struct snd_pcm_substream *substream,
306 struct snd_pcm_hw_params *p) 286 struct snd_pcm_hw_params *p)
307{ 287{
308 DEBUG_NAME(substream, name); 288 char name[16];
289 snd_pcm_debug_name(substream, name, sizeof(name));
309 snd_printd("%s HWPARAMS\n", name); 290 snd_printd("%s HWPARAMS\n", name);
310 snd_printd(" samplerate %d Hz\n", params_rate(p)); 291 snd_printd(" samplerate %d Hz\n", params_rate(p));
311 snd_printd(" channels %d\n", params_channels(p)); 292 snd_printd(" channels %d\n", params_channels(p));
@@ -577,8 +558,9 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
577 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); 558 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
578 struct snd_pcm_substream *s; 559 struct snd_pcm_substream *s;
579 u16 e; 560 u16 e;
580 DEBUG_NAME(substream, name); 561 char name[16];
581 562
563 snd_pcm_debug_name(substream, name, sizeof(name));
582 snd_printdd("%s trigger\n", name); 564 snd_printdd("%s trigger\n", name);
583 565
584 switch (cmd) { 566 switch (cmd) {
@@ -742,7 +724,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
742 int loops = 0; 724 int loops = 0;
743 u16 state; 725 u16 state;
744 u32 buffer_size, bytes_avail, samples_played, on_card_bytes; 726 u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
745 DEBUG_NAME(substream, name); 727 char name[16];
728
729 snd_pcm_debug_name(substream, name, sizeof(name));
746 730
747 snd_printdd("%s snd_card_asihpi_timer_function\n", name); 731 snd_printdd("%s snd_card_asihpi_timer_function\n", name);
748 732
@@ -1324,10 +1308,12 @@ static const char * const asihpi_src_names[] = {
1324 "RF", 1308 "RF",
1325 "Clock", 1309 "Clock",
1326 "Bitstream", 1310 "Bitstream",
1327 "Microphone", 1311 "Mic",
1328 "Cobranet", 1312 "Net",
1329 "Analog", 1313 "Analog",
1330 "Adapter", 1314 "Adapter",
1315 "RTP",
1316 "GPI",
1331}; 1317};
1332 1318
1333compile_time_assert( 1319compile_time_assert(
@@ -1342,8 +1328,10 @@ static const char * const asihpi_dst_names[] = {
1342 "Digital", 1328 "Digital",
1343 "RF", 1329 "RF",
1344 "Speaker", 1330 "Speaker",
1345 "Cobranet Out", 1331 "Net",
1346 "Analog" 1332 "Analog",
1333 "RTP",
1334 "GPO",
1347}; 1335};
1348 1336
1349compile_time_assert( 1337compile_time_assert(
@@ -1477,11 +1465,40 @@ static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1477 1465
1478static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0); 1466static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1479 1467
1468#define snd_asihpi_volume_mute_info snd_ctl_boolean_mono_info
1469
1470static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
1471 struct snd_ctl_elem_value *ucontrol)
1472{
1473 u32 h_control = kcontrol->private_value;
1474 u32 mute;
1475
1476 hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
1477 ucontrol->value.integer.value[0] = mute ? 0 : 1;
1478
1479 return 0;
1480}
1481
1482static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
1483 struct snd_ctl_elem_value *ucontrol)
1484{
1485 u32 h_control = kcontrol->private_value;
1486 int change = 1;
1487 /* HPI currently only supports all or none muting of multichannel volume
1488 ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
1489 */
1490 int mute = ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
1491 hpi_handle_error(hpi_volume_set_mute(h_control, mute));
1492 return change;
1493}
1494
1480static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi, 1495static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1481 struct hpi_control *hpi_ctl) 1496 struct hpi_control *hpi_ctl)
1482{ 1497{
1483 struct snd_card *card = asihpi->card; 1498 struct snd_card *card = asihpi->card;
1484 struct snd_kcontrol_new snd_control; 1499 struct snd_kcontrol_new snd_control;
1500 int err;
1501 u32 mute;
1485 1502
1486 asihpi_ctl_init(&snd_control, hpi_ctl, "Volume"); 1503 asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
1487 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1504 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1491,7 +1508,19 @@ static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1491 snd_control.put = snd_asihpi_volume_put; 1508 snd_control.put = snd_asihpi_volume_put;
1492 snd_control.tlv.p = db_scale_100; 1509 snd_control.tlv.p = db_scale_100;
1493 1510
1494 return ctl_add(card, &snd_control, asihpi); 1511 err = ctl_add(card, &snd_control, asihpi);
1512 if (err)
1513 return err;
1514
1515 if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
1516 asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
1517 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1518 snd_control.info = snd_asihpi_volume_mute_info;
1519 snd_control.get = snd_asihpi_volume_mute_get;
1520 snd_control.put = snd_asihpi_volume_mute_put;
1521 err = ctl_add(card, &snd_control, asihpi);
1522 }
1523 return err;
1495} 1524}
1496 1525
1497/*------------------------------------------------------------ 1526/*------------------------------------------------------------
@@ -2924,7 +2953,7 @@ static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
2924MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl); 2953MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2925 2954
2926static struct pci_driver driver = { 2955static struct pci_driver driver = {
2927 .name = "asihpi", 2956 .name = KBUILD_MODNAME,
2928 .id_table = asihpi_pci_tbl, 2957 .id_table = asihpi_pci_tbl,
2929 .probe = snd_asihpi_probe, 2958 .probe = snd_asihpi_probe,
2930 .remove = __devexit_p(snd_asihpi_remove), 2959 .remove = __devexit_p(snd_asihpi_remove),
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h
index 255429c32c1..f2072728899 100644
--- a/sound/pci/asihpi/hpi.h
+++ b/sound/pci/asihpi/hpi.h
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
@@ -42,12 +42,11 @@ i.e 3.05.02 is a development version
42#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF)) 42#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
43#define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) 43#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
44 44
45/* Use single digits for versions less that 10 to avoid octal. */ 45#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 8, 0)
46#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 6, 0) 46#define HPI_VER_STRING "4.08.00"
47#define HPI_VER_STRING "4.06.00"
48 47
49/* Library version as documented in hpi-api-versions.txt */ 48/* Library version as documented in hpi-api-versions.txt */
50#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0) 49#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 0, 0)
51 50
52#include <linux/types.h> 51#include <linux/types.h>
53#define HPI_BUILD_EXCLUDE_DEPRECATED 52#define HPI_BUILD_EXCLUDE_DEPRECATED
@@ -211,8 +210,12 @@ enum HPI_SOURCENODES {
211 HPI_SOURCENODE_COBRANET = 109, 210 HPI_SOURCENODE_COBRANET = 109,
212 HPI_SOURCENODE_ANALOG = 110, /**< analog input node. */ 211 HPI_SOURCENODE_ANALOG = 110, /**< analog input node. */
213 HPI_SOURCENODE_ADAPTER = 111, /**< adapter node. */ 212 HPI_SOURCENODE_ADAPTER = 111, /**< adapter node. */
213 /** RTP stream input node - This node is a destination for
214 packets of RTP audio samples from other devices. */
215 HPI_SOURCENODE_RTP_DESTINATION = 112,
216 HPI_SOURCENODE_GP_IN = 113, /**< general purpose input. */
214 /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */ 217 /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */
215 HPI_SOURCENODE_LAST_INDEX = 111 /**< largest ID */ 218 HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */
216 /* AX6 max sourcenode types = 15 */ 219 /* AX6 max sourcenode types = 15 */
217}; 220};
218 221
@@ -228,7 +231,7 @@ enum HPI_DESTNODES {
228 HPI_DESTNODE_NONE = 200, 231 HPI_DESTNODE_NONE = 200,
229 /** In Stream (Record) node. */ 232 /** In Stream (Record) node. */
230 HPI_DESTNODE_ISTREAM = 201, 233 HPI_DESTNODE_ISTREAM = 201,
231 HPI_DESTNODE_LINEOUT = 202, /**< line out node. */ 234 HPI_DESTNODE_LINEOUT = 202, /**< line out node. */
232 HPI_DESTNODE_AESEBU_OUT = 203, /**< AES/EBU output node. */ 235 HPI_DESTNODE_AESEBU_OUT = 203, /**< AES/EBU output node. */
233 HPI_DESTNODE_RF = 204, /**< RF output node. */ 236 HPI_DESTNODE_RF = 204, /**< RF output node. */
234 HPI_DESTNODE_SPEAKER = 205, /**< speaker output node. */ 237 HPI_DESTNODE_SPEAKER = 205, /**< speaker output node. */
@@ -236,9 +239,12 @@ enum HPI_DESTNODES {
236 Audio samples from the device are sent out on the Cobranet network.*/ 239 Audio samples from the device are sent out on the Cobranet network.*/
237 HPI_DESTNODE_COBRANET = 206, 240 HPI_DESTNODE_COBRANET = 206,
238 HPI_DESTNODE_ANALOG = 207, /**< analog output node. */ 241 HPI_DESTNODE_ANALOG = 207, /**< analog output node. */
239 242 /** RTP stream output node - This node is a source for
243 packets of RTP audio samples that are sent to other devices. */
244 HPI_DESTNODE_RTP_SOURCE = 208,
245 HPI_DESTNODE_GP_OUT = 209, /**< general purpose output node. */
240 /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */ 246 /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
241 HPI_DESTNODE_LAST_INDEX = 207 /**< largest ID */ 247 HPI_DESTNODE_LAST_INDEX = 209 /**< largest ID */
242 /* AX6 max destnode types = 15 */ 248 /* AX6 max destnode types = 15 */
243}; 249};
244 250
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index df4aed5295d..3cc6f11c20a 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -359,7 +359,7 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
359 HPI_ERROR_PROCESSING_MESSAGE); 359 HPI_ERROR_PROCESSING_MESSAGE);
360 360
361 switch (phm->type) { 361 switch (phm->type) {
362 case HPI_TYPE_MESSAGE: 362 case HPI_TYPE_REQUEST:
363 switch (phm->object) { 363 switch (phm->object) {
364 case HPI_OBJ_SUBSYSTEM: 364 case HPI_OBJ_SUBSYSTEM:
365 subsys_message(phm, phr); 365 subsys_message(phm, phr);
@@ -538,7 +538,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
538 538
539 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); 539 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
540 memset(&hm, 0, sizeof(hm)); 540 memset(&hm, 0, sizeof(hm));
541 hm.type = HPI_TYPE_MESSAGE; 541 hm.type = HPI_TYPE_REQUEST;
542 hm.size = sizeof(struct hpi_message); 542 hm.size = sizeof(struct hpi_message);
543 hm.object = HPI_OBJ_ADAPTER; 543 hm.object = HPI_OBJ_ADAPTER;
544 hm.function = HPI_ADAPTER_GET_INFO; 544 hm.function = HPI_ADAPTER_GET_INFO;
@@ -946,11 +946,8 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
946 } 946 }
947 947
948 /* write the DSP code down into the DSPs memory */ 948 /* write the DSP code down into the DSPs memory */
949 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ 949 error = hpi_dsp_code_open(boot_load_family, pao->pci.pci_dev,
950 dsp_code.ps_dev = pao->pci.pci_dev; 950 &dsp_code, pos_error_code);
951
952 error = hpi_dsp_code_open(boot_load_family, &dsp_code,
953 pos_error_code);
954 951
955 if (error) 952 if (error)
956 return error; 953 return error;
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index 9d5df54a6b4..e041a6ae1c5 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -373,6 +373,7 @@ static void instream_message(struct hpi_adapter_obj *pao,
373/** Entry point to this HPI backend 373/** Entry point to this HPI backend
374 * All calls to the HPI start here 374 * All calls to the HPI start here
375 */ 375 */
376static
376void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm, 377void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
377 struct hpi_response *phr) 378 struct hpi_response *phr)
378{ 379{
@@ -392,7 +393,7 @@ void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
392 393
393 HPI_DEBUG_LOG(VERBOSE, "start of switch\n"); 394 HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
394 switch (phm->type) { 395 switch (phm->type) {
395 case HPI_TYPE_MESSAGE: 396 case HPI_TYPE_REQUEST:
396 switch (phm->object) { 397 switch (phm->object) {
397 case HPI_OBJ_SUBSYSTEM: 398 case HPI_OBJ_SUBSYSTEM:
398 subsys_message(pao, phm, phr); 399 subsys_message(pao, phm, phr);
@@ -402,7 +403,6 @@ void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
402 adapter_message(pao, phm, phr); 403 adapter_message(pao, phm, phr);
403 break; 404 break;
404 405
405 case HPI_OBJ_CONTROLEX:
406 case HPI_OBJ_CONTROL: 406 case HPI_OBJ_CONTROL:
407 control_message(pao, phm, phr); 407 control_message(pao, phm, phr);
408 break; 408 break;
@@ -634,11 +634,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
634 634
635 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n"); 635 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
636 memset(&hm, 0, sizeof(hm)); 636 memset(&hm, 0, sizeof(hm));
637 hm.type = HPI_TYPE_MESSAGE; 637 /* wAdapterIndex == version == 0 */
638 hm.type = HPI_TYPE_REQUEST;
638 hm.size = sizeof(hm); 639 hm.size = sizeof(hm);
639 hm.object = HPI_OBJ_ADAPTER; 640 hm.object = HPI_OBJ_ADAPTER;
640 hm.function = HPI_ADAPTER_GET_INFO; 641 hm.function = HPI_ADAPTER_GET_INFO;
641 hm.adapter_index = 0; 642
642 memset(&hr, 0, sizeof(hr)); 643 memset(&hr, 0, sizeof(hr));
643 hr.size = sizeof(hr); 644 hr.size = sizeof(hr);
644 645
@@ -658,9 +659,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
658 hr.u.ax.info.num_outstreams + 659 hr.u.ax.info.num_outstreams +
659 hr.u.ax.info.num_instreams; 660 hr.u.ax.info.num_instreams;
660 661
661 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
662 65536, pao->pci.pci_dev);
663
664 HPI_DEBUG_LOG(VERBOSE, 662 HPI_DEBUG_LOG(VERBOSE,
665 "got adapter info type %x index %d serial %d\n", 663 "got adapter info type %x index %d serial %d\n",
666 hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index, 664 hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
@@ -709,9 +707,6 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao)
709 [i]); 707 [i]);
710 phw->outstream_host_buffer_size[i] = 0; 708 phw->outstream_host_buffer_size[i] = 0;
711 } 709 }
712
713 hpios_locked_mem_unprepare(pao->pci.pci_dev);
714
715 kfree(phw); 710 kfree(phw);
716} 711}
717 712
@@ -1371,9 +1366,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1371 return err; 1366 return err;
1372 1367
1373 /* write the DSP code down into the DSPs memory */ 1368 /* write the DSP code down into the DSPs memory */
1374 dsp_code.ps_dev = pao->pci.pci_dev; 1369 err = hpi_dsp_code_open(boot_code_id[dsp], pao->pci.pci_dev,
1375 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code, 1370 &dsp_code, pos_error_code);
1376 pos_error_code);
1377 if (err) 1371 if (err)
1378 return err; 1372 return err;
1379 1373
@@ -2084,13 +2078,13 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2084 u16 err = 0; 2078 u16 err = 0;
2085 2079
2086 message_count++; 2080 message_count++;
2087 if (phm->size > sizeof(interface->u)) { 2081 if (phm->size > sizeof(interface->u.message_buffer)) {
2088 phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL; 2082 phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
2089 phr->specific_error = sizeof(interface->u); 2083 phr->specific_error = sizeof(interface->u.message_buffer);
2090 phr->size = sizeof(struct hpi_response_header); 2084 phr->size = sizeof(struct hpi_response_header);
2091 HPI_DEBUG_LOG(ERROR, 2085 HPI_DEBUG_LOG(ERROR,
2092 "message len %d too big for buffer %zd \n", phm->size, 2086 "message len %d too big for buffer %zd \n", phm->size,
2093 sizeof(interface->u)); 2087 sizeof(interface->u.message_buffer));
2094 return 0; 2088 return 0;
2095 } 2089 }
2096 2090
@@ -2122,18 +2116,19 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2122 2116
2123 /* read the result */ 2117 /* read the result */
2124 if (time_out) { 2118 if (time_out) {
2125 if (interface->u.response_buffer.size <= phr->size) 2119 if (interface->u.response_buffer.response.size <= phr->size)
2126 memcpy(phr, &interface->u.response_buffer, 2120 memcpy(phr, &interface->u.response_buffer,
2127 interface->u.response_buffer.size); 2121 interface->u.response_buffer.response.size);
2128 else { 2122 else {
2129 HPI_DEBUG_LOG(ERROR, 2123 HPI_DEBUG_LOG(ERROR,
2130 "response len %d too big for buffer %d\n", 2124 "response len %d too big for buffer %d\n",
2131 interface->u.response_buffer.size, phr->size); 2125 interface->u.response_buffer.response.size,
2126 phr->size);
2132 memcpy(phr, &interface->u.response_buffer, 2127 memcpy(phr, &interface->u.response_buffer,
2133 sizeof(struct hpi_response_header)); 2128 sizeof(struct hpi_response_header));
2134 phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL; 2129 phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
2135 phr->specific_error = 2130 phr->specific_error =
2136 interface->u.response_buffer.size; 2131 interface->u.response_buffer.response.size;
2137 phr->size = sizeof(struct hpi_response_header); 2132 phr->size = sizeof(struct hpi_response_header);
2138 } 2133 }
2139 } 2134 }
@@ -2202,23 +2197,6 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2202 phm->u.d.u.data.data_size, H620_HIF_GET_DATA); 2197 phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
2203 break; 2198 break;
2204 2199
2205 case HPI_CONTROL_SET_STATE:
2206 if (phm->object == HPI_OBJ_CONTROLEX
2207 && phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
2208 err = hpi6205_transfer_data(pao,
2209 phm->u.cx.u.cobranet_bigdata.pb_data,
2210 phm->u.cx.u.cobranet_bigdata.byte_count,
2211 H620_HIF_SEND_DATA);
2212 break;
2213
2214 case HPI_CONTROL_GET_STATE:
2215 if (phm->object == HPI_OBJ_CONTROLEX
2216 && phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
2217 err = hpi6205_transfer_data(pao,
2218 phm->u.cx.u.cobranet_bigdata.pb_data,
2219 phr->u.cx.u.cobranet_data.byte_count,
2220 H620_HIF_GET_DATA);
2221 break;
2222 } 2200 }
2223 phr->error = err; 2201 phr->error = err;
2224 2202
diff --git a/sound/pci/asihpi/hpi6205.h b/sound/pci/asihpi/hpi6205.h
index df2f02c0c7b..ec0827b633a 100644
--- a/sound/pci/asihpi/hpi6205.h
+++ b/sound/pci/asihpi/hpi6205.h
@@ -1,7 +1,7 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
@@ -70,15 +70,28 @@ The Host located memory buffer that the 6205 will bus master
70in and out of. 70in and out of.
71************************************************************/ 71************************************************************/
72#define HPI6205_SIZEOF_DATA (16*1024) 72#define HPI6205_SIZEOF_DATA (16*1024)
73
74struct message_buffer_6205 {
75 struct hpi_message message;
76 char data[256];
77};
78
79struct response_buffer_6205 {
80 struct hpi_response response;
81 char data[256];
82};
83
84union buffer_6205 {
85 struct message_buffer_6205 message_buffer;
86 struct response_buffer_6205 response_buffer;
87 u8 b_data[HPI6205_SIZEOF_DATA];
88};
89
73struct bus_master_interface { 90struct bus_master_interface {
74 u32 host_cmd; 91 u32 host_cmd;
75 u32 dsp_ack; 92 u32 dsp_ack;
76 u32 transfer_size_in_bytes; 93 u32 transfer_size_in_bytes;
77 union { 94 union buffer_6205 u;
78 struct hpi_message_header message_buffer;
79 struct hpi_response_header response_buffer;
80 u8 b_data[HPI6205_SIZEOF_DATA];
81 } u;
82 struct controlcache_6205 control_cache; 95 struct controlcache_6205 control_cache;
83 struct async_event_buffer_6205 async_buffer; 96 struct async_event_buffer_6205 async_buffer;
84 struct hpi_hostbuffer_status 97 struct hpi_hostbuffer_status
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index bf5eced76ba..d497030c160 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
@@ -32,12 +32,6 @@ HPI internal definitions
32#include "hpios.h" 32#include "hpios.h"
33 33
34/* physical memory allocation */ 34/* physical memory allocation */
35void hpios_locked_mem_init(void
36 );
37void hpios_locked_mem_free_all(void
38 );
39#define hpios_locked_mem_prepare(a, b, c, d);
40#define hpios_locked_mem_unprepare(a)
41 35
42/** Allocate and map an area of locked memory for bus master DMA operations. 36/** Allocate and map an area of locked memory for bus master DMA operations.
43 37
@@ -226,8 +220,8 @@ enum HPI_CONTROL_ATTRIBUTES {
226 220
227 HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1), 221 HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1),
228 HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2), 222 HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2),
229 HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3), 223 /*HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3), */
230 HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4), 224 /*HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4), */
231 HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5), 225 HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5),
232 HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6), 226 HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6),
233 HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7), 227 HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7),
@@ -364,10 +358,12 @@ Used in DLL to indicate device not present
364#define HPI_ADAPTER_ASI(f) (f) 358#define HPI_ADAPTER_ASI(f) (f)
365 359
366enum HPI_MESSAGE_TYPES { 360enum HPI_MESSAGE_TYPES {
367 HPI_TYPE_MESSAGE = 1, 361 HPI_TYPE_REQUEST = 1,
368 HPI_TYPE_RESPONSE = 2, 362 HPI_TYPE_RESPONSE = 2,
369 HPI_TYPE_DATA = 3, 363 HPI_TYPE_DATA = 3,
370 HPI_TYPE_SSX2BYPASS_MESSAGE = 4 364 HPI_TYPE_SSX2BYPASS_MESSAGE = 4,
365 HPI_TYPE_COMMAND = 5,
366 HPI_TYPE_NOTIFICATION = 6
371}; 367};
372 368
373enum HPI_OBJECT_TYPES { 369enum HPI_OBJECT_TYPES {
@@ -383,7 +379,7 @@ enum HPI_OBJECT_TYPES {
383 HPI_OBJ_WATCHDOG = 10, 379 HPI_OBJ_WATCHDOG = 10,
384 HPI_OBJ_CLOCK = 11, 380 HPI_OBJ_CLOCK = 11,
385 HPI_OBJ_PROFILE = 12, 381 HPI_OBJ_PROFILE = 12,
386 HPI_OBJ_CONTROLEX = 13, 382 /* HPI_ OBJ_ CONTROLEX = 13, */
387 HPI_OBJ_ASYNCEVENT = 14 383 HPI_OBJ_ASYNCEVENT = 14
388#define HPI_OBJ_MAXINDEX 14 384#define HPI_OBJ_MAXINDEX 14
389}; 385};
@@ -608,7 +604,7 @@ struct hpi_data_compat32 {
608#endif 604#endif
609 605
610struct hpi_buffer { 606struct hpi_buffer {
611 /** placehoder for backward compatibility (see dwBufferSize) */ 607 /** placeholder for backward compatibility (see dwBufferSize) */
612 struct hpi_msg_format reserved; 608 struct hpi_msg_format reserved;
613 u32 command; /**< HPI_BUFFER_CMD_xxx*/ 609 u32 command; /**< HPI_BUFFER_CMD_xxx*/
614 u32 pci_address; /**< PCI physical address of buffer for DSP DMA */ 610 u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
@@ -912,95 +908,13 @@ union hpi_control_union_res {
912 u32 remaining_chars; 908 u32 remaining_chars;
913 } chars8; 909 } chars8;
914 char c_data12[12]; 910 char c_data12[12];
915};
916
917/* HPI_CONTROLX_STRUCTURES */
918
919/* Message */
920
921/** Used for all HMI variables where max length <= 8 bytes
922*/
923struct hpi_controlx_msg_cobranet_data {
924 u32 hmi_address;
925 u32 byte_count;
926 u32 data[2];
927};
928
929/** Used for string data, and for packet bridge
930*/
931struct hpi_controlx_msg_cobranet_bigdata {
932 u32 hmi_address;
933 u32 byte_count;
934 u8 *pb_data;
935#ifndef HPI64BIT
936 u32 padding;
937#endif
938};
939
940/** Used for PADS control reading of string fields.
941*/
942struct hpi_controlx_msg_pad_data {
943 u32 field;
944 u32 byte_count;
945 u8 *pb_data;
946#ifndef HPI64BIT
947 u32 padding;
948#endif
949};
950
951/** Used for generic data
952*/
953
954struct hpi_controlx_msg_generic {
955 u32 param1;
956 u32 param2;
957};
958
959struct hpi_controlx_msg {
960 u16 attribute; /* control attribute or property */
961 u16 saved_index;
962 union {
963 struct hpi_controlx_msg_cobranet_data cobranet_data;
964 struct hpi_controlx_msg_cobranet_bigdata cobranet_bigdata;
965 struct hpi_controlx_msg_generic generic;
966 struct hpi_controlx_msg_pad_data pad_data;
967 /*struct param_value universal_value; */
968 /* nothing extra to send for status read */
969 } u;
970};
971
972/* Response */
973/**
974*/
975struct hpi_controlx_res_cobranet_data {
976 u32 byte_count;
977 u32 data[2];
978};
979
980struct hpi_controlx_res_cobranet_bigdata {
981 u32 byte_count;
982};
983
984struct hpi_controlx_res_cobranet_status {
985 u32 status;
986 u32 readable_size;
987 u32 writeable_size;
988};
989
990struct hpi_controlx_res_generic {
991 u32 param1;
992 u32 param2;
993};
994
995struct hpi_controlx_res {
996 union { 911 union {
997 struct hpi_controlx_res_cobranet_bigdata cobranet_bigdata; 912 struct {
998 struct hpi_controlx_res_cobranet_data cobranet_data; 913 u32 status;
999 struct hpi_controlx_res_cobranet_status cobranet_status; 914 u32 readable_size;
1000 struct hpi_controlx_res_generic generic; 915 u32 writeable_size;
1001 /*struct param_info universal_info; */ 916 } status;
1002 /*struct param_value universal_value; */ 917 } cobranet;
1003 } u;
1004}; 918};
1005 919
1006struct hpi_nvmemory_msg { 920struct hpi_nvmemory_msg {
@@ -1126,7 +1040,6 @@ struct hpi_message {
1126 /* identical to struct hpi_control_msg, 1040 /* identical to struct hpi_control_msg,
1127 but field naming is improved */ 1041 but field naming is improved */
1128 struct hpi_control_union_msg cu; 1042 struct hpi_control_union_msg cu;
1129 struct hpi_controlx_msg cx; /* extended mixer control; */
1130 struct hpi_nvmemory_msg n; 1043 struct hpi_nvmemory_msg n;
1131 struct hpi_gpio_msg l; /* digital i/o */ 1044 struct hpi_gpio_msg l; /* digital i/o */
1132 struct hpi_watchdog_msg w; 1045 struct hpi_watchdog_msg w;
@@ -1151,7 +1064,7 @@ struct hpi_message {
1151 sizeof(struct hpi_message_header) + sizeof(struct hpi_watchdog_msg),\ 1064 sizeof(struct hpi_message_header) + sizeof(struct hpi_watchdog_msg),\
1152 sizeof(struct hpi_message_header) + sizeof(struct hpi_clock_msg),\ 1065 sizeof(struct hpi_message_header) + sizeof(struct hpi_clock_msg),\
1153 sizeof(struct hpi_message_header) + sizeof(struct hpi_profile_msg),\ 1066 sizeof(struct hpi_message_header) + sizeof(struct hpi_profile_msg),\
1154 sizeof(struct hpi_message_header) + sizeof(struct hpi_controlx_msg),\ 1067 sizeof(struct hpi_message_header), /* controlx obj removed */ \
1155 sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \ 1068 sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \
1156} 1069}
1157 1070
@@ -1188,7 +1101,6 @@ struct hpi_response {
1188 struct hpi_control_res c; /* mixer control; */ 1101 struct hpi_control_res c; /* mixer control; */
1189 /* identical to hpi_control_res, but field naming is improved */ 1102 /* identical to hpi_control_res, but field naming is improved */
1190 union hpi_control_union_res cu; 1103 union hpi_control_union_res cu;
1191 struct hpi_controlx_res cx; /* extended mixer control; */
1192 struct hpi_nvmemory_res n; 1104 struct hpi_nvmemory_res n;
1193 struct hpi_gpio_res l; /* digital i/o */ 1105 struct hpi_gpio_res l; /* digital i/o */
1194 struct hpi_watchdog_res w; 1106 struct hpi_watchdog_res w;
@@ -1213,7 +1125,7 @@ struct hpi_response {
1213 sizeof(struct hpi_response_header) + sizeof(struct hpi_watchdog_res),\ 1125 sizeof(struct hpi_response_header) + sizeof(struct hpi_watchdog_res),\
1214 sizeof(struct hpi_response_header) + sizeof(struct hpi_clock_res),\ 1126 sizeof(struct hpi_response_header) + sizeof(struct hpi_clock_res),\
1215 sizeof(struct hpi_response_header) + sizeof(struct hpi_profile_res),\ 1127 sizeof(struct hpi_response_header) + sizeof(struct hpi_profile_res),\
1216 sizeof(struct hpi_response_header) + sizeof(struct hpi_controlx_res),\ 1128 sizeof(struct hpi_response_header), /* controlx obj removed */ \
1217 sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \ 1129 sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \
1218} 1130}
1219 1131
@@ -1308,6 +1220,30 @@ struct hpi_res_adapter_debug_read {
1308 u8 bytes[256]; 1220 u8 bytes[256];
1309}; 1221};
1310 1222
1223struct hpi_msg_cobranet_hmi {
1224 u16 attribute;
1225 u16 padding;
1226 u32 hmi_address;
1227 u32 byte_count;
1228};
1229
1230struct hpi_msg_cobranet_hmiwrite {
1231 struct hpi_message_header h;
1232 struct hpi_msg_cobranet_hmi p;
1233 u8 bytes[256];
1234};
1235
1236struct hpi_msg_cobranet_hmiread {
1237 struct hpi_message_header h;
1238 struct hpi_msg_cobranet_hmi p;
1239};
1240
1241struct hpi_res_cobranet_hmiread {
1242 struct hpi_response_header h;
1243 u32 byte_count;
1244 u8 bytes[256];
1245};
1246
1311#if 1 1247#if 1
1312#define hpi_message_header_v1 hpi_message_header 1248#define hpi_message_header_v1 hpi_message_header
1313#define hpi_response_header_v1 hpi_response_header 1249#define hpi_response_header_v1 hpi_response_header
@@ -1338,7 +1274,6 @@ struct hpi_msg_payload_v0 {
1338 union hpi_mixerx_msg mx; 1274 union hpi_mixerx_msg mx;
1339 struct hpi_control_msg c; 1275 struct hpi_control_msg c;
1340 struct hpi_control_union_msg cu; 1276 struct hpi_control_union_msg cu;
1341 struct hpi_controlx_msg cx;
1342 struct hpi_nvmemory_msg n; 1277 struct hpi_nvmemory_msg n;
1343 struct hpi_gpio_msg l; 1278 struct hpi_gpio_msg l;
1344 struct hpi_watchdog_msg w; 1279 struct hpi_watchdog_msg w;
@@ -1358,7 +1293,6 @@ struct hpi_res_payload_v0 {
1358 union hpi_mixerx_res mx; 1293 union hpi_mixerx_res mx;
1359 struct hpi_control_res c; 1294 struct hpi_control_res c;
1360 union hpi_control_union_res cu; 1295 union hpi_control_union_res cu;
1361 struct hpi_controlx_res cx;
1362 struct hpi_nvmemory_res n; 1296 struct hpi_nvmemory_res n;
1363 struct hpi_gpio_res l; 1297 struct hpi_gpio_res l;
1364 struct hpi_watchdog_res w; 1298 struct hpi_watchdog_res w;
@@ -1493,12 +1427,6 @@ struct hpi_control_cache_microphone {
1493 char temp_padding[6]; 1427 char temp_padding[6];
1494}; 1428};
1495 1429
1496struct hpi_control_cache_generic {
1497 struct hpi_control_cache_info i;
1498 u32 dw1;
1499 u32 dw2;
1500};
1501
1502struct hpi_control_cache_single { 1430struct hpi_control_cache_single {
1503 union { 1431 union {
1504 struct hpi_control_cache_info i; 1432 struct hpi_control_cache_info i;
@@ -1514,7 +1442,6 @@ struct hpi_control_cache_single {
1514 struct hpi_control_cache_silencedetector silence; 1442 struct hpi_control_cache_silencedetector silence;
1515 struct hpi_control_cache_sampleclock clk; 1443 struct hpi_control_cache_sampleclock clk;
1516 struct hpi_control_cache_microphone microphone; 1444 struct hpi_control_cache_microphone microphone;
1517 struct hpi_control_cache_generic generic;
1518 } u; 1445 } u;
1519}; 1446};
1520 1447
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index b15a02e91f8..65b7ca13115 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -57,7 +57,7 @@ u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
57 } 57 }
58 58
59 if (phr->function != phm->function) { 59 if (phr->function != phm->function) {
60 HPI_DEBUG_LOG(ERROR, "header type %d invalid\n", 60 HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
61 phr->function); 61 phr->function);
62 return HPI_ERROR_INVALID_RESPONSE; 62 return HPI_ERROR_INVALID_RESPONSE;
63 } 63 }
@@ -315,8 +315,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
315 short found = 1; 315 short found = 1;
316 struct hpi_control_cache_info *pI; 316 struct hpi_control_cache_info *pI;
317 struct hpi_control_cache_single *pC; 317 struct hpi_control_cache_single *pC;
318 struct hpi_control_cache_pad *p_pad; 318 size_t response_size;
319
320 if (!find_control(phm->obj_index, p_cache, &pI)) { 319 if (!find_control(phm->obj_index, p_cache, &pI)) {
321 HPI_DEBUG_LOG(VERBOSE, 320 HPI_DEBUG_LOG(VERBOSE,
322 "HPICMN find_control() failed for adap %d\n", 321 "HPICMN find_control() failed for adap %d\n",
@@ -326,11 +325,15 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
326 325
327 phr->error = 0; 326 phr->error = 0;
328 327
328 /* set the default response size */
329 response_size =
330 sizeof(struct hpi_response_header) +
331 sizeof(struct hpi_control_res);
332
329 /* pC is the default cached control strucure. May be cast to 333 /* pC is the default cached control strucure. May be cast to
330 something else in the following switch statement. 334 something else in the following switch statement.
331 */ 335 */
332 pC = (struct hpi_control_cache_single *)pI; 336 pC = (struct hpi_control_cache_single *)pI;
333 p_pad = (struct hpi_control_cache_pad *)pI;
334 337
335 switch (pI->control_type) { 338 switch (pI->control_type) {
336 339
@@ -529,9 +532,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
529 pI->control_index, pI->control_type, phm->u.c.attribute); 532 pI->control_index, pI->control_type, phm->u.c.attribute);
530 533
531 if (found) 534 if (found)
532 phr->size = 535 phr->size = (u16)response_size;
533 sizeof(struct hpi_response_header) +
534 sizeof(struct hpi_control_res);
535 536
536 return found; 537 return found;
537} 538}
@@ -682,7 +683,7 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
682void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr) 683void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
683{ 684{
684 switch (phm->type) { 685 switch (phm->type) {
685 case HPI_TYPE_MESSAGE: 686 case HPI_TYPE_REQUEST:
686 switch (phm->object) { 687 switch (phm->object) {
687 case HPI_OBJ_SUBSYSTEM: 688 case HPI_OBJ_SUBSYSTEM:
688 subsys_message(phm, phr); 689 subsys_message(phm, phr);
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
index fb311d8c05b..71d32c868c9 100644
--- a/sound/pci/asihpi/hpidspcd.c
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -1,8 +1,8 @@
1/***********************************************************************/ 1/***********************************************************************/
2/*! 2/**
3 3
4 AudioScience HPI driver 4 AudioScience HPI driver
5 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 5 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
6 6
7 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as 8 it under the terms of version 2 of the GNU General Public License as
@@ -18,90 +18,60 @@
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20\file 20\file
21Functions for reading DSP code to load into DSP 21Functions for reading DSP code using
22
23(Linux only:) If DSPCODE_FIRMWARE_LOADER is defined, code is read using
24hotplug firmware loader from individual dsp code files 22hotplug firmware loader from individual dsp code files
25 23*/
26If neither of the above is defined, code is read from linked arrays.
27DSPCODE_ARRAY is defined.
28
29HPI_INCLUDE_**** must be defined
30and the appropriate hzz?????.c or hex?????.c linked in
31
32 */
33/***********************************************************************/ 24/***********************************************************************/
34#define SOURCEFILE_NAME "hpidspcd.c" 25#define SOURCEFILE_NAME "hpidspcd.c"
35#include "hpidspcd.h" 26#include "hpidspcd.h"
36#include "hpidebug.h" 27#include "hpidebug.h"
37 28
38/** 29struct dsp_code_private {
39 Header structure for binary dsp code file (see asidsp.doc) 30 /** Firmware descriptor */
40 This structure must match that used in s2bin.c for generation of asidsp.bin 31 const struct firmware *firmware;
41 */ 32 struct pci_dev *dev;
42
43#ifndef DISABLE_PRAGMA_PACK1
44#pragma pack(push, 1)
45#endif
46
47struct code_header {
48 u32 size;
49 char type[4];
50 u32 adapter;
51 u32 version;
52 u32 crc;
53}; 33};
54 34
55#ifndef DISABLE_PRAGMA_PACK1
56#pragma pack(pop)
57#endif
58
59#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \ 35#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
60 HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER))) 36 HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
61 37
62/***********************************************************************/
63#include "linux/pci.h"
64/*-------------------------------------------------------------------*/ 38/*-------------------------------------------------------------------*/
65short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code, 39short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
66 u32 *pos_error_code) 40 u32 *os_error_code)
67{ 41{
68 const struct firmware *ps_firmware = ps_dsp_code->ps_firmware; 42 const struct firmware *firmware;
43 struct pci_dev *dev = os_data;
69 struct code_header header; 44 struct code_header header;
70 char fw_name[20]; 45 char fw_name[20];
46 short err_ret = HPI_ERROR_DSP_FILE_NOT_FOUND;
71 int err; 47 int err;
72 48
73 sprintf(fw_name, "asihpi/dsp%04x.bin", adapter); 49 sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
74 50
75 err = request_firmware(&ps_firmware, fw_name, 51 err = request_firmware(&firmware, fw_name, &dev->dev);
76 &ps_dsp_code->ps_dev->dev);
77 52
78 if (err != 0) { 53 if (err || !firmware) {
79 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, 54 dev_printk(KERN_ERR, &dev->dev,
80 "%d, request_firmware failed for %s\n", err, 55 "%d, request_firmware failed for %s\n", err,
81 fw_name); 56 fw_name);
82 goto error1; 57 goto error1;
83 } 58 }
84 if (ps_firmware->size < sizeof(header)) { 59 if (firmware->size < sizeof(header)) {
85 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, 60 dev_printk(KERN_ERR, &dev->dev, "Header size too small %s\n",
86 "Header size too small %s\n", fw_name); 61 fw_name);
87 goto error2;
88 }
89 memcpy(&header, ps_firmware->data, sizeof(header));
90 if (header.adapter != adapter) {
91 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
92 "Adapter type incorrect %4x != %4x\n", header.adapter,
93 adapter);
94 goto error2; 62 goto error2;
95 } 63 }
96 if (header.size != ps_firmware->size) { 64 memcpy(&header, firmware->data, sizeof(header));
97 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, 65
98 "Code size wrong %d != %ld\n", header.size, 66 if ((header.type != 0x45444F43) || /* "CODE" */
99 (unsigned long)ps_firmware->size); 67 (header.adapter != adapter)
68 || (header.size != firmware->size)) {
69 dev_printk(KERN_ERR, &dev->dev, "Invalid firmware file\n");
100 goto error2; 70 goto error2;
101 } 71 }
102 72
103 if (header.version / 100 != HPI_VER_DECIMAL / 100) { 73 if ((header.version / 100 & ~1) != (HPI_VER_DECIMAL / 100 & ~1)) {
104 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, 74 dev_printk(KERN_ERR, &dev->dev,
105 "Incompatible firmware version " 75 "Incompatible firmware version "
106 "DSP image %d != Driver %d\n", header.version, 76 "DSP image %d != Driver %d\n", header.version,
107 HPI_VER_DECIMAL); 77 HPI_VER_DECIMAL);
@@ -109,67 +79,72 @@ short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
109 } 79 }
110 80
111 if (header.version != HPI_VER_DECIMAL) { 81 if (header.version != HPI_VER_DECIMAL) {
112 dev_printk(KERN_WARNING, &ps_dsp_code->ps_dev->dev, 82 dev_printk(KERN_WARNING, &dev->dev,
113 "Firmware: release version mismatch DSP image %d != Driver %d\n", 83 "Firmware: release version mismatch DSP image %d != Driver %d\n",
114 header.version, HPI_VER_DECIMAL); 84 header.version, HPI_VER_DECIMAL);
115 } 85 }
116 86
117 HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name); 87 HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
118 ps_dsp_code->ps_firmware = ps_firmware; 88 dsp_code->pvt = kmalloc(sizeof(*dsp_code->pvt), GFP_KERNEL);
119 ps_dsp_code->block_length = header.size / sizeof(u32); 89 if (!dsp_code->pvt) {
120 ps_dsp_code->word_count = sizeof(header) / sizeof(u32); 90 err_ret = HPI_ERROR_MEMORY_ALLOC;
121 ps_dsp_code->version = header.version; 91 goto error2;
122 ps_dsp_code->crc = header.crc; 92 }
93
94 dsp_code->pvt->dev = dev;
95 dsp_code->pvt->firmware = firmware;
96 dsp_code->header = header;
97 dsp_code->block_length = header.size / sizeof(u32);
98 dsp_code->word_count = sizeof(header) / sizeof(u32);
123 return 0; 99 return 0;
124 100
125error2: 101error2:
126 release_firmware(ps_firmware); 102 release_firmware(firmware);
127error1: 103error1:
128 ps_dsp_code->ps_firmware = NULL; 104 dsp_code->block_length = 0;
129 ps_dsp_code->block_length = 0; 105 return err_ret;
130 return HPI_ERROR_DSP_FILE_NOT_FOUND;
131} 106}
132 107
133/*-------------------------------------------------------------------*/ 108/*-------------------------------------------------------------------*/
134void hpi_dsp_code_close(struct dsp_code *ps_dsp_code) 109void hpi_dsp_code_close(struct dsp_code *dsp_code)
135{ 110{
136 if (ps_dsp_code->ps_firmware != NULL) { 111 if (dsp_code->pvt->firmware) {
137 HPI_DEBUG_LOG(DEBUG, "dsp code closed\n"); 112 HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
138 release_firmware(ps_dsp_code->ps_firmware); 113 release_firmware(dsp_code->pvt->firmware);
139 ps_dsp_code->ps_firmware = NULL; 114 dsp_code->pvt->firmware = NULL;
140 } 115 }
116 kfree(dsp_code->pvt);
141} 117}
142 118
143/*-------------------------------------------------------------------*/ 119/*-------------------------------------------------------------------*/
144void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code) 120void hpi_dsp_code_rewind(struct dsp_code *dsp_code)
145{ 121{
146 /* Go back to start of data, after header */ 122 /* Go back to start of data, after header */
147 ps_dsp_code->word_count = sizeof(struct code_header) / sizeof(u32); 123 dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
148} 124}
149 125
150/*-------------------------------------------------------------------*/ 126/*-------------------------------------------------------------------*/
151short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword) 127short hpi_dsp_code_read_word(struct dsp_code *dsp_code, u32 *pword)
152{ 128{
153 if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length) 129 if (dsp_code->word_count + 1 > dsp_code->block_length)
154 return HPI_ERROR_DSP_FILE_FORMAT; 130 return HPI_ERROR_DSP_FILE_FORMAT;
155 131
156 *pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code-> 132 *pword = ((u32 *)(dsp_code->pvt->firmware->data))[dsp_code->
157 word_count]; 133 word_count];
158 ps_dsp_code->word_count++; 134 dsp_code->word_count++;
159 return 0; 135 return 0;
160} 136}
161 137
162/*-------------------------------------------------------------------*/ 138/*-------------------------------------------------------------------*/
163short hpi_dsp_code_read_block(size_t words_requested, 139short hpi_dsp_code_read_block(size_t words_requested,
164 struct dsp_code *ps_dsp_code, u32 **ppblock) 140 struct dsp_code *dsp_code, u32 **ppblock)
165{ 141{
166 if (ps_dsp_code->word_count + words_requested > 142 if (dsp_code->word_count + words_requested > dsp_code->block_length)
167 ps_dsp_code->block_length)
168 return HPI_ERROR_DSP_FILE_FORMAT; 143 return HPI_ERROR_DSP_FILE_FORMAT;
169 144
170 *ppblock = 145 *ppblock =
171 ((u32 *)(ps_dsp_code->ps_firmware->data)) + 146 ((u32 *)(dsp_code->pvt->firmware->data)) +
172 ps_dsp_code->word_count; 147 dsp_code->word_count;
173 ps_dsp_code->word_count += words_requested; 148 dsp_code->word_count += words_requested;
174 return 0; 149 return 0;
175} 150}
diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h
index 65f0ca73270..b22881122f1 100644
--- a/sound/pci/asihpi/hpidspcd.h
+++ b/sound/pci/asihpi/hpidspcd.h
@@ -2,7 +2,7 @@
2/** 2/**
3 3
4 AudioScience HPI driver 4 AudioScience HPI driver
5 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 5 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
6 6
7 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as 8 it under the terms of version 2 of the GNU General Public License as
@@ -20,19 +20,6 @@
20\file 20\file
21Functions for reading DSP code to load into DSP 21Functions for reading DSP code to load into DSP
22 22
23 hpi_dspcode_defines HPI DSP code loading method
24Define exactly one of these to select how the DSP code is supplied to
25the adapter.
26
27End users writing applications that use the HPI interface do not have to
28use any of the below defines; they are only necessary for building drivers
29
30HPI_DSPCODE_FILE:
31DSP code is supplied as a file that is opened and read from by the driver.
32
33HPI_DSPCODE_FIRMWARE:
34DSP code is read using the hotplug firmware loader module.
35 Only valid when compiling the HPI kernel driver under Linux.
36*/ 23*/
37/***********************************************************************/ 24/***********************************************************************/
38#ifndef _HPIDSPCD_H_ 25#ifndef _HPIDSPCD_H_
@@ -40,37 +27,56 @@ DSP code is read using the hotplug firmware loader module.
40 27
41#include "hpi_internal.h" 28#include "hpi_internal.h"
42 29
43#ifndef DISABLE_PRAGMA_PACK1 30/** Code header version is decimal encoded e.g. 4.06.10 is 40601 */
44#pragma pack(push, 1) 31#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
45#endif 32HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
33
34/** Header structure for dsp firmware file
35 This structure must match that used in s2bin.c for generation of asidsp.bin
36 */
37/*#ifndef DISABLE_PRAGMA_PACK1 */
38/*#pragma pack(push, 1) */
39/*#endif */
40struct code_header {
41 /** Size in bytes including header */
42 u32 size;
43 /** File type tag "CODE" == 0x45444F43 */
44 u32 type;
45 /** Adapter model number */
46 u32 adapter;
47 /** Firmware version*/
48 u32 version;
49 /** Data checksum */
50 u32 checksum;
51};
52/*#ifndef DISABLE_PRAGMA_PACK1 */
53/*#pragma pack(pop) */
54/*#endif */
55
56/*? Don't need the pragmas? */
57compile_time_assert((sizeof(struct code_header) == 20), code_header_size);
46 58
47/** Descriptor for dspcode from firmware loader */ 59/** Descriptor for dspcode from firmware loader */
48struct dsp_code { 60struct dsp_code {
49 /** Firmware descriptor */ 61 /** copy of file header */
50 const struct firmware *ps_firmware; 62 struct code_header header;
51 struct pci_dev *ps_dev;
52 /** Expected number of words in the whole dsp code,INCL header */ 63 /** Expected number of words in the whole dsp code,INCL header */
53 long int block_length; 64 u32 block_length;
54 /** Number of words read so far */ 65 /** Number of words read so far */
55 long int word_count; 66 u32 word_count;
56 /** Version read from dsp code file */
57 u32 version;
58 /** CRC read from dsp code file */
59 u32 crc;
60};
61 67
62#ifndef DISABLE_PRAGMA_PACK1 68 /** internal state of DSP code reader */
63#pragma pack(pop) 69 struct dsp_code_private *pvt;
64#endif 70};
65 71
66/** Prepare *psDspCode to refer to the requuested adapter. 72/** Prepare *psDspCode to refer to the requested adapter's firmware.
67 Searches the file, or selects the appropriate linked array 73Code file name is obtained from HpiOs_GetDspCodePath
68 74
69\return 0 for success, or error code if requested code is not available 75\return 0 for success, or error code if requested code is not available
70*/ 76*/
71short hpi_dsp_code_open( 77short hpi_dsp_code_open(
72 /** Code identifier, usually adapter family */ 78 /** Code identifier, usually adapter family */
73 u32 adapter, 79 u32 adapter, void *pci_dev,
74 /** Pointer to DSP code control structure */ 80 /** Pointer to DSP code control structure */
75 struct dsp_code *ps_dsp_code, 81 struct dsp_code *ps_dsp_code,
76 /** Pointer to dword to receive OS specific error code */ 82 /** Pointer to dword to receive OS specific error code */
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index 7397b169b89..ebb568d695f 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -1663,68 +1663,64 @@ u16 hpi_channel_mode_get(u32 h_control, u16 *mode)
1663u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count, 1663u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count,
1664 u8 *pb_data) 1664 u8 *pb_data)
1665{ 1665{
1666 struct hpi_message hm; 1666 struct hpi_msg_cobranet_hmiwrite hm;
1667 struct hpi_response hr; 1667 struct hpi_response_header hr;
1668 1668
1669 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 1669 hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr, sizeof(hr),
1670 HPI_CONTROL_SET_STATE); 1670 HPI_OBJ_CONTROL, HPI_CONTROL_SET_STATE);
1671 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1672 return HPI_ERROR_INVALID_HANDLE;
1673 1671
1674 hm.u.cx.u.cobranet_data.byte_count = byte_count; 1672 if (hpi_handle_indexes(h_control, &hm.h.adapter_index,
1675 hm.u.cx.u.cobranet_data.hmi_address = hmi_address; 1673 &hm.h.obj_index))
1674 return HPI_ERROR_INVALID_HANDLE;
1676 1675
1677 if (byte_count <= 8) { 1676 if (byte_count > sizeof(hm.bytes))
1678 memcpy(hm.u.cx.u.cobranet_data.data, pb_data, byte_count); 1677 return HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
1679 hm.u.cx.attribute = HPI_COBRANET_SET;
1680 } else {
1681 hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
1682 hm.u.cx.attribute = HPI_COBRANET_SET_DATA;
1683 }
1684 1678
1685 hpi_send_recv(&hm, &hr); 1679 hm.p.attribute = HPI_COBRANET_SET;
1680 hm.p.byte_count = byte_count;
1681 hm.p.hmi_address = hmi_address;
1682 memcpy(hm.bytes, pb_data, byte_count);
1683 hm.h.size = (u16)(sizeof(hm.h) + sizeof(hm.p) + byte_count);
1686 1684
1685 hpi_send_recvV1(&hm.h, &hr);
1687 return hr.error; 1686 return hr.error;
1688} 1687}
1689 1688
1690u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count, 1689u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count,
1691 u32 *pbyte_count, u8 *pb_data) 1690 u32 *pbyte_count, u8 *pb_data)
1692{ 1691{
1693 struct hpi_message hm; 1692 struct hpi_msg_cobranet_hmiread hm;
1694 struct hpi_response hr; 1693 struct hpi_res_cobranet_hmiread hr;
1695 1694
1696 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 1695 hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr.h, sizeof(hr),
1697 HPI_CONTROL_GET_STATE); 1696 HPI_OBJ_CONTROL, HPI_CONTROL_GET_STATE);
1698 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index)) 1697
1698 if (hpi_handle_indexes(h_control, &hm.h.adapter_index,
1699 &hm.h.obj_index))
1699 return HPI_ERROR_INVALID_HANDLE; 1700 return HPI_ERROR_INVALID_HANDLE;
1700 1701
1701 hm.u.cx.u.cobranet_data.byte_count = max_byte_count; 1702 if (max_byte_count > sizeof(hr.bytes))
1702 hm.u.cx.u.cobranet_data.hmi_address = hmi_address; 1703 return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
1703 1704
1704 if (max_byte_count <= 8) { 1705 hm.p.attribute = HPI_COBRANET_GET;
1705 hm.u.cx.attribute = HPI_COBRANET_GET; 1706 hm.p.byte_count = max_byte_count;
1706 } else { 1707 hm.p.hmi_address = hmi_address;
1707 hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
1708 hm.u.cx.attribute = HPI_COBRANET_GET_DATA;
1709 }
1710 1708
1711 hpi_send_recv(&hm, &hr); 1709 hpi_send_recvV1(&hm.h, &hr.h);
1712 if (!hr.error && pb_data) {
1713 1710
1714 *pbyte_count = hr.u.cx.u.cobranet_data.byte_count; 1711 if (!hr.h.error && pb_data) {
1712 if (hr.byte_count > sizeof(hr.bytes))
1715 1713
1716 if (*pbyte_count < max_byte_count) 1714 return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
1717 max_byte_count = *pbyte_count;
1718 1715
1719 if (hm.u.cx.attribute == HPI_COBRANET_GET) { 1716 *pbyte_count = hr.byte_count;
1720 memcpy(pb_data, hr.u.cx.u.cobranet_data.data,
1721 max_byte_count);
1722 } else {
1723 1717
1724 } 1718 if (hr.byte_count < max_byte_count)
1719 max_byte_count = *pbyte_count;
1725 1720
1721 memcpy(pb_data, hr.bytes, max_byte_count);
1726 } 1722 }
1727 return hr.error; 1723 return hr.h.error;
1728} 1724}
1729 1725
1730u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus, 1726u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
@@ -1733,23 +1729,23 @@ u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
1733 struct hpi_message hm; 1729 struct hpi_message hm;
1734 struct hpi_response hr; 1730 struct hpi_response hr;
1735 1731
1736 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 1732 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1737 HPI_CONTROL_GET_STATE); 1733 HPI_CONTROL_GET_STATE);
1738 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index)) 1734 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1739 return HPI_ERROR_INVALID_HANDLE; 1735 return HPI_ERROR_INVALID_HANDLE;
1740 1736
1741 hm.u.cx.attribute = HPI_COBRANET_GET_STATUS; 1737 hm.u.c.attribute = HPI_COBRANET_GET_STATUS;
1742 1738
1743 hpi_send_recv(&hm, &hr); 1739 hpi_send_recv(&hm, &hr);
1744 if (!hr.error) { 1740 if (!hr.error) {
1745 if (pstatus) 1741 if (pstatus)
1746 *pstatus = hr.u.cx.u.cobranet_status.status; 1742 *pstatus = hr.u.cu.cobranet.status.status;
1747 if (preadable_size) 1743 if (preadable_size)
1748 *preadable_size = 1744 *preadable_size =
1749 hr.u.cx.u.cobranet_status.readable_size; 1745 hr.u.cu.cobranet.status.readable_size;
1750 if (pwriteable_size) 1746 if (pwriteable_size)
1751 *pwriteable_size = 1747 *pwriteable_size =
1752 hr.u.cx.u.cobranet_status.writeable_size; 1748 hr.u.cu.cobranet.status.writeable_size;
1753 } 1749 }
1754 return hr.error; 1750 return hr.error;
1755} 1751}
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c
index 628376ce4a4..52400a6b5f1 100644
--- a/sound/pci/asihpi/hpimsginit.c
+++ b/sound/pci/asihpi/hpimsginit.c
@@ -46,7 +46,7 @@ static void hpi_init_message(struct hpi_message *phm, u16 object,
46 if (gwSSX2_bypass) 46 if (gwSSX2_bypass)
47 phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE; 47 phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
48 else 48 else
49 phm->type = HPI_TYPE_MESSAGE; 49 phm->type = HPI_TYPE_REQUEST;
50 phm->object = object; 50 phm->object = object;
51 phm->function = function; 51 phm->function = function;
52 phm->version = 0; 52 phm->version = 0;
@@ -89,7 +89,7 @@ static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
89 memset(phm, 0, sizeof(*phm)); 89 memset(phm, 0, sizeof(*phm));
90 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 90 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
91 phm->size = size; 91 phm->size = size;
92 phm->type = HPI_TYPE_MESSAGE; 92 phm->type = HPI_TYPE_REQUEST;
93 phm->object = object; 93 phm->object = object;
94 phm->function = function; 94 phm->function = function;
95 phm->version = 1; 95 phm->version = 1;
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
index 7352a5f7b4f..2e779421a61 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -16,7 +16,7 @@
16 along with this program; if not, write to the Free Software 16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18
19Extended Message Function With Response Cacheing 19Extended Message Function With Response Caching
20 20
21(C) Copyright AudioScience Inc. 2002 21(C) Copyright AudioScience Inc. 2002
22*****************************************************************************/ 22*****************************************************************************/
@@ -186,7 +186,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
186 /* Initialize this module's internal state */ 186 /* Initialize this module's internal state */
187 hpios_msgxlock_init(&msgx_lock); 187 hpios_msgxlock_init(&msgx_lock);
188 memset(&hpi_entry_points, 0, sizeof(hpi_entry_points)); 188 memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
189 hpios_locked_mem_init();
190 /* Init subsys_findadapters response to no-adapters */ 189 /* Init subsys_findadapters response to no-adapters */
191 HPIMSGX__reset(HPIMSGX_ALLADAPTERS); 190 HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
192 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, 191 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
@@ -197,7 +196,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
197 case HPI_SUBSYS_DRIVER_UNLOAD: 196 case HPI_SUBSYS_DRIVER_UNLOAD:
198 HPI_COMMON(phm, phr); 197 HPI_COMMON(phm, phr);
199 HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner); 198 HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
200 hpios_locked_mem_free_all();
201 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, 199 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
202 HPI_SUBSYS_DRIVER_UNLOAD, 0); 200 HPI_SUBSYS_DRIVER_UNLOAD, 0);
203 return; 201 return;
@@ -315,7 +313,7 @@ void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
315{ 313{
316 HPI_DEBUG_MESSAGE(DEBUG, phm); 314 HPI_DEBUG_MESSAGE(DEBUG, phm);
317 315
318 if (phm->type != HPI_TYPE_MESSAGE) { 316 if (phm->type != HPI_TYPE_REQUEST) {
319 hpi_init_response(phr, phm->object, phm->function, 317 hpi_init_response(phr, phm->object, phm->function,
320 HPI_ERROR_INVALID_TYPE); 318 HPI_ERROR_INVALID_TYPE);
321 return; 319 return;
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index d8e7047512f..a32502e796d 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -1,7 +1,7 @@
1/******************************************************************************* 1/*******************************************************************************
2 2
3 AudioScience HPI driver 3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as 7 it under the terms of version 2 of the GNU General Public License as
@@ -107,7 +107,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
107 union hpi_response_buffer_v1 *hr; 107 union hpi_response_buffer_v1 *hr;
108 u16 res_max_size; 108 u16 res_max_size;
109 u32 uncopied_bytes; 109 u32 uncopied_bytes;
110 struct hpi_adapter *pa = NULL;
111 int err = 0; 110 int err = 0;
112 111
113 if (cmd != HPI_IOCTL_LINUX) 112 if (cmd != HPI_IOCTL_LINUX)
@@ -157,11 +156,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
157 goto out; 156 goto out;
158 } 157 }
159 158
160 if (hm->h.adapter_index >= HPI_MAX_ADAPTERS) {
161 err = -EINVAL;
162 goto out;
163 }
164
165 switch (hm->h.function) { 159 switch (hm->h.function) {
166 case HPI_SUBSYS_CREATE_ADAPTER: 160 case HPI_SUBSYS_CREATE_ADAPTER:
167 case HPI_ADAPTER_DELETE: 161 case HPI_ADAPTER_DELETE:
@@ -183,16 +177,21 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
183 } else { 177 } else {
184 u16 __user *ptr = NULL; 178 u16 __user *ptr = NULL;
185 u32 size = 0; 179 u32 size = 0;
186 180 u32 adapter_present;
187 /* -1=no data 0=read from user mem, 1=write to user mem */ 181 /* -1=no data 0=read from user mem, 1=write to user mem */
188 int wrflag = -1; 182 int wrflag = -1;
189 u32 adapter = hm->h.adapter_index; 183 struct hpi_adapter *pa;
190 pa = &adapters[adapter]; 184
185 if (hm->h.adapter_index < HPI_MAX_ADAPTERS) {
186 pa = &adapters[hm->h.adapter_index];
187 adapter_present = pa->type;
188 } else {
189 adapter_present = 0;
190 }
191 191
192 if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) { 192 if (!adapter_present) {
193 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, 193 hpi_init_response(&hr->r0, hm->h.object,
194 HPI_ADAPTER_OPEN, 194 hm->h.function, HPI_ERROR_BAD_ADAPTER_NUMBER);
195 HPI_ERROR_BAD_ADAPTER_NUMBER);
196 195
197 uncopied_bytes = 196 uncopied_bytes =
198 copy_to_user(puhr, hr, sizeof(hr->h)); 197 copy_to_user(puhr, hr, sizeof(hr->h));
@@ -203,7 +202,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
203 goto out; 202 goto out;
204 } 203 }
205 204
206 if (mutex_lock_interruptible(&adapters[adapter].mutex)) { 205 if (mutex_lock_interruptible(&pa->mutex)) {
207 err = -EINTR; 206 err = -EINTR;
208 goto out; 207 goto out;
209 } 208 }
@@ -239,8 +238,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
239 "stream buffer size %d\n", 238 "stream buffer size %d\n",
240 size); 239 size);
241 240
242 mutex_unlock(&adapters 241 mutex_unlock(&pa->mutex);
243 [adapter].mutex);
244 err = -EINVAL; 242 err = -EINVAL;
245 goto out; 243 goto out;
246 } 244 }
@@ -281,7 +279,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
281 uncopied_bytes, size); 279 uncopied_bytes, size);
282 } 280 }
283 281
284 mutex_unlock(&adapters[adapter].mutex); 282 mutex_unlock(&pa->mutex);
285 } 283 }
286 284
287 /* on return response size must be set */ 285 /* on return response size must be set */
diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c
index 742ee12a9e1..ff2a19b544f 100644
--- a/sound/pci/asihpi/hpios.c
+++ b/sound/pci/asihpi/hpios.c
@@ -39,10 +39,6 @@ void hpios_delay_micro_seconds(u32 num_micro_sec)
39 39
40} 40}
41 41
42void hpios_locked_mem_init(void)
43{
44}
45
46/** Allocated an area of locked memory for bus master DMA operations. 42/** Allocated an area of locked memory for bus master DMA operations.
47 43
48On error, return -ENOMEM, and *pMemArea.size = 0 44On error, return -ENOMEM, and *pMemArea.size = 0
@@ -85,7 +81,3 @@ u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
85 return 1; 81 return 1;
86 } 82 }
87} 83}
88
89void hpios_locked_mem_free_all(void)
90{
91}
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h
index 03273e729f9..2f605e34bad 100644
--- a/sound/pci/asihpi/hpios.h
+++ b/sound/pci/asihpi/hpios.h
@@ -38,6 +38,7 @@ HPI Operating System Specific macros for Linux Kernel driver
38#include <linux/firmware.h> 38#include <linux/firmware.h>
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/pci.h> 40#include <linux/pci.h>
41#include <linux/mutex.h>
41 42
42#define HPI_NO_OS_FILE_OPS 43#define HPI_NO_OS_FILE_OPS
43 44
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 3119cd97a21..537e0a2cc68 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1624,7 +1624,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
1624 } 1624 }
1625 1625
1626 if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED, 1626 if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
1627 card->shortname, chip)) { 1627 KBUILD_MODNAME, chip)) {
1628 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1628 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1629 snd_atiixp_free(chip); 1629 snd_atiixp_free(chip);
1630 return -EBUSY; 1630 return -EBUSY;
@@ -1701,7 +1701,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
1701} 1701}
1702 1702
1703static struct pci_driver driver = { 1703static struct pci_driver driver = {
1704 .name = "ATI IXP AC97 controller", 1704 .name = KBUILD_MODNAME,
1705 .id_table = snd_atiixp_ids, 1705 .id_table = snd_atiixp_ids,
1706 .probe = snd_atiixp_probe, 1706 .probe = snd_atiixp_probe,
1707 .remove = __devexit_p(snd_atiixp_remove), 1707 .remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 2f74c2fdf1e..45df275c824 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1260,7 +1260,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
1260 } 1260 }
1261 1261
1262 if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED, 1262 if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
1263 card->shortname, chip)) { 1263 KBUILD_MODNAME, chip)) {
1264 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1264 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1265 snd_atiixp_free(chip); 1265 snd_atiixp_free(chip);
1266 return -EBUSY; 1266 return -EBUSY;
@@ -1332,7 +1332,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
1332} 1332}
1333 1333
1334static struct pci_driver driver = { 1334static struct pci_driver driver = {
1335 .name = "ATI IXP MC97 controller", 1335 .name = KBUILD_MODNAME,
1336 .id_table = snd_atiixp_ids, 1336 .id_table = snd_atiixp_ids,
1337 .probe = snd_atiixp_probe, 1337 .probe = snd_atiixp_probe,
1338 .remove = __devexit_p(snd_atiixp_remove), 1338 .remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 7b72c88e449..a3846998688 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -196,7 +196,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
196 } 196 }
197 197
198 if ((err = request_irq(pci->irq, vortex_interrupt, 198 if ((err = request_irq(pci->irq, vortex_interrupt,
199 IRQF_SHARED, CARD_NAME_SHORT, 199 IRQF_SHARED, KBUILD_MODNAME,
200 chip)) != 0) { 200 chip)) != 0) {
201 printk(KERN_ERR "cannot grab irq\n"); 201 printk(KERN_ERR "cannot grab irq\n");
202 goto irq_out; 202 goto irq_out;
@@ -375,7 +375,7 @@ static void __devexit snd_vortex_remove(struct pci_dev *pci)
375 375
376// pci_driver definition 376// pci_driver definition
377static struct pci_driver driver = { 377static struct pci_driver driver = {
378 .name = CARD_NAME_SHORT, 378 .name = KBUILD_MODNAME,
379 .id_table = snd_vortex_ids, 379 .id_table = snd_vortex_ids,
380 .probe = snd_vortex_probe, 380 .probe = snd_vortex_probe,
381 .remove = __devexit_p(snd_vortex_remove), 381 .remove = __devexit_p(snd_vortex_remove),
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index c15002242d9..f8569b11331 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -171,7 +171,7 @@ MODULE_DEVICE_TABLE(pci, snd_aw2_ids);
171 171
172/* pci_driver definition */ 172/* pci_driver definition */
173static struct pci_driver driver = { 173static struct pci_driver driver = {
174 .name = "Emagic Audiowerk 2", 174 .name = KBUILD_MODNAME,
175 .id_table = snd_aw2_ids, 175 .id_table = snd_aw2_ids,
176 .probe = snd_aw2_probe, 176 .probe = snd_aw2_probe,
177 .remove = __devexit_p(snd_aw2_remove), 177 .remove = __devexit_p(snd_aw2_remove),
@@ -317,7 +317,7 @@ static int __devinit snd_aw2_create(struct snd_card *card,
317 snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt); 317 snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
318 318
319 if (request_irq(pci->irq, snd_aw2_saa7146_interrupt, 319 if (request_irq(pci->irq, snd_aw2_saa7146_interrupt,
320 IRQF_SHARED, "Audiowerk2", chip)) { 320 IRQF_SHARED, KBUILD_MODNAME, chip)) {
321 printk(KERN_ERR "aw2: Cannot grab irq %d\n", pci->irq); 321 printk(KERN_ERR "aw2: Cannot grab irq %d\n", pci->irq);
322 322
323 iounmap(chip->iobase_virt); 323 iounmap(chip->iobase_virt);
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 9b7a6346037..e4d76a270c9 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2559,7 +2559,7 @@ snd_azf3328_create(struct snd_card *card,
2559 codec_setup->name = "I2S_OUT"; 2559 codec_setup->name = "I2S_OUT";
2560 2560
2561 if (request_irq(pci->irq, snd_azf3328_interrupt, 2561 if (request_irq(pci->irq, snd_azf3328_interrupt,
2562 IRQF_SHARED, card->shortname, chip)) { 2562 IRQF_SHARED, KBUILD_MODNAME, chip)) {
2563 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 2563 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2564 err = -EBUSY; 2564 err = -EBUSY;
2565 goto out_err; 2565 goto out_err;
@@ -2860,7 +2860,7 @@ snd_azf3328_resume(struct pci_dev *pci)
2860 2860
2861 2861
2862static struct pci_driver driver = { 2862static struct pci_driver driver = {
2863 .name = "AZF3328", 2863 .name = KBUILD_MODNAME,
2864 .id_table = snd_azf3328_ids, 2864 .id_table = snd_azf3328_ids,
2865 .probe = snd_azf3328_probe, 2865 .probe = snd_azf3328_probe,
2866 .remove = __devexit_p(snd_azf3328_remove), 2866 .remove = __devexit_p(snd_azf3328_remove),
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 2958a05b529..39180335c23 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -760,7 +760,7 @@ static int __devinit snd_bt87x_create(struct snd_card *card,
760 snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS); 760 snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
761 761
762 err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED, 762 err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
763 "Bt87x audio", chip); 763 KBUILD_MODNAME, chip);
764 if (err < 0) { 764 if (err < 0) {
765 snd_printk(KERN_ERR "cannot grab irq %d\n", pci->irq); 765 snd_printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
766 goto fail; 766 goto fail;
@@ -965,7 +965,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_default_ids) = {
965}; 965};
966 966
967static struct pci_driver driver = { 967static struct pci_driver driver = {
968 .name = "Bt87x", 968 .name = KBUILD_MODNAME,
969 .id_table = snd_bt87x_ids, 969 .id_table = snd_bt87x_ids,
970 .probe = snd_bt87x_probe, 970 .probe = snd_bt87x_probe,
971 .remove = __devexit_p(snd_bt87x_remove), 971 .remove = __devexit_p(snd_bt87x_remove),
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 43775923969..061b7e65458 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1666,7 +1666,7 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1666 } 1666 }
1667 1667
1668 if (request_irq(pci->irq, snd_ca0106_interrupt, 1668 if (request_irq(pci->irq, snd_ca0106_interrupt,
1669 IRQF_SHARED, "snd_ca0106", chip)) { 1669 IRQF_SHARED, KBUILD_MODNAME, chip)) {
1670 snd_ca0106_free(chip); 1670 snd_ca0106_free(chip);
1671 printk(KERN_ERR "cannot grab irq\n"); 1671 printk(KERN_ERR "cannot grab irq\n");
1672 return -EBUSY; 1672 return -EBUSY;
@@ -1933,7 +1933,7 @@ MODULE_DEVICE_TABLE(pci, snd_ca0106_ids);
1933 1933
1934// pci_driver definition 1934// pci_driver definition
1935static struct pci_driver driver = { 1935static struct pci_driver driver = {
1936 .name = "CA0106", 1936 .name = KBUILD_MODNAME,
1937 .id_table = snd_ca0106_ids, 1937 .id_table = snd_ca0106_ids,
1938 .probe = snd_ca0106_probe, 1938 .probe = snd_ca0106_probe,
1939 .remove = __devexit_p(snd_ca0106_remove), 1939 .remove = __devexit_p(snd_ca0106_remove),
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index f4e573555da..9cf99fb7eb9 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -3053,7 +3053,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
3053 cm->iobase = pci_resource_start(pci, 0); 3053 cm->iobase = pci_resource_start(pci, 0);
3054 3054
3055 if (request_irq(pci->irq, snd_cmipci_interrupt, 3055 if (request_irq(pci->irq, snd_cmipci_interrupt,
3056 IRQF_SHARED, card->driver, cm)) { 3056 IRQF_SHARED, KBUILD_MODNAME, cm)) {
3057 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 3057 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
3058 snd_cmipci_free(cm); 3058 snd_cmipci_free(cm);
3059 return -EBUSY; 3059 return -EBUSY;
@@ -3398,7 +3398,7 @@ static int snd_cmipci_resume(struct pci_dev *pci)
3398#endif /* CONFIG_PM */ 3398#endif /* CONFIG_PM */
3399 3399
3400static struct pci_driver driver = { 3400static struct pci_driver driver = {
3401 .name = "C-Media PCI", 3401 .name = KBUILD_MODNAME,
3402 .id_table = snd_cmipci_ids, 3402 .id_table = snd_cmipci_ids,
3403 .probe = snd_cmipci_probe, 3403 .probe = snd_cmipci_probe,
3404 .remove = __devexit_p(snd_cmipci_remove), 3404 .remove = __devexit_p(snd_cmipci_remove),
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 6772070ed49..07f04e390aa 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1382,7 +1382,7 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
1382 } 1382 }
1383 1383
1384 if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_SHARED, 1384 if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_SHARED,
1385 "CS4281", chip)) { 1385 KBUILD_MODNAME, chip)) {
1386 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1386 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1387 snd_cs4281_free(chip); 1387 snd_cs4281_free(chip);
1388 return -ENOMEM; 1388 return -ENOMEM;
@@ -2085,7 +2085,7 @@ static int cs4281_resume(struct pci_dev *pci)
2085#endif /* CONFIG_PM */ 2085#endif /* CONFIG_PM */
2086 2086
2087static struct pci_driver driver = { 2087static struct pci_driver driver = {
2088 .name = "CS4281", 2088 .name = KBUILD_MODNAME,
2089 .id_table = snd_cs4281_ids, 2089 .id_table = snd_cs4281_ids,
2090 .probe = snd_cs4281_probe, 2090 .probe = snd_cs4281_probe,
2091 .remove = __devexit_p(snd_cs4281_remove), 2091 .remove = __devexit_p(snd_cs4281_remove),
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 767fa7f06cd..1af95559aaa 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -162,7 +162,7 @@ static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci)
162} 162}
163 163
164static struct pci_driver driver = { 164static struct pci_driver driver = {
165 .name = "Sound Fusion CS46xx", 165 .name = KBUILD_MODNAME,
166 .id_table = snd_cs46xx_ids, 166 .id_table = snd_cs46xx_ids,
167 .probe = snd_card_cs46xx_probe, 167 .probe = snd_card_cs46xx_probe,
168 .remove = __devexit_p(snd_card_cs46xx_remove), 168 .remove = __devexit_p(snd_card_cs46xx_remove),
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index aad37082cb6..9546bf07f0d 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -3835,7 +3835,7 @@ int __devinit snd_cs46xx_create(struct snd_card *card,
3835 } 3835 }
3836 3836
3837 if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED, 3837 if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
3838 "CS46XX", chip)) { 3838 KBUILD_MODNAME, chip)) {
3839 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 3839 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
3840 snd_cs46xx_free(chip); 3840 snd_cs46xx_free(chip);
3841 return -EBUSY; 3841 return -EBUSY;
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index bc07e275d4d..a4669346d14 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -285,7 +285,7 @@ static int __devinit snd_cs5530_probe(struct pci_dev *pci,
285} 285}
286 286
287static struct pci_driver driver = { 287static struct pci_driver driver = {
288 .name = "CS5530_Audio", 288 .name = KBUILD_MODNAME,
289 .id_table = snd_cs5530_ids, 289 .id_table = snd_cs5530_ids,
290 .probe = snd_cs5530_probe, 290 .probe = snd_cs5530_probe,
291 .remove = __devexit_p(snd_cs5530_remove), 291 .remove = __devexit_p(snd_cs5530_remove),
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index afb80370841..10d22ed5fec 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -311,7 +311,7 @@ static int __devinit snd_cs5535audio_create(struct snd_card *card,
311 cs5535au->port = pci_resource_start(pci, 0); 311 cs5535au->port = pci_resource_start(pci, 0);
312 312
313 if (request_irq(pci->irq, snd_cs5535audio_interrupt, 313 if (request_irq(pci->irq, snd_cs5535audio_interrupt,
314 IRQF_SHARED, "CS5535 Audio", cs5535au)) { 314 IRQF_SHARED, KBUILD_MODNAME, cs5535au)) {
315 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 315 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
316 err = -EBUSY; 316 err = -EBUSY;
317 goto sndfail; 317 goto sndfail;
@@ -395,7 +395,7 @@ static void __devexit snd_cs5535audio_remove(struct pci_dev *pci)
395} 395}
396 396
397static struct pci_driver driver = { 397static struct pci_driver driver = {
398 .name = DRIVER_NAME, 398 .name = KBUILD_MODNAME,
399 .id_table = snd_cs5535audio_ids, 399 .id_table = snd_cs5535audio_ids,
400 .probe = snd_cs5535audio_probe, 400 .probe = snd_cs5535audio_probe,
401 .remove = __devexit_p(snd_cs5535audio_remove), 401 .remove = __devexit_p(snd_cs5535audio_remove),
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index f16bc8aad6e..e083122ca55 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -149,7 +149,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
149 &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i]; 149 &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i];
150 desc->addr = cpu_to_le32(addr); 150 desc->addr = cpu_to_le32(addr);
151 desc->size = cpu_to_le32(period_bytes); 151 desc->size = cpu_to_le32(period_bytes);
152 desc->ctlreserved = cpu_to_le32(PRD_EOP); 152 desc->ctlreserved = cpu_to_le16(PRD_EOP);
153 desc_addr += sizeof(struct cs5535audio_dma_desc); 153 desc_addr += sizeof(struct cs5535audio_dma_desc);
154 addr += period_bytes; 154 addr += period_bytes;
155 } 155 }
@@ -157,7 +157,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
157 lastdesc = &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[periods]; 157 lastdesc = &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[periods];
158 lastdesc->addr = cpu_to_le32((u32) dma->desc_buf.addr); 158 lastdesc->addr = cpu_to_le32((u32) dma->desc_buf.addr);
159 lastdesc->size = 0; 159 lastdesc->size = 0;
160 lastdesc->ctlreserved = cpu_to_le32(PRD_JMP); 160 lastdesc->ctlreserved = cpu_to_le16(PRD_JMP);
161 jmpprd_addr = cpu_to_le32(lastdesc->addr + 161 jmpprd_addr = cpu_to_le32(lastdesc->addr +
162 (sizeof(struct cs5535audio_dma_desc)*periods)); 162 (sizeof(struct cs5535audio_dma_desc)*periods));
163 163
diff --git a/sound/pci/ctxfi/ct20k2reg.h b/sound/pci/ctxfi/ct20k2reg.h
index e0394e3996e..ca501ba03d6 100644
--- a/sound/pci/ctxfi/ct20k2reg.h
+++ b/sound/pci/ctxfi/ct20k2reg.h
@@ -55,6 +55,7 @@
55/* GPIO Registers */ 55/* GPIO Registers */
56#define GPIO_DATA 0x1B7020 56#define GPIO_DATA 0x1B7020
57#define GPIO_CTRL 0x1B7024 57#define GPIO_CTRL 0x1B7024
58#define GPIO_EXT_DATA 0x1B70A0
58 59
59/* Virtual memory registers */ 60/* Virtual memory registers */
60#define VMEM_PTPAL 0x1C6300 /* 0x1C6300 + (16 * Chn) */ 61#define VMEM_PTPAL 0x1C6300 /* 0x1C6300 + (16 * Chn) */
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 13f33c0719d..d8a4423539c 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -18,7 +18,6 @@
18#include "ctatc.h" 18#include "ctatc.h"
19#include "ctpcm.h" 19#include "ctpcm.h"
20#include "ctmixer.h" 20#include "ctmixer.h"
21#include "cthardware.h"
22#include "ctsrc.h" 21#include "ctsrc.h"
23#include "ctamixer.h" 22#include "ctamixer.h"
24#include "ctdaio.h" 23#include "ctdaio.h"
@@ -30,7 +29,6 @@
30#include <sound/asoundef.h> 29#include <sound/asoundef.h>
31 30
32#define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */ 31#define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */
33#define DAIONUM 7
34#define MAX_MULTI_CHN 8 32#define MAX_MULTI_CHN 8
35 33
36#define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \ 34#define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \
@@ -53,6 +51,8 @@ static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = {
53static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = { 51static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
54 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760, 52 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760,
55 "SB0760", CTSB0760), 53 "SB0760", CTSB0760),
54 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB1270,
55 "SB1270", CTSB1270),
56 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801, 56 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801,
57 "SB0880", CTSB0880), 57 "SB0880", CTSB0880),
58 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802, 58 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802,
@@ -75,6 +75,7 @@ static const char *ct_subsys_name[NUM_CTCARDS] = {
75 [CTSB0760] = "SB076x", 75 [CTSB0760] = "SB076x",
76 [CTHENDRIX] = "Hendrix", 76 [CTHENDRIX] = "Hendrix",
77 [CTSB0880] = "SB0880", 77 [CTSB0880] = "SB0880",
78 [CTSB1270] = "SB1270",
78 [CT20K2_UNKNOWN] = "Unknown", 79 [CT20K2_UNKNOWN] = "Unknown",
79}; 80};
80 81
@@ -459,12 +460,12 @@ static void setup_src_node_conf(struct ct_atc *atc, struct ct_atc_pcm *apcm,
459 apcm->substream->runtime->rate); 460 apcm->substream->runtime->rate);
460 *n_srcc = 0; 461 *n_srcc = 0;
461 462
462 if (1 == atc->msr) { 463 if (1 == atc->msr) { /* FIXME: do we really need SRC here if pitch==1 */
463 *n_srcc = apcm->substream->runtime->channels; 464 *n_srcc = apcm->substream->runtime->channels;
464 conf[0].pitch = pitch; 465 conf[0].pitch = pitch;
465 conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1; 466 conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1;
466 conf[0].vo = 1; 467 conf[0].vo = 1;
467 } else if (2 == atc->msr) { 468 } else if (2 <= atc->msr) {
468 if (0x8000000 < pitch) { 469 if (0x8000000 < pitch) {
469 /* Need two-stage SRCs, SRCIMPs and 470 /* Need two-stage SRCs, SRCIMPs and
470 * AMIXERs for converting format */ 471 * AMIXERs for converting format */
@@ -970,11 +971,39 @@ static int atc_select_mic_in(struct ct_atc *atc)
970 return 0; 971 return 0;
971} 972}
972 973
973static int atc_have_digit_io_switch(struct ct_atc *atc) 974static struct capabilities atc_capabilities(struct ct_atc *atc)
974{ 975{
975 struct hw *hw = atc->hw; 976 struct hw *hw = atc->hw;
976 977
977 return hw->have_digit_io_switch(hw); 978 return hw->capabilities(hw);
979}
980
981static int atc_output_switch_get(struct ct_atc *atc)
982{
983 struct hw *hw = atc->hw;
984
985 return hw->output_switch_get(hw);
986}
987
988static int atc_output_switch_put(struct ct_atc *atc, int position)
989{
990 struct hw *hw = atc->hw;
991
992 return hw->output_switch_put(hw, position);
993}
994
995static int atc_mic_source_switch_get(struct ct_atc *atc)
996{
997 struct hw *hw = atc->hw;
998
999 return hw->mic_source_switch_get(hw);
1000}
1001
1002static int atc_mic_source_switch_put(struct ct_atc *atc, int position)
1003{
1004 struct hw *hw = atc->hw;
1005
1006 return hw->mic_source_switch_put(hw, position);
978} 1007}
979 1008
980static int atc_select_digit_io(struct ct_atc *atc) 1009static int atc_select_digit_io(struct ct_atc *atc)
@@ -1045,6 +1074,11 @@ static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
1045 return atc_daio_unmute(atc, state, LINEIM); 1074 return atc_daio_unmute(atc, state, LINEIM);
1046} 1075}
1047 1076
1077static int atc_mic_unmute(struct ct_atc *atc, unsigned char state)
1078{
1079 return atc_daio_unmute(atc, state, MIC);
1080}
1081
1048static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state) 1082static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state)
1049{ 1083{
1050 return atc_daio_unmute(atc, state, SPDIFOO); 1084 return atc_daio_unmute(atc, state, SPDIFOO);
@@ -1331,17 +1365,20 @@ static int atc_get_resources(struct ct_atc *atc)
1331 struct srcimp_mgr *srcimp_mgr; 1365 struct srcimp_mgr *srcimp_mgr;
1332 struct sum_desc sum_dsc = {0}; 1366 struct sum_desc sum_dsc = {0};
1333 struct sum_mgr *sum_mgr; 1367 struct sum_mgr *sum_mgr;
1334 int err, i; 1368 int err, i, num_srcs, num_daios;
1335 1369
1336 atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL); 1370 num_daios = ((atc->model == CTSB1270) ? 8 : 7);
1371 num_srcs = ((atc->model == CTSB1270) ? 6 : 4);
1372
1373 atc->daios = kzalloc(sizeof(void *)*num_daios, GFP_KERNEL);
1337 if (!atc->daios) 1374 if (!atc->daios)
1338 return -ENOMEM; 1375 return -ENOMEM;
1339 1376
1340 atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL); 1377 atc->srcs = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL);
1341 if (!atc->srcs) 1378 if (!atc->srcs)
1342 return -ENOMEM; 1379 return -ENOMEM;
1343 1380
1344 atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL); 1381 atc->srcimps = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL);
1345 if (!atc->srcimps) 1382 if (!atc->srcimps)
1346 return -ENOMEM; 1383 return -ENOMEM;
1347 1384
@@ -1351,8 +1388,9 @@ static int atc_get_resources(struct ct_atc *atc)
1351 1388
1352 daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; 1389 daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
1353 da_desc.msr = atc->msr; 1390 da_desc.msr = atc->msr;
1354 for (i = 0, atc->n_daio = 0; i < DAIONUM-1; i++) { 1391 for (i = 0, atc->n_daio = 0; i < num_daios; i++) {
1355 da_desc.type = i; 1392 da_desc.type = (atc->model != CTSB073X) ? i :
1393 ((i == SPDIFIO) ? SPDIFI1 : i);
1356 err = daio_mgr->get_daio(daio_mgr, &da_desc, 1394 err = daio_mgr->get_daio(daio_mgr, &da_desc,
1357 (struct daio **)&atc->daios[i]); 1395 (struct daio **)&atc->daios[i]);
1358 if (err) { 1396 if (err) {
@@ -1362,23 +1400,12 @@ static int atc_get_resources(struct ct_atc *atc)
1362 } 1400 }
1363 atc->n_daio++; 1401 atc->n_daio++;
1364 } 1402 }
1365 if (atc->model == CTSB073X)
1366 da_desc.type = SPDIFI1;
1367 else
1368 da_desc.type = SPDIFIO;
1369 err = daio_mgr->get_daio(daio_mgr, &da_desc,
1370 (struct daio **)&atc->daios[i]);
1371 if (err) {
1372 printk(KERN_ERR "ctxfi: Failed to get S/PDIF-in resource!!!\n");
1373 return err;
1374 }
1375 atc->n_daio++;
1376 1403
1377 src_mgr = atc->rsc_mgrs[SRC]; 1404 src_mgr = atc->rsc_mgrs[SRC];
1378 src_dsc.multi = 1; 1405 src_dsc.multi = 1;
1379 src_dsc.msr = atc->msr; 1406 src_dsc.msr = atc->msr;
1380 src_dsc.mode = ARCRW; 1407 src_dsc.mode = ARCRW;
1381 for (i = 0, atc->n_src = 0; i < (2*2); i++) { 1408 for (i = 0, atc->n_src = 0; i < num_srcs; i++) {
1382 err = src_mgr->get_src(src_mgr, &src_dsc, 1409 err = src_mgr->get_src(src_mgr, &src_dsc,
1383 (struct src **)&atc->srcs[i]); 1410 (struct src **)&atc->srcs[i]);
1384 if (err) 1411 if (err)
@@ -1388,8 +1415,8 @@ static int atc_get_resources(struct ct_atc *atc)
1388 } 1415 }
1389 1416
1390 srcimp_mgr = atc->rsc_mgrs[SRCIMP]; 1417 srcimp_mgr = atc->rsc_mgrs[SRCIMP];
1391 srcimp_dsc.msr = 8; /* SRCIMPs for S/PDIFIn SRT */ 1418 srcimp_dsc.msr = 8;
1392 for (i = 0, atc->n_srcimp = 0; i < (2*1); i++) { 1419 for (i = 0, atc->n_srcimp = 0; i < num_srcs; i++) {
1393 err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, 1420 err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
1394 (struct srcimp **)&atc->srcimps[i]); 1421 (struct srcimp **)&atc->srcimps[i]);
1395 if (err) 1422 if (err)
@@ -1397,15 +1424,6 @@ static int atc_get_resources(struct ct_atc *atc)
1397 1424
1398 atc->n_srcimp++; 1425 atc->n_srcimp++;
1399 } 1426 }
1400 srcimp_dsc.msr = 8; /* SRCIMPs for LINE/MICIn SRT */
1401 for (i = 0; i < (2*1); i++) {
1402 err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
1403 (struct srcimp **)&atc->srcimps[2*1+i]);
1404 if (err)
1405 return err;
1406
1407 atc->n_srcimp++;
1408 }
1409 1427
1410 sum_mgr = atc->rsc_mgrs[SUM]; 1428 sum_mgr = atc->rsc_mgrs[SUM];
1411 sum_dsc.msr = atc->msr; 1429 sum_dsc.msr = atc->msr;
@@ -1488,6 +1506,18 @@ static void atc_connect_resources(struct ct_atc *atc)
1488 src = atc->srcs[3]; 1506 src = atc->srcs[3];
1489 mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc); 1507 mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
1490 1508
1509 if (atc->model == CTSB1270) {
1510 /* Titanium HD has a dedicated ADC for the Mic. */
1511 dai = container_of(atc->daios[MIC], struct dai, daio);
1512 atc_connect_dai(atc->rsc_mgrs[SRC], dai,
1513 (struct src **)&atc->srcs[4],
1514 (struct srcimp **)&atc->srcimps[4]);
1515 src = atc->srcs[4];
1516 mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc);
1517 src = atc->srcs[5];
1518 mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc);
1519 }
1520
1491 dai = container_of(atc->daios[SPDIFIO], struct dai, daio); 1521 dai = container_of(atc->daios[SPDIFIO], struct dai, daio);
1492 atc_connect_dai(atc->rsc_mgrs[SRC], dai, 1522 atc_connect_dai(atc->rsc_mgrs[SRC], dai,
1493 (struct src **)&atc->srcs[0], 1523 (struct src **)&atc->srcs[0],
@@ -1606,12 +1636,17 @@ static struct ct_atc atc_preset __devinitdata = {
1606 .line_clfe_unmute = atc_line_clfe_unmute, 1636 .line_clfe_unmute = atc_line_clfe_unmute,
1607 .line_rear_unmute = atc_line_rear_unmute, 1637 .line_rear_unmute = atc_line_rear_unmute,
1608 .line_in_unmute = atc_line_in_unmute, 1638 .line_in_unmute = atc_line_in_unmute,
1639 .mic_unmute = atc_mic_unmute,
1609 .spdif_out_unmute = atc_spdif_out_unmute, 1640 .spdif_out_unmute = atc_spdif_out_unmute,
1610 .spdif_in_unmute = atc_spdif_in_unmute, 1641 .spdif_in_unmute = atc_spdif_in_unmute,
1611 .spdif_out_get_status = atc_spdif_out_get_status, 1642 .spdif_out_get_status = atc_spdif_out_get_status,
1612 .spdif_out_set_status = atc_spdif_out_set_status, 1643 .spdif_out_set_status = atc_spdif_out_set_status,
1613 .spdif_out_passthru = atc_spdif_out_passthru, 1644 .spdif_out_passthru = atc_spdif_out_passthru,
1614 .have_digit_io_switch = atc_have_digit_io_switch, 1645 .capabilities = atc_capabilities,
1646 .output_switch_get = atc_output_switch_get,
1647 .output_switch_put = atc_output_switch_put,
1648 .mic_source_switch_get = atc_mic_source_switch_get,
1649 .mic_source_switch_put = atc_mic_source_switch_put,
1615#ifdef CONFIG_PM 1650#ifdef CONFIG_PM
1616 .suspend = atc_suspend, 1651 .suspend = atc_suspend,
1617 .resume = atc_resume, 1652 .resume = atc_resume,
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 7167c0185d5..3a0def656af 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -25,6 +25,7 @@
25#include <sound/core.h> 25#include <sound/core.h>
26 26
27#include "ctvmem.h" 27#include "ctvmem.h"
28#include "cthardware.h"
28#include "ctresource.h" 29#include "ctresource.h"
29 30
30enum CTALSADEVS { /* Types of alsa devices */ 31enum CTALSADEVS { /* Types of alsa devices */
@@ -115,12 +116,17 @@ struct ct_atc {
115 int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state); 116 int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state);
116 int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state); 117 int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state);
117 int (*line_in_unmute)(struct ct_atc *atc, unsigned char state); 118 int (*line_in_unmute)(struct ct_atc *atc, unsigned char state);
119 int (*mic_unmute)(struct ct_atc *atc, unsigned char state);
118 int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state); 120 int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state);
119 int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state); 121 int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state);
120 int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status); 122 int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status);
121 int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status); 123 int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status);
122 int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state); 124 int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state);
123 int (*have_digit_io_switch)(struct ct_atc *atc); 125 struct capabilities (*capabilities)(struct ct_atc *atc);
126 int (*output_switch_get)(struct ct_atc *atc);
127 int (*output_switch_put)(struct ct_atc *atc, int position);
128 int (*mic_source_switch_get)(struct ct_atc *atc);
129 int (*mic_source_switch_put)(struct ct_atc *atc, int position);
124 130
125 /* Don't touch! Used for internal object. */ 131 /* Don't touch! Used for internal object. */
126 void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */ 132 void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */
diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c
index 47d9ea97de0..0c00eb4088e 100644
--- a/sound/pci/ctxfi/ctdaio.c
+++ b/sound/pci/ctxfi/ctdaio.c
@@ -22,20 +22,9 @@
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24 24
25#define DAIO_RESOURCE_NUM NUM_DAIOTYP
26#define DAIO_OUT_MAX SPDIFOO 25#define DAIO_OUT_MAX SPDIFOO
27 26
28union daio_usage { 27struct daio_usage {
29 struct {
30 unsigned short lineo1:1;
31 unsigned short lineo2:1;
32 unsigned short lineo3:1;
33 unsigned short lineo4:1;
34 unsigned short spdifoo:1;
35 unsigned short lineim:1;
36 unsigned short spdifio:1;
37 unsigned short spdifi1:1;
38 } bf;
39 unsigned short data; 28 unsigned short data;
40}; 29};
41 30
@@ -61,6 +50,7 @@ struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = {
61 [LINEO3] = {.left = 0x50, .right = 0x51}, 50 [LINEO3] = {.left = 0x50, .right = 0x51},
62 [LINEO4] = {.left = 0x70, .right = 0x71}, 51 [LINEO4] = {.left = 0x70, .right = 0x71},
63 [LINEIM] = {.left = 0x45, .right = 0xc5}, 52 [LINEIM] = {.left = 0x45, .right = 0xc5},
53 [MIC] = {.left = 0x55, .right = 0xd5},
64 [SPDIFOO] = {.left = 0x00, .right = 0x01}, 54 [SPDIFOO] = {.left = 0x00, .right = 0x01},
65 [SPDIFIO] = {.left = 0x05, .right = 0x85}, 55 [SPDIFIO] = {.left = 0x05, .right = 0x85},
66}; 56};
@@ -138,6 +128,7 @@ static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
138 case LINEO3: return 5; 128 case LINEO3: return 5;
139 case LINEO4: return 6; 129 case LINEO4: return 6;
140 case LINEIM: return 4; 130 case LINEIM: return 4;
131 case MIC: return 5;
141 default: return -EINVAL; 132 default: return -EINVAL;
142 } 133 }
143 default: 134 default:
@@ -519,17 +510,17 @@ static int dai_rsc_uninit(struct dai *dai)
519 510
520static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type) 511static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
521{ 512{
522 if (((union daio_usage *)mgr->rscs)->data & (0x1 << type)) 513 if (((struct daio_usage *)mgr->rscs)->data & (0x1 << type))
523 return -ENOENT; 514 return -ENOENT;
524 515
525 ((union daio_usage *)mgr->rscs)->data |= (0x1 << type); 516 ((struct daio_usage *)mgr->rscs)->data |= (0x1 << type);
526 517
527 return 0; 518 return 0;
528} 519}
529 520
530static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type) 521static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
531{ 522{
532 ((union daio_usage *)mgr->rscs)->data &= ~(0x1 << type); 523 ((struct daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
533 524
534 return 0; 525 return 0;
535} 526}
@@ -712,7 +703,7 @@ int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
712 if (!daio_mgr) 703 if (!daio_mgr)
713 return -ENOMEM; 704 return -ENOMEM;
714 705
715 err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw); 706 err = rsc_mgr_init(&daio_mgr->mgr, DAIO, NUM_DAIOTYP, hw);
716 if (err) 707 if (err)
717 goto error1; 708 goto error1;
718 709
diff --git a/sound/pci/ctxfi/ctdaio.h b/sound/pci/ctxfi/ctdaio.h
index 0f52ce571ee..85ccb6ee1ab 100644
--- a/sound/pci/ctxfi/ctdaio.h
+++ b/sound/pci/ctxfi/ctdaio.h
@@ -33,6 +33,7 @@ enum DAIOTYP {
33 SPDIFOO, /* S/PDIF Out (Flexijack/Optical) */ 33 SPDIFOO, /* S/PDIF Out (Flexijack/Optical) */
34 LINEIM, 34 LINEIM,
35 SPDIFIO, /* S/PDIF In (Flexijack/Optical) on the card */ 35 SPDIFIO, /* S/PDIF In (Flexijack/Optical) on the card */
36 MIC, /* Dedicated mic on Titanium HD */
36 SPDIFI1, /* S/PDIF In on internal Drive Bay */ 37 SPDIFI1, /* S/PDIF In on internal Drive Bay */
37 NUM_DAIOTYP 38 NUM_DAIOTYP
38}; 39};
diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h
index af55405f5de..908315bec3b 100644
--- a/sound/pci/ctxfi/cthardware.h
+++ b/sound/pci/ctxfi/cthardware.h
@@ -39,6 +39,7 @@ enum CTCARDS {
39 CT20K2_MODEL_FIRST = CTSB0760, 39 CT20K2_MODEL_FIRST = CTSB0760,
40 CTHENDRIX, 40 CTHENDRIX,
41 CTSB0880, 41 CTSB0880,
42 CTSB1270,
42 CT20K2_UNKNOWN, 43 CT20K2_UNKNOWN,
43 NUM_CTCARDS /* This should always be the last */ 44 NUM_CTCARDS /* This should always be the last */
44}; 45};
@@ -60,6 +61,13 @@ struct card_conf {
60 unsigned int msr; /* master sample rate in rsrs */ 61 unsigned int msr; /* master sample rate in rsrs */
61}; 62};
62 63
64struct capabilities {
65 unsigned int digit_io_switch:1;
66 unsigned int dedicated_mic:1;
67 unsigned int output_switch:1;
68 unsigned int mic_source_switch:1;
69};
70
63struct hw { 71struct hw {
64 int (*card_init)(struct hw *hw, struct card_conf *info); 72 int (*card_init)(struct hw *hw, struct card_conf *info);
65 int (*card_stop)(struct hw *hw); 73 int (*card_stop)(struct hw *hw);
@@ -70,7 +78,11 @@ struct hw {
70#endif 78#endif
71 int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source); 79 int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
72 int (*select_adc_source)(struct hw *hw, enum ADCSRC source); 80 int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
73 int (*have_digit_io_switch)(struct hw *hw); 81 struct capabilities (*capabilities)(struct hw *hw);
82 int (*output_switch_get)(struct hw *hw);
83 int (*output_switch_put)(struct hw *hw, int position);
84 int (*mic_source_switch_get)(struct hw *hw);
85 int (*mic_source_switch_put)(struct hw *hw, int position);
74 86
75 /* SRC operations */ 87 /* SRC operations */
76 int (*src_rsc_get_ctrl_blk)(void **rblk); 88 int (*src_rsc_get_ctrl_blk)(void **rblk);
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index a5c957db5ce..a7df19791f5 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -1777,10 +1777,17 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
1777 return adc_init_SBx(hw, info->input, info->mic20db); 1777 return adc_init_SBx(hw, info->input, info->mic20db);
1778} 1778}
1779 1779
1780static int hw_have_digit_io_switch(struct hw *hw) 1780static struct capabilities hw_capabilities(struct hw *hw)
1781{ 1781{
1782 struct capabilities cap;
1783
1782 /* SB073x and Vista compatible cards have no digit IO switch */ 1784 /* SB073x and Vista compatible cards have no digit IO switch */
1783 return !(hw->model == CTSB073X || hw->model == CTUAA); 1785 cap.digit_io_switch = !(hw->model == CTSB073X || hw->model == CTUAA);
1786 cap.dedicated_mic = 0;
1787 cap.output_switch = 0;
1788 cap.mic_source_switch = 0;
1789
1790 return cap;
1784} 1791}
1785 1792
1786#define CTLBITS(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) 1793#define CTLBITS(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
@@ -1933,7 +1940,7 @@ static int hw_card_start(struct hw *hw)
1933 1940
1934 if (hw->irq < 0) { 1941 if (hw->irq < 0) {
1935 err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED, 1942 err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
1936 "ctxfi", hw); 1943 KBUILD_MODNAME, hw);
1937 if (err < 0) { 1944 if (err < 0) {
1938 printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq); 1945 printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
1939 goto error2; 1946 goto error2;
@@ -2172,7 +2179,7 @@ static struct hw ct20k1_preset __devinitdata = {
2172 .pll_init = hw_pll_init, 2179 .pll_init = hw_pll_init,
2173 .is_adc_source_selected = hw_is_adc_input_selected, 2180 .is_adc_source_selected = hw_is_adc_input_selected,
2174 .select_adc_source = hw_adc_input_select, 2181 .select_adc_source = hw_adc_input_select,
2175 .have_digit_io_switch = hw_have_digit_io_switch, 2182 .capabilities = hw_capabilities,
2176#ifdef CONFIG_PM 2183#ifdef CONFIG_PM
2177 .suspend = hw_suspend, 2184 .suspend = hw_suspend,
2178 .resume = hw_resume, 2185 .resume = hw_resume,
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index 5364164674e..d6c54b524bf 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -8,7 +8,7 @@
8 * @File cthw20k2.c 8 * @File cthw20k2.c
9 * 9 *
10 * @Brief 10 * @Brief
11 * This file contains the implementation of hardware access methord for 20k2. 11 * This file contains the implementation of hardware access method for 20k2.
12 * 12 *
13 * @Author Liu Chun 13 * @Author Liu Chun
14 * @Date May 14 2008 14 * @Date May 14 2008
@@ -38,6 +38,8 @@ struct hw20k2 {
38 unsigned char dev_id; 38 unsigned char dev_id;
39 unsigned char addr_size; 39 unsigned char addr_size;
40 unsigned char data_size; 40 unsigned char data_size;
41
42 int mic_source;
41}; 43};
42 44
43static u32 hw_read_20kx(struct hw *hw, u32 reg); 45static u32 hw_read_20kx(struct hw *hw, u32 reg);
@@ -1163,7 +1165,12 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
1163 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101); 1165 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101);
1164 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0); 1166 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
1165 } else if (2 == info->msr) { 1167 } else if (2 == info->msr) {
1166 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111); 1168 if (hw->model != CTSB1270) {
1169 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111);
1170 } else {
1171 /* PCM4220 on Titanium HD is different. */
1172 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11011111);
1173 }
1167 /* Specify all playing 96khz 1174 /* Specify all playing 96khz
1168 * EA [0] - Enabled 1175 * EA [0] - Enabled
1169 * RTA [4:5] - 96kHz 1176 * RTA [4:5] - 96kHz
@@ -1175,6 +1182,10 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
1175 * RTD [28:29] - 96kHz */ 1182 * RTD [28:29] - 96kHz */
1176 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111); 1183 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111);
1177 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0); 1184 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
1185 } else if ((4 == info->msr) && (hw->model == CTSB1270)) {
1186 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x21011111);
1187 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x21212121);
1188 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
1178 } else { 1189 } else {
1179 printk(KERN_ALERT "ctxfi: ERROR!!! Invalid sampling rate!!!\n"); 1190 printk(KERN_ALERT "ctxfi: ERROR!!! Invalid sampling rate!!!\n");
1180 return -EINVAL; 1191 return -EINVAL;
@@ -1182,6 +1193,8 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
1182 1193
1183 for (i = 0; i < 8; i++) { 1194 for (i = 0; i < 8; i++) {
1184 if (i <= 3) { 1195 if (i <= 3) {
1196 /* This comment looks wrong since loop is over 4 */
1197 /* channels and emu20k2 supports 4 spdif IOs. */
1185 /* 1st 3 channels are SPDIFs (SB0960) */ 1198 /* 1st 3 channels are SPDIFs (SB0960) */
1186 if (i == 3) 1199 if (i == 3)
1187 data = 0x1001001; 1200 data = 0x1001001;
@@ -1206,12 +1219,16 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
1206 1219
1207 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B); 1220 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B);
1208 } else { 1221 } else {
1222 /* Again, loop is over 4 channels not 5. */
1209 /* Next 5 channels are I2S (SB0960) */ 1223 /* Next 5 channels are I2S (SB0960) */
1210 data = 0x11; 1224 data = 0x11;
1211 hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data); 1225 hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data);
1212 if (2 == info->msr) { 1226 if (2 == info->msr) {
1213 /* Four channels per sample period */ 1227 /* Four channels per sample period */
1214 data |= 0x1000; 1228 data |= 0x1000;
1229 } else if (4 == info->msr) {
1230 /* FIXME: check this against the chip spec */
1231 data |= 0x2000;
1215 } 1232 }
1216 hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data); 1233 hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data);
1217 } 1234 }
@@ -1299,21 +1316,18 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr)
1299 1316
1300 pllenb = 0xB; 1317 pllenb = 0xB;
1301 hw_write_20kx(hw, PLL_ENB, pllenb); 1318 hw_write_20kx(hw, PLL_ENB, pllenb);
1302 pllctl = 0x20D00000; 1319 pllctl = 0x20C00000;
1303 set_field(&pllctl, PLLCTL_FD, 16 - 4); 1320 set_field(&pllctl, PLLCTL_B, 0);
1321 set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 4 : 147 - 4);
1322 set_field(&pllctl, PLLCTL_RD, 48000 == rsr ? 1 - 1 : 10 - 1);
1304 hw_write_20kx(hw, PLL_CTL, pllctl); 1323 hw_write_20kx(hw, PLL_CTL, pllctl);
1305 mdelay(40); 1324 mdelay(40);
1325
1306 pllctl = hw_read_20kx(hw, PLL_CTL); 1326 pllctl = hw_read_20kx(hw, PLL_CTL);
1307 set_field(&pllctl, PLLCTL_B, 0); 1327 set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 2 : 147 - 2);
1308 if (48000 == rsr) {
1309 set_field(&pllctl, PLLCTL_FD, 16 - 2);
1310 set_field(&pllctl, PLLCTL_RD, 1 - 1); /* 3000*16/1 = 48000 */
1311 } else { /* 44100 */
1312 set_field(&pllctl, PLLCTL_FD, 147 - 2);
1313 set_field(&pllctl, PLLCTL_RD, 10 - 1); /* 3000*147/10 = 44100 */
1314 }
1315 hw_write_20kx(hw, PLL_CTL, pllctl); 1328 hw_write_20kx(hw, PLL_CTL, pllctl);
1316 mdelay(40); 1329 mdelay(40);
1330
1317 for (i = 0; i < 1000; i++) { 1331 for (i = 0; i < 1000; i++) {
1318 pllstat = hw_read_20kx(hw, PLL_STAT); 1332 pllstat = hw_read_20kx(hw, PLL_STAT);
1319 if (get_field(pllstat, PLLSTAT_PD)) 1333 if (get_field(pllstat, PLLSTAT_PD))
@@ -1557,7 +1571,7 @@ static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)
1557 1571
1558 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status); 1572 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
1559 hw20k2_i2c_wait_data_ready(hw); 1573 hw20k2_i2c_wait_data_ready(hw);
1560 /* Dummy write to trigger the write oprtation */ 1574 /* Dummy write to trigger the write operation */
1561 hw_write_20kx(hw, I2C_IF_WDATA, 0); 1575 hw_write_20kx(hw, I2C_IF_WDATA, 0);
1562 hw20k2_i2c_wait_data_ready(hw); 1576 hw20k2_i2c_wait_data_ready(hw);
1563 1577
@@ -1568,6 +1582,30 @@ static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)
1568 return 0; 1582 return 0;
1569} 1583}
1570 1584
1585static void hw_dac_stop(struct hw *hw)
1586{
1587 u32 data;
1588 data = hw_read_20kx(hw, GPIO_DATA);
1589 data &= 0xFFFFFFFD;
1590 hw_write_20kx(hw, GPIO_DATA, data);
1591 mdelay(10);
1592}
1593
1594static void hw_dac_start(struct hw *hw)
1595{
1596 u32 data;
1597 data = hw_read_20kx(hw, GPIO_DATA);
1598 data |= 0x2;
1599 hw_write_20kx(hw, GPIO_DATA, data);
1600 mdelay(50);
1601}
1602
1603static void hw_dac_reset(struct hw *hw)
1604{
1605 hw_dac_stop(hw);
1606 hw_dac_start(hw);
1607}
1608
1571static int hw_dac_init(struct hw *hw, const struct dac_conf *info) 1609static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
1572{ 1610{
1573 int err; 1611 int err;
@@ -1594,6 +1632,21 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
1594 0x00000000 /* Vol Control B4 */ 1632 0x00000000 /* Vol Control B4 */
1595 }; 1633 };
1596 1634
1635 if (hw->model == CTSB1270) {
1636 hw_dac_stop(hw);
1637 data = hw_read_20kx(hw, GPIO_DATA);
1638 data &= ~0x0600;
1639 if (1 == info->msr)
1640 data |= 0x0000; /* Single Speed Mode 0-50kHz */
1641 else if (2 == info->msr)
1642 data |= 0x0200; /* Double Speed Mode 50-100kHz */
1643 else
1644 data |= 0x0600; /* Quad Speed Mode 100-200kHz */
1645 hw_write_20kx(hw, GPIO_DATA, data);
1646 hw_dac_start(hw);
1647 return 0;
1648 }
1649
1597 /* Set DAC reset bit as output */ 1650 /* Set DAC reset bit as output */
1598 data = hw_read_20kx(hw, GPIO_CTRL); 1651 data = hw_read_20kx(hw, GPIO_CTRL);
1599 data |= 0x02; 1652 data |= 0x02;
@@ -1606,22 +1659,8 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
1606 for (i = 0; i < 2; i++) { 1659 for (i = 0; i < 2; i++) {
1607 /* Reset DAC twice just in-case the chip 1660 /* Reset DAC twice just in-case the chip
1608 * didn't initialized properly */ 1661 * didn't initialized properly */
1609 data = hw_read_20kx(hw, GPIO_DATA); 1662 hw_dac_reset(hw);
1610 /* GPIO data bit 1 */ 1663 hw_dac_reset(hw);
1611 data &= 0xFFFFFFFD;
1612 hw_write_20kx(hw, GPIO_DATA, data);
1613 mdelay(10);
1614 data |= 0x2;
1615 hw_write_20kx(hw, GPIO_DATA, data);
1616 mdelay(50);
1617
1618 /* Reset the 2nd time */
1619 data &= 0xFFFFFFFD;
1620 hw_write_20kx(hw, GPIO_DATA, data);
1621 mdelay(10);
1622 data |= 0x2;
1623 hw_write_20kx(hw, GPIO_DATA, data);
1624 mdelay(50);
1625 1664
1626 if (hw20k2_i2c_read(hw, CS4382_MC1, &cs_read.mode_control_1)) 1665 if (hw20k2_i2c_read(hw, CS4382_MC1, &cs_read.mode_control_1))
1627 continue; 1666 continue;
@@ -1725,7 +1764,11 @@ End:
1725static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type) 1764static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
1726{ 1765{
1727 u32 data; 1766 u32 data;
1728 1767 if (hw->model == CTSB1270) {
1768 /* Titanium HD has two ADC chips, one for line in and one */
1769 /* for MIC. We don't need to switch the ADC input. */
1770 return 1;
1771 }
1729 data = hw_read_20kx(hw, GPIO_DATA); 1772 data = hw_read_20kx(hw, GPIO_DATA);
1730 switch (type) { 1773 switch (type) {
1731 case ADC_MICIN: 1774 case ADC_MICIN:
@@ -1742,35 +1785,47 @@ static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
1742 1785
1743#define MIC_BOOST_0DB 0xCF 1786#define MIC_BOOST_0DB 0xCF
1744#define MIC_BOOST_STEPS_PER_DB 2 1787#define MIC_BOOST_STEPS_PER_DB 2
1745#define MIC_BOOST_20DB (MIC_BOOST_0DB + 20 * MIC_BOOST_STEPS_PER_DB) 1788
1789static void hw_wm8775_input_select(struct hw *hw, u8 input, s8 gain_in_db)
1790{
1791 u32 adcmc, gain;
1792
1793 if (input > 3)
1794 input = 3;
1795
1796 adcmc = ((u32)1 << input) | 0x100; /* Link L+R gain... */
1797
1798 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, adcmc),
1799 MAKE_WM8775_DATA(adcmc));
1800
1801 if (gain_in_db < -103)
1802 gain_in_db = -103;
1803 if (gain_in_db > 24)
1804 gain_in_db = 24;
1805
1806 gain = gain_in_db * MIC_BOOST_STEPS_PER_DB + MIC_BOOST_0DB;
1807
1808 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, gain),
1809 MAKE_WM8775_DATA(gain));
1810 /* ...so there should be no need for the following. */
1811 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, gain),
1812 MAKE_WM8775_DATA(gain));
1813}
1746 1814
1747static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) 1815static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
1748{ 1816{
1749 u32 data; 1817 u32 data;
1750
1751 data = hw_read_20kx(hw, GPIO_DATA); 1818 data = hw_read_20kx(hw, GPIO_DATA);
1752 switch (type) { 1819 switch (type) {
1753 case ADC_MICIN: 1820 case ADC_MICIN:
1754 data |= (0x1 << 14); 1821 data |= (0x1 << 14);
1755 hw_write_20kx(hw, GPIO_DATA, data); 1822 hw_write_20kx(hw, GPIO_DATA, data);
1756 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101), 1823 hw_wm8775_input_select(hw, 0, 20); /* Mic, 20dB */
1757 MAKE_WM8775_DATA(0x101)); /* Mic-in */
1758 hw20k2_i2c_write(hw,
1759 MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
1760 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1761 hw20k2_i2c_write(hw,
1762 MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
1763 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1764 break; 1824 break;
1765 case ADC_LINEIN: 1825 case ADC_LINEIN:
1766 data &= ~(0x1 << 14); 1826 data &= ~(0x1 << 14);
1767 hw_write_20kx(hw, GPIO_DATA, data); 1827 hw_write_20kx(hw, GPIO_DATA, data);
1768 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102), 1828 hw_wm8775_input_select(hw, 1, 0); /* Line-in, 0dB */
1769 MAKE_WM8775_DATA(0x102)); /* Line-in */
1770 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
1771 MAKE_WM8775_DATA(0xCF)); /* No boost */
1772 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
1773 MAKE_WM8775_DATA(0xCF)); /* No boost */
1774 break; 1829 break;
1775 default: 1830 default:
1776 break; 1831 break;
@@ -1782,7 +1837,7 @@ static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
1782static int hw_adc_init(struct hw *hw, const struct adc_conf *info) 1837static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
1783{ 1838{
1784 int err; 1839 int err;
1785 u32 mux = 2, data, ctl; 1840 u32 data, ctl;
1786 1841
1787 /* Set ADC reset bit as output */ 1842 /* Set ADC reset bit as output */
1788 data = hw_read_20kx(hw, GPIO_CTRL); 1843 data = hw_read_20kx(hw, GPIO_CTRL);
@@ -1796,19 +1851,42 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
1796 goto error; 1851 goto error;
1797 } 1852 }
1798 1853
1799 /* Make ADC in normal operation */ 1854 /* Reset the ADC (reset is active low). */
1800 data = hw_read_20kx(hw, GPIO_DATA); 1855 data = hw_read_20kx(hw, GPIO_DATA);
1801 data &= ~(0x1 << 15); 1856 data &= ~(0x1 << 15);
1857 hw_write_20kx(hw, GPIO_DATA, data);
1858
1859 if (hw->model == CTSB1270) {
1860 /* Set up the PCM4220 ADC on Titanium HD */
1861 data &= ~0x0C;
1862 if (1 == info->msr)
1863 data |= 0x00; /* Single Speed Mode 32-50kHz */
1864 else if (2 == info->msr)
1865 data |= 0x08; /* Double Speed Mode 50-108kHz */
1866 else
1867 data |= 0x04; /* Quad Speed Mode 108kHz-216kHz */
1868 hw_write_20kx(hw, GPIO_DATA, data);
1869 }
1870
1802 mdelay(10); 1871 mdelay(10);
1872 /* Return the ADC to normal operation. */
1803 data |= (0x1 << 15); 1873 data |= (0x1 << 15);
1804 hw_write_20kx(hw, GPIO_DATA, data); 1874 hw_write_20kx(hw, GPIO_DATA, data);
1805 mdelay(50); 1875 mdelay(50);
1806 1876
1877 /* I2C write to register offset 0x0B to set ADC LRCLK polarity */
1878 /* invert bit, interface format to I2S, word length to 24-bit, */
1879 /* enable ADC high pass filter. Fixes bug 5323? */
1880 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_IC, 0x26),
1881 MAKE_WM8775_DATA(0x26));
1882
1807 /* Set the master mode (256fs) */ 1883 /* Set the master mode (256fs) */
1808 if (1 == info->msr) { 1884 if (1 == info->msr) {
1885 /* slave mode, 128x oversampling 256fs */
1809 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02), 1886 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02),
1810 MAKE_WM8775_DATA(0x02)); 1887 MAKE_WM8775_DATA(0x02));
1811 } else if (2 == info->msr) { 1888 } else if ((2 == info->msr) || (4 == info->msr)) {
1889 /* slave mode, 64x oversampling, 256fs */
1812 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A), 1890 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A),
1813 MAKE_WM8775_DATA(0x0A)); 1891 MAKE_WM8775_DATA(0x0A));
1814 } else { 1892 } else {
@@ -1818,55 +1896,113 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
1818 goto error; 1896 goto error;
1819 } 1897 }
1820 1898
1821 /* Configure GPIO bit 14 change to line-in/mic-in */ 1899 if (hw->model != CTSB1270) {
1822 ctl = hw_read_20kx(hw, GPIO_CTRL); 1900 /* Configure GPIO bit 14 change to line-in/mic-in */
1823 ctl |= 0x1 << 14; 1901 ctl = hw_read_20kx(hw, GPIO_CTRL);
1824 hw_write_20kx(hw, GPIO_CTRL, ctl); 1902 ctl |= 0x1 << 14;
1825 1903 hw_write_20kx(hw, GPIO_CTRL, ctl);
1826 /* Check using Mic-in or Line-in */ 1904 hw_adc_input_select(hw, ADC_LINEIN);
1827 data = hw_read_20kx(hw, GPIO_DATA);
1828
1829 if (mux == 1) {
1830 /* Configures GPIO data to select Mic-in */
1831 data |= 0x1 << 14;
1832 hw_write_20kx(hw, GPIO_DATA, data);
1833
1834 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
1835 MAKE_WM8775_DATA(0x101)); /* Mic-in */
1836 hw20k2_i2c_write(hw,
1837 MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
1838 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1839 hw20k2_i2c_write(hw,
1840 MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
1841 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1842 } else if (mux == 2) {
1843 /* Configures GPIO data to select Line-in */
1844 data &= ~(0x1 << 14);
1845 hw_write_20kx(hw, GPIO_DATA, data);
1846
1847 /* Setup ADC */
1848 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102),
1849 MAKE_WM8775_DATA(0x102)); /* Line-in */
1850 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
1851 MAKE_WM8775_DATA(0xCF)); /* No boost */
1852 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
1853 MAKE_WM8775_DATA(0xCF)); /* No boost */
1854 } else { 1905 } else {
1855 printk(KERN_ALERT "ctxfi: ERROR!!! Invalid input mux!!!\n"); 1906 hw_wm8775_input_select(hw, 0, 0);
1856 err = -EINVAL;
1857 goto error;
1858 } 1907 }
1859 1908
1860 return 0; 1909 return 0;
1861
1862error: 1910error:
1863 hw20k2_i2c_uninit(hw); 1911 hw20k2_i2c_uninit(hw);
1864 return err; 1912 return err;
1865} 1913}
1866 1914
1867static int hw_have_digit_io_switch(struct hw *hw) 1915static struct capabilities hw_capabilities(struct hw *hw)
1868{ 1916{
1869 return 0; 1917 struct capabilities cap;
1918
1919 cap.digit_io_switch = 0;
1920 cap.dedicated_mic = hw->model == CTSB1270;
1921 cap.output_switch = hw->model == CTSB1270;
1922 cap.mic_source_switch = hw->model == CTSB1270;
1923
1924 return cap;
1925}
1926
1927static int hw_output_switch_get(struct hw *hw)
1928{
1929 u32 data = hw_read_20kx(hw, GPIO_EXT_DATA);
1930
1931 switch (data & 0x30) {
1932 case 0x00:
1933 return 0;
1934 case 0x10:
1935 return 1;
1936 case 0x20:
1937 return 2;
1938 default:
1939 return 3;
1940 }
1941}
1942
1943static int hw_output_switch_put(struct hw *hw, int position)
1944{
1945 u32 data;
1946
1947 if (position == hw_output_switch_get(hw))
1948 return 0;
1949
1950 /* Mute line and headphones (intended for anti-pop). */
1951 data = hw_read_20kx(hw, GPIO_DATA);
1952 data |= (0x03 << 11);
1953 hw_write_20kx(hw, GPIO_DATA, data);
1954
1955 data = hw_read_20kx(hw, GPIO_EXT_DATA) & ~0x30;
1956 switch (position) {
1957 case 0:
1958 break;
1959 case 1:
1960 data |= 0x10;
1961 break;
1962 default:
1963 data |= 0x20;
1964 }
1965 hw_write_20kx(hw, GPIO_EXT_DATA, data);
1966
1967 /* Unmute line and headphones. */
1968 data = hw_read_20kx(hw, GPIO_DATA);
1969 data &= ~(0x03 << 11);
1970 hw_write_20kx(hw, GPIO_DATA, data);
1971
1972 return 1;
1973}
1974
1975static int hw_mic_source_switch_get(struct hw *hw)
1976{
1977 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
1978
1979 return hw20k2->mic_source;
1980}
1981
1982static int hw_mic_source_switch_put(struct hw *hw, int position)
1983{
1984 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
1985
1986 if (position == hw20k2->mic_source)
1987 return 0;
1988
1989 switch (position) {
1990 case 0:
1991 hw_wm8775_input_select(hw, 0, 0); /* Mic, 0dB */
1992 break;
1993 case 1:
1994 hw_wm8775_input_select(hw, 1, 0); /* FP Mic, 0dB */
1995 break;
1996 case 2:
1997 hw_wm8775_input_select(hw, 3, 0); /* Aux Ext, 0dB */
1998 break;
1999 default:
2000 return 0;
2001 }
2002
2003 hw20k2->mic_source = position;
2004
2005 return 1;
1870} 2006}
1871 2007
1872static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id) 2008static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id)
@@ -1925,7 +2061,7 @@ static int hw_card_start(struct hw *hw)
1925 2061
1926 if (hw->irq < 0) { 2062 if (hw->irq < 0) {
1927 err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED, 2063 err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,
1928 "ctxfi", hw); 2064 KBUILD_MODNAME, hw);
1929 if (err < 0) { 2065 if (err < 0) {
1930 printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq); 2066 printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
1931 goto error2; 2067 goto error2;
@@ -2023,13 +2159,16 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
2023 /* Reset all SRC pending interrupts */ 2159 /* Reset all SRC pending interrupts */
2024 hw_write_20kx(hw, SRC_IP, 0); 2160 hw_write_20kx(hw, SRC_IP, 0);
2025 2161
2026 /* TODO: detect the card ID and configure GPIO accordingly. */ 2162 if (hw->model != CTSB1270) {
2027 /* Configures GPIO (0xD802 0x98028) */ 2163 /* TODO: detect the card ID and configure GPIO accordingly. */
2028 /*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/ 2164 /* Configures GPIO (0xD802 0x98028) */
2029 /* Configures GPIO (SB0880) */ 2165 /*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/
2030 /*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/ 2166 /* Configures GPIO (SB0880) */
2031 hw_write_20kx(hw, GPIO_CTRL, 0xD802); 2167 /*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/
2032 2168 hw_write_20kx(hw, GPIO_CTRL, 0xD802);
2169 } else {
2170 hw_write_20kx(hw, GPIO_CTRL, 0x9E5F);
2171 }
2033 /* Enable audio ring */ 2172 /* Enable audio ring */
2034 hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01); 2173 hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01);
2035 2174
@@ -2106,7 +2245,11 @@ static struct hw ct20k2_preset __devinitdata = {
2106 .pll_init = hw_pll_init, 2245 .pll_init = hw_pll_init,
2107 .is_adc_source_selected = hw_is_adc_input_selected, 2246 .is_adc_source_selected = hw_is_adc_input_selected,
2108 .select_adc_source = hw_adc_input_select, 2247 .select_adc_source = hw_adc_input_select,
2109 .have_digit_io_switch = hw_have_digit_io_switch, 2248 .capabilities = hw_capabilities,
2249 .output_switch_get = hw_output_switch_get,
2250 .output_switch_put = hw_output_switch_put,
2251 .mic_source_switch_get = hw_mic_source_switch_get,
2252 .mic_source_switch_put = hw_mic_source_switch_put,
2110#ifdef CONFIG_PM 2253#ifdef CONFIG_PM
2111 .suspend = hw_suspend, 2254 .suspend = hw_suspend,
2112 .resume = hw_resume, 2255 .resume = hw_resume,
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c
index c3519ff42fb..0cc13eeef8d 100644
--- a/sound/pci/ctxfi/ctmixer.c
+++ b/sound/pci/ctxfi/ctmixer.c
@@ -86,9 +86,7 @@ enum CTALSA_MIXER_CTL {
86 MIXER_LINEIN_C_S, 86 MIXER_LINEIN_C_S,
87 MIXER_MIC_C_S, 87 MIXER_MIC_C_S,
88 MIXER_SPDIFI_C_S, 88 MIXER_SPDIFI_C_S,
89 MIXER_LINEIN_P_S,
90 MIXER_SPDIFO_P_S, 89 MIXER_SPDIFO_P_S,
91 MIXER_SPDIFI_P_S,
92 MIXER_WAVEF_P_S, 90 MIXER_WAVEF_P_S,
93 MIXER_WAVER_P_S, 91 MIXER_WAVER_P_S,
94 MIXER_WAVEC_P_S, 92 MIXER_WAVEC_P_S,
@@ -137,11 +135,11 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
137 }, 135 },
138 [MIXER_LINEIN_P] = { 136 [MIXER_LINEIN_P] = {
139 .ctl = 1, 137 .ctl = 1,
140 .name = "Line-in Playback Volume", 138 .name = "Line Playback Volume",
141 }, 139 },
142 [MIXER_LINEIN_C] = { 140 [MIXER_LINEIN_C] = {
143 .ctl = 1, 141 .ctl = 1,
144 .name = "Line-in Capture Volume", 142 .name = "Line Capture Volume",
145 }, 143 },
146 [MIXER_MIC_P] = { 144 [MIXER_MIC_P] = {
147 .ctl = 1, 145 .ctl = 1,
@@ -153,15 +151,15 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
153 }, 151 },
154 [MIXER_SPDIFI_P] = { 152 [MIXER_SPDIFI_P] = {
155 .ctl = 1, 153 .ctl = 1,
156 .name = "S/PDIF-in Playback Volume", 154 .name = "IEC958 Playback Volume",
157 }, 155 },
158 [MIXER_SPDIFI_C] = { 156 [MIXER_SPDIFI_C] = {
159 .ctl = 1, 157 .ctl = 1,
160 .name = "S/PDIF-in Capture Volume", 158 .name = "IEC958 Capture Volume",
161 }, 159 },
162 [MIXER_SPDIFO_P] = { 160 [MIXER_SPDIFO_P] = {
163 .ctl = 1, 161 .ctl = 1,
164 .name = "S/PDIF-out Playback Volume", 162 .name = "Digital Playback Volume",
165 }, 163 },
166 [MIXER_WAVEF_P] = { 164 [MIXER_WAVEF_P] = {
167 .ctl = 1, 165 .ctl = 1,
@@ -179,14 +177,13 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
179 .ctl = 1, 177 .ctl = 1,
180 .name = "Surround Playback Volume", 178 .name = "Surround Playback Volume",
181 }, 179 },
182
183 [MIXER_PCM_C_S] = { 180 [MIXER_PCM_C_S] = {
184 .ctl = 1, 181 .ctl = 1,
185 .name = "PCM Capture Switch", 182 .name = "PCM Capture Switch",
186 }, 183 },
187 [MIXER_LINEIN_C_S] = { 184 [MIXER_LINEIN_C_S] = {
188 .ctl = 1, 185 .ctl = 1,
189 .name = "Line-in Capture Switch", 186 .name = "Line Capture Switch",
190 }, 187 },
191 [MIXER_MIC_C_S] = { 188 [MIXER_MIC_C_S] = {
192 .ctl = 1, 189 .ctl = 1,
@@ -194,19 +191,11 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
194 }, 191 },
195 [MIXER_SPDIFI_C_S] = { 192 [MIXER_SPDIFI_C_S] = {
196 .ctl = 1, 193 .ctl = 1,
197 .name = "S/PDIF-in Capture Switch", 194 .name = "IEC958 Capture Switch",
198 },
199 [MIXER_LINEIN_P_S] = {
200 .ctl = 1,
201 .name = "Line-in Playback Switch",
202 }, 195 },
203 [MIXER_SPDIFO_P_S] = { 196 [MIXER_SPDIFO_P_S] = {
204 .ctl = 1, 197 .ctl = 1,
205 .name = "S/PDIF-out Playback Switch", 198 .name = "Digital Playback Switch",
206 },
207 [MIXER_SPDIFI_P_S] = {
208 .ctl = 1,
209 .name = "S/PDIF-in Playback Switch",
210 }, 199 },
211 [MIXER_WAVEF_P_S] = { 200 [MIXER_WAVEF_P_S] = {
212 .ctl = 1, 201 .ctl = 1,
@@ -236,6 +225,8 @@ ct_mixer_recording_select(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
236static void 225static void
237ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type); 226ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
238 227
228/* FIXME: this static looks like it would fail if more than one card was */
229/* installed. */
239static struct snd_kcontrol *kctls[2] = {NULL}; 230static struct snd_kcontrol *kctls[2] = {NULL};
240 231
241static enum CT_AMIXER_CTL get_amixer_index(enum CTALSA_MIXER_CTL alsa_index) 232static enum CT_AMIXER_CTL get_amixer_index(enum CTALSA_MIXER_CTL alsa_index)
@@ -420,6 +411,77 @@ static struct snd_kcontrol_new vol_ctl = {
420 .tlv = { .p = ct_vol_db_scale }, 411 .tlv = { .p = ct_vol_db_scale },
421}; 412};
422 413
414static int output_switch_info(struct snd_kcontrol *kcontrol,
415 struct snd_ctl_elem_info *info)
416{
417 static const char *const names[3] = {
418 "FP Headphones", "Headphones", "Speakers"
419 };
420
421 return snd_ctl_enum_info(info, 1, 3, names);
422}
423
424static int output_switch_get(struct snd_kcontrol *kcontrol,
425 struct snd_ctl_elem_value *ucontrol)
426{
427 struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
428 ucontrol->value.enumerated.item[0] = atc->output_switch_get(atc);
429 return 0;
430}
431
432static int output_switch_put(struct snd_kcontrol *kcontrol,
433 struct snd_ctl_elem_value *ucontrol)
434{
435 struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
436 if (ucontrol->value.enumerated.item[0] > 2)
437 return -EINVAL;
438 return atc->output_switch_put(atc, ucontrol->value.enumerated.item[0]);
439}
440
441static struct snd_kcontrol_new output_ctl = {
442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
443 .name = "Analog Output Playback Enum",
444 .info = output_switch_info,
445 .get = output_switch_get,
446 .put = output_switch_put,
447};
448
449static int mic_source_switch_info(struct snd_kcontrol *kcontrol,
450 struct snd_ctl_elem_info *info)
451{
452 static const char *const names[3] = {
453 "Mic", "FP Mic", "Aux"
454 };
455
456 return snd_ctl_enum_info(info, 1, 3, names);
457}
458
459static int mic_source_switch_get(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_value *ucontrol)
461{
462 struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
463 ucontrol->value.enumerated.item[0] = atc->mic_source_switch_get(atc);
464 return 0;
465}
466
467static int mic_source_switch_put(struct snd_kcontrol *kcontrol,
468 struct snd_ctl_elem_value *ucontrol)
469{
470 struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
471 if (ucontrol->value.enumerated.item[0] > 2)
472 return -EINVAL;
473 return atc->mic_source_switch_put(atc,
474 ucontrol->value.enumerated.item[0]);
475}
476
477static struct snd_kcontrol_new mic_source_ctl = {
478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
479 .name = "Mic Source Capture Enum",
480 .info = mic_source_switch_info,
481 .get = mic_source_switch_get,
482 .put = mic_source_switch_put,
483};
484
423static void 485static void
424do_line_mic_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type) 486do_line_mic_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type)
425{ 487{
@@ -465,6 +527,7 @@ do_digit_io_switch(struct ct_atc *atc, int state)
465static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state) 527static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
466{ 528{
467 struct ct_mixer *mixer = atc->mixer; 529 struct ct_mixer *mixer = atc->mixer;
530 struct capabilities cap = atc->capabilities(atc);
468 531
469 /* Do changes in mixer. */ 532 /* Do changes in mixer. */
470 if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) { 533 if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
@@ -477,8 +540,17 @@ static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
477 } 540 }
478 } 541 }
479 /* Do changes out of mixer. */ 542 /* Do changes out of mixer. */
480 if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) 543 if (!cap.dedicated_mic &&
481 do_line_mic_switch(atc, type); 544 (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) {
545 if (state)
546 do_line_mic_switch(atc, type);
547 atc->line_in_unmute(atc, state);
548 } else if (cap.dedicated_mic && (MIXER_LINEIN_C_S == type))
549 atc->line_in_unmute(atc, state);
550 else if (cap.dedicated_mic && (MIXER_MIC_C_S == type))
551 atc->mic_unmute(atc, state);
552 else if (MIXER_SPDIFI_C_S == type)
553 atc->spdif_in_unmute(atc, state);
482 else if (MIXER_WAVEF_P_S == type) 554 else if (MIXER_WAVEF_P_S == type)
483 atc->line_front_unmute(atc, state); 555 atc->line_front_unmute(atc, state);
484 else if (MIXER_WAVES_P_S == type) 556 else if (MIXER_WAVES_P_S == type)
@@ -487,12 +559,8 @@ static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
487 atc->line_clfe_unmute(atc, state); 559 atc->line_clfe_unmute(atc, state);
488 else if (MIXER_WAVER_P_S == type) 560 else if (MIXER_WAVER_P_S == type)
489 atc->line_rear_unmute(atc, state); 561 atc->line_rear_unmute(atc, state);
490 else if (MIXER_LINEIN_P_S == type)
491 atc->line_in_unmute(atc, state);
492 else if (MIXER_SPDIFO_P_S == type) 562 else if (MIXER_SPDIFO_P_S == type)
493 atc->spdif_out_unmute(atc, state); 563 atc->spdif_out_unmute(atc, state);
494 else if (MIXER_SPDIFI_P_S == type)
495 atc->spdif_in_unmute(atc, state);
496 else if (MIXER_DIGITAL_IO_S == type) 564 else if (MIXER_DIGITAL_IO_S == type)
497 do_digit_io_switch(atc, state); 565 do_digit_io_switch(atc, state);
498 566
@@ -671,6 +739,7 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
671{ 739{
672 enum CTALSA_MIXER_CTL type; 740 enum CTALSA_MIXER_CTL type;
673 struct ct_atc *atc = mixer->atc; 741 struct ct_atc *atc = mixer->atc;
742 struct capabilities cap = atc->capabilities(atc);
674 int err; 743 int err;
675 744
676 /* Create snd kcontrol instances on demand */ 745 /* Create snd kcontrol instances on demand */
@@ -684,8 +753,8 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
684 } 753 }
685 } 754 }
686 755
687 ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl = 756 ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl = cap.digit_io_switch;
688 atc->have_digit_io_switch(atc); 757
689 for (type = SWH_MIXER_START; type <= SWH_MIXER_END; type++) { 758 for (type = SWH_MIXER_START; type <= SWH_MIXER_END; type++) {
690 if (ct_kcontrol_init_table[type].ctl) { 759 if (ct_kcontrol_init_table[type].ctl) {
691 swh_ctl.name = ct_kcontrol_init_table[type].name; 760 swh_ctl.name = ct_kcontrol_init_table[type].name;
@@ -708,6 +777,17 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
708 if (err) 777 if (err)
709 return err; 778 return err;
710 779
780 if (cap.output_switch) {
781 err = ct_mixer_kcontrol_new(mixer, &output_ctl);
782 if (err)
783 return err;
784 }
785
786 if (cap.mic_source_switch) {
787 err = ct_mixer_kcontrol_new(mixer, &mic_source_ctl);
788 if (err)
789 return err;
790 }
711 atc->line_front_unmute(atc, 1); 791 atc->line_front_unmute(atc, 1);
712 set_switch_state(mixer, MIXER_WAVEF_P_S, 1); 792 set_switch_state(mixer, MIXER_WAVEF_P_S, 1);
713 atc->line_surround_unmute(atc, 0); 793 atc->line_surround_unmute(atc, 0);
@@ -719,13 +799,12 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
719 atc->spdif_out_unmute(atc, 0); 799 atc->spdif_out_unmute(atc, 0);
720 set_switch_state(mixer, MIXER_SPDIFO_P_S, 0); 800 set_switch_state(mixer, MIXER_SPDIFO_P_S, 0);
721 atc->line_in_unmute(atc, 0); 801 atc->line_in_unmute(atc, 0);
722 set_switch_state(mixer, MIXER_LINEIN_P_S, 0); 802 if (cap.dedicated_mic)
803 atc->mic_unmute(atc, 0);
723 atc->spdif_in_unmute(atc, 0); 804 atc->spdif_in_unmute(atc, 0);
724 set_switch_state(mixer, MIXER_SPDIFI_P_S, 0); 805 set_switch_state(mixer, MIXER_PCM_C_S, 0);
725 806 set_switch_state(mixer, MIXER_LINEIN_C_S, 0);
726 set_switch_state(mixer, MIXER_PCM_C_S, 1); 807 set_switch_state(mixer, MIXER_SPDIFI_C_S, 0);
727 set_switch_state(mixer, MIXER_LINEIN_C_S, 1);
728 set_switch_state(mixer, MIXER_SPDIFI_C_S, 1);
729 808
730 return 0; 809 return 0;
731} 810}
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index f42e7e1a107..b259aa03a3a 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -80,11 +80,11 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
80 "are 48000 and 44100, Value 48000 is assumed.\n"); 80 "are 48000 and 44100, Value 48000 is assumed.\n");
81 reference_rate = 48000; 81 reference_rate = 48000;
82 } 82 }
83 if ((multiple != 1) && (multiple != 2)) { 83 if ((multiple != 1) && (multiple != 2) && (multiple != 4)) {
84 printk(KERN_ERR "ctxfi: Invalid multiple value %u!!!\n", 84 printk(KERN_ERR "ctxfi: Invalid multiple value %u!!!\n",
85 multiple); 85 multiple);
86 printk(KERN_ERR "ctxfi: The valid values for multiple are " 86 printk(KERN_ERR "ctxfi: The valid values for multiple are "
87 "1 and 2, Value 2 is assumed.\n"); 87 "1, 2 and 4, Value 2 is assumed.\n");
88 multiple = 2; 88 multiple = 2;
89 } 89 }
90 err = ct_atc_create(card, pci, reference_rate, multiple, 90 err = ct_atc_create(card, pci, reference_rate, multiple,
@@ -143,7 +143,7 @@ static int ct_card_resume(struct pci_dev *pci)
143#endif 143#endif
144 144
145static struct pci_driver ct_driver = { 145static struct pci_driver ct_driver = {
146 .name = "SB-XFi", 146 .name = KBUILD_MODNAME,
147 .id_table = ct_pci_dev_ids, 147 .id_table = ct_pci_dev_ids,
148 .probe = ct_card_probe, 148 .probe = ct_card_probe,
149 .remove = __devexit_p(ct_card_remove), 149 .remove = __devexit_p(ct_card_remove),
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 20763dd03fa..d7306980d0f 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -1995,7 +1995,7 @@ static __devinit int snd_echo_create(struct snd_card *card,
1995 ioremap_nocache(chip->dsp_registers_phys, sz); 1995 ioremap_nocache(chip->dsp_registers_phys, sz);
1996 1996
1997 if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED, 1997 if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
1998 ECHOCARD_NAME, chip)) { 1998 KBUILD_MODNAME, chip)) {
1999 snd_echo_free(chip); 1999 snd_echo_free(chip);
2000 snd_printk(KERN_ERR "cannot grab irq\n"); 2000 snd_printk(KERN_ERR "cannot grab irq\n");
2001 return -EBUSY; 2001 return -EBUSY;
@@ -2286,7 +2286,7 @@ static int snd_echo_resume(struct pci_dev *pci)
2286 kfree(commpage_bak); 2286 kfree(commpage_bak);
2287 2287
2288 if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED, 2288 if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
2289 ECHOCARD_NAME, chip)) { 2289 KBUILD_MODNAME, chip)) {
2290 snd_echo_free(chip); 2290 snd_echo_free(chip);
2291 snd_printk(KERN_ERR "cannot grab irq\n"); 2291 snd_printk(KERN_ERR "cannot grab irq\n");
2292 return -EBUSY; 2292 return -EBUSY;
@@ -2327,7 +2327,7 @@ static void __devexit snd_echo_remove(struct pci_dev *pci)
2327 2327
2328/* pci_driver definition */ 2328/* pci_driver definition */
2329static struct pci_driver driver = { 2329static struct pci_driver driver = {
2330 .name = "Echoaudio " ECHOCARD_NAME, 2330 .name = KBUILD_MODNAME,
2331 .id_table = snd_echo_ids, 2331 .id_table = snd_echo_ids,
2332 .probe = snd_echo_probe, 2332 .probe = snd_echo_probe,
2333 .remove = __devexit_p(snd_echo_remove), 2333 .remove = __devexit_p(snd_echo_remove),
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index aff8387c45c..a9c45d2cdb1 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -264,7 +264,7 @@ static int snd_emu10k1_resume(struct pci_dev *pci)
264#endif 264#endif
265 265
266static struct pci_driver driver = { 266static struct pci_driver driver = {
267 .name = "EMU10K1_Audigy", 267 .name = KBUILD_MODNAME,
268 .id_table = snd_emu10k1_ids, 268 .id_table = snd_emu10k1_ids,
269 .probe = snd_card_emu10k1_probe, 269 .probe = snd_card_emu10k1_probe,
270 .remove = __devexit_p(snd_card_emu10k1_remove), 270 .remove = __devexit_p(snd_card_emu10k1_remove),
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 5e619a84da0..fcd4935766b 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1440,6 +1440,14 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1440 .ca0102_chip = 1, 1440 .ca0102_chip = 1,
1441 .spk71 = 1, 1441 .spk71 = 1,
1442 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */ 1442 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */
1443 /* EMU0404 PCIe */
1444 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40051102,
1445 .driver = "Audigy2", .name = "E-mu 0404 PCIe [MAEM8984]",
1446 .id = "EMU0404",
1447 .emu10k2_chip = 1,
1448 .ca0108_chip = 1,
1449 .spk71 = 1,
1450 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 PCIe ver_03 */
1443 /* Note that all E-mu cards require kernel 2.6 or newer. */ 1451 /* Note that all E-mu cards require kernel 2.6 or newer. */
1444 {.vendor = 0x1102, .device = 0x0008, 1452 {.vendor = 0x1102, .device = 0x0008,
1445 .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]", 1453 .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]",
@@ -1904,7 +1912,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1904 1912
1905 /* irq handler must be registered after I/O ports are activated */ 1913 /* irq handler must be registered after I/O ports are activated */
1906 if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED, 1914 if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED,
1907 "EMU10K1", emu)) { 1915 KBUILD_MODNAME, emu)) {
1908 err = -EBUSY; 1916 err = -EBUSY;
1909 goto error; 1917 goto error;
1910 } 1918 }
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 0c701e4ec8a..d4fde1b4b09 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -925,7 +925,7 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card,
925 } 925 }
926 926
927 if (request_irq(pci->irq, snd_emu10k1x_interrupt, 927 if (request_irq(pci->irq, snd_emu10k1x_interrupt,
928 IRQF_SHARED, "EMU10K1X", chip)) { 928 IRQF_SHARED, KBUILD_MODNAME, chip)) {
929 snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq); 929 snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq);
930 snd_emu10k1x_free(chip); 930 snd_emu10k1x_free(chip);
931 return -EBUSY; 931 return -EBUSY;
@@ -1613,7 +1613,7 @@ MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
1613 1613
1614// pci_driver definition 1614// pci_driver definition
1615static struct pci_driver driver = { 1615static struct pci_driver driver = {
1616 .name = "EMU10K1X", 1616 .name = KBUILD_MODNAME,
1617 .id_table = snd_emu10k1x_ids, 1617 .id_table = snd_emu10k1x_ids,
1618 .probe = snd_emu10k1x_probe, 1618 .probe = snd_emu10k1x_probe,
1619 .remove = __devexit_p(snd_emu10k1x_remove), 1619 .remove = __devexit_p(snd_emu10k1x_remove),
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 863eafea691..f02e2f8d712 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -2120,7 +2120,7 @@ static int __devinit snd_ensoniq_create(struct snd_card *card,
2120 } 2120 }
2121 ensoniq->port = pci_resource_start(pci, 0); 2121 ensoniq->port = pci_resource_start(pci, 0);
2122 if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_SHARED, 2122 if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_SHARED,
2123 "Ensoniq AudioPCI", ensoniq)) { 2123 KBUILD_MODNAME, ensoniq)) {
2124 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 2124 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2125 snd_ensoniq_free(ensoniq); 2125 snd_ensoniq_free(ensoniq);
2126 return -EBUSY; 2126 return -EBUSY;
@@ -2489,7 +2489,7 @@ static void __devexit snd_audiopci_remove(struct pci_dev *pci)
2489} 2489}
2490 2490
2491static struct pci_driver driver = { 2491static struct pci_driver driver = {
2492 .name = DRIVER_NAME, 2492 .name = KBUILD_MODNAME,
2493 .id_table = snd_audiopci_ids, 2493 .id_table = snd_audiopci_ids,
2494 .probe = snd_audiopci_probe, 2494 .probe = snd_audiopci_probe,
2495 .remove = __devexit_p(snd_audiopci_remove), 2495 .remove = __devexit_p(snd_audiopci_remove),
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 553b7521725..26a5a2f25d4 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1514,7 +1514,7 @@ static int es1938_resume(struct pci_dev *pci)
1514 } 1514 }
1515 1515
1516 if (request_irq(pci->irq, snd_es1938_interrupt, 1516 if (request_irq(pci->irq, snd_es1938_interrupt,
1517 IRQF_SHARED, "ES1938", chip)) { 1517 IRQF_SHARED, KBUILD_MODNAME, chip)) {
1518 printk(KERN_ERR "es1938: unable to grab IRQ %d, " 1518 printk(KERN_ERR "es1938: unable to grab IRQ %d, "
1519 "disabling device\n", pci->irq); 1519 "disabling device\n", pci->irq);
1520 snd_card_disconnect(card); 1520 snd_card_disconnect(card);
@@ -1636,7 +1636,7 @@ static int __devinit snd_es1938_create(struct snd_card *card,
1636 chip->mpu_port = pci_resource_start(pci, 3); 1636 chip->mpu_port = pci_resource_start(pci, 3);
1637 chip->game_port = pci_resource_start(pci, 4); 1637 chip->game_port = pci_resource_start(pci, 4);
1638 if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_SHARED, 1638 if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_SHARED,
1639 "ES1938", chip)) { 1639 KBUILD_MODNAME, chip)) {
1640 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1640 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1641 snd_es1938_free(chip); 1641 snd_es1938_free(chip);
1642 return -EBUSY; 1642 return -EBUSY;
@@ -1882,7 +1882,7 @@ static void __devexit snd_es1938_remove(struct pci_dev *pci)
1882} 1882}
1883 1883
1884static struct pci_driver driver = { 1884static struct pci_driver driver = {
1885 .name = "ESS ES1938 (Solo-1)", 1885 .name = KBUILD_MODNAME,
1886 .id_table = snd_es1938_ids, 1886 .id_table = snd_es1938_ids,
1887 .probe = snd_es1938_probe, 1887 .probe = snd_es1938_probe,
1888 .remove = __devexit_p(snd_es1938_remove), 1888 .remove = __devexit_p(snd_es1938_remove),
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index ab0a6156a70..99ea9320c6b 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -554,9 +554,8 @@ struct es1968 {
554#else 554#else
555 struct snd_kcontrol *master_switch; /* for h/w volume control */ 555 struct snd_kcontrol *master_switch; /* for h/w volume control */
556 struct snd_kcontrol *master_volume; 556 struct snd_kcontrol *master_volume;
557 spinlock_t ac97_lock;
558 struct tasklet_struct hwvol_tq;
559#endif 557#endif
558 struct work_struct hwvol_work;
560 559
561#ifdef CONFIG_SND_ES1968_RADIO 560#ifdef CONFIG_SND_ES1968_RADIO
562 struct snd_tea575x tea; 561 struct snd_tea575x tea;
@@ -646,38 +645,23 @@ static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
646static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) 645static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
647{ 646{
648 struct es1968 *chip = ac97->private_data; 647 struct es1968 *chip = ac97->private_data;
649#ifndef CONFIG_SND_ES1968_INPUT
650 unsigned long flags;
651#endif
652 648
653 snd_es1968_ac97_wait(chip); 649 snd_es1968_ac97_wait(chip);
654 650
655 /* Write the bus */ 651 /* Write the bus */
656#ifndef CONFIG_SND_ES1968_INPUT
657 spin_lock_irqsave(&chip->ac97_lock, flags);
658#endif
659 outw(val, chip->io_port + ESM_AC97_DATA); 652 outw(val, chip->io_port + ESM_AC97_DATA);
660 /*msleep(1);*/ 653 /*msleep(1);*/
661 outb(reg, chip->io_port + ESM_AC97_INDEX); 654 outb(reg, chip->io_port + ESM_AC97_INDEX);
662 /*msleep(1);*/ 655 /*msleep(1);*/
663#ifndef CONFIG_SND_ES1968_INPUT
664 spin_unlock_irqrestore(&chip->ac97_lock, flags);
665#endif
666} 656}
667 657
668static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 658static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
669{ 659{
670 u16 data = 0; 660 u16 data = 0;
671 struct es1968 *chip = ac97->private_data; 661 struct es1968 *chip = ac97->private_data;
672#ifndef CONFIG_SND_ES1968_INPUT
673 unsigned long flags;
674#endif
675 662
676 snd_es1968_ac97_wait(chip); 663 snd_es1968_ac97_wait(chip);
677 664
678#ifndef CONFIG_SND_ES1968_INPUT
679 spin_lock_irqsave(&chip->ac97_lock, flags);
680#endif
681 outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX); 665 outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
682 /*msleep(1);*/ 666 /*msleep(1);*/
683 667
@@ -685,9 +669,6 @@ static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short
685 data = inw(chip->io_port + ESM_AC97_DATA); 669 data = inw(chip->io_port + ESM_AC97_DATA);
686 /*msleep(1);*/ 670 /*msleep(1);*/
687 } 671 }
688#ifndef CONFIG_SND_ES1968_INPUT
689 spin_unlock_irqrestore(&chip->ac97_lock, flags);
690#endif
691 672
692 return data; 673 return data;
693} 674}
@@ -1904,13 +1885,10 @@ static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es)
1904 (without wrap around) in response to volume button presses and then 1885 (without wrap around) in response to volume button presses and then
1905 generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7 1886 generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
1906 of a byte wide register. The meaning of bits 0 and 4 is unknown. */ 1887 of a byte wide register. The meaning of bits 0 and 4 is unknown. */
1907static void es1968_update_hw_volume(unsigned long private_data) 1888static void es1968_update_hw_volume(struct work_struct *work)
1908{ 1889{
1909 struct es1968 *chip = (struct es1968 *) private_data; 1890 struct es1968 *chip = container_of(work, struct es1968, hwvol_work);
1910 int x, val; 1891 int x, val;
1911#ifndef CONFIG_SND_ES1968_INPUT
1912 unsigned long flags;
1913#endif
1914 1892
1915 /* Figure out which volume control button was pushed, 1893 /* Figure out which volume control button was pushed,
1916 based on differences from the default register 1894 based on differences from the default register
@@ -1929,18 +1907,11 @@ static void es1968_update_hw_volume(unsigned long private_data)
1929 if (! chip->master_switch || ! chip->master_volume) 1907 if (! chip->master_switch || ! chip->master_volume)
1930 return; 1908 return;
1931 1909
1932 /* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */ 1910 val = snd_ac97_read(chip->ac97, AC97_MASTER);
1933 spin_lock_irqsave(&chip->ac97_lock, flags);
1934 val = chip->ac97->regs[AC97_MASTER];
1935 switch (x) { 1911 switch (x) {
1936 case 0x88: 1912 case 0x88:
1937 /* mute */ 1913 /* mute */
1938 val ^= 0x8000; 1914 val ^= 0x8000;
1939 chip->ac97->regs[AC97_MASTER] = val;
1940 outw(val, chip->io_port + ESM_AC97_DATA);
1941 outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
1942 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1943 &chip->master_switch->id);
1944 break; 1915 break;
1945 case 0xaa: 1916 case 0xaa:
1946 /* volume up */ 1917 /* volume up */
@@ -1948,11 +1919,6 @@ static void es1968_update_hw_volume(unsigned long private_data)
1948 val--; 1919 val--;
1949 if ((val & 0x7f00) > 0) 1920 if ((val & 0x7f00) > 0)
1950 val -= 0x0100; 1921 val -= 0x0100;
1951 chip->ac97->regs[AC97_MASTER] = val;
1952 outw(val, chip->io_port + ESM_AC97_DATA);
1953 outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
1954 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1955 &chip->master_volume->id);
1956 break; 1922 break;
1957 case 0x66: 1923 case 0x66:
1958 /* volume down */ 1924 /* volume down */
@@ -1960,14 +1926,11 @@ static void es1968_update_hw_volume(unsigned long private_data)
1960 val++; 1926 val++;
1961 if ((val & 0x7f00) < 0x1f00) 1927 if ((val & 0x7f00) < 0x1f00)
1962 val += 0x0100; 1928 val += 0x0100;
1963 chip->ac97->regs[AC97_MASTER] = val;
1964 outw(val, chip->io_port + ESM_AC97_DATA);
1965 outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
1966 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1967 &chip->master_volume->id);
1968 break; 1929 break;
1969 } 1930 }
1970 spin_unlock_irqrestore(&chip->ac97_lock, flags); 1931 if (snd_ac97_update(chip->ac97, AC97_MASTER, val))
1932 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1933 &chip->master_volume->id);
1971#else 1934#else
1972 if (!chip->input_dev) 1935 if (!chip->input_dev)
1973 return; 1936 return;
@@ -2013,11 +1976,7 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
2013 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4); 1976 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
2014 1977
2015 if (event & ESM_HWVOL_IRQ) 1978 if (event & ESM_HWVOL_IRQ)
2016#ifdef CONFIG_SND_ES1968_INPUT 1979 schedule_work(&chip->hwvol_work);
2017 es1968_update_hw_volume((unsigned long)chip);
2018#else
2019 tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */
2020#endif
2021 1980
2022 /* else ack 'em all, i imagine */ 1981 /* else ack 'em all, i imagine */
2023 outb(0xFF, chip->io_port + 0x1A); 1982 outb(0xFF, chip->io_port + 0x1A);
@@ -2426,6 +2385,7 @@ static int es1968_suspend(struct pci_dev *pci, pm_message_t state)
2426 return 0; 2385 return 0;
2427 2386
2428 chip->in_suspend = 1; 2387 chip->in_suspend = 1;
2388 cancel_work_sync(&chip->hwvol_work);
2429 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2389 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2430 snd_pcm_suspend_all(chip->pcm); 2390 snd_pcm_suspend_all(chip->pcm);
2431 snd_ac97_suspend(chip->ac97); 2391 snd_ac97_suspend(chip->ac97);
@@ -2638,6 +2598,7 @@ static struct snd_tea575x_ops snd_es1968_tea_ops = {
2638 2598
2639static int snd_es1968_free(struct es1968 *chip) 2599static int snd_es1968_free(struct es1968 *chip)
2640{ 2600{
2601 cancel_work_sync(&chip->hwvol_work);
2641#ifdef CONFIG_SND_ES1968_INPUT 2602#ifdef CONFIG_SND_ES1968_INPUT
2642 if (chip->input_dev) 2603 if (chip->input_dev)
2643 input_unregister_device(chip->input_dev); 2604 input_unregister_device(chip->input_dev);
@@ -2728,10 +2689,7 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2728 INIT_LIST_HEAD(&chip->buf_list); 2689 INIT_LIST_HEAD(&chip->buf_list);
2729 INIT_LIST_HEAD(&chip->substream_list); 2690 INIT_LIST_HEAD(&chip->substream_list);
2730 mutex_init(&chip->memory_mutex); 2691 mutex_init(&chip->memory_mutex);
2731#ifndef CONFIG_SND_ES1968_INPUT 2692 INIT_WORK(&chip->hwvol_work, es1968_update_hw_volume);
2732 spin_lock_init(&chip->ac97_lock);
2733 tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip);
2734#endif
2735 chip->card = card; 2693 chip->card = card;
2736 chip->pci = pci; 2694 chip->pci = pci;
2737 chip->irq = -1; 2695 chip->irq = -1;
@@ -2746,7 +2704,7 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2746 } 2704 }
2747 chip->io_port = pci_resource_start(pci, 0); 2705 chip->io_port = pci_resource_start(pci, 0);
2748 if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED, 2706 if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED,
2749 "ESS Maestro", chip)) { 2707 KBUILD_MODNAME, chip)) {
2750 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 2708 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2751 snd_es1968_free(chip); 2709 snd_es1968_free(chip);
2752 return -EBUSY; 2710 return -EBUSY;
@@ -2925,7 +2883,7 @@ static void __devexit snd_es1968_remove(struct pci_dev *pci)
2925} 2883}
2926 2884
2927static struct pci_driver driver = { 2885static struct pci_driver driver = {
2928 .name = "ES1968 (ESS Maestro)", 2886 .name = KBUILD_MODNAME,
2929 .id_table = snd_es1968_ids, 2887 .id_table = snd_es1968_ids,
2930 .probe = snd_es1968_probe, 2888 .probe = snd_es1968_probe,
2931 .remove = __devexit_p(snd_es1968_remove), 2889 .remove = __devexit_p(snd_es1968_remove),
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index eacd4901a30..f9123f09e83 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1199,7 +1199,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1199 chip->port = pci_resource_start(pci, 0); 1199 chip->port = pci_resource_start(pci, 0);
1200 if ((tea575x_tuner & TUNER_ONLY) == 0) { 1200 if ((tea575x_tuner & TUNER_ONLY) == 0) {
1201 if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED, 1201 if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
1202 "FM801", chip)) { 1202 KBUILD_MODNAME, chip)) {
1203 snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq); 1203 snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
1204 snd_fm801_free(chip); 1204 snd_fm801_free(chip);
1205 return -EBUSY; 1205 return -EBUSY;
@@ -1234,9 +1234,12 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1234 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); 1234 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
1235 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && 1235 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
1236 (tea575x_tuner & TUNER_TYPE_MASK) < 4) { 1236 (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
1237 if (snd_tea575x_init(&chip->tea)) 1237 if (snd_tea575x_init(&chip->tea)) {
1238 snd_printk(KERN_ERR "TEA575x radio not found\n"); 1238 snd_printk(KERN_ERR "TEA575x radio not found\n");
1239 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) 1239 snd_fm801_free(chip);
1240 return -ENODEV;
1241 }
1242 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) {
1240 /* autodetect tuner connection */ 1243 /* autodetect tuner connection */
1241 for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { 1244 for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) {
1242 chip->tea575x_tuner = tea575x_tuner; 1245 chip->tea575x_tuner = tea575x_tuner;
@@ -1246,6 +1249,12 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1246 break; 1249 break;
1247 } 1250 }
1248 } 1251 }
1252 if (tea575x_tuner == 4) {
1253 snd_printk(KERN_ERR "TEA575x radio not found\n");
1254 snd_fm801_free(chip);
1255 return -ENODEV;
1256 }
1257 }
1249 strlcpy(chip->tea.card, snd_fm801_tea575x_gpios[(tea575x_tuner & TUNER_TYPE_MASK) - 1].name, sizeof(chip->tea.card)); 1258 strlcpy(chip->tea.card, snd_fm801_tea575x_gpios[(tea575x_tuner & TUNER_TYPE_MASK) - 1].name, sizeof(chip->tea.card));
1250#endif 1259#endif
1251 1260
@@ -1385,7 +1394,7 @@ static int snd_fm801_resume(struct pci_dev *pci)
1385#endif 1394#endif
1386 1395
1387static struct pci_driver driver = { 1396static struct pci_driver driver = {
1388 .name = "FM801", 1397 .name = KBUILD_MODNAME,
1389 .id_table = snd_fm801_ids, 1398 .id_table = snd_fm801_ids,
1390 .probe = snd_card_fm801_probe, 1399 .probe = snd_card_fm801_probe,
1391 .remove = __devexit_p(snd_card_fm801_remove), 1400 .remove = __devexit_p(snd_card_fm801_remove),
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 0ea5cc60ac7..bb7e102d672 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -14,6 +14,19 @@ menuconfig SND_HDA_INTEL
14 14
15if SND_HDA_INTEL 15if SND_HDA_INTEL
16 16
17config SND_HDA_PREALLOC_SIZE
18 int "Pre-allocated buffer size for HD-audio driver"
19 range 0 32768
20 default 64
21 help
22 Specifies the default pre-allocated buffer-size in kB for the
23 HD-audio driver. A larger buffer (e.g. 2048) is preferred
24 for systems using PulseAudio. The default 64 is chosen just
25 for compatibility reasons.
26
27 Note that the pre-allocation size can be changed dynamically
28 via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too.
29
17config SND_HDA_HWDEP 30config SND_HDA_HWDEP
18 bool "Build hwdep interface for HD-audio driver" 31 bool "Build hwdep interface for HD-audio driver"
19 select SND_HWDEP 32 select SND_HWDEP
@@ -83,6 +96,19 @@ config SND_HDA_CODEC_REALTEK
83 snd-hda-codec-realtek. 96 snd-hda-codec-realtek.
84 This module is automatically loaded at probing. 97 This module is automatically loaded at probing.
85 98
99config SND_HDA_ENABLE_REALTEK_QUIRKS
100 bool "Build static quirks for Realtek codecs"
101 depends on SND_HDA_CODEC_REALTEK
102 default y
103 help
104 Say Y here to build the static quirks codes for Realtek codecs.
105 If you need the "model" preset that the default BIOS auto-parser
106 can't handle, turn this option on.
107
108 If your device works with model=auto option, basically you don't
109 need the quirk code. By turning this off, you can reduce the
110 module size quite a lot.
111
86config SND_HDA_CODEC_ANALOG 112config SND_HDA_CODEC_ANALOG
87 bool "Build Analog Device HD-audio codec support" 113 bool "Build Analog Device HD-audio codec support"
88 default y 114 default y
@@ -171,6 +197,19 @@ config SND_HDA_CODEC_CA0110
171 snd-hda-codec-ca0110. 197 snd-hda-codec-ca0110.
172 This module is automatically loaded at probing. 198 This module is automatically loaded at probing.
173 199
200config SND_HDA_CODEC_CA0132
201 bool "Build Creative CA0132 codec support"
202 depends on SND_HDA_INTEL
203 default y
204 help
205 Say Y here to include Creative CA0132 codec support in
206 snd-hda-intel driver.
207
208 When the HD-audio driver is built as a module, the codec
209 support code is also built as another module,
210 snd-hda-codec-ca0132.
211 This module is automatically loaded at probing.
212
174config SND_HDA_CODEC_CMEDIA 213config SND_HDA_CODEC_CMEDIA
175 bool "Build C-Media HD-audio codec support" 214 bool "Build C-Media HD-audio codec support"
176 default y 215 default y
@@ -204,6 +243,7 @@ config SND_HDA_GENERIC
204 243
205config SND_HDA_POWER_SAVE 244config SND_HDA_POWER_SAVE
206 bool "Aggressive power-saving on HD-audio" 245 bool "Aggressive power-saving on HD-audio"
246 depends on PM
207 help 247 help
208 Say Y here to enable more aggressive power-saving mode on 248 Say Y here to enable more aggressive power-saving mode on
209 HD-audio driver. The power-saving timeout can be configured 249 HD-audio driver. The power-saving timeout can be configured
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 17ef3658f34..87365d5ea2a 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -13,6 +13,7 @@ snd-hda-codec-idt-objs := patch_sigmatel.o
13snd-hda-codec-si3054-objs := patch_si3054.o 13snd-hda-codec-si3054-objs := patch_si3054.o
14snd-hda-codec-cirrus-objs := patch_cirrus.o 14snd-hda-codec-cirrus-objs := patch_cirrus.o
15snd-hda-codec-ca0110-objs := patch_ca0110.o 15snd-hda-codec-ca0110-objs := patch_ca0110.o
16snd-hda-codec-ca0132-objs := patch_ca0132.o
16snd-hda-codec-conexant-objs := patch_conexant.o 17snd-hda-codec-conexant-objs := patch_conexant.o
17snd-hda-codec-via-objs := patch_via.o 18snd-hda-codec-via-objs := patch_via.o
18snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o 19snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o
@@ -42,6 +43,9 @@ endif
42ifdef CONFIG_SND_HDA_CODEC_CA0110 43ifdef CONFIG_SND_HDA_CODEC_CA0110
43obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o 44obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o
44endif 45endif
46ifdef CONFIG_SND_HDA_CODEC_CA0132
47obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0132.o
48endif
45ifdef CONFIG_SND_HDA_CODEC_CONEXANT 49ifdef CONFIG_SND_HDA_CODEC_CONEXANT
46obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o 50obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o
47endif 51endif
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c
new file mode 100644
index 00000000000..21ec2cb100b
--- /dev/null
+++ b/sound/pci/hda/alc260_quirks.c
@@ -0,0 +1,1272 @@
1/*
2 * ALC260 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC260 models */
7enum {
8 ALC260_AUTO,
9 ALC260_BASIC,
10 ALC260_HP,
11 ALC260_HP_DC7600,
12 ALC260_HP_3013,
13 ALC260_FUJITSU_S702X,
14 ALC260_ACER,
15 ALC260_WILL,
16 ALC260_REPLACER_672V,
17 ALC260_FAVORIT100,
18#ifdef CONFIG_SND_DEBUG
19 ALC260_TEST,
20#endif
21 ALC260_MODEL_LAST /* last tag */
22};
23
24static const hda_nid_t alc260_dac_nids[1] = {
25 /* front */
26 0x02,
27};
28
29static const hda_nid_t alc260_adc_nids[1] = {
30 /* ADC0 */
31 0x04,
32};
33
34static const hda_nid_t alc260_adc_nids_alt[1] = {
35 /* ADC1 */
36 0x05,
37};
38
39/* NIDs used when simultaneous access to both ADCs makes sense. Note that
40 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
41 */
42static const hda_nid_t alc260_dual_adc_nids[2] = {
43 /* ADC0, ADC1 */
44 0x04, 0x05
45};
46
47#define ALC260_DIGOUT_NID 0x03
48#define ALC260_DIGIN_NID 0x06
49
50static const struct hda_input_mux alc260_capture_source = {
51 .num_items = 4,
52 .items = {
53 { "Mic", 0x0 },
54 { "Front Mic", 0x1 },
55 { "Line", 0x2 },
56 { "CD", 0x4 },
57 },
58};
59
60/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
61 * headphone jack and the internal CD lines since these are the only pins at
62 * which audio can appear. For flexibility, also allow the option of
63 * recording the mixer output on the second ADC (ADC0 doesn't have a
64 * connection to the mixer output).
65 */
66static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
67 {
68 .num_items = 3,
69 .items = {
70 { "Mic/Line", 0x0 },
71 { "CD", 0x4 },
72 { "Headphone", 0x2 },
73 },
74 },
75 {
76 .num_items = 4,
77 .items = {
78 { "Mic/Line", 0x0 },
79 { "CD", 0x4 },
80 { "Headphone", 0x2 },
81 { "Mixer", 0x5 },
82 },
83 },
84
85};
86
87/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
88 * the Fujitsu S702x, but jacks are marked differently.
89 */
90static const struct hda_input_mux alc260_acer_capture_sources[2] = {
91 {
92 .num_items = 4,
93 .items = {
94 { "Mic", 0x0 },
95 { "Line", 0x2 },
96 { "CD", 0x4 },
97 { "Headphone", 0x5 },
98 },
99 },
100 {
101 .num_items = 5,
102 .items = {
103 { "Mic", 0x0 },
104 { "Line", 0x2 },
105 { "CD", 0x4 },
106 { "Headphone", 0x6 },
107 { "Mixer", 0x5 },
108 },
109 },
110};
111
112/* Maxdata Favorit 100XS */
113static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
114 {
115 .num_items = 2,
116 .items = {
117 { "Line/Mic", 0x0 },
118 { "CD", 0x4 },
119 },
120 },
121 {
122 .num_items = 3,
123 .items = {
124 { "Line/Mic", 0x0 },
125 { "CD", 0x4 },
126 { "Mixer", 0x5 },
127 },
128 },
129};
130
131/*
132 * This is just place-holder, so there's something for alc_build_pcms to look
133 * at when it calculates the maximum number of channels. ALC260 has no mixer
134 * element which allows changing the channel mode, so the verb list is
135 * never used.
136 */
137static const struct hda_channel_mode alc260_modes[1] = {
138 { 2, NULL },
139};
140
141
142/* Mixer combinations
143 *
144 * basic: base_output + input + pc_beep + capture
145 * HP: base_output + input + capture_alt
146 * HP_3013: hp_3013 + input + capture
147 * fujitsu: fujitsu + capture
148 * acer: acer + capture
149 */
150
151static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
152 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
153 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
154 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
155 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
156 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
157 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
158 { } /* end */
159};
160
161static const struct snd_kcontrol_new alc260_input_mixer[] = {
162 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
163 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
164 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
165 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
167 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
168 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
169 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
170 { } /* end */
171};
172
173/* update HP, line and mono out pins according to the master switch */
174static void alc260_hp_master_update(struct hda_codec *codec)
175{
176 update_speakers(codec);
177}
178
179static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol)
181{
182 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
183 struct alc_spec *spec = codec->spec;
184 *ucontrol->value.integer.value = !spec->master_mute;
185 return 0;
186}
187
188static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
189 struct snd_ctl_elem_value *ucontrol)
190{
191 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
192 struct alc_spec *spec = codec->spec;
193 int val = !*ucontrol->value.integer.value;
194
195 if (val == spec->master_mute)
196 return 0;
197 spec->master_mute = val;
198 alc260_hp_master_update(codec);
199 return 1;
200}
201
202static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
203 {
204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
205 .name = "Master Playback Switch",
206 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
207 .info = snd_ctl_boolean_mono_info,
208 .get = alc260_hp_master_sw_get,
209 .put = alc260_hp_master_sw_put,
210 },
211 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
212 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
213 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
214 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
215 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
216 HDA_OUTPUT),
217 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
218 { } /* end */
219};
220
221static const struct hda_verb alc260_hp_unsol_verbs[] = {
222 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
223 {},
224};
225
226static void alc260_hp_setup(struct hda_codec *codec)
227{
228 struct alc_spec *spec = codec->spec;
229
230 spec->autocfg.hp_pins[0] = 0x0f;
231 spec->autocfg.speaker_pins[0] = 0x10;
232 spec->autocfg.speaker_pins[1] = 0x11;
233 spec->automute = 1;
234 spec->automute_mode = ALC_AUTOMUTE_PIN;
235}
236
237static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
238 {
239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
240 .name = "Master Playback Switch",
241 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
242 .info = snd_ctl_boolean_mono_info,
243 .get = alc260_hp_master_sw_get,
244 .put = alc260_hp_master_sw_put,
245 },
246 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
247 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
248 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
249 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
250 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
251 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
252 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
253 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
254 { } /* end */
255};
256
257static void alc260_hp_3013_setup(struct hda_codec *codec)
258{
259 struct alc_spec *spec = codec->spec;
260
261 spec->autocfg.hp_pins[0] = 0x15;
262 spec->autocfg.speaker_pins[0] = 0x10;
263 spec->autocfg.speaker_pins[1] = 0x11;
264 spec->automute = 1;
265 spec->automute_mode = ALC_AUTOMUTE_PIN;
266}
267
268static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
269 .ops = &snd_hda_bind_vol,
270 .values = {
271 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
272 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
273 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
274 0
275 },
276};
277
278static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
279 .ops = &snd_hda_bind_sw,
280 .values = {
281 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
282 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
283 0
284 },
285};
286
287static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
288 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
289 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
290 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
292 { } /* end */
293};
294
295static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
296 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
297 {},
298};
299
300static void alc260_hp_3012_setup(struct hda_codec *codec)
301{
302 struct alc_spec *spec = codec->spec;
303
304 spec->autocfg.hp_pins[0] = 0x10;
305 spec->autocfg.speaker_pins[0] = 0x0f;
306 spec->autocfg.speaker_pins[1] = 0x11;
307 spec->autocfg.speaker_pins[2] = 0x15;
308 spec->automute = 1;
309 spec->automute_mode = ALC_AUTOMUTE_PIN;
310}
311
312/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
313 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
314 */
315static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
316 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
317 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
318 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
319 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
320 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
321 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
322 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
323 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
324 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
325 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
326 { } /* end */
327};
328
329/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
330 * versions of the ALC260 don't act on requests to enable mic bias from NID
331 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
332 * datasheet doesn't mention this restriction. At this stage it's not clear
333 * whether this behaviour is intentional or is a hardware bug in chip
334 * revisions available in early 2006. Therefore for now allow the
335 * "Headphone Jack Mode" control to span all choices, but if it turns out
336 * that the lack of mic bias for this NID is intentional we could change the
337 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
338 *
339 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
340 * don't appear to make the mic bias available from the "line" jack, even
341 * though the NID used for this jack (0x14) can supply it. The theory is
342 * that perhaps Acer have included blocking capacitors between the ALC260
343 * and the output jack. If this turns out to be the case for all such
344 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
345 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
346 *
347 * The C20x Tablet series have a mono internal speaker which is controlled
348 * via the chip's Mono sum widget and pin complex, so include the necessary
349 * controls for such models. On models without a "mono speaker" the control
350 * won't do anything.
351 */
352static const struct snd_kcontrol_new alc260_acer_mixer[] = {
353 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
354 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
355 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
356 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
357 HDA_OUTPUT),
358 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
359 HDA_INPUT),
360 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
361 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
362 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
363 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
364 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
365 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
366 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
367 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
368 { } /* end */
369};
370
371/* Maxdata Favorit 100XS: one output and one input (0x12) jack
372 */
373static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
374 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
375 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
376 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
377 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
378 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
379 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
380 { } /* end */
381};
382
383/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
384 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
385 */
386static const struct snd_kcontrol_new alc260_will_mixer[] = {
387 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
388 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
389 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
390 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
391 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
392 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
393 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
394 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
395 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
396 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
397 { } /* end */
398};
399
400/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
401 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
402 */
403static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
404 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
405 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
406 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
407 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
408 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
409 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
410 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
411 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
412 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
413 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
414 { } /* end */
415};
416
417/*
418 * initialization verbs
419 */
420static const struct hda_verb alc260_init_verbs[] = {
421 /* Line In pin widget for input */
422 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
423 /* CD pin widget for input */
424 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
425 /* Mic1 (rear panel) pin widget for input and vref at 80% */
426 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
427 /* Mic2 (front panel) pin widget for input and vref at 80% */
428 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
429 /* LINE-2 is used for line-out in rear */
430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
431 /* select line-out */
432 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
433 /* LINE-OUT pin */
434 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
435 /* enable HP */
436 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
437 /* enable Mono */
438 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
439 /* mute capture amp left and right */
440 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
441 /* set connection select to line in (default select for this ADC) */
442 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
443 /* mute capture amp left and right */
444 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
445 /* set connection select to line in (default select for this ADC) */
446 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
447 /* set vol=0 Line-Out mixer amp left and right */
448 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
449 /* unmute pin widget amp left and right (no gain on this amp) */
450 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
451 /* set vol=0 HP mixer amp left and right */
452 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
453 /* unmute pin widget amp left and right (no gain on this amp) */
454 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
455 /* set vol=0 Mono mixer amp left and right */
456 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
457 /* unmute pin widget amp left and right (no gain on this amp) */
458 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
459 /* unmute LINE-2 out pin */
460 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
461 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
462 * Line In 2 = 0x03
463 */
464 /* mute analog inputs */
465 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
466 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
467 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
468 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
469 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
470 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
471 /* mute Front out path */
472 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
473 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
474 /* mute Headphone out path */
475 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
476 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
477 /* mute Mono out path */
478 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
479 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
480 { }
481};
482
483#if 0 /* should be identical with alc260_init_verbs? */
484static const struct hda_verb alc260_hp_init_verbs[] = {
485 /* Headphone and output */
486 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
487 /* mono output */
488 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
489 /* Mic1 (rear panel) pin widget for input and vref at 80% */
490 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
491 /* Mic2 (front panel) pin widget for input and vref at 80% */
492 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
493 /* Line In pin widget for input */
494 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
495 /* Line-2 pin widget for output */
496 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
497 /* CD pin widget for input */
498 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
499 /* unmute amp left and right */
500 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
501 /* set connection select to line in (default select for this ADC) */
502 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
503 /* unmute Line-Out mixer amp left and right (volume = 0) */
504 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
505 /* mute pin widget amp left and right (no gain on this amp) */
506 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
507 /* unmute HP mixer amp left and right (volume = 0) */
508 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
509 /* mute pin widget amp left and right (no gain on this amp) */
510 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
511 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
512 * Line In 2 = 0x03
513 */
514 /* mute analog inputs */
515 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
516 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
517 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
518 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
519 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
520 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
521 /* Unmute Front out path */
522 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
523 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
524 /* Unmute Headphone out path */
525 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
526 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
527 /* Unmute Mono out path */
528 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
529 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
530 { }
531};
532#endif
533
534static const struct hda_verb alc260_hp_3013_init_verbs[] = {
535 /* Line out and output */
536 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
537 /* mono output */
538 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
539 /* Mic1 (rear panel) pin widget for input and vref at 80% */
540 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
541 /* Mic2 (front panel) pin widget for input and vref at 80% */
542 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
543 /* Line In pin widget for input */
544 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
545 /* Headphone pin widget for output */
546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
547 /* CD pin widget for input */
548 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
549 /* unmute amp left and right */
550 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
551 /* set connection select to line in (default select for this ADC) */
552 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
553 /* unmute Line-Out mixer amp left and right (volume = 0) */
554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
555 /* mute pin widget amp left and right (no gain on this amp) */
556 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
557 /* unmute HP mixer amp left and right (volume = 0) */
558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
559 /* mute pin widget amp left and right (no gain on this amp) */
560 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
561 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
562 * Line In 2 = 0x03
563 */
564 /* mute analog inputs */
565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
569 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
570 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
571 /* Unmute Front out path */
572 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
573 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
574 /* Unmute Headphone out path */
575 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
576 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
577 /* Unmute Mono out path */
578 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
579 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
580 { }
581};
582
583/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
584 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
585 * audio = 0x16, internal speaker = 0x10.
586 */
587static const struct hda_verb alc260_fujitsu_init_verbs[] = {
588 /* Disable all GPIOs */
589 {0x01, AC_VERB_SET_GPIO_MASK, 0},
590 /* Internal speaker is connected to headphone pin */
591 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
592 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
593 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
594 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
595 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
596 /* Ensure all other unused pins are disabled and muted. */
597 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
598 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
599 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
600 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
601 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
602 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
604 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
605
606 /* Disable digital (SPDIF) pins */
607 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
608 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
609
610 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
611 * when acting as an output.
612 */
613 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
614
615 /* Start with output sum widgets muted and their output gains at min */
616 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
617 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
618 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
619 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
620 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
621 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
622 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
623 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
624 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
625
626 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
627 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
628 /* Unmute Line1 pin widget output buffer since it starts as an output.
629 * If the pin mode is changed by the user the pin mode control will
630 * take care of enabling the pin's input/output buffers as needed.
631 * Therefore there's no need to enable the input buffer at this
632 * stage.
633 */
634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
635 /* Unmute input buffer of pin widget used for Line-in (no equiv
636 * mixer ctrl)
637 */
638 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
639
640 /* Mute capture amp left and right */
641 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
642 /* Set ADC connection select to match default mixer setting - line
643 * in (on mic1 pin)
644 */
645 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
646
647 /* Do the same for the second ADC: mute capture input amp and
648 * set ADC connection to line in (on mic1 pin)
649 */
650 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
651 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
652
653 /* Mute all inputs to mixer widget (even unconnected ones) */
654 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
655 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
656 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
657 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
658 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
659 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
660 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
661 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
662
663 { }
664};
665
666/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
667 * similar laptops (adapted from Fujitsu init verbs).
668 */
669static const struct hda_verb alc260_acer_init_verbs[] = {
670 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
671 * the headphone jack. Turn this on and rely on the standard mute
672 * methods whenever the user wants to turn these outputs off.
673 */
674 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
675 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
676 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
677 /* Internal speaker/Headphone jack is connected to Line-out pin */
678 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
679 /* Internal microphone/Mic jack is connected to Mic1 pin */
680 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
681 /* Line In jack is connected to Line1 pin */
682 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
683 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
684 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
685 /* Ensure all other unused pins are disabled and muted. */
686 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
687 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
688 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
689 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
690 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
691 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
692 /* Disable digital (SPDIF) pins */
693 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
694 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
695
696 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
697 * bus when acting as outputs.
698 */
699 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
700 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
701
702 /* Start with output sum widgets muted and their output gains at min */
703 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
704 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
705 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
706 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
707 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
708 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
709 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
710 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
711 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
712
713 /* Unmute Line-out pin widget amp left and right
714 * (no equiv mixer ctrl)
715 */
716 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
717 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
718 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
719 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
720 * inputs. If the pin mode is changed by the user the pin mode control
721 * will take care of enabling the pin's input/output buffers as needed.
722 * Therefore there's no need to enable the input buffer at this
723 * stage.
724 */
725 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
726 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
727
728 /* Mute capture amp left and right */
729 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
730 /* Set ADC connection select to match default mixer setting - mic
731 * (on mic1 pin)
732 */
733 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
734
735 /* Do similar with the second ADC: mute capture input amp and
736 * set ADC connection to mic to match ALSA's default state.
737 */
738 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
739 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
740
741 /* Mute all inputs to mixer widget (even unconnected ones) */
742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
745 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
746 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
748 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
749 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
750
751 { }
752};
753
754/* Initialisation sequence for Maxdata Favorit 100XS
755 * (adapted from Acer init verbs).
756 */
757static const struct hda_verb alc260_favorit100_init_verbs[] = {
758 /* GPIO 0 enables the output jack.
759 * Turn this on and rely on the standard mute
760 * methods whenever the user wants to turn these outputs off.
761 */
762 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
763 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
764 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
765 /* Line/Mic input jack is connected to Mic1 pin */
766 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
767 /* Ensure all other unused pins are disabled and muted. */
768 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
769 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
770 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
771 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
772 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
773 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
774 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
775 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
776 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
777 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
778 /* Disable digital (SPDIF) pins */
779 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
780 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
781
782 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
783 * bus when acting as outputs.
784 */
785 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
786 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
787
788 /* Start with output sum widgets muted and their output gains at min */
789 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
791 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
792 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
794 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
795 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
796 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
797 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
798
799 /* Unmute Line-out pin widget amp left and right
800 * (no equiv mixer ctrl)
801 */
802 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
803 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
804 * inputs. If the pin mode is changed by the user the pin mode control
805 * will take care of enabling the pin's input/output buffers as needed.
806 * Therefore there's no need to enable the input buffer at this
807 * stage.
808 */
809 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
810
811 /* Mute capture amp left and right */
812 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
813 /* Set ADC connection select to match default mixer setting - mic
814 * (on mic1 pin)
815 */
816 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
817
818 /* Do similar with the second ADC: mute capture input amp and
819 * set ADC connection to mic to match ALSA's default state.
820 */
821 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
822 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
823
824 /* Mute all inputs to mixer widget (even unconnected ones) */
825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
832 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
833
834 { }
835};
836
837static const struct hda_verb alc260_will_verbs[] = {
838 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
839 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
840 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
841 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
842 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
843 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
844 {}
845};
846
847static const struct hda_verb alc260_replacer_672v_verbs[] = {
848 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
849 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
850 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
851
852 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
853 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
854 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
855
856 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
857 {}
858};
859
860/* toggle speaker-output according to the hp-jack state */
861static void alc260_replacer_672v_automute(struct hda_codec *codec)
862{
863 unsigned int present;
864
865 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
866 present = snd_hda_jack_detect(codec, 0x0f);
867 if (present) {
868 snd_hda_codec_write_cache(codec, 0x01, 0,
869 AC_VERB_SET_GPIO_DATA, 1);
870 snd_hda_codec_write_cache(codec, 0x0f, 0,
871 AC_VERB_SET_PIN_WIDGET_CONTROL,
872 PIN_HP);
873 } else {
874 snd_hda_codec_write_cache(codec, 0x01, 0,
875 AC_VERB_SET_GPIO_DATA, 0);
876 snd_hda_codec_write_cache(codec, 0x0f, 0,
877 AC_VERB_SET_PIN_WIDGET_CONTROL,
878 PIN_OUT);
879 }
880}
881
882static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
883 unsigned int res)
884{
885 if ((res >> 26) == ALC_HP_EVENT)
886 alc260_replacer_672v_automute(codec);
887}
888
889static const struct hda_verb alc260_hp_dc7600_verbs[] = {
890 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
891 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
892 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
893 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
894 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
896 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
897 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
898 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
899 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
900 {}
901};
902
903/* Test configuration for debugging, modelled after the ALC880 test
904 * configuration.
905 */
906#ifdef CONFIG_SND_DEBUG
907static const hda_nid_t alc260_test_dac_nids[1] = {
908 0x02,
909};
910static const hda_nid_t alc260_test_adc_nids[2] = {
911 0x04, 0x05,
912};
913/* For testing the ALC260, each input MUX needs its own definition since
914 * the signal assignments are different. This assumes that the first ADC
915 * is NID 0x04.
916 */
917static const struct hda_input_mux alc260_test_capture_sources[2] = {
918 {
919 .num_items = 7,
920 .items = {
921 { "MIC1 pin", 0x0 },
922 { "MIC2 pin", 0x1 },
923 { "LINE1 pin", 0x2 },
924 { "LINE2 pin", 0x3 },
925 { "CD pin", 0x4 },
926 { "LINE-OUT pin", 0x5 },
927 { "HP-OUT pin", 0x6 },
928 },
929 },
930 {
931 .num_items = 8,
932 .items = {
933 { "MIC1 pin", 0x0 },
934 { "MIC2 pin", 0x1 },
935 { "LINE1 pin", 0x2 },
936 { "LINE2 pin", 0x3 },
937 { "CD pin", 0x4 },
938 { "Mixer", 0x5 },
939 { "LINE-OUT pin", 0x6 },
940 { "HP-OUT pin", 0x7 },
941 },
942 },
943};
944static const struct snd_kcontrol_new alc260_test_mixer[] = {
945 /* Output driver widgets */
946 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
947 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
948 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
949 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
950 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
951 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
952
953 /* Modes for retasking pin widgets
954 * Note: the ALC260 doesn't seem to act on requests to enable mic
955 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
956 * mention this restriction. At this stage it's not clear whether
957 * this behaviour is intentional or is a hardware bug in chip
958 * revisions available at least up until early 2006. Therefore for
959 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
960 * choices, but if it turns out that the lack of mic bias for these
961 * NIDs is intentional we could change their modes from
962 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
963 */
964 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
965 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
966 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
967 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
968 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
969 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
970
971 /* Loopback mixer controls */
972 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
973 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
974 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
975 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
976 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
977 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
978 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
979 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
980 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
981 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
982 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
983 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
984 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
985 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
986
987 /* Controls for GPIO pins, assuming they are configured as outputs */
988 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
989 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
990 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
991 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
992
993 /* Switches to allow the digital IO pins to be enabled. The datasheet
994 * is ambigious as to which NID is which; testing on laptops which
995 * make this output available should provide clarification.
996 */
997 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
998 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
999
1000 /* A switch allowing EAPD to be enabled. Some laptops seem to use
1001 * this output to turn on an external amplifier.
1002 */
1003 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
1004 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
1005
1006 { } /* end */
1007};
1008static const struct hda_verb alc260_test_init_verbs[] = {
1009 /* Enable all GPIOs as outputs with an initial value of 0 */
1010 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
1011 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
1012 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
1013
1014 /* Enable retasking pins as output, initially without power amp */
1015 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1016 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1018 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1019 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1020 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1021
1022 /* Disable digital (SPDIF) pins initially, but users can enable
1023 * them via a mixer switch. In the case of SPDIF-out, this initverb
1024 * payload also sets the generation to 0, output to be in "consumer"
1025 * PCM format, copyright asserted, no pre-emphasis and no validity
1026 * control.
1027 */
1028 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
1029 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
1030
1031 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
1032 * OUT1 sum bus when acting as an output.
1033 */
1034 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
1035 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
1036 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
1037 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
1038
1039 /* Start with output sum widgets muted and their output gains at min */
1040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1041 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1042 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1043 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1044 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1045 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1046 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1047 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1048 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1049
1050 /* Unmute retasking pin widget output buffers since the default
1051 * state appears to be output. As the pin mode is changed by the
1052 * user the pin mode control will take care of enabling the pin's
1053 * input/output buffers as needed.
1054 */
1055 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1056 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1059 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1060 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1061 /* Also unmute the mono-out pin widget */
1062 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1063
1064 /* Mute capture amp left and right */
1065 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1066 /* Set ADC connection select to match default mixer setting (mic1
1067 * pin)
1068 */
1069 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
1070
1071 /* Do the same for the second ADC: mute capture input amp and
1072 * set ADC connection to mic1 pin
1073 */
1074 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1075 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
1076
1077 /* Mute all inputs to mixer widget (even unconnected ones) */
1078 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1079 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1080 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1081 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1082 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1084 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1085 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1086
1087 { }
1088};
1089#endif
1090
1091/*
1092 * ALC260 configurations
1093 */
1094static const char * const alc260_models[ALC260_MODEL_LAST] = {
1095 [ALC260_BASIC] = "basic",
1096 [ALC260_HP] = "hp",
1097 [ALC260_HP_3013] = "hp-3013",
1098 [ALC260_HP_DC7600] = "hp-dc7600",
1099 [ALC260_FUJITSU_S702X] = "fujitsu",
1100 [ALC260_ACER] = "acer",
1101 [ALC260_WILL] = "will",
1102 [ALC260_REPLACER_672V] = "replacer",
1103 [ALC260_FAVORIT100] = "favorit100",
1104#ifdef CONFIG_SND_DEBUG
1105 [ALC260_TEST] = "test",
1106#endif
1107 [ALC260_AUTO] = "auto",
1108};
1109
1110static const struct snd_pci_quirk alc260_cfg_tbl[] = {
1111 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
1112 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
1113 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
1114 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
1115 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
1116 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
1117 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
1118 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
1119 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
1120 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
1121 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
1122 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
1123 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
1124 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
1125 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
1126 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
1127 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
1128 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
1129 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
1130 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
1131 {}
1132};
1133
1134static const struct alc_config_preset alc260_presets[] = {
1135 [ALC260_BASIC] = {
1136 .mixers = { alc260_base_output_mixer,
1137 alc260_input_mixer },
1138 .init_verbs = { alc260_init_verbs },
1139 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1140 .dac_nids = alc260_dac_nids,
1141 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1142 .adc_nids = alc260_dual_adc_nids,
1143 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1144 .channel_mode = alc260_modes,
1145 .input_mux = &alc260_capture_source,
1146 },
1147 [ALC260_HP] = {
1148 .mixers = { alc260_hp_output_mixer,
1149 alc260_input_mixer },
1150 .init_verbs = { alc260_init_verbs,
1151 alc260_hp_unsol_verbs },
1152 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1153 .dac_nids = alc260_dac_nids,
1154 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1155 .adc_nids = alc260_adc_nids_alt,
1156 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1157 .channel_mode = alc260_modes,
1158 .input_mux = &alc260_capture_source,
1159 .unsol_event = alc_sku_unsol_event,
1160 .setup = alc260_hp_setup,
1161 .init_hook = alc_inithook,
1162 },
1163 [ALC260_HP_DC7600] = {
1164 .mixers = { alc260_hp_dc7600_mixer,
1165 alc260_input_mixer },
1166 .init_verbs = { alc260_init_verbs,
1167 alc260_hp_dc7600_verbs },
1168 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1169 .dac_nids = alc260_dac_nids,
1170 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1171 .adc_nids = alc260_adc_nids_alt,
1172 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1173 .channel_mode = alc260_modes,
1174 .input_mux = &alc260_capture_source,
1175 .unsol_event = alc_sku_unsol_event,
1176 .setup = alc260_hp_3012_setup,
1177 .init_hook = alc_inithook,
1178 },
1179 [ALC260_HP_3013] = {
1180 .mixers = { alc260_hp_3013_mixer,
1181 alc260_input_mixer },
1182 .init_verbs = { alc260_hp_3013_init_verbs,
1183 alc260_hp_3013_unsol_verbs },
1184 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1185 .dac_nids = alc260_dac_nids,
1186 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1187 .adc_nids = alc260_adc_nids_alt,
1188 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1189 .channel_mode = alc260_modes,
1190 .input_mux = &alc260_capture_source,
1191 .unsol_event = alc_sku_unsol_event,
1192 .setup = alc260_hp_3013_setup,
1193 .init_hook = alc_inithook,
1194 },
1195 [ALC260_FUJITSU_S702X] = {
1196 .mixers = { alc260_fujitsu_mixer },
1197 .init_verbs = { alc260_fujitsu_init_verbs },
1198 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1199 .dac_nids = alc260_dac_nids,
1200 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1201 .adc_nids = alc260_dual_adc_nids,
1202 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1203 .channel_mode = alc260_modes,
1204 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
1205 .input_mux = alc260_fujitsu_capture_sources,
1206 },
1207 [ALC260_ACER] = {
1208 .mixers = { alc260_acer_mixer },
1209 .init_verbs = { alc260_acer_init_verbs },
1210 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1211 .dac_nids = alc260_dac_nids,
1212 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1213 .adc_nids = alc260_dual_adc_nids,
1214 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1215 .channel_mode = alc260_modes,
1216 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
1217 .input_mux = alc260_acer_capture_sources,
1218 },
1219 [ALC260_FAVORIT100] = {
1220 .mixers = { alc260_favorit100_mixer },
1221 .init_verbs = { alc260_favorit100_init_verbs },
1222 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1223 .dac_nids = alc260_dac_nids,
1224 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1225 .adc_nids = alc260_dual_adc_nids,
1226 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1227 .channel_mode = alc260_modes,
1228 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
1229 .input_mux = alc260_favorit100_capture_sources,
1230 },
1231 [ALC260_WILL] = {
1232 .mixers = { alc260_will_mixer },
1233 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
1234 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1235 .dac_nids = alc260_dac_nids,
1236 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
1237 .adc_nids = alc260_adc_nids,
1238 .dig_out_nid = ALC260_DIGOUT_NID,
1239 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1240 .channel_mode = alc260_modes,
1241 .input_mux = &alc260_capture_source,
1242 },
1243 [ALC260_REPLACER_672V] = {
1244 .mixers = { alc260_replacer_672v_mixer },
1245 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
1246 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1247 .dac_nids = alc260_dac_nids,
1248 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
1249 .adc_nids = alc260_adc_nids,
1250 .dig_out_nid = ALC260_DIGOUT_NID,
1251 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1252 .channel_mode = alc260_modes,
1253 .input_mux = &alc260_capture_source,
1254 .unsol_event = alc260_replacer_672v_unsol_event,
1255 .init_hook = alc260_replacer_672v_automute,
1256 },
1257#ifdef CONFIG_SND_DEBUG
1258 [ALC260_TEST] = {
1259 .mixers = { alc260_test_mixer },
1260 .init_verbs = { alc260_test_init_verbs },
1261 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
1262 .dac_nids = alc260_test_dac_nids,
1263 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
1264 .adc_nids = alc260_test_adc_nids,
1265 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1266 .channel_mode = alc260_modes,
1267 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
1268 .input_mux = alc260_test_capture_sources,
1269 },
1270#endif
1271};
1272
diff --git a/sound/pci/hda/alc262_quirks.c b/sound/pci/hda/alc262_quirks.c
new file mode 100644
index 00000000000..8d2097d7764
--- /dev/null
+++ b/sound/pci/hda/alc262_quirks.c
@@ -0,0 +1,1353 @@
1/*
2 * ALC262 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC262 models */
7enum {
8 ALC262_AUTO,
9 ALC262_BASIC,
10 ALC262_HIPPO,
11 ALC262_HIPPO_1,
12 ALC262_FUJITSU,
13 ALC262_HP_BPC,
14 ALC262_HP_BPC_D7000_WL,
15 ALC262_HP_BPC_D7000_WF,
16 ALC262_HP_TC_T5735,
17 ALC262_HP_RP5700,
18 ALC262_BENQ_ED8,
19 ALC262_SONY_ASSAMD,
20 ALC262_BENQ_T31,
21 ALC262_ULTRA,
22 ALC262_LENOVO_3000,
23 ALC262_NEC,
24 ALC262_TOSHIBA_S06,
25 ALC262_TOSHIBA_RX1,
26 ALC262_TYAN,
27 ALC262_MODEL_LAST /* last tag */
28};
29
30#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
31#define ALC262_DIGIN_NID ALC880_DIGIN_NID
32
33#define alc262_dac_nids alc260_dac_nids
34#define alc262_adc_nids alc882_adc_nids
35#define alc262_adc_nids_alt alc882_adc_nids_alt
36#define alc262_capsrc_nids alc882_capsrc_nids
37#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
38
39#define alc262_modes alc260_modes
40#define alc262_capture_source alc882_capture_source
41
42static const hda_nid_t alc262_dmic_adc_nids[1] = {
43 /* ADC0 */
44 0x09
45};
46
47static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
48
49static const struct snd_kcontrol_new alc262_base_mixer[] = {
50 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
51 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
52 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
53 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
54 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
55 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
56 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
57 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
58 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
59 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
60 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
61 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
62 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
63 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
64 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
65 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
66 { } /* end */
67};
68
69/* update HP, line and mono-out pins according to the master switch */
70#define alc262_hp_master_update alc260_hp_master_update
71
72static void alc262_hp_bpc_setup(struct hda_codec *codec)
73{
74 struct alc_spec *spec = codec->spec;
75
76 spec->autocfg.hp_pins[0] = 0x1b;
77 spec->autocfg.speaker_pins[0] = 0x16;
78 spec->automute = 1;
79 spec->automute_mode = ALC_AUTOMUTE_PIN;
80}
81
82static void alc262_hp_wildwest_setup(struct hda_codec *codec)
83{
84 struct alc_spec *spec = codec->spec;
85
86 spec->autocfg.hp_pins[0] = 0x15;
87 spec->autocfg.speaker_pins[0] = 0x16;
88 spec->automute = 1;
89 spec->automute_mode = ALC_AUTOMUTE_PIN;
90}
91
92#define alc262_hp_master_sw_get alc260_hp_master_sw_get
93#define alc262_hp_master_sw_put alc260_hp_master_sw_put
94
95#define ALC262_HP_MASTER_SWITCH \
96 { \
97 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
98 .name = "Master Playback Switch", \
99 .info = snd_ctl_boolean_mono_info, \
100 .get = alc262_hp_master_sw_get, \
101 .put = alc262_hp_master_sw_put, \
102 }, \
103 { \
104 .iface = NID_MAPPING, \
105 .name = "Master Playback Switch", \
106 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
107 }
108
109
110static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
111 ALC262_HP_MASTER_SWITCH,
112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
113 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
115 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
116 HDA_OUTPUT),
117 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
118 HDA_OUTPUT),
119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
121 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
122 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
123 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
124 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
127 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
128 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
129 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
130 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
131 { } /* end */
132};
133
134static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
135 ALC262_HP_MASTER_SWITCH,
136 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
137 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
138 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
139 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
140 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
141 HDA_OUTPUT),
142 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
143 HDA_OUTPUT),
144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
145 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
146 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
147 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
148 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
149 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
150 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
151 { } /* end */
152};
153
154static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
155 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
156 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
157 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
158 { } /* end */
159};
160
161/* mute/unmute internal speaker according to the hp jack and mute state */
162static void alc262_hp_t5735_setup(struct hda_codec *codec)
163{
164 struct alc_spec *spec = codec->spec;
165
166 spec->autocfg.hp_pins[0] = 0x15;
167 spec->autocfg.speaker_pins[0] = 0x14;
168 spec->automute = 1;
169 spec->automute_mode = ALC_AUTOMUTE_PIN;
170}
171
172static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
173 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
174 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
175 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
176 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
177 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
178 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
179 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
180 { } /* end */
181};
182
183static const struct hda_verb alc262_hp_t5735_verbs[] = {
184 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
185 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
186
187 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
188 { }
189};
190
191static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
192 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
194 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
195 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
196 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
197 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
198 { } /* end */
199};
200
201static const struct hda_verb alc262_hp_rp5700_verbs[] = {
202 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
203 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
204 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
205 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
206 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
207 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
208 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
211 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
212 {}
213};
214
215static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
216 .num_items = 1,
217 .items = {
218 { "Line", 0x1 },
219 },
220};
221
222/* bind hp and internal speaker mute (with plug check) as master switch */
223#define alc262_hippo_master_update alc262_hp_master_update
224#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
225#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
226
227#define ALC262_HIPPO_MASTER_SWITCH \
228 { \
229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
230 .name = "Master Playback Switch", \
231 .info = snd_ctl_boolean_mono_info, \
232 .get = alc262_hippo_master_sw_get, \
233 .put = alc262_hippo_master_sw_put, \
234 }, \
235 { \
236 .iface = NID_MAPPING, \
237 .name = "Master Playback Switch", \
238 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
239 (SUBDEV_SPEAKER(0) << 16), \
240 }
241
242static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
243 ALC262_HIPPO_MASTER_SWITCH,
244 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
245 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
246 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
247 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
248 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
251 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
252 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
254 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
255 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
256 { } /* end */
257};
258
259static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
260 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
261 ALC262_HIPPO_MASTER_SWITCH,
262 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
263 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
264 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
265 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
268 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
269 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
270 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
271 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272 { } /* end */
273};
274
275/* mute/unmute internal speaker according to the hp jack and mute state */
276static void alc262_hippo_setup(struct hda_codec *codec)
277{
278 struct alc_spec *spec = codec->spec;
279
280 spec->autocfg.hp_pins[0] = 0x15;
281 spec->autocfg.speaker_pins[0] = 0x14;
282 spec->automute = 1;
283 spec->automute_mode = ALC_AUTOMUTE_AMP;
284}
285
286static void alc262_hippo1_setup(struct hda_codec *codec)
287{
288 struct alc_spec *spec = codec->spec;
289
290 spec->autocfg.hp_pins[0] = 0x1b;
291 spec->autocfg.speaker_pins[0] = 0x14;
292 spec->automute = 1;
293 spec->automute_mode = ALC_AUTOMUTE_AMP;
294}
295
296
297static const struct snd_kcontrol_new alc262_sony_mixer[] = {
298 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
299 ALC262_HIPPO_MASTER_SWITCH,
300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
301 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
302 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
303 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
304 { } /* end */
305};
306
307static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
308 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
309 ALC262_HIPPO_MASTER_SWITCH,
310 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
311 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
312 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
313 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
314 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
315 { } /* end */
316};
317
318static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
319 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
320 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
321 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
322 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
323 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
324 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
325 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
326 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
327 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
328 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
329 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
330 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
331 { } /* end */
332};
333
334static const struct hda_verb alc262_tyan_verbs[] = {
335 /* Headphone automute */
336 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
337 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
338 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
339
340 /* P11 AUX_IN, white 4-pin connector */
341 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
342 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
343 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
344 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
345
346 {}
347};
348
349/* unsolicited event for HP jack sensing */
350static void alc262_tyan_setup(struct hda_codec *codec)
351{
352 struct alc_spec *spec = codec->spec;
353
354 spec->autocfg.hp_pins[0] = 0x1b;
355 spec->autocfg.speaker_pins[0] = 0x15;
356 spec->automute = 1;
357 spec->automute_mode = ALC_AUTOMUTE_AMP;
358}
359
360
361#define alc262_capture_mixer alc882_capture_mixer
362#define alc262_capture_alt_mixer alc882_capture_alt_mixer
363
364/*
365 * generic initialization of ADC, input mixers and output mixers
366 */
367static const struct hda_verb alc262_init_verbs[] = {
368 /*
369 * Unmute ADC0-2 and set the default input to mic-in
370 */
371 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
372 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
373 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
374 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
375 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
377
378 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
379 * mixer widget
380 * Note: PASD motherboards uses the Line In 2 as the input for
381 * front panel mic (mic 2)
382 */
383 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
386 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
388 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
389
390 /*
391 * Set up output mixers (0x0c - 0x0e)
392 */
393 /* set vol=0 to output mixers */
394 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
395 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
396 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
397 /* set up input amps for analog loopback */
398 /* Amp Indices: DAC = 0, mixer = 1 */
399 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
400 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
401 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
402 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
403 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
404 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
405
406 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
407 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
408 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
409 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
410 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
411 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
412
413 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
414 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
415 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
416 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
417 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
418
419 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
420 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
421
422 /* FIXME: use matrix-type input source selection */
423 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
424 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
425 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
426 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
428 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
429 /* Input mixer2 */
430 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
431 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
432 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
433 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
434 /* Input mixer3 */
435 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
439
440 { }
441};
442
443static const struct hda_verb alc262_eapd_verbs[] = {
444 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
445 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
446 { }
447};
448
449static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
450 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
451 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
452 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
453
454 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
455 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
456 {}
457};
458
459static const struct hda_verb alc262_sony_unsol_verbs[] = {
460 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
461 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
462 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
463
464 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
465 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
466 {}
467};
468
469static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
470 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
471 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
472 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
473 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
474 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
475 { } /* end */
476};
477
478static const struct hda_verb alc262_toshiba_s06_verbs[] = {
479 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
481 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
483 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
484 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
485 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
486 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
487 {}
488};
489
490static void alc262_toshiba_s06_setup(struct hda_codec *codec)
491{
492 struct alc_spec *spec = codec->spec;
493
494 spec->autocfg.hp_pins[0] = 0x15;
495 spec->autocfg.speaker_pins[0] = 0x14;
496 spec->ext_mic_pin = 0x18;
497 spec->int_mic_pin = 0x12;
498 spec->auto_mic = 1;
499 spec->automute = 1;
500 spec->automute_mode = ALC_AUTOMUTE_PIN;
501}
502
503/*
504 * nec model
505 * 0x15 = headphone
506 * 0x16 = internal speaker
507 * 0x18 = external mic
508 */
509
510static const struct snd_kcontrol_new alc262_nec_mixer[] = {
511 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
512 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
513
514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
516 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
517
518 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
520 { } /* end */
521};
522
523static const struct hda_verb alc262_nec_verbs[] = {
524 /* Unmute Speaker */
525 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
526
527 /* Headphone */
528 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
530
531 /* External mic to headphone */
532 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
533 /* External mic to speaker */
534 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
535 {}
536};
537
538/*
539 * fujitsu model
540 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
541 * 0x1b = port replicator headphone out
542 */
543
544static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
545 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
546 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
547 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
549 {}
550};
551
552static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
553 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
554 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
555 {}
556};
557
558static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
559 /* Front Mic pin: input vref at 50% */
560 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
561 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
562 {}
563};
564
565static const struct hda_input_mux alc262_fujitsu_capture_source = {
566 .num_items = 3,
567 .items = {
568 { "Mic", 0x0 },
569 { "Internal Mic", 0x1 },
570 { "CD", 0x4 },
571 },
572};
573
574static const struct hda_input_mux alc262_HP_capture_source = {
575 .num_items = 5,
576 .items = {
577 { "Mic", 0x0 },
578 { "Front Mic", 0x1 },
579 { "Line", 0x2 },
580 { "CD", 0x4 },
581 { "AUX IN", 0x6 },
582 },
583};
584
585static const struct hda_input_mux alc262_HP_D7000_capture_source = {
586 .num_items = 4,
587 .items = {
588 { "Mic", 0x0 },
589 { "Front Mic", 0x2 },
590 { "Line", 0x1 },
591 { "CD", 0x4 },
592 },
593};
594
595static void alc262_fujitsu_setup(struct hda_codec *codec)
596{
597 struct alc_spec *spec = codec->spec;
598
599 spec->autocfg.hp_pins[0] = 0x14;
600 spec->autocfg.hp_pins[1] = 0x1b;
601 spec->autocfg.speaker_pins[0] = 0x15;
602 spec->automute = 1;
603 spec->automute_mode = ALC_AUTOMUTE_AMP;
604}
605
606/* bind volumes of both NID 0x0c and 0x0d */
607static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
608 .ops = &snd_hda_bind_vol,
609 .values = {
610 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
611 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
612 0
613 },
614};
615
616static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
617 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
618 {
619 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
620 .name = "Master Playback Switch",
621 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
622 .info = snd_ctl_boolean_mono_info,
623 .get = alc262_hp_master_sw_get,
624 .put = alc262_hp_master_sw_put,
625 },
626 {
627 .iface = NID_MAPPING,
628 .name = "Master Playback Switch",
629 .private_value = 0x1b,
630 },
631 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
632 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
633 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
635 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
636 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
637 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
638 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
639 { } /* end */
640};
641
642static void alc262_lenovo_3000_setup(struct hda_codec *codec)
643{
644 struct alc_spec *spec = codec->spec;
645
646 spec->autocfg.hp_pins[0] = 0x1b;
647 spec->autocfg.speaker_pins[0] = 0x14;
648 spec->autocfg.speaker_pins[1] = 0x16;
649 spec->automute = 1;
650 spec->automute_mode = ALC_AUTOMUTE_AMP;
651}
652
653static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
654 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
655 {
656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
657 .name = "Master Playback Switch",
658 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
659 .info = snd_ctl_boolean_mono_info,
660 .get = alc262_hp_master_sw_get,
661 .put = alc262_hp_master_sw_put,
662 },
663 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
664 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
665 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
667 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
668 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
669 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
670 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
671 { } /* end */
672};
673
674static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
675 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
676 ALC262_HIPPO_MASTER_SWITCH,
677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
679 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
680 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
681 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
682 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
683 { } /* end */
684};
685
686/* additional init verbs for Benq laptops */
687static const struct hda_verb alc262_EAPD_verbs[] = {
688 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
689 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
690 {}
691};
692
693static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
694 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
695 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
696
697 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
698 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
699 {}
700};
701
702/* Samsung Q1 Ultra Vista model setup */
703static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
704 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
705 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
708 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
709 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
710 { } /* end */
711};
712
713static const struct hda_verb alc262_ultra_verbs[] = {
714 /* output mixer */
715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
718 /* speaker */
719 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
720 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
721 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
722 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
723 /* HP */
724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
726 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
727 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
728 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
729 /* internal mic */
730 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
731 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
732 /* ADC, choose mic */
733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
734 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
735 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
736 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
737 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
738 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
739 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
740 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
742 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
743 {}
744};
745
746/* mute/unmute internal speaker according to the hp jack and mute state */
747static void alc262_ultra_automute(struct hda_codec *codec)
748{
749 struct alc_spec *spec = codec->spec;
750 unsigned int mute;
751
752 mute = 0;
753 /* auto-mute only when HP is used as HP */
754 if (!spec->cur_mux[0]) {
755 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
756 if (spec->jack_present)
757 mute = HDA_AMP_MUTE;
758 }
759 /* mute/unmute internal speaker */
760 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
761 HDA_AMP_MUTE, mute);
762 /* mute/unmute HP */
763 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
764 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
765}
766
767/* unsolicited event for HP jack sensing */
768static void alc262_ultra_unsol_event(struct hda_codec *codec,
769 unsigned int res)
770{
771 if ((res >> 26) != ALC_HP_EVENT)
772 return;
773 alc262_ultra_automute(codec);
774}
775
776static const struct hda_input_mux alc262_ultra_capture_source = {
777 .num_items = 2,
778 .items = {
779 { "Mic", 0x1 },
780 { "Headphone", 0x7 },
781 },
782};
783
784static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
785 struct snd_ctl_elem_value *ucontrol)
786{
787 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
788 struct alc_spec *spec = codec->spec;
789 int ret;
790
791 ret = alc_mux_enum_put(kcontrol, ucontrol);
792 if (!ret)
793 return 0;
794 /* reprogram the HP pin as mic or HP according to the input source */
795 snd_hda_codec_write_cache(codec, 0x15, 0,
796 AC_VERB_SET_PIN_WIDGET_CONTROL,
797 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
798 alc262_ultra_automute(codec); /* mute/unmute HP */
799 return ret;
800}
801
802static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
803 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
804 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
805 {
806 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
807 .name = "Capture Source",
808 .info = alc_mux_enum_info,
809 .get = alc_mux_enum_get,
810 .put = alc262_ultra_mux_enum_put,
811 },
812 {
813 .iface = NID_MAPPING,
814 .name = "Capture Source",
815 .private_value = 0x15,
816 },
817 { } /* end */
818};
819
820static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
821 /*
822 * Unmute ADC0-2 and set the default input to mic-in
823 */
824 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
826 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
827 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
828 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
829 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
830
831 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
832 * mixer widget
833 * Note: PASD motherboards uses the Line In 2 as the input for
834 * front panel mic (mic 2)
835 */
836 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
842 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
843 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
844
845 /*
846 * Set up output mixers (0x0c - 0x0e)
847 */
848 /* set vol=0 to output mixers */
849 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
850 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
851 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
852
853 /* set up input amps for analog loopback */
854 /* Amp Indices: DAC = 0, mixer = 1 */
855 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
856 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
857 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
858 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
859 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
860 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
861
862 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
864 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
865
866 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
867 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
868
869 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
870 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
871
872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
873 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
874 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
875 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
876 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
877
878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
879 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
880 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
881 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
882 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
883 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
884
885
886 /* FIXME: use matrix-type input source selection */
887 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
888 /* Input mixer1: only unmute Mic */
889 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
890 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
891 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
892 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
893 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
894 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
895 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
898 /* Input mixer2 */
899 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
900 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
901 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
902 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
903 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
904 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
905 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
906 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
907 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
908 /* Input mixer3 */
909 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
911 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
912 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
918
919 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
920
921 { }
922};
923
924static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
925 /*
926 * Unmute ADC0-2 and set the default input to mic-in
927 */
928 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
929 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
930 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
931 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
932 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
933 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
934
935 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
936 * mixer widget
937 * Note: PASD motherboards uses the Line In 2 as the input for front
938 * panel mic (mic 2)
939 */
940 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
941 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
942 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
943 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
944 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
945 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
946 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
947 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
948 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
949 /*
950 * Set up output mixers (0x0c - 0x0e)
951 */
952 /* set vol=0 to output mixers */
953 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
954 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
955 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
956
957 /* set up input amps for analog loopback */
958 /* Amp Indices: DAC = 0, mixer = 1 */
959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
961 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
962 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
963 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
964 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
965
966
967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
968 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
969 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
970 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
971 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
973 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
974
975 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
976 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
977
978 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
979 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
980
981 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
982 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
983 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
984 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
985 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
986 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
987
988 /* FIXME: use matrix-type input source selection */
989 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
990 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
991 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
996 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
998 /* Input mixer2 */
999 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1000 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
1002 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
1003 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
1004 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
1005 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
1006 /* Input mixer3 */
1007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1009 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
1010 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
1011 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
1012 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
1013 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
1014
1015 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1016
1017 { }
1018};
1019
1020static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
1021
1022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
1023 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1024 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
1025
1026 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
1027 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
1028 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
1029 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
1030
1031 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
1032 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1033 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1034 {}
1035};
1036
1037/*
1038 * configuration and preset
1039 */
1040static const char * const alc262_models[ALC262_MODEL_LAST] = {
1041 [ALC262_BASIC] = "basic",
1042 [ALC262_HIPPO] = "hippo",
1043 [ALC262_HIPPO_1] = "hippo_1",
1044 [ALC262_FUJITSU] = "fujitsu",
1045 [ALC262_HP_BPC] = "hp-bpc",
1046 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
1047 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
1048 [ALC262_HP_RP5700] = "hp-rp5700",
1049 [ALC262_BENQ_ED8] = "benq",
1050 [ALC262_BENQ_T31] = "benq-t31",
1051 [ALC262_SONY_ASSAMD] = "sony-assamd",
1052 [ALC262_TOSHIBA_S06] = "toshiba-s06",
1053 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
1054 [ALC262_ULTRA] = "ultra",
1055 [ALC262_LENOVO_3000] = "lenovo-3000",
1056 [ALC262_NEC] = "nec",
1057 [ALC262_TYAN] = "tyan",
1058 [ALC262_AUTO] = "auto",
1059};
1060
1061static const struct snd_pci_quirk alc262_cfg_tbl[] = {
1062 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
1063 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
1064 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
1065 ALC262_HP_BPC),
1066 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
1067 ALC262_HP_BPC),
1068 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
1069 ALC262_HP_BPC),
1070 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
1071 ALC262_AUTO),
1072 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
1073 ALC262_HP_BPC),
1074 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
1075 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
1076 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
1077 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
1078 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
1079 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
1080 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
1081 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
1082 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
1083 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
1084 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
1085 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
1086 ALC262_HP_TC_T5735),
1087 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
1088 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
1089 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
1090 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
1091 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
1092 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
1093 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
1094 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
1095#if 0 /* disable the quirk since model=auto works better in recent versions */
1096 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
1097 ALC262_SONY_ASSAMD),
1098#endif
1099 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
1100 ALC262_TOSHIBA_RX1),
1101 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
1102 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
1103 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
1104 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
1105 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
1106 ALC262_ULTRA),
1107 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
1108 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
1109 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
1110 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
1111 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
1112 {}
1113};
1114
1115static const struct alc_config_preset alc262_presets[] = {
1116 [ALC262_BASIC] = {
1117 .mixers = { alc262_base_mixer },
1118 .init_verbs = { alc262_init_verbs },
1119 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1120 .dac_nids = alc262_dac_nids,
1121 .hp_nid = 0x03,
1122 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1123 .channel_mode = alc262_modes,
1124 .input_mux = &alc262_capture_source,
1125 },
1126 [ALC262_HIPPO] = {
1127 .mixers = { alc262_hippo_mixer },
1128 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
1129 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1130 .dac_nids = alc262_dac_nids,
1131 .hp_nid = 0x03,
1132 .dig_out_nid = ALC262_DIGOUT_NID,
1133 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1134 .channel_mode = alc262_modes,
1135 .input_mux = &alc262_capture_source,
1136 .unsol_event = alc_sku_unsol_event,
1137 .setup = alc262_hippo_setup,
1138 .init_hook = alc_inithook,
1139 },
1140 [ALC262_HIPPO_1] = {
1141 .mixers = { alc262_hippo1_mixer },
1142 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
1143 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1144 .dac_nids = alc262_dac_nids,
1145 .hp_nid = 0x02,
1146 .dig_out_nid = ALC262_DIGOUT_NID,
1147 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1148 .channel_mode = alc262_modes,
1149 .input_mux = &alc262_capture_source,
1150 .unsol_event = alc_sku_unsol_event,
1151 .setup = alc262_hippo1_setup,
1152 .init_hook = alc_inithook,
1153 },
1154 [ALC262_FUJITSU] = {
1155 .mixers = { alc262_fujitsu_mixer },
1156 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
1157 alc262_fujitsu_unsol_verbs },
1158 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1159 .dac_nids = alc262_dac_nids,
1160 .hp_nid = 0x03,
1161 .dig_out_nid = ALC262_DIGOUT_NID,
1162 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1163 .channel_mode = alc262_modes,
1164 .input_mux = &alc262_fujitsu_capture_source,
1165 .unsol_event = alc_sku_unsol_event,
1166 .setup = alc262_fujitsu_setup,
1167 .init_hook = alc_inithook,
1168 },
1169 [ALC262_HP_BPC] = {
1170 .mixers = { alc262_HP_BPC_mixer },
1171 .init_verbs = { alc262_HP_BPC_init_verbs },
1172 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1173 .dac_nids = alc262_dac_nids,
1174 .hp_nid = 0x03,
1175 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1176 .channel_mode = alc262_modes,
1177 .input_mux = &alc262_HP_capture_source,
1178 .unsol_event = alc_sku_unsol_event,
1179 .setup = alc262_hp_bpc_setup,
1180 .init_hook = alc_inithook,
1181 },
1182 [ALC262_HP_BPC_D7000_WF] = {
1183 .mixers = { alc262_HP_BPC_WildWest_mixer },
1184 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
1185 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1186 .dac_nids = alc262_dac_nids,
1187 .hp_nid = 0x03,
1188 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1189 .channel_mode = alc262_modes,
1190 .input_mux = &alc262_HP_D7000_capture_source,
1191 .unsol_event = alc_sku_unsol_event,
1192 .setup = alc262_hp_wildwest_setup,
1193 .init_hook = alc_inithook,
1194 },
1195 [ALC262_HP_BPC_D7000_WL] = {
1196 .mixers = { alc262_HP_BPC_WildWest_mixer,
1197 alc262_HP_BPC_WildWest_option_mixer },
1198 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
1199 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1200 .dac_nids = alc262_dac_nids,
1201 .hp_nid = 0x03,
1202 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1203 .channel_mode = alc262_modes,
1204 .input_mux = &alc262_HP_D7000_capture_source,
1205 .unsol_event = alc_sku_unsol_event,
1206 .setup = alc262_hp_wildwest_setup,
1207 .init_hook = alc_inithook,
1208 },
1209 [ALC262_HP_TC_T5735] = {
1210 .mixers = { alc262_hp_t5735_mixer },
1211 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
1212 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1213 .dac_nids = alc262_dac_nids,
1214 .hp_nid = 0x03,
1215 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1216 .channel_mode = alc262_modes,
1217 .input_mux = &alc262_capture_source,
1218 .unsol_event = alc_sku_unsol_event,
1219 .setup = alc262_hp_t5735_setup,
1220 .init_hook = alc_inithook,
1221 },
1222 [ALC262_HP_RP5700] = {
1223 .mixers = { alc262_hp_rp5700_mixer },
1224 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
1225 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1226 .dac_nids = alc262_dac_nids,
1227 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1228 .channel_mode = alc262_modes,
1229 .input_mux = &alc262_hp_rp5700_capture_source,
1230 },
1231 [ALC262_BENQ_ED8] = {
1232 .mixers = { alc262_base_mixer },
1233 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
1234 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1235 .dac_nids = alc262_dac_nids,
1236 .hp_nid = 0x03,
1237 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1238 .channel_mode = alc262_modes,
1239 .input_mux = &alc262_capture_source,
1240 },
1241 [ALC262_SONY_ASSAMD] = {
1242 .mixers = { alc262_sony_mixer },
1243 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
1244 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1245 .dac_nids = alc262_dac_nids,
1246 .hp_nid = 0x02,
1247 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1248 .channel_mode = alc262_modes,
1249 .input_mux = &alc262_capture_source,
1250 .unsol_event = alc_sku_unsol_event,
1251 .setup = alc262_hippo_setup,
1252 .init_hook = alc_inithook,
1253 },
1254 [ALC262_BENQ_T31] = {
1255 .mixers = { alc262_benq_t31_mixer },
1256 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
1257 alc_hp15_unsol_verbs },
1258 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1259 .dac_nids = alc262_dac_nids,
1260 .hp_nid = 0x03,
1261 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1262 .channel_mode = alc262_modes,
1263 .input_mux = &alc262_capture_source,
1264 .unsol_event = alc_sku_unsol_event,
1265 .setup = alc262_hippo_setup,
1266 .init_hook = alc_inithook,
1267 },
1268 [ALC262_ULTRA] = {
1269 .mixers = { alc262_ultra_mixer },
1270 .cap_mixer = alc262_ultra_capture_mixer,
1271 .init_verbs = { alc262_ultra_verbs },
1272 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1273 .dac_nids = alc262_dac_nids,
1274 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1275 .channel_mode = alc262_modes,
1276 .input_mux = &alc262_ultra_capture_source,
1277 .adc_nids = alc262_adc_nids, /* ADC0 */
1278 .capsrc_nids = alc262_capsrc_nids,
1279 .num_adc_nids = 1, /* single ADC */
1280 .unsol_event = alc262_ultra_unsol_event,
1281 .init_hook = alc262_ultra_automute,
1282 },
1283 [ALC262_LENOVO_3000] = {
1284 .mixers = { alc262_lenovo_3000_mixer },
1285 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
1286 alc262_lenovo_3000_unsol_verbs,
1287 alc262_lenovo_3000_init_verbs },
1288 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1289 .dac_nids = alc262_dac_nids,
1290 .hp_nid = 0x03,
1291 .dig_out_nid = ALC262_DIGOUT_NID,
1292 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1293 .channel_mode = alc262_modes,
1294 .input_mux = &alc262_fujitsu_capture_source,
1295 .unsol_event = alc_sku_unsol_event,
1296 .setup = alc262_lenovo_3000_setup,
1297 .init_hook = alc_inithook,
1298 },
1299 [ALC262_NEC] = {
1300 .mixers = { alc262_nec_mixer },
1301 .init_verbs = { alc262_nec_verbs },
1302 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1303 .dac_nids = alc262_dac_nids,
1304 .hp_nid = 0x03,
1305 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1306 .channel_mode = alc262_modes,
1307 .input_mux = &alc262_capture_source,
1308 },
1309 [ALC262_TOSHIBA_S06] = {
1310 .mixers = { alc262_toshiba_s06_mixer },
1311 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
1312 alc262_eapd_verbs },
1313 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1314 .capsrc_nids = alc262_dmic_capsrc_nids,
1315 .dac_nids = alc262_dac_nids,
1316 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
1317 .num_adc_nids = 1, /* single ADC */
1318 .dig_out_nid = ALC262_DIGOUT_NID,
1319 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1320 .channel_mode = alc262_modes,
1321 .unsol_event = alc_sku_unsol_event,
1322 .setup = alc262_toshiba_s06_setup,
1323 .init_hook = alc_inithook,
1324 },
1325 [ALC262_TOSHIBA_RX1] = {
1326 .mixers = { alc262_toshiba_rx1_mixer },
1327 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
1328 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1329 .dac_nids = alc262_dac_nids,
1330 .hp_nid = 0x03,
1331 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1332 .channel_mode = alc262_modes,
1333 .input_mux = &alc262_capture_source,
1334 .unsol_event = alc_sku_unsol_event,
1335 .setup = alc262_hippo_setup,
1336 .init_hook = alc_inithook,
1337 },
1338 [ALC262_TYAN] = {
1339 .mixers = { alc262_tyan_mixer },
1340 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
1341 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1342 .dac_nids = alc262_dac_nids,
1343 .hp_nid = 0x02,
1344 .dig_out_nid = ALC262_DIGOUT_NID,
1345 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1346 .channel_mode = alc262_modes,
1347 .input_mux = &alc262_capture_source,
1348 .unsol_event = alc_sku_unsol_event,
1349 .setup = alc262_tyan_setup,
1350 .init_hook = alc_hp_automute,
1351 },
1352};
1353
diff --git a/sound/pci/hda/alc268_quirks.c b/sound/pci/hda/alc268_quirks.c
new file mode 100644
index 00000000000..be58bf2f3ae
--- /dev/null
+++ b/sound/pci/hda/alc268_quirks.c
@@ -0,0 +1,636 @@
1/*
2 * ALC267/ALC268 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC268 models */
7enum {
8 ALC268_AUTO,
9 ALC267_QUANTA_IL1,
10 ALC268_3ST,
11 ALC268_TOSHIBA,
12 ALC268_ACER,
13 ALC268_ACER_DMIC,
14 ALC268_ACER_ASPIRE_ONE,
15 ALC268_DELL,
16 ALC268_ZEPTO,
17#ifdef CONFIG_SND_DEBUG
18 ALC268_TEST,
19#endif
20 ALC268_MODEL_LAST /* last tag */
21};
22
23/*
24 * ALC268 channel source setting (2 channel)
25 */
26#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
27#define alc268_modes alc260_modes
28
29static const hda_nid_t alc268_dac_nids[2] = {
30 /* front, hp */
31 0x02, 0x03
32};
33
34static const hda_nid_t alc268_adc_nids[2] = {
35 /* ADC0-1 */
36 0x08, 0x07
37};
38
39static const hda_nid_t alc268_adc_nids_alt[1] = {
40 /* ADC0 */
41 0x08
42};
43
44static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
45
46static const struct snd_kcontrol_new alc268_base_mixer[] = {
47 /* output mixer control */
48 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
49 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
50 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
51 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
52 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
53 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
54 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
55 { }
56};
57
58static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
59 /* output mixer control */
60 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
61 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
62 ALC262_HIPPO_MASTER_SWITCH,
63 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
65 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
66 { }
67};
68
69static const struct hda_verb alc268_eapd_verbs[] = {
70 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
71 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
72 { }
73};
74
75/* Toshiba specific */
76static const struct hda_verb alc268_toshiba_verbs[] = {
77 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
78 { } /* end */
79};
80
81/* Acer specific */
82/* bind volumes of both NID 0x02 and 0x03 */
83static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
84 .ops = &snd_hda_bind_vol,
85 .values = {
86 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
87 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
88 0
89 },
90};
91
92static void alc268_acer_setup(struct hda_codec *codec)
93{
94 struct alc_spec *spec = codec->spec;
95
96 spec->autocfg.hp_pins[0] = 0x14;
97 spec->autocfg.speaker_pins[0] = 0x15;
98 spec->automute = 1;
99 spec->automute_mode = ALC_AUTOMUTE_AMP;
100}
101
102#define alc268_acer_master_sw_get alc262_hp_master_sw_get
103#define alc268_acer_master_sw_put alc262_hp_master_sw_put
104
105static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
106 /* output mixer control */
107 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
108 {
109 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
110 .name = "Master Playback Switch",
111 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
112 .info = snd_ctl_boolean_mono_info,
113 .get = alc268_acer_master_sw_get,
114 .put = alc268_acer_master_sw_put,
115 },
116 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
117 { }
118};
119
120static const struct snd_kcontrol_new alc268_acer_mixer[] = {
121 /* output mixer control */
122 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
123 {
124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
125 .name = "Master Playback Switch",
126 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
127 .info = snd_ctl_boolean_mono_info,
128 .get = alc268_acer_master_sw_get,
129 .put = alc268_acer_master_sw_put,
130 },
131 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
132 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
133 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
134 { }
135};
136
137static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
138 /* output mixer control */
139 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
140 {
141 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
142 .name = "Master Playback Switch",
143 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
144 .info = snd_ctl_boolean_mono_info,
145 .get = alc268_acer_master_sw_get,
146 .put = alc268_acer_master_sw_put,
147 },
148 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
149 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
150 { }
151};
152
153static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
154 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
155 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
156 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
157 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
158 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
159 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
160 { }
161};
162
163static const struct hda_verb alc268_acer_verbs[] = {
164 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
165 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
166 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
167 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
168 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
169 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
170 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
171 { }
172};
173
174/* unsolicited event for HP jack sensing */
175#define alc268_toshiba_setup alc262_hippo_setup
176
177static void alc268_acer_lc_setup(struct hda_codec *codec)
178{
179 struct alc_spec *spec = codec->spec;
180 spec->autocfg.hp_pins[0] = 0x15;
181 spec->autocfg.speaker_pins[0] = 0x14;
182 spec->automute = 1;
183 spec->automute_mode = ALC_AUTOMUTE_AMP;
184 spec->ext_mic_pin = 0x18;
185 spec->int_mic_pin = 0x12;
186 spec->auto_mic = 1;
187}
188
189static const struct snd_kcontrol_new alc268_dell_mixer[] = {
190 /* output mixer control */
191 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
192 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
195 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
196 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
197 { }
198};
199
200static const struct hda_verb alc268_dell_verbs[] = {
201 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
203 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
204 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
205 { }
206};
207
208/* mute/unmute internal speaker according to the hp jack and mute state */
209static void alc268_dell_setup(struct hda_codec *codec)
210{
211 struct alc_spec *spec = codec->spec;
212
213 spec->autocfg.hp_pins[0] = 0x15;
214 spec->autocfg.speaker_pins[0] = 0x14;
215 spec->ext_mic_pin = 0x18;
216 spec->int_mic_pin = 0x19;
217 spec->auto_mic = 1;
218 spec->automute = 1;
219 spec->automute_mode = ALC_AUTOMUTE_PIN;
220}
221
222static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
223 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
224 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
225 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
226 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
227 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
228 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
229 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
230 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
231 { }
232};
233
234static const struct hda_verb alc267_quanta_il1_verbs[] = {
235 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
236 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
237 { }
238};
239
240static void alc267_quanta_il1_setup(struct hda_codec *codec)
241{
242 struct alc_spec *spec = codec->spec;
243 spec->autocfg.hp_pins[0] = 0x15;
244 spec->autocfg.speaker_pins[0] = 0x14;
245 spec->ext_mic_pin = 0x18;
246 spec->int_mic_pin = 0x19;
247 spec->auto_mic = 1;
248 spec->automute = 1;
249 spec->automute_mode = ALC_AUTOMUTE_PIN;
250}
251
252/*
253 * generic initialization of ADC, input mixers and output mixers
254 */
255static const struct hda_verb alc268_base_init_verbs[] = {
256 /* Unmute DAC0-1 and set vol = 0 */
257 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
258 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
259
260 /*
261 * Set up output mixers (0x0c - 0x0e)
262 */
263 /* set vol=0 to output mixers */
264 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
265 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
266
267 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
268 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
269
270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
272 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
273 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
274 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
276 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
277 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
278
279 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
280 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
281 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
282 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
283 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
284
285 /* set PCBEEP vol = 0, mute connections */
286 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
287 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
288 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
289
290 /* Unmute Selector 23h,24h and set the default input to mic-in */
291
292 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
293 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
294 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
296
297 { }
298};
299
300/* only for model=test */
301#ifdef CONFIG_SND_DEBUG
302/*
303 * generic initialization of ADC, input mixers and output mixers
304 */
305static const struct hda_verb alc268_volume_init_verbs[] = {
306 /* set output DAC */
307 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
308 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
309
310 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
311 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
312 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
313 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
314 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
315
316 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
317 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
318 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
319
320 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
321 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
322 { }
323};
324#endif /* CONFIG_SND_DEBUG */
325
326static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
327 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
328 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
329 { } /* end */
330};
331
332static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
333 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
334 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
335 _DEFINE_CAPSRC(1),
336 { } /* end */
337};
338
339static const struct snd_kcontrol_new alc268_capture_mixer[] = {
340 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
341 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
342 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
343 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
344 _DEFINE_CAPSRC(2),
345 { } /* end */
346};
347
348static const struct hda_input_mux alc268_capture_source = {
349 .num_items = 4,
350 .items = {
351 { "Mic", 0x0 },
352 { "Front Mic", 0x1 },
353 { "Line", 0x2 },
354 { "CD", 0x3 },
355 },
356};
357
358static const struct hda_input_mux alc268_acer_capture_source = {
359 .num_items = 3,
360 .items = {
361 { "Mic", 0x0 },
362 { "Internal Mic", 0x1 },
363 { "Line", 0x2 },
364 },
365};
366
367static const struct hda_input_mux alc268_acer_dmic_capture_source = {
368 .num_items = 3,
369 .items = {
370 { "Mic", 0x0 },
371 { "Internal Mic", 0x6 },
372 { "Line", 0x2 },
373 },
374};
375
376#ifdef CONFIG_SND_DEBUG
377static const struct snd_kcontrol_new alc268_test_mixer[] = {
378 /* Volume widgets */
379 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
380 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
381 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
382 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
383 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
384 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
385 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
386 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
387 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
388 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
389 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
390 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
391 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
392 /* The below appears problematic on some hardwares */
393 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
394 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
395 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
396 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
397 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
398
399 /* Modes for retasking pin widgets */
400 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
401 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
402 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
403 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
404
405 /* Controls for GPIO pins, assuming they are configured as outputs */
406 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
407 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
408 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
409 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
410
411 /* Switches to allow the digital SPDIF output pin to be enabled.
412 * The ALC268 does not have an SPDIF input.
413 */
414 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
415
416 /* A switch allowing EAPD to be enabled. Some laptops seem to use
417 * this output to turn on an external amplifier.
418 */
419 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
420 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
421
422 { } /* end */
423};
424#endif
425
426/*
427 * configuration and preset
428 */
429static const char * const alc268_models[ALC268_MODEL_LAST] = {
430 [ALC267_QUANTA_IL1] = "quanta-il1",
431 [ALC268_3ST] = "3stack",
432 [ALC268_TOSHIBA] = "toshiba",
433 [ALC268_ACER] = "acer",
434 [ALC268_ACER_DMIC] = "acer-dmic",
435 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
436 [ALC268_DELL] = "dell",
437 [ALC268_ZEPTO] = "zepto",
438#ifdef CONFIG_SND_DEBUG
439 [ALC268_TEST] = "test",
440#endif
441 [ALC268_AUTO] = "auto",
442};
443
444static const struct snd_pci_quirk alc268_cfg_tbl[] = {
445 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
446 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
447 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
448 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
449 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
450 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
451 ALC268_ACER_ASPIRE_ONE),
452 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
453 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
454 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
455 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
456 /* almost compatible with toshiba but with optional digital outs;
457 * auto-probing seems working fine
458 */
459 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
460 ALC268_AUTO),
461 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
462 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
463 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
464 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
465 {}
466};
467
468/* Toshiba laptops have no unique PCI SSID but only codec SSID */
469static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
470 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
471 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
472 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
473 ALC268_TOSHIBA),
474 {}
475};
476
477static const struct alc_config_preset alc268_presets[] = {
478 [ALC267_QUANTA_IL1] = {
479 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
480 alc268_capture_nosrc_mixer },
481 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
482 alc267_quanta_il1_verbs },
483 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
484 .dac_nids = alc268_dac_nids,
485 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
486 .adc_nids = alc268_adc_nids_alt,
487 .hp_nid = 0x03,
488 .num_channel_mode = ARRAY_SIZE(alc268_modes),
489 .channel_mode = alc268_modes,
490 .unsol_event = alc_sku_unsol_event,
491 .setup = alc267_quanta_il1_setup,
492 .init_hook = alc_inithook,
493 },
494 [ALC268_3ST] = {
495 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
496 alc268_beep_mixer },
497 .init_verbs = { alc268_base_init_verbs },
498 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
499 .dac_nids = alc268_dac_nids,
500 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
501 .adc_nids = alc268_adc_nids_alt,
502 .capsrc_nids = alc268_capsrc_nids,
503 .hp_nid = 0x03,
504 .dig_out_nid = ALC268_DIGOUT_NID,
505 .num_channel_mode = ARRAY_SIZE(alc268_modes),
506 .channel_mode = alc268_modes,
507 .input_mux = &alc268_capture_source,
508 },
509 [ALC268_TOSHIBA] = {
510 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
511 alc268_beep_mixer },
512 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
513 alc268_toshiba_verbs },
514 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
515 .dac_nids = alc268_dac_nids,
516 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
517 .adc_nids = alc268_adc_nids_alt,
518 .capsrc_nids = alc268_capsrc_nids,
519 .hp_nid = 0x03,
520 .num_channel_mode = ARRAY_SIZE(alc268_modes),
521 .channel_mode = alc268_modes,
522 .input_mux = &alc268_capture_source,
523 .unsol_event = alc_sku_unsol_event,
524 .setup = alc268_toshiba_setup,
525 .init_hook = alc_inithook,
526 },
527 [ALC268_ACER] = {
528 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
529 alc268_beep_mixer },
530 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
531 alc268_acer_verbs },
532 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
533 .dac_nids = alc268_dac_nids,
534 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
535 .adc_nids = alc268_adc_nids_alt,
536 .capsrc_nids = alc268_capsrc_nids,
537 .hp_nid = 0x02,
538 .num_channel_mode = ARRAY_SIZE(alc268_modes),
539 .channel_mode = alc268_modes,
540 .input_mux = &alc268_acer_capture_source,
541 .unsol_event = alc_sku_unsol_event,
542 .setup = alc268_acer_setup,
543 .init_hook = alc_inithook,
544 },
545 [ALC268_ACER_DMIC] = {
546 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
547 alc268_beep_mixer },
548 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
549 alc268_acer_verbs },
550 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
551 .dac_nids = alc268_dac_nids,
552 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
553 .adc_nids = alc268_adc_nids_alt,
554 .capsrc_nids = alc268_capsrc_nids,
555 .hp_nid = 0x02,
556 .num_channel_mode = ARRAY_SIZE(alc268_modes),
557 .channel_mode = alc268_modes,
558 .input_mux = &alc268_acer_dmic_capture_source,
559 .unsol_event = alc_sku_unsol_event,
560 .setup = alc268_acer_setup,
561 .init_hook = alc_inithook,
562 },
563 [ALC268_ACER_ASPIRE_ONE] = {
564 .mixers = { alc268_acer_aspire_one_mixer,
565 alc268_beep_mixer,
566 alc268_capture_nosrc_mixer },
567 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
568 alc268_acer_aspire_one_verbs },
569 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
570 .dac_nids = alc268_dac_nids,
571 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
572 .adc_nids = alc268_adc_nids_alt,
573 .capsrc_nids = alc268_capsrc_nids,
574 .hp_nid = 0x03,
575 .num_channel_mode = ARRAY_SIZE(alc268_modes),
576 .channel_mode = alc268_modes,
577 .unsol_event = alc_sku_unsol_event,
578 .setup = alc268_acer_lc_setup,
579 .init_hook = alc_inithook,
580 },
581 [ALC268_DELL] = {
582 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
583 alc268_capture_nosrc_mixer },
584 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
585 alc268_dell_verbs },
586 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
587 .dac_nids = alc268_dac_nids,
588 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
589 .adc_nids = alc268_adc_nids_alt,
590 .capsrc_nids = alc268_capsrc_nids,
591 .hp_nid = 0x02,
592 .num_channel_mode = ARRAY_SIZE(alc268_modes),
593 .channel_mode = alc268_modes,
594 .unsol_event = alc_sku_unsol_event,
595 .setup = alc268_dell_setup,
596 .init_hook = alc_inithook,
597 },
598 [ALC268_ZEPTO] = {
599 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
600 alc268_beep_mixer },
601 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
602 alc268_toshiba_verbs },
603 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
604 .dac_nids = alc268_dac_nids,
605 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
606 .adc_nids = alc268_adc_nids_alt,
607 .capsrc_nids = alc268_capsrc_nids,
608 .hp_nid = 0x03,
609 .dig_out_nid = ALC268_DIGOUT_NID,
610 .num_channel_mode = ARRAY_SIZE(alc268_modes),
611 .channel_mode = alc268_modes,
612 .input_mux = &alc268_capture_source,
613 .unsol_event = alc_sku_unsol_event,
614 .setup = alc268_toshiba_setup,
615 .init_hook = alc_inithook,
616 },
617#ifdef CONFIG_SND_DEBUG
618 [ALC268_TEST] = {
619 .mixers = { alc268_test_mixer, alc268_capture_mixer },
620 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
621 alc268_volume_init_verbs,
622 alc268_beep_init_verbs },
623 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
624 .dac_nids = alc268_dac_nids,
625 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
626 .adc_nids = alc268_adc_nids_alt,
627 .capsrc_nids = alc268_capsrc_nids,
628 .hp_nid = 0x03,
629 .dig_out_nid = ALC268_DIGOUT_NID,
630 .num_channel_mode = ARRAY_SIZE(alc268_modes),
631 .channel_mode = alc268_modes,
632 .input_mux = &alc268_capture_source,
633 },
634#endif
635};
636
diff --git a/sound/pci/hda/alc269_quirks.c b/sound/pci/hda/alc269_quirks.c
new file mode 100644
index 00000000000..14fdcf29b15
--- /dev/null
+++ b/sound/pci/hda/alc269_quirks.c
@@ -0,0 +1,681 @@
1/*
2 * ALC269/ALC270/ALC275/ALC276 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC269 models */
7enum {
8 ALC269_AUTO,
9 ALC269_BASIC,
10 ALC269_QUANTA_FL1,
11 ALC269_AMIC,
12 ALC269_DMIC,
13 ALC269VB_AMIC,
14 ALC269VB_DMIC,
15 ALC269_FUJITSU,
16 ALC269_LIFEBOOK,
17 ALC271_ACER,
18 ALC269_MODEL_LAST /* last tag */
19};
20
21/*
22 * ALC269 channel source setting (2 channel)
23 */
24#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
25
26#define alc269_dac_nids alc260_dac_nids
27
28static const hda_nid_t alc269_adc_nids[1] = {
29 /* ADC1 */
30 0x08,
31};
32
33static const hda_nid_t alc269_capsrc_nids[1] = {
34 0x23,
35};
36
37static const hda_nid_t alc269vb_adc_nids[1] = {
38 /* ADC1 */
39 0x09,
40};
41
42static const hda_nid_t alc269vb_capsrc_nids[1] = {
43 0x22,
44};
45
46#define alc269_modes alc260_modes
47#define alc269_capture_source alc880_lg_lw_capture_source
48
49static const struct snd_kcontrol_new alc269_base_mixer[] = {
50 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
51 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
52 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
53 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
54 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
55 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
56 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
57 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
58 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
59 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
60 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
61 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
62 { } /* end */
63};
64
65static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
66 /* output mixer control */
67 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
68 {
69 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
70 .name = "Master Playback Switch",
71 .subdevice = HDA_SUBDEV_AMP_FLAG,
72 .info = snd_hda_mixer_amp_switch_info,
73 .get = snd_hda_mixer_amp_switch_get,
74 .put = alc268_acer_master_sw_put,
75 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
76 },
77 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
78 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
79 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
80 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
81 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
82 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
83 { }
84};
85
86static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
87 /* output mixer control */
88 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
89 {
90 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
91 .name = "Master Playback Switch",
92 .subdevice = HDA_SUBDEV_AMP_FLAG,
93 .info = snd_hda_mixer_amp_switch_info,
94 .get = snd_hda_mixer_amp_switch_get,
95 .put = alc268_acer_master_sw_put,
96 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
97 },
98 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
99 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
100 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
101 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
102 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
103 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
104 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
105 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
106 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
107 { }
108};
109
110static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
111 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
112 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
113 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
114 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
115 { } /* end */
116};
117
118static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
119 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
120 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
121 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
122 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
123 { } /* end */
124};
125
126static const struct snd_kcontrol_new alc269_asus_mixer[] = {
127 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
128 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
129 { } /* end */
130};
131
132/* capture mixer elements */
133static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
134 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
135 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
136 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
137 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
138 { } /* end */
139};
140
141static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
142 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
143 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
144 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
145 { } /* end */
146};
147
148static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
149 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
150 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
151 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
152 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
153 { } /* end */
154};
155
156static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
157 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
158 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
159 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
160 { } /* end */
161};
162
163/* FSC amilo */
164#define alc269_fujitsu_mixer alc269_laptop_mixer
165
166static const struct hda_verb alc269_quanta_fl1_verbs[] = {
167 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
168 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
169 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
170 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
171 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
172 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
173 { }
174};
175
176static const struct hda_verb alc269_lifebook_verbs[] = {
177 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
178 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
179 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
180 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
181 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
182 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
183 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
184 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
185 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
186 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
187 { }
188};
189
190/* toggle speaker-output according to the hp-jack state */
191static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
192{
193 alc_hp_automute(codec);
194
195 snd_hda_codec_write(codec, 0x20, 0,
196 AC_VERB_SET_COEF_INDEX, 0x0c);
197 snd_hda_codec_write(codec, 0x20, 0,
198 AC_VERB_SET_PROC_COEF, 0x680);
199
200 snd_hda_codec_write(codec, 0x20, 0,
201 AC_VERB_SET_COEF_INDEX, 0x0c);
202 snd_hda_codec_write(codec, 0x20, 0,
203 AC_VERB_SET_PROC_COEF, 0x480);
204}
205
206#define alc269_lifebook_speaker_automute \
207 alc269_quanta_fl1_speaker_automute
208
209static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
210{
211 unsigned int present_laptop;
212 unsigned int present_dock;
213
214 present_laptop = snd_hda_jack_detect(codec, 0x18);
215 present_dock = snd_hda_jack_detect(codec, 0x1b);
216
217 /* Laptop mic port overrides dock mic port, design decision */
218 if (present_dock)
219 snd_hda_codec_write(codec, 0x23, 0,
220 AC_VERB_SET_CONNECT_SEL, 0x3);
221 if (present_laptop)
222 snd_hda_codec_write(codec, 0x23, 0,
223 AC_VERB_SET_CONNECT_SEL, 0x0);
224 if (!present_dock && !present_laptop)
225 snd_hda_codec_write(codec, 0x23, 0,
226 AC_VERB_SET_CONNECT_SEL, 0x1);
227}
228
229static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
230 unsigned int res)
231{
232 switch (res >> 26) {
233 case ALC_HP_EVENT:
234 alc269_quanta_fl1_speaker_automute(codec);
235 break;
236 case ALC_MIC_EVENT:
237 alc_mic_automute(codec);
238 break;
239 }
240}
241
242static void alc269_lifebook_unsol_event(struct hda_codec *codec,
243 unsigned int res)
244{
245 if ((res >> 26) == ALC_HP_EVENT)
246 alc269_lifebook_speaker_automute(codec);
247 if ((res >> 26) == ALC_MIC_EVENT)
248 alc269_lifebook_mic_autoswitch(codec);
249}
250
251static void alc269_quanta_fl1_setup(struct hda_codec *codec)
252{
253 struct alc_spec *spec = codec->spec;
254 spec->autocfg.hp_pins[0] = 0x15;
255 spec->autocfg.speaker_pins[0] = 0x14;
256 spec->automute_mixer_nid[0] = 0x0c;
257 spec->automute = 1;
258 spec->automute_mode = ALC_AUTOMUTE_MIXER;
259 spec->ext_mic_pin = 0x18;
260 spec->int_mic_pin = 0x19;
261 spec->auto_mic = 1;
262}
263
264static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
265{
266 alc269_quanta_fl1_speaker_automute(codec);
267 alc_mic_automute(codec);
268}
269
270static void alc269_lifebook_setup(struct hda_codec *codec)
271{
272 struct alc_spec *spec = codec->spec;
273 spec->autocfg.hp_pins[0] = 0x15;
274 spec->autocfg.hp_pins[1] = 0x1a;
275 spec->autocfg.speaker_pins[0] = 0x14;
276 spec->automute_mixer_nid[0] = 0x0c;
277 spec->automute = 1;
278 spec->automute_mode = ALC_AUTOMUTE_MIXER;
279}
280
281static void alc269_lifebook_init_hook(struct hda_codec *codec)
282{
283 alc269_lifebook_speaker_automute(codec);
284 alc269_lifebook_mic_autoswitch(codec);
285}
286
287static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
288 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
289 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
290 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
291 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
292 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
293 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
294 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
295 {}
296};
297
298static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
299 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
300 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
301 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
302 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
303 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
305 {}
306};
307
308static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
309 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
310 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
311 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
312 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
313 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
314 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
315 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
316 {}
317};
318
319static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
320 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
321 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
322 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
323 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
324 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
325 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
326 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
327 {}
328};
329
330static const struct hda_verb alc271_acer_dmic_verbs[] = {
331 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
332 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
333 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
334 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
335 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
336 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
337 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
338 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
339 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
340 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
341 { }
342};
343
344static void alc269_laptop_amic_setup(struct hda_codec *codec)
345{
346 struct alc_spec *spec = codec->spec;
347 spec->autocfg.hp_pins[0] = 0x15;
348 spec->autocfg.speaker_pins[0] = 0x14;
349 spec->automute_mixer_nid[0] = 0x0c;
350 spec->automute = 1;
351 spec->automute_mode = ALC_AUTOMUTE_MIXER;
352 spec->ext_mic_pin = 0x18;
353 spec->int_mic_pin = 0x19;
354 spec->auto_mic = 1;
355}
356
357static void alc269_laptop_dmic_setup(struct hda_codec *codec)
358{
359 struct alc_spec *spec = codec->spec;
360 spec->autocfg.hp_pins[0] = 0x15;
361 spec->autocfg.speaker_pins[0] = 0x14;
362 spec->automute_mixer_nid[0] = 0x0c;
363 spec->automute = 1;
364 spec->automute_mode = ALC_AUTOMUTE_MIXER;
365 spec->ext_mic_pin = 0x18;
366 spec->int_mic_pin = 0x12;
367 spec->auto_mic = 1;
368}
369
370static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
371{
372 struct alc_spec *spec = codec->spec;
373 spec->autocfg.hp_pins[0] = 0x21;
374 spec->autocfg.speaker_pins[0] = 0x14;
375 spec->automute_mixer_nid[0] = 0x0c;
376 spec->automute = 1;
377 spec->automute_mode = ALC_AUTOMUTE_MIXER;
378 spec->ext_mic_pin = 0x18;
379 spec->int_mic_pin = 0x19;
380 spec->auto_mic = 1;
381}
382
383static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
384{
385 struct alc_spec *spec = codec->spec;
386 spec->autocfg.hp_pins[0] = 0x21;
387 spec->autocfg.speaker_pins[0] = 0x14;
388 spec->automute_mixer_nid[0] = 0x0c;
389 spec->automute = 1;
390 spec->automute_mode = ALC_AUTOMUTE_MIXER;
391 spec->ext_mic_pin = 0x18;
392 spec->int_mic_pin = 0x12;
393 spec->auto_mic = 1;
394}
395
396/*
397 * generic initialization of ADC, input mixers and output mixers
398 */
399static const struct hda_verb alc269_init_verbs[] = {
400 /*
401 * Unmute ADC0 and set the default input to mic-in
402 */
403 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
404
405 /*
406 * Set up output mixers (0x02 - 0x03)
407 */
408 /* set vol=0 to output mixers */
409 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
410 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
411
412 /* set up input amps for analog loopback */
413 /* Amp Indices: DAC = 0, mixer = 1 */
414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
420
421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
427 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
428
429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
431
432 /* FIXME: use Mux-type input source selection */
433 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
434 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
435 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
436
437 /* set EAPD */
438 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
439 { }
440};
441
442static const struct hda_verb alc269vb_init_verbs[] = {
443 /*
444 * Unmute ADC0 and set the default input to mic-in
445 */
446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
447
448 /*
449 * Set up output mixers (0x02 - 0x03)
450 */
451 /* set vol=0 to output mixers */
452 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
453 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
454
455 /* set up input amps for analog loopback */
456 /* Amp Indices: DAC = 0, mixer = 1 */
457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
461 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
463
464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
465 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
466 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
467 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
468 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
471
472 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
473 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
474
475 /* FIXME: use Mux-type input source selection */
476 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
477 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
478 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
479
480 /* set EAPD */
481 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
482 { }
483};
484
485/*
486 * configuration and preset
487 */
488static const char * const alc269_models[ALC269_MODEL_LAST] = {
489 [ALC269_BASIC] = "basic",
490 [ALC269_QUANTA_FL1] = "quanta",
491 [ALC269_AMIC] = "laptop-amic",
492 [ALC269_DMIC] = "laptop-dmic",
493 [ALC269_FUJITSU] = "fujitsu",
494 [ALC269_LIFEBOOK] = "lifebook",
495 [ALC269_AUTO] = "auto",
496};
497
498static const struct snd_pci_quirk alc269_cfg_tbl[] = {
499 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
500 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
501 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
502 ALC269_AMIC),
503 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
504 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
505 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
506 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
507 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
508 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
509 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
510 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
511 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
512 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
513 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
514 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
515 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
516 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
517 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
518 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
519 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
520 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
521 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
522 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
523 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
524 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
525 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
526 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
527 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
528 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
529 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
530 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
531 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
532 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
533 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
534 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
535 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
536 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
537 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
538 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
539 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
540 ALC269_DMIC),
541 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
542 ALC269_DMIC),
543 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
544 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
545 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
546 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
547 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
548 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
549 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
550 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
551 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
552 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
553 {}
554};
555
556static const struct alc_config_preset alc269_presets[] = {
557 [ALC269_BASIC] = {
558 .mixers = { alc269_base_mixer },
559 .init_verbs = { alc269_init_verbs },
560 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
561 .dac_nids = alc269_dac_nids,
562 .hp_nid = 0x03,
563 .num_channel_mode = ARRAY_SIZE(alc269_modes),
564 .channel_mode = alc269_modes,
565 .input_mux = &alc269_capture_source,
566 },
567 [ALC269_QUANTA_FL1] = {
568 .mixers = { alc269_quanta_fl1_mixer },
569 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
570 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
571 .dac_nids = alc269_dac_nids,
572 .hp_nid = 0x03,
573 .num_channel_mode = ARRAY_SIZE(alc269_modes),
574 .channel_mode = alc269_modes,
575 .input_mux = &alc269_capture_source,
576 .unsol_event = alc269_quanta_fl1_unsol_event,
577 .setup = alc269_quanta_fl1_setup,
578 .init_hook = alc269_quanta_fl1_init_hook,
579 },
580 [ALC269_AMIC] = {
581 .mixers = { alc269_laptop_mixer },
582 .cap_mixer = alc269_laptop_analog_capture_mixer,
583 .init_verbs = { alc269_init_verbs,
584 alc269_laptop_amic_init_verbs },
585 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
586 .dac_nids = alc269_dac_nids,
587 .hp_nid = 0x03,
588 .num_channel_mode = ARRAY_SIZE(alc269_modes),
589 .channel_mode = alc269_modes,
590 .unsol_event = alc_sku_unsol_event,
591 .setup = alc269_laptop_amic_setup,
592 .init_hook = alc_inithook,
593 },
594 [ALC269_DMIC] = {
595 .mixers = { alc269_laptop_mixer },
596 .cap_mixer = alc269_laptop_digital_capture_mixer,
597 .init_verbs = { alc269_init_verbs,
598 alc269_laptop_dmic_init_verbs },
599 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
600 .dac_nids = alc269_dac_nids,
601 .hp_nid = 0x03,
602 .num_channel_mode = ARRAY_SIZE(alc269_modes),
603 .channel_mode = alc269_modes,
604 .unsol_event = alc_sku_unsol_event,
605 .setup = alc269_laptop_dmic_setup,
606 .init_hook = alc_inithook,
607 },
608 [ALC269VB_AMIC] = {
609 .mixers = { alc269vb_laptop_mixer },
610 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
611 .init_verbs = { alc269vb_init_verbs,
612 alc269vb_laptop_amic_init_verbs },
613 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
614 .dac_nids = alc269_dac_nids,
615 .hp_nid = 0x03,
616 .num_channel_mode = ARRAY_SIZE(alc269_modes),
617 .channel_mode = alc269_modes,
618 .unsol_event = alc_sku_unsol_event,
619 .setup = alc269vb_laptop_amic_setup,
620 .init_hook = alc_inithook,
621 },
622 [ALC269VB_DMIC] = {
623 .mixers = { alc269vb_laptop_mixer },
624 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
625 .init_verbs = { alc269vb_init_verbs,
626 alc269vb_laptop_dmic_init_verbs },
627 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
628 .dac_nids = alc269_dac_nids,
629 .hp_nid = 0x03,
630 .num_channel_mode = ARRAY_SIZE(alc269_modes),
631 .channel_mode = alc269_modes,
632 .unsol_event = alc_sku_unsol_event,
633 .setup = alc269vb_laptop_dmic_setup,
634 .init_hook = alc_inithook,
635 },
636 [ALC269_FUJITSU] = {
637 .mixers = { alc269_fujitsu_mixer },
638 .cap_mixer = alc269_laptop_digital_capture_mixer,
639 .init_verbs = { alc269_init_verbs,
640 alc269_laptop_dmic_init_verbs },
641 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
642 .dac_nids = alc269_dac_nids,
643 .hp_nid = 0x03,
644 .num_channel_mode = ARRAY_SIZE(alc269_modes),
645 .channel_mode = alc269_modes,
646 .unsol_event = alc_sku_unsol_event,
647 .setup = alc269_laptop_dmic_setup,
648 .init_hook = alc_inithook,
649 },
650 [ALC269_LIFEBOOK] = {
651 .mixers = { alc269_lifebook_mixer },
652 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
653 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
654 .dac_nids = alc269_dac_nids,
655 .hp_nid = 0x03,
656 .num_channel_mode = ARRAY_SIZE(alc269_modes),
657 .channel_mode = alc269_modes,
658 .input_mux = &alc269_capture_source,
659 .unsol_event = alc269_lifebook_unsol_event,
660 .setup = alc269_lifebook_setup,
661 .init_hook = alc269_lifebook_init_hook,
662 },
663 [ALC271_ACER] = {
664 .mixers = { alc269_asus_mixer },
665 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
666 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
667 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
668 .dac_nids = alc269_dac_nids,
669 .adc_nids = alc262_dmic_adc_nids,
670 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
671 .capsrc_nids = alc262_dmic_capsrc_nids,
672 .num_channel_mode = ARRAY_SIZE(alc269_modes),
673 .channel_mode = alc269_modes,
674 .input_mux = &alc269_capture_source,
675 .dig_out_nid = ALC880_DIGOUT_NID,
676 .unsol_event = alc_sku_unsol_event,
677 .setup = alc269vb_laptop_dmic_setup,
678 .init_hook = alc_inithook,
679 },
680};
681
diff --git a/sound/pci/hda/alc662_quirks.c b/sound/pci/hda/alc662_quirks.c
new file mode 100644
index 00000000000..e69a6ea3083
--- /dev/null
+++ b/sound/pci/hda/alc662_quirks.c
@@ -0,0 +1,1408 @@
1/*
2 * ALC662/ALC663/ALC665/ALC670 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC662 models */
7enum {
8 ALC662_AUTO,
9 ALC662_3ST_2ch_DIG,
10 ALC662_3ST_6ch_DIG,
11 ALC662_3ST_6ch,
12 ALC662_5ST_DIG,
13 ALC662_LENOVO_101E,
14 ALC662_ASUS_EEEPC_P701,
15 ALC662_ASUS_EEEPC_EP20,
16 ALC663_ASUS_M51VA,
17 ALC663_ASUS_G71V,
18 ALC663_ASUS_H13,
19 ALC663_ASUS_G50V,
20 ALC662_ECS,
21 ALC663_ASUS_MODE1,
22 ALC662_ASUS_MODE2,
23 ALC663_ASUS_MODE3,
24 ALC663_ASUS_MODE4,
25 ALC663_ASUS_MODE5,
26 ALC663_ASUS_MODE6,
27 ALC663_ASUS_MODE7,
28 ALC663_ASUS_MODE8,
29 ALC272_DELL,
30 ALC272_DELL_ZM1,
31 ALC272_SAMSUNG_NC10,
32 ALC662_MODEL_LAST,
33};
34
35#define ALC662_DIGOUT_NID 0x06
36#define ALC662_DIGIN_NID 0x0a
37
38static const hda_nid_t alc662_dac_nids[3] = {
39 /* front, rear, clfe */
40 0x02, 0x03, 0x04
41};
42
43static const hda_nid_t alc272_dac_nids[2] = {
44 0x02, 0x03
45};
46
47static const hda_nid_t alc662_adc_nids[2] = {
48 /* ADC1-2 */
49 0x09, 0x08
50};
51
52static const hda_nid_t alc272_adc_nids[1] = {
53 /* ADC1-2 */
54 0x08,
55};
56
57static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
58static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
59
60
61/* input MUX */
62/* FIXME: should be a matrix-type input source selection */
63static const struct hda_input_mux alc662_capture_source = {
64 .num_items = 4,
65 .items = {
66 { "Mic", 0x0 },
67 { "Front Mic", 0x1 },
68 { "Line", 0x2 },
69 { "CD", 0x4 },
70 },
71};
72
73static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
74 .num_items = 2,
75 .items = {
76 { "Mic", 0x1 },
77 { "Line", 0x2 },
78 },
79};
80
81static const struct hda_input_mux alc663_capture_source = {
82 .num_items = 3,
83 .items = {
84 { "Mic", 0x0 },
85 { "Front Mic", 0x1 },
86 { "Line", 0x2 },
87 },
88};
89
90#if 0 /* set to 1 for testing other input sources below */
91static const struct hda_input_mux alc272_nc10_capture_source = {
92 .num_items = 16,
93 .items = {
94 { "Autoselect Mic", 0x0 },
95 { "Internal Mic", 0x1 },
96 { "In-0x02", 0x2 },
97 { "In-0x03", 0x3 },
98 { "In-0x04", 0x4 },
99 { "In-0x05", 0x5 },
100 { "In-0x06", 0x6 },
101 { "In-0x07", 0x7 },
102 { "In-0x08", 0x8 },
103 { "In-0x09", 0x9 },
104 { "In-0x0a", 0x0a },
105 { "In-0x0b", 0x0b },
106 { "In-0x0c", 0x0c },
107 { "In-0x0d", 0x0d },
108 { "In-0x0e", 0x0e },
109 { "In-0x0f", 0x0f },
110 },
111};
112#endif
113
114/*
115 * 2ch mode
116 */
117static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
118 { 2, NULL }
119};
120
121/*
122 * 2ch mode
123 */
124static const struct hda_verb alc662_3ST_ch2_init[] = {
125 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
126 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
127 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
128 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
129 { } /* end */
130};
131
132/*
133 * 6ch mode
134 */
135static const struct hda_verb alc662_3ST_ch6_init[] = {
136 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
137 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
138 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
139 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
140 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
141 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
142 { } /* end */
143};
144
145static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
146 { 2, alc662_3ST_ch2_init },
147 { 6, alc662_3ST_ch6_init },
148};
149
150/*
151 * 2ch mode
152 */
153static const struct hda_verb alc662_sixstack_ch6_init[] = {
154 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
155 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
156 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
157 { } /* end */
158};
159
160/*
161 * 6ch mode
162 */
163static const struct hda_verb alc662_sixstack_ch8_init[] = {
164 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
165 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
166 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
167 { } /* end */
168};
169
170static const struct hda_channel_mode alc662_5stack_modes[2] = {
171 { 2, alc662_sixstack_ch6_init },
172 { 6, alc662_sixstack_ch8_init },
173};
174
175/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
176 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
177 */
178
179static const struct snd_kcontrol_new alc662_base_mixer[] = {
180 /* output mixer control */
181 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
182 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
183 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
184 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
185 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
186 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
187 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
188 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
189 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
190
191 /*Input mixer control */
192 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
193 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
194 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
195 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
196 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
197 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
198 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
199 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
200 { } /* end */
201};
202
203static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
204 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
205 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
206 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
207 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
208 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
213 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
214 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
215 { } /* end */
216};
217
218static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
219 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
220 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
221 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
222 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
223 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
224 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
225 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
226 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
227 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
228 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
229 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
230 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
231 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
232 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
233 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
234 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
235 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
236 { } /* end */
237};
238
239static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
240 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
241 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
242 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
243 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
244 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
245 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
246 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
247 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
248 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
249 { } /* end */
250};
251
252static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
253 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
254 ALC262_HIPPO_MASTER_SWITCH,
255
256 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
257 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
258 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
259
260 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
261 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
262 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
263 { } /* end */
264};
265
266static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
267 ALC262_HIPPO_MASTER_SWITCH,
268 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
270 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
271 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
272 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
273 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
274 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
275 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
276 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
277 { } /* end */
278};
279
280static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
281 .ops = &snd_hda_bind_vol,
282 .values = {
283 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
284 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
285 0
286 },
287};
288
289static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
290 .ops = &snd_hda_bind_sw,
291 .values = {
292 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
293 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
294 0
295 },
296};
297
298static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
299 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
300 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
303 { } /* end */
304};
305
306static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
307 .ops = &snd_hda_bind_sw,
308 .values = {
309 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
310 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
311 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
312 0
313 },
314};
315
316static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
317 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
318 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
321 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
322 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
323
324 { } /* end */
325};
326
327static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
328 .ops = &snd_hda_bind_sw,
329 .values = {
330 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
331 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
332 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
333 0
334 },
335};
336
337static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
338 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
339 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
340 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
341 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
342 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
343 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
344 { } /* end */
345};
346
347static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
348 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
349 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
352 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
353 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
354 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
355 { } /* end */
356};
357
358static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
359 .ops = &snd_hda_bind_vol,
360 .values = {
361 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
362 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
363 0
364 },
365};
366
367static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
368 .ops = &snd_hda_bind_sw,
369 .values = {
370 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
371 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
372 0
373 },
374};
375
376static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
377 HDA_BIND_VOL("Master Playback Volume",
378 &alc663_asus_two_bind_master_vol),
379 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
380 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
381 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
383 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
384 { } /* end */
385};
386
387static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
388 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
389 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
390 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
391 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
393 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
394 { } /* end */
395};
396
397static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
398 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
399 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
400 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
401 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
402 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
403
404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
406 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
407 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
408 { } /* end */
409};
410
411static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
412 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
413 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
414 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
415
416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
417 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
418 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
419 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
420 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
421 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
422 { } /* end */
423};
424
425static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
426 .ops = &snd_hda_bind_sw,
427 .values = {
428 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
429 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
430 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
431 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
432 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
433 0
434 },
435};
436
437static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
438 .ops = &snd_hda_bind_sw,
439 .values = {
440 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
441 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
442 0
443 },
444};
445
446static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
447 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
448 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
449 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
450 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
451 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
452 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
453 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
454 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
456 { } /* end */
457};
458
459static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
460 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
461 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
462 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
463 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
464 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
467 { } /* end */
468};
469
470
471static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
472 {
473 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
474 .name = "Channel Mode",
475 .info = alc_ch_mode_info,
476 .get = alc_ch_mode_get,
477 .put = alc_ch_mode_put,
478 },
479 { } /* end */
480};
481
482static const struct hda_verb alc662_init_verbs[] = {
483 /* ADC: mute amp left and right */
484 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
485 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
486
487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
488 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
489 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
490 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
491 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
492 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
493
494 /* Front Pin: output 0 (0x0c) */
495 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
496 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
497
498 /* Rear Pin: output 1 (0x0d) */
499 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
501
502 /* CLFE Pin: output 2 (0x0e) */
503 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
504 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
505
506 /* Mic (rear) pin: input vref at 80% */
507 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
509 /* Front Mic pin: input vref at 80% */
510 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
511 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
512 /* Line In pin: input */
513 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
514 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
515 /* Line-2 In: Headphone output (output 0 - 0x0c) */
516 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
517 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
518 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
519 /* CD pin widget for input */
520 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
521
522 /* FIXME: use matrix-type input source selection */
523 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
524 /* Input mixer */
525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
527
528 { }
529};
530
531static const struct hda_verb alc662_eapd_init_verbs[] = {
532 /* always trun on EAPD */
533 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
534 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
535 { }
536};
537
538static const struct hda_verb alc662_sue_init_verbs[] = {
539 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_FRONT_EVENT},
540 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
541 {}
542};
543
544static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
545 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
546 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
547 {}
548};
549
550/* Set Unsolicited Event*/
551static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
552 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
553 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
554 {}
555};
556
557static const struct hda_verb alc663_m51va_init_verbs[] = {
558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
559 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
560 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
561 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
562 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
564 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
565 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
566 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
567 {}
568};
569
570static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
571 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
572 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
573 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
574 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
575 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
576 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
577 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
578 {}
579};
580
581static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
582 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
583 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
584 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
585 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
588 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
589 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
590 {}
591};
592
593static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
594 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
595 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
596 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
597 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
598 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
599 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
600 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
601 {}
602};
603
604static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
606 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
607 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
608 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
611 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
612 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
613 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
614 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
615 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
616 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
617 {}
618};
619
620static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
621 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
622 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
623 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
624 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
627 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
629 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
630 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
631 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
632 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
633 {}
634};
635
636static const struct hda_verb alc663_g71v_init_verbs[] = {
637 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
638 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
639 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
640
641 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
642 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
643 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
644
645 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_FRONT_EVENT},
646 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_MIC_EVENT},
647 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
648 {}
649};
650
651static const struct hda_verb alc663_g50v_init_verbs[] = {
652 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
653 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
654 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
655
656 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
657 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
658 {}
659};
660
661static const struct hda_verb alc662_ecs_init_verbs[] = {
662 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
664 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
665 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
666 {}
667};
668
669static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
670 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
671 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
672 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
673 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
674 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
675 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
676 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
679 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
680 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
681 {}
682};
683
684static const struct hda_verb alc272_dell_init_verbs[] = {
685 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
686 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
687 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
688 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
689 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
690 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
691 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
692 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
693 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
694 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
695 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
696 {}
697};
698
699static const struct hda_verb alc663_mode7_init_verbs[] = {
700 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
701 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
702 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
703 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
705 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
706 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
707 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
708 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
709 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
711 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
712 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
713 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
714 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
715 {}
716};
717
718static const struct hda_verb alc663_mode8_init_verbs[] = {
719 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
720 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
721 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
722 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
723 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
724 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
725 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
726 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
727 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
728 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
729 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
732 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
733 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
734 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
735 {}
736};
737
738static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
739 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
740 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
741 { } /* end */
742};
743
744static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
745 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
746 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
747 { } /* end */
748};
749
750static void alc662_lenovo_101e_setup(struct hda_codec *codec)
751{
752 struct alc_spec *spec = codec->spec;
753
754 spec->autocfg.hp_pins[0] = 0x1b;
755 spec->autocfg.line_out_pins[0] = 0x14;
756 spec->autocfg.speaker_pins[0] = 0x15;
757 spec->automute = 1;
758 spec->detect_line = 1;
759 spec->automute_lines = 1;
760 spec->automute_mode = ALC_AUTOMUTE_AMP;
761}
762
763static void alc662_eeepc_setup(struct hda_codec *codec)
764{
765 struct alc_spec *spec = codec->spec;
766
767 alc262_hippo1_setup(codec);
768 spec->ext_mic_pin = 0x18;
769 spec->int_mic_pin = 0x19;
770 spec->auto_mic = 1;
771}
772
773static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
774{
775 struct alc_spec *spec = codec->spec;
776
777 spec->autocfg.hp_pins[0] = 0x14;
778 spec->autocfg.speaker_pins[0] = 0x1b;
779 spec->automute = 1;
780 spec->automute_mode = ALC_AUTOMUTE_AMP;
781}
782
783static void alc663_m51va_setup(struct hda_codec *codec)
784{
785 struct alc_spec *spec = codec->spec;
786 spec->autocfg.hp_pins[0] = 0x21;
787 spec->autocfg.speaker_pins[0] = 0x14;
788 spec->automute_mixer_nid[0] = 0x0c;
789 spec->automute = 1;
790 spec->automute_mode = ALC_AUTOMUTE_MIXER;
791 spec->ext_mic_pin = 0x18;
792 spec->int_mic_pin = 0x12;
793 spec->auto_mic = 1;
794}
795
796/* ***************** Mode1 ******************************/
797static void alc663_mode1_setup(struct hda_codec *codec)
798{
799 struct alc_spec *spec = codec->spec;
800 spec->autocfg.hp_pins[0] = 0x21;
801 spec->autocfg.speaker_pins[0] = 0x14;
802 spec->automute_mixer_nid[0] = 0x0c;
803 spec->automute = 1;
804 spec->automute_mode = ALC_AUTOMUTE_MIXER;
805 spec->ext_mic_pin = 0x18;
806 spec->int_mic_pin = 0x19;
807 spec->auto_mic = 1;
808}
809
810/* ***************** Mode2 ******************************/
811static void alc662_mode2_setup(struct hda_codec *codec)
812{
813 struct alc_spec *spec = codec->spec;
814 spec->autocfg.hp_pins[0] = 0x1b;
815 spec->autocfg.speaker_pins[0] = 0x14;
816 spec->automute = 1;
817 spec->automute_mode = ALC_AUTOMUTE_PIN;
818 spec->ext_mic_pin = 0x18;
819 spec->int_mic_pin = 0x19;
820 spec->auto_mic = 1;
821}
822
823/* ***************** Mode3 ******************************/
824static void alc663_mode3_setup(struct hda_codec *codec)
825{
826 struct alc_spec *spec = codec->spec;
827 spec->autocfg.hp_pins[0] = 0x21;
828 spec->autocfg.hp_pins[0] = 0x15;
829 spec->autocfg.speaker_pins[0] = 0x14;
830 spec->automute = 1;
831 spec->automute_mode = ALC_AUTOMUTE_PIN;
832 spec->ext_mic_pin = 0x18;
833 spec->int_mic_pin = 0x19;
834 spec->auto_mic = 1;
835}
836
837/* ***************** Mode4 ******************************/
838static void alc663_mode4_setup(struct hda_codec *codec)
839{
840 struct alc_spec *spec = codec->spec;
841 spec->autocfg.hp_pins[0] = 0x21;
842 spec->autocfg.speaker_pins[0] = 0x14;
843 spec->autocfg.speaker_pins[1] = 0x16;
844 spec->automute_mixer_nid[0] = 0x0c;
845 spec->automute_mixer_nid[1] = 0x0e;
846 spec->automute = 1;
847 spec->automute_mode = ALC_AUTOMUTE_MIXER;
848 spec->ext_mic_pin = 0x18;
849 spec->int_mic_pin = 0x19;
850 spec->auto_mic = 1;
851}
852
853/* ***************** Mode5 ******************************/
854static void alc663_mode5_setup(struct hda_codec *codec)
855{
856 struct alc_spec *spec = codec->spec;
857 spec->autocfg.hp_pins[0] = 0x15;
858 spec->autocfg.speaker_pins[0] = 0x14;
859 spec->autocfg.speaker_pins[1] = 0x16;
860 spec->automute_mixer_nid[0] = 0x0c;
861 spec->automute_mixer_nid[1] = 0x0e;
862 spec->automute = 1;
863 spec->automute_mode = ALC_AUTOMUTE_MIXER;
864 spec->ext_mic_pin = 0x18;
865 spec->int_mic_pin = 0x19;
866 spec->auto_mic = 1;
867}
868
869/* ***************** Mode6 ******************************/
870static void alc663_mode6_setup(struct hda_codec *codec)
871{
872 struct alc_spec *spec = codec->spec;
873 spec->autocfg.hp_pins[0] = 0x1b;
874 spec->autocfg.hp_pins[0] = 0x15;
875 spec->autocfg.speaker_pins[0] = 0x14;
876 spec->automute_mixer_nid[0] = 0x0c;
877 spec->automute = 1;
878 spec->automute_mode = ALC_AUTOMUTE_MIXER;
879 spec->ext_mic_pin = 0x18;
880 spec->int_mic_pin = 0x19;
881 spec->auto_mic = 1;
882}
883
884/* ***************** Mode7 ******************************/
885static void alc663_mode7_setup(struct hda_codec *codec)
886{
887 struct alc_spec *spec = codec->spec;
888 spec->autocfg.hp_pins[0] = 0x1b;
889 spec->autocfg.hp_pins[0] = 0x21;
890 spec->autocfg.speaker_pins[0] = 0x14;
891 spec->autocfg.speaker_pins[0] = 0x17;
892 spec->automute = 1;
893 spec->automute_mode = ALC_AUTOMUTE_PIN;
894 spec->ext_mic_pin = 0x18;
895 spec->int_mic_pin = 0x19;
896 spec->auto_mic = 1;
897}
898
899/* ***************** Mode8 ******************************/
900static void alc663_mode8_setup(struct hda_codec *codec)
901{
902 struct alc_spec *spec = codec->spec;
903 spec->autocfg.hp_pins[0] = 0x21;
904 spec->autocfg.hp_pins[1] = 0x15;
905 spec->autocfg.speaker_pins[0] = 0x14;
906 spec->autocfg.speaker_pins[0] = 0x17;
907 spec->automute = 1;
908 spec->automute_mode = ALC_AUTOMUTE_PIN;
909 spec->ext_mic_pin = 0x18;
910 spec->int_mic_pin = 0x12;
911 spec->auto_mic = 1;
912}
913
914static void alc663_g71v_setup(struct hda_codec *codec)
915{
916 struct alc_spec *spec = codec->spec;
917 spec->autocfg.hp_pins[0] = 0x21;
918 spec->autocfg.line_out_pins[0] = 0x15;
919 spec->autocfg.speaker_pins[0] = 0x14;
920 spec->automute = 1;
921 spec->automute_mode = ALC_AUTOMUTE_AMP;
922 spec->detect_line = 1;
923 spec->automute_lines = 1;
924 spec->ext_mic_pin = 0x18;
925 spec->int_mic_pin = 0x12;
926 spec->auto_mic = 1;
927}
928
929#define alc663_g50v_setup alc663_m51va_setup
930
931static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
932 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
933 ALC262_HIPPO_MASTER_SWITCH,
934
935 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
936 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
937 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
938
939 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
940 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
941 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
942 { } /* end */
943};
944
945static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
946 /* Master Playback automatically created from Speaker and Headphone */
947 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
948 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
949 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
950 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
951
952 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
953 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
954 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
955
956 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
957 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
958 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
959 { } /* end */
960};
961
962
963/*
964 * configuration and preset
965 */
966static const char * const alc662_models[ALC662_MODEL_LAST] = {
967 [ALC662_3ST_2ch_DIG] = "3stack-dig",
968 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
969 [ALC662_3ST_6ch] = "3stack-6ch",
970 [ALC662_5ST_DIG] = "5stack-dig",
971 [ALC662_LENOVO_101E] = "lenovo-101e",
972 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
973 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
974 [ALC662_ECS] = "ecs",
975 [ALC663_ASUS_M51VA] = "m51va",
976 [ALC663_ASUS_G71V] = "g71v",
977 [ALC663_ASUS_H13] = "h13",
978 [ALC663_ASUS_G50V] = "g50v",
979 [ALC663_ASUS_MODE1] = "asus-mode1",
980 [ALC662_ASUS_MODE2] = "asus-mode2",
981 [ALC663_ASUS_MODE3] = "asus-mode3",
982 [ALC663_ASUS_MODE4] = "asus-mode4",
983 [ALC663_ASUS_MODE5] = "asus-mode5",
984 [ALC663_ASUS_MODE6] = "asus-mode6",
985 [ALC663_ASUS_MODE7] = "asus-mode7",
986 [ALC663_ASUS_MODE8] = "asus-mode8",
987 [ALC272_DELL] = "dell",
988 [ALC272_DELL_ZM1] = "dell-zm1",
989 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
990 [ALC662_AUTO] = "auto",
991};
992
993static const struct snd_pci_quirk alc662_cfg_tbl[] = {
994 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
995 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
996 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
997 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
998 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
999 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
1000 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
1001 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
1002 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
1003 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
1004 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
1005 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
1006 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
1007 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
1008 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
1009 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
1010 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
1011 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
1012 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
1013 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
1014 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
1015 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
1016 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
1017 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
1018 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
1019 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
1020 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
1021 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
1022 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
1023 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
1024 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
1025 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
1026 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
1027 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
1028 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
1029 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
1030 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
1031 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
1032 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
1033 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
1034 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
1035 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
1036 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
1037 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
1038 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
1039 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
1040 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
1041 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
1042 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
1043 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
1044 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
1045 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
1046 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
1047 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
1048 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
1049 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
1050 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
1051 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
1052 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
1053 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
1054 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
1055 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
1056 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
1057 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
1058 ALC662_3ST_6ch_DIG),
1059 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
1060 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
1061 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
1062 ALC662_3ST_6ch_DIG),
1063 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
1064 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
1065 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
1066 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
1067 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
1068 ALC662_3ST_6ch_DIG),
1069 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
1070 ALC663_ASUS_H13),
1071 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
1072 {}
1073};
1074
1075static const struct alc_config_preset alc662_presets[] = {
1076 [ALC662_3ST_2ch_DIG] = {
1077 .mixers = { alc662_3ST_2ch_mixer },
1078 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1079 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1080 .dac_nids = alc662_dac_nids,
1081 .dig_out_nid = ALC662_DIGOUT_NID,
1082 .dig_in_nid = ALC662_DIGIN_NID,
1083 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1084 .channel_mode = alc662_3ST_2ch_modes,
1085 .input_mux = &alc662_capture_source,
1086 },
1087 [ALC662_3ST_6ch_DIG] = {
1088 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
1089 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1090 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1091 .dac_nids = alc662_dac_nids,
1092 .dig_out_nid = ALC662_DIGOUT_NID,
1093 .dig_in_nid = ALC662_DIGIN_NID,
1094 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1095 .channel_mode = alc662_3ST_6ch_modes,
1096 .need_dac_fix = 1,
1097 .input_mux = &alc662_capture_source,
1098 },
1099 [ALC662_3ST_6ch] = {
1100 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
1101 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1102 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1103 .dac_nids = alc662_dac_nids,
1104 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1105 .channel_mode = alc662_3ST_6ch_modes,
1106 .need_dac_fix = 1,
1107 .input_mux = &alc662_capture_source,
1108 },
1109 [ALC662_5ST_DIG] = {
1110 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
1111 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1112 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1113 .dac_nids = alc662_dac_nids,
1114 .dig_out_nid = ALC662_DIGOUT_NID,
1115 .dig_in_nid = ALC662_DIGIN_NID,
1116 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
1117 .channel_mode = alc662_5stack_modes,
1118 .input_mux = &alc662_capture_source,
1119 },
1120 [ALC662_LENOVO_101E] = {
1121 .mixers = { alc662_lenovo_101e_mixer },
1122 .init_verbs = { alc662_init_verbs,
1123 alc662_eapd_init_verbs,
1124 alc662_sue_init_verbs },
1125 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1126 .dac_nids = alc662_dac_nids,
1127 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1128 .channel_mode = alc662_3ST_2ch_modes,
1129 .input_mux = &alc662_lenovo_101e_capture_source,
1130 .unsol_event = alc_sku_unsol_event,
1131 .setup = alc662_lenovo_101e_setup,
1132 .init_hook = alc_inithook,
1133 },
1134 [ALC662_ASUS_EEEPC_P701] = {
1135 .mixers = { alc662_eeepc_p701_mixer },
1136 .init_verbs = { alc662_init_verbs,
1137 alc662_eapd_init_verbs,
1138 alc662_eeepc_sue_init_verbs },
1139 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1140 .dac_nids = alc662_dac_nids,
1141 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1142 .channel_mode = alc662_3ST_2ch_modes,
1143 .unsol_event = alc_sku_unsol_event,
1144 .setup = alc662_eeepc_setup,
1145 .init_hook = alc_inithook,
1146 },
1147 [ALC662_ASUS_EEEPC_EP20] = {
1148 .mixers = { alc662_eeepc_ep20_mixer,
1149 alc662_chmode_mixer },
1150 .init_verbs = { alc662_init_verbs,
1151 alc662_eapd_init_verbs,
1152 alc662_eeepc_ep20_sue_init_verbs },
1153 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1154 .dac_nids = alc662_dac_nids,
1155 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1156 .channel_mode = alc662_3ST_6ch_modes,
1157 .input_mux = &alc662_lenovo_101e_capture_source,
1158 .unsol_event = alc_sku_unsol_event,
1159 .setup = alc662_eeepc_ep20_setup,
1160 .init_hook = alc_inithook,
1161 },
1162 [ALC662_ECS] = {
1163 .mixers = { alc662_ecs_mixer },
1164 .init_verbs = { alc662_init_verbs,
1165 alc662_eapd_init_verbs,
1166 alc662_ecs_init_verbs },
1167 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1168 .dac_nids = alc662_dac_nids,
1169 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1170 .channel_mode = alc662_3ST_2ch_modes,
1171 .unsol_event = alc_sku_unsol_event,
1172 .setup = alc662_eeepc_setup,
1173 .init_hook = alc_inithook,
1174 },
1175 [ALC663_ASUS_M51VA] = {
1176 .mixers = { alc663_m51va_mixer },
1177 .init_verbs = { alc662_init_verbs,
1178 alc662_eapd_init_verbs,
1179 alc663_m51va_init_verbs },
1180 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1181 .dac_nids = alc662_dac_nids,
1182 .dig_out_nid = ALC662_DIGOUT_NID,
1183 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1184 .channel_mode = alc662_3ST_2ch_modes,
1185 .unsol_event = alc_sku_unsol_event,
1186 .setup = alc663_m51va_setup,
1187 .init_hook = alc_inithook,
1188 },
1189 [ALC663_ASUS_G71V] = {
1190 .mixers = { alc663_g71v_mixer },
1191 .init_verbs = { alc662_init_verbs,
1192 alc662_eapd_init_verbs,
1193 alc663_g71v_init_verbs },
1194 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1195 .dac_nids = alc662_dac_nids,
1196 .dig_out_nid = ALC662_DIGOUT_NID,
1197 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1198 .channel_mode = alc662_3ST_2ch_modes,
1199 .unsol_event = alc_sku_unsol_event,
1200 .setup = alc663_g71v_setup,
1201 .init_hook = alc_inithook,
1202 },
1203 [ALC663_ASUS_H13] = {
1204 .mixers = { alc663_m51va_mixer },
1205 .init_verbs = { alc662_init_verbs,
1206 alc662_eapd_init_verbs,
1207 alc663_m51va_init_verbs },
1208 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1209 .dac_nids = alc662_dac_nids,
1210 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1211 .channel_mode = alc662_3ST_2ch_modes,
1212 .setup = alc663_m51va_setup,
1213 .unsol_event = alc_sku_unsol_event,
1214 .init_hook = alc_inithook,
1215 },
1216 [ALC663_ASUS_G50V] = {
1217 .mixers = { alc663_g50v_mixer },
1218 .init_verbs = { alc662_init_verbs,
1219 alc662_eapd_init_verbs,
1220 alc663_g50v_init_verbs },
1221 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1222 .dac_nids = alc662_dac_nids,
1223 .dig_out_nid = ALC662_DIGOUT_NID,
1224 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1225 .channel_mode = alc662_3ST_6ch_modes,
1226 .input_mux = &alc663_capture_source,
1227 .unsol_event = alc_sku_unsol_event,
1228 .setup = alc663_g50v_setup,
1229 .init_hook = alc_inithook,
1230 },
1231 [ALC663_ASUS_MODE1] = {
1232 .mixers = { alc663_m51va_mixer },
1233 .cap_mixer = alc662_auto_capture_mixer,
1234 .init_verbs = { alc662_init_verbs,
1235 alc662_eapd_init_verbs,
1236 alc663_21jd_amic_init_verbs },
1237 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1238 .hp_nid = 0x03,
1239 .dac_nids = alc662_dac_nids,
1240 .dig_out_nid = ALC662_DIGOUT_NID,
1241 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1242 .channel_mode = alc662_3ST_2ch_modes,
1243 .unsol_event = alc_sku_unsol_event,
1244 .setup = alc663_mode1_setup,
1245 .init_hook = alc_inithook,
1246 },
1247 [ALC662_ASUS_MODE2] = {
1248 .mixers = { alc662_1bjd_mixer },
1249 .cap_mixer = alc662_auto_capture_mixer,
1250 .init_verbs = { alc662_init_verbs,
1251 alc662_eapd_init_verbs,
1252 alc662_1bjd_amic_init_verbs },
1253 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1254 .dac_nids = alc662_dac_nids,
1255 .dig_out_nid = ALC662_DIGOUT_NID,
1256 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1257 .channel_mode = alc662_3ST_2ch_modes,
1258 .unsol_event = alc_sku_unsol_event,
1259 .setup = alc662_mode2_setup,
1260 .init_hook = alc_inithook,
1261 },
1262 [ALC663_ASUS_MODE3] = {
1263 .mixers = { alc663_two_hp_m1_mixer },
1264 .cap_mixer = alc662_auto_capture_mixer,
1265 .init_verbs = { alc662_init_verbs,
1266 alc662_eapd_init_verbs,
1267 alc663_two_hp_amic_m1_init_verbs },
1268 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1269 .hp_nid = 0x03,
1270 .dac_nids = alc662_dac_nids,
1271 .dig_out_nid = ALC662_DIGOUT_NID,
1272 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1273 .channel_mode = alc662_3ST_2ch_modes,
1274 .unsol_event = alc_sku_unsol_event,
1275 .setup = alc663_mode3_setup,
1276 .init_hook = alc_inithook,
1277 },
1278 [ALC663_ASUS_MODE4] = {
1279 .mixers = { alc663_asus_21jd_clfe_mixer },
1280 .cap_mixer = alc662_auto_capture_mixer,
1281 .init_verbs = { alc662_init_verbs,
1282 alc662_eapd_init_verbs,
1283 alc663_21jd_amic_init_verbs},
1284 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1285 .hp_nid = 0x03,
1286 .dac_nids = alc662_dac_nids,
1287 .dig_out_nid = ALC662_DIGOUT_NID,
1288 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1289 .channel_mode = alc662_3ST_2ch_modes,
1290 .unsol_event = alc_sku_unsol_event,
1291 .setup = alc663_mode4_setup,
1292 .init_hook = alc_inithook,
1293 },
1294 [ALC663_ASUS_MODE5] = {
1295 .mixers = { alc663_asus_15jd_clfe_mixer },
1296 .cap_mixer = alc662_auto_capture_mixer,
1297 .init_verbs = { alc662_init_verbs,
1298 alc662_eapd_init_verbs,
1299 alc663_15jd_amic_init_verbs },
1300 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1301 .hp_nid = 0x03,
1302 .dac_nids = alc662_dac_nids,
1303 .dig_out_nid = ALC662_DIGOUT_NID,
1304 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1305 .channel_mode = alc662_3ST_2ch_modes,
1306 .unsol_event = alc_sku_unsol_event,
1307 .setup = alc663_mode5_setup,
1308 .init_hook = alc_inithook,
1309 },
1310 [ALC663_ASUS_MODE6] = {
1311 .mixers = { alc663_two_hp_m2_mixer },
1312 .cap_mixer = alc662_auto_capture_mixer,
1313 .init_verbs = { alc662_init_verbs,
1314 alc662_eapd_init_verbs,
1315 alc663_two_hp_amic_m2_init_verbs },
1316 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1317 .hp_nid = 0x03,
1318 .dac_nids = alc662_dac_nids,
1319 .dig_out_nid = ALC662_DIGOUT_NID,
1320 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1321 .channel_mode = alc662_3ST_2ch_modes,
1322 .unsol_event = alc_sku_unsol_event,
1323 .setup = alc663_mode6_setup,
1324 .init_hook = alc_inithook,
1325 },
1326 [ALC663_ASUS_MODE7] = {
1327 .mixers = { alc663_mode7_mixer },
1328 .cap_mixer = alc662_auto_capture_mixer,
1329 .init_verbs = { alc662_init_verbs,
1330 alc662_eapd_init_verbs,
1331 alc663_mode7_init_verbs },
1332 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1333 .hp_nid = 0x03,
1334 .dac_nids = alc662_dac_nids,
1335 .dig_out_nid = ALC662_DIGOUT_NID,
1336 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1337 .channel_mode = alc662_3ST_2ch_modes,
1338 .unsol_event = alc_sku_unsol_event,
1339 .setup = alc663_mode7_setup,
1340 .init_hook = alc_inithook,
1341 },
1342 [ALC663_ASUS_MODE8] = {
1343 .mixers = { alc663_mode8_mixer },
1344 .cap_mixer = alc662_auto_capture_mixer,
1345 .init_verbs = { alc662_init_verbs,
1346 alc662_eapd_init_verbs,
1347 alc663_mode8_init_verbs },
1348 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1349 .hp_nid = 0x03,
1350 .dac_nids = alc662_dac_nids,
1351 .dig_out_nid = ALC662_DIGOUT_NID,
1352 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1353 .channel_mode = alc662_3ST_2ch_modes,
1354 .unsol_event = alc_sku_unsol_event,
1355 .setup = alc663_mode8_setup,
1356 .init_hook = alc_inithook,
1357 },
1358 [ALC272_DELL] = {
1359 .mixers = { alc663_m51va_mixer },
1360 .cap_mixer = alc272_auto_capture_mixer,
1361 .init_verbs = { alc662_init_verbs,
1362 alc662_eapd_init_verbs,
1363 alc272_dell_init_verbs },
1364 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1365 .dac_nids = alc272_dac_nids,
1366 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1367 .adc_nids = alc272_adc_nids,
1368 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
1369 .capsrc_nids = alc272_capsrc_nids,
1370 .channel_mode = alc662_3ST_2ch_modes,
1371 .unsol_event = alc_sku_unsol_event,
1372 .setup = alc663_m51va_setup,
1373 .init_hook = alc_inithook,
1374 },
1375 [ALC272_DELL_ZM1] = {
1376 .mixers = { alc663_m51va_mixer },
1377 .cap_mixer = alc662_auto_capture_mixer,
1378 .init_verbs = { alc662_init_verbs,
1379 alc662_eapd_init_verbs,
1380 alc272_dell_zm1_init_verbs },
1381 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1382 .dac_nids = alc272_dac_nids,
1383 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1384 .adc_nids = alc662_adc_nids,
1385 .num_adc_nids = 1,
1386 .capsrc_nids = alc662_capsrc_nids,
1387 .channel_mode = alc662_3ST_2ch_modes,
1388 .unsol_event = alc_sku_unsol_event,
1389 .setup = alc663_m51va_setup,
1390 .init_hook = alc_inithook,
1391 },
1392 [ALC272_SAMSUNG_NC10] = {
1393 .mixers = { alc272_nc10_mixer },
1394 .init_verbs = { alc662_init_verbs,
1395 alc662_eapd_init_verbs,
1396 alc663_21jd_amic_init_verbs },
1397 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1398 .dac_nids = alc272_dac_nids,
1399 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1400 .channel_mode = alc662_3ST_2ch_modes,
1401 /*.input_mux = &alc272_nc10_capture_source,*/
1402 .unsol_event = alc_sku_unsol_event,
1403 .setup = alc663_mode4_setup,
1404 .init_hook = alc_inithook,
1405 },
1406};
1407
1408
diff --git a/sound/pci/hda/alc680_quirks.c b/sound/pci/hda/alc680_quirks.c
new file mode 100644
index 00000000000..0eeb227c7bc
--- /dev/null
+++ b/sound/pci/hda/alc680_quirks.c
@@ -0,0 +1,222 @@
1/*
2 * ALC680 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC680 models */
7enum {
8 ALC680_AUTO,
9 ALC680_BASE,
10 ALC680_MODEL_LAST,
11};
12
13#define ALC680_DIGIN_NID ALC880_DIGIN_NID
14#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
15#define alc680_modes alc260_modes
16
17static const hda_nid_t alc680_dac_nids[3] = {
18 /* Lout1, Lout2, hp */
19 0x02, 0x03, 0x04
20};
21
22static const hda_nid_t alc680_adc_nids[3] = {
23 /* ADC0-2 */
24 /* DMIC, MIC, Line-in*/
25 0x07, 0x08, 0x09
26};
27
28/*
29 * Analog capture ADC cgange
30 */
31static hda_nid_t alc680_get_cur_adc(struct hda_codec *codec)
32{
33 static hda_nid_t pins[] = {0x18, 0x19};
34 static hda_nid_t adcs[] = {0x08, 0x09};
35 int i;
36
37 for (i = 0; i < ARRAY_SIZE(pins); i++) {
38 if (!is_jack_detectable(codec, pins[i]))
39 continue;
40 if (snd_hda_jack_detect(codec, pins[i]))
41 return adcs[i];
42 }
43 return 0x07;
44}
45
46static void alc680_rec_autoswitch(struct hda_codec *codec)
47{
48 struct alc_spec *spec = codec->spec;
49 hda_nid_t nid = alc680_get_cur_adc(codec);
50 if (spec->cur_adc && nid != spec->cur_adc) {
51 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
52 spec->cur_adc = nid;
53 snd_hda_codec_setup_stream(codec, nid,
54 spec->cur_adc_stream_tag, 0,
55 spec->cur_adc_format);
56 }
57}
58
59static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
60 struct hda_codec *codec,
61 unsigned int stream_tag,
62 unsigned int format,
63 struct snd_pcm_substream *substream)
64{
65 struct alc_spec *spec = codec->spec;
66 hda_nid_t nid = alc680_get_cur_adc(codec);
67
68 spec->cur_adc = nid;
69 spec->cur_adc_stream_tag = stream_tag;
70 spec->cur_adc_format = format;
71 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
72 return 0;
73}
74
75static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
76 struct hda_codec *codec,
77 struct snd_pcm_substream *substream)
78{
79 struct alc_spec *spec = codec->spec;
80 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
81 spec->cur_adc = 0;
82 return 0;
83}
84
85static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
86 .substreams = 1, /* can be overridden */
87 .channels_min = 2,
88 .channels_max = 2,
89 /* NID is set in alc_build_pcms */
90 .ops = {
91 .prepare = alc680_capture_pcm_prepare,
92 .cleanup = alc680_capture_pcm_cleanup
93 },
94};
95
96static const struct snd_kcontrol_new alc680_base_mixer[] = {
97 /* output mixer control */
98 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
99 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
100 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
101 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
102 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
103 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
104 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
105 { }
106};
107
108static const struct hda_bind_ctls alc680_bind_cap_vol = {
109 .ops = &snd_hda_bind_vol,
110 .values = {
111 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
112 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
113 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
114 0
115 },
116};
117
118static const struct hda_bind_ctls alc680_bind_cap_switch = {
119 .ops = &snd_hda_bind_sw,
120 .values = {
121 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
122 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
123 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
124 0
125 },
126};
127
128static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
129 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
130 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
131 { } /* end */
132};
133
134/*
135 * generic initialization of ADC, input mixers and output mixers
136 */
137static const struct hda_verb alc680_init_verbs[] = {
138 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
139 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
140 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
141
142 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
143 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
146 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
147 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
148
149 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
150 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
151 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
152 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
153 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
154
155 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
156 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
157 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
158
159 { }
160};
161
162/* toggle speaker-output according to the hp-jack state */
163static void alc680_base_setup(struct hda_codec *codec)
164{
165 struct alc_spec *spec = codec->spec;
166
167 spec->autocfg.hp_pins[0] = 0x16;
168 spec->autocfg.speaker_pins[0] = 0x14;
169 spec->autocfg.speaker_pins[1] = 0x15;
170 spec->autocfg.num_inputs = 2;
171 spec->autocfg.inputs[0].pin = 0x18;
172 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
173 spec->autocfg.inputs[1].pin = 0x19;
174 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
175 spec->automute = 1;
176 spec->automute_mode = ALC_AUTOMUTE_AMP;
177}
178
179static void alc680_unsol_event(struct hda_codec *codec,
180 unsigned int res)
181{
182 if ((res >> 26) == ALC_HP_EVENT)
183 alc_hp_automute(codec);
184 if ((res >> 26) == ALC_MIC_EVENT)
185 alc680_rec_autoswitch(codec);
186}
187
188static void alc680_inithook(struct hda_codec *codec)
189{
190 alc_hp_automute(codec);
191 alc680_rec_autoswitch(codec);
192}
193
194/*
195 * configuration and preset
196 */
197static const char * const alc680_models[ALC680_MODEL_LAST] = {
198 [ALC680_BASE] = "base",
199 [ALC680_AUTO] = "auto",
200};
201
202static const struct snd_pci_quirk alc680_cfg_tbl[] = {
203 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
204 {}
205};
206
207static const struct alc_config_preset alc680_presets[] = {
208 [ALC680_BASE] = {
209 .mixers = { alc680_base_mixer },
210 .cap_mixer = alc680_master_capture_mixer,
211 .init_verbs = { alc680_init_verbs },
212 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
213 .dac_nids = alc680_dac_nids,
214 .dig_out_nid = ALC680_DIGOUT_NID,
215 .num_channel_mode = ARRAY_SIZE(alc680_modes),
216 .channel_mode = alc680_modes,
217 .unsol_event = alc680_unsol_event,
218 .setup = alc680_base_setup,
219 .init_hook = alc680_inithook,
220
221 },
222};
diff --git a/sound/pci/hda/alc861_quirks.c b/sound/pci/hda/alc861_quirks.c
new file mode 100644
index 00000000000..d719ec6350e
--- /dev/null
+++ b/sound/pci/hda/alc861_quirks.c
@@ -0,0 +1,725 @@
1/*
2 * ALC660/ALC861 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC861 models */
7enum {
8 ALC861_AUTO,
9 ALC861_3ST,
10 ALC660_3ST,
11 ALC861_3ST_DIG,
12 ALC861_6ST_DIG,
13 ALC861_UNIWILL_M31,
14 ALC861_TOSHIBA,
15 ALC861_ASUS,
16 ALC861_ASUS_LAPTOP,
17 ALC861_MODEL_LAST,
18};
19
20/*
21 * ALC861 channel source setting (2/6 channel selection for 3-stack)
22 */
23
24/*
25 * set the path ways for 2 channel output
26 * need to set the codec line out and mic 1 pin widgets to inputs
27 */
28static const struct hda_verb alc861_threestack_ch2_init[] = {
29 /* set pin widget 1Ah (line in) for input */
30 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
31 /* set pin widget 18h (mic1/2) for input, for mic also enable
32 * the vref
33 */
34 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
35
36 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
37#if 0
38 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
39 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
40#endif
41 { } /* end */
42};
43/*
44 * 6ch mode
45 * need to set the codec line out and mic 1 pin widgets to outputs
46 */
47static const struct hda_verb alc861_threestack_ch6_init[] = {
48 /* set pin widget 1Ah (line in) for output (Back Surround)*/
49 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
50 /* set pin widget 18h (mic1) for output (CLFE)*/
51 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
52
53 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
54 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
55
56 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
57#if 0
58 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
59 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
60#endif
61 { } /* end */
62};
63
64static const struct hda_channel_mode alc861_threestack_modes[2] = {
65 { 2, alc861_threestack_ch2_init },
66 { 6, alc861_threestack_ch6_init },
67};
68/* Set mic1 as input and unmute the mixer */
69static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
70 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
71 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
72 { } /* end */
73};
74/* Set mic1 as output and mute mixer */
75static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
76 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
77 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
78 { } /* end */
79};
80
81static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
82 { 2, alc861_uniwill_m31_ch2_init },
83 { 4, alc861_uniwill_m31_ch4_init },
84};
85
86/* Set mic1 and line-in as input and unmute the mixer */
87static const struct hda_verb alc861_asus_ch2_init[] = {
88 /* set pin widget 1Ah (line in) for input */
89 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
90 /* set pin widget 18h (mic1/2) for input, for mic also enable
91 * the vref
92 */
93 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
94
95 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
96#if 0
97 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
98 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
99#endif
100 { } /* end */
101};
102/* Set mic1 nad line-in as output and mute mixer */
103static const struct hda_verb alc861_asus_ch6_init[] = {
104 /* set pin widget 1Ah (line in) for output (Back Surround)*/
105 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
106 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
107 /* set pin widget 18h (mic1) for output (CLFE)*/
108 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
109 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
110 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
111 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
112
113 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
114#if 0
115 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
116 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
117#endif
118 { } /* end */
119};
120
121static const struct hda_channel_mode alc861_asus_modes[2] = {
122 { 2, alc861_asus_ch2_init },
123 { 6, alc861_asus_ch6_init },
124};
125
126/* patch-ALC861 */
127
128static const struct snd_kcontrol_new alc861_base_mixer[] = {
129 /* output mixer control */
130 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
131 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
132 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
133 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
134 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
135
136 /*Input mixer control */
137 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
138 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
139 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
140 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
141 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
142 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
144 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
145 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
147
148 { } /* end */
149};
150
151static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
152 /* output mixer control */
153 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
154 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
155 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
156 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
157 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
158
159 /* Input mixer control */
160 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
161 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
162 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
163 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
164 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
165 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
167 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
168 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
169 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
170
171 {
172 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
173 .name = "Channel Mode",
174 .info = alc_ch_mode_info,
175 .get = alc_ch_mode_get,
176 .put = alc_ch_mode_put,
177 .private_value = ARRAY_SIZE(alc861_threestack_modes),
178 },
179 { } /* end */
180};
181
182static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
183 /* output mixer control */
184 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
185 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
186 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
187
188 { } /* end */
189};
190
191static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
192 /* output mixer control */
193 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
194 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
195 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
196 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
197 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
198
199 /* Input mixer control */
200 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
201 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
202 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
203 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
204 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
205 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
206 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
207 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
208 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
209 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
210
211 {
212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
213 .name = "Channel Mode",
214 .info = alc_ch_mode_info,
215 .get = alc_ch_mode_get,
216 .put = alc_ch_mode_put,
217 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
218 },
219 { } /* end */
220};
221
222static const struct snd_kcontrol_new alc861_asus_mixer[] = {
223 /* output mixer control */
224 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
225 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
226 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
227 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
228 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
229
230 /* Input mixer control */
231 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
232 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
233 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
234 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
235 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
236 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
237 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
238 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
239 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
240 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
241
242 {
243 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
244 .name = "Channel Mode",
245 .info = alc_ch_mode_info,
246 .get = alc_ch_mode_get,
247 .put = alc_ch_mode_put,
248 .private_value = ARRAY_SIZE(alc861_asus_modes),
249 },
250 { }
251};
252
253/* additional mixer */
254static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
255 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
256 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
257 { }
258};
259
260/*
261 * generic initialization of ADC, input mixers and output mixers
262 */
263static const struct hda_verb alc861_base_init_verbs[] = {
264 /*
265 * Unmute ADC0 and set the default input to mic-in
266 */
267 /* port-A for surround (rear panel) */
268 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
269 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
270 /* port-B for mic-in (rear panel) with vref */
271 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
272 /* port-C for line-in (rear panel) */
273 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
274 /* port-D for Front */
275 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
276 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
277 /* port-E for HP out (front panel) */
278 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
279 /* route front PCM to HP */
280 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
281 /* port-F for mic-in (front panel) with vref */
282 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
283 /* port-G for CLFE (rear panel) */
284 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
285 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
286 /* port-H for side (rear panel) */
287 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
288 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
289 /* CD-in */
290 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
291 /* route front mic to ADC1*/
292 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
293 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
294
295 /* Unmute DAC0~3 & spdif out*/
296 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
297 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
298 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
299 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
300 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
301
302 /* Unmute Mixer 14 (mic) 1c (Line in)*/
303 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
304 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
305 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
306 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
307
308 /* Unmute Stereo Mixer 15 */
309 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
310 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
311 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
312 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
313
314 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
315 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
316 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
317 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
318 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
319 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
320 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
321 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
322 /* hp used DAC 3 (Front) */
323 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
324 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
325
326 { }
327};
328
329static const struct hda_verb alc861_threestack_init_verbs[] = {
330 /*
331 * Unmute ADC0 and set the default input to mic-in
332 */
333 /* port-A for surround (rear panel) */
334 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
335 /* port-B for mic-in (rear panel) with vref */
336 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
337 /* port-C for line-in (rear panel) */
338 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
339 /* port-D for Front */
340 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
341 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
342 /* port-E for HP out (front panel) */
343 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
344 /* route front PCM to HP */
345 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
346 /* port-F for mic-in (front panel) with vref */
347 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
348 /* port-G for CLFE (rear panel) */
349 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
350 /* port-H for side (rear panel) */
351 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
352 /* CD-in */
353 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
354 /* route front mic to ADC1*/
355 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
356 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
357 /* Unmute DAC0~3 & spdif out*/
358 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
359 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
360 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
361 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
362 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
363
364 /* Unmute Mixer 14 (mic) 1c (Line in)*/
365 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
366 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
367 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
368 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
369
370 /* Unmute Stereo Mixer 15 */
371 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
373 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
374 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
375
376 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
377 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
378 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
379 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
380 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
381 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
382 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
383 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
384 /* hp used DAC 3 (Front) */
385 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
386 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
387 { }
388};
389
390static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
391 /*
392 * Unmute ADC0 and set the default input to mic-in
393 */
394 /* port-A for surround (rear panel) */
395 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
396 /* port-B for mic-in (rear panel) with vref */
397 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
398 /* port-C for line-in (rear panel) */
399 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
400 /* port-D for Front */
401 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
402 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
403 /* port-E for HP out (front panel) */
404 /* this has to be set to VREF80 */
405 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
406 /* route front PCM to HP */
407 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
408 /* port-F for mic-in (front panel) with vref */
409 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
410 /* port-G for CLFE (rear panel) */
411 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
412 /* port-H for side (rear panel) */
413 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
414 /* CD-in */
415 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
416 /* route front mic to ADC1*/
417 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
418 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
419 /* Unmute DAC0~3 & spdif out*/
420 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
421 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
422 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
423 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
425
426 /* Unmute Mixer 14 (mic) 1c (Line in)*/
427 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
428 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
429 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
430 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
431
432 /* Unmute Stereo Mixer 15 */
433 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
434 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
435 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
436 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
437
438 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
439 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
440 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
441 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
442 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
443 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
444 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
445 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
446 /* hp used DAC 3 (Front) */
447 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
448 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
449 { }
450};
451
452static const struct hda_verb alc861_asus_init_verbs[] = {
453 /*
454 * Unmute ADC0 and set the default input to mic-in
455 */
456 /* port-A for surround (rear panel)
457 * according to codec#0 this is the HP jack
458 */
459 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
460 /* route front PCM to HP */
461 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
462 /* port-B for mic-in (rear panel) with vref */
463 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
464 /* port-C for line-in (rear panel) */
465 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
466 /* port-D for Front */
467 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
468 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
469 /* port-E for HP out (front panel) */
470 /* this has to be set to VREF80 */
471 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
472 /* route front PCM to HP */
473 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
474 /* port-F for mic-in (front panel) with vref */
475 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
476 /* port-G for CLFE (rear panel) */
477 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
478 /* port-H for side (rear panel) */
479 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
480 /* CD-in */
481 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
482 /* route front mic to ADC1*/
483 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
485 /* Unmute DAC0~3 & spdif out*/
486 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
487 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
488 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
489 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
490 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
491 /* Unmute Mixer 14 (mic) 1c (Line in)*/
492 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
493 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
494 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
495 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
496
497 /* Unmute Stereo Mixer 15 */
498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
502
503 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
504 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
505 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
506 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
507 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
509 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
511 /* hp used DAC 3 (Front) */
512 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
513 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
514 { }
515};
516
517/* additional init verbs for ASUS laptops */
518static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
519 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
520 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
521 { }
522};
523
524static const struct hda_verb alc861_toshiba_init_verbs[] = {
525 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
526
527 { }
528};
529
530/* toggle speaker-output according to the hp-jack state */
531static void alc861_toshiba_automute(struct hda_codec *codec)
532{
533 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
534
535 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
536 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
537 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
538 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
539}
540
541static void alc861_toshiba_unsol_event(struct hda_codec *codec,
542 unsigned int res)
543{
544 if ((res >> 26) == ALC_HP_EVENT)
545 alc861_toshiba_automute(codec);
546}
547
548#define ALC861_DIGOUT_NID 0x07
549
550static const struct hda_channel_mode alc861_8ch_modes[1] = {
551 { 8, NULL }
552};
553
554static const hda_nid_t alc861_dac_nids[4] = {
555 /* front, surround, clfe, side */
556 0x03, 0x06, 0x05, 0x04
557};
558
559static const hda_nid_t alc660_dac_nids[3] = {
560 /* front, clfe, surround */
561 0x03, 0x05, 0x06
562};
563
564static const hda_nid_t alc861_adc_nids[1] = {
565 /* ADC0-2 */
566 0x08,
567};
568
569static const struct hda_input_mux alc861_capture_source = {
570 .num_items = 5,
571 .items = {
572 { "Mic", 0x0 },
573 { "Front Mic", 0x3 },
574 { "Line", 0x1 },
575 { "CD", 0x4 },
576 { "Mixer", 0x5 },
577 },
578};
579
580/*
581 * configuration and preset
582 */
583static const char * const alc861_models[ALC861_MODEL_LAST] = {
584 [ALC861_3ST] = "3stack",
585 [ALC660_3ST] = "3stack-660",
586 [ALC861_3ST_DIG] = "3stack-dig",
587 [ALC861_6ST_DIG] = "6stack-dig",
588 [ALC861_UNIWILL_M31] = "uniwill-m31",
589 [ALC861_TOSHIBA] = "toshiba",
590 [ALC861_ASUS] = "asus",
591 [ALC861_ASUS_LAPTOP] = "asus-laptop",
592 [ALC861_AUTO] = "auto",
593};
594
595static const struct snd_pci_quirk alc861_cfg_tbl[] = {
596 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
597 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
598 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
599 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
600 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
601 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
602 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
603 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
604 * Any other models that need this preset?
605 */
606 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
607 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
608 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
609 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
610 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
611 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
612 /* FIXME: the below seems conflict */
613 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
614 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
615 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
616 {}
617};
618
619static const struct alc_config_preset alc861_presets[] = {
620 [ALC861_3ST] = {
621 .mixers = { alc861_3ST_mixer },
622 .init_verbs = { alc861_threestack_init_verbs },
623 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
624 .dac_nids = alc861_dac_nids,
625 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
626 .channel_mode = alc861_threestack_modes,
627 .need_dac_fix = 1,
628 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
629 .adc_nids = alc861_adc_nids,
630 .input_mux = &alc861_capture_source,
631 },
632 [ALC861_3ST_DIG] = {
633 .mixers = { alc861_base_mixer },
634 .init_verbs = { alc861_threestack_init_verbs },
635 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
636 .dac_nids = alc861_dac_nids,
637 .dig_out_nid = ALC861_DIGOUT_NID,
638 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
639 .channel_mode = alc861_threestack_modes,
640 .need_dac_fix = 1,
641 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
642 .adc_nids = alc861_adc_nids,
643 .input_mux = &alc861_capture_source,
644 },
645 [ALC861_6ST_DIG] = {
646 .mixers = { alc861_base_mixer },
647 .init_verbs = { alc861_base_init_verbs },
648 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
649 .dac_nids = alc861_dac_nids,
650 .dig_out_nid = ALC861_DIGOUT_NID,
651 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
652 .channel_mode = alc861_8ch_modes,
653 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
654 .adc_nids = alc861_adc_nids,
655 .input_mux = &alc861_capture_source,
656 },
657 [ALC660_3ST] = {
658 .mixers = { alc861_3ST_mixer },
659 .init_verbs = { alc861_threestack_init_verbs },
660 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
661 .dac_nids = alc660_dac_nids,
662 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
663 .channel_mode = alc861_threestack_modes,
664 .need_dac_fix = 1,
665 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
666 .adc_nids = alc861_adc_nids,
667 .input_mux = &alc861_capture_source,
668 },
669 [ALC861_UNIWILL_M31] = {
670 .mixers = { alc861_uniwill_m31_mixer },
671 .init_verbs = { alc861_uniwill_m31_init_verbs },
672 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
673 .dac_nids = alc861_dac_nids,
674 .dig_out_nid = ALC861_DIGOUT_NID,
675 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
676 .channel_mode = alc861_uniwill_m31_modes,
677 .need_dac_fix = 1,
678 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
679 .adc_nids = alc861_adc_nids,
680 .input_mux = &alc861_capture_source,
681 },
682 [ALC861_TOSHIBA] = {
683 .mixers = { alc861_toshiba_mixer },
684 .init_verbs = { alc861_base_init_verbs,
685 alc861_toshiba_init_verbs },
686 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
687 .dac_nids = alc861_dac_nids,
688 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
689 .channel_mode = alc883_3ST_2ch_modes,
690 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
691 .adc_nids = alc861_adc_nids,
692 .input_mux = &alc861_capture_source,
693 .unsol_event = alc861_toshiba_unsol_event,
694 .init_hook = alc861_toshiba_automute,
695 },
696 [ALC861_ASUS] = {
697 .mixers = { alc861_asus_mixer },
698 .init_verbs = { alc861_asus_init_verbs },
699 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
700 .dac_nids = alc861_dac_nids,
701 .dig_out_nid = ALC861_DIGOUT_NID,
702 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
703 .channel_mode = alc861_asus_modes,
704 .need_dac_fix = 1,
705 .hp_nid = 0x06,
706 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
707 .adc_nids = alc861_adc_nids,
708 .input_mux = &alc861_capture_source,
709 },
710 [ALC861_ASUS_LAPTOP] = {
711 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
712 .init_verbs = { alc861_asus_init_verbs,
713 alc861_asus_laptop_init_verbs },
714 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
715 .dac_nids = alc861_dac_nids,
716 .dig_out_nid = ALC861_DIGOUT_NID,
717 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
718 .channel_mode = alc883_3ST_2ch_modes,
719 .need_dac_fix = 1,
720 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
721 .adc_nids = alc861_adc_nids,
722 .input_mux = &alc861_capture_source,
723 },
724};
725
diff --git a/sound/pci/hda/alc861vd_quirks.c b/sound/pci/hda/alc861vd_quirks.c
new file mode 100644
index 00000000000..8f28450f41f
--- /dev/null
+++ b/sound/pci/hda/alc861vd_quirks.c
@@ -0,0 +1,605 @@
1/*
2 * ALC660-VD/ALC861-VD quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC861-VD models */
7enum {
8 ALC861VD_AUTO,
9 ALC660VD_3ST,
10 ALC660VD_3ST_DIG,
11 ALC660VD_ASUS_V1S,
12 ALC861VD_3ST,
13 ALC861VD_3ST_DIG,
14 ALC861VD_6ST_DIG,
15 ALC861VD_LENOVO,
16 ALC861VD_DALLAS,
17 ALC861VD_HP,
18 ALC861VD_MODEL_LAST,
19};
20
21#define ALC861VD_DIGOUT_NID 0x06
22
23static const hda_nid_t alc861vd_dac_nids[4] = {
24 /* front, surr, clfe, side surr */
25 0x02, 0x03, 0x04, 0x05
26};
27
28/* dac_nids for ALC660vd are in a different order - according to
29 * Realtek's driver.
30 * This should probably result in a different mixer for 6stack models
31 * of ALC660vd codecs, but for now there is only 3stack mixer
32 * - and it is the same as in 861vd.
33 * adc_nids in ALC660vd are (is) the same as in 861vd
34 */
35static const hda_nid_t alc660vd_dac_nids[3] = {
36 /* front, rear, clfe, rear_surr */
37 0x02, 0x04, 0x03
38};
39
40static const hda_nid_t alc861vd_adc_nids[1] = {
41 /* ADC0 */
42 0x09,
43};
44
45static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
46
47/* input MUX */
48/* FIXME: should be a matrix-type input source selection */
49static const struct hda_input_mux alc861vd_capture_source = {
50 .num_items = 4,
51 .items = {
52 { "Mic", 0x0 },
53 { "Front Mic", 0x1 },
54 { "Line", 0x2 },
55 { "CD", 0x4 },
56 },
57};
58
59static const struct hda_input_mux alc861vd_dallas_capture_source = {
60 .num_items = 2,
61 .items = {
62 { "Mic", 0x0 },
63 { "Internal Mic", 0x1 },
64 },
65};
66
67static const struct hda_input_mux alc861vd_hp_capture_source = {
68 .num_items = 2,
69 .items = {
70 { "Front Mic", 0x0 },
71 { "ATAPI Mic", 0x1 },
72 },
73};
74
75/*
76 * 2ch mode
77 */
78static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
79 { 2, NULL }
80};
81
82/*
83 * 6ch mode
84 */
85static const struct hda_verb alc861vd_6stack_ch6_init[] = {
86 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
87 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
88 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
89 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
90 { } /* end */
91};
92
93/*
94 * 8ch mode
95 */
96static const struct hda_verb alc861vd_6stack_ch8_init[] = {
97 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
98 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
99 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
100 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
101 { } /* end */
102};
103
104static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
105 { 6, alc861vd_6stack_ch6_init },
106 { 8, alc861vd_6stack_ch8_init },
107};
108
109static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
110 {
111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
112 .name = "Channel Mode",
113 .info = alc_ch_mode_info,
114 .get = alc_ch_mode_get,
115 .put = alc_ch_mode_put,
116 },
117 { } /* end */
118};
119
120/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
121 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
122 */
123static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
124 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
125 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
126
127 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
128 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
129
130 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
131 HDA_OUTPUT),
132 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
133 HDA_OUTPUT),
134 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
135 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
136
137 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
138 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
139
140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
141
142 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
145
146 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
147 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
149
150 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
151 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
152
153 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
154 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
155
156 { } /* end */
157};
158
159static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
160 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
161 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
162
163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
164
165 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
167 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
168
169 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
170 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
171 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
172
173 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
174 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
175
176 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
177 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
178
179 { } /* end */
180};
181
182static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
183 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
184 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
185 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
186
187 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
188
189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
192
193 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
194 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
195 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
196
197 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
198 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
199
200 { } /* end */
201};
202
203/* Pin assignment: Speaker=0x14, HP = 0x15,
204 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
205 */
206static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
207 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
208 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
209 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
210 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
214 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
215 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
216 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
217 { } /* end */
218};
219
220/* Pin assignment: Speaker=0x14, Line-out = 0x15,
221 * Front Mic=0x18, ATAPI Mic = 0x19,
222 */
223static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
224 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
225 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
226 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
227 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
228 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
229 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
230 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
231 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
232
233 { } /* end */
234};
235
236/*
237 * generic initialization of ADC, input mixers and output mixers
238 */
239static const struct hda_verb alc861vd_volume_init_verbs[] = {
240 /*
241 * Unmute ADC0 and set the default input to mic-in
242 */
243 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
245
246 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
247 * the analog-loopback mixer widget
248 */
249 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
253 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
254 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
255
256 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
257 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
261
262 /*
263 * Set up output mixers (0x02 - 0x05)
264 */
265 /* set vol=0 to output mixers */
266 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
267 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
268 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
269 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
270
271 /* set up input amps for analog loopback */
272 /* Amp Indices: DAC = 0, mixer = 1 */
273 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
274 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
275 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
276 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
277 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
278 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
279 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
280 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
281
282 { }
283};
284
285/*
286 * 3-stack pin configuration:
287 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
288 */
289static const struct hda_verb alc861vd_3stack_init_verbs[] = {
290 /*
291 * Set pin mode and muting
292 */
293 /* set front pin widgets 0x14 for output */
294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
295 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
296 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
297
298 /* Mic (rear) pin: input vref at 80% */
299 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
300 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
301 /* Front Mic pin: input vref at 80% */
302 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
303 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
304 /* Line In pin: input */
305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
307 /* Line-2 In: Headphone output (output 0 - 0x0c) */
308 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
310 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
311 /* CD pin widget for input */
312 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
313
314 { }
315};
316
317/*
318 * 6-stack pin configuration:
319 */
320static const struct hda_verb alc861vd_6stack_init_verbs[] = {
321 /*
322 * Set pin mode and muting
323 */
324 /* set front pin widgets 0x14 for output */
325 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
326 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
327 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
328
329 /* Rear Pin: output 1 (0x0d) */
330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
333 /* CLFE Pin: output 2 (0x0e) */
334 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
335 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
336 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
337 /* Side Pin: output 3 (0x0f) */
338 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
339 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
340 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
341
342 /* Mic (rear) pin: input vref at 80% */
343 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
344 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
345 /* Front Mic pin: input vref at 80% */
346 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
347 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
348 /* Line In pin: input */
349 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
350 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
351 /* Line-2 In: Headphone output (output 0 - 0x0c) */
352 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
353 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
354 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
355 /* CD pin widget for input */
356 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
357
358 { }
359};
360
361static const struct hda_verb alc861vd_eapd_verbs[] = {
362 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
363 { }
364};
365
366static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
370 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
371 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
372 {}
373};
374
375static void alc861vd_lenovo_setup(struct hda_codec *codec)
376{
377 struct alc_spec *spec = codec->spec;
378 spec->autocfg.hp_pins[0] = 0x1b;
379 spec->autocfg.speaker_pins[0] = 0x14;
380 spec->automute = 1;
381 spec->automute_mode = ALC_AUTOMUTE_AMP;
382}
383
384static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
385{
386 alc_hp_automute(codec);
387 alc88x_simple_mic_automute(codec);
388}
389
390static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
391 unsigned int res)
392{
393 switch (res >> 26) {
394 case ALC_MIC_EVENT:
395 alc88x_simple_mic_automute(codec);
396 break;
397 default:
398 alc_sku_unsol_event(codec, res);
399 break;
400 }
401}
402
403static const struct hda_verb alc861vd_dallas_verbs[] = {
404 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
405 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
406 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
407 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
408
409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
411 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
412 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
414 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
415 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
416 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
417
418 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
419 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
420 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
422 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
423 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
424 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
425 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
426
427 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
428 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
429 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
430 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
431 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
432 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
433 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
434 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
435
436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
439 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
440
441 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
442 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
443 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
444
445 { } /* end */
446};
447
448/* toggle speaker-output according to the hp-jack state */
449static void alc861vd_dallas_setup(struct hda_codec *codec)
450{
451 struct alc_spec *spec = codec->spec;
452
453 spec->autocfg.hp_pins[0] = 0x15;
454 spec->autocfg.speaker_pins[0] = 0x14;
455 spec->automute = 1;
456 spec->automute_mode = ALC_AUTOMUTE_AMP;
457}
458
459/*
460 * configuration and preset
461 */
462static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
463 [ALC660VD_3ST] = "3stack-660",
464 [ALC660VD_3ST_DIG] = "3stack-660-digout",
465 [ALC660VD_ASUS_V1S] = "asus-v1s",
466 [ALC861VD_3ST] = "3stack",
467 [ALC861VD_3ST_DIG] = "3stack-digout",
468 [ALC861VD_6ST_DIG] = "6stack-digout",
469 [ALC861VD_LENOVO] = "lenovo",
470 [ALC861VD_DALLAS] = "dallas",
471 [ALC861VD_HP] = "hp",
472 [ALC861VD_AUTO] = "auto",
473};
474
475static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
476 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
477 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
478 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
479 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
480 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
481 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
482 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
483 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
484 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
485 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
486 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
487 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
488 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
489 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
490 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
491 {}
492};
493
494static const struct alc_config_preset alc861vd_presets[] = {
495 [ALC660VD_3ST] = {
496 .mixers = { alc861vd_3st_mixer },
497 .init_verbs = { alc861vd_volume_init_verbs,
498 alc861vd_3stack_init_verbs },
499 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
500 .dac_nids = alc660vd_dac_nids,
501 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
502 .channel_mode = alc861vd_3stack_2ch_modes,
503 .input_mux = &alc861vd_capture_source,
504 },
505 [ALC660VD_3ST_DIG] = {
506 .mixers = { alc861vd_3st_mixer },
507 .init_verbs = { alc861vd_volume_init_verbs,
508 alc861vd_3stack_init_verbs },
509 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
510 .dac_nids = alc660vd_dac_nids,
511 .dig_out_nid = ALC861VD_DIGOUT_NID,
512 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
513 .channel_mode = alc861vd_3stack_2ch_modes,
514 .input_mux = &alc861vd_capture_source,
515 },
516 [ALC861VD_3ST] = {
517 .mixers = { alc861vd_3st_mixer },
518 .init_verbs = { alc861vd_volume_init_verbs,
519 alc861vd_3stack_init_verbs },
520 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
521 .dac_nids = alc861vd_dac_nids,
522 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
523 .channel_mode = alc861vd_3stack_2ch_modes,
524 .input_mux = &alc861vd_capture_source,
525 },
526 [ALC861VD_3ST_DIG] = {
527 .mixers = { alc861vd_3st_mixer },
528 .init_verbs = { alc861vd_volume_init_verbs,
529 alc861vd_3stack_init_verbs },
530 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
531 .dac_nids = alc861vd_dac_nids,
532 .dig_out_nid = ALC861VD_DIGOUT_NID,
533 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
534 .channel_mode = alc861vd_3stack_2ch_modes,
535 .input_mux = &alc861vd_capture_source,
536 },
537 [ALC861VD_6ST_DIG] = {
538 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
539 .init_verbs = { alc861vd_volume_init_verbs,
540 alc861vd_6stack_init_verbs },
541 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
542 .dac_nids = alc861vd_dac_nids,
543 .dig_out_nid = ALC861VD_DIGOUT_NID,
544 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
545 .channel_mode = alc861vd_6stack_modes,
546 .input_mux = &alc861vd_capture_source,
547 },
548 [ALC861VD_LENOVO] = {
549 .mixers = { alc861vd_lenovo_mixer },
550 .init_verbs = { alc861vd_volume_init_verbs,
551 alc861vd_3stack_init_verbs,
552 alc861vd_eapd_verbs,
553 alc861vd_lenovo_unsol_verbs },
554 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
555 .dac_nids = alc660vd_dac_nids,
556 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
557 .channel_mode = alc861vd_3stack_2ch_modes,
558 .input_mux = &alc861vd_capture_source,
559 .unsol_event = alc861vd_lenovo_unsol_event,
560 .setup = alc861vd_lenovo_setup,
561 .init_hook = alc861vd_lenovo_init_hook,
562 },
563 [ALC861VD_DALLAS] = {
564 .mixers = { alc861vd_dallas_mixer },
565 .init_verbs = { alc861vd_dallas_verbs },
566 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
567 .dac_nids = alc861vd_dac_nids,
568 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
569 .channel_mode = alc861vd_3stack_2ch_modes,
570 .input_mux = &alc861vd_dallas_capture_source,
571 .unsol_event = alc_sku_unsol_event,
572 .setup = alc861vd_dallas_setup,
573 .init_hook = alc_hp_automute,
574 },
575 [ALC861VD_HP] = {
576 .mixers = { alc861vd_hp_mixer },
577 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
578 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
579 .dac_nids = alc861vd_dac_nids,
580 .dig_out_nid = ALC861VD_DIGOUT_NID,
581 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
582 .channel_mode = alc861vd_3stack_2ch_modes,
583 .input_mux = &alc861vd_hp_capture_source,
584 .unsol_event = alc_sku_unsol_event,
585 .setup = alc861vd_dallas_setup,
586 .init_hook = alc_hp_automute,
587 },
588 [ALC660VD_ASUS_V1S] = {
589 .mixers = { alc861vd_lenovo_mixer },
590 .init_verbs = { alc861vd_volume_init_verbs,
591 alc861vd_3stack_init_verbs,
592 alc861vd_eapd_verbs,
593 alc861vd_lenovo_unsol_verbs },
594 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
595 .dac_nids = alc660vd_dac_nids,
596 .dig_out_nid = ALC861VD_DIGOUT_NID,
597 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
598 .channel_mode = alc861vd_3stack_2ch_modes,
599 .input_mux = &alc861vd_capture_source,
600 .unsol_event = alc861vd_lenovo_unsol_event,
601 .setup = alc861vd_lenovo_setup,
602 .init_hook = alc861vd_lenovo_init_hook,
603 },
604};
605
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c
new file mode 100644
index 00000000000..c844d2b5998
--- /dev/null
+++ b/sound/pci/hda/alc880_quirks.c
@@ -0,0 +1,1898 @@
1/*
2 * ALC880 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC880 board config type */
7enum {
8 ALC880_AUTO,
9 ALC880_3ST,
10 ALC880_3ST_DIG,
11 ALC880_5ST,
12 ALC880_5ST_DIG,
13 ALC880_W810,
14 ALC880_Z71V,
15 ALC880_6ST,
16 ALC880_6ST_DIG,
17 ALC880_F1734,
18 ALC880_ASUS,
19 ALC880_ASUS_DIG,
20 ALC880_ASUS_W1V,
21 ALC880_ASUS_DIG2,
22 ALC880_FUJITSU,
23 ALC880_UNIWILL_DIG,
24 ALC880_UNIWILL,
25 ALC880_UNIWILL_P53,
26 ALC880_CLEVO,
27 ALC880_TCL_S700,
28 ALC880_LG,
29 ALC880_LG_LW,
30 ALC880_MEDION_RIM,
31#ifdef CONFIG_SND_DEBUG
32 ALC880_TEST,
33#endif
34 ALC880_MODEL_LAST /* last tag */
35};
36
37/*
38 * ALC880 3-stack model
39 *
40 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
41 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
42 * F-Mic = 0x1b, HP = 0x19
43 */
44
45static const hda_nid_t alc880_dac_nids[4] = {
46 /* front, rear, clfe, rear_surr */
47 0x02, 0x05, 0x04, 0x03
48};
49
50static const hda_nid_t alc880_adc_nids[3] = {
51 /* ADC0-2 */
52 0x07, 0x08, 0x09,
53};
54
55/* The datasheet says the node 0x07 is connected from inputs,
56 * but it shows zero connection in the real implementation on some devices.
57 * Note: this is a 915GAV bug, fixed on 915GLV
58 */
59static const hda_nid_t alc880_adc_nids_alt[2] = {
60 /* ADC1-2 */
61 0x08, 0x09,
62};
63
64#define ALC880_DIGOUT_NID 0x06
65#define ALC880_DIGIN_NID 0x0a
66#define ALC880_PIN_CD_NID 0x1c
67
68static const struct hda_input_mux alc880_capture_source = {
69 .num_items = 4,
70 .items = {
71 { "Mic", 0x0 },
72 { "Front Mic", 0x3 },
73 { "Line", 0x2 },
74 { "CD", 0x4 },
75 },
76};
77
78/* channel source setting (2/6 channel selection for 3-stack) */
79/* 2ch mode */
80static const struct hda_verb alc880_threestack_ch2_init[] = {
81 /* set line-in to input, mute it */
82 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
83 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
84 /* set mic-in to input vref 80%, mute it */
85 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
86 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
87 { } /* end */
88};
89
90/* 6ch mode */
91static const struct hda_verb alc880_threestack_ch6_init[] = {
92 /* set line-in to output, unmute it */
93 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
94 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
95 /* set mic-in to output, unmute it */
96 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
97 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
98 { } /* end */
99};
100
101static const struct hda_channel_mode alc880_threestack_modes[2] = {
102 { 2, alc880_threestack_ch2_init },
103 { 6, alc880_threestack_ch6_init },
104};
105
106static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
107 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
108 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
109 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
110 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
111 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
112 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
113 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
114 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
115 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
116 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
117 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
118 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
121 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
122 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
123 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
124 {
125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
126 .name = "Channel Mode",
127 .info = alc_ch_mode_info,
128 .get = alc_ch_mode_get,
129 .put = alc_ch_mode_put,
130 },
131 { } /* end */
132};
133
134/*
135 * ALC880 5-stack model
136 *
137 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
138 * Side = 0x02 (0xd)
139 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
140 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
141 */
142
143/* additional mixers to alc880_three_stack_mixer */
144static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
145 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
146 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
147 { } /* end */
148};
149
150/* channel source setting (6/8 channel selection for 5-stack) */
151/* 6ch mode */
152static const struct hda_verb alc880_fivestack_ch6_init[] = {
153 /* set line-in to input, mute it */
154 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
155 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
156 { } /* end */
157};
158
159/* 8ch mode */
160static const struct hda_verb alc880_fivestack_ch8_init[] = {
161 /* set line-in to output, unmute it */
162 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
163 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
164 { } /* end */
165};
166
167static const struct hda_channel_mode alc880_fivestack_modes[2] = {
168 { 6, alc880_fivestack_ch6_init },
169 { 8, alc880_fivestack_ch8_init },
170};
171
172
173/*
174 * ALC880 6-stack model
175 *
176 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
177 * Side = 0x05 (0x0f)
178 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
179 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
180 */
181
182static const hda_nid_t alc880_6st_dac_nids[4] = {
183 /* front, rear, clfe, rear_surr */
184 0x02, 0x03, 0x04, 0x05
185};
186
187static const struct hda_input_mux alc880_6stack_capture_source = {
188 .num_items = 4,
189 .items = {
190 { "Mic", 0x0 },
191 { "Front Mic", 0x1 },
192 { "Line", 0x2 },
193 { "CD", 0x4 },
194 },
195};
196
197/* fixed 8-channels */
198static const struct hda_channel_mode alc880_sixstack_modes[1] = {
199 { 8, NULL },
200};
201
202static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
203 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
204 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
205 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
206 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
207 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
208 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
209 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
210 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
211 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
212 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
213 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
214 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
215 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
216 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
219 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
220 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
221 {
222 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
223 .name = "Channel Mode",
224 .info = alc_ch_mode_info,
225 .get = alc_ch_mode_get,
226 .put = alc_ch_mode_put,
227 },
228 { } /* end */
229};
230
231
232/*
233 * ALC880 W810 model
234 *
235 * W810 has rear IO for:
236 * Front (DAC 02)
237 * Surround (DAC 03)
238 * Center/LFE (DAC 04)
239 * Digital out (06)
240 *
241 * The system also has a pair of internal speakers, and a headphone jack.
242 * These are both connected to Line2 on the codec, hence to DAC 02.
243 *
244 * There is a variable resistor to control the speaker or headphone
245 * volume. This is a hardware-only device without a software API.
246 *
247 * Plugging headphones in will disable the internal speakers. This is
248 * implemented in hardware, not via the driver using jack sense. In
249 * a similar fashion, plugging into the rear socket marked "front" will
250 * disable both the speakers and headphones.
251 *
252 * For input, there's a microphone jack, and an "audio in" jack.
253 * These may not do anything useful with this driver yet, because I
254 * haven't setup any initialization verbs for these yet...
255 */
256
257static const hda_nid_t alc880_w810_dac_nids[3] = {
258 /* front, rear/surround, clfe */
259 0x02, 0x03, 0x04
260};
261
262/* fixed 6 channels */
263static const struct hda_channel_mode alc880_w810_modes[1] = {
264 { 6, NULL }
265};
266
267/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
268static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
269 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
270 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
271 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
272 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
273 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
274 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
275 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
276 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
277 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
278 { } /* end */
279};
280
281
282/*
283 * Z710V model
284 *
285 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
286 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
287 * Line = 0x1a
288 */
289
290static const hda_nid_t alc880_z71v_dac_nids[1] = {
291 0x02
292};
293#define ALC880_Z71V_HP_DAC 0x03
294
295/* fixed 2 channels */
296static const struct hda_channel_mode alc880_2_jack_modes[1] = {
297 { 2, NULL }
298};
299
300static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
301 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
302 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
303 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
304 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
305 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
306 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
307 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
308 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
309 { } /* end */
310};
311
312
313/*
314 * ALC880 F1734 model
315 *
316 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
317 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
318 */
319
320static const hda_nid_t alc880_f1734_dac_nids[1] = {
321 0x03
322};
323#define ALC880_F1734_HP_DAC 0x02
324
325static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
326 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
327 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
328 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
329 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
330 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
331 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
332 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
333 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
334 { } /* end */
335};
336
337static const struct hda_input_mux alc880_f1734_capture_source = {
338 .num_items = 2,
339 .items = {
340 { "Mic", 0x1 },
341 { "CD", 0x4 },
342 },
343};
344
345
346/*
347 * ALC880 ASUS model
348 *
349 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
350 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
351 * Mic = 0x18, Line = 0x1a
352 */
353
354#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
355#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
356
357static const struct snd_kcontrol_new alc880_asus_mixer[] = {
358 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
359 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
360 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
361 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
362 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
363 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
364 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
365 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
366 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
367 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
368 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
369 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
372 {
373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
374 .name = "Channel Mode",
375 .info = alc_ch_mode_info,
376 .get = alc_ch_mode_get,
377 .put = alc_ch_mode_put,
378 },
379 { } /* end */
380};
381
382/*
383 * ALC880 ASUS W1V model
384 *
385 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
386 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
387 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
388 */
389
390/* additional mixers to alc880_asus_mixer */
391static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
392 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
393 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
394 { } /* end */
395};
396
397/* TCL S700 */
398static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
399 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
400 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
402 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
403 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
406 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
407 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
408 { } /* end */
409};
410
411/* Uniwill */
412static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
413 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
414 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
415 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
416 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
417 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
418 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
419 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
420 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
421 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
422 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
423 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
424 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
427 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
428 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
429 {
430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
431 .name = "Channel Mode",
432 .info = alc_ch_mode_info,
433 .get = alc_ch_mode_get,
434 .put = alc_ch_mode_put,
435 },
436 { } /* end */
437};
438
439static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
440 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
441 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
442 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
443 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
444 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
445 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
448 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
449 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
450 { } /* end */
451};
452
453static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
454 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
455 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
456 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
457 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
460 { } /* end */
461};
462
463/*
464 * initialize the codec volumes, etc
465 */
466
467/*
468 * generic initialization of ADC, input mixers and output mixers
469 */
470static const struct hda_verb alc880_volume_init_verbs[] = {
471 /*
472 * Unmute ADC0-2 and set the default input to mic-in
473 */
474 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
475 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
476 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
477 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
478 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
479 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
480
481 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
482 * mixer widget
483 * Note: PASD motherboards uses the Line In 2 as the input for front
484 * panel mic (mic 2)
485 */
486 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
492 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
493 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
494
495 /*
496 * Set up output mixers (0x0c - 0x0f)
497 */
498 /* set vol=0 to output mixers */
499 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
500 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
501 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
502 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
503 /* set up input amps for analog loopback */
504 /* Amp Indices: DAC = 0, mixer = 1 */
505 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
506 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
508 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
509 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
510 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
511 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
512 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
513
514 { }
515};
516
517/*
518 * 3-stack pin configuration:
519 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
520 */
521static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
522 /*
523 * preset connection lists of input pins
524 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
525 */
526 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
527 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
528 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
529
530 /*
531 * Set pin mode and muting
532 */
533 /* set front pin widgets 0x14 for output */
534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
536 /* Mic1 (rear panel) pin widget for input and vref at 80% */
537 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
538 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
539 /* Mic2 (as headphone out) for HP output */
540 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
541 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
542 /* Line In pin widget for input */
543 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
544 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
545 /* Line2 (as front mic) pin widget for input and vref at 80% */
546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
547 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
548 /* CD pin widget for input */
549 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
550
551 { }
552};
553
554/*
555 * 5-stack pin configuration:
556 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
557 * line-in/side = 0x1a, f-mic = 0x1b
558 */
559static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
560 /*
561 * preset connection lists of input pins
562 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
563 */
564 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
565 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
566
567 /*
568 * Set pin mode and muting
569 */
570 /* set pin widgets 0x14-0x17 for output */
571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
572 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
573 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
574 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
575 /* unmute pins for output (no gain on this amp) */
576 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
578 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
579 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
580
581 /* Mic1 (rear panel) pin widget for input and vref at 80% */
582 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
583 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
584 /* Mic2 (as headphone out) for HP output */
585 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
587 /* Line In pin widget for input */
588 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
590 /* Line2 (as front mic) pin widget for input and vref at 80% */
591 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
592 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
593 /* CD pin widget for input */
594 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
595
596 { }
597};
598
599/*
600 * W810 pin configuration:
601 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
602 */
603static const struct hda_verb alc880_pin_w810_init_verbs[] = {
604 /* hphone/speaker input selector: front DAC */
605 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
606
607 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
608 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
611 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
612 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
613
614 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
615 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
616
617 { }
618};
619
620/*
621 * Z71V pin configuration:
622 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
623 */
624static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
625 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
626 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
627 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
628 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
629
630 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
631 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
632 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
633 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
634
635 { }
636};
637
638/*
639 * 6-stack pin configuration:
640 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
641 * f-mic = 0x19, line = 0x1a, HP = 0x1b
642 */
643static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
644 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
645
646 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
647 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
648 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
650 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
651 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
652 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
653 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
654
655 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
656 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
658 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
660 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
661 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
662 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
663 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
664
665 { }
666};
667
668/*
669 * Uniwill pin configuration:
670 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
671 * line = 0x1a
672 */
673static const struct hda_verb alc880_uniwill_init_verbs[] = {
674 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
675
676 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
677 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
678 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
679 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
680 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
681 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
682 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
683 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
686 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
687 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
688 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
690
691 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
693 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
694 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
695 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
697 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
698 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
699 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
700
701 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
702 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
703
704 { }
705};
706
707/*
708* Uniwill P53
709* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
710 */
711static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
712 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
713
714 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
715 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
716 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
717 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
718 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
719 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
720 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
721 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
722 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
723 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
724 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
725 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
726
727 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
731 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
733
734 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
735 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_DCVOL_EVENT},
736
737 { }
738};
739
740static const struct hda_verb alc880_beep_init_verbs[] = {
741 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
742 { }
743};
744
745static void alc880_uniwill_setup(struct hda_codec *codec)
746{
747 struct alc_spec *spec = codec->spec;
748
749 spec->autocfg.hp_pins[0] = 0x14;
750 spec->autocfg.speaker_pins[0] = 0x15;
751 spec->autocfg.speaker_pins[0] = 0x16;
752 spec->automute = 1;
753 spec->automute_mode = ALC_AUTOMUTE_AMP;
754}
755
756static void alc880_uniwill_init_hook(struct hda_codec *codec)
757{
758 alc_hp_automute(codec);
759 alc88x_simple_mic_automute(codec);
760}
761
762static void alc880_uniwill_unsol_event(struct hda_codec *codec,
763 unsigned int res)
764{
765 /* Looks like the unsol event is incompatible with the standard
766 * definition. 4bit tag is placed at 28 bit!
767 */
768 switch (res >> 28) {
769 case ALC_MIC_EVENT:
770 alc88x_simple_mic_automute(codec);
771 break;
772 default:
773 alc_sku_unsol_event(codec, res);
774 break;
775 }
776}
777
778static void alc880_uniwill_p53_setup(struct hda_codec *codec)
779{
780 struct alc_spec *spec = codec->spec;
781
782 spec->autocfg.hp_pins[0] = 0x14;
783 spec->autocfg.speaker_pins[0] = 0x15;
784 spec->automute = 1;
785 spec->automute_mode = ALC_AUTOMUTE_AMP;
786}
787
788static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
789{
790 unsigned int present;
791
792 present = snd_hda_codec_read(codec, 0x21, 0,
793 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
794 present &= HDA_AMP_VOLMASK;
795 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
796 HDA_AMP_VOLMASK, present);
797 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
798 HDA_AMP_VOLMASK, present);
799}
800
801static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
802 unsigned int res)
803{
804 /* Looks like the unsol event is incompatible with the standard
805 * definition. 4bit tag is placed at 28 bit!
806 */
807 if ((res >> 28) == ALC_DCVOL_EVENT)
808 alc880_uniwill_p53_dcvol_automute(codec);
809 else
810 alc_sku_unsol_event(codec, res);
811}
812
813/*
814 * F1734 pin configuration:
815 * HP = 0x14, speaker-out = 0x15, mic = 0x18
816 */
817static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
818 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
819 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
820 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
821 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
822 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
823
824 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
825 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
826 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
828
829 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
830 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
831 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
832 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
833 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
835 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
836 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
837 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
838
839 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
840 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_DCVOL_EVENT},
841
842 { }
843};
844
845/*
846 * ASUS pin configuration:
847 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
848 */
849static const struct hda_verb alc880_pin_asus_init_verbs[] = {
850 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
851 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
852 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
853 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
854
855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
858 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
859 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
860 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
861 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
862 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
863
864 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
865 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
866 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
867 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
868 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
869 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
870 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
871 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
872 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
873
874 { }
875};
876
877/* Enable GPIO mask and set output */
878#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
879#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
880#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
881
882/* Clevo m520g init */
883static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
884 /* headphone output */
885 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
886 /* line-out */
887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
889 /* Line-in */
890 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
891 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
892 /* CD */
893 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
894 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
895 /* Mic1 (rear panel) */
896 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
897 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
898 /* Mic2 (front panel) */
899 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
900 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
901 /* headphone */
902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
903 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
904 /* change to EAPD mode */
905 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
906 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
907
908 { }
909};
910
911static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
912 /* change to EAPD mode */
913 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
914 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
915
916 /* Headphone output */
917 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
918 /* Front output*/
919 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
920 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
921
922 /* Line In pin widget for input */
923 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
924 /* CD pin widget for input */
925 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
926 /* Mic1 (rear panel) pin widget for input and vref at 80% */
927 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
928
929 /* change to EAPD mode */
930 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
931 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
932
933 { }
934};
935
936/*
937 * LG m1 express dual
938 *
939 * Pin assignment:
940 * Rear Line-In/Out (blue): 0x14
941 * Build-in Mic-In: 0x15
942 * Speaker-out: 0x17
943 * HP-Out (green): 0x1b
944 * Mic-In/Out (red): 0x19
945 * SPDIF-Out: 0x1e
946 */
947
948/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
949static const hda_nid_t alc880_lg_dac_nids[3] = {
950 0x05, 0x02, 0x03
951};
952
953/* seems analog CD is not working */
954static const struct hda_input_mux alc880_lg_capture_source = {
955 .num_items = 3,
956 .items = {
957 { "Mic", 0x1 },
958 { "Line", 0x5 },
959 { "Internal Mic", 0x6 },
960 },
961};
962
963/* 2,4,6 channel modes */
964static const struct hda_verb alc880_lg_ch2_init[] = {
965 /* set line-in and mic-in to input */
966 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
967 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
968 { }
969};
970
971static const struct hda_verb alc880_lg_ch4_init[] = {
972 /* set line-in to out and mic-in to input */
973 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
974 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
975 { }
976};
977
978static const struct hda_verb alc880_lg_ch6_init[] = {
979 /* set line-in and mic-in to output */
980 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
981 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
982 { }
983};
984
985static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
986 { 2, alc880_lg_ch2_init },
987 { 4, alc880_lg_ch4_init },
988 { 6, alc880_lg_ch6_init },
989};
990
991static const struct snd_kcontrol_new alc880_lg_mixer[] = {
992 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
993 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
994 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
995 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
996 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
997 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
998 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
999 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1004 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1005 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1006 {
1007 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1008 .name = "Channel Mode",
1009 .info = alc_ch_mode_info,
1010 .get = alc_ch_mode_get,
1011 .put = alc_ch_mode_put,
1012 },
1013 { } /* end */
1014};
1015
1016static const struct hda_verb alc880_lg_init_verbs[] = {
1017 /* set capture source to mic-in */
1018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1021 /* mute all amp mixer inputs */
1022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1025 /* line-in to input */
1026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1027 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1028 /* built-in mic */
1029 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1030 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1031 /* speaker-out */
1032 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1033 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1034 /* mic-in to input */
1035 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1036 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1037 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1038 /* HP-out */
1039 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1040 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1041 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1042 /* jack sense */
1043 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1044 { }
1045};
1046
1047/* toggle speaker-output according to the hp-jack state */
1048static void alc880_lg_setup(struct hda_codec *codec)
1049{
1050 struct alc_spec *spec = codec->spec;
1051
1052 spec->autocfg.hp_pins[0] = 0x1b;
1053 spec->autocfg.speaker_pins[0] = 0x17;
1054 spec->automute = 1;
1055 spec->automute_mode = ALC_AUTOMUTE_AMP;
1056}
1057
1058/*
1059 * LG LW20
1060 *
1061 * Pin assignment:
1062 * Speaker-out: 0x14
1063 * Mic-In: 0x18
1064 * Built-in Mic-In: 0x19
1065 * Line-In: 0x1b
1066 * HP-Out: 0x1a
1067 * SPDIF-Out: 0x1e
1068 */
1069
1070static const struct hda_input_mux alc880_lg_lw_capture_source = {
1071 .num_items = 3,
1072 .items = {
1073 { "Mic", 0x0 },
1074 { "Internal Mic", 0x1 },
1075 { "Line In", 0x2 },
1076 },
1077};
1078
1079#define alc880_lg_lw_modes alc880_threestack_modes
1080
1081static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1082 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1083 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1084 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1085 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1086 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1087 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1088 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1089 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1090 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1091 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1092 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1093 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1094 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1095 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1096 {
1097 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1098 .name = "Channel Mode",
1099 .info = alc_ch_mode_info,
1100 .get = alc_ch_mode_get,
1101 .put = alc_ch_mode_put,
1102 },
1103 { } /* end */
1104};
1105
1106static const struct hda_verb alc880_lg_lw_init_verbs[] = {
1107 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1108 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1109 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1110
1111 /* set capture source to mic-in */
1112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1113 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1114 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1115 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1116 /* speaker-out */
1117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1119 /* HP-out */
1120 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1121 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1122 /* mic-in to input */
1123 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1124 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1125 /* built-in mic */
1126 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1127 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1128 /* jack sense */
1129 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1130 { }
1131};
1132
1133/* toggle speaker-output according to the hp-jack state */
1134static void alc880_lg_lw_setup(struct hda_codec *codec)
1135{
1136 struct alc_spec *spec = codec->spec;
1137
1138 spec->autocfg.hp_pins[0] = 0x1b;
1139 spec->autocfg.speaker_pins[0] = 0x14;
1140 spec->automute = 1;
1141 spec->automute_mode = ALC_AUTOMUTE_AMP;
1142}
1143
1144static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
1145 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1146 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
1147 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1148 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1149 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1150 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
1151 { } /* end */
1152};
1153
1154static const struct hda_input_mux alc880_medion_rim_capture_source = {
1155 .num_items = 2,
1156 .items = {
1157 { "Mic", 0x0 },
1158 { "Internal Mic", 0x1 },
1159 },
1160};
1161
1162static const struct hda_verb alc880_medion_rim_init_verbs[] = {
1163 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1164
1165 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1166 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1167
1168 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1169 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1170 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1171 /* Mic2 (as headphone out) for HP output */
1172 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1174 /* Internal Speaker */
1175 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1176 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1177
1178 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1179 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1180
1181 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1182 { }
1183};
1184
1185/* toggle speaker-output according to the hp-jack state */
1186static void alc880_medion_rim_automute(struct hda_codec *codec)
1187{
1188 struct alc_spec *spec = codec->spec;
1189 alc_hp_automute(codec);
1190 /* toggle EAPD */
1191 if (spec->jack_present)
1192 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
1193 else
1194 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
1195}
1196
1197static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
1198 unsigned int res)
1199{
1200 /* Looks like the unsol event is incompatible with the standard
1201 * definition. 4bit tag is placed at 28 bit!
1202 */
1203 if ((res >> 28) == ALC_HP_EVENT)
1204 alc880_medion_rim_automute(codec);
1205}
1206
1207static void alc880_medion_rim_setup(struct hda_codec *codec)
1208{
1209 struct alc_spec *spec = codec->spec;
1210
1211 spec->autocfg.hp_pins[0] = 0x14;
1212 spec->autocfg.speaker_pins[0] = 0x1b;
1213 spec->automute = 1;
1214 spec->automute_mode = ALC_AUTOMUTE_AMP;
1215}
1216
1217#ifdef CONFIG_SND_HDA_POWER_SAVE
1218static const struct hda_amp_list alc880_lg_loopbacks[] = {
1219 { 0x0b, HDA_INPUT, 1 },
1220 { 0x0b, HDA_INPUT, 6 },
1221 { 0x0b, HDA_INPUT, 7 },
1222 { } /* end */
1223};
1224#endif
1225
1226/*
1227 * Test configuration for debugging
1228 *
1229 * Almost all inputs/outputs are enabled. I/O pins can be configured via
1230 * enum controls.
1231 */
1232#ifdef CONFIG_SND_DEBUG
1233static const hda_nid_t alc880_test_dac_nids[4] = {
1234 0x02, 0x03, 0x04, 0x05
1235};
1236
1237static const struct hda_input_mux alc880_test_capture_source = {
1238 .num_items = 7,
1239 .items = {
1240 { "In-1", 0x0 },
1241 { "In-2", 0x1 },
1242 { "In-3", 0x2 },
1243 { "In-4", 0x3 },
1244 { "CD", 0x4 },
1245 { "Front", 0x5 },
1246 { "Surround", 0x6 },
1247 },
1248};
1249
1250static const struct hda_channel_mode alc880_test_modes[4] = {
1251 { 2, NULL },
1252 { 4, NULL },
1253 { 6, NULL },
1254 { 8, NULL },
1255};
1256
1257static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
1258 struct snd_ctl_elem_info *uinfo)
1259{
1260 static const char * const texts[] = {
1261 "N/A", "Line Out", "HP Out",
1262 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1263 };
1264 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1265 uinfo->count = 1;
1266 uinfo->value.enumerated.items = 8;
1267 if (uinfo->value.enumerated.item >= 8)
1268 uinfo->value.enumerated.item = 7;
1269 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1270 return 0;
1271}
1272
1273static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
1274 struct snd_ctl_elem_value *ucontrol)
1275{
1276 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1277 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1278 unsigned int pin_ctl, item = 0;
1279
1280 pin_ctl = snd_hda_codec_read(codec, nid, 0,
1281 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1282 if (pin_ctl & AC_PINCTL_OUT_EN) {
1283 if (pin_ctl & AC_PINCTL_HP_EN)
1284 item = 2;
1285 else
1286 item = 1;
1287 } else if (pin_ctl & AC_PINCTL_IN_EN) {
1288 switch (pin_ctl & AC_PINCTL_VREFEN) {
1289 case AC_PINCTL_VREF_HIZ: item = 3; break;
1290 case AC_PINCTL_VREF_50: item = 4; break;
1291 case AC_PINCTL_VREF_GRD: item = 5; break;
1292 case AC_PINCTL_VREF_80: item = 6; break;
1293 case AC_PINCTL_VREF_100: item = 7; break;
1294 }
1295 }
1296 ucontrol->value.enumerated.item[0] = item;
1297 return 0;
1298}
1299
1300static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
1301 struct snd_ctl_elem_value *ucontrol)
1302{
1303 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1304 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1305 static const unsigned int ctls[] = {
1306 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1307 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1308 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1309 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1310 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1311 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1312 };
1313 unsigned int old_ctl, new_ctl;
1314
1315 old_ctl = snd_hda_codec_read(codec, nid, 0,
1316 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1317 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1318 if (old_ctl != new_ctl) {
1319 int val;
1320 snd_hda_codec_write_cache(codec, nid, 0,
1321 AC_VERB_SET_PIN_WIDGET_CONTROL,
1322 new_ctl);
1323 val = ucontrol->value.enumerated.item[0] >= 3 ?
1324 HDA_AMP_MUTE : 0;
1325 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1326 HDA_AMP_MUTE, val);
1327 return 1;
1328 }
1329 return 0;
1330}
1331
1332static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
1333 struct snd_ctl_elem_info *uinfo)
1334{
1335 static const char * const texts[] = {
1336 "Front", "Surround", "CLFE", "Side"
1337 };
1338 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1339 uinfo->count = 1;
1340 uinfo->value.enumerated.items = 4;
1341 if (uinfo->value.enumerated.item >= 4)
1342 uinfo->value.enumerated.item = 3;
1343 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1344 return 0;
1345}
1346
1347static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
1348 struct snd_ctl_elem_value *ucontrol)
1349{
1350 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1351 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1352 unsigned int sel;
1353
1354 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1355 ucontrol->value.enumerated.item[0] = sel & 3;
1356 return 0;
1357}
1358
1359static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
1360 struct snd_ctl_elem_value *ucontrol)
1361{
1362 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1363 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1364 unsigned int sel;
1365
1366 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1367 if (ucontrol->value.enumerated.item[0] != sel) {
1368 sel = ucontrol->value.enumerated.item[0] & 3;
1369 snd_hda_codec_write_cache(codec, nid, 0,
1370 AC_VERB_SET_CONNECT_SEL, sel);
1371 return 1;
1372 }
1373 return 0;
1374}
1375
1376#define PIN_CTL_TEST(xname,nid) { \
1377 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1378 .name = xname, \
1379 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1380 .info = alc_test_pin_ctl_info, \
1381 .get = alc_test_pin_ctl_get, \
1382 .put = alc_test_pin_ctl_put, \
1383 .private_value = nid \
1384 }
1385
1386#define PIN_SRC_TEST(xname,nid) { \
1387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1388 .name = xname, \
1389 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1390 .info = alc_test_pin_src_info, \
1391 .get = alc_test_pin_src_get, \
1392 .put = alc_test_pin_src_put, \
1393 .private_value = nid \
1394 }
1395
1396static const struct snd_kcontrol_new alc880_test_mixer[] = {
1397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1398 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1399 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1400 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1401 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1402 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1403 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
1404 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1405 PIN_CTL_TEST("Front Pin Mode", 0x14),
1406 PIN_CTL_TEST("Surround Pin Mode", 0x15),
1407 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1408 PIN_CTL_TEST("Side Pin Mode", 0x17),
1409 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1410 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1411 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1412 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1413 PIN_SRC_TEST("In-1 Pin Source", 0x18),
1414 PIN_SRC_TEST("In-2 Pin Source", 0x19),
1415 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1416 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1417 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1418 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1419 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1420 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1421 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1422 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1423 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1424 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1425 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1426 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1427 {
1428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1429 .name = "Channel Mode",
1430 .info = alc_ch_mode_info,
1431 .get = alc_ch_mode_get,
1432 .put = alc_ch_mode_put,
1433 },
1434 { } /* end */
1435};
1436
1437static const struct hda_verb alc880_test_init_verbs[] = {
1438 /* Unmute inputs of 0x0c - 0x0f */
1439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1440 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1442 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1445 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1446 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1447 /* Vol output for 0x0c-0x0f */
1448 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1449 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1450 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1451 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1452 /* Set output pins 0x14-0x17 */
1453 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1454 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1455 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1456 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1457 /* Unmute output pins 0x14-0x17 */
1458 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1459 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1460 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1461 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1462 /* Set input pins 0x18-0x1c */
1463 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1464 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1465 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1466 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1467 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1468 /* Mute input pins 0x18-0x1b */
1469 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1470 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1471 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1472 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1473 /* ADC set up */
1474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1475 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1476 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1477 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1478 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1479 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1480 /* Analog input/passthru */
1481 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1482 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1483 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1484 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1485 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1486 { }
1487};
1488#endif
1489
1490/*
1491 */
1492
1493static const char * const alc880_models[ALC880_MODEL_LAST] = {
1494 [ALC880_3ST] = "3stack",
1495 [ALC880_TCL_S700] = "tcl",
1496 [ALC880_3ST_DIG] = "3stack-digout",
1497 [ALC880_CLEVO] = "clevo",
1498 [ALC880_5ST] = "5stack",
1499 [ALC880_5ST_DIG] = "5stack-digout",
1500 [ALC880_W810] = "w810",
1501 [ALC880_Z71V] = "z71v",
1502 [ALC880_6ST] = "6stack",
1503 [ALC880_6ST_DIG] = "6stack-digout",
1504 [ALC880_ASUS] = "asus",
1505 [ALC880_ASUS_W1V] = "asus-w1v",
1506 [ALC880_ASUS_DIG] = "asus-dig",
1507 [ALC880_ASUS_DIG2] = "asus-dig2",
1508 [ALC880_UNIWILL_DIG] = "uniwill",
1509 [ALC880_UNIWILL_P53] = "uniwill-p53",
1510 [ALC880_FUJITSU] = "fujitsu",
1511 [ALC880_F1734] = "F1734",
1512 [ALC880_LG] = "lg",
1513 [ALC880_LG_LW] = "lg-lw",
1514 [ALC880_MEDION_RIM] = "medion",
1515#ifdef CONFIG_SND_DEBUG
1516 [ALC880_TEST] = "test",
1517#endif
1518 [ALC880_AUTO] = "auto",
1519};
1520
1521static const struct snd_pci_quirk alc880_cfg_tbl[] = {
1522 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
1523 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
1524 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
1525 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
1526 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
1527 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
1528 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
1529 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
1530 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
1531 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
1532 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
1533 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
1534 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
1535 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
1536 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
1537 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
1538 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
1539 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
1540 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
1541 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
1542 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
1543 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
1544 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
1545 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
1546 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
1547 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
1548 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
1549 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
1550 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
1551 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
1552 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
1553 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
1554 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
1555 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
1556 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
1557 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
1558 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
1559 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
1560 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
1561 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
1562 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
1563 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
1564 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
1565 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
1566 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
1567 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
1568 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1569 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
1570 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
1571 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
1572 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
1573 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
1574 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
1575 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
1576 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
1577 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
1578 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
1579 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
1580 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
1581 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
1582 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
1583 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
1584 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
1585 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
1586 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
1587 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
1588 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
1589 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
1590 /* default Intel */
1591 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
1592 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
1593 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1594 {}
1595};
1596
1597/*
1598 * ALC880 codec presets
1599 */
1600static const struct alc_config_preset alc880_presets[] = {
1601 [ALC880_3ST] = {
1602 .mixers = { alc880_three_stack_mixer },
1603 .init_verbs = { alc880_volume_init_verbs,
1604 alc880_pin_3stack_init_verbs },
1605 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1606 .dac_nids = alc880_dac_nids,
1607 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1608 .channel_mode = alc880_threestack_modes,
1609 .need_dac_fix = 1,
1610 .input_mux = &alc880_capture_source,
1611 },
1612 [ALC880_3ST_DIG] = {
1613 .mixers = { alc880_three_stack_mixer },
1614 .init_verbs = { alc880_volume_init_verbs,
1615 alc880_pin_3stack_init_verbs },
1616 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1617 .dac_nids = alc880_dac_nids,
1618 .dig_out_nid = ALC880_DIGOUT_NID,
1619 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1620 .channel_mode = alc880_threestack_modes,
1621 .need_dac_fix = 1,
1622 .input_mux = &alc880_capture_source,
1623 },
1624 [ALC880_TCL_S700] = {
1625 .mixers = { alc880_tcl_s700_mixer },
1626 .init_verbs = { alc880_volume_init_verbs,
1627 alc880_pin_tcl_S700_init_verbs,
1628 alc880_gpio2_init_verbs },
1629 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1630 .dac_nids = alc880_dac_nids,
1631 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
1632 .num_adc_nids = 1, /* single ADC */
1633 .hp_nid = 0x03,
1634 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1635 .channel_mode = alc880_2_jack_modes,
1636 .input_mux = &alc880_capture_source,
1637 },
1638 [ALC880_5ST] = {
1639 .mixers = { alc880_three_stack_mixer,
1640 alc880_five_stack_mixer},
1641 .init_verbs = { alc880_volume_init_verbs,
1642 alc880_pin_5stack_init_verbs },
1643 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1644 .dac_nids = alc880_dac_nids,
1645 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1646 .channel_mode = alc880_fivestack_modes,
1647 .input_mux = &alc880_capture_source,
1648 },
1649 [ALC880_5ST_DIG] = {
1650 .mixers = { alc880_three_stack_mixer,
1651 alc880_five_stack_mixer },
1652 .init_verbs = { alc880_volume_init_verbs,
1653 alc880_pin_5stack_init_verbs },
1654 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1655 .dac_nids = alc880_dac_nids,
1656 .dig_out_nid = ALC880_DIGOUT_NID,
1657 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1658 .channel_mode = alc880_fivestack_modes,
1659 .input_mux = &alc880_capture_source,
1660 },
1661 [ALC880_6ST] = {
1662 .mixers = { alc880_six_stack_mixer },
1663 .init_verbs = { alc880_volume_init_verbs,
1664 alc880_pin_6stack_init_verbs },
1665 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1666 .dac_nids = alc880_6st_dac_nids,
1667 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1668 .channel_mode = alc880_sixstack_modes,
1669 .input_mux = &alc880_6stack_capture_source,
1670 },
1671 [ALC880_6ST_DIG] = {
1672 .mixers = { alc880_six_stack_mixer },
1673 .init_verbs = { alc880_volume_init_verbs,
1674 alc880_pin_6stack_init_verbs },
1675 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1676 .dac_nids = alc880_6st_dac_nids,
1677 .dig_out_nid = ALC880_DIGOUT_NID,
1678 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1679 .channel_mode = alc880_sixstack_modes,
1680 .input_mux = &alc880_6stack_capture_source,
1681 },
1682 [ALC880_W810] = {
1683 .mixers = { alc880_w810_base_mixer },
1684 .init_verbs = { alc880_volume_init_verbs,
1685 alc880_pin_w810_init_verbs,
1686 alc880_gpio2_init_verbs },
1687 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
1688 .dac_nids = alc880_w810_dac_nids,
1689 .dig_out_nid = ALC880_DIGOUT_NID,
1690 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1691 .channel_mode = alc880_w810_modes,
1692 .input_mux = &alc880_capture_source,
1693 },
1694 [ALC880_Z71V] = {
1695 .mixers = { alc880_z71v_mixer },
1696 .init_verbs = { alc880_volume_init_verbs,
1697 alc880_pin_z71v_init_verbs },
1698 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
1699 .dac_nids = alc880_z71v_dac_nids,
1700 .dig_out_nid = ALC880_DIGOUT_NID,
1701 .hp_nid = 0x03,
1702 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1703 .channel_mode = alc880_2_jack_modes,
1704 .input_mux = &alc880_capture_source,
1705 },
1706 [ALC880_F1734] = {
1707 .mixers = { alc880_f1734_mixer },
1708 .init_verbs = { alc880_volume_init_verbs,
1709 alc880_pin_f1734_init_verbs },
1710 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
1711 .dac_nids = alc880_f1734_dac_nids,
1712 .hp_nid = 0x02,
1713 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1714 .channel_mode = alc880_2_jack_modes,
1715 .input_mux = &alc880_f1734_capture_source,
1716 .unsol_event = alc880_uniwill_p53_unsol_event,
1717 .setup = alc880_uniwill_p53_setup,
1718 .init_hook = alc_hp_automute,
1719 },
1720 [ALC880_ASUS] = {
1721 .mixers = { alc880_asus_mixer },
1722 .init_verbs = { alc880_volume_init_verbs,
1723 alc880_pin_asus_init_verbs,
1724 alc880_gpio1_init_verbs },
1725 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1726 .dac_nids = alc880_asus_dac_nids,
1727 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1728 .channel_mode = alc880_asus_modes,
1729 .need_dac_fix = 1,
1730 .input_mux = &alc880_capture_source,
1731 },
1732 [ALC880_ASUS_DIG] = {
1733 .mixers = { alc880_asus_mixer },
1734 .init_verbs = { alc880_volume_init_verbs,
1735 alc880_pin_asus_init_verbs,
1736 alc880_gpio1_init_verbs },
1737 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1738 .dac_nids = alc880_asus_dac_nids,
1739 .dig_out_nid = ALC880_DIGOUT_NID,
1740 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1741 .channel_mode = alc880_asus_modes,
1742 .need_dac_fix = 1,
1743 .input_mux = &alc880_capture_source,
1744 },
1745 [ALC880_ASUS_DIG2] = {
1746 .mixers = { alc880_asus_mixer },
1747 .init_verbs = { alc880_volume_init_verbs,
1748 alc880_pin_asus_init_verbs,
1749 alc880_gpio2_init_verbs }, /* use GPIO2 */
1750 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1751 .dac_nids = alc880_asus_dac_nids,
1752 .dig_out_nid = ALC880_DIGOUT_NID,
1753 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1754 .channel_mode = alc880_asus_modes,
1755 .need_dac_fix = 1,
1756 .input_mux = &alc880_capture_source,
1757 },
1758 [ALC880_ASUS_W1V] = {
1759 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
1760 .init_verbs = { alc880_volume_init_verbs,
1761 alc880_pin_asus_init_verbs,
1762 alc880_gpio1_init_verbs },
1763 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1764 .dac_nids = alc880_asus_dac_nids,
1765 .dig_out_nid = ALC880_DIGOUT_NID,
1766 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1767 .channel_mode = alc880_asus_modes,
1768 .need_dac_fix = 1,
1769 .input_mux = &alc880_capture_source,
1770 },
1771 [ALC880_UNIWILL_DIG] = {
1772 .mixers = { alc880_asus_mixer },
1773 .init_verbs = { alc880_volume_init_verbs,
1774 alc880_pin_asus_init_verbs },
1775 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1776 .dac_nids = alc880_asus_dac_nids,
1777 .dig_out_nid = ALC880_DIGOUT_NID,
1778 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1779 .channel_mode = alc880_asus_modes,
1780 .need_dac_fix = 1,
1781 .input_mux = &alc880_capture_source,
1782 },
1783 [ALC880_UNIWILL] = {
1784 .mixers = { alc880_uniwill_mixer },
1785 .init_verbs = { alc880_volume_init_verbs,
1786 alc880_uniwill_init_verbs },
1787 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1788 .dac_nids = alc880_asus_dac_nids,
1789 .dig_out_nid = ALC880_DIGOUT_NID,
1790 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1791 .channel_mode = alc880_threestack_modes,
1792 .need_dac_fix = 1,
1793 .input_mux = &alc880_capture_source,
1794 .unsol_event = alc880_uniwill_unsol_event,
1795 .setup = alc880_uniwill_setup,
1796 .init_hook = alc880_uniwill_init_hook,
1797 },
1798 [ALC880_UNIWILL_P53] = {
1799 .mixers = { alc880_uniwill_p53_mixer },
1800 .init_verbs = { alc880_volume_init_verbs,
1801 alc880_uniwill_p53_init_verbs },
1802 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1803 .dac_nids = alc880_asus_dac_nids,
1804 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1805 .channel_mode = alc880_threestack_modes,
1806 .input_mux = &alc880_capture_source,
1807 .unsol_event = alc880_uniwill_p53_unsol_event,
1808 .setup = alc880_uniwill_p53_setup,
1809 .init_hook = alc_hp_automute,
1810 },
1811 [ALC880_FUJITSU] = {
1812 .mixers = { alc880_fujitsu_mixer },
1813 .init_verbs = { alc880_volume_init_verbs,
1814 alc880_uniwill_p53_init_verbs,
1815 alc880_beep_init_verbs },
1816 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1817 .dac_nids = alc880_dac_nids,
1818 .dig_out_nid = ALC880_DIGOUT_NID,
1819 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1820 .channel_mode = alc880_2_jack_modes,
1821 .input_mux = &alc880_capture_source,
1822 .unsol_event = alc880_uniwill_p53_unsol_event,
1823 .setup = alc880_uniwill_p53_setup,
1824 .init_hook = alc_hp_automute,
1825 },
1826 [ALC880_CLEVO] = {
1827 .mixers = { alc880_three_stack_mixer },
1828 .init_verbs = { alc880_volume_init_verbs,
1829 alc880_pin_clevo_init_verbs },
1830 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1831 .dac_nids = alc880_dac_nids,
1832 .hp_nid = 0x03,
1833 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1834 .channel_mode = alc880_threestack_modes,
1835 .need_dac_fix = 1,
1836 .input_mux = &alc880_capture_source,
1837 },
1838 [ALC880_LG] = {
1839 .mixers = { alc880_lg_mixer },
1840 .init_verbs = { alc880_volume_init_verbs,
1841 alc880_lg_init_verbs },
1842 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
1843 .dac_nids = alc880_lg_dac_nids,
1844 .dig_out_nid = ALC880_DIGOUT_NID,
1845 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
1846 .channel_mode = alc880_lg_ch_modes,
1847 .need_dac_fix = 1,
1848 .input_mux = &alc880_lg_capture_source,
1849 .unsol_event = alc_sku_unsol_event,
1850 .setup = alc880_lg_setup,
1851 .init_hook = alc_hp_automute,
1852#ifdef CONFIG_SND_HDA_POWER_SAVE
1853 .loopbacks = alc880_lg_loopbacks,
1854#endif
1855 },
1856 [ALC880_LG_LW] = {
1857 .mixers = { alc880_lg_lw_mixer },
1858 .init_verbs = { alc880_volume_init_verbs,
1859 alc880_lg_lw_init_verbs },
1860 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1861 .dac_nids = alc880_dac_nids,
1862 .dig_out_nid = ALC880_DIGOUT_NID,
1863 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
1864 .channel_mode = alc880_lg_lw_modes,
1865 .input_mux = &alc880_lg_lw_capture_source,
1866 .unsol_event = alc_sku_unsol_event,
1867 .setup = alc880_lg_lw_setup,
1868 .init_hook = alc_hp_automute,
1869 },
1870 [ALC880_MEDION_RIM] = {
1871 .mixers = { alc880_medion_rim_mixer },
1872 .init_verbs = { alc880_volume_init_verbs,
1873 alc880_medion_rim_init_verbs,
1874 alc_gpio2_init_verbs },
1875 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1876 .dac_nids = alc880_dac_nids,
1877 .dig_out_nid = ALC880_DIGOUT_NID,
1878 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1879 .channel_mode = alc880_2_jack_modes,
1880 .input_mux = &alc880_medion_rim_capture_source,
1881 .unsol_event = alc880_medion_rim_unsol_event,
1882 .setup = alc880_medion_rim_setup,
1883 .init_hook = alc880_medion_rim_automute,
1884 },
1885#ifdef CONFIG_SND_DEBUG
1886 [ALC880_TEST] = {
1887 .mixers = { alc880_test_mixer },
1888 .init_verbs = { alc880_test_init_verbs },
1889 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
1890 .dac_nids = alc880_test_dac_nids,
1891 .dig_out_nid = ALC880_DIGOUT_NID,
1892 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
1893 .channel_mode = alc880_test_modes,
1894 .input_mux = &alc880_test_capture_source,
1895 },
1896#endif
1897};
1898
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c
new file mode 100644
index 00000000000..617d04723b8
--- /dev/null
+++ b/sound/pci/hda/alc882_quirks.c
@@ -0,0 +1,3755 @@
1/*
2 * ALC882/ALC883/ALC888/ALC889 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC882 models */
7enum {
8 ALC882_AUTO,
9 ALC882_3ST_DIG,
10 ALC882_6ST_DIG,
11 ALC882_ARIMA,
12 ALC882_W2JC,
13 ALC882_TARGA,
14 ALC882_ASUS_A7J,
15 ALC882_ASUS_A7M,
16 ALC885_MACPRO,
17 ALC885_MBA21,
18 ALC885_MBP3,
19 ALC885_MB5,
20 ALC885_MACMINI3,
21 ALC885_IMAC24,
22 ALC885_IMAC91,
23 ALC883_3ST_2ch_DIG,
24 ALC883_3ST_6ch_DIG,
25 ALC883_3ST_6ch,
26 ALC883_6ST_DIG,
27 ALC883_TARGA_DIG,
28 ALC883_TARGA_2ch_DIG,
29 ALC883_TARGA_8ch_DIG,
30 ALC883_ACER,
31 ALC883_ACER_ASPIRE,
32 ALC888_ACER_ASPIRE_4930G,
33 ALC888_ACER_ASPIRE_6530G,
34 ALC888_ACER_ASPIRE_8930G,
35 ALC888_ACER_ASPIRE_7730G,
36 ALC883_MEDION,
37 ALC883_MEDION_WIM2160,
38 ALC883_LAPTOP_EAPD,
39 ALC883_LENOVO_101E_2ch,
40 ALC883_LENOVO_NB0763,
41 ALC888_LENOVO_MS7195_DIG,
42 ALC888_LENOVO_SKY,
43 ALC883_HAIER_W66,
44 ALC888_3ST_HP,
45 ALC888_6ST_DELL,
46 ALC883_MITAC,
47 ALC883_CLEVO_M540R,
48 ALC883_CLEVO_M720,
49 ALC883_FUJITSU_PI2515,
50 ALC888_FUJITSU_XA3530,
51 ALC883_3ST_6ch_INTEL,
52 ALC889A_INTEL,
53 ALC889_INTEL,
54 ALC888_ASUS_M90V,
55 ALC888_ASUS_EEE1601,
56 ALC889A_MB31,
57 ALC1200_ASUS_P5Q,
58 ALC883_SONY_VAIO_TT,
59 ALC882_MODEL_LAST,
60};
61
62/*
63 * 2ch mode
64 */
65static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
66/* Mic-in jack as mic in */
67 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
68 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
69/* Line-in jack as Line in */
70 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
71 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
72/* Line-Out as Front */
73 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
74 { } /* end */
75};
76
77/*
78 * 4ch mode
79 */
80static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
81/* Mic-in jack as mic in */
82 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
83 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
84/* Line-in jack as Surround */
85 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
86 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87/* Line-Out as Front */
88 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
89 { } /* end */
90};
91
92/*
93 * 6ch mode
94 */
95static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
96/* Mic-in jack as CLFE */
97 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
98 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
99/* Line-in jack as Surround */
100 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
101 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
102/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
103 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
104 { } /* end */
105};
106
107/*
108 * 8ch mode
109 */
110static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
111/* Mic-in jack as CLFE */
112 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
113 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
114/* Line-in jack as Surround */
115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
116 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
117/* Line-Out as Side */
118 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
119 { } /* end */
120};
121
122static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
123 { 2, alc888_4ST_ch2_intel_init },
124 { 4, alc888_4ST_ch4_intel_init },
125 { 6, alc888_4ST_ch6_intel_init },
126 { 8, alc888_4ST_ch8_intel_init },
127};
128
129/*
130 * ALC888 Fujitsu Siemens Amillo xa3530
131 */
132
133static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
134/* Front Mic: set to PIN_IN (empty by default) */
135 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
136/* Connect Internal HP to Front */
137 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
138 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
139 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
140/* Connect Bass HP to Front */
141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
143 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
144/* Connect Line-Out side jack (SPDIF) to Side */
145 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
146 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
147 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
148/* Connect Mic jack to CLFE */
149 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
150 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
151 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
152/* Connect Line-in jack to Surround */
153 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
154 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
155 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
156/* Connect HP out jack to Front */
157 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
158 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
159 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
160/* Enable unsolicited event for HP jack and Line-out jack */
161 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
162 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
163 {}
164};
165
166static void alc889_automute_setup(struct hda_codec *codec)
167{
168 struct alc_spec *spec = codec->spec;
169
170 spec->autocfg.hp_pins[0] = 0x15;
171 spec->autocfg.speaker_pins[0] = 0x14;
172 spec->autocfg.speaker_pins[1] = 0x16;
173 spec->autocfg.speaker_pins[2] = 0x17;
174 spec->autocfg.speaker_pins[3] = 0x19;
175 spec->autocfg.speaker_pins[4] = 0x1a;
176 spec->automute = 1;
177 spec->automute_mode = ALC_AUTOMUTE_AMP;
178}
179
180static void alc889_intel_init_hook(struct hda_codec *codec)
181{
182 alc889_coef_init(codec);
183 alc_hp_automute(codec);
184}
185
186static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
187{
188 struct alc_spec *spec = codec->spec;
189
190 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
191 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
192 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
193 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
194 spec->automute = 1;
195 spec->automute_mode = ALC_AUTOMUTE_AMP;
196}
197
198/*
199 * ALC888 Acer Aspire 4930G model
200 */
201
202static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
203/* Front Mic: set to PIN_IN (empty by default) */
204 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
205/* Unselect Front Mic by default in input mixer 3 */
206 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
207/* Enable unsolicited event for HP jack */
208 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
209/* Connect Internal HP to front */
210 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
211 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
212 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
213/* Connect HP out to front */
214 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
215 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
216 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
217 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
218 { }
219};
220
221/*
222 * ALC888 Acer Aspire 6530G model
223 */
224
225static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
226/* Route to built-in subwoofer as well as speakers */
227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
229 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
230 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
231/* Bias voltage on for external mic port */
232 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
233/* Front Mic: set to PIN_IN (empty by default) */
234 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
235/* Unselect Front Mic by default in input mixer 3 */
236 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
237/* Enable unsolicited event for HP jack */
238 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
239/* Enable speaker output */
240 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
241 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
242 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
243/* Enable headphone output */
244 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
245 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
246 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
247 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
248 { }
249};
250
251/*
252 *ALC888 Acer Aspire 7730G model
253 */
254
255static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
256/* Bias voltage on for external mic port */
257 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
258/* Front Mic: set to PIN_IN (empty by default) */
259 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
260/* Unselect Front Mic by default in input mixer 3 */
261 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
262/* Enable unsolicited event for HP jack */
263 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
264/* Enable speaker output */
265 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
266 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
267 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
268/* Enable headphone output */
269 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
271 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
272 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
273/*Enable internal subwoofer */
274 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
275 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
276 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
277 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
278 { }
279};
280
281/*
282 * ALC889 Acer Aspire 8930G model
283 */
284
285static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
286/* Front Mic: set to PIN_IN (empty by default) */
287 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
288/* Unselect Front Mic by default in input mixer 3 */
289 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
290/* Enable unsolicited event for HP jack */
291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
292/* Connect Internal Front to Front */
293 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
294 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
295 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
296/* Connect Internal Rear to Rear */
297 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
298 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
299 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
300/* Connect Internal CLFE to CLFE */
301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
302 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
303 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
304/* Connect HP out to Front */
305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
306 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
308/* Enable all DACs */
309/* DAC DISABLE/MUTE 1? */
310/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
311 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
312 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
313/* DAC DISABLE/MUTE 2? */
314/* some bit here disables the other DACs. Init=0x4900 */
315 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
316 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
317/* DMIC fix
318 * This laptop has a stereo digital microphone. The mics are only 1cm apart
319 * which makes the stereo useless. However, either the mic or the ALC889
320 * makes the signal become a difference/sum signal instead of standard
321 * stereo, which is annoying. So instead we flip this bit which makes the
322 * codec replicate the sum signal to both channels, turning it into a
323 * normal mono mic.
324 */
325/* DMIC_CONTROL? Init value = 0x0001 */
326 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
327 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
328 { }
329};
330
331static const struct hda_input_mux alc888_2_capture_sources[2] = {
332 /* Front mic only available on one ADC */
333 {
334 .num_items = 4,
335 .items = {
336 { "Mic", 0x0 },
337 { "Line", 0x2 },
338 { "CD", 0x4 },
339 { "Front Mic", 0xb },
340 },
341 },
342 {
343 .num_items = 3,
344 .items = {
345 { "Mic", 0x0 },
346 { "Line", 0x2 },
347 { "CD", 0x4 },
348 },
349 }
350};
351
352static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
353 /* Interal mic only available on one ADC */
354 {
355 .num_items = 5,
356 .items = {
357 { "Mic", 0x0 },
358 { "Line In", 0x2 },
359 { "CD", 0x4 },
360 { "Input Mix", 0xa },
361 { "Internal Mic", 0xb },
362 },
363 },
364 {
365 .num_items = 4,
366 .items = {
367 { "Mic", 0x0 },
368 { "Line In", 0x2 },
369 { "CD", 0x4 },
370 { "Input Mix", 0xa },
371 },
372 }
373};
374
375static const struct hda_input_mux alc889_capture_sources[3] = {
376 /* Digital mic only available on first "ADC" */
377 {
378 .num_items = 5,
379 .items = {
380 { "Mic", 0x0 },
381 { "Line", 0x2 },
382 { "CD", 0x4 },
383 { "Front Mic", 0xb },
384 { "Input Mix", 0xa },
385 },
386 },
387 {
388 .num_items = 4,
389 .items = {
390 { "Mic", 0x0 },
391 { "Line", 0x2 },
392 { "CD", 0x4 },
393 { "Input Mix", 0xa },
394 },
395 },
396 {
397 .num_items = 4,
398 .items = {
399 { "Mic", 0x0 },
400 { "Line", 0x2 },
401 { "CD", 0x4 },
402 { "Input Mix", 0xa },
403 },
404 }
405};
406
407static const struct snd_kcontrol_new alc888_base_mixer[] = {
408 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
409 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
410 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
411 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
412 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
413 HDA_OUTPUT),
414 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
415 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
416 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
417 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
418 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
419 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
420 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
424 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
425 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
426 { } /* end */
427};
428
429static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
432 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
433 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
434 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
435 HDA_OUTPUT),
436 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
437 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
438 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
439 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
440 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
441 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
442 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
443 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
444 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
446 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
448 { } /* end */
449};
450
451static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
452 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
453 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
454 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
455 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
456 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
457 HDA_OUTPUT),
458 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
459 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
460 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
461 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
462 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
466 { } /* end */
467};
468
469
470static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
471{
472 struct alc_spec *spec = codec->spec;
473
474 spec->autocfg.hp_pins[0] = 0x15;
475 spec->autocfg.speaker_pins[0] = 0x14;
476 spec->autocfg.speaker_pins[1] = 0x16;
477 spec->autocfg.speaker_pins[2] = 0x17;
478 spec->automute = 1;
479 spec->automute_mode = ALC_AUTOMUTE_AMP;
480}
481
482static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
483{
484 struct alc_spec *spec = codec->spec;
485
486 spec->autocfg.hp_pins[0] = 0x15;
487 spec->autocfg.speaker_pins[0] = 0x14;
488 spec->autocfg.speaker_pins[1] = 0x16;
489 spec->autocfg.speaker_pins[2] = 0x17;
490 spec->automute = 1;
491 spec->automute_mode = ALC_AUTOMUTE_AMP;
492}
493
494static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
495{
496 struct alc_spec *spec = codec->spec;
497
498 spec->autocfg.hp_pins[0] = 0x15;
499 spec->autocfg.speaker_pins[0] = 0x14;
500 spec->autocfg.speaker_pins[1] = 0x16;
501 spec->autocfg.speaker_pins[2] = 0x17;
502 spec->automute = 1;
503 spec->automute_mode = ALC_AUTOMUTE_AMP;
504}
505
506static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
507{
508 struct alc_spec *spec = codec->spec;
509
510 spec->autocfg.hp_pins[0] = 0x15;
511 spec->autocfg.speaker_pins[0] = 0x14;
512 spec->autocfg.speaker_pins[1] = 0x16;
513 spec->autocfg.speaker_pins[2] = 0x1b;
514 spec->automute = 1;
515 spec->automute_mode = ALC_AUTOMUTE_AMP;
516}
517
518#define ALC882_DIGOUT_NID 0x06
519#define ALC882_DIGIN_NID 0x0a
520#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
521#define ALC883_DIGIN_NID ALC882_DIGIN_NID
522#define ALC1200_DIGOUT_NID 0x10
523
524
525static const struct hda_channel_mode alc882_ch_modes[1] = {
526 { 8, NULL }
527};
528
529/* DACs */
530static const hda_nid_t alc882_dac_nids[4] = {
531 /* front, rear, clfe, rear_surr */
532 0x02, 0x03, 0x04, 0x05
533};
534#define alc883_dac_nids alc882_dac_nids
535
536/* ADCs */
537#define alc882_adc_nids alc880_adc_nids
538#define alc882_adc_nids_alt alc880_adc_nids_alt
539#define alc883_adc_nids alc882_adc_nids_alt
540static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
541static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
542#define alc889_adc_nids alc880_adc_nids
543
544static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
545static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
546#define alc883_capsrc_nids alc882_capsrc_nids_alt
547static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
548#define alc889_capsrc_nids alc882_capsrc_nids
549
550/* input MUX */
551/* FIXME: should be a matrix-type input source selection */
552
553static const struct hda_input_mux alc882_capture_source = {
554 .num_items = 4,
555 .items = {
556 { "Mic", 0x0 },
557 { "Front Mic", 0x1 },
558 { "Line", 0x2 },
559 { "CD", 0x4 },
560 },
561};
562
563#define alc883_capture_source alc882_capture_source
564
565static const struct hda_input_mux alc889_capture_source = {
566 .num_items = 3,
567 .items = {
568 { "Front Mic", 0x0 },
569 { "Mic", 0x3 },
570 { "Line", 0x2 },
571 },
572};
573
574static const struct hda_input_mux mb5_capture_source = {
575 .num_items = 3,
576 .items = {
577 { "Mic", 0x1 },
578 { "Line", 0x7 },
579 { "CD", 0x4 },
580 },
581};
582
583static const struct hda_input_mux macmini3_capture_source = {
584 .num_items = 2,
585 .items = {
586 { "Line", 0x2 },
587 { "CD", 0x4 },
588 },
589};
590
591static const struct hda_input_mux alc883_3stack_6ch_intel = {
592 .num_items = 4,
593 .items = {
594 { "Mic", 0x1 },
595 { "Front Mic", 0x0 },
596 { "Line", 0x2 },
597 { "CD", 0x4 },
598 },
599};
600
601static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
602 .num_items = 2,
603 .items = {
604 { "Mic", 0x1 },
605 { "Line", 0x2 },
606 },
607};
608
609static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
610 .num_items = 4,
611 .items = {
612 { "Mic", 0x0 },
613 { "Internal Mic", 0x1 },
614 { "Line", 0x2 },
615 { "CD", 0x4 },
616 },
617};
618
619static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
620 .num_items = 2,
621 .items = {
622 { "Mic", 0x0 },
623 { "Internal Mic", 0x1 },
624 },
625};
626
627static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
628 .num_items = 3,
629 .items = {
630 { "Mic", 0x0 },
631 { "Front Mic", 0x1 },
632 { "Line", 0x4 },
633 },
634};
635
636static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
637 .num_items = 2,
638 .items = {
639 { "Mic", 0x0 },
640 { "Line", 0x2 },
641 },
642};
643
644static const struct hda_input_mux alc889A_mb31_capture_source = {
645 .num_items = 2,
646 .items = {
647 { "Mic", 0x0 },
648 /* Front Mic (0x01) unused */
649 { "Line", 0x2 },
650 /* Line 2 (0x03) unused */
651 /* CD (0x04) unused? */
652 },
653};
654
655static const struct hda_input_mux alc889A_imac91_capture_source = {
656 .num_items = 2,
657 .items = {
658 { "Mic", 0x01 },
659 { "Line", 0x2 }, /* Not sure! */
660 },
661};
662
663/*
664 * 2ch mode
665 */
666static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
667 { 2, NULL }
668};
669
670/*
671 * 2ch mode
672 */
673static const struct hda_verb alc882_3ST_ch2_init[] = {
674 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
675 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
676 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
677 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
678 { } /* end */
679};
680
681/*
682 * 4ch mode
683 */
684static const struct hda_verb alc882_3ST_ch4_init[] = {
685 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
686 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
687 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
688 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
689 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
690 { } /* end */
691};
692
693/*
694 * 6ch mode
695 */
696static const struct hda_verb alc882_3ST_ch6_init[] = {
697 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
698 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
699 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
700 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
701 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
702 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
703 { } /* end */
704};
705
706static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
707 { 2, alc882_3ST_ch2_init },
708 { 4, alc882_3ST_ch4_init },
709 { 6, alc882_3ST_ch6_init },
710};
711
712#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
713
714/*
715 * 2ch mode
716 */
717static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
718 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
719 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
720 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
721 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
722 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
723 { } /* end */
724};
725
726/*
727 * 4ch mode
728 */
729static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
730 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
731 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
732 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
733 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
734 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
735 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
736 { } /* end */
737};
738
739/*
740 * 6ch mode
741 */
742static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
743 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
744 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
745 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
746 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
747 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
748 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
749 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
750 { } /* end */
751};
752
753static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
754 { 2, alc883_3ST_ch2_clevo_init },
755 { 4, alc883_3ST_ch4_clevo_init },
756 { 6, alc883_3ST_ch6_clevo_init },
757};
758
759
760/*
761 * 6ch mode
762 */
763static const struct hda_verb alc882_sixstack_ch6_init[] = {
764 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
765 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
766 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
767 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
768 { } /* end */
769};
770
771/*
772 * 8ch mode
773 */
774static const struct hda_verb alc882_sixstack_ch8_init[] = {
775 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
776 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
777 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
778 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
779 { } /* end */
780};
781
782static const struct hda_channel_mode alc882_sixstack_modes[2] = {
783 { 6, alc882_sixstack_ch6_init },
784 { 8, alc882_sixstack_ch8_init },
785};
786
787
788/* Macbook Air 2,1 */
789
790static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
791 { 2, NULL },
792};
793
794/*
795 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
796 */
797
798/*
799 * 2ch mode
800 */
801static const struct hda_verb alc885_mbp_ch2_init[] = {
802 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
803 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
804 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
805 { } /* end */
806};
807
808/*
809 * 4ch mode
810 */
811static const struct hda_verb alc885_mbp_ch4_init[] = {
812 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
813 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
814 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
815 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
816 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
817 { } /* end */
818};
819
820static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
821 { 2, alc885_mbp_ch2_init },
822 { 4, alc885_mbp_ch4_init },
823};
824
825/*
826 * 2ch
827 * Speakers/Woofer/HP = Front
828 * LineIn = Input
829 */
830static const struct hda_verb alc885_mb5_ch2_init[] = {
831 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
832 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
833 { } /* end */
834};
835
836/*
837 * 6ch mode
838 * Speakers/HP = Front
839 * Woofer = LFE
840 * LineIn = Surround
841 */
842static const struct hda_verb alc885_mb5_ch6_init[] = {
843 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
844 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
845 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
846 { } /* end */
847};
848
849static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
850 { 2, alc885_mb5_ch2_init },
851 { 6, alc885_mb5_ch6_init },
852};
853
854#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
855
856/*
857 * 2ch mode
858 */
859static const struct hda_verb alc883_4ST_ch2_init[] = {
860 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
861 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
862 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
863 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
864 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
865 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
866 { } /* end */
867};
868
869/*
870 * 4ch mode
871 */
872static const struct hda_verb alc883_4ST_ch4_init[] = {
873 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
874 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
875 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
876 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
877 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
878 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
879 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
880 { } /* end */
881};
882
883/*
884 * 6ch mode
885 */
886static const struct hda_verb alc883_4ST_ch6_init[] = {
887 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
888 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
889 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
890 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
891 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
892 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
893 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
894 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
895 { } /* end */
896};
897
898/*
899 * 8ch mode
900 */
901static const struct hda_verb alc883_4ST_ch8_init[] = {
902 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
903 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
904 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
905 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
906 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
907 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
908 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
909 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
910 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
911 { } /* end */
912};
913
914static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
915 { 2, alc883_4ST_ch2_init },
916 { 4, alc883_4ST_ch4_init },
917 { 6, alc883_4ST_ch6_init },
918 { 8, alc883_4ST_ch8_init },
919};
920
921
922/*
923 * 2ch mode
924 */
925static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
926 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
927 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
928 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
929 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
930 { } /* end */
931};
932
933/*
934 * 4ch mode
935 */
936static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
937 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
938 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
939 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
940 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
941 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
942 { } /* end */
943};
944
945/*
946 * 6ch mode
947 */
948static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
949 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
950 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
951 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
952 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
953 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
954 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
955 { } /* end */
956};
957
958static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
959 { 2, alc883_3ST_ch2_intel_init },
960 { 4, alc883_3ST_ch4_intel_init },
961 { 6, alc883_3ST_ch6_intel_init },
962};
963
964/*
965 * 2ch mode
966 */
967static const struct hda_verb alc889_ch2_intel_init[] = {
968 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
969 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
970 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
971 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
972 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
973 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
974 { } /* end */
975};
976
977/*
978 * 6ch mode
979 */
980static const struct hda_verb alc889_ch6_intel_init[] = {
981 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
982 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
983 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
984 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
985 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
986 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
987 { } /* end */
988};
989
990/*
991 * 8ch mode
992 */
993static const struct hda_verb alc889_ch8_intel_init[] = {
994 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
995 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
996 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
997 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
998 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
999 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1000 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1001 { } /* end */
1002};
1003
1004static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
1005 { 2, alc889_ch2_intel_init },
1006 { 6, alc889_ch6_intel_init },
1007 { 8, alc889_ch8_intel_init },
1008};
1009
1010/*
1011 * 6ch mode
1012 */
1013static const struct hda_verb alc883_sixstack_ch6_init[] = {
1014 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
1015 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1016 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1017 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1018 { } /* end */
1019};
1020
1021/*
1022 * 8ch mode
1023 */
1024static const struct hda_verb alc883_sixstack_ch8_init[] = {
1025 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1026 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1027 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1028 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1029 { } /* end */
1030};
1031
1032static const struct hda_channel_mode alc883_sixstack_modes[2] = {
1033 { 6, alc883_sixstack_ch6_init },
1034 { 8, alc883_sixstack_ch8_init },
1035};
1036
1037
1038/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
1039 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
1040 */
1041static const struct snd_kcontrol_new alc882_base_mixer[] = {
1042 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1043 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1044 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1045 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1046 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1047 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1048 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1049 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1050 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1051 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1052 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1053 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1054 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1055 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1056 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1057 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1058 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1059 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1060 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1061 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1062 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1063 { } /* end */
1064};
1065
1066/* Macbook Air 2,1 same control for HP and internal Speaker */
1067
1068static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
1069 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1070 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
1071 { }
1072};
1073
1074
1075static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
1076 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1077 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
1078 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
1079 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
1080 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
1081 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1082 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
1084 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
1085 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
1086 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
1087 { } /* end */
1088};
1089
1090static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
1091 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1092 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
1093 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
1094 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
1095 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
1096 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
1097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
1098 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
1099 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
1100 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
1101 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1102 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1103 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
1104 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
1105 { } /* end */
1106};
1107
1108static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
1109 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1110 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
1111 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
1112 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
1113 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
1114 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
1115 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
1116 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
1117 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
1118 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
1119 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
1120 { } /* end */
1121};
1122
1123static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
1124 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1125 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
1126 { } /* end */
1127};
1128
1129
1130static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
1131 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1132 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1133 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1134 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1135 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1136 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1138 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1139 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1140 { } /* end */
1141};
1142
1143static const struct snd_kcontrol_new alc882_targa_mixer[] = {
1144 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1145 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1147 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1148 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1149 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1150 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1151 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1152 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1153 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1154 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1155 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1156 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1157 { } /* end */
1158};
1159
1160/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
1161 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
1162 */
1163static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
1164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1165 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1167 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
1168 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1169 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1170 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1171 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1172 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
1173 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
1174 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1175 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1176 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1177 { } /* end */
1178};
1179
1180static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
1181 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1182 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1183 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1184 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1185 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1186 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1187 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1190 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1191 { } /* end */
1192};
1193
1194static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
1195 {
1196 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1197 .name = "Channel Mode",
1198 .info = alc_ch_mode_info,
1199 .get = alc_ch_mode_get,
1200 .put = alc_ch_mode_put,
1201 },
1202 { } /* end */
1203};
1204
1205static const struct hda_verb alc882_base_init_verbs[] = {
1206 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1207 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1208 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1209 /* Rear mixer */
1210 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1211 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1212 /* CLFE mixer */
1213 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1214 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1215 /* Side mixer */
1216 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1217 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1218
1219 /* Front Pin: output 0 (0x0c) */
1220 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1221 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1222 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1223 /* Rear Pin: output 1 (0x0d) */
1224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1226 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
1227 /* CLFE Pin: output 2 (0x0e) */
1228 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1229 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1230 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1231 /* Side Pin: output 3 (0x0f) */
1232 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1233 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1234 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1235 /* Mic (rear) pin: input vref at 80% */
1236 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1237 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1238 /* Front Mic pin: input vref at 80% */
1239 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1240 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1241 /* Line In pin: input */
1242 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1243 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1244 /* Line-2 In: Headphone output (output 0 - 0x0c) */
1245 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1246 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1247 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1248 /* CD pin widget for input */
1249 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1250
1251 /* FIXME: use matrix-type input source selection */
1252 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1253 /* Input mixer2 */
1254 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1255 /* Input mixer3 */
1256 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1257 /* ADC2: mute amp left and right */
1258 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1259 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1260 /* ADC3: mute amp left and right */
1261 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1262 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1263
1264 { }
1265};
1266
1267static const struct hda_verb alc882_adc1_init_verbs[] = {
1268 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1269 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1270 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1271 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1272 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1273 /* ADC1: mute amp left and right */
1274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1275 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1276 { }
1277};
1278
1279static const struct hda_verb alc882_eapd_verbs[] = {
1280 /* change to EAPD mode */
1281 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1282 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1283 { }
1284};
1285
1286static const struct hda_verb alc889_eapd_verbs[] = {
1287 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
1288 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1289 { }
1290};
1291
1292static const struct hda_verb alc_hp15_unsol_verbs[] = {
1293 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1294 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1295 {}
1296};
1297
1298static const struct hda_verb alc885_init_verbs[] = {
1299 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1301 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1302 /* Rear mixer */
1303 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1304 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1305 /* CLFE mixer */
1306 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1307 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1308 /* Side mixer */
1309 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1310 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1311
1312 /* Front HP Pin: output 0 (0x0c) */
1313 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1314 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1315 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1316 /* Front Pin: output 0 (0x0c) */
1317 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1318 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1319 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1320 /* Rear Pin: output 1 (0x0d) */
1321 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1322 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1323 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
1324 /* CLFE Pin: output 2 (0x0e) */
1325 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1326 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1327 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1328 /* Side Pin: output 3 (0x0f) */
1329 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1330 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1331 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1332 /* Mic (rear) pin: input vref at 80% */
1333 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1334 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1335 /* Front Mic pin: input vref at 80% */
1336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1338 /* Line In pin: input */
1339 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1340 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1341
1342 /* Mixer elements: 0x18, , 0x1a, 0x1b */
1343 /* Input mixer1 */
1344 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1345 /* Input mixer2 */
1346 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1347 /* Input mixer3 */
1348 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1349 /* ADC2: mute amp left and right */
1350 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1351 /* ADC3: mute amp left and right */
1352 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1353
1354 { }
1355};
1356
1357static const struct hda_verb alc885_init_input_verbs[] = {
1358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1361 { }
1362};
1363
1364
1365/* Unmute Selector 24h and set the default input to front mic */
1366static const struct hda_verb alc889_init_input_verbs[] = {
1367 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
1368 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1369 { }
1370};
1371
1372
1373#define alc883_init_verbs alc882_base_init_verbs
1374
1375/* Mac Pro test */
1376static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
1377 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1378 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1379 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
1380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
1381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
1382 /* FIXME: this looks suspicious...
1383 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
1384 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
1385 */
1386 { } /* end */
1387};
1388
1389static const struct hda_verb alc882_macpro_init_verbs[] = {
1390 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1394 /* Front Pin: output 0 (0x0c) */
1395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1397 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1398 /* Front Mic pin: input vref at 80% */
1399 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1400 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1401 /* Speaker: output */
1402 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1403 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1404 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
1405 /* Headphone output (output 0 - 0x0c) */
1406 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1407 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1408 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1409
1410 /* FIXME: use matrix-type input source selection */
1411 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1412 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1413 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1414 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1415 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1416 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1417 /* Input mixer2 */
1418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1419 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1420 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1421 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1422 /* Input mixer3 */
1423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1424 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1425 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1426 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1427 /* ADC1: mute amp left and right */
1428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1429 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1430 /* ADC2: mute amp left and right */
1431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1432 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1433 /* ADC3: mute amp left and right */
1434 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1435 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1436
1437 { }
1438};
1439
1440/* Macbook 5,1 */
1441static const struct hda_verb alc885_mb5_init_verbs[] = {
1442 /* DACs */
1443 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1444 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1445 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1446 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1447 /* Front mixer */
1448 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1449 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1450 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1451 /* Surround mixer */
1452 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1453 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1454 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1455 /* LFE mixer */
1456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1457 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1458 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1459 /* HP mixer */
1460 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1461 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1463 /* Front Pin (0x0c) */
1464 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1465 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1466 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1467 /* LFE Pin (0x0e) */
1468 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1469 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1470 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
1471 /* HP Pin (0x0f) */
1472 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1474 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
1475 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1476 /* Front Mic pin: input vref at 80% */
1477 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1478 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1479 /* Line In pin */
1480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1482
1483 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
1484 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
1485 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
1486 { }
1487};
1488
1489/* Macmini 3,1 */
1490static const struct hda_verb alc885_macmini3_init_verbs[] = {
1491 /* DACs */
1492 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1493 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1494 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1496 /* Front mixer */
1497 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1498 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1499 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1500 /* Surround mixer */
1501 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1502 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1503 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1504 /* LFE mixer */
1505 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1506 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1508 /* HP mixer */
1509 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1511 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1512 /* Front Pin (0x0c) */
1513 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1514 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1515 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1516 /* LFE Pin (0x0e) */
1517 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1518 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1519 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
1520 /* HP Pin (0x0f) */
1521 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1523 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
1524 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1525 /* Line In pin */
1526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1528
1529 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1532 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1533 { }
1534};
1535
1536
1537static const struct hda_verb alc885_mba21_init_verbs[] = {
1538 /*Internal and HP Speaker Mixer*/
1539 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1542 /*Internal Speaker Pin (0x0c)*/
1543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
1544 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1545 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1546 /* HP Pin: output 0 (0x0e) */
1547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
1548 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1549 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1550 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
1551 /* Line in (is hp when jack connected)*/
1552 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
1553 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1554
1555 { }
1556 };
1557
1558
1559/* Macbook Pro rev3 */
1560static const struct hda_verb alc885_mbp3_init_verbs[] = {
1561 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1564 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1565 /* Rear mixer */
1566 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1568 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1569 /* HP mixer */
1570 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1571 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1572 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1573 /* Front Pin: output 0 (0x0c) */
1574 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1575 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1576 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1577 /* HP Pin: output 0 (0x0e) */
1578 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
1579 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1580 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
1581 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1582 /* Mic (rear) pin: input vref at 80% */
1583 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1585 /* Front Mic pin: input vref at 80% */
1586 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1587 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1588 /* Line In pin: use output 1 when in LineOut mode */
1589 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1590 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1591 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1592
1593 /* FIXME: use matrix-type input source selection */
1594 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1595 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1596 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1597 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1598 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1599 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1600 /* Input mixer2 */
1601 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1602 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1603 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1604 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1605 /* Input mixer3 */
1606 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1607 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1609 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1610 /* ADC1: mute amp left and right */
1611 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1612 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1613 /* ADC2: mute amp left and right */
1614 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1615 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1616 /* ADC3: mute amp left and right */
1617 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1618 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1619
1620 { }
1621};
1622
1623/* iMac 9,1 */
1624static const struct hda_verb alc885_imac91_init_verbs[] = {
1625 /* Internal Speaker Pin (0x0c) */
1626 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
1627 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1628 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1629 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
1630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1631 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1632 /* HP Pin: Rear */
1633 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1635 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1636 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
1637 /* Line in Rear */
1638 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
1639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1640 /* Front Mic pin: input vref at 80% */
1641 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1642 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1643 /* Rear mixer */
1644 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1645 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1646 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1647 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
1648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1650 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1651 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
1652 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1656 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
1657 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1658 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1659 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1661 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
1662 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1666 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
1667 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1668 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1669 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
1670 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1671 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1672 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
1673 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1674 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1675 { }
1676};
1677
1678/* iMac 24 mixer. */
1679static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
1680 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1681 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
1682 { } /* end */
1683};
1684
1685/* iMac 24 init verbs. */
1686static const struct hda_verb alc885_imac24_init_verbs[] = {
1687 /* Internal speakers: output 0 (0x0c) */
1688 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1689 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1690 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1691 /* Internal speakers: output 0 (0x0c) */
1692 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1693 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1694 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1695 /* Headphone: output 0 (0x0c) */
1696 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1697 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1698 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1699 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1700 /* Front Mic: input vref at 80% */
1701 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1702 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1703 { }
1704};
1705
1706/* Toggle speaker-output according to the hp-jack state */
1707static void alc885_imac24_setup(struct hda_codec *codec)
1708{
1709 struct alc_spec *spec = codec->spec;
1710
1711 spec->autocfg.hp_pins[0] = 0x14;
1712 spec->autocfg.speaker_pins[0] = 0x18;
1713 spec->autocfg.speaker_pins[1] = 0x1a;
1714 spec->automute = 1;
1715 spec->automute_mode = ALC_AUTOMUTE_AMP;
1716}
1717
1718#define alc885_mb5_setup alc885_imac24_setup
1719#define alc885_macmini3_setup alc885_imac24_setup
1720
1721/* Macbook Air 2,1 */
1722static void alc885_mba21_setup(struct hda_codec *codec)
1723{
1724 struct alc_spec *spec = codec->spec;
1725
1726 spec->autocfg.hp_pins[0] = 0x14;
1727 spec->autocfg.speaker_pins[0] = 0x18;
1728 spec->automute = 1;
1729 spec->automute_mode = ALC_AUTOMUTE_AMP;
1730}
1731
1732
1733
1734static void alc885_mbp3_setup(struct hda_codec *codec)
1735{
1736 struct alc_spec *spec = codec->spec;
1737
1738 spec->autocfg.hp_pins[0] = 0x15;
1739 spec->autocfg.speaker_pins[0] = 0x14;
1740 spec->automute = 1;
1741 spec->automute_mode = ALC_AUTOMUTE_AMP;
1742}
1743
1744static void alc885_imac91_setup(struct hda_codec *codec)
1745{
1746 struct alc_spec *spec = codec->spec;
1747
1748 spec->autocfg.hp_pins[0] = 0x14;
1749 spec->autocfg.speaker_pins[0] = 0x18;
1750 spec->autocfg.speaker_pins[1] = 0x1a;
1751 spec->automute = 1;
1752 spec->automute_mode = ALC_AUTOMUTE_AMP;
1753}
1754
1755static const struct hda_verb alc882_targa_verbs[] = {
1756 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1757 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1758
1759 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1760 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1761
1762 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1763 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
1764 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1765
1766 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1767 { } /* end */
1768};
1769
1770/* toggle speaker-output according to the hp-jack state */
1771static void alc882_targa_automute(struct hda_codec *codec)
1772{
1773 struct alc_spec *spec = codec->spec;
1774 alc_hp_automute(codec);
1775 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
1776 spec->jack_present ? 1 : 3);
1777}
1778
1779static void alc882_targa_setup(struct hda_codec *codec)
1780{
1781 struct alc_spec *spec = codec->spec;
1782
1783 spec->autocfg.hp_pins[0] = 0x14;
1784 spec->autocfg.speaker_pins[0] = 0x1b;
1785 spec->automute = 1;
1786 spec->automute_mode = ALC_AUTOMUTE_AMP;
1787}
1788
1789static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
1790{
1791 if ((res >> 26) == ALC_HP_EVENT)
1792 alc882_targa_automute(codec);
1793}
1794
1795static const struct hda_verb alc882_asus_a7j_verbs[] = {
1796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1798
1799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1800 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1801 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1802
1803 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1804 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1805 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1806
1807 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1808 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
1809 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1810 { } /* end */
1811};
1812
1813static const struct hda_verb alc882_asus_a7m_verbs[] = {
1814 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1815 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1816
1817 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1819 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1820
1821 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1822 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1823 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1824
1825 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1826 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
1827 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1828 { } /* end */
1829};
1830
1831static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1832{
1833 unsigned int gpiostate, gpiomask, gpiodir;
1834
1835 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
1836 AC_VERB_GET_GPIO_DATA, 0);
1837
1838 if (!muted)
1839 gpiostate |= (1 << pin);
1840 else
1841 gpiostate &= ~(1 << pin);
1842
1843 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
1844 AC_VERB_GET_GPIO_MASK, 0);
1845 gpiomask |= (1 << pin);
1846
1847 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
1848 AC_VERB_GET_GPIO_DIRECTION, 0);
1849 gpiodir |= (1 << pin);
1850
1851
1852 snd_hda_codec_write(codec, codec->afg, 0,
1853 AC_VERB_SET_GPIO_MASK, gpiomask);
1854 snd_hda_codec_write(codec, codec->afg, 0,
1855 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1856
1857 msleep(1);
1858
1859 snd_hda_codec_write(codec, codec->afg, 0,
1860 AC_VERB_SET_GPIO_DATA, gpiostate);
1861}
1862
1863/* set up GPIO at initialization */
1864static void alc885_macpro_init_hook(struct hda_codec *codec)
1865{
1866 alc882_gpio_mute(codec, 0, 0);
1867 alc882_gpio_mute(codec, 1, 0);
1868}
1869
1870/* set up GPIO and update auto-muting at initialization */
1871static void alc885_imac24_init_hook(struct hda_codec *codec)
1872{
1873 alc885_macpro_init_hook(codec);
1874 alc_hp_automute(codec);
1875}
1876
1877/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
1878static const struct hda_verb alc889A_mb31_ch2_init[] = {
1879 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
1880 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
1881 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
1882 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
1883 { } /* end */
1884};
1885
1886/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
1887static const struct hda_verb alc889A_mb31_ch4_init[] = {
1888 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
1889 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
1890 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
1891 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
1892 { } /* end */
1893};
1894
1895/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
1896static const struct hda_verb alc889A_mb31_ch5_init[] = {
1897 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
1898 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
1899 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
1900 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
1901 { } /* end */
1902};
1903
1904/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
1905static const struct hda_verb alc889A_mb31_ch6_init[] = {
1906 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
1907 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
1908 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
1909 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
1910 { } /* end */
1911};
1912
1913static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
1914 { 2, alc889A_mb31_ch2_init },
1915 { 4, alc889A_mb31_ch4_init },
1916 { 5, alc889A_mb31_ch5_init },
1917 { 6, alc889A_mb31_ch6_init },
1918};
1919
1920static const struct hda_verb alc883_medion_eapd_verbs[] = {
1921 /* eanable EAPD on medion laptop */
1922 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1923 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
1924 { }
1925};
1926
1927#define alc883_base_mixer alc882_base_mixer
1928
1929static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
1930 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1931 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1932 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1933 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1934 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1935 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1936 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1937 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1938 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1939 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1940 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1941 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1942 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1943 { } /* end */
1944};
1945
1946static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
1947 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1948 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1949 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1950 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1951 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1952 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1953 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1954 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1955 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
1956 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1957 { } /* end */
1958};
1959
1960static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
1961 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1962 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1963 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1964 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1965 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1966 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1967 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1968 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1969 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
1970 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1971 { } /* end */
1972};
1973
1974static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
1975 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1976 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1977 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1978 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1979 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1980 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1981 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1982 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1983 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1984 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1985 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1986 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1987 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1988 { } /* end */
1989};
1990
1991static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
1992 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1993 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1994 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1995 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1996 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1997 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1998 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1999 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2004 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2005 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2006 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2008 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2009 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
2010 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2011 { } /* end */
2012};
2013
2014static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
2015 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2016 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2017 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2018 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2019 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2020 HDA_OUTPUT),
2021 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2022 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2023 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2024 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2025 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2026 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2027 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2028 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2029 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2030 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
2031 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2032 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2033 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
2034 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2035 { } /* end */
2036};
2037
2038static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
2039 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2040 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2041 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2042 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2043 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2044 HDA_OUTPUT),
2045 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2046 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2047 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2048 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2049 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
2050 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2051 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2052 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2053 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2054 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
2055 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2056 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2057 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
2058 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2059 { } /* end */
2060};
2061
2062static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
2063 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2064 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2065 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2066 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2067 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2068 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2069 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2070 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2071 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2072 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2073 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2077 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2078 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2079 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2080 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
2081 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2082 { } /* end */
2083};
2084
2085static const struct snd_kcontrol_new alc883_targa_mixer[] = {
2086 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2087 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2088 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2089 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2090 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2091 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2092 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2093 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2094 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2095 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2096 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2097 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2098 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2099 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2101 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2103 { } /* end */
2104};
2105
2106static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
2107 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2108 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2109 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2110 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2111 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2112 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2114 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2116 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2117 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
2118 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2119 { } /* end */
2120};
2121
2122static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
2123 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2124 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2125 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2126 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
2127 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2128 { } /* end */
2129};
2130
2131static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
2132 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2133 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2134 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2135 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2138 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2139 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2140 { } /* end */
2141};
2142
2143static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
2144 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2145 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
2146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2147 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2148 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2151 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2152 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2153 { } /* end */
2154};
2155
2156static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
2157 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2158 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2159 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2160 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
2161 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
2162 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
2163 { } /* end */
2164};
2165
2166static const struct hda_verb alc883_medion_wim2160_verbs[] = {
2167 /* Unmute front mixer */
2168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2169 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2170
2171 /* Set speaker pin to front mixer */
2172 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2173
2174 /* Init headphone pin */
2175 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2177 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
2178 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2179
2180 { } /* end */
2181};
2182
2183/* toggle speaker-output according to the hp-jack state */
2184static void alc883_medion_wim2160_setup(struct hda_codec *codec)
2185{
2186 struct alc_spec *spec = codec->spec;
2187
2188 spec->autocfg.hp_pins[0] = 0x1a;
2189 spec->autocfg.speaker_pins[0] = 0x15;
2190 spec->automute = 1;
2191 spec->automute_mode = ALC_AUTOMUTE_AMP;
2192}
2193
2194static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
2195 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2196 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2197 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2198 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2199 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2201 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2202 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2203 { } /* end */
2204};
2205
2206static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
2207 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2208 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2211 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2212 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2213 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2214 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2216 { } /* end */
2217};
2218
2219static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
2220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2222 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2223 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
2224 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
2225 0x0d, 1, 0x0, HDA_OUTPUT),
2226 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2229 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2230 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2238 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2239 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
2240 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2241 { } /* end */
2242};
2243
2244static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
2245 /* Output mixers */
2246 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
2247 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
2248 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2249 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
2250 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
2251 HDA_OUTPUT),
2252 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
2253 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
2254 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
2255 /* Output switches */
2256 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
2257 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
2258 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
2259 /* Boost mixers */
2260 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
2261 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
2262 /* Input mixers */
2263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
2264 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2265 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2266 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2267 { } /* end */
2268};
2269
2270static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
2271 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2272 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2273 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2274 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2275 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
2276 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2277 { } /* end */
2278};
2279
2280static const struct hda_bind_ctls alc883_bind_cap_vol = {
2281 .ops = &snd_hda_bind_vol,
2282 .values = {
2283 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
2284 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
2285 0
2286 },
2287};
2288
2289static const struct hda_bind_ctls alc883_bind_cap_switch = {
2290 .ops = &snd_hda_bind_sw,
2291 .values = {
2292 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
2293 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
2294 0
2295 },
2296};
2297
2298static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
2299 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2300 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2301 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2305 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2307 { } /* end */
2308};
2309
2310static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
2311 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
2312 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
2313 {
2314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2315 /* .name = "Capture Source", */
2316 .name = "Input Source",
2317 .count = 1,
2318 .info = alc_mux_enum_info,
2319 .get = alc_mux_enum_get,
2320 .put = alc_mux_enum_put,
2321 },
2322 { } /* end */
2323};
2324
2325static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
2326 {
2327 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2328 .name = "Channel Mode",
2329 .info = alc_ch_mode_info,
2330 .get = alc_ch_mode_get,
2331 .put = alc_ch_mode_put,
2332 },
2333 { } /* end */
2334};
2335
2336/* toggle speaker-output according to the hp-jack state */
2337static void alc883_mitac_setup(struct hda_codec *codec)
2338{
2339 struct alc_spec *spec = codec->spec;
2340
2341 spec->autocfg.hp_pins[0] = 0x15;
2342 spec->autocfg.speaker_pins[0] = 0x14;
2343 spec->autocfg.speaker_pins[1] = 0x17;
2344 spec->automute = 1;
2345 spec->automute_mode = ALC_AUTOMUTE_AMP;
2346}
2347
2348static const struct hda_verb alc883_mitac_verbs[] = {
2349 /* HP */
2350 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2352 /* Subwoofer */
2353 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2354 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2355
2356 /* enable unsolicited event */
2357 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2358 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, */
2359
2360 { } /* end */
2361};
2362
2363static const struct hda_verb alc883_clevo_m540r_verbs[] = {
2364 /* HP */
2365 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2367 /* Int speaker */
2368 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
2369
2370 /* enable unsolicited event */
2371 /*
2372 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2373 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
2374 */
2375
2376 { } /* end */
2377};
2378
2379static const struct hda_verb alc883_clevo_m720_verbs[] = {
2380 /* HP */
2381 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2382 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2383 /* Int speaker */
2384 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
2385 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2386
2387 /* enable unsolicited event */
2388 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2389 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
2390
2391 { } /* end */
2392};
2393
2394static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
2395 /* HP */
2396 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2397 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2398 /* Subwoofer */
2399 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
2400 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2401
2402 /* enable unsolicited event */
2403 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2404
2405 { } /* end */
2406};
2407
2408static const struct hda_verb alc883_targa_verbs[] = {
2409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2411
2412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2413 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2414
2415/* Connect Line-Out side jack (SPDIF) to Side */
2416 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2417 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2418 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2419/* Connect Mic jack to CLFE */
2420 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2421 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2422 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2423/* Connect Line-in jack to Surround */
2424 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2426 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2427/* Connect HP out jack to Front */
2428 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2429 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2430 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2431
2432 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2433
2434 { } /* end */
2435};
2436
2437static const struct hda_verb alc883_lenovo_101e_verbs[] = {
2438 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2439 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_FRONT_EVENT|AC_USRSP_EN},
2440 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT|AC_USRSP_EN},
2441 { } /* end */
2442};
2443
2444static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
2445 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2447 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2448 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2449 { } /* end */
2450};
2451
2452static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
2453 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2454 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2456 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_FRONT_EVENT | AC_USRSP_EN},
2457 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2458 { } /* end */
2459};
2460
2461static const struct hda_verb alc883_haier_w66_verbs[] = {
2462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2464
2465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2466
2467 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2468 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2469 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2471 { } /* end */
2472};
2473
2474static const struct hda_verb alc888_lenovo_sky_verbs[] = {
2475 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2477 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2478 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2479 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2480 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2481 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
2482 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2483 { } /* end */
2484};
2485
2486static const struct hda_verb alc888_6st_dell_verbs[] = {
2487 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2488 { }
2489};
2490
2491static const struct hda_verb alc883_vaiott_verbs[] = {
2492 /* HP */
2493 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2495
2496 /* enable unsolicited event */
2497 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2498
2499 { } /* end */
2500};
2501
2502static void alc888_3st_hp_setup(struct hda_codec *codec)
2503{
2504 struct alc_spec *spec = codec->spec;
2505
2506 spec->autocfg.hp_pins[0] = 0x1b;
2507 spec->autocfg.speaker_pins[0] = 0x14;
2508 spec->autocfg.speaker_pins[1] = 0x16;
2509 spec->autocfg.speaker_pins[2] = 0x18;
2510 spec->automute = 1;
2511 spec->automute_mode = ALC_AUTOMUTE_AMP;
2512}
2513
2514static const struct hda_verb alc888_3st_hp_verbs[] = {
2515 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
2516 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
2517 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
2518 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2519 { } /* end */
2520};
2521
2522/*
2523 * 2ch mode
2524 */
2525static const struct hda_verb alc888_3st_hp_2ch_init[] = {
2526 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2527 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2528 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2529 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2530 { } /* end */
2531};
2532
2533/*
2534 * 4ch mode
2535 */
2536static const struct hda_verb alc888_3st_hp_4ch_init[] = {
2537 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2538 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2539 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2540 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2541 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
2542 { } /* end */
2543};
2544
2545/*
2546 * 6ch mode
2547 */
2548static const struct hda_verb alc888_3st_hp_6ch_init[] = {
2549 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2550 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2551 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
2552 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2553 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2554 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
2555 { } /* end */
2556};
2557
2558static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
2559 { 2, alc888_3st_hp_2ch_init },
2560 { 4, alc888_3st_hp_4ch_init },
2561 { 6, alc888_3st_hp_6ch_init },
2562};
2563
2564static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
2565{
2566 struct alc_spec *spec = codec->spec;
2567
2568 spec->autocfg.hp_pins[0] = 0x1b;
2569 spec->autocfg.line_out_pins[0] = 0x14;
2570 spec->autocfg.speaker_pins[0] = 0x15;
2571 spec->automute = 1;
2572 spec->automute_mode = ALC_AUTOMUTE_AMP;
2573}
2574
2575/* toggle speaker-output according to the hp-jack state */
2576static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
2577{
2578 struct alc_spec *spec = codec->spec;
2579
2580 spec->autocfg.hp_pins[0] = 0x14;
2581 spec->autocfg.speaker_pins[0] = 0x15;
2582 spec->automute = 1;
2583 spec->automute_mode = ALC_AUTOMUTE_AMP;
2584}
2585
2586/* toggle speaker-output according to the hp-jack state */
2587#define alc883_targa_init_hook alc882_targa_init_hook
2588#define alc883_targa_unsol_event alc882_targa_unsol_event
2589
2590static void alc883_clevo_m720_setup(struct hda_codec *codec)
2591{
2592 struct alc_spec *spec = codec->spec;
2593
2594 spec->autocfg.hp_pins[0] = 0x15;
2595 spec->autocfg.speaker_pins[0] = 0x14;
2596 spec->automute = 1;
2597 spec->automute_mode = ALC_AUTOMUTE_AMP;
2598}
2599
2600static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
2601{
2602 alc_hp_automute(codec);
2603 alc88x_simple_mic_automute(codec);
2604}
2605
2606static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
2607 unsigned int res)
2608{
2609 switch (res >> 26) {
2610 case ALC_MIC_EVENT:
2611 alc88x_simple_mic_automute(codec);
2612 break;
2613 default:
2614 alc_sku_unsol_event(codec, res);
2615 break;
2616 }
2617}
2618
2619/* toggle speaker-output according to the hp-jack state */
2620static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
2621{
2622 struct alc_spec *spec = codec->spec;
2623
2624 spec->autocfg.hp_pins[0] = 0x14;
2625 spec->autocfg.speaker_pins[0] = 0x15;
2626 spec->automute = 1;
2627 spec->automute_mode = ALC_AUTOMUTE_AMP;
2628}
2629
2630static void alc883_haier_w66_setup(struct hda_codec *codec)
2631{
2632 struct alc_spec *spec = codec->spec;
2633
2634 spec->autocfg.hp_pins[0] = 0x1b;
2635 spec->autocfg.speaker_pins[0] = 0x14;
2636 spec->automute = 1;
2637 spec->automute_mode = ALC_AUTOMUTE_AMP;
2638}
2639
2640static void alc883_lenovo_101e_setup(struct hda_codec *codec)
2641{
2642 struct alc_spec *spec = codec->spec;
2643
2644 spec->autocfg.hp_pins[0] = 0x1b;
2645 spec->autocfg.line_out_pins[0] = 0x14;
2646 spec->autocfg.speaker_pins[0] = 0x15;
2647 spec->automute = 1;
2648 spec->detect_line = 1;
2649 spec->automute_lines = 1;
2650 spec->automute_mode = ALC_AUTOMUTE_AMP;
2651}
2652
2653/* toggle speaker-output according to the hp-jack state */
2654static void alc883_acer_aspire_setup(struct hda_codec *codec)
2655{
2656 struct alc_spec *spec = codec->spec;
2657
2658 spec->autocfg.hp_pins[0] = 0x14;
2659 spec->autocfg.speaker_pins[0] = 0x15;
2660 spec->autocfg.speaker_pins[1] = 0x16;
2661 spec->automute = 1;
2662 spec->automute_mode = ALC_AUTOMUTE_AMP;
2663}
2664
2665static const struct hda_verb alc883_acer_eapd_verbs[] = {
2666 /* HP Pin: output 0 (0x0c) */
2667 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2668 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2669 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2670 /* Front Pin: output 0 (0x0c) */
2671 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2673 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2674 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
2675 /* eanable EAPD on medion laptop */
2676 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2677 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
2678 /* enable unsolicited event */
2679 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2680 { }
2681};
2682
2683static void alc888_6st_dell_setup(struct hda_codec *codec)
2684{
2685 struct alc_spec *spec = codec->spec;
2686
2687 spec->autocfg.hp_pins[0] = 0x1b;
2688 spec->autocfg.speaker_pins[0] = 0x14;
2689 spec->autocfg.speaker_pins[1] = 0x15;
2690 spec->autocfg.speaker_pins[2] = 0x16;
2691 spec->autocfg.speaker_pins[3] = 0x17;
2692 spec->automute = 1;
2693 spec->automute_mode = ALC_AUTOMUTE_AMP;
2694}
2695
2696static void alc888_lenovo_sky_setup(struct hda_codec *codec)
2697{
2698 struct alc_spec *spec = codec->spec;
2699
2700 spec->autocfg.hp_pins[0] = 0x1b;
2701 spec->autocfg.speaker_pins[0] = 0x14;
2702 spec->autocfg.speaker_pins[1] = 0x15;
2703 spec->autocfg.speaker_pins[2] = 0x16;
2704 spec->autocfg.speaker_pins[3] = 0x17;
2705 spec->autocfg.speaker_pins[4] = 0x1a;
2706 spec->automute = 1;
2707 spec->automute_mode = ALC_AUTOMUTE_AMP;
2708}
2709
2710static void alc883_vaiott_setup(struct hda_codec *codec)
2711{
2712 struct alc_spec *spec = codec->spec;
2713
2714 spec->autocfg.hp_pins[0] = 0x15;
2715 spec->autocfg.speaker_pins[0] = 0x14;
2716 spec->autocfg.speaker_pins[1] = 0x17;
2717 spec->automute = 1;
2718 spec->automute_mode = ALC_AUTOMUTE_AMP;
2719}
2720
2721static const struct hda_verb alc888_asus_m90v_verbs[] = {
2722 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2723 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2724 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2725 /* enable unsolicited event */
2726 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2727 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
2728 { } /* end */
2729};
2730
2731static void alc883_mode2_setup(struct hda_codec *codec)
2732{
2733 struct alc_spec *spec = codec->spec;
2734
2735 spec->autocfg.hp_pins[0] = 0x1b;
2736 spec->autocfg.speaker_pins[0] = 0x14;
2737 spec->autocfg.speaker_pins[1] = 0x15;
2738 spec->autocfg.speaker_pins[2] = 0x16;
2739 spec->ext_mic_pin = 0x18;
2740 spec->int_mic_pin = 0x19;
2741 spec->auto_mic = 1;
2742 spec->automute = 1;
2743 spec->automute_mode = ALC_AUTOMUTE_AMP;
2744}
2745
2746static const struct hda_verb alc888_asus_eee1601_verbs[] = {
2747 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2748 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2749 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2750 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2751 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2752 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2753 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
2754 /* enable unsolicited event */
2755 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2756 { } /* end */
2757};
2758
2759static void alc883_eee1601_inithook(struct hda_codec *codec)
2760{
2761 struct alc_spec *spec = codec->spec;
2762
2763 spec->autocfg.hp_pins[0] = 0x14;
2764 spec->autocfg.speaker_pins[0] = 0x1b;
2765 alc_hp_automute(codec);
2766}
2767
2768static const struct hda_verb alc889A_mb31_verbs[] = {
2769 /* Init rear pin (used as headphone output) */
2770 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
2771 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
2772 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2773 /* Init line pin (used as output in 4ch and 6ch mode) */
2774 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
2775 /* Init line 2 pin (used as headphone out by default) */
2776 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
2777 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
2778 { } /* end */
2779};
2780
2781/* Mute speakers according to the headphone jack state */
2782static void alc889A_mb31_automute(struct hda_codec *codec)
2783{
2784 unsigned int present;
2785
2786 /* Mute only in 2ch or 4ch mode */
2787 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
2788 == 0x00) {
2789 present = snd_hda_jack_detect(codec, 0x15);
2790 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2791 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2792 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2793 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2794 }
2795}
2796
2797static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
2798{
2799 if ((res >> 26) == ALC_HP_EVENT)
2800 alc889A_mb31_automute(codec);
2801}
2802
2803static const hda_nid_t alc883_slave_dig_outs[] = {
2804 ALC1200_DIGOUT_NID, 0,
2805};
2806
2807static const hda_nid_t alc1200_slave_dig_outs[] = {
2808 ALC883_DIGOUT_NID, 0,
2809};
2810
2811/*
2812 * configuration and preset
2813 */
2814static const char * const alc882_models[ALC882_MODEL_LAST] = {
2815 [ALC882_3ST_DIG] = "3stack-dig",
2816 [ALC882_6ST_DIG] = "6stack-dig",
2817 [ALC882_ARIMA] = "arima",
2818 [ALC882_W2JC] = "w2jc",
2819 [ALC882_TARGA] = "targa",
2820 [ALC882_ASUS_A7J] = "asus-a7j",
2821 [ALC882_ASUS_A7M] = "asus-a7m",
2822 [ALC885_MACPRO] = "macpro",
2823 [ALC885_MB5] = "mb5",
2824 [ALC885_MACMINI3] = "macmini3",
2825 [ALC885_MBA21] = "mba21",
2826 [ALC885_MBP3] = "mbp3",
2827 [ALC885_IMAC24] = "imac24",
2828 [ALC885_IMAC91] = "imac91",
2829 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
2830 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
2831 [ALC883_3ST_6ch] = "3stack-6ch",
2832 [ALC883_6ST_DIG] = "alc883-6stack-dig",
2833 [ALC883_TARGA_DIG] = "targa-dig",
2834 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
2835 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
2836 [ALC883_ACER] = "acer",
2837 [ALC883_ACER_ASPIRE] = "acer-aspire",
2838 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
2839 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
2840 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
2841 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
2842 [ALC883_MEDION] = "medion",
2843 [ALC883_MEDION_WIM2160] = "medion-wim2160",
2844 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
2845 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
2846 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
2847 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
2848 [ALC888_LENOVO_SKY] = "lenovo-sky",
2849 [ALC883_HAIER_W66] = "haier-w66",
2850 [ALC888_3ST_HP] = "3stack-hp",
2851 [ALC888_6ST_DELL] = "6stack-dell",
2852 [ALC883_MITAC] = "mitac",
2853 [ALC883_CLEVO_M540R] = "clevo-m540r",
2854 [ALC883_CLEVO_M720] = "clevo-m720",
2855 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
2856 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
2857 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
2858 [ALC889A_INTEL] = "intel-alc889a",
2859 [ALC889_INTEL] = "intel-x58",
2860 [ALC1200_ASUS_P5Q] = "asus-p5q",
2861 [ALC889A_MB31] = "mb31",
2862 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
2863 [ALC882_AUTO] = "auto",
2864};
2865
2866static const struct snd_pci_quirk alc882_cfg_tbl[] = {
2867 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
2868
2869 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
2870 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
2871 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
2872 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
2873 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
2874 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
2875 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2876 ALC888_ACER_ASPIRE_4930G),
2877 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2878 ALC888_ACER_ASPIRE_4930G),
2879 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2880 ALC888_ACER_ASPIRE_8930G),
2881 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2882 ALC888_ACER_ASPIRE_8930G),
2883 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
2884 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
2885 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2886 ALC888_ACER_ASPIRE_6530G),
2887 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2888 ALC888_ACER_ASPIRE_6530G),
2889 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2890 ALC888_ACER_ASPIRE_7730G),
2891 /* default Acer -- disabled as it causes more problems.
2892 * model=auto should work fine now
2893 */
2894 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
2895
2896 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
2897
2898 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
2899 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
2900 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
2901 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
2902 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
2903 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
2904
2905 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
2906 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
2907 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
2908 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
2909 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
2910 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
2911 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
2912 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
2913 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
2914 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
2915 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
2916
2917 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
2918 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
2919 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2920 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
2921 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
2922 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
2923 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
2924 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
2925 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
2926
2927 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
2928 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
2929 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
2930 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2931 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
2932 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
2933 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
2934 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
2935 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
2936 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
2937 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
2938 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
2939 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
2940 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
2941 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
2942 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
2943 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
2944 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
2945 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
2946 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
2947 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
2948 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
2949 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
2950 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
2951 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
2952 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
2953 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
2954 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
2955 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
2956 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
2957 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
2958
2959 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
2960 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
2961 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
2962 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
2963 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
2964 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
2965 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
2966 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
2967 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
2968 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
2969 ALC883_FUJITSU_PI2515),
2970 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
2971 ALC888_FUJITSU_XA3530),
2972 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
2973 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
2974 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
2975 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
2976 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
2977 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
2978 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
2979 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
2980
2981 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
2982 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2983 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
2984 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
2985 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
2986 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
2987 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
2988
2989 {}
2990};
2991
2992/* codec SSID table for Intel Mac */
2993static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
2994 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
2995 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
2996 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
2997 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
2998 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
2999 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
3000 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
3001 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
3002 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
3003 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
3004 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
3005 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
3006 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
3007 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
3008 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
3009 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3010 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
3011 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
3012 * so apparently no perfect solution yet
3013 */
3014 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
3015 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
3016 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
3017 {} /* terminator */
3018};
3019
3020static const struct alc_config_preset alc882_presets[] = {
3021 [ALC882_3ST_DIG] = {
3022 .mixers = { alc882_base_mixer },
3023 .init_verbs = { alc882_base_init_verbs,
3024 alc882_adc1_init_verbs },
3025 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3026 .dac_nids = alc882_dac_nids,
3027 .dig_out_nid = ALC882_DIGOUT_NID,
3028 .dig_in_nid = ALC882_DIGIN_NID,
3029 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
3030 .channel_mode = alc882_ch_modes,
3031 .need_dac_fix = 1,
3032 .input_mux = &alc882_capture_source,
3033 },
3034 [ALC882_6ST_DIG] = {
3035 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
3036 .init_verbs = { alc882_base_init_verbs,
3037 alc882_adc1_init_verbs },
3038 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3039 .dac_nids = alc882_dac_nids,
3040 .dig_out_nid = ALC882_DIGOUT_NID,
3041 .dig_in_nid = ALC882_DIGIN_NID,
3042 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
3043 .channel_mode = alc882_sixstack_modes,
3044 .input_mux = &alc882_capture_source,
3045 },
3046 [ALC882_ARIMA] = {
3047 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
3048 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3049 alc882_eapd_verbs },
3050 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3051 .dac_nids = alc882_dac_nids,
3052 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
3053 .channel_mode = alc882_sixstack_modes,
3054 .input_mux = &alc882_capture_source,
3055 },
3056 [ALC882_W2JC] = {
3057 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
3058 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3059 alc882_eapd_verbs, alc880_gpio1_init_verbs },
3060 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3061 .dac_nids = alc882_dac_nids,
3062 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3063 .channel_mode = alc880_threestack_modes,
3064 .need_dac_fix = 1,
3065 .input_mux = &alc882_capture_source,
3066 .dig_out_nid = ALC882_DIGOUT_NID,
3067 },
3068 [ALC885_MBA21] = {
3069 .mixers = { alc885_mba21_mixer },
3070 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
3071 .num_dacs = 2,
3072 .dac_nids = alc882_dac_nids,
3073 .channel_mode = alc885_mba21_ch_modes,
3074 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
3075 .input_mux = &alc882_capture_source,
3076 .unsol_event = alc_sku_unsol_event,
3077 .setup = alc885_mba21_setup,
3078 .init_hook = alc_hp_automute,
3079 },
3080 [ALC885_MBP3] = {
3081 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
3082 .init_verbs = { alc885_mbp3_init_verbs,
3083 alc880_gpio1_init_verbs },
3084 .num_dacs = 2,
3085 .dac_nids = alc882_dac_nids,
3086 .hp_nid = 0x04,
3087 .channel_mode = alc885_mbp_4ch_modes,
3088 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
3089 .input_mux = &alc882_capture_source,
3090 .dig_out_nid = ALC882_DIGOUT_NID,
3091 .dig_in_nid = ALC882_DIGIN_NID,
3092 .unsol_event = alc_sku_unsol_event,
3093 .setup = alc885_mbp3_setup,
3094 .init_hook = alc_hp_automute,
3095 },
3096 [ALC885_MB5] = {
3097 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
3098 .init_verbs = { alc885_mb5_init_verbs,
3099 alc880_gpio1_init_verbs },
3100 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3101 .dac_nids = alc882_dac_nids,
3102 .channel_mode = alc885_mb5_6ch_modes,
3103 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
3104 .input_mux = &mb5_capture_source,
3105 .dig_out_nid = ALC882_DIGOUT_NID,
3106 .dig_in_nid = ALC882_DIGIN_NID,
3107 .unsol_event = alc_sku_unsol_event,
3108 .setup = alc885_mb5_setup,
3109 .init_hook = alc_hp_automute,
3110 },
3111 [ALC885_MACMINI3] = {
3112 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
3113 .init_verbs = { alc885_macmini3_init_verbs,
3114 alc880_gpio1_init_verbs },
3115 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3116 .dac_nids = alc882_dac_nids,
3117 .channel_mode = alc885_macmini3_6ch_modes,
3118 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
3119 .input_mux = &macmini3_capture_source,
3120 .dig_out_nid = ALC882_DIGOUT_NID,
3121 .dig_in_nid = ALC882_DIGIN_NID,
3122 .unsol_event = alc_sku_unsol_event,
3123 .setup = alc885_macmini3_setup,
3124 .init_hook = alc_hp_automute,
3125 },
3126 [ALC885_MACPRO] = {
3127 .mixers = { alc882_macpro_mixer },
3128 .init_verbs = { alc882_macpro_init_verbs },
3129 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3130 .dac_nids = alc882_dac_nids,
3131 .dig_out_nid = ALC882_DIGOUT_NID,
3132 .dig_in_nid = ALC882_DIGIN_NID,
3133 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
3134 .channel_mode = alc882_ch_modes,
3135 .input_mux = &alc882_capture_source,
3136 .init_hook = alc885_macpro_init_hook,
3137 },
3138 [ALC885_IMAC24] = {
3139 .mixers = { alc885_imac24_mixer },
3140 .init_verbs = { alc885_imac24_init_verbs },
3141 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3142 .dac_nids = alc882_dac_nids,
3143 .dig_out_nid = ALC882_DIGOUT_NID,
3144 .dig_in_nid = ALC882_DIGIN_NID,
3145 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
3146 .channel_mode = alc882_ch_modes,
3147 .input_mux = &alc882_capture_source,
3148 .unsol_event = alc_sku_unsol_event,
3149 .setup = alc885_imac24_setup,
3150 .init_hook = alc885_imac24_init_hook,
3151 },
3152 [ALC885_IMAC91] = {
3153 .mixers = {alc885_imac91_mixer},
3154 .init_verbs = { alc885_imac91_init_verbs,
3155 alc880_gpio1_init_verbs },
3156 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3157 .dac_nids = alc882_dac_nids,
3158 .channel_mode = alc885_mba21_ch_modes,
3159 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
3160 .input_mux = &alc889A_imac91_capture_source,
3161 .dig_out_nid = ALC882_DIGOUT_NID,
3162 .dig_in_nid = ALC882_DIGIN_NID,
3163 .unsol_event = alc_sku_unsol_event,
3164 .setup = alc885_imac91_setup,
3165 .init_hook = alc_hp_automute,
3166 },
3167 [ALC882_TARGA] = {
3168 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
3169 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3170 alc880_gpio3_init_verbs, alc882_targa_verbs},
3171 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3172 .dac_nids = alc882_dac_nids,
3173 .dig_out_nid = ALC882_DIGOUT_NID,
3174 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
3175 .adc_nids = alc882_adc_nids,
3176 .capsrc_nids = alc882_capsrc_nids,
3177 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
3178 .channel_mode = alc882_3ST_6ch_modes,
3179 .need_dac_fix = 1,
3180 .input_mux = &alc882_capture_source,
3181 .unsol_event = alc_sku_unsol_event,
3182 .setup = alc882_targa_setup,
3183 .init_hook = alc882_targa_automute,
3184 },
3185 [ALC882_ASUS_A7J] = {
3186 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
3187 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3188 alc882_asus_a7j_verbs},
3189 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3190 .dac_nids = alc882_dac_nids,
3191 .dig_out_nid = ALC882_DIGOUT_NID,
3192 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
3193 .adc_nids = alc882_adc_nids,
3194 .capsrc_nids = alc882_capsrc_nids,
3195 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
3196 .channel_mode = alc882_3ST_6ch_modes,
3197 .need_dac_fix = 1,
3198 .input_mux = &alc882_capture_source,
3199 },
3200 [ALC882_ASUS_A7M] = {
3201 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
3202 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3203 alc882_eapd_verbs, alc880_gpio1_init_verbs,
3204 alc882_asus_a7m_verbs },
3205 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3206 .dac_nids = alc882_dac_nids,
3207 .dig_out_nid = ALC882_DIGOUT_NID,
3208 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3209 .channel_mode = alc880_threestack_modes,
3210 .need_dac_fix = 1,
3211 .input_mux = &alc882_capture_source,
3212 },
3213 [ALC883_3ST_2ch_DIG] = {
3214 .mixers = { alc883_3ST_2ch_mixer },
3215 .init_verbs = { alc883_init_verbs },
3216 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3217 .dac_nids = alc883_dac_nids,
3218 .dig_out_nid = ALC883_DIGOUT_NID,
3219 .dig_in_nid = ALC883_DIGIN_NID,
3220 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3221 .channel_mode = alc883_3ST_2ch_modes,
3222 .input_mux = &alc883_capture_source,
3223 },
3224 [ALC883_3ST_6ch_DIG] = {
3225 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3226 .init_verbs = { alc883_init_verbs },
3227 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3228 .dac_nids = alc883_dac_nids,
3229 .dig_out_nid = ALC883_DIGOUT_NID,
3230 .dig_in_nid = ALC883_DIGIN_NID,
3231 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3232 .channel_mode = alc883_3ST_6ch_modes,
3233 .need_dac_fix = 1,
3234 .input_mux = &alc883_capture_source,
3235 },
3236 [ALC883_3ST_6ch] = {
3237 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3238 .init_verbs = { alc883_init_verbs },
3239 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3240 .dac_nids = alc883_dac_nids,
3241 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3242 .channel_mode = alc883_3ST_6ch_modes,
3243 .need_dac_fix = 1,
3244 .input_mux = &alc883_capture_source,
3245 },
3246 [ALC883_3ST_6ch_INTEL] = {
3247 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
3248 .init_verbs = { alc883_init_verbs },
3249 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3250 .dac_nids = alc883_dac_nids,
3251 .dig_out_nid = ALC883_DIGOUT_NID,
3252 .dig_in_nid = ALC883_DIGIN_NID,
3253 .slave_dig_outs = alc883_slave_dig_outs,
3254 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
3255 .channel_mode = alc883_3ST_6ch_intel_modes,
3256 .need_dac_fix = 1,
3257 .input_mux = &alc883_3stack_6ch_intel,
3258 },
3259 [ALC889A_INTEL] = {
3260 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
3261 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
3262 alc_hp15_unsol_verbs },
3263 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3264 .dac_nids = alc883_dac_nids,
3265 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
3266 .adc_nids = alc889_adc_nids,
3267 .dig_out_nid = ALC883_DIGOUT_NID,
3268 .dig_in_nid = ALC883_DIGIN_NID,
3269 .slave_dig_outs = alc883_slave_dig_outs,
3270 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
3271 .channel_mode = alc889_8ch_intel_modes,
3272 .capsrc_nids = alc889_capsrc_nids,
3273 .input_mux = &alc889_capture_source,
3274 .setup = alc889_automute_setup,
3275 .init_hook = alc_hp_automute,
3276 .unsol_event = alc_sku_unsol_event,
3277 .need_dac_fix = 1,
3278 },
3279 [ALC889_INTEL] = {
3280 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
3281 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
3282 alc889_eapd_verbs, alc_hp15_unsol_verbs},
3283 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3284 .dac_nids = alc883_dac_nids,
3285 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
3286 .adc_nids = alc889_adc_nids,
3287 .dig_out_nid = ALC883_DIGOUT_NID,
3288 .dig_in_nid = ALC883_DIGIN_NID,
3289 .slave_dig_outs = alc883_slave_dig_outs,
3290 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
3291 .channel_mode = alc889_8ch_intel_modes,
3292 .capsrc_nids = alc889_capsrc_nids,
3293 .input_mux = &alc889_capture_source,
3294 .setup = alc889_automute_setup,
3295 .init_hook = alc889_intel_init_hook,
3296 .unsol_event = alc_sku_unsol_event,
3297 .need_dac_fix = 1,
3298 },
3299 [ALC883_6ST_DIG] = {
3300 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
3301 .init_verbs = { alc883_init_verbs },
3302 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3303 .dac_nids = alc883_dac_nids,
3304 .dig_out_nid = ALC883_DIGOUT_NID,
3305 .dig_in_nid = ALC883_DIGIN_NID,
3306 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3307 .channel_mode = alc883_sixstack_modes,
3308 .input_mux = &alc883_capture_source,
3309 },
3310 [ALC883_TARGA_DIG] = {
3311 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
3312 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
3313 alc883_targa_verbs},
3314 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3315 .dac_nids = alc883_dac_nids,
3316 .dig_out_nid = ALC883_DIGOUT_NID,
3317 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3318 .channel_mode = alc883_3ST_6ch_modes,
3319 .need_dac_fix = 1,
3320 .input_mux = &alc883_capture_source,
3321 .unsol_event = alc883_targa_unsol_event,
3322 .setup = alc882_targa_setup,
3323 .init_hook = alc882_targa_automute,
3324 },
3325 [ALC883_TARGA_2ch_DIG] = {
3326 .mixers = { alc883_targa_2ch_mixer},
3327 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
3328 alc883_targa_verbs},
3329 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3330 .dac_nids = alc883_dac_nids,
3331 .adc_nids = alc883_adc_nids_alt,
3332 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
3333 .capsrc_nids = alc883_capsrc_nids,
3334 .dig_out_nid = ALC883_DIGOUT_NID,
3335 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3336 .channel_mode = alc883_3ST_2ch_modes,
3337 .input_mux = &alc883_capture_source,
3338 .unsol_event = alc883_targa_unsol_event,
3339 .setup = alc882_targa_setup,
3340 .init_hook = alc882_targa_automute,
3341 },
3342 [ALC883_TARGA_8ch_DIG] = {
3343 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
3344 alc883_chmode_mixer },
3345 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
3346 alc883_targa_verbs },
3347 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3348 .dac_nids = alc883_dac_nids,
3349 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3350 .adc_nids = alc883_adc_nids_rev,
3351 .capsrc_nids = alc883_capsrc_nids_rev,
3352 .dig_out_nid = ALC883_DIGOUT_NID,
3353 .dig_in_nid = ALC883_DIGIN_NID,
3354 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
3355 .channel_mode = alc883_4ST_8ch_modes,
3356 .need_dac_fix = 1,
3357 .input_mux = &alc883_capture_source,
3358 .unsol_event = alc883_targa_unsol_event,
3359 .setup = alc882_targa_setup,
3360 .init_hook = alc882_targa_automute,
3361 },
3362 [ALC883_ACER] = {
3363 .mixers = { alc883_base_mixer },
3364 /* On TravelMate laptops, GPIO 0 enables the internal speaker
3365 * and the headphone jack. Turn this on and rely on the
3366 * standard mute methods whenever the user wants to turn
3367 * these outputs off.
3368 */
3369 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
3370 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3371 .dac_nids = alc883_dac_nids,
3372 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3373 .channel_mode = alc883_3ST_2ch_modes,
3374 .input_mux = &alc883_capture_source,
3375 },
3376 [ALC883_ACER_ASPIRE] = {
3377 .mixers = { alc883_acer_aspire_mixer },
3378 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
3379 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3380 .dac_nids = alc883_dac_nids,
3381 .dig_out_nid = ALC883_DIGOUT_NID,
3382 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3383 .channel_mode = alc883_3ST_2ch_modes,
3384 .input_mux = &alc883_capture_source,
3385 .unsol_event = alc_sku_unsol_event,
3386 .setup = alc883_acer_aspire_setup,
3387 .init_hook = alc_hp_automute,
3388 },
3389 [ALC888_ACER_ASPIRE_4930G] = {
3390 .mixers = { alc888_acer_aspire_4930g_mixer,
3391 alc883_chmode_mixer },
3392 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3393 alc888_acer_aspire_4930g_verbs },
3394 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3395 .dac_nids = alc883_dac_nids,
3396 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3397 .adc_nids = alc883_adc_nids_rev,
3398 .capsrc_nids = alc883_capsrc_nids_rev,
3399 .dig_out_nid = ALC883_DIGOUT_NID,
3400 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3401 .channel_mode = alc883_3ST_6ch_modes,
3402 .need_dac_fix = 1,
3403 .const_channel_count = 6,
3404 .num_mux_defs =
3405 ARRAY_SIZE(alc888_2_capture_sources),
3406 .input_mux = alc888_2_capture_sources,
3407 .unsol_event = alc_sku_unsol_event,
3408 .setup = alc888_acer_aspire_4930g_setup,
3409 .init_hook = alc_hp_automute,
3410 },
3411 [ALC888_ACER_ASPIRE_6530G] = {
3412 .mixers = { alc888_acer_aspire_6530_mixer },
3413 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3414 alc888_acer_aspire_6530g_verbs },
3415 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3416 .dac_nids = alc883_dac_nids,
3417 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3418 .adc_nids = alc883_adc_nids_rev,
3419 .capsrc_nids = alc883_capsrc_nids_rev,
3420 .dig_out_nid = ALC883_DIGOUT_NID,
3421 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3422 .channel_mode = alc883_3ST_2ch_modes,
3423 .num_mux_defs =
3424 ARRAY_SIZE(alc888_2_capture_sources),
3425 .input_mux = alc888_acer_aspire_6530_sources,
3426 .unsol_event = alc_sku_unsol_event,
3427 .setup = alc888_acer_aspire_6530g_setup,
3428 .init_hook = alc_hp_automute,
3429 },
3430 [ALC888_ACER_ASPIRE_8930G] = {
3431 .mixers = { alc889_acer_aspire_8930g_mixer,
3432 alc883_chmode_mixer },
3433 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3434 alc889_acer_aspire_8930g_verbs,
3435 alc889_eapd_verbs},
3436 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3437 .dac_nids = alc883_dac_nids,
3438 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
3439 .adc_nids = alc889_adc_nids,
3440 .capsrc_nids = alc889_capsrc_nids,
3441 .dig_out_nid = ALC883_DIGOUT_NID,
3442 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3443 .channel_mode = alc883_3ST_6ch_modes,
3444 .need_dac_fix = 1,
3445 .const_channel_count = 6,
3446 .num_mux_defs =
3447 ARRAY_SIZE(alc889_capture_sources),
3448 .input_mux = alc889_capture_sources,
3449 .unsol_event = alc_sku_unsol_event,
3450 .setup = alc889_acer_aspire_8930g_setup,
3451 .init_hook = alc_hp_automute,
3452#ifdef CONFIG_SND_HDA_POWER_SAVE
3453 .power_hook = alc_power_eapd,
3454#endif
3455 },
3456 [ALC888_ACER_ASPIRE_7730G] = {
3457 .mixers = { alc883_3ST_6ch_mixer,
3458 alc883_chmode_mixer },
3459 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3460 alc888_acer_aspire_7730G_verbs },
3461 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3462 .dac_nids = alc883_dac_nids,
3463 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3464 .adc_nids = alc883_adc_nids_rev,
3465 .capsrc_nids = alc883_capsrc_nids_rev,
3466 .dig_out_nid = ALC883_DIGOUT_NID,
3467 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3468 .channel_mode = alc883_3ST_6ch_modes,
3469 .need_dac_fix = 1,
3470 .const_channel_count = 6,
3471 .input_mux = &alc883_capture_source,
3472 .unsol_event = alc_sku_unsol_event,
3473 .setup = alc888_acer_aspire_7730g_setup,
3474 .init_hook = alc_hp_automute,
3475 },
3476 [ALC883_MEDION] = {
3477 .mixers = { alc883_fivestack_mixer,
3478 alc883_chmode_mixer },
3479 .init_verbs = { alc883_init_verbs,
3480 alc883_medion_eapd_verbs },
3481 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3482 .dac_nids = alc883_dac_nids,
3483 .adc_nids = alc883_adc_nids_alt,
3484 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
3485 .capsrc_nids = alc883_capsrc_nids,
3486 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3487 .channel_mode = alc883_sixstack_modes,
3488 .input_mux = &alc883_capture_source,
3489 },
3490 [ALC883_MEDION_WIM2160] = {
3491 .mixers = { alc883_medion_wim2160_mixer },
3492 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
3493 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3494 .dac_nids = alc883_dac_nids,
3495 .dig_out_nid = ALC883_DIGOUT_NID,
3496 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
3497 .adc_nids = alc883_adc_nids,
3498 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3499 .channel_mode = alc883_3ST_2ch_modes,
3500 .input_mux = &alc883_capture_source,
3501 .unsol_event = alc_sku_unsol_event,
3502 .setup = alc883_medion_wim2160_setup,
3503 .init_hook = alc_hp_automute,
3504 },
3505 [ALC883_LAPTOP_EAPD] = {
3506 .mixers = { alc883_base_mixer },
3507 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
3508 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3509 .dac_nids = alc883_dac_nids,
3510 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3511 .channel_mode = alc883_3ST_2ch_modes,
3512 .input_mux = &alc883_capture_source,
3513 },
3514 [ALC883_CLEVO_M540R] = {
3515 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3516 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
3517 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3518 .dac_nids = alc883_dac_nids,
3519 .dig_out_nid = ALC883_DIGOUT_NID,
3520 .dig_in_nid = ALC883_DIGIN_NID,
3521 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
3522 .channel_mode = alc883_3ST_6ch_clevo_modes,
3523 .need_dac_fix = 1,
3524 .input_mux = &alc883_capture_source,
3525 /* This machine has the hardware HP auto-muting, thus
3526 * we need no software mute via unsol event
3527 */
3528 },
3529 [ALC883_CLEVO_M720] = {
3530 .mixers = { alc883_clevo_m720_mixer },
3531 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
3532 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3533 .dac_nids = alc883_dac_nids,
3534 .dig_out_nid = ALC883_DIGOUT_NID,
3535 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3536 .channel_mode = alc883_3ST_2ch_modes,
3537 .input_mux = &alc883_capture_source,
3538 .unsol_event = alc883_clevo_m720_unsol_event,
3539 .setup = alc883_clevo_m720_setup,
3540 .init_hook = alc883_clevo_m720_init_hook,
3541 },
3542 [ALC883_LENOVO_101E_2ch] = {
3543 .mixers = { alc883_lenovo_101e_2ch_mixer},
3544 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
3545 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3546 .dac_nids = alc883_dac_nids,
3547 .adc_nids = alc883_adc_nids_alt,
3548 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
3549 .capsrc_nids = alc883_capsrc_nids,
3550 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3551 .channel_mode = alc883_3ST_2ch_modes,
3552 .input_mux = &alc883_lenovo_101e_capture_source,
3553 .setup = alc883_lenovo_101e_setup,
3554 .unsol_event = alc_sku_unsol_event,
3555 .init_hook = alc_inithook,
3556 },
3557 [ALC883_LENOVO_NB0763] = {
3558 .mixers = { alc883_lenovo_nb0763_mixer },
3559 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
3560 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3561 .dac_nids = alc883_dac_nids,
3562 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3563 .channel_mode = alc883_3ST_2ch_modes,
3564 .need_dac_fix = 1,
3565 .input_mux = &alc883_lenovo_nb0763_capture_source,
3566 .unsol_event = alc_sku_unsol_event,
3567 .setup = alc883_lenovo_nb0763_setup,
3568 .init_hook = alc_hp_automute,
3569 },
3570 [ALC888_LENOVO_MS7195_DIG] = {
3571 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3572 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
3573 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3574 .dac_nids = alc883_dac_nids,
3575 .dig_out_nid = ALC883_DIGOUT_NID,
3576 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3577 .channel_mode = alc883_3ST_6ch_modes,
3578 .need_dac_fix = 1,
3579 .input_mux = &alc883_capture_source,
3580 .unsol_event = alc_sku_unsol_event,
3581 .setup = alc888_lenovo_ms7195_setup,
3582 .init_hook = alc_inithook,
3583 },
3584 [ALC883_HAIER_W66] = {
3585 .mixers = { alc883_targa_2ch_mixer},
3586 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
3587 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3588 .dac_nids = alc883_dac_nids,
3589 .dig_out_nid = ALC883_DIGOUT_NID,
3590 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3591 .channel_mode = alc883_3ST_2ch_modes,
3592 .input_mux = &alc883_capture_source,
3593 .unsol_event = alc_sku_unsol_event,
3594 .setup = alc883_haier_w66_setup,
3595 .init_hook = alc_hp_automute,
3596 },
3597 [ALC888_3ST_HP] = {
3598 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3599 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
3600 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3601 .dac_nids = alc883_dac_nids,
3602 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
3603 .channel_mode = alc888_3st_hp_modes,
3604 .need_dac_fix = 1,
3605 .input_mux = &alc883_capture_source,
3606 .unsol_event = alc_sku_unsol_event,
3607 .setup = alc888_3st_hp_setup,
3608 .init_hook = alc_hp_automute,
3609 },
3610 [ALC888_6ST_DELL] = {
3611 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
3612 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
3613 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3614 .dac_nids = alc883_dac_nids,
3615 .dig_out_nid = ALC883_DIGOUT_NID,
3616 .dig_in_nid = ALC883_DIGIN_NID,
3617 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3618 .channel_mode = alc883_sixstack_modes,
3619 .input_mux = &alc883_capture_source,
3620 .unsol_event = alc_sku_unsol_event,
3621 .setup = alc888_6st_dell_setup,
3622 .init_hook = alc_hp_automute,
3623 },
3624 [ALC883_MITAC] = {
3625 .mixers = { alc883_mitac_mixer },
3626 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
3627 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3628 .dac_nids = alc883_dac_nids,
3629 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3630 .channel_mode = alc883_3ST_2ch_modes,
3631 .input_mux = &alc883_capture_source,
3632 .unsol_event = alc_sku_unsol_event,
3633 .setup = alc883_mitac_setup,
3634 .init_hook = alc_hp_automute,
3635 },
3636 [ALC883_FUJITSU_PI2515] = {
3637 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
3638 .init_verbs = { alc883_init_verbs,
3639 alc883_2ch_fujitsu_pi2515_verbs},
3640 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3641 .dac_nids = alc883_dac_nids,
3642 .dig_out_nid = ALC883_DIGOUT_NID,
3643 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3644 .channel_mode = alc883_3ST_2ch_modes,
3645 .input_mux = &alc883_fujitsu_pi2515_capture_source,
3646 .unsol_event = alc_sku_unsol_event,
3647 .setup = alc883_2ch_fujitsu_pi2515_setup,
3648 .init_hook = alc_hp_automute,
3649 },
3650 [ALC888_FUJITSU_XA3530] = {
3651 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
3652 .init_verbs = { alc883_init_verbs,
3653 alc888_fujitsu_xa3530_verbs },
3654 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3655 .dac_nids = alc883_dac_nids,
3656 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3657 .adc_nids = alc883_adc_nids_rev,
3658 .capsrc_nids = alc883_capsrc_nids_rev,
3659 .dig_out_nid = ALC883_DIGOUT_NID,
3660 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
3661 .channel_mode = alc888_4ST_8ch_intel_modes,
3662 .num_mux_defs =
3663 ARRAY_SIZE(alc888_2_capture_sources),
3664 .input_mux = alc888_2_capture_sources,
3665 .unsol_event = alc_sku_unsol_event,
3666 .setup = alc888_fujitsu_xa3530_setup,
3667 .init_hook = alc_hp_automute,
3668 },
3669 [ALC888_LENOVO_SKY] = {
3670 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
3671 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
3672 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3673 .dac_nids = alc883_dac_nids,
3674 .dig_out_nid = ALC883_DIGOUT_NID,
3675 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3676 .channel_mode = alc883_sixstack_modes,
3677 .need_dac_fix = 1,
3678 .input_mux = &alc883_lenovo_sky_capture_source,
3679 .unsol_event = alc_sku_unsol_event,
3680 .setup = alc888_lenovo_sky_setup,
3681 .init_hook = alc_hp_automute,
3682 },
3683 [ALC888_ASUS_M90V] = {
3684 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3685 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
3686 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3687 .dac_nids = alc883_dac_nids,
3688 .dig_out_nid = ALC883_DIGOUT_NID,
3689 .dig_in_nid = ALC883_DIGIN_NID,
3690 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3691 .channel_mode = alc883_3ST_6ch_modes,
3692 .need_dac_fix = 1,
3693 .input_mux = &alc883_fujitsu_pi2515_capture_source,
3694 .unsol_event = alc_sku_unsol_event,
3695 .setup = alc883_mode2_setup,
3696 .init_hook = alc_inithook,
3697 },
3698 [ALC888_ASUS_EEE1601] = {
3699 .mixers = { alc883_asus_eee1601_mixer },
3700 .cap_mixer = alc883_asus_eee1601_cap_mixer,
3701 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
3702 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3703 .dac_nids = alc883_dac_nids,
3704 .dig_out_nid = ALC883_DIGOUT_NID,
3705 .dig_in_nid = ALC883_DIGIN_NID,
3706 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3707 .channel_mode = alc883_3ST_2ch_modes,
3708 .need_dac_fix = 1,
3709 .input_mux = &alc883_asus_eee1601_capture_source,
3710 .unsol_event = alc_sku_unsol_event,
3711 .init_hook = alc883_eee1601_inithook,
3712 },
3713 [ALC1200_ASUS_P5Q] = {
3714 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
3715 .init_verbs = { alc883_init_verbs },
3716 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3717 .dac_nids = alc883_dac_nids,
3718 .dig_out_nid = ALC1200_DIGOUT_NID,
3719 .dig_in_nid = ALC883_DIGIN_NID,
3720 .slave_dig_outs = alc1200_slave_dig_outs,
3721 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3722 .channel_mode = alc883_sixstack_modes,
3723 .input_mux = &alc883_capture_source,
3724 },
3725 [ALC889A_MB31] = {
3726 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
3727 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
3728 alc880_gpio1_init_verbs },
3729 .adc_nids = alc883_adc_nids,
3730 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
3731 .capsrc_nids = alc883_capsrc_nids,
3732 .dac_nids = alc883_dac_nids,
3733 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3734 .channel_mode = alc889A_mb31_6ch_modes,
3735 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
3736 .input_mux = &alc889A_mb31_capture_source,
3737 .dig_out_nid = ALC883_DIGOUT_NID,
3738 .unsol_event = alc889A_mb31_unsol_event,
3739 .init_hook = alc889A_mb31_automute,
3740 },
3741 [ALC883_SONY_VAIO_TT] = {
3742 .mixers = { alc883_vaiott_mixer },
3743 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
3744 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3745 .dac_nids = alc883_dac_nids,
3746 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3747 .channel_mode = alc883_3ST_2ch_modes,
3748 .input_mux = &alc883_capture_source,
3749 .unsol_event = alc_sku_unsol_event,
3750 .setup = alc883_vaiott_setup,
3751 .init_hook = alc_hp_automute,
3752 },
3753};
3754
3755
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c
new file mode 100644
index 00000000000..2be1129cf45
--- /dev/null
+++ b/sound/pci/hda/alc_quirks.c
@@ -0,0 +1,467 @@
1/*
2 * Common codes for Realtek codec quirks
3 * included by patch_realtek.c
4 */
5
6/*
7 * configuration template - to be copied to the spec instance
8 */
9struct alc_config_preset {
10 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
11 * with spec
12 */
13 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
14 const struct hda_verb *init_verbs[5];
15 unsigned int num_dacs;
16 const hda_nid_t *dac_nids;
17 hda_nid_t dig_out_nid; /* optional */
18 hda_nid_t hp_nid; /* optional */
19 const hda_nid_t *slave_dig_outs;
20 unsigned int num_adc_nids;
21 const hda_nid_t *adc_nids;
22 const hda_nid_t *capsrc_nids;
23 hda_nid_t dig_in_nid;
24 unsigned int num_channel_mode;
25 const struct hda_channel_mode *channel_mode;
26 int need_dac_fix;
27 int const_channel_count;
28 unsigned int num_mux_defs;
29 const struct hda_input_mux *input_mux;
30 void (*unsol_event)(struct hda_codec *, unsigned int);
31 void (*setup)(struct hda_codec *);
32 void (*init_hook)(struct hda_codec *);
33#ifdef CONFIG_SND_HDA_POWER_SAVE
34 const struct hda_amp_list *loopbacks;
35 void (*power_hook)(struct hda_codec *codec);
36#endif
37};
38
39/*
40 * channel mode setting
41 */
42static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
43 struct snd_ctl_elem_info *uinfo)
44{
45 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
46 struct alc_spec *spec = codec->spec;
47 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
48 spec->num_channel_mode);
49}
50
51static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
52 struct snd_ctl_elem_value *ucontrol)
53{
54 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
55 struct alc_spec *spec = codec->spec;
56 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
57 spec->num_channel_mode,
58 spec->ext_channel_count);
59}
60
61static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
62 struct snd_ctl_elem_value *ucontrol)
63{
64 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
65 struct alc_spec *spec = codec->spec;
66 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
67 spec->num_channel_mode,
68 &spec->ext_channel_count);
69 if (err >= 0 && !spec->const_channel_count) {
70 spec->multiout.max_channels = spec->ext_channel_count;
71 if (spec->need_dac_fix)
72 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
73 }
74 return err;
75}
76
77/*
78 * Control the mode of pin widget settings via the mixer. "pc" is used
79 * instead of "%" to avoid consequences of accidentally treating the % as
80 * being part of a format specifier. Maximum allowed length of a value is
81 * 63 characters plus NULL terminator.
82 *
83 * Note: some retasking pin complexes seem to ignore requests for input
84 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
85 * are requested. Therefore order this list so that this behaviour will not
86 * cause problems when mixer clients move through the enum sequentially.
87 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
88 * March 2006.
89 */
90static const char * const alc_pin_mode_names[] = {
91 "Mic 50pc bias", "Mic 80pc bias",
92 "Line in", "Line out", "Headphone out",
93};
94static const unsigned char alc_pin_mode_values[] = {
95 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
96};
97/* The control can present all 5 options, or it can limit the options based
98 * in the pin being assumed to be exclusively an input or an output pin. In
99 * addition, "input" pins may or may not process the mic bias option
100 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
101 * accept requests for bias as of chip versions up to March 2006) and/or
102 * wiring in the computer.
103 */
104#define ALC_PIN_DIR_IN 0x00
105#define ALC_PIN_DIR_OUT 0x01
106#define ALC_PIN_DIR_INOUT 0x02
107#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
108#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
109
110/* Info about the pin modes supported by the different pin direction modes.
111 * For each direction the minimum and maximum values are given.
112 */
113static const signed char alc_pin_mode_dir_info[5][2] = {
114 { 0, 2 }, /* ALC_PIN_DIR_IN */
115 { 3, 4 }, /* ALC_PIN_DIR_OUT */
116 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
117 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
118 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
119};
120#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
121#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
122#define alc_pin_mode_n_items(_dir) \
123 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
124
125static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
126 struct snd_ctl_elem_info *uinfo)
127{
128 unsigned int item_num = uinfo->value.enumerated.item;
129 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
130
131 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
132 uinfo->count = 1;
133 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
134
135 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
136 item_num = alc_pin_mode_min(dir);
137 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
138 return 0;
139}
140
141static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
142 struct snd_ctl_elem_value *ucontrol)
143{
144 unsigned int i;
145 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
146 hda_nid_t nid = kcontrol->private_value & 0xffff;
147 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
148 long *valp = ucontrol->value.integer.value;
149 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
150 AC_VERB_GET_PIN_WIDGET_CONTROL,
151 0x00);
152
153 /* Find enumerated value for current pinctl setting */
154 i = alc_pin_mode_min(dir);
155 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
156 i++;
157 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
158 return 0;
159}
160
161static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
162 struct snd_ctl_elem_value *ucontrol)
163{
164 signed int change;
165 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
166 hda_nid_t nid = kcontrol->private_value & 0xffff;
167 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
168 long val = *ucontrol->value.integer.value;
169 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
170 AC_VERB_GET_PIN_WIDGET_CONTROL,
171 0x00);
172
173 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
174 val = alc_pin_mode_min(dir);
175
176 change = pinctl != alc_pin_mode_values[val];
177 if (change) {
178 /* Set pin mode to that requested */
179 snd_hda_codec_write_cache(codec, nid, 0,
180 AC_VERB_SET_PIN_WIDGET_CONTROL,
181 alc_pin_mode_values[val]);
182
183 /* Also enable the retasking pin's input/output as required
184 * for the requested pin mode. Enum values of 2 or less are
185 * input modes.
186 *
187 * Dynamically switching the input/output buffers probably
188 * reduces noise slightly (particularly on input) so we'll
189 * do it. However, having both input and output buffers
190 * enabled simultaneously doesn't seem to be problematic if
191 * this turns out to be necessary in the future.
192 */
193 if (val <= 2) {
194 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
195 HDA_AMP_MUTE, HDA_AMP_MUTE);
196 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
197 HDA_AMP_MUTE, 0);
198 } else {
199 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
200 HDA_AMP_MUTE, HDA_AMP_MUTE);
201 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
202 HDA_AMP_MUTE, 0);
203 }
204 }
205 return change;
206}
207
208#define ALC_PIN_MODE(xname, nid, dir) \
209 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
210 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
211 .info = alc_pin_mode_info, \
212 .get = alc_pin_mode_get, \
213 .put = alc_pin_mode_put, \
214 .private_value = nid | (dir<<16) }
215
216/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
217 * together using a mask with more than one bit set. This control is
218 * currently used only by the ALC260 test model. At this stage they are not
219 * needed for any "production" models.
220 */
221#ifdef CONFIG_SND_DEBUG
222#define alc_gpio_data_info snd_ctl_boolean_mono_info
223
224static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
225 struct snd_ctl_elem_value *ucontrol)
226{
227 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
228 hda_nid_t nid = kcontrol->private_value & 0xffff;
229 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
230 long *valp = ucontrol->value.integer.value;
231 unsigned int val = snd_hda_codec_read(codec, nid, 0,
232 AC_VERB_GET_GPIO_DATA, 0x00);
233
234 *valp = (val & mask) != 0;
235 return 0;
236}
237static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
238 struct snd_ctl_elem_value *ucontrol)
239{
240 signed int change;
241 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
242 hda_nid_t nid = kcontrol->private_value & 0xffff;
243 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
244 long val = *ucontrol->value.integer.value;
245 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
246 AC_VERB_GET_GPIO_DATA,
247 0x00);
248
249 /* Set/unset the masked GPIO bit(s) as needed */
250 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
251 if (val == 0)
252 gpio_data &= ~mask;
253 else
254 gpio_data |= mask;
255 snd_hda_codec_write_cache(codec, nid, 0,
256 AC_VERB_SET_GPIO_DATA, gpio_data);
257
258 return change;
259}
260#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
261 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
262 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
263 .info = alc_gpio_data_info, \
264 .get = alc_gpio_data_get, \
265 .put = alc_gpio_data_put, \
266 .private_value = nid | (mask<<16) }
267#endif /* CONFIG_SND_DEBUG */
268
269/* A switch control to allow the enabling of the digital IO pins on the
270 * ALC260. This is incredibly simplistic; the intention of this control is
271 * to provide something in the test model allowing digital outputs to be
272 * identified if present. If models are found which can utilise these
273 * outputs a more complete mixer control can be devised for those models if
274 * necessary.
275 */
276#ifdef CONFIG_SND_DEBUG
277#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
278
279static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
280 struct snd_ctl_elem_value *ucontrol)
281{
282 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
283 hda_nid_t nid = kcontrol->private_value & 0xffff;
284 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
285 long *valp = ucontrol->value.integer.value;
286 unsigned int val = snd_hda_codec_read(codec, nid, 0,
287 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
288
289 *valp = (val & mask) != 0;
290 return 0;
291}
292static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
293 struct snd_ctl_elem_value *ucontrol)
294{
295 signed int change;
296 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
297 hda_nid_t nid = kcontrol->private_value & 0xffff;
298 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
299 long val = *ucontrol->value.integer.value;
300 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
301 AC_VERB_GET_DIGI_CONVERT_1,
302 0x00);
303
304 /* Set/unset the masked control bit(s) as needed */
305 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
306 if (val==0)
307 ctrl_data &= ~mask;
308 else
309 ctrl_data |= mask;
310 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
311 ctrl_data);
312
313 return change;
314}
315#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
316 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
317 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
318 .info = alc_spdif_ctrl_info, \
319 .get = alc_spdif_ctrl_get, \
320 .put = alc_spdif_ctrl_put, \
321 .private_value = nid | (mask<<16) }
322#endif /* CONFIG_SND_DEBUG */
323
324/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
325 * Again, this is only used in the ALC26x test models to help identify when
326 * the EAPD line must be asserted for features to work.
327 */
328#ifdef CONFIG_SND_DEBUG
329#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
330
331static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
332 struct snd_ctl_elem_value *ucontrol)
333{
334 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
335 hda_nid_t nid = kcontrol->private_value & 0xffff;
336 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
337 long *valp = ucontrol->value.integer.value;
338 unsigned int val = snd_hda_codec_read(codec, nid, 0,
339 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
340
341 *valp = (val & mask) != 0;
342 return 0;
343}
344
345static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
346 struct snd_ctl_elem_value *ucontrol)
347{
348 int change;
349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
350 hda_nid_t nid = kcontrol->private_value & 0xffff;
351 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
352 long val = *ucontrol->value.integer.value;
353 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
354 AC_VERB_GET_EAPD_BTLENABLE,
355 0x00);
356
357 /* Set/unset the masked control bit(s) as needed */
358 change = (!val ? 0 : mask) != (ctrl_data & mask);
359 if (!val)
360 ctrl_data &= ~mask;
361 else
362 ctrl_data |= mask;
363 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
364 ctrl_data);
365
366 return change;
367}
368
369#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
370 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
371 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
372 .info = alc_eapd_ctrl_info, \
373 .get = alc_eapd_ctrl_get, \
374 .put = alc_eapd_ctrl_put, \
375 .private_value = nid | (mask<<16) }
376#endif /* CONFIG_SND_DEBUG */
377
378static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
379{
380 struct alc_spec *spec = codec->spec;
381 struct auto_pin_cfg *cfg = &spec->autocfg;
382
383 if (!cfg->line_outs) {
384 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
385 cfg->line_out_pins[cfg->line_outs])
386 cfg->line_outs++;
387 }
388 if (!cfg->speaker_outs) {
389 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
390 cfg->speaker_pins[cfg->speaker_outs])
391 cfg->speaker_outs++;
392 }
393 if (!cfg->hp_outs) {
394 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
395 cfg->hp_pins[cfg->hp_outs])
396 cfg->hp_outs++;
397 }
398}
399
400/*
401 * set up from the preset table
402 */
403static void setup_preset(struct hda_codec *codec,
404 const struct alc_config_preset *preset)
405{
406 struct alc_spec *spec = codec->spec;
407 int i;
408
409 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
410 add_mixer(spec, preset->mixers[i]);
411 spec->cap_mixer = preset->cap_mixer;
412 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
413 i++)
414 add_verb(spec, preset->init_verbs[i]);
415
416 spec->channel_mode = preset->channel_mode;
417 spec->num_channel_mode = preset->num_channel_mode;
418 spec->need_dac_fix = preset->need_dac_fix;
419 spec->const_channel_count = preset->const_channel_count;
420
421 if (preset->const_channel_count)
422 spec->multiout.max_channels = preset->const_channel_count;
423 else
424 spec->multiout.max_channels = spec->channel_mode[0].channels;
425 spec->ext_channel_count = spec->channel_mode[0].channels;
426
427 spec->multiout.num_dacs = preset->num_dacs;
428 spec->multiout.dac_nids = preset->dac_nids;
429 spec->multiout.dig_out_nid = preset->dig_out_nid;
430 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
431 spec->multiout.hp_nid = preset->hp_nid;
432
433 spec->num_mux_defs = preset->num_mux_defs;
434 if (!spec->num_mux_defs)
435 spec->num_mux_defs = 1;
436 spec->input_mux = preset->input_mux;
437
438 spec->num_adc_nids = preset->num_adc_nids;
439 spec->adc_nids = preset->adc_nids;
440 spec->capsrc_nids = preset->capsrc_nids;
441 spec->dig_in_nid = preset->dig_in_nid;
442
443 spec->unsol_event = preset->unsol_event;
444 spec->init_hook = preset->init_hook;
445#ifdef CONFIG_SND_HDA_POWER_SAVE
446 spec->power_hook = preset->power_hook;
447 spec->loopback.amplist = preset->loopbacks;
448#endif
449
450 if (preset->setup)
451 preset->setup(codec);
452
453 alc_fixup_autocfg_pin_nums(codec);
454}
455
456
457/* auto-toggle front mic */
458static void alc88x_simple_mic_automute(struct hda_codec *codec)
459{
460 unsigned int present;
461 unsigned char bits;
462
463 present = snd_hda_jack_detect(codec, 0x18);
464 bits = present ? HDA_AMP_MUTE : 0;
465 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
466}
467
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
index f1de1bac042..55f0647458c 100644
--- a/sound/pci/hda/hda_beep.h
+++ b/sound/pci/hda/hda_beep.h
@@ -50,7 +50,12 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable);
50int snd_hda_attach_beep_device(struct hda_codec *codec, int nid); 50int snd_hda_attach_beep_device(struct hda_codec *codec, int nid);
51void snd_hda_detach_beep_device(struct hda_codec *codec); 51void snd_hda_detach_beep_device(struct hda_codec *codec);
52#else 52#else
53#define snd_hda_attach_beep_device(...) 0 53static inline int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
54#define snd_hda_detach_beep_device(...) 54{
55 return 0;
56}
57static inline void snd_hda_detach_beep_device(struct hda_codec *codec)
58{
59}
55#endif 60#endif
56#endif 61#endif
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 45b4a8d70e0..3e7850c238c 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -91,8 +91,10 @@ EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
91#ifdef CONFIG_SND_HDA_POWER_SAVE 91#ifdef CONFIG_SND_HDA_POWER_SAVE
92static void hda_power_work(struct work_struct *work); 92static void hda_power_work(struct work_struct *work);
93static void hda_keep_power_on(struct hda_codec *codec); 93static void hda_keep_power_on(struct hda_codec *codec);
94#define hda_codec_is_power_on(codec) ((codec)->power_on)
94#else 95#else
95static inline void hda_keep_power_on(struct hda_codec *codec) {} 96static inline void hda_keep_power_on(struct hda_codec *codec) {}
97#define hda_codec_is_power_on(codec) 1
96#endif 98#endif
97 99
98/** 100/**
@@ -243,7 +245,8 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
243{ 245{
244 unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm); 246 unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm);
245 unsigned int res; 247 unsigned int res;
246 codec_exec_verb(codec, cmd, &res); 248 if (codec_exec_verb(codec, cmd, &res))
249 return -1;
247 return res; 250 return res;
248} 251}
249EXPORT_SYMBOL_HDA(snd_hda_codec_read); 252EXPORT_SYMBOL_HDA(snd_hda_codec_read);
@@ -307,63 +310,107 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
307} 310}
308EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); 311EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
309 312
310static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 313/* look up the cached results */
311 hda_nid_t *conn_list, int max_conns); 314static hda_nid_t *lookup_conn_list(struct snd_array *array, hda_nid_t nid)
312static bool add_conn_list(struct snd_array *array, hda_nid_t nid); 315{
313static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, 316 int i, len;
314 hda_nid_t *src, int len); 317 for (i = 0; i < array->used; ) {
318 hda_nid_t *p = snd_array_elem(array, i);
319 if (nid == *p)
320 return p;
321 len = p[1];
322 i += len + 2;
323 }
324 return NULL;
325}
315 326
316/** 327/**
317 * snd_hda_get_connections - get connection list 328 * snd_hda_get_conn_list - get connection list
318 * @codec: the HDA codec 329 * @codec: the HDA codec
319 * @nid: NID to parse 330 * @nid: NID to parse
320 * @conn_list: connection list array 331 * @listp: the pointer to store NID list
321 * @max_conns: max. number of connections to store
322 * 332 *
323 * Parses the connection list of the given widget and stores the list 333 * Parses the connection list of the given widget and stores the list
324 * of NIDs. 334 * of NIDs.
325 * 335 *
326 * Returns the number of connections, or a negative error code. 336 * Returns the number of connections, or a negative error code.
327 */ 337 */
328int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 338int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
329 hda_nid_t *conn_list, int max_conns) 339 const hda_nid_t **listp)
330{ 340{
331 struct snd_array *array = &codec->conn_lists; 341 struct snd_array *array = &codec->conn_lists;
332 int i, len, old_used; 342 int len, err;
333 hda_nid_t list[HDA_MAX_CONNECTIONS]; 343 hda_nid_t list[HDA_MAX_CONNECTIONS];
344 hda_nid_t *p;
345 bool added = false;
334 346
335 /* look up the cached results */ 347 again:
336 for (i = 0; i < array->used; ) { 348 /* if the connection-list is already cached, read it */
337 hda_nid_t *p = snd_array_elem(array, i); 349 p = lookup_conn_list(array, nid);
338 len = p[1]; 350 if (p) {
339 if (nid == *p) 351 if (listp)
340 return copy_conn_list(nid, conn_list, max_conns, 352 *listp = p + 2;
341 p + 2, len); 353 return p[1];
342 i += len + 2;
343 } 354 }
355 if (snd_BUG_ON(added))
356 return -EINVAL;
344 357
345 len = _hda_get_connections(codec, nid, list, HDA_MAX_CONNECTIONS); 358 /* read the connection and add to the cache */
359 len = snd_hda_get_raw_connections(codec, nid, list, HDA_MAX_CONNECTIONS);
346 if (len < 0) 360 if (len < 0)
347 return len; 361 return len;
362 err = snd_hda_override_conn_list(codec, nid, len, list);
363 if (err < 0)
364 return err;
365 added = true;
366 goto again;
367}
368EXPORT_SYMBOL_HDA(snd_hda_get_conn_list);
348 369
349 /* add to the cache */ 370/**
350 old_used = array->used; 371 * snd_hda_get_connections - copy connection list
351 if (!add_conn_list(array, nid) || !add_conn_list(array, len)) 372 * @codec: the HDA codec
352 goto error_add; 373 * @nid: NID to parse
353 for (i = 0; i < len; i++) 374 * @conn_list: connection list array
354 if (!add_conn_list(array, list[i])) 375 * @max_conns: max. number of connections to store
355 goto error_add; 376 *
377 * Parses the connection list of the given widget and stores the list
378 * of NIDs.
379 *
380 * Returns the number of connections, or a negative error code.
381 */
382int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
383 hda_nid_t *conn_list, int max_conns)
384{
385 const hda_nid_t *list;
386 int len = snd_hda_get_conn_list(codec, nid, &list);
356 387
357 return copy_conn_list(nid, conn_list, max_conns, list, len); 388 if (len <= 0)
358 389 return len;
359 error_add: 390 if (len > max_conns) {
360 array->used = old_used; 391 snd_printk(KERN_ERR "hda_codec: "
361 return -ENOMEM; 392 "Too many connections %d for NID 0x%x\n",
393 len, nid);
394 return -EINVAL;
395 }
396 memcpy(conn_list, list, len * sizeof(hda_nid_t));
397 return len;
362} 398}
363EXPORT_SYMBOL_HDA(snd_hda_get_connections); 399EXPORT_SYMBOL_HDA(snd_hda_get_connections);
364 400
365static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 401/**
366 hda_nid_t *conn_list, int max_conns) 402 * snd_hda_get_raw_connections - copy connection list without cache
403 * @codec: the HDA codec
404 * @nid: NID to parse
405 * @conn_list: connection list array
406 * @max_conns: max. number of connections to store
407 *
408 * Like snd_hda_get_connections(), copy the connection list but without
409 * checking through the connection-list cache.
410 * Currently called only from hda_proc.c, so not exported.
411 */
412int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
413 hda_nid_t *conn_list, int max_conns)
367{ 414{
368 unsigned int parm; 415 unsigned int parm;
369 int i, conn_len, conns; 416 int i, conn_len, conns;
@@ -376,11 +423,8 @@ static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
376 423
377 wcaps = get_wcaps(codec, nid); 424 wcaps = get_wcaps(codec, nid);
378 if (!(wcaps & AC_WCAP_CONN_LIST) && 425 if (!(wcaps & AC_WCAP_CONN_LIST) &&
379 get_wcaps_type(wcaps) != AC_WID_VOL_KNB) { 426 get_wcaps_type(wcaps) != AC_WID_VOL_KNB)
380 snd_printk(KERN_WARNING "hda_codec: " 427 return 0;
381 "connection list not available for 0x%x\n", nid);
382 return -EINVAL;
383 }
384 428
385 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); 429 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
386 if (parm & AC_CLIST_LONG) { 430 if (parm & AC_CLIST_LONG) {
@@ -470,18 +514,77 @@ static bool add_conn_list(struct snd_array *array, hda_nid_t nid)
470 return true; 514 return true;
471} 515}
472 516
473static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, 517/**
474 hda_nid_t *src, int len) 518 * snd_hda_override_conn_list - add/modify the connection-list to cache
519 * @codec: the HDA codec
520 * @nid: NID to parse
521 * @len: number of connection list entries
522 * @list: the list of connection entries
523 *
524 * Add or modify the given connection-list to the cache. If the corresponding
525 * cache already exists, invalidate it and append a new one.
526 *
527 * Returns zero or a negative error code.
528 */
529int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len,
530 const hda_nid_t *list)
475{ 531{
476 if (len > max_dst) { 532 struct snd_array *array = &codec->conn_lists;
477 snd_printk(KERN_ERR "hda_codec: " 533 hda_nid_t *p;
478 "Too many connections %d for NID 0x%x\n", 534 int i, old_used;
479 len, nid); 535
480 return -EINVAL; 536 p = lookup_conn_list(array, nid);
537 if (p)
538 *p = -1; /* invalidate the old entry */
539
540 old_used = array->used;
541 if (!add_conn_list(array, nid) || !add_conn_list(array, len))
542 goto error_add;
543 for (i = 0; i < len; i++)
544 if (!add_conn_list(array, list[i]))
545 goto error_add;
546 return 0;
547
548 error_add:
549 array->used = old_used;
550 return -ENOMEM;
551}
552EXPORT_SYMBOL_HDA(snd_hda_override_conn_list);
553
554/**
555 * snd_hda_get_conn_index - get the connection index of the given NID
556 * @codec: the HDA codec
557 * @mux: NID containing the list
558 * @nid: NID to select
559 * @recursive: 1 when searching NID recursively, otherwise 0
560 *
561 * Parses the connection list of the widget @mux and checks whether the
562 * widget @nid is present. If it is, return the connection index.
563 * Otherwise it returns -1.
564 */
565int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
566 hda_nid_t nid, int recursive)
567{
568 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
569 int i, nums;
570
571 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
572 for (i = 0; i < nums; i++)
573 if (conn[i] == nid)
574 return i;
575 if (!recursive)
576 return -1;
577 if (recursive > 5) {
578 snd_printd("hda_codec: too deep connection for 0x%x\n", nid);
579 return -1;
481 } 580 }
482 memcpy(dst, src, len * sizeof(hda_nid_t)); 581 recursive++;
483 return len; 582 for (i = 0; i < nums; i++)
583 if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0)
584 return i;
585 return -1;
484} 586}
587EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
485 588
486/** 589/**
487 * snd_hda_queue_unsol_event - add an unsolicited event to queue 590 * snd_hda_queue_unsol_event - add an unsolicited event to queue
@@ -1000,7 +1103,7 @@ void snd_hda_shutup_pins(struct hda_codec *codec)
1000} 1103}
1001EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); 1104EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
1002 1105
1003#ifdef SND_HDA_NEEDS_RESUME 1106#ifdef CONFIG_PM
1004/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ 1107/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */
1005static void restore_shutup_pins(struct hda_codec *codec) 1108static void restore_shutup_pins(struct hda_codec *codec)
1006{ 1109{
@@ -1083,6 +1186,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
1083 snd_array_free(&codec->mixers); 1186 snd_array_free(&codec->mixers);
1084 snd_array_free(&codec->nids); 1187 snd_array_free(&codec->nids);
1085 snd_array_free(&codec->conn_lists); 1188 snd_array_free(&codec->conn_lists);
1189 snd_array_free(&codec->spdif_out);
1086 codec->bus->caddr_tbl[codec->addr] = NULL; 1190 codec->bus->caddr_tbl[codec->addr] = NULL;
1087 if (codec->patch_ops.free) 1191 if (codec->patch_ops.free)
1088 codec->patch_ops.free(codec); 1192 codec->patch_ops.free(codec);
@@ -1144,6 +1248,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
1144 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 1248 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
1145 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); 1249 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
1146 snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); 1250 snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
1251 snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
1147 if (codec->bus->modelname) { 1252 if (codec->bus->modelname) {
1148 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); 1253 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
1149 if (!codec->modelname) { 1254 if (!codec->modelname) {
@@ -1396,7 +1501,7 @@ static void purify_inactive_streams(struct hda_codec *codec)
1396 } 1501 }
1397} 1502}
1398 1503
1399#ifdef SND_HDA_NEEDS_RESUME 1504#ifdef CONFIG_PM
1400/* clean up all streams; called from suspend */ 1505/* clean up all streams; called from suspend */
1401static void hda_cleanup_all_streams(struct hda_codec *codec) 1506static void hda_cleanup_all_streams(struct hda_codec *codec)
1402{ 1507{
@@ -1735,7 +1840,7 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
1735} 1840}
1736EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo); 1841EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo);
1737 1842
1738#ifdef SND_HDA_NEEDS_RESUME 1843#ifdef CONFIG_PM
1739/** 1844/**
1740 * snd_hda_codec_resume_amp - Resume all AMP commands from the cache 1845 * snd_hda_codec_resume_amp - Resume all AMP commands from the cache
1741 * @codec: HD-audio codec 1846 * @codec: HD-audio codec
@@ -1765,7 +1870,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
1765 } 1870 }
1766} 1871}
1767EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); 1872EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
1768#endif /* SND_HDA_NEEDS_RESUME */ 1873#endif /* CONFIG_PM */
1769 1874
1770static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir, 1875static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir,
1771 unsigned int ofs) 1876 unsigned int ofs)
@@ -2555,11 +2660,13 @@ static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
2555 struct snd_ctl_elem_value *ucontrol) 2660 struct snd_ctl_elem_value *ucontrol)
2556{ 2661{
2557 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2662 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2663 int idx = kcontrol->private_value;
2664 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2558 2665
2559 ucontrol->value.iec958.status[0] = codec->spdif_status & 0xff; 2666 ucontrol->value.iec958.status[0] = spdif->status & 0xff;
2560 ucontrol->value.iec958.status[1] = (codec->spdif_status >> 8) & 0xff; 2667 ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff;
2561 ucontrol->value.iec958.status[2] = (codec->spdif_status >> 16) & 0xff; 2668 ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff;
2562 ucontrol->value.iec958.status[3] = (codec->spdif_status >> 24) & 0xff; 2669 ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff;
2563 2670
2564 return 0; 2671 return 0;
2565} 2672}
@@ -2644,23 +2751,23 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
2644 struct snd_ctl_elem_value *ucontrol) 2751 struct snd_ctl_elem_value *ucontrol)
2645{ 2752{
2646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2753 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2647 hda_nid_t nid = kcontrol->private_value; 2754 int idx = kcontrol->private_value;
2755 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2756 hda_nid_t nid = spdif->nid;
2648 unsigned short val; 2757 unsigned short val;
2649 int change; 2758 int change;
2650 2759
2651 mutex_lock(&codec->spdif_mutex); 2760 mutex_lock(&codec->spdif_mutex);
2652 codec->spdif_status = ucontrol->value.iec958.status[0] | 2761 spdif->status = ucontrol->value.iec958.status[0] |
2653 ((unsigned int)ucontrol->value.iec958.status[1] << 8) | 2762 ((unsigned int)ucontrol->value.iec958.status[1] << 8) |
2654 ((unsigned int)ucontrol->value.iec958.status[2] << 16) | 2763 ((unsigned int)ucontrol->value.iec958.status[2] << 16) |
2655 ((unsigned int)ucontrol->value.iec958.status[3] << 24); 2764 ((unsigned int)ucontrol->value.iec958.status[3] << 24);
2656 val = convert_from_spdif_status(codec->spdif_status); 2765 val = convert_from_spdif_status(spdif->status);
2657 val |= codec->spdif_ctls & 1; 2766 val |= spdif->ctls & 1;
2658 change = codec->spdif_ctls != val; 2767 change = spdif->ctls != val;
2659 codec->spdif_ctls = val; 2768 spdif->ctls = val;
2660 2769 if (change && nid != (u16)-1)
2661 if (change)
2662 set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff); 2770 set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
2663
2664 mutex_unlock(&codec->spdif_mutex); 2771 mutex_unlock(&codec->spdif_mutex);
2665 return change; 2772 return change;
2666} 2773}
@@ -2671,33 +2778,42 @@ static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
2671 struct snd_ctl_elem_value *ucontrol) 2778 struct snd_ctl_elem_value *ucontrol)
2672{ 2779{
2673 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2780 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2781 int idx = kcontrol->private_value;
2782 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2674 2783
2675 ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE; 2784 ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE;
2676 return 0; 2785 return 0;
2677} 2786}
2678 2787
2788static inline void set_spdif_ctls(struct hda_codec *codec, hda_nid_t nid,
2789 int dig1, int dig2)
2790{
2791 set_dig_out_convert(codec, nid, dig1, dig2);
2792 /* unmute amp switch (if any) */
2793 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
2794 (dig1 & AC_DIG1_ENABLE))
2795 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2796 HDA_AMP_MUTE, 0);
2797}
2798
2679static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, 2799static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
2680 struct snd_ctl_elem_value *ucontrol) 2800 struct snd_ctl_elem_value *ucontrol)
2681{ 2801{
2682 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2802 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2683 hda_nid_t nid = kcontrol->private_value; 2803 int idx = kcontrol->private_value;
2804 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2805 hda_nid_t nid = spdif->nid;
2684 unsigned short val; 2806 unsigned short val;
2685 int change; 2807 int change;
2686 2808
2687 mutex_lock(&codec->spdif_mutex); 2809 mutex_lock(&codec->spdif_mutex);
2688 val = codec->spdif_ctls & ~AC_DIG1_ENABLE; 2810 val = spdif->ctls & ~AC_DIG1_ENABLE;
2689 if (ucontrol->value.integer.value[0]) 2811 if (ucontrol->value.integer.value[0])
2690 val |= AC_DIG1_ENABLE; 2812 val |= AC_DIG1_ENABLE;
2691 change = codec->spdif_ctls != val; 2813 change = spdif->ctls != val;
2692 if (change) { 2814 spdif->ctls = val;
2693 codec->spdif_ctls = val; 2815 if (change && nid != (u16)-1)
2694 set_dig_out_convert(codec, nid, val & 0xff, -1); 2816 set_spdif_ctls(codec, nid, val & 0xff, -1);
2695 /* unmute amp switch (if any) */
2696 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
2697 (val & AC_DIG1_ENABLE))
2698 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2699 HDA_AMP_MUTE, 0);
2700 }
2701 mutex_unlock(&codec->spdif_mutex); 2817 mutex_unlock(&codec->spdif_mutex);
2702 return change; 2818 return change;
2703} 2819}
@@ -2744,36 +2860,79 @@ static struct snd_kcontrol_new dig_mixes[] = {
2744 * 2860 *
2745 * Returns 0 if successful, or a negative error code. 2861 * Returns 0 if successful, or a negative error code.
2746 */ 2862 */
2747int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) 2863int snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
2864 hda_nid_t associated_nid,
2865 hda_nid_t cvt_nid)
2748{ 2866{
2749 int err; 2867 int err;
2750 struct snd_kcontrol *kctl; 2868 struct snd_kcontrol *kctl;
2751 struct snd_kcontrol_new *dig_mix; 2869 struct snd_kcontrol_new *dig_mix;
2752 int idx; 2870 int idx;
2871 struct hda_spdif_out *spdif;
2753 2872
2754 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch"); 2873 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
2755 if (idx < 0) { 2874 if (idx < 0) {
2756 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); 2875 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
2757 return -EBUSY; 2876 return -EBUSY;
2758 } 2877 }
2878 spdif = snd_array_new(&codec->spdif_out);
2759 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { 2879 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
2760 kctl = snd_ctl_new1(dig_mix, codec); 2880 kctl = snd_ctl_new1(dig_mix, codec);
2761 if (!kctl) 2881 if (!kctl)
2762 return -ENOMEM; 2882 return -ENOMEM;
2763 kctl->id.index = idx; 2883 kctl->id.index = idx;
2764 kctl->private_value = nid; 2884 kctl->private_value = codec->spdif_out.used - 1;
2765 err = snd_hda_ctl_add(codec, nid, kctl); 2885 err = snd_hda_ctl_add(codec, associated_nid, kctl);
2766 if (err < 0) 2886 if (err < 0)
2767 return err; 2887 return err;
2768 } 2888 }
2769 codec->spdif_ctls = 2889 spdif->nid = cvt_nid;
2770 snd_hda_codec_read(codec, nid, 0, 2890 spdif->ctls = snd_hda_codec_read(codec, cvt_nid, 0,
2771 AC_VERB_GET_DIGI_CONVERT_1, 0); 2891 AC_VERB_GET_DIGI_CONVERT_1, 0);
2772 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); 2892 spdif->status = convert_to_spdif_status(spdif->ctls);
2773 return 0; 2893 return 0;
2774} 2894}
2775EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls); 2895EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls);
2776 2896
2897struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
2898 hda_nid_t nid)
2899{
2900 int i;
2901 for (i = 0; i < codec->spdif_out.used; i++) {
2902 struct hda_spdif_out *spdif =
2903 snd_array_elem(&codec->spdif_out, i);
2904 if (spdif->nid == nid)
2905 return spdif;
2906 }
2907 return NULL;
2908}
2909EXPORT_SYMBOL_HDA(snd_hda_spdif_out_of_nid);
2910
2911void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx)
2912{
2913 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2914
2915 mutex_lock(&codec->spdif_mutex);
2916 spdif->nid = (u16)-1;
2917 mutex_unlock(&codec->spdif_mutex);
2918}
2919EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_unassign);
2920
2921void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid)
2922{
2923 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2924 unsigned short val;
2925
2926 mutex_lock(&codec->spdif_mutex);
2927 if (spdif->nid != nid) {
2928 spdif->nid = nid;
2929 val = spdif->ctls;
2930 set_spdif_ctls(codec, nid, val & 0xff, (val >> 8) & 0xff);
2931 }
2932 mutex_unlock(&codec->spdif_mutex);
2933}
2934EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_assign);
2935
2777/* 2936/*
2778 * SPDIF sharing with analog output 2937 * SPDIF sharing with analog output
2779 */ 2938 */
@@ -2925,7 +3084,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
2925} 3084}
2926EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls); 3085EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls);
2927 3086
2928#ifdef SND_HDA_NEEDS_RESUME 3087#ifdef CONFIG_PM
2929/* 3088/*
2930 * command cache 3089 * command cache
2931 */ 3090 */
@@ -3042,53 +3201,32 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec,
3042 seq->param); 3201 seq->param);
3043} 3202}
3044EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache); 3203EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache);
3045#endif /* SND_HDA_NEEDS_RESUME */ 3204#endif /* CONFIG_PM */
3046 3205
3047/* 3206void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
3048 * set power state of the codec 3207 unsigned int power_state,
3049 */ 3208 bool eapd_workaround)
3050static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3051 unsigned int power_state)
3052{ 3209{
3053 hda_nid_t nid; 3210 hda_nid_t nid = codec->start_nid;
3054 int i; 3211 int i;
3055 3212
3056 /* this delay seems necessary to avoid click noise at power-down */
3057 if (power_state == AC_PWRST_D3)
3058 msleep(100);
3059 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
3060 power_state);
3061 /* partial workaround for "azx_get_response timeout" */
3062 if (power_state == AC_PWRST_D0 &&
3063 (codec->vendor_id & 0xffff0000) == 0x14f10000)
3064 msleep(10);
3065
3066 nid = codec->start_nid;
3067 for (i = 0; i < codec->num_nodes; i++, nid++) { 3213 for (i = 0; i < codec->num_nodes; i++, nid++) {
3068 unsigned int wcaps = get_wcaps(codec, nid); 3214 unsigned int wcaps = get_wcaps(codec, nid);
3069 if (wcaps & AC_WCAP_POWER) { 3215 if (!(wcaps & AC_WCAP_POWER))
3070 unsigned int wid_type = get_wcaps_type(wcaps); 3216 continue;
3071 if (power_state == AC_PWRST_D3 && 3217 /* don't power down the widget if it controls eapd and
3072 wid_type == AC_WID_PIN) { 3218 * EAPD_BTLENABLE is set.
3073 unsigned int pincap; 3219 */
3074 /* 3220 if (eapd_workaround && power_state == AC_PWRST_D3 &&
3075 * don't power down the widget if it controls 3221 get_wcaps_type(wcaps) == AC_WID_PIN &&
3076 * eapd and EAPD_BTLENABLE is set. 3222 (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) {
3077 */ 3223 int eapd = snd_hda_codec_read(codec, nid, 0,
3078 pincap = snd_hda_query_pin_caps(codec, nid);
3079 if (pincap & AC_PINCAP_EAPD) {
3080 int eapd = snd_hda_codec_read(codec,
3081 nid, 0,
3082 AC_VERB_GET_EAPD_BTLENABLE, 0); 3224 AC_VERB_GET_EAPD_BTLENABLE, 0);
3083 eapd &= 0x02; 3225 if (eapd & 0x02)
3084 if (eapd) 3226 continue;
3085 continue;
3086 }
3087 }
3088 snd_hda_codec_write(codec, nid, 0,
3089 AC_VERB_SET_POWER_STATE,
3090 power_state);
3091 } 3227 }
3228 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
3229 power_state);
3092 } 3230 }
3093 3231
3094 if (power_state == AC_PWRST_D0) { 3232 if (power_state == AC_PWRST_D0) {
@@ -3105,6 +3243,26 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3105 } while (time_after_eq(end_time, jiffies)); 3243 } while (time_after_eq(end_time, jiffies));
3106 } 3244 }
3107} 3245}
3246EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all);
3247
3248/*
3249 * set power state of the codec
3250 */
3251static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3252 unsigned int power_state)
3253{
3254 if (codec->patch_ops.set_power_state) {
3255 codec->patch_ops.set_power_state(codec, fg, power_state);
3256 return;
3257 }
3258
3259 /* this delay seems necessary to avoid click noise at power-down */
3260 if (power_state == AC_PWRST_D3)
3261 msleep(100);
3262 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
3263 power_state);
3264 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
3265}
3108 3266
3109#ifdef CONFIG_SND_HDA_HWDEP 3267#ifdef CONFIG_SND_HDA_HWDEP
3110/* execute additional init verbs */ 3268/* execute additional init verbs */
@@ -3117,7 +3275,7 @@ static void hda_exec_init_verbs(struct hda_codec *codec)
3117static inline void hda_exec_init_verbs(struct hda_codec *codec) {} 3275static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
3118#endif 3276#endif
3119 3277
3120#ifdef SND_HDA_NEEDS_RESUME 3278#ifdef CONFIG_PM
3121/* 3279/*
3122 * call suspend and power-down; used both from PM and power-save 3280 * call suspend and power-down; used both from PM and power-save
3123 */ 3281 */
@@ -3158,7 +3316,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
3158 snd_hda_codec_resume_cache(codec); 3316 snd_hda_codec_resume_cache(codec);
3159 } 3317 }
3160} 3318}
3161#endif /* SND_HDA_NEEDS_RESUME */ 3319#endif /* CONFIG_PM */
3162 3320
3163 3321
3164/** 3322/**
@@ -3356,7 +3514,7 @@ static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
3356 * 3514 *
3357 * Returns 0 if successful, otherwise a negative error code. 3515 * Returns 0 if successful, otherwise a negative error code.
3358 */ 3516 */
3359static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 3517int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
3360 u32 *ratesp, u64 *formatsp, unsigned int *bpsp) 3518 u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
3361{ 3519{
3362 unsigned int i, val, wcaps; 3520 unsigned int i, val, wcaps;
@@ -3448,6 +3606,7 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
3448 3606
3449 return 0; 3607 return 0;
3450} 3608}
3609EXPORT_SYMBOL_HDA(snd_hda_query_supported_pcm);
3451 3610
3452/** 3611/**
3453 * snd_hda_is_supported_format - Check the validity of the format 3612 * snd_hda_is_supported_format - Check the validity of the format
@@ -3913,9 +4072,6 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
3913EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls); 4072EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
3914 4073
3915#ifdef CONFIG_SND_HDA_POWER_SAVE 4074#ifdef CONFIG_SND_HDA_POWER_SAVE
3916static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3917 unsigned int power_state);
3918
3919static void hda_power_work(struct work_struct *work) 4075static void hda_power_work(struct work_struct *work)
3920{ 4076{
3921 struct hda_codec *codec = 4077 struct hda_codec *codec =
@@ -4177,10 +4333,12 @@ EXPORT_SYMBOL_HDA(snd_hda_input_mux_put);
4177static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, 4333static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
4178 unsigned int stream_tag, unsigned int format) 4334 unsigned int stream_tag, unsigned int format)
4179{ 4335{
4336 struct hda_spdif_out *spdif = snd_hda_spdif_out_of_nid(codec, nid);
4337
4180 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 4338 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
4181 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 4339 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
4182 set_dig_out_convert(codec, nid, 4340 set_dig_out_convert(codec, nid,
4183 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff, 4341 spdif->ctls & ~AC_DIG1_ENABLE & 0xff,
4184 -1); 4342 -1);
4185 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 4343 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
4186 if (codec->slave_dig_outs) { 4344 if (codec->slave_dig_outs) {
@@ -4190,9 +4348,9 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
4190 format); 4348 format);
4191 } 4349 }
4192 /* turn on again (if needed) */ 4350 /* turn on again (if needed) */
4193 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 4351 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
4194 set_dig_out_convert(codec, nid, 4352 set_dig_out_convert(codec, nid,
4195 codec->spdif_ctls & 0xff, -1); 4353 spdif->ctls & 0xff, -1);
4196} 4354}
4197 4355
4198static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid) 4356static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
@@ -4216,11 +4374,8 @@ void snd_hda_bus_reboot_notify(struct hda_bus *bus)
4216 if (!bus) 4374 if (!bus)
4217 return; 4375 return;
4218 list_for_each_entry(codec, &bus->codec_list, list) { 4376 list_for_each_entry(codec, &bus->codec_list, list) {
4219#ifdef CONFIG_SND_HDA_POWER_SAVE 4377 if (hda_codec_is_power_on(codec) &&
4220 if (!codec->power_on) 4378 codec->patch_ops.reboot_notify)
4221 continue;
4222#endif
4223 if (codec->patch_ops.reboot_notify)
4224 codec->patch_ops.reboot_notify(codec); 4379 codec->patch_ops.reboot_notify(codec);
4225 } 4380 }
4226} 4381}
@@ -4348,6 +4503,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
4348{ 4503{
4349 const hda_nid_t *nids = mout->dac_nids; 4504 const hda_nid_t *nids = mout->dac_nids;
4350 int chs = substream->runtime->channels; 4505 int chs = substream->runtime->channels;
4506 struct hda_spdif_out *spdif =
4507 snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid);
4351 int i; 4508 int i;
4352 4509
4353 mutex_lock(&codec->spdif_mutex); 4510 mutex_lock(&codec->spdif_mutex);
@@ -4356,7 +4513,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
4356 if (chs == 2 && 4513 if (chs == 2 &&
4357 snd_hda_is_supported_format(codec, mout->dig_out_nid, 4514 snd_hda_is_supported_format(codec, mout->dig_out_nid,
4358 format) && 4515 format) &&
4359 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { 4516 !(spdif->status & IEC958_AES0_NONAUDIO)) {
4360 mout->dig_out_used = HDA_DIG_ANALOG_DUP; 4517 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
4361 setup_dig_out_stream(codec, mout->dig_out_nid, 4518 setup_dig_out_stream(codec, mout->dig_out_nid,
4362 stream_tag, format); 4519 stream_tag, format);
@@ -4528,7 +4685,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4528 unsigned int wid_caps = get_wcaps(codec, nid); 4685 unsigned int wid_caps = get_wcaps(codec, nid);
4529 unsigned int wid_type = get_wcaps_type(wid_caps); 4686 unsigned int wid_type = get_wcaps_type(wid_caps);
4530 unsigned int def_conf; 4687 unsigned int def_conf;
4531 short assoc, loc; 4688 short assoc, loc, conn, dev;
4532 4689
4533 /* read all default configuration for pin complex */ 4690 /* read all default configuration for pin complex */
4534 if (wid_type != AC_WID_PIN) 4691 if (wid_type != AC_WID_PIN)
@@ -4538,10 +4695,19 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4538 continue; 4695 continue;
4539 4696
4540 def_conf = snd_hda_codec_get_pincfg(codec, nid); 4697 def_conf = snd_hda_codec_get_pincfg(codec, nid);
4541 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) 4698 conn = get_defcfg_connect(def_conf);
4699 if (conn == AC_JACK_PORT_NONE)
4542 continue; 4700 continue;
4543 loc = get_defcfg_location(def_conf); 4701 loc = get_defcfg_location(def_conf);
4544 switch (get_defcfg_device(def_conf)) { 4702 dev = get_defcfg_device(def_conf);
4703
4704 /* workaround for buggy BIOS setups */
4705 if (dev == AC_JACK_LINE_OUT) {
4706 if (conn == AC_JACK_PORT_FIXED)
4707 dev = AC_JACK_SPEAKER;
4708 }
4709
4710 switch (dev) {
4545 case AC_JACK_LINE_OUT: 4711 case AC_JACK_LINE_OUT:
4546 seq = get_defcfg_sequence(def_conf); 4712 seq = get_defcfg_sequence(def_conf);
4547 assoc = get_defcfg_association(def_conf); 4713 assoc = get_defcfg_association(def_conf);
@@ -4908,11 +5074,10 @@ int snd_hda_suspend(struct hda_bus *bus)
4908 struct hda_codec *codec; 5074 struct hda_codec *codec;
4909 5075
4910 list_for_each_entry(codec, &bus->codec_list, list) { 5076 list_for_each_entry(codec, &bus->codec_list, list) {
4911#ifdef CONFIG_SND_HDA_POWER_SAVE 5077 if (hda_codec_is_power_on(codec))
4912 if (!codec->power_on) 5078 hda_call_codec_suspend(codec);
4913 continue; 5079 if (codec->patch_ops.post_suspend)
4914#endif 5080 codec->patch_ops.post_suspend(codec);
4915 hda_call_codec_suspend(codec);
4916 } 5081 }
4917 return 0; 5082 return 0;
4918} 5083}
@@ -4932,6 +5097,8 @@ int snd_hda_resume(struct hda_bus *bus)
4932 struct hda_codec *codec; 5097 struct hda_codec *codec;
4933 5098
4934 list_for_each_entry(codec, &bus->codec_list, list) { 5099 list_for_each_entry(codec, &bus->codec_list, list) {
5100 if (codec->patch_ops.pre_resume)
5101 codec->patch_ops.pre_resume(codec);
4935 if (snd_hda_codec_needs_resume(codec)) 5102 if (snd_hda_codec_needs_resume(codec))
4936 hda_call_codec_resume(codec); 5103 hda_call_codec_resume(codec);
4937 } 5104 }
@@ -4957,17 +5124,15 @@ void *snd_array_new(struct snd_array *array)
4957{ 5124{
4958 if (array->used >= array->alloced) { 5125 if (array->used >= array->alloced) {
4959 int num = array->alloced + array->alloc_align; 5126 int num = array->alloced + array->alloc_align;
5127 int size = (num + 1) * array->elem_size;
5128 int oldsize = array->alloced * array->elem_size;
4960 void *nlist; 5129 void *nlist;
4961 if (snd_BUG_ON(num >= 4096)) 5130 if (snd_BUG_ON(num >= 4096))
4962 return NULL; 5131 return NULL;
4963 nlist = kcalloc(num + 1, array->elem_size, GFP_KERNEL); 5132 nlist = krealloc(array->list, size, GFP_KERNEL);
4964 if (!nlist) 5133 if (!nlist)
4965 return NULL; 5134 return NULL;
4966 if (array->list) { 5135 memset(nlist + oldsize, 0, size - oldsize);
4967 memcpy(nlist, array->list,
4968 array->elem_size * array->alloced);
4969 kfree(array->list);
4970 }
4971 array->list = nlist; 5136 array->list = nlist;
4972 array->alloced = num; 5137 array->alloced = num;
4973 } 5138 }
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 59c97306c1d..755f2b0f9d8 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -26,10 +26,6 @@
26#include <sound/pcm.h> 26#include <sound/pcm.h>
27#include <sound/hwdep.h> 27#include <sound/hwdep.h>
28 28
29#if defined(CONFIG_PM) || defined(CONFIG_SND_HDA_POWER_SAVE)
30#define SND_HDA_NEEDS_RESUME /* resume control code is required */
31#endif
32
33/* 29/*
34 * nodes 30 * nodes
35 */ 31 */
@@ -704,8 +700,12 @@ struct hda_codec_ops {
704 int (*init)(struct hda_codec *codec); 700 int (*init)(struct hda_codec *codec);
705 void (*free)(struct hda_codec *codec); 701 void (*free)(struct hda_codec *codec);
706 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 702 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
707#ifdef SND_HDA_NEEDS_RESUME 703 void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
704 unsigned int power_state);
705#ifdef CONFIG_PM
708 int (*suspend)(struct hda_codec *codec, pm_message_t state); 706 int (*suspend)(struct hda_codec *codec, pm_message_t state);
707 int (*post_suspend)(struct hda_codec *codec);
708 int (*pre_resume)(struct hda_codec *codec);
709 int (*resume)(struct hda_codec *codec); 709 int (*resume)(struct hda_codec *codec);
710#endif 710#endif
711#ifdef CONFIG_SND_HDA_POWER_SAVE 711#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -829,8 +829,7 @@ struct hda_codec {
829 829
830 struct mutex spdif_mutex; 830 struct mutex spdif_mutex;
831 struct mutex control_mutex; 831 struct mutex control_mutex;
832 unsigned int spdif_status; /* IEC958 status bits */ 832 struct snd_array spdif_out;
833 unsigned short spdif_ctls; /* SPDIF control bits */
834 unsigned int spdif_in_enable; /* SPDIF input enable? */ 833 unsigned int spdif_in_enable; /* SPDIF input enable? */
835 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ 834 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
836 struct snd_array init_pins; /* initial (BIOS) pin configurations */ 835 struct snd_array init_pins; /* initial (BIOS) pin configurations */
@@ -904,6 +903,16 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
904 hda_nid_t *start_id); 903 hda_nid_t *start_id);
905int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 904int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
906 hda_nid_t *conn_list, int max_conns); 905 hda_nid_t *conn_list, int max_conns);
906int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
907 hda_nid_t *conn_list, int max_conns);
908int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
909 const hda_nid_t **listp);
910int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
911 const hda_nid_t *list);
912int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
913 hda_nid_t nid, int recursive);
914int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
915 u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
907 916
908struct hda_verb { 917struct hda_verb {
909 hda_nid_t nid; 918 hda_nid_t nid;
@@ -918,7 +927,7 @@ void snd_hda_sequence_write(struct hda_codec *codec,
918int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); 927int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex);
919 928
920/* cached write */ 929/* cached write */
921#ifdef SND_HDA_NEEDS_RESUME 930#ifdef CONFIG_PM
922int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, 931int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
923 int direct, unsigned int verb, unsigned int parm); 932 int direct, unsigned int verb, unsigned int parm);
924void snd_hda_sequence_write_cache(struct hda_codec *codec, 933void snd_hda_sequence_write_cache(struct hda_codec *codec,
@@ -947,6 +956,17 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
947 hda_nid_t nid, unsigned int cfg); /* for hwdep */ 956 hda_nid_t nid, unsigned int cfg); /* for hwdep */
948void snd_hda_shutup_pins(struct hda_codec *codec); 957void snd_hda_shutup_pins(struct hda_codec *codec);
949 958
959/* SPDIF controls */
960struct hda_spdif_out {
961 hda_nid_t nid; /* Converter nid values relate to */
962 unsigned int status; /* IEC958 status bits */
963 unsigned short ctls; /* SPDIF control bits */
964};
965struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
966 hda_nid_t nid);
967void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx);
968void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid);
969
950/* 970/*
951 * Mixer 971 * Mixer
952 */ 972 */
@@ -988,6 +1008,9 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
988 */ 1008 */
989void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); 1009void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
990void snd_hda_bus_reboot_notify(struct hda_bus *bus); 1010void snd_hda_bus_reboot_notify(struct hda_bus *bus);
1011void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
1012 unsigned int power_state,
1013 bool eapd_workaround);
991 1014
992/* 1015/*
993 * power management 1016 * power management
@@ -997,17 +1020,15 @@ int snd_hda_suspend(struct hda_bus *bus);
997int snd_hda_resume(struct hda_bus *bus); 1020int snd_hda_resume(struct hda_bus *bus);
998#endif 1021#endif
999 1022
1000#ifdef CONFIG_SND_HDA_POWER_SAVE
1001static inline 1023static inline
1002int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid) 1024int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1003{ 1025{
1026#ifdef CONFIG_SND_HDA_POWER_SAVE
1004 if (codec->patch_ops.check_power_status) 1027 if (codec->patch_ops.check_power_status)
1005 return codec->patch_ops.check_power_status(codec, nid); 1028 return codec->patch_ops.check_power_status(codec, nid);
1029#endif
1006 return 0; 1030 return 0;
1007} 1031}
1008#else
1009#define hda_call_check_power_status(codec, nid) 0
1010#endif
1011 1032
1012/* 1033/*
1013 * get widget information 1034 * get widget information
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index b05f7be9dc1..28ce17d09c3 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -294,7 +294,7 @@ static int hdmi_update_eld(struct hdmi_eld *e,
294 snd_printd(KERN_INFO "HDMI: out of range MNL %d\n", mnl); 294 snd_printd(KERN_INFO "HDMI: out of range MNL %d\n", mnl);
295 goto out_fail; 295 goto out_fail;
296 } else 296 } else
297 strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl); 297 strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1);
298 298
299 for (i = 0; i < e->sad_count; i++) { 299 for (i = 0; i < e->sad_count; i++) {
300 if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { 300 if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) {
@@ -580,43 +580,45 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
580#endif /* CONFIG_PROC_FS */ 580#endif /* CONFIG_PROC_FS */
581 581
582/* update PCM info based on ELD */ 582/* update PCM info based on ELD */
583void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, 583void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld,
584 struct hda_pcm_stream *codec_pars) 584 struct hda_pcm_stream *hinfo)
585{ 585{
586 u32 rates;
587 u64 formats;
588 unsigned int maxbps;
589 unsigned int channels_max;
586 int i; 590 int i;
587 591
588 /* assume basic audio support (the basic audio flag is not in ELD; 592 /* assume basic audio support (the basic audio flag is not in ELD;
589 * however, all audio capable sinks are required to support basic 593 * however, all audio capable sinks are required to support basic
590 * audio) */ 594 * audio) */
591 pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; 595 rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
592 pcm->formats = SNDRV_PCM_FMTBIT_S16_LE; 596 SNDRV_PCM_RATE_48000;
593 pcm->maxbps = 16; 597 formats = SNDRV_PCM_FMTBIT_S16_LE;
594 pcm->channels_max = 2; 598 maxbps = 16;
599 channels_max = 2;
595 for (i = 0; i < eld->sad_count; i++) { 600 for (i = 0; i < eld->sad_count; i++) {
596 struct cea_sad *a = &eld->sad[i]; 601 struct cea_sad *a = &eld->sad[i];
597 pcm->rates |= a->rates; 602 rates |= a->rates;
598 if (a->channels > pcm->channels_max) 603 if (a->channels > channels_max)
599 pcm->channels_max = a->channels; 604 channels_max = a->channels;
600 if (a->format == AUDIO_CODING_TYPE_LPCM) { 605 if (a->format == AUDIO_CODING_TYPE_LPCM) {
601 if (a->sample_bits & AC_SUPPCM_BITS_20) { 606 if (a->sample_bits & AC_SUPPCM_BITS_20) {
602 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; 607 formats |= SNDRV_PCM_FMTBIT_S32_LE;
603 if (pcm->maxbps < 20) 608 if (maxbps < 20)
604 pcm->maxbps = 20; 609 maxbps = 20;
605 } 610 }
606 if (a->sample_bits & AC_SUPPCM_BITS_24) { 611 if (a->sample_bits & AC_SUPPCM_BITS_24) {
607 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; 612 formats |= SNDRV_PCM_FMTBIT_S32_LE;
608 if (pcm->maxbps < 24) 613 if (maxbps < 24)
609 pcm->maxbps = 24; 614 maxbps = 24;
610 } 615 }
611 } 616 }
612 } 617 }
613 618
614 if (!codec_pars)
615 return;
616
617 /* restrict the parameters by the values the codec provides */ 619 /* restrict the parameters by the values the codec provides */
618 pcm->rates &= codec_pars->rates; 620 hinfo->rates &= rates;
619 pcm->formats &= codec_pars->formats; 621 hinfo->formats &= formats;
620 pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); 622 hinfo->maxbps = min(hinfo->maxbps, maxbps);
621 pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); 623 hinfo->channels_max = min(hinfo->channels_max, channels_max);
622} 624}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 486f6deb3ee..be6982289c0 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -177,7 +177,8 @@ MODULE_DESCRIPTION("Intel HDA driver");
177#define ICH6_REG_INTCTL 0x20 177#define ICH6_REG_INTCTL 0x20
178#define ICH6_REG_INTSTS 0x24 178#define ICH6_REG_INTSTS 0x24
179#define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */ 179#define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */
180#define ICH6_REG_SYNC 0x34 180#define ICH6_REG_OLD_SSYNC 0x34 /* SSYNC for old ICH */
181#define ICH6_REG_SSYNC 0x38
181#define ICH6_REG_CORBLBASE 0x40 182#define ICH6_REG_CORBLBASE 0x40
182#define ICH6_REG_CORBUBASE 0x44 183#define ICH6_REG_CORBUBASE 0x44
183#define ICH6_REG_CORBWP 0x48 184#define ICH6_REG_CORBWP 0x48
@@ -479,6 +480,7 @@ enum {
479#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */ 480#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */
480#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ 481#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */
481#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ 482#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
483#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */
482 484
483/* quirks for ATI SB / AMD Hudson */ 485/* quirks for ATI SB / AMD Hudson */
484#define AZX_DCAPS_PRESET_ATI_SB \ 486#define AZX_DCAPS_PRESET_ATI_SB \
@@ -1706,13 +1708,16 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1706 struct snd_pcm_runtime *runtime = substream->runtime; 1708 struct snd_pcm_runtime *runtime = substream->runtime;
1707 unsigned int bufsize, period_bytes, format_val, stream_tag; 1709 unsigned int bufsize, period_bytes, format_val, stream_tag;
1708 int err; 1710 int err;
1711 struct hda_spdif_out *spdif =
1712 snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
1713 unsigned short ctls = spdif ? spdif->ctls : 0;
1709 1714
1710 azx_stream_reset(chip, azx_dev); 1715 azx_stream_reset(chip, azx_dev);
1711 format_val = snd_hda_calc_stream_format(runtime->rate, 1716 format_val = snd_hda_calc_stream_format(runtime->rate,
1712 runtime->channels, 1717 runtime->channels,
1713 runtime->format, 1718 runtime->format,
1714 hinfo->maxbps, 1719 hinfo->maxbps,
1715 apcm->codec->spdif_ctls); 1720 ctls);
1716 if (!format_val) { 1721 if (!format_val) {
1717 snd_printk(KERN_ERR SFX 1722 snd_printk(KERN_ERR SFX
1718 "invalid format_val, rate=%d, ch=%d, format=%d\n", 1723 "invalid format_val, rate=%d, ch=%d, format=%d\n",
@@ -1792,7 +1797,11 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1792 spin_lock(&chip->reg_lock); 1797 spin_lock(&chip->reg_lock);
1793 if (nsync > 1) { 1798 if (nsync > 1) {
1794 /* first, set SYNC bits of corresponding streams */ 1799 /* first, set SYNC bits of corresponding streams */
1795 azx_writel(chip, SYNC, azx_readl(chip, SYNC) | sbits); 1800 if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
1801 azx_writel(chip, OLD_SSYNC,
1802 azx_readl(chip, OLD_SSYNC) | sbits);
1803 else
1804 azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits);
1796 } 1805 }
1797 snd_pcm_group_for_each_entry(s, substream) { 1806 snd_pcm_group_for_each_entry(s, substream) {
1798 if (s->pcm->card != substream->pcm->card) 1807 if (s->pcm->card != substream->pcm->card)
@@ -1848,7 +1857,11 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1848 if (nsync > 1) { 1857 if (nsync > 1) {
1849 spin_lock(&chip->reg_lock); 1858 spin_lock(&chip->reg_lock);
1850 /* reset SYNC bits */ 1859 /* reset SYNC bits */
1851 azx_writel(chip, SYNC, azx_readl(chip, SYNC) & ~sbits); 1860 if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
1861 azx_writel(chip, OLD_SSYNC,
1862 azx_readl(chip, OLD_SSYNC) & ~sbits);
1863 else
1864 azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
1852 spin_unlock(&chip->reg_lock); 1865 spin_unlock(&chip->reg_lock);
1853 } 1866 }
1854 return 0; 1867 return 0;
@@ -1863,7 +1876,7 @@ static unsigned int azx_via_get_position(struct azx *chip,
1863 unsigned int fifo_size; 1876 unsigned int fifo_size;
1864 1877
1865 link_pos = azx_sd_readl(azx_dev, SD_LPIB); 1878 link_pos = azx_sd_readl(azx_dev, SD_LPIB);
1866 if (azx_dev->index >= 4) { 1879 if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1867 /* Playback, no problem using link position */ 1880 /* Playback, no problem using link position */
1868 return link_pos; 1881 return link_pos;
1869 } 1882 }
@@ -1927,6 +1940,17 @@ static unsigned int azx_get_position(struct azx *chip,
1927 default: 1940 default:
1928 /* use the position buffer */ 1941 /* use the position buffer */
1929 pos = le32_to_cpu(*azx_dev->posbuf); 1942 pos = le32_to_cpu(*azx_dev->posbuf);
1943 if (chip->position_fix[stream] == POS_FIX_AUTO) {
1944 if (!pos || pos == (u32)-1) {
1945 printk(KERN_WARNING
1946 "hda-intel: Invalid position buffer, "
1947 "using LPIB read method instead.\n");
1948 chip->position_fix[stream] = POS_FIX_LPIB;
1949 pos = azx_sd_readl(azx_dev, SD_LPIB);
1950 } else
1951 chip->position_fix[stream] = POS_FIX_POSBUF;
1952 }
1953 break;
1930 } 1954 }
1931 1955
1932 if (pos >= azx_dev->bufsize) 1956 if (pos >= azx_dev->bufsize)
@@ -1964,16 +1988,6 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
1964 1988
1965 stream = azx_dev->substream->stream; 1989 stream = azx_dev->substream->stream;
1966 pos = azx_get_position(chip, azx_dev); 1990 pos = azx_get_position(chip, azx_dev);
1967 if (chip->position_fix[stream] == POS_FIX_AUTO) {
1968 if (!pos) {
1969 printk(KERN_WARNING
1970 "hda-intel: Invalid position buffer, "
1971 "using LPIB read method instead.\n");
1972 chip->position_fix[stream] = POS_FIX_LPIB;
1973 pos = azx_get_position(chip, azx_dev);
1974 } else
1975 chip->position_fix[stream] = POS_FIX_POSBUF;
1976 }
1977 1991
1978 if (WARN_ONCE(!azx_dev->period_bytes, 1992 if (WARN_ONCE(!azx_dev->period_bytes,
1979 "hda-intel: zero azx_dev->period_bytes")) 1993 "hda-intel: zero azx_dev->period_bytes"))
@@ -2061,6 +2075,8 @@ static void azx_pcm_free(struct snd_pcm *pcm)
2061 } 2075 }
2062} 2076}
2063 2077
2078#define MAX_PREALLOC_SIZE (32 * 1024 * 1024)
2079
2064static int 2080static int
2065azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, 2081azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2066 struct hda_pcm *cpcm) 2082 struct hda_pcm *cpcm)
@@ -2069,6 +2085,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2069 struct snd_pcm *pcm; 2085 struct snd_pcm *pcm;
2070 struct azx_pcm *apcm; 2086 struct azx_pcm *apcm;
2071 int pcm_dev = cpcm->device; 2087 int pcm_dev = cpcm->device;
2088 unsigned int size;
2072 int s, err; 2089 int s, err;
2073 2090
2074 if (pcm_dev >= HDA_MAX_PCMS) { 2091 if (pcm_dev >= HDA_MAX_PCMS) {
@@ -2104,9 +2121,12 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2104 snd_pcm_set_ops(pcm, s, &azx_pcm_ops); 2121 snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
2105 } 2122 }
2106 /* buffer pre-allocation */ 2123 /* buffer pre-allocation */
2124 size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
2125 if (size > MAX_PREALLOC_SIZE)
2126 size = MAX_PREALLOC_SIZE;
2107 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 2127 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
2108 snd_dma_pci_data(chip->pci), 2128 snd_dma_pci_data(chip->pci),
2109 1024 * 64, 32 * 1024 * 1024); 2129 size, MAX_PREALLOC_SIZE);
2110 return 0; 2130 return 0;
2111} 2131}
2112 2132
@@ -2149,7 +2169,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
2149{ 2169{
2150 if (request_irq(chip->pci->irq, azx_interrupt, 2170 if (request_irq(chip->pci->irq, azx_interrupt,
2151 chip->msi ? 0 : IRQF_SHARED, 2171 chip->msi ? 0 : IRQF_SHARED,
2152 "hda_intel", chip)) { 2172 KBUILD_MODNAME, chip)) {
2153 printk(KERN_ERR "hda-intel: unable to grab IRQ %d, " 2173 printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
2154 "disabling device\n", chip->pci->irq); 2174 "disabling device\n", chip->pci->irq);
2155 if (do_disconnect) 2175 if (do_disconnect)
@@ -2347,28 +2367,20 @@ static int azx_dev_free(struct snd_device *device)
2347 * white/black-listing for position_fix 2367 * white/black-listing for position_fix
2348 */ 2368 */
2349static struct snd_pci_quirk position_fix_list[] __devinitdata = { 2369static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2350 SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
2351 SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB),
2352 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2370 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2353 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2371 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2354 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
2355 SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB),
2356 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2372 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2357 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2373 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2358 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), 2374 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
2359 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), 2375 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
2360 SND_PCI_QUIRK(0x1043, 0x8410, "ASUS", POS_FIX_LPIB),
2361 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), 2376 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
2362 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), 2377 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2363 SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB),
2364 SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), 2378 SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
2365 SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), 2379 SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
2366 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), 2380 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
2367 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
2368 SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB), 2381 SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
2369 SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB), 2382 SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB),
2370 SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB), 2383 SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
2371 SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB),
2372 {} 2384 {}
2373}; 2385};
2374 2386
@@ -2815,6 +2827,22 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2815 /* SCH */ 2827 /* SCH */
2816 { PCI_DEVICE(0x8086, 0x811b), 2828 { PCI_DEVICE(0x8086, 0x811b),
2817 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP }, 2829 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP },
2830 { PCI_DEVICE(0x8086, 0x2668),
2831 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH6 */
2832 { PCI_DEVICE(0x8086, 0x27d8),
2833 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH7 */
2834 { PCI_DEVICE(0x8086, 0x269a),
2835 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ESB2 */
2836 { PCI_DEVICE(0x8086, 0x284b),
2837 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH8 */
2838 { PCI_DEVICE(0x8086, 0x293e),
2839 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */
2840 { PCI_DEVICE(0x8086, 0x293f),
2841 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */
2842 { PCI_DEVICE(0x8086, 0x3a3e),
2843 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */
2844 { PCI_DEVICE(0x8086, 0x3a6e),
2845 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */
2818 /* Generic Intel */ 2846 /* Generic Intel */
2819 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), 2847 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
2820 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2848 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
@@ -2908,7 +2936,7 @@ MODULE_DEVICE_TABLE(pci, azx_ids);
2908 2936
2909/* pci_driver definition */ 2937/* pci_driver definition */
2910static struct pci_driver driver = { 2938static struct pci_driver driver = {
2911 .name = "HDA Intel", 2939 .name = KBUILD_MODNAME,
2912 .id_table = azx_ids, 2940 .id_table = azx_ids,
2913 .probe = azx_probe, 2941 .probe = azx_probe,
2914 .remove = __devexit_p(azx_remove), 2942 .remove = __devexit_p(azx_remove),
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 08ec073444e..2e7ac31afa8 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -131,7 +131,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
131 int direction, int idx, int mask, int val); 131 int direction, int idx, int mask, int val);
132int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, 132int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
133 int dir, int idx, int mask, int val); 133 int dir, int idx, int mask, int val);
134#ifdef SND_HDA_NEEDS_RESUME 134#ifdef CONFIG_PM
135void snd_hda_codec_resume_amp(struct hda_codec *codec); 135void snd_hda_codec_resume_amp(struct hda_codec *codec);
136#endif 136#endif
137 137
@@ -212,7 +212,9 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
212/* 212/*
213 * SPDIF I/O 213 * SPDIF I/O
214 */ 214 */
215int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); 215int snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
216 hda_nid_t associated_nid,
217 hda_nid_t cvt_nid);
216int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); 218int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
217 219
218/* 220/*
@@ -563,7 +565,6 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
563 * power-management 565 * power-management
564 */ 566 */
565 567
566#ifdef CONFIG_SND_HDA_POWER_SAVE
567void snd_hda_schedule_power_save(struct hda_codec *codec); 568void snd_hda_schedule_power_save(struct hda_codec *codec);
568 569
569struct hda_amp_list { 570struct hda_amp_list {
@@ -580,7 +581,6 @@ struct hda_loopback_check {
580int snd_hda_check_amp_list_power(struct hda_codec *codec, 581int snd_hda_check_amp_list_power(struct hda_codec *codec,
581 struct hda_loopback_check *check, 582 struct hda_loopback_check *check,
582 hda_nid_t nid); 583 hda_nid_t nid);
583#endif /* CONFIG_SND_HDA_POWER_SAVE */
584 584
585/* 585/*
586 * AMP control callbacks 586 * AMP control callbacks
@@ -639,8 +639,8 @@ struct hdmi_eld {
639int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); 639int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
640int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t); 640int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t);
641void snd_hdmi_show_eld(struct hdmi_eld *eld); 641void snd_hdmi_show_eld(struct hdmi_eld *eld);
642void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, 642void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld,
643 struct hda_pcm_stream *codec_pars); 643 struct hda_pcm_stream *hinfo);
644 644
645#ifdef CONFIG_PROC_FS 645#ifdef CONFIG_PROC_FS
646int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld, 646int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index bfe74c2fb07..2be57b051aa 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -636,7 +636,7 @@ static void print_codec_info(struct snd_info_entry *entry,
636 wid_caps |= AC_WCAP_CONN_LIST; 636 wid_caps |= AC_WCAP_CONN_LIST;
637 637
638 if (wid_caps & AC_WCAP_CONN_LIST) 638 if (wid_caps & AC_WCAP_CONN_LIST)
639 conn_len = snd_hda_get_connections(codec, nid, conn, 639 conn_len = snd_hda_get_raw_connections(codec, nid, conn,
640 HDA_MAX_CONNECTIONS); 640 HDA_MAX_CONNECTIONS);
641 641
642 if (wid_caps & AC_WCAP_IN_AMP) { 642 if (wid_caps & AC_WCAP_IN_AMP) {
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 696ac259030..8648917acff 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -213,7 +213,9 @@ static int ad198x_build_controls(struct hda_codec *codec)
213 return err; 213 return err;
214 } 214 }
215 if (spec->multiout.dig_out_nid) { 215 if (spec->multiout.dig_out_nid) {
216 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 216 err = snd_hda_create_spdif_out_ctls(codec,
217 spec->multiout.dig_out_nid,
218 spec->multiout.dig_out_nid);
217 if (err < 0) 219 if (err < 0)
218 return err; 220 return err;
219 err = snd_hda_create_spdif_share_sw(codec, 221 err = snd_hda_create_spdif_share_sw(codec,
@@ -506,9 +508,11 @@ static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
506 hda_nid_t hp) 508 hda_nid_t hp)
507{ 509{
508 struct ad198x_spec *spec = codec->spec; 510 struct ad198x_spec *spec = codec->spec;
509 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, 511 if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD)
512 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
510 !spec->inv_eapd ? 0x00 : 0x02); 513 !spec->inv_eapd ? 0x00 : 0x02);
511 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, 514 if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD)
515 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
512 !spec->inv_eapd ? 0x00 : 0x02); 516 !spec->inv_eapd ? 0x00 : 0x02);
513} 517}
514 518
@@ -524,6 +528,10 @@ static void ad198x_power_eapd(struct hda_codec *codec)
524 case 0x11d4184a: 528 case 0x11d4184a:
525 case 0x11d4194a: 529 case 0x11d4194a:
526 case 0x11d4194b: 530 case 0x11d4194b:
531 case 0x11d41988:
532 case 0x11d4198b:
533 case 0x11d4989a:
534 case 0x11d4989b:
527 ad198x_power_eapd_write(codec, 0x12, 0x11); 535 ad198x_power_eapd_write(codec, 0x12, 0x11);
528 break; 536 break;
529 case 0x11d41981: 537 case 0x11d41981:
@@ -533,12 +541,6 @@ static void ad198x_power_eapd(struct hda_codec *codec)
533 case 0x11d41986: 541 case 0x11d41986:
534 ad198x_power_eapd_write(codec, 0x1b, 0x1a); 542 ad198x_power_eapd_write(codec, 0x1b, 0x1a);
535 break; 543 break;
536 case 0x11d41988:
537 case 0x11d4198b:
538 case 0x11d4989a:
539 case 0x11d4989b:
540 ad198x_power_eapd_write(codec, 0x29, 0x22);
541 break;
542 } 544 }
543} 545}
544 546
@@ -561,7 +563,7 @@ static void ad198x_free(struct hda_codec *codec)
561 snd_hda_detach_beep_device(codec); 563 snd_hda_detach_beep_device(codec);
562} 564}
563 565
564#ifdef SND_HDA_NEEDS_RESUME 566#ifdef CONFIG_PM
565static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) 567static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
566{ 568{
567 ad198x_shutup(codec); 569 ad198x_shutup(codec);
@@ -577,7 +579,7 @@ static const struct hda_codec_ops ad198x_patch_ops = {
577#ifdef CONFIG_SND_HDA_POWER_SAVE 579#ifdef CONFIG_SND_HDA_POWER_SAVE
578 .check_power_status = ad198x_check_power_status, 580 .check_power_status = ad198x_check_power_status,
579#endif 581#endif
580#ifdef SND_HDA_NEEDS_RESUME 582#ifdef CONFIG_PM
581 .suspend = ad198x_suspend, 583 .suspend = ad198x_suspend,
582#endif 584#endif
583 .reboot_notify = ad198x_shutup, 585 .reboot_notify = ad198x_shutup,
@@ -1920,7 +1922,8 @@ static int patch_ad1981(struct hda_codec *codec)
1920 spec->mixers[0] = ad1981_hp_mixers; 1922 spec->mixers[0] = ad1981_hp_mixers;
1921 spec->num_init_verbs = 2; 1923 spec->num_init_verbs = 2;
1922 spec->init_verbs[1] = ad1981_hp_init_verbs; 1924 spec->init_verbs[1] = ad1981_hp_init_verbs;
1923 spec->multiout.dig_out_nid = 0; 1925 if (!is_jack_available(codec, 0x0a))
1926 spec->multiout.dig_out_nid = 0;
1924 spec->input_mux = &ad1981_hp_capture_source; 1927 spec->input_mux = &ad1981_hp_capture_source;
1925 1928
1926 codec->patch_ops.init = ad1981_hp_init; 1929 codec->patch_ops.init = ad1981_hp_init;
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index 61b92634b16..6b406840846 100644
--- a/sound/pci/hda/patch_ca0110.c
+++ b/sound/pci/hda/patch_ca0110.c
@@ -240,7 +240,8 @@ static int ca0110_build_controls(struct hda_codec *codec)
240 } 240 }
241 241
242 if (spec->dig_out) { 242 if (spec->dig_out) {
243 err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out); 243 err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out,
244 spec->dig_out);
244 if (err < 0) 245 if (err < 0)
245 return err; 246 return err;
246 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); 247 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
new file mode 100644
index 00000000000..d9a2254ceef
--- /dev/null
+++ b/sound/pci/hda/patch_ca0132.c
@@ -0,0 +1,1097 @@
1/*
2 * HD audio interface patch for Creative CA0132 chip
3 *
4 * Copyright (c) 2011, Creative Technology Ltd.
5 *
6 * Based on patch_ca0110.c
7 * Copyright (c) 2008 Takashi Iwai <tiwai@suse.de>
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/slab.h>
27#include <linux/pci.h>
28#include <linux/mutex.h>
29#include <sound/core.h>
30#include "hda_codec.h"
31#include "hda_local.h"
32
33#define WIDGET_CHIP_CTRL 0x15
34#define WIDGET_DSP_CTRL 0x16
35
36#define WUH_MEM_CONNID 10
37#define DSP_MEM_CONNID 16
38
39enum hda_cmd_vendor_io {
40 /* for DspIO node */
41 VENDOR_DSPIO_SCP_WRITE_DATA_LOW = 0x000,
42 VENDOR_DSPIO_SCP_WRITE_DATA_HIGH = 0x100,
43
44 VENDOR_DSPIO_STATUS = 0xF01,
45 VENDOR_DSPIO_SCP_POST_READ_DATA = 0x702,
46 VENDOR_DSPIO_SCP_READ_DATA = 0xF02,
47 VENDOR_DSPIO_DSP_INIT = 0x703,
48 VENDOR_DSPIO_SCP_POST_COUNT_QUERY = 0x704,
49 VENDOR_DSPIO_SCP_READ_COUNT = 0xF04,
50
51 /* for ChipIO node */
52 VENDOR_CHIPIO_ADDRESS_LOW = 0x000,
53 VENDOR_CHIPIO_ADDRESS_HIGH = 0x100,
54 VENDOR_CHIPIO_STREAM_FORMAT = 0x200,
55 VENDOR_CHIPIO_DATA_LOW = 0x300,
56 VENDOR_CHIPIO_DATA_HIGH = 0x400,
57
58 VENDOR_CHIPIO_GET_PARAMETER = 0xF00,
59 VENDOR_CHIPIO_STATUS = 0xF01,
60 VENDOR_CHIPIO_HIC_POST_READ = 0x702,
61 VENDOR_CHIPIO_HIC_READ_DATA = 0xF03,
62
63 VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE = 0x70A,
64
65 VENDOR_CHIPIO_PLL_PMU_WRITE = 0x70C,
66 VENDOR_CHIPIO_PLL_PMU_READ = 0xF0C,
67 VENDOR_CHIPIO_8051_ADDRESS_LOW = 0x70D,
68 VENDOR_CHIPIO_8051_ADDRESS_HIGH = 0x70E,
69 VENDOR_CHIPIO_FLAG_SET = 0x70F,
70 VENDOR_CHIPIO_FLAGS_GET = 0xF0F,
71 VENDOR_CHIPIO_PARAMETER_SET = 0x710,
72 VENDOR_CHIPIO_PARAMETER_GET = 0xF10,
73
74 VENDOR_CHIPIO_PORT_ALLOC_CONFIG_SET = 0x711,
75 VENDOR_CHIPIO_PORT_ALLOC_SET = 0x712,
76 VENDOR_CHIPIO_PORT_ALLOC_GET = 0xF12,
77 VENDOR_CHIPIO_PORT_FREE_SET = 0x713,
78
79 VENDOR_CHIPIO_PARAMETER_EX_ID_GET = 0xF17,
80 VENDOR_CHIPIO_PARAMETER_EX_ID_SET = 0x717,
81 VENDOR_CHIPIO_PARAMETER_EX_VALUE_GET = 0xF18,
82 VENDOR_CHIPIO_PARAMETER_EX_VALUE_SET = 0x718
83};
84
85/*
86 * Control flag IDs
87 */
88enum control_flag_id {
89 /* Connection manager stream setup is bypassed/enabled */
90 CONTROL_FLAG_C_MGR = 0,
91 /* DSP DMA is bypassed/enabled */
92 CONTROL_FLAG_DMA = 1,
93 /* 8051 'idle' mode is disabled/enabled */
94 CONTROL_FLAG_IDLE_ENABLE = 2,
95 /* Tracker for the SPDIF-in path is bypassed/enabled */
96 CONTROL_FLAG_TRACKER = 3,
97 /* DigitalOut to Spdif2Out connection is disabled/enabled */
98 CONTROL_FLAG_SPDIF2OUT = 4,
99 /* Digital Microphone is disabled/enabled */
100 CONTROL_FLAG_DMIC = 5,
101 /* ADC_B rate is 48 kHz/96 kHz */
102 CONTROL_FLAG_ADC_B_96KHZ = 6,
103 /* ADC_C rate is 48 kHz/96 kHz */
104 CONTROL_FLAG_ADC_C_96KHZ = 7,
105 /* DAC rate is 48 kHz/96 kHz (affects all DACs) */
106 CONTROL_FLAG_DAC_96KHZ = 8,
107 /* DSP rate is 48 kHz/96 kHz */
108 CONTROL_FLAG_DSP_96KHZ = 9,
109 /* SRC clock is 98 MHz/196 MHz (196 MHz forces rate to 96 KHz) */
110 CONTROL_FLAG_SRC_CLOCK_196MHZ = 10,
111 /* SRC rate is 48 kHz/96 kHz (48 kHz disabled when clock is 196 MHz) */
112 CONTROL_FLAG_SRC_RATE_96KHZ = 11,
113 /* Decode Loop (DSP->SRC->DSP) is disabled/enabled */
114 CONTROL_FLAG_DECODE_LOOP = 12,
115 /* De-emphasis filter on DAC-1 disabled/enabled */
116 CONTROL_FLAG_DAC1_DEEMPHASIS = 13,
117 /* De-emphasis filter on DAC-2 disabled/enabled */
118 CONTROL_FLAG_DAC2_DEEMPHASIS = 14,
119 /* De-emphasis filter on DAC-3 disabled/enabled */
120 CONTROL_FLAG_DAC3_DEEMPHASIS = 15,
121 /* High-pass filter on ADC_B disabled/enabled */
122 CONTROL_FLAG_ADC_B_HIGH_PASS = 16,
123 /* High-pass filter on ADC_C disabled/enabled */
124 CONTROL_FLAG_ADC_C_HIGH_PASS = 17,
125 /* Common mode on Port_A disabled/enabled */
126 CONTROL_FLAG_PORT_A_COMMON_MODE = 18,
127 /* Common mode on Port_D disabled/enabled */
128 CONTROL_FLAG_PORT_D_COMMON_MODE = 19,
129 /* Impedance for ramp generator on Port_A 16 Ohm/10K Ohm */
130 CONTROL_FLAG_PORT_A_10KOHM_LOAD = 20,
131 /* Impedance for ramp generator on Port_D, 16 Ohm/10K Ohm */
132 CONTROL_FLAG_PORT_D_10K0HM_LOAD = 21,
133 /* ASI rate is 48kHz/96kHz */
134 CONTROL_FLAG_ASI_96KHZ = 22,
135 /* DAC power settings able to control attached ports no/yes */
136 CONTROL_FLAG_DACS_CONTROL_PORTS = 23,
137 /* Clock Stop OK reporting is disabled/enabled */
138 CONTROL_FLAG_CONTROL_STOP_OK_ENABLE = 24,
139 /* Number of control flags */
140 CONTROL_FLAGS_MAX = (CONTROL_FLAG_CONTROL_STOP_OK_ENABLE+1)
141};
142
143/*
144 * Control parameter IDs
145 */
146enum control_parameter_id {
147 /* 0: force HDA, 1: allow DSP if HDA Spdif1Out stream is idle */
148 CONTROL_PARAM_SPDIF1_SOURCE = 2,
149
150 /* Stream Control */
151
152 /* Select stream with the given ID */
153 CONTROL_PARAM_STREAM_ID = 24,
154 /* Source connection point for the selected stream */
155 CONTROL_PARAM_STREAM_SOURCE_CONN_POINT = 25,
156 /* Destination connection point for the selected stream */
157 CONTROL_PARAM_STREAM_DEST_CONN_POINT = 26,
158 /* Number of audio channels in the selected stream */
159 CONTROL_PARAM_STREAMS_CHANNELS = 27,
160 /*Enable control for the selected stream */
161 CONTROL_PARAM_STREAM_CONTROL = 28,
162
163 /* Connection Point Control */
164
165 /* Select connection point with the given ID */
166 CONTROL_PARAM_CONN_POINT_ID = 29,
167 /* Connection point sample rate */
168 CONTROL_PARAM_CONN_POINT_SAMPLE_RATE = 30,
169
170 /* Node Control */
171
172 /* Select HDA node with the given ID */
173 CONTROL_PARAM_NODE_ID = 31
174};
175
176/*
177 * Dsp Io Status codes
178 */
179enum hda_vendor_status_dspio {
180 /* Success */
181 VENDOR_STATUS_DSPIO_OK = 0x00,
182 /* Busy, unable to accept new command, the host must retry */
183 VENDOR_STATUS_DSPIO_BUSY = 0x01,
184 /* SCP command queue is full */
185 VENDOR_STATUS_DSPIO_SCP_COMMAND_QUEUE_FULL = 0x02,
186 /* SCP response queue is empty */
187 VENDOR_STATUS_DSPIO_SCP_RESPONSE_QUEUE_EMPTY = 0x03
188};
189
190/*
191 * Chip Io Status codes
192 */
193enum hda_vendor_status_chipio {
194 /* Success */
195 VENDOR_STATUS_CHIPIO_OK = 0x00,
196 /* Busy, unable to accept new command, the host must retry */
197 VENDOR_STATUS_CHIPIO_BUSY = 0x01
198};
199
200/*
201 * CA0132 sample rate
202 */
203enum ca0132_sample_rate {
204 SR_6_000 = 0x00,
205 SR_8_000 = 0x01,
206 SR_9_600 = 0x02,
207 SR_11_025 = 0x03,
208 SR_16_000 = 0x04,
209 SR_22_050 = 0x05,
210 SR_24_000 = 0x06,
211 SR_32_000 = 0x07,
212 SR_44_100 = 0x08,
213 SR_48_000 = 0x09,
214 SR_88_200 = 0x0A,
215 SR_96_000 = 0x0B,
216 SR_144_000 = 0x0C,
217 SR_176_400 = 0x0D,
218 SR_192_000 = 0x0E,
219 SR_384_000 = 0x0F,
220
221 SR_COUNT = 0x10,
222
223 SR_RATE_UNKNOWN = 0x1F
224};
225
226/*
227 * Scp Helper function
228 */
229enum get_set {
230 IS_SET = 0,
231 IS_GET = 1,
232};
233
234/*
235 * Duplicated from ca0110 codec
236 */
237
238static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
239{
240 if (pin) {
241 snd_hda_codec_write(codec, pin, 0,
242 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
243 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
244 snd_hda_codec_write(codec, pin, 0,
245 AC_VERB_SET_AMP_GAIN_MUTE,
246 AMP_OUT_UNMUTE);
247 }
248 if (dac)
249 snd_hda_codec_write(codec, dac, 0,
250 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO);
251}
252
253static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
254{
255 if (pin) {
256 snd_hda_codec_write(codec, pin, 0,
257 AC_VERB_SET_PIN_WIDGET_CONTROL,
258 PIN_VREF80);
259 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
260 snd_hda_codec_write(codec, pin, 0,
261 AC_VERB_SET_AMP_GAIN_MUTE,
262 AMP_IN_UNMUTE(0));
263 }
264 if (adc)
265 snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE,
266 AMP_IN_UNMUTE(0));
267}
268
269static char *dirstr[2] = { "Playback", "Capture" };
270
271static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
272 int chan, int dir)
273{
274 char namestr[44];
275 int type = dir ? HDA_INPUT : HDA_OUTPUT;
276 struct snd_kcontrol_new knew =
277 HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type);
278 sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
279 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
280}
281
282static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
283 int chan, int dir)
284{
285 char namestr[44];
286 int type = dir ? HDA_INPUT : HDA_OUTPUT;
287 struct snd_kcontrol_new knew =
288 HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type);
289 sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]);
290 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
291}
292
293#define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0)
294#define add_out_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 0)
295#define add_in_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 1)
296#define add_in_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 1)
297#define add_mono_switch(codec, nid, pfx, chan) \
298 _add_switch(codec, nid, pfx, chan, 0)
299#define add_mono_volume(codec, nid, pfx, chan) \
300 _add_volume(codec, nid, pfx, chan, 0)
301#define add_in_mono_switch(codec, nid, pfx, chan) \
302 _add_switch(codec, nid, pfx, chan, 1)
303#define add_in_mono_volume(codec, nid, pfx, chan) \
304 _add_volume(codec, nid, pfx, chan, 1)
305
306
307/*
308 * CA0132 specific
309 */
310
311struct ca0132_spec {
312 struct auto_pin_cfg autocfg;
313 struct hda_multi_out multiout;
314 hda_nid_t out_pins[AUTO_CFG_MAX_OUTS];
315 hda_nid_t dacs[AUTO_CFG_MAX_OUTS];
316 hda_nid_t hp_dac;
317 hda_nid_t input_pins[AUTO_PIN_LAST];
318 hda_nid_t adcs[AUTO_PIN_LAST];
319 hda_nid_t dig_out;
320 hda_nid_t dig_in;
321 unsigned int num_inputs;
322 long curr_hp_switch;
323 long curr_hp_volume[2];
324 long curr_speaker_switch;
325 struct mutex chipio_mutex;
326 const char *input_labels[AUTO_PIN_LAST];
327 struct hda_pcm pcm_rec[2]; /* PCM information */
328};
329
330/* Chip access helper function */
331static int chipio_send(struct hda_codec *codec,
332 unsigned int reg,
333 unsigned int data)
334{
335 unsigned int res;
336 int retry = 50;
337
338 /* send bits of data specified by reg */
339 do {
340 res = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
341 reg, data);
342 if (res == VENDOR_STATUS_CHIPIO_OK)
343 return 0;
344 } while (--retry);
345 return -EIO;
346}
347
348/*
349 * Write chip address through the vendor widget -- NOT protected by the Mutex!
350 */
351static int chipio_write_address(struct hda_codec *codec,
352 unsigned int chip_addx)
353{
354 int res;
355
356 /* send low 16 bits of the address */
357 res = chipio_send(codec, VENDOR_CHIPIO_ADDRESS_LOW,
358 chip_addx & 0xffff);
359
360 if (res != -EIO) {
361 /* send high 16 bits of the address */
362 res = chipio_send(codec, VENDOR_CHIPIO_ADDRESS_HIGH,
363 chip_addx >> 16);
364 }
365
366 return res;
367}
368
369/*
370 * Write data through the vendor widget -- NOT protected by the Mutex!
371 */
372
373static int chipio_write_data(struct hda_codec *codec, unsigned int data)
374{
375 int res;
376
377 /* send low 16 bits of the data */
378 res = chipio_send(codec, VENDOR_CHIPIO_DATA_LOW, data & 0xffff);
379
380 if (res != -EIO) {
381 /* send high 16 bits of the data */
382 res = chipio_send(codec, VENDOR_CHIPIO_DATA_HIGH,
383 data >> 16);
384 }
385
386 return res;
387}
388
389/*
390 * Read data through the vendor widget -- NOT protected by the Mutex!
391 */
392static int chipio_read_data(struct hda_codec *codec, unsigned int *data)
393{
394 int res;
395
396 /* post read */
397 res = chipio_send(codec, VENDOR_CHIPIO_HIC_POST_READ, 0);
398
399 if (res != -EIO) {
400 /* read status */
401 res = chipio_send(codec, VENDOR_CHIPIO_STATUS, 0);
402 }
403
404 if (res != -EIO) {
405 /* read data */
406 *data = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
407 VENDOR_CHIPIO_HIC_READ_DATA,
408 0);
409 }
410
411 return res;
412}
413
414/*
415 * Write given value to the given address through the chip I/O widget.
416 * protected by the Mutex
417 */
418static int chipio_write(struct hda_codec *codec,
419 unsigned int chip_addx, const unsigned int data)
420{
421 struct ca0132_spec *spec = codec->spec;
422 int err;
423
424 mutex_lock(&spec->chipio_mutex);
425
426 /* write the address, and if successful proceed to write data */
427 err = chipio_write_address(codec, chip_addx);
428 if (err < 0)
429 goto exit;
430
431 err = chipio_write_data(codec, data);
432 if (err < 0)
433 goto exit;
434
435exit:
436 mutex_unlock(&spec->chipio_mutex);
437 return err;
438}
439
440/*
441 * Read the given address through the chip I/O widget
442 * protected by the Mutex
443 */
444static int chipio_read(struct hda_codec *codec,
445 unsigned int chip_addx, unsigned int *data)
446{
447 struct ca0132_spec *spec = codec->spec;
448 int err;
449
450 mutex_lock(&spec->chipio_mutex);
451
452 /* write the address, and if successful proceed to write data */
453 err = chipio_write_address(codec, chip_addx);
454 if (err < 0)
455 goto exit;
456
457 err = chipio_read_data(codec, data);
458 if (err < 0)
459 goto exit;
460
461exit:
462 mutex_unlock(&spec->chipio_mutex);
463 return err;
464}
465
466/*
467 * PCM stuffs
468 */
469static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid,
470 u32 stream_tag,
471 int channel_id, int format)
472{
473 unsigned int oldval, newval;
474
475 if (!nid)
476 return;
477
478 snd_printdd("ca0132_setup_stream: "
479 "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
480 nid, stream_tag, channel_id, format);
481
482 /* update the format-id if changed */
483 oldval = snd_hda_codec_read(codec, nid, 0,
484 AC_VERB_GET_STREAM_FORMAT,
485 0);
486 if (oldval != format) {
487 msleep(20);
488 snd_hda_codec_write(codec, nid, 0,
489 AC_VERB_SET_STREAM_FORMAT,
490 format);
491 }
492
493 oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
494 newval = (stream_tag << 4) | channel_id;
495 if (oldval != newval) {
496 snd_hda_codec_write(codec, nid, 0,
497 AC_VERB_SET_CHANNEL_STREAMID,
498 newval);
499 }
500}
501
502static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
503{
504 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
505 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
506}
507
508/*
509 * PCM callbacks
510 */
511static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
512 struct hda_codec *codec,
513 unsigned int stream_tag,
514 unsigned int format,
515 struct snd_pcm_substream *substream)
516{
517 struct ca0132_spec *spec = codec->spec;
518
519 ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format);
520
521 return 0;
522}
523
524static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
525 struct hda_codec *codec,
526 struct snd_pcm_substream *substream)
527{
528 struct ca0132_spec *spec = codec->spec;
529
530 ca0132_cleanup_stream(codec, spec->dacs[0]);
531
532 return 0;
533}
534
535/*
536 * Digital out
537 */
538static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
539 struct hda_codec *codec,
540 unsigned int stream_tag,
541 unsigned int format,
542 struct snd_pcm_substream *substream)
543{
544 struct ca0132_spec *spec = codec->spec;
545
546 ca0132_setup_stream(codec, spec->dig_out, stream_tag, 0, format);
547
548 return 0;
549}
550
551static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
552 struct hda_codec *codec,
553 struct snd_pcm_substream *substream)
554{
555 struct ca0132_spec *spec = codec->spec;
556
557 ca0132_cleanup_stream(codec, spec->dig_out);
558
559 return 0;
560}
561
562/*
563 * Analog capture
564 */
565static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
566 struct hda_codec *codec,
567 unsigned int stream_tag,
568 unsigned int format,
569 struct snd_pcm_substream *substream)
570{
571 struct ca0132_spec *spec = codec->spec;
572
573 ca0132_setup_stream(codec, spec->adcs[substream->number],
574 stream_tag, 0, format);
575
576 return 0;
577}
578
579static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
580 struct hda_codec *codec,
581 struct snd_pcm_substream *substream)
582{
583 struct ca0132_spec *spec = codec->spec;
584
585 ca0132_cleanup_stream(codec, spec->adcs[substream->number]);
586
587 return 0;
588}
589
590/*
591 * Digital capture
592 */
593static int ca0132_dig_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
594 struct hda_codec *codec,
595 unsigned int stream_tag,
596 unsigned int format,
597 struct snd_pcm_substream *substream)
598{
599 struct ca0132_spec *spec = codec->spec;
600
601 ca0132_setup_stream(codec, spec->dig_in, stream_tag, 0, format);
602
603 return 0;
604}
605
606static int ca0132_dig_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
607 struct hda_codec *codec,
608 struct snd_pcm_substream *substream)
609{
610 struct ca0132_spec *spec = codec->spec;
611
612 ca0132_cleanup_stream(codec, spec->dig_in);
613
614 return 0;
615}
616
617/*
618 */
619static struct hda_pcm_stream ca0132_pcm_analog_playback = {
620 .substreams = 1,
621 .channels_min = 2,
622 .channels_max = 2,
623 .ops = {
624 .prepare = ca0132_playback_pcm_prepare,
625 .cleanup = ca0132_playback_pcm_cleanup
626 },
627};
628
629static struct hda_pcm_stream ca0132_pcm_analog_capture = {
630 .substreams = 1,
631 .channels_min = 2,
632 .channels_max = 2,
633 .ops = {
634 .prepare = ca0132_capture_pcm_prepare,
635 .cleanup = ca0132_capture_pcm_cleanup
636 },
637};
638
639static struct hda_pcm_stream ca0132_pcm_digital_playback = {
640 .substreams = 1,
641 .channels_min = 2,
642 .channels_max = 2,
643 .ops = {
644 .prepare = ca0132_dig_playback_pcm_prepare,
645 .cleanup = ca0132_dig_playback_pcm_cleanup
646 },
647};
648
649static struct hda_pcm_stream ca0132_pcm_digital_capture = {
650 .substreams = 1,
651 .channels_min = 2,
652 .channels_max = 2,
653 .ops = {
654 .prepare = ca0132_dig_capture_pcm_prepare,
655 .cleanup = ca0132_dig_capture_pcm_cleanup
656 },
657};
658
659static int ca0132_build_pcms(struct hda_codec *codec)
660{
661 struct ca0132_spec *spec = codec->spec;
662 struct hda_pcm *info = spec->pcm_rec;
663
664 codec->pcm_info = info;
665 codec->num_pcms = 0;
666
667 info->name = "CA0132 Analog";
668 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0132_pcm_analog_playback;
669 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0];
670 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
671 spec->multiout.max_channels;
672 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
673 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs;
674 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
675 codec->num_pcms++;
676
677 if (!spec->dig_out && !spec->dig_in)
678 return 0;
679
680 info++;
681 info->name = "CA0132 Digital";
682 info->pcm_type = HDA_PCM_TYPE_SPDIF;
683 if (spec->dig_out) {
684 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
685 ca0132_pcm_digital_playback;
686 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out;
687 }
688 if (spec->dig_in) {
689 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
690 ca0132_pcm_digital_capture;
691 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
692 }
693 codec->num_pcms++;
694
695 return 0;
696}
697
698#define REG_CODEC_MUTE 0x18b014
699#define REG_CODEC_HP_VOL_L 0x18b070
700#define REG_CODEC_HP_VOL_R 0x18b074
701
702static int ca0132_hp_switch_get(struct snd_kcontrol *kcontrol,
703 struct snd_ctl_elem_value *ucontrol)
704{
705 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
706 struct ca0132_spec *spec = codec->spec;
707 long *valp = ucontrol->value.integer.value;
708
709 *valp = spec->curr_hp_switch;
710 return 0;
711}
712
713static int ca0132_hp_switch_put(struct snd_kcontrol *kcontrol,
714 struct snd_ctl_elem_value *ucontrol)
715{
716 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
717 struct ca0132_spec *spec = codec->spec;
718 long *valp = ucontrol->value.integer.value;
719 unsigned int data;
720 int err;
721
722 /* any change? */
723 if (spec->curr_hp_switch == *valp)
724 return 0;
725
726 snd_hda_power_up(codec);
727
728 err = chipio_read(codec, REG_CODEC_MUTE, &data);
729 if (err < 0)
730 return err;
731
732 /* *valp 0 is mute, 1 is unmute */
733 data = (data & 0x7f) | (*valp ? 0 : 0x80);
734 chipio_write(codec, REG_CODEC_MUTE, data);
735 if (err < 0)
736 return err;
737
738 spec->curr_hp_switch = *valp;
739
740 snd_hda_power_down(codec);
741 return 1;
742}
743
744static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol,
745 struct snd_ctl_elem_value *ucontrol)
746{
747 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
748 struct ca0132_spec *spec = codec->spec;
749 long *valp = ucontrol->value.integer.value;
750
751 *valp = spec->curr_speaker_switch;
752 return 0;
753}
754
755static int ca0132_speaker_switch_put(struct snd_kcontrol *kcontrol,
756 struct snd_ctl_elem_value *ucontrol)
757{
758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
759 struct ca0132_spec *spec = codec->spec;
760 long *valp = ucontrol->value.integer.value;
761 unsigned int data;
762 int err;
763
764 /* any change? */
765 if (spec->curr_speaker_switch == *valp)
766 return 0;
767
768 snd_hda_power_up(codec);
769
770 err = chipio_read(codec, REG_CODEC_MUTE, &data);
771 if (err < 0)
772 return err;
773
774 /* *valp 0 is mute, 1 is unmute */
775 data = (data & 0xef) | (*valp ? 0 : 0x10);
776 chipio_write(codec, REG_CODEC_MUTE, data);
777 if (err < 0)
778 return err;
779
780 spec->curr_speaker_switch = *valp;
781
782 snd_hda_power_down(codec);
783 return 1;
784}
785
786static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol,
787 struct snd_ctl_elem_value *ucontrol)
788{
789 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
790 struct ca0132_spec *spec = codec->spec;
791 long *valp = ucontrol->value.integer.value;
792
793 *valp++ = spec->curr_hp_volume[0];
794 *valp = spec->curr_hp_volume[1];
795 return 0;
796}
797
798static int ca0132_hp_volume_put(struct snd_kcontrol *kcontrol,
799 struct snd_ctl_elem_value *ucontrol)
800{
801 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
802 struct ca0132_spec *spec = codec->spec;
803 long *valp = ucontrol->value.integer.value;
804 long left_vol, right_vol;
805 unsigned int data;
806 int val;
807 int err;
808
809 left_vol = *valp++;
810 right_vol = *valp;
811
812 /* any change? */
813 if ((spec->curr_hp_volume[0] == left_vol) &&
814 (spec->curr_hp_volume[1] == right_vol))
815 return 0;
816
817 snd_hda_power_up(codec);
818
819 err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data);
820 if (err < 0)
821 return err;
822
823 val = 31 - left_vol;
824 data = (data & 0xe0) | val;
825 chipio_write(codec, REG_CODEC_HP_VOL_L, data);
826 if (err < 0)
827 return err;
828
829 val = 31 - right_vol;
830 data = (data & 0xe0) | val;
831 chipio_write(codec, REG_CODEC_HP_VOL_R, data);
832 if (err < 0)
833 return err;
834
835 spec->curr_hp_volume[0] = left_vol;
836 spec->curr_hp_volume[1] = right_vol;
837
838 snd_hda_power_down(codec);
839 return 1;
840}
841
842static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid)
843{
844 struct snd_kcontrol_new knew =
845 HDA_CODEC_MUTE_MONO("Headphone Playback Switch",
846 nid, 1, 0, HDA_OUTPUT);
847 knew.get = ca0132_hp_switch_get;
848 knew.put = ca0132_hp_switch_put;
849 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
850}
851
852static int add_hp_volume(struct hda_codec *codec, hda_nid_t nid)
853{
854 struct snd_kcontrol_new knew =
855 HDA_CODEC_VOLUME_MONO("Headphone Playback Volume",
856 nid, 3, 0, HDA_OUTPUT);
857 knew.get = ca0132_hp_volume_get;
858 knew.put = ca0132_hp_volume_put;
859 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
860}
861
862static int add_speaker_switch(struct hda_codec *codec, hda_nid_t nid)
863{
864 struct snd_kcontrol_new knew =
865 HDA_CODEC_MUTE_MONO("Speaker Playback Switch",
866 nid, 1, 0, HDA_OUTPUT);
867 knew.get = ca0132_speaker_switch_get;
868 knew.put = ca0132_speaker_switch_put;
869 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
870}
871
872static void ca0132_fix_hp_caps(struct hda_codec *codec)
873{
874 struct ca0132_spec *spec = codec->spec;
875 struct auto_pin_cfg *cfg = &spec->autocfg;
876 unsigned int caps;
877
878 /* set mute-capable, 1db step, 32 steps, ofs 6 */
879 caps = 0x80031f06;
880 snd_hda_override_amp_caps(codec, cfg->hp_pins[0], HDA_OUTPUT, caps);
881}
882
883static int ca0132_build_controls(struct hda_codec *codec)
884{
885 struct ca0132_spec *spec = codec->spec;
886 struct auto_pin_cfg *cfg = &spec->autocfg;
887 int i, err;
888
889 if (spec->multiout.num_dacs) {
890 err = add_speaker_switch(codec, spec->out_pins[0]);
891 if (err < 0)
892 return err;
893 }
894
895 if (cfg->hp_outs) {
896 ca0132_fix_hp_caps(codec);
897 err = add_hp_switch(codec, cfg->hp_pins[0]);
898 if (err < 0)
899 return err;
900 err = add_hp_volume(codec, cfg->hp_pins[0]);
901 if (err < 0)
902 return err;
903 }
904
905 for (i = 0; i < spec->num_inputs; i++) {
906 const char *label = spec->input_labels[i];
907
908 err = add_in_switch(codec, spec->adcs[i], label);
909 if (err < 0)
910 return err;
911 err = add_in_volume(codec, spec->adcs[i], label);
912 if (err < 0)
913 return err;
914 if (cfg->inputs[i].type == AUTO_PIN_MIC) {
915 /* add Mic-Boost */
916 err = add_in_mono_volume(codec, spec->input_pins[i],
917 "Mic Boost", 1);
918 if (err < 0)
919 return err;
920 }
921 }
922
923 if (spec->dig_out) {
924 err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out,
925 spec->dig_out);
926 if (err < 0)
927 return err;
928 err = add_out_volume(codec, spec->dig_out, "IEC958");
929 if (err < 0)
930 return err;
931 }
932
933 if (spec->dig_in) {
934 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
935 if (err < 0)
936 return err;
937 err = add_in_volume(codec, spec->dig_in, "IEC958");
938 }
939 return 0;
940}
941
942
943static void ca0132_set_ct_ext(struct hda_codec *codec, int enable)
944{
945 /* Set Creative extension */
946 snd_printdd("SET CREATIVE EXTENSION\n");
947 snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
948 VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE,
949 enable);
950 msleep(20);
951}
952
953
954static void ca0132_config(struct hda_codec *codec)
955{
956 struct ca0132_spec *spec = codec->spec;
957 struct auto_pin_cfg *cfg = &spec->autocfg;
958
959 /* line-outs */
960 cfg->line_outs = 1;
961 cfg->line_out_pins[0] = 0x0b; /* front */
962 cfg->line_out_type = AUTO_PIN_LINE_OUT;
963
964 spec->dacs[0] = 0x02;
965 spec->out_pins[0] = 0x0b;
966 spec->multiout.dac_nids = spec->dacs;
967 spec->multiout.num_dacs = 1;
968 spec->multiout.max_channels = 2;
969
970 /* headphone */
971 cfg->hp_outs = 1;
972 cfg->hp_pins[0] = 0x0f;
973
974 spec->hp_dac = 0;
975 spec->multiout.hp_nid = 0;
976
977 /* inputs */
978 cfg->num_inputs = 2; /* Mic-in and line-in */
979 cfg->inputs[0].pin = 0x12;
980 cfg->inputs[0].type = AUTO_PIN_MIC;
981 cfg->inputs[1].pin = 0x11;
982 cfg->inputs[1].type = AUTO_PIN_LINE_IN;
983
984 /* Mic-in */
985 spec->input_pins[0] = 0x12;
986 spec->input_labels[0] = "Mic-In";
987 spec->adcs[0] = 0x07;
988
989 /* Line-In */
990 spec->input_pins[1] = 0x11;
991 spec->input_labels[1] = "Line-In";
992 spec->adcs[1] = 0x08;
993 spec->num_inputs = 2;
994}
995
996static void ca0132_init_chip(struct hda_codec *codec)
997{
998 struct ca0132_spec *spec = codec->spec;
999
1000 mutex_init(&spec->chipio_mutex);
1001}
1002
1003static void ca0132_exit_chip(struct hda_codec *codec)
1004{
1005 /* put any chip cleanup stuffs here. */
1006}
1007
1008static int ca0132_init(struct hda_codec *codec)
1009{
1010 struct ca0132_spec *spec = codec->spec;
1011 struct auto_pin_cfg *cfg = &spec->autocfg;
1012 int i;
1013
1014 for (i = 0; i < spec->multiout.num_dacs; i++) {
1015 init_output(codec, spec->out_pins[i],
1016 spec->multiout.dac_nids[i]);
1017 }
1018 init_output(codec, cfg->hp_pins[0], spec->hp_dac);
1019 init_output(codec, cfg->dig_out_pins[0], spec->dig_out);
1020
1021 for (i = 0; i < spec->num_inputs; i++)
1022 init_input(codec, spec->input_pins[i], spec->adcs[i]);
1023
1024 init_input(codec, cfg->dig_in_pin, spec->dig_in);
1025
1026 ca0132_set_ct_ext(codec, 1);
1027
1028 return 0;
1029}
1030
1031
1032static void ca0132_free(struct hda_codec *codec)
1033{
1034 ca0132_set_ct_ext(codec, 0);
1035 ca0132_exit_chip(codec);
1036 kfree(codec->spec);
1037}
1038
1039static struct hda_codec_ops ca0132_patch_ops = {
1040 .build_controls = ca0132_build_controls,
1041 .build_pcms = ca0132_build_pcms,
1042 .init = ca0132_init,
1043 .free = ca0132_free,
1044};
1045
1046
1047
1048static int patch_ca0132(struct hda_codec *codec)
1049{
1050 struct ca0132_spec *spec;
1051
1052 snd_printdd("patch_ca0132\n");
1053
1054 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1055 if (!spec)
1056 return -ENOMEM;
1057 codec->spec = spec;
1058
1059 ca0132_init_chip(codec);
1060
1061 ca0132_config(codec);
1062
1063 codec->patch_ops = ca0132_patch_ops;
1064
1065 return 0;
1066}
1067
1068/*
1069 * patch entries
1070 */
1071static struct hda_codec_preset snd_hda_preset_ca0132[] = {
1072 { .id = 0x11020011, .name = "CA0132", .patch = patch_ca0132 },
1073 {} /* terminator */
1074};
1075
1076MODULE_ALIAS("snd-hda-codec-id:11020011");
1077
1078MODULE_LICENSE("GPL");
1079MODULE_DESCRIPTION("Creative CA0132, CA0132 HD-audio codec");
1080
1081static struct hda_codec_preset_list ca0132_list = {
1082 .preset = snd_hda_preset_ca0132,
1083 .owner = THIS_MODULE,
1084};
1085
1086static int __init patch_ca0132_init(void)
1087{
1088 return snd_hda_add_codec_preset(&ca0132_list);
1089}
1090
1091static void __exit patch_ca0132_exit(void)
1092{
1093 snd_hda_delete_codec_preset(&ca0132_list);
1094}
1095
1096module_init(patch_ca0132_init)
1097module_exit(patch_ca0132_exit)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 26a1521045b..47d6ffc9b5b 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -25,6 +25,7 @@
25#include <sound/core.h> 25#include <sound/core.h>
26#include "hda_codec.h" 26#include "hda_codec.h"
27#include "hda_local.h" 27#include "hda_local.h"
28#include <sound/tlv.h>
28 29
29/* 30/*
30 */ 31 */
@@ -61,9 +62,15 @@ struct cs_spec {
61 62
62 unsigned int hp_detect:1; 63 unsigned int hp_detect:1;
63 unsigned int mic_detect:1; 64 unsigned int mic_detect:1;
65 /* CS421x */
66 unsigned int spdif_detect:1;
67 unsigned int sense_b:1;
68 hda_nid_t vendor_nid;
69 struct hda_input_mux input_mux;
70 unsigned int last_input;
64}; 71};
65 72
66/* available models */ 73/* available models with CS420x */
67enum { 74enum {
68 CS420X_MBP53, 75 CS420X_MBP53,
69 CS420X_MBP55, 76 CS420X_MBP55,
@@ -72,6 +79,12 @@ enum {
72 CS420X_MODELS 79 CS420X_MODELS
73}; 80};
74 81
82/* CS421x boards */
83enum {
84 CS421X_CDB4210,
85 CS421X_MODELS
86};
87
75/* Vendor-specific processing widget */ 88/* Vendor-specific processing widget */
76#define CS420X_VENDOR_NID 0x11 89#define CS420X_VENDOR_NID 0x11
77#define CS_DIG_OUT1_PIN_NID 0x10 90#define CS_DIG_OUT1_PIN_NID 0x10
@@ -111,21 +124,42 @@ enum {
111/* 0x0009 - 0x0014 -> 12 test regs */ 124/* 0x0009 - 0x0014 -> 12 test regs */
112/* 0x0015 - visibility reg */ 125/* 0x0015 - visibility reg */
113 126
127/*
128 * Cirrus Logic CS4210
129 *
130 * 1 DAC => HP(sense) / Speakers,
131 * 1 ADC <= LineIn(sense) / MicIn / DMicIn,
132 * 1 SPDIF OUT => SPDIF Trasmitter(sense)
133*/
134#define CS4210_DAC_NID 0x02
135#define CS4210_ADC_NID 0x03
136#define CS421X_VENDOR_NID 0x0B
137#define CS421X_DMIC_PIN_NID 0x09 /* Port E */
138#define CS421X_SPDIF_PIN_NID 0x0A /* Port H */
139
140#define CS421X_IDX_DEV_CFG 0x01
141#define CS421X_IDX_ADC_CFG 0x02
142#define CS421X_IDX_DAC_CFG 0x03
143#define CS421X_IDX_SPK_CTL 0x04
144
145#define SPDIF_EVENT 0x04
114 146
115static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx) 147static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
116{ 148{
117 snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, 149 struct cs_spec *spec = codec->spec;
150 snd_hda_codec_write(codec, spec->vendor_nid, 0,
118 AC_VERB_SET_COEF_INDEX, idx); 151 AC_VERB_SET_COEF_INDEX, idx);
119 return snd_hda_codec_read(codec, CS420X_VENDOR_NID, 0, 152 return snd_hda_codec_read(codec, spec->vendor_nid, 0,
120 AC_VERB_GET_PROC_COEF, 0); 153 AC_VERB_GET_PROC_COEF, 0);
121} 154}
122 155
123static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx, 156static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx,
124 unsigned int coef) 157 unsigned int coef)
125{ 158{
126 snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, 159 struct cs_spec *spec = codec->spec;
160 snd_hda_codec_write(codec, spec->vendor_nid, 0,
127 AC_VERB_SET_COEF_INDEX, idx); 161 AC_VERB_SET_COEF_INDEX, idx);
128 snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, 162 snd_hda_codec_write(codec, spec->vendor_nid, 0,
129 AC_VERB_SET_PROC_COEF, coef); 163 AC_VERB_SET_PROC_COEF, coef);
130} 164}
131 165
@@ -346,22 +380,13 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
346 380
347 nid = codec->start_nid; 381 nid = codec->start_nid;
348 for (i = 0; i < codec->num_nodes; i++, nid++) { 382 for (i = 0; i < codec->num_nodes; i++, nid++) {
349 hda_nid_t pins[2];
350 unsigned int type; 383 unsigned int type;
351 int j, nums;
352 type = get_wcaps_type(get_wcaps(codec, nid)); 384 type = get_wcaps_type(get_wcaps(codec, nid));
353 if (type != AC_WID_AUD_IN) 385 if (type != AC_WID_AUD_IN)
354 continue; 386 continue;
355 nums = snd_hda_get_connections(codec, nid, pins, 387 *idxp = snd_hda_get_conn_index(codec, nid, pin, false);
356 ARRAY_SIZE(pins)); 388 if (*idxp >= 0)
357 if (nums <= 0) 389 return nid;
358 continue;
359 for (j = 0; j < nums; j++) {
360 if (pins[j] == pin) {
361 *idxp = j;
362 return nid;
363 }
364 }
365 } 390 }
366 return 0; 391 return 0;
367} 392}
@@ -821,7 +846,8 @@ static int build_digital_output(struct hda_codec *codec)
821 if (!spec->multiout.dig_out_nid) 846 if (!spec->multiout.dig_out_nid)
822 return 0; 847 return 0;
823 848
824 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 849 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid,
850 spec->multiout.dig_out_nid);
825 if (err < 0) 851 if (err < 0)
826 return err; 852 return err;
827 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); 853 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
@@ -840,6 +866,8 @@ static int build_digital_input(struct hda_codec *codec)
840 866
841/* 867/*
842 * auto-mute and auto-mic switching 868 * auto-mute and auto-mic switching
869 * CS421x auto-output redirecting
870 * HP/SPK/SPDIF
843 */ 871 */
844 872
845static void cs_automute(struct hda_codec *codec) 873static void cs_automute(struct hda_codec *codec)
@@ -847,9 +875,25 @@ static void cs_automute(struct hda_codec *codec)
847 struct cs_spec *spec = codec->spec; 875 struct cs_spec *spec = codec->spec;
848 struct auto_pin_cfg *cfg = &spec->autocfg; 876 struct auto_pin_cfg *cfg = &spec->autocfg;
849 unsigned int hp_present; 877 unsigned int hp_present;
878 unsigned int spdif_present;
850 hda_nid_t nid; 879 hda_nid_t nid;
851 int i; 880 int i;
852 881
882 spdif_present = 0;
883 if (cfg->dig_outs) {
884 nid = cfg->dig_out_pins[0];
885 if (is_jack_detectable(codec, nid)) {
886 /*
887 TODO: SPDIF output redirect when SENSE_B is enabled.
888 Shared (SENSE_A) jack (e.g HP/mini-TOSLINK)
889 assumed.
890 */
891 if (snd_hda_jack_detect(codec, nid)
892 /* && spec->sense_b */)
893 spdif_present = 1;
894 }
895 }
896
853 hp_present = 0; 897 hp_present = 0;
854 for (i = 0; i < cfg->hp_outs; i++) { 898 for (i = 0; i < cfg->hp_outs; i++) {
855 nid = cfg->hp_pins[i]; 899 nid = cfg->hp_pins[i];
@@ -859,11 +903,19 @@ static void cs_automute(struct hda_codec *codec)
859 if (hp_present) 903 if (hp_present)
860 break; 904 break;
861 } 905 }
906
907 /* mute speakers if spdif or hp jack is plugged in */
862 for (i = 0; i < cfg->speaker_outs; i++) { 908 for (i = 0; i < cfg->speaker_outs; i++) {
863 nid = cfg->speaker_pins[i]; 909 nid = cfg->speaker_pins[i];
864 snd_hda_codec_write(codec, nid, 0, 910 snd_hda_codec_write(codec, nid, 0,
865 AC_VERB_SET_PIN_WIDGET_CONTROL, 911 AC_VERB_SET_PIN_WIDGET_CONTROL,
866 hp_present ? 0 : PIN_OUT); 912 hp_present ? 0 : PIN_OUT);
913 /* detect on spdif is specific to CS421x */
914 if (spec->vendor_nid == CS421X_VENDOR_NID) {
915 snd_hda_codec_write(codec, nid, 0,
916 AC_VERB_SET_PIN_WIDGET_CONTROL,
917 spdif_present ? 0 : PIN_OUT);
918 }
867 } 919 }
868 if (spec->board_config == CS420X_MBP53 || 920 if (spec->board_config == CS420X_MBP53 ||
869 spec->board_config == CS420X_MBP55 || 921 spec->board_config == CS420X_MBP55 ||
@@ -872,21 +924,62 @@ static void cs_automute(struct hda_codec *codec)
872 snd_hda_codec_write(codec, 0x01, 0, 924 snd_hda_codec_write(codec, 0x01, 0,
873 AC_VERB_SET_GPIO_DATA, gpio); 925 AC_VERB_SET_GPIO_DATA, gpio);
874 } 926 }
927
928 /* specific to CS421x */
929 if (spec->vendor_nid == CS421X_VENDOR_NID) {
930 /* mute HPs if spdif jack (SENSE_B) is present */
931 for (i = 0; i < cfg->hp_outs; i++) {
932 nid = cfg->hp_pins[i];
933 snd_hda_codec_write(codec, nid, 0,
934 AC_VERB_SET_PIN_WIDGET_CONTROL,
935 (spdif_present && spec->sense_b) ? 0 : PIN_HP);
936 }
937
938 /* SPDIF TX on/off */
939 if (cfg->dig_outs) {
940 nid = cfg->dig_out_pins[0];
941 snd_hda_codec_write(codec, nid, 0,
942 AC_VERB_SET_PIN_WIDGET_CONTROL,
943 spdif_present ? PIN_OUT : 0);
944
945 }
946 /* Update board GPIOs if neccessary ... */
947 }
875} 948}
876 949
950/*
951 * Auto-input redirect for CS421x
952 * Switch max 3 inputs of a single ADC (nid 3)
953*/
954
877static void cs_automic(struct hda_codec *codec) 955static void cs_automic(struct hda_codec *codec)
878{ 956{
879 struct cs_spec *spec = codec->spec; 957 struct cs_spec *spec = codec->spec;
880 struct auto_pin_cfg *cfg = &spec->autocfg; 958 struct auto_pin_cfg *cfg = &spec->autocfg;
881 hda_nid_t nid; 959 hda_nid_t nid;
882 unsigned int present; 960 unsigned int present;
883 961
884 nid = cfg->inputs[spec->automic_idx].pin; 962 nid = cfg->inputs[spec->automic_idx].pin;
885 present = snd_hda_jack_detect(codec, nid); 963 present = snd_hda_jack_detect(codec, nid);
886 if (present) 964
887 change_cur_input(codec, spec->automic_idx, 0); 965 /* specific to CS421x, single ADC */
888 else 966 if (spec->vendor_nid == CS421X_VENDOR_NID) {
889 change_cur_input(codec, !spec->automic_idx, 0); 967 if (present) {
968 spec->last_input = spec->cur_input;
969 spec->cur_input = spec->automic_idx;
970 } else {
971 spec->cur_input = spec->last_input;
972 }
973
974 snd_hda_codec_write_cache(codec, spec->cur_adc, 0,
975 AC_VERB_SET_CONNECT_SEL,
976 spec->adc_idx[spec->cur_input]);
977 } else {
978 if (present)
979 change_cur_input(codec, spec->automic_idx, 0);
980 else
981 change_cur_input(codec, !spec->automic_idx, 0);
982 }
890} 983}
891 984
892/* 985/*
@@ -916,23 +1009,28 @@ static void init_output(struct hda_codec *codec)
916 for (i = 0; i < cfg->line_outs; i++) 1009 for (i = 0; i < cfg->line_outs; i++)
917 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, 1010 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
918 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 1011 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1012 /* HP */
919 for (i = 0; i < cfg->hp_outs; i++) { 1013 for (i = 0; i < cfg->hp_outs; i++) {
920 hda_nid_t nid = cfg->hp_pins[i]; 1014 hda_nid_t nid = cfg->hp_pins[i];
921 snd_hda_codec_write(codec, nid, 0, 1015 snd_hda_codec_write(codec, nid, 0,
922 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); 1016 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
923 if (!cfg->speaker_outs) 1017 if (!cfg->speaker_outs)
924 continue; 1018 continue;
925 if (is_jack_detectable(codec, nid)) { 1019 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
926 snd_hda_codec_write(codec, nid, 0, 1020 snd_hda_codec_write(codec, nid, 0,
927 AC_VERB_SET_UNSOLICITED_ENABLE, 1021 AC_VERB_SET_UNSOLICITED_ENABLE,
928 AC_USRSP_EN | HP_EVENT); 1022 AC_USRSP_EN | HP_EVENT);
929 spec->hp_detect = 1; 1023 spec->hp_detect = 1;
930 } 1024 }
931 } 1025 }
1026
1027 /* Speaker */
932 for (i = 0; i < cfg->speaker_outs; i++) 1028 for (i = 0; i < cfg->speaker_outs; i++)
933 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, 1029 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
934 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 1030 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
935 if (spec->hp_detect) 1031
1032 /* SPDIF is enabled on presence detect for CS421x */
1033 if (spec->hp_detect || spec->spdif_detect)
936 cs_automute(codec); 1034 cs_automute(codec);
937} 1035}
938 1036
@@ -966,19 +1064,31 @@ static void init_input(struct hda_codec *codec)
966 AC_VERB_SET_UNSOLICITED_ENABLE, 1064 AC_VERB_SET_UNSOLICITED_ENABLE,
967 AC_USRSP_EN | MIC_EVENT); 1065 AC_USRSP_EN | MIC_EVENT);
968 } 1066 }
969 change_cur_input(codec, spec->cur_input, 1); 1067 /* specific to CS421x */
970 if (spec->mic_detect) 1068 if (spec->vendor_nid == CS421X_VENDOR_NID) {
971 cs_automic(codec); 1069 if (spec->mic_detect)
972 1070 cs_automic(codec);
973 coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ 1071 else {
974 if (is_active_pin(codec, CS_DMIC2_PIN_NID)) 1072 spec->cur_adc = spec->adc_nid[spec->cur_input];
975 coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */ 1073 snd_hda_codec_write(codec, spec->cur_adc, 0,
976 if (is_active_pin(codec, CS_DMIC1_PIN_NID)) 1074 AC_VERB_SET_CONNECT_SEL,
977 coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0 1075 spec->adc_idx[spec->cur_input]);
978 * No effect if SPDIF_OUT2 is selected in 1076 }
979 * IDX_SPDIF_CTL. 1077 } else {
980 */ 1078 change_cur_input(codec, spec->cur_input, 1);
981 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); 1079 if (spec->mic_detect)
1080 cs_automic(codec);
1081
1082 coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
1083 if (is_active_pin(codec, CS_DMIC2_PIN_NID))
1084 coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */
1085 if (is_active_pin(codec, CS_DMIC1_PIN_NID))
1086 coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off
1087 * No effect if SPDIF_OUT2 is
1088 * selected in IDX_SPDIF_CTL.
1089 */
1090 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
1091 }
982} 1092}
983 1093
984static const struct hda_verb cs_coef_init_verbs[] = { 1094static const struct hda_verb cs_coef_init_verbs[] = {
@@ -1226,16 +1336,16 @@ static const struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = {
1226 [CS420X_IMAC27] = imac27_pincfgs, 1336 [CS420X_IMAC27] = imac27_pincfgs,
1227}; 1337};
1228 1338
1229static void fix_pincfg(struct hda_codec *codec, int model) 1339static void fix_pincfg(struct hda_codec *codec, int model,
1340 const struct cs_pincfg **pin_configs)
1230{ 1341{
1231 const struct cs_pincfg *cfg = cs_pincfgs[model]; 1342 const struct cs_pincfg *cfg = pin_configs[model];
1232 if (!cfg) 1343 if (!cfg)
1233 return; 1344 return;
1234 for (; cfg->nid; cfg++) 1345 for (; cfg->nid; cfg++)
1235 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1346 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1236} 1347}
1237 1348
1238
1239static int patch_cs420x(struct hda_codec *codec) 1349static int patch_cs420x(struct hda_codec *codec)
1240{ 1350{
1241 struct cs_spec *spec; 1351 struct cs_spec *spec;
@@ -1246,11 +1356,13 @@ static int patch_cs420x(struct hda_codec *codec)
1246 return -ENOMEM; 1356 return -ENOMEM;
1247 codec->spec = spec; 1357 codec->spec = spec;
1248 1358
1359 spec->vendor_nid = CS420X_VENDOR_NID;
1360
1249 spec->board_config = 1361 spec->board_config =
1250 snd_hda_check_board_config(codec, CS420X_MODELS, 1362 snd_hda_check_board_config(codec, CS420X_MODELS,
1251 cs420x_models, cs420x_cfg_tbl); 1363 cs420x_models, cs420x_cfg_tbl);
1252 if (spec->board_config >= 0) 1364 if (spec->board_config >= 0)
1253 fix_pincfg(codec, spec->board_config); 1365 fix_pincfg(codec, spec->board_config, cs_pincfgs);
1254 1366
1255 switch (spec->board_config) { 1367 switch (spec->board_config) {
1256 case CS420X_IMAC27: 1368 case CS420X_IMAC27:
@@ -1277,6 +1389,562 @@ static int patch_cs420x(struct hda_codec *codec)
1277 return err; 1389 return err;
1278} 1390}
1279 1391
1392/*
1393 * Cirrus Logic CS4210
1394 *
1395 * 1 DAC => HP(sense) / Speakers,
1396 * 1 ADC <= LineIn(sense) / MicIn / DMicIn,
1397 * 1 SPDIF OUT => SPDIF Trasmitter(sense)
1398*/
1399
1400/* CS4210 board names */
1401static const char *cs421x_models[CS421X_MODELS] = {
1402 [CS421X_CDB4210] = "cdb4210",
1403};
1404
1405static const struct snd_pci_quirk cs421x_cfg_tbl[] = {
1406 /* Test Intel board + CDB2410 */
1407 SND_PCI_QUIRK(0x8086, 0x5001, "DP45SG/CDB4210", CS421X_CDB4210),
1408 {} /* terminator */
1409};
1410
1411/* CS4210 board pinconfigs */
1412/* Default CS4210 (CDB4210)*/
1413static const struct cs_pincfg cdb4210_pincfgs[] = {
1414 { 0x05, 0x0321401f },
1415 { 0x06, 0x90170010 },
1416 { 0x07, 0x03813031 },
1417 { 0x08, 0xb7a70037 },
1418 { 0x09, 0xb7a6003e },
1419 { 0x0a, 0x034510f0 },
1420 {} /* terminator */
1421};
1422
1423static const struct cs_pincfg *cs421x_pincfgs[CS421X_MODELS] = {
1424 [CS421X_CDB4210] = cdb4210_pincfgs,
1425};
1426
1427static const struct hda_verb cs421x_coef_init_verbs[] = {
1428 {0x0B, AC_VERB_SET_PROC_STATE, 1},
1429 {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DEV_CFG},
1430 /*
1431 Disable Coefficient Index Auto-Increment(DAI)=1,
1432 PDREF=0
1433 */
1434 {0x0B, AC_VERB_SET_PROC_COEF, 0x0001 },
1435
1436 {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_ADC_CFG},
1437 /* ADC SZCMode = Digital Soft Ramp */
1438 {0x0B, AC_VERB_SET_PROC_COEF, 0x0002 },
1439
1440 {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DAC_CFG},
1441 {0x0B, AC_VERB_SET_PROC_COEF,
1442 (0x0002 /* DAC SZCMode = Digital Soft Ramp */
1443 | 0x0004 /* Mute DAC on FIFO error */
1444 | 0x0008 /* Enable DAC High Pass Filter */
1445 )},
1446 {} /* terminator */
1447};
1448
1449/* Errata: CS4210 rev A1 Silicon
1450 *
1451 * http://www.cirrus.com/en/pubs/errata/
1452 *
1453 * Description:
1454 * 1. Performance degredation is present in the ADC.
1455 * 2. Speaker output is not completely muted upon HP detect.
1456 * 3. Noise is present when clipping occurs on the amplified
1457 * speaker outputs.
1458 *
1459 * Workaround:
1460 * The following verb sequence written to the registers during
1461 * initialization will correct the issues listed above.
1462 */
1463
1464static const struct hda_verb cs421x_coef_init_verbs_A1_silicon_fixes[] = {
1465 {0x0B, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */
1466
1467 {0x0B, AC_VERB_SET_COEF_INDEX, 0x0006},
1468 {0x0B, AC_VERB_SET_PROC_COEF, 0x9999}, /* Test mode: on */
1469
1470 {0x0B, AC_VERB_SET_COEF_INDEX, 0x000A},
1471 {0x0B, AC_VERB_SET_PROC_COEF, 0x14CB}, /* Chop double */
1472
1473 {0x0B, AC_VERB_SET_COEF_INDEX, 0x0011},
1474 {0x0B, AC_VERB_SET_PROC_COEF, 0xA2D0}, /* Increase ADC current */
1475
1476 {0x0B, AC_VERB_SET_COEF_INDEX, 0x001A},
1477 {0x0B, AC_VERB_SET_PROC_COEF, 0x02A9}, /* Mute speaker */
1478
1479 {0x0B, AC_VERB_SET_COEF_INDEX, 0x001B},
1480 {0x0B, AC_VERB_SET_PROC_COEF, 0X1006}, /* Remove noise */
1481
1482 {} /* terminator */
1483};
1484
1485/* Speaker Amp Gain is controlled by the vendor widget's coef 4 */
1486static const DECLARE_TLV_DB_SCALE(cs421x_speaker_boost_db_scale, 900, 300, 0);
1487
1488static int cs421x_boost_vol_info(struct snd_kcontrol *kcontrol,
1489 struct snd_ctl_elem_info *uinfo)
1490{
1491 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1492 uinfo->count = 1;
1493 uinfo->value.integer.min = 0;
1494 uinfo->value.integer.max = 3;
1495 return 0;
1496}
1497
1498static int cs421x_boost_vol_get(struct snd_kcontrol *kcontrol,
1499 struct snd_ctl_elem_value *ucontrol)
1500{
1501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1502
1503 ucontrol->value.integer.value[0] =
1504 cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL) & 0x0003;
1505 return 0;
1506}
1507
1508static int cs421x_boost_vol_put(struct snd_kcontrol *kcontrol,
1509 struct snd_ctl_elem_value *ucontrol)
1510{
1511 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1512
1513 unsigned int vol = ucontrol->value.integer.value[0];
1514 unsigned int coef =
1515 cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL);
1516 unsigned int original_coef = coef;
1517
1518 coef &= ~0x0003;
1519 coef |= (vol & 0x0003);
1520 if (original_coef == coef)
1521 return 0;
1522 else {
1523 cs_vendor_coef_set(codec, CS421X_IDX_SPK_CTL, coef);
1524 return 1;
1525 }
1526}
1527
1528static const struct snd_kcontrol_new cs421x_speaker_bost_ctl = {
1529
1530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1531 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1532 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1533 .name = "Speaker Boost Playback Volume",
1534 .info = cs421x_boost_vol_info,
1535 .get = cs421x_boost_vol_get,
1536 .put = cs421x_boost_vol_put,
1537 .tlv = { .p = cs421x_speaker_boost_db_scale },
1538};
1539
1540static void cs421x_pinmux_init(struct hda_codec *codec)
1541{
1542 struct cs_spec *spec = codec->spec;
1543 unsigned int def_conf, coef;
1544
1545 /* GPIO, DMIC_SCL, DMIC_SDA and SENSE_B are multiplexed */
1546 coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
1547
1548 if (spec->gpio_mask)
1549 coef |= 0x0008; /* B1,B2 are GPIOs */
1550 else
1551 coef &= ~0x0008;
1552
1553 if (spec->sense_b)
1554 coef |= 0x0010; /* B2 is SENSE_B, not inverted */
1555 else
1556 coef &= ~0x0010;
1557
1558 cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
1559
1560 if ((spec->gpio_mask || spec->sense_b) &&
1561 is_active_pin(codec, CS421X_DMIC_PIN_NID)) {
1562
1563 /*
1564 GPIO or SENSE_B forced - disconnect the DMIC pin.
1565 */
1566 def_conf = snd_hda_codec_get_pincfg(codec, CS421X_DMIC_PIN_NID);
1567 def_conf &= ~AC_DEFCFG_PORT_CONN;
1568 def_conf |= (AC_JACK_PORT_NONE << AC_DEFCFG_PORT_CONN_SHIFT);
1569 snd_hda_codec_set_pincfg(codec, CS421X_DMIC_PIN_NID, def_conf);
1570 }
1571}
1572
1573static void init_cs421x_digital(struct hda_codec *codec)
1574{
1575 struct cs_spec *spec = codec->spec;
1576 struct auto_pin_cfg *cfg = &spec->autocfg;
1577 int i;
1578
1579
1580 for (i = 0; i < cfg->dig_outs; i++) {
1581 hda_nid_t nid = cfg->dig_out_pins[i];
1582 if (!cfg->speaker_outs)
1583 continue;
1584 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
1585
1586 snd_hda_codec_write(codec, nid, 0,
1587 AC_VERB_SET_UNSOLICITED_ENABLE,
1588 AC_USRSP_EN | SPDIF_EVENT);
1589 spec->spdif_detect = 1;
1590 }
1591 }
1592}
1593
1594static int cs421x_init(struct hda_codec *codec)
1595{
1596 struct cs_spec *spec = codec->spec;
1597
1598 snd_hda_sequence_write(codec, cs421x_coef_init_verbs);
1599 snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes);
1600
1601 cs421x_pinmux_init(codec);
1602
1603 if (spec->gpio_mask) {
1604 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
1605 spec->gpio_mask);
1606 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
1607 spec->gpio_dir);
1608 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
1609 spec->gpio_data);
1610 }
1611
1612 init_output(codec);
1613 init_input(codec);
1614 init_cs421x_digital(codec);
1615
1616 return 0;
1617}
1618
1619/*
1620 * CS4210 Input MUX (1 ADC)
1621 */
1622static int cs421x_mux_enum_info(struct snd_kcontrol *kcontrol,
1623 struct snd_ctl_elem_info *uinfo)
1624{
1625 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1626 struct cs_spec *spec = codec->spec;
1627
1628 return snd_hda_input_mux_info(&spec->input_mux, uinfo);
1629}
1630
1631static int cs421x_mux_enum_get(struct snd_kcontrol *kcontrol,
1632 struct snd_ctl_elem_value *ucontrol)
1633{
1634 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1635 struct cs_spec *spec = codec->spec;
1636
1637 ucontrol->value.enumerated.item[0] = spec->cur_input;
1638 return 0;
1639}
1640
1641static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_value *ucontrol)
1643{
1644 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1645 struct cs_spec *spec = codec->spec;
1646
1647 return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol,
1648 spec->adc_nid[0], &spec->cur_input);
1649
1650}
1651
1652static struct snd_kcontrol_new cs421x_capture_source = {
1653
1654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1655 .name = "Capture Source",
1656 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1657 .info = cs421x_mux_enum_info,
1658 .get = cs421x_mux_enum_get,
1659 .put = cs421x_mux_enum_put,
1660};
1661
1662static int cs421x_add_input_volume_control(struct hda_codec *codec, int item)
1663{
1664 struct cs_spec *spec = codec->spec;
1665 struct auto_pin_cfg *cfg = &spec->autocfg;
1666 const struct hda_input_mux *imux = &spec->input_mux;
1667 hda_nid_t pin = cfg->inputs[item].pin;
1668 struct snd_kcontrol *kctl;
1669 u32 caps;
1670
1671 if (!(get_wcaps(codec, pin) & AC_WCAP_IN_AMP))
1672 return 0;
1673
1674 caps = query_amp_caps(codec, pin, HDA_INPUT);
1675 caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
1676 if (caps <= 1)
1677 return 0;
1678
1679 return add_volume(codec, imux->items[item].label, 0,
1680 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT), 1, &kctl);
1681}
1682
1683/* add a (input-boost) volume control to the given input pin */
1684static int build_cs421x_input(struct hda_codec *codec)
1685{
1686 struct cs_spec *spec = codec->spec;
1687 struct auto_pin_cfg *cfg = &spec->autocfg;
1688 struct hda_input_mux *imux = &spec->input_mux;
1689 int i, err, type_idx;
1690 const char *label;
1691
1692 if (!spec->num_inputs)
1693 return 0;
1694
1695 /* make bind-capture */
1696 spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw);
1697 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
1698 for (i = 0; i < 2; i++) {
1699 struct snd_kcontrol *kctl;
1700 int n;
1701 if (!spec->capture_bind[i])
1702 return -ENOMEM;
1703 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
1704 if (!kctl)
1705 return -ENOMEM;
1706 kctl->private_value = (long)spec->capture_bind[i];
1707 err = snd_hda_ctl_add(codec, 0, kctl);
1708 if (err < 0)
1709 return err;
1710 for (n = 0; n < AUTO_PIN_LAST; n++) {
1711 if (!spec->adc_nid[n])
1712 continue;
1713 err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]);
1714 if (err < 0)
1715 return err;
1716 }
1717 }
1718
1719 /* Add Input MUX Items + Capture Volume/Switch */
1720 for (i = 0; i < spec->num_inputs; i++) {
1721 label = hda_get_autocfg_input_label(codec, cfg, i);
1722 snd_hda_add_imux_item(imux, label, spec->adc_idx[i], &type_idx);
1723
1724 err = cs421x_add_input_volume_control(codec, i);
1725 if (err < 0)
1726 return err;
1727 }
1728
1729 /*
1730 Add 'Capture Source' Switch if
1731 * 2 inputs and no mic detec
1732 * 3 inputs
1733 */
1734 if ((spec->num_inputs == 2 && !spec->mic_detect) ||
1735 (spec->num_inputs == 3)) {
1736
1737 err = snd_hda_ctl_add(codec, spec->adc_nid[0],
1738 snd_ctl_new1(&cs421x_capture_source, codec));
1739 if (err < 0)
1740 return err;
1741 }
1742
1743 return 0;
1744}
1745
1746/* Single DAC (Mute/Gain) */
1747static int build_cs421x_output(struct hda_codec *codec)
1748{
1749 hda_nid_t dac = CS4210_DAC_NID;
1750 struct cs_spec *spec = codec->spec;
1751 struct auto_pin_cfg *cfg = &spec->autocfg;
1752 struct snd_kcontrol *kctl;
1753 int err;
1754 char *name = "HP/Speakers";
1755
1756 fix_volume_caps(codec, dac);
1757 if (!spec->vmaster_sw) {
1758 err = add_vmaster(codec, dac);
1759 if (err < 0)
1760 return err;
1761 }
1762
1763 err = add_mute(codec, name, 0,
1764 HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
1765 if (err < 0)
1766 return err;
1767 err = snd_ctl_add_slave(spec->vmaster_sw, kctl);
1768 if (err < 0)
1769 return err;
1770
1771 err = add_volume(codec, name, 0,
1772 HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
1773 if (err < 0)
1774 return err;
1775 err = snd_ctl_add_slave(spec->vmaster_vol, kctl);
1776 if (err < 0)
1777 return err;
1778
1779 if (cfg->speaker_outs) {
1780 err = snd_hda_ctl_add(codec, 0,
1781 snd_ctl_new1(&cs421x_speaker_bost_ctl, codec));
1782 if (err < 0)
1783 return err;
1784 }
1785 return err;
1786}
1787
1788static int cs421x_build_controls(struct hda_codec *codec)
1789{
1790 int err;
1791
1792 err = build_cs421x_output(codec);
1793 if (err < 0)
1794 return err;
1795 err = build_cs421x_input(codec);
1796 if (err < 0)
1797 return err;
1798 err = build_digital_output(codec);
1799 if (err < 0)
1800 return err;
1801 return cs421x_init(codec);
1802}
1803
1804static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res)
1805{
1806 switch ((res >> 26) & 0x3f) {
1807 case HP_EVENT:
1808 case SPDIF_EVENT:
1809 cs_automute(codec);
1810 break;
1811
1812 case MIC_EVENT:
1813 cs_automic(codec);
1814 break;
1815 }
1816}
1817
1818static int parse_cs421x_input(struct hda_codec *codec)
1819{
1820 struct cs_spec *spec = codec->spec;
1821 struct auto_pin_cfg *cfg = &spec->autocfg;
1822 int i;
1823
1824 for (i = 0; i < cfg->num_inputs; i++) {
1825 hda_nid_t pin = cfg->inputs[i].pin;
1826 spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]);
1827 spec->cur_input = spec->last_input = i;
1828 spec->num_inputs++;
1829
1830 /* check whether the automatic mic switch is available */
1831 if (is_ext_mic(codec, i) && cfg->num_inputs >= 2) {
1832 spec->mic_detect = 1;
1833 spec->automic_idx = i;
1834 }
1835 }
1836 return 0;
1837}
1838
1839static int cs421x_parse_auto_config(struct hda_codec *codec)
1840{
1841 struct cs_spec *spec = codec->spec;
1842 int err;
1843
1844 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1845 if (err < 0)
1846 return err;
1847 err = parse_output(codec);
1848 if (err < 0)
1849 return err;
1850 err = parse_cs421x_input(codec);
1851 if (err < 0)
1852 return err;
1853 err = parse_digital_output(codec);
1854 if (err < 0)
1855 return err;
1856 return 0;
1857}
1858
1859#ifdef CONFIG_PM
1860/*
1861 Manage PDREF, when transitioning to D3hot
1862 (DAC,ADC) -> D3, PDREF=1, AFG->D3
1863*/
1864static int cs421x_suspend(struct hda_codec *codec, pm_message_t state)
1865{
1866 unsigned int coef;
1867
1868 snd_hda_shutup_pins(codec);
1869
1870 snd_hda_codec_write(codec, CS4210_DAC_NID, 0,
1871 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1872 snd_hda_codec_write(codec, CS4210_ADC_NID, 0,
1873 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1874
1875 coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
1876 coef |= 0x0004; /* PDREF */
1877 cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
1878
1879 return 0;
1880}
1881#endif
1882
1883static struct hda_codec_ops cs4210_patch_ops = {
1884 .build_controls = cs421x_build_controls,
1885 .build_pcms = cs_build_pcms,
1886 .init = cs421x_init,
1887 .free = cs_free,
1888 .unsol_event = cs421x_unsol_event,
1889#ifdef CONFIG_PM
1890 .suspend = cs421x_suspend,
1891#endif
1892};
1893
1894static int patch_cs421x(struct hda_codec *codec)
1895{
1896 struct cs_spec *spec;
1897 int err;
1898
1899 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1900 if (!spec)
1901 return -ENOMEM;
1902 codec->spec = spec;
1903
1904 spec->vendor_nid = CS421X_VENDOR_NID;
1905
1906 spec->board_config =
1907 snd_hda_check_board_config(codec, CS421X_MODELS,
1908 cs421x_models, cs421x_cfg_tbl);
1909 if (spec->board_config >= 0)
1910 fix_pincfg(codec, spec->board_config, cs421x_pincfgs);
1911 /*
1912 Setup GPIO/SENSE for each board (if used)
1913 */
1914 switch (spec->board_config) {
1915 case CS421X_CDB4210:
1916 snd_printd("CS4210 board: %s\n",
1917 cs421x_models[spec->board_config]);
1918/* spec->gpio_mask = 3;
1919 spec->gpio_dir = 3;
1920 spec->gpio_data = 3;
1921*/
1922 spec->sense_b = 1;
1923
1924 break;
1925 }
1926
1927 /*
1928 Update the GPIO/DMIC/SENSE_B pinmux before the configuration
1929 is auto-parsed. If GPIO or SENSE_B is forced, DMIC input
1930 is disabled.
1931 */
1932 cs421x_pinmux_init(codec);
1933
1934 err = cs421x_parse_auto_config(codec);
1935 if (err < 0)
1936 goto error;
1937
1938 codec->patch_ops = cs4210_patch_ops;
1939
1940 return 0;
1941
1942 error:
1943 kfree(codec->spec);
1944 codec->spec = NULL;
1945 return err;
1946}
1947
1280 1948
1281/* 1949/*
1282 * patch entries 1950 * patch entries
@@ -1284,11 +1952,13 @@ static int patch_cs420x(struct hda_codec *codec)
1284static const struct hda_codec_preset snd_hda_preset_cirrus[] = { 1952static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
1285 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, 1953 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
1286 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, 1954 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
1955 { .id = 0x10134210, .name = "CS4210", .patch = patch_cs421x },
1287 {} /* terminator */ 1956 {} /* terminator */
1288}; 1957};
1289 1958
1290MODULE_ALIAS("snd-hda-codec-id:10134206"); 1959MODULE_ALIAS("snd-hda-codec-id:10134206");
1291MODULE_ALIAS("snd-hda-codec-id:10134207"); 1960MODULE_ALIAS("snd-hda-codec-id:10134207");
1961MODULE_ALIAS("snd-hda-codec-id:10134210");
1292 1962
1293MODULE_LICENSE("GPL"); 1963MODULE_LICENSE("GPL");
1294MODULE_DESCRIPTION("Cirrus Logic HD-audio codec"); 1964MODULE_DESCRIPTION("Cirrus Logic HD-audio codec");
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index ab3308daa96..cd2cf5e94e8 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -327,7 +327,9 @@ static int cmi9880_build_controls(struct hda_codec *codec)
327 return err; 327 return err;
328 } 328 }
329 if (spec->multiout.dig_out_nid) { 329 if (spec->multiout.dig_out_nid) {
330 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 330 err = snd_hda_create_spdif_out_ctls(codec,
331 spec->multiout.dig_out_nid,
332 spec->multiout.dig_out_nid);
331 if (err < 0) 333 if (err < 0)
332 return err; 334 return err;
333 err = snd_hda_create_spdif_share_sw(codec, 335 err = snd_hda_create_spdif_share_sw(codec,
@@ -396,12 +398,11 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pi
396{ 398{
397 struct cmi_spec *spec = codec->spec; 399 struct cmi_spec *spec = codec->spec;
398 hda_nid_t nid; 400 hda_nid_t nid;
399 int i, j, k, len; 401 int i, j, k;
400 402
401 /* clear the table, only one c-media dac assumed here */ 403 /* clear the table, only one c-media dac assumed here */
402 memset(spec->multi_init, 0, sizeof(spec->multi_init)); 404 memset(spec->multi_init, 0, sizeof(spec->multi_init));
403 for (j = 0, i = 0; i < cfg->line_outs; i++) { 405 for (j = 0, i = 0; i < cfg->line_outs; i++) {
404 hda_nid_t conn[4];
405 nid = cfg->line_out_pins[i]; 406 nid = cfg->line_out_pins[i];
406 /* set as output */ 407 /* set as output */
407 spec->multi_init[j].nid = nid; 408 spec->multi_init[j].nid = nid;
@@ -414,12 +415,10 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pi
414 spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL; 415 spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL;
415 spec->multi_init[j].param = 0; 416 spec->multi_init[j].param = 0;
416 /* find the index in connect list */ 417 /* find the index in connect list */
417 len = snd_hda_get_connections(codec, nid, conn, 4); 418 k = snd_hda_get_conn_index(codec, nid,
418 for (k = 0; k < len; k++) 419 spec->dac_nids[i], 0);
419 if (conn[k] == spec->dac_nids[i]) { 420 if (k >= 0)
420 spec->multi_init[j].param = k; 421 spec->multi_init[j].param = k;
421 break;
422 }
423 j++; 422 j++;
424 } 423 }
425 } 424 }
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 3e6b9a8539c..502fc949945 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -155,6 +155,10 @@ struct conexant_spec {
155 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ 155 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
156 156
157 unsigned int beep_amp; 157 unsigned int beep_amp;
158
159 /* extra EAPD pins */
160 unsigned int num_eapds;
161 hda_nid_t eapds[4];
158}; 162};
159 163
160static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 164static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -442,6 +446,19 @@ static int conexant_init_jacks(struct hda_codec *codec)
442 return 0; 446 return 0;
443} 447}
444 448
449static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg,
450 unsigned int power_state)
451{
452 if (power_state == AC_PWRST_D3)
453 msleep(100);
454 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
455 power_state);
456 /* partial workaround for "azx_get_response timeout" */
457 if (power_state == AC_PWRST_D0)
458 msleep(10);
459 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
460}
461
445static int conexant_init(struct hda_codec *codec) 462static int conexant_init(struct hda_codec *codec)
446{ 463{
447 struct conexant_spec *spec = codec->spec; 464 struct conexant_spec *spec = codec->spec;
@@ -510,6 +527,7 @@ static int conexant_build_controls(struct hda_codec *codec)
510 } 527 }
511 if (spec->multiout.dig_out_nid) { 528 if (spec->multiout.dig_out_nid) {
512 err = snd_hda_create_spdif_out_ctls(codec, 529 err = snd_hda_create_spdif_out_ctls(codec,
530 spec->multiout.dig_out_nid,
513 spec->multiout.dig_out_nid); 531 spec->multiout.dig_out_nid);
514 if (err < 0) 532 if (err < 0)
515 return err; 533 return err;
@@ -583,6 +601,7 @@ static const struct hda_codec_ops conexant_patch_ops = {
583 .build_pcms = conexant_build_pcms, 601 .build_pcms = conexant_build_pcms,
584 .init = conexant_init, 602 .init = conexant_init,
585 .free = conexant_free, 603 .free = conexant_free,
604 .set_power_state = conexant_set_power,
586#ifdef CONFIG_SND_HDA_POWER_SAVE 605#ifdef CONFIG_SND_HDA_POWER_SAVE
587 .suspend = conexant_suspend, 606 .suspend = conexant_suspend,
588#endif 607#endif
@@ -1123,10 +1142,8 @@ static int patch_cxt5045(struct hda_codec *codec)
1123 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, 1142 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1124 cxt5045_models, 1143 cxt5045_models,
1125 cxt5045_cfg_tbl); 1144 cxt5045_cfg_tbl);
1126#if 0 /* use the old method just for safety */
1127 if (board_config < 0) 1145 if (board_config < 0)
1128 board_config = CXT5045_AUTO; 1146 board_config = CXT5045_AUTO; /* model=auto as default */
1129#endif
1130 if (board_config == CXT5045_AUTO) 1147 if (board_config == CXT5045_AUTO)
1131 return patch_conexant_auto(codec); 1148 return patch_conexant_auto(codec);
1132 1149
@@ -1564,10 +1581,8 @@ static int patch_cxt5047(struct hda_codec *codec)
1564 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS, 1581 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1565 cxt5047_models, 1582 cxt5047_models,
1566 cxt5047_cfg_tbl); 1583 cxt5047_cfg_tbl);
1567#if 0 /* not enabled as default, as BIOS often broken for this codec */
1568 if (board_config < 0) 1584 if (board_config < 0)
1569 board_config = CXT5047_AUTO; 1585 board_config = CXT5047_AUTO; /* model=auto as default */
1570#endif
1571 if (board_config == CXT5047_AUTO) 1586 if (board_config == CXT5047_AUTO)
1572 return patch_conexant_auto(codec); 1587 return patch_conexant_auto(codec);
1573 1588
@@ -1993,10 +2008,8 @@ static int patch_cxt5051(struct hda_codec *codec)
1993 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, 2008 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1994 cxt5051_models, 2009 cxt5051_models,
1995 cxt5051_cfg_tbl); 2010 cxt5051_cfg_tbl);
1996#if 0 /* use the old method just for safety */
1997 if (board_config < 0) 2011 if (board_config < 0)
1998 board_config = CXT5051_AUTO; 2012 board_config = CXT5051_AUTO; /* model=auto as default */
1999#endif
2000 if (board_config == CXT5051_AUTO) 2013 if (board_config == CXT5051_AUTO)
2001 return patch_conexant_auto(codec); 2014 return patch_conexant_auto(codec);
2002 2015
@@ -3074,6 +3087,7 @@ static const char * const cxt5066_models[CXT5066_MODELS] = {
3074}; 3087};
3075 3088
3076static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { 3089static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3090 SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT5066_AUTO),
3077 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), 3091 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
3078 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), 3092 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
3079 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), 3093 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
@@ -3102,6 +3116,7 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3102 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), 3116 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
3103 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), 3117 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
3104 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ 3118 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
3119 SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
3105 {} 3120 {}
3106}; 3121};
3107 3122
@@ -3112,10 +3127,8 @@ static int patch_cxt5066(struct hda_codec *codec)
3112 3127
3113 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, 3128 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3114 cxt5066_models, cxt5066_cfg_tbl); 3129 cxt5066_models, cxt5066_cfg_tbl);
3115#if 0 /* use the old method just for safety */
3116 if (board_config < 0) 3130 if (board_config < 0)
3117 board_config = CXT5066_AUTO; 3131 board_config = CXT5066_AUTO; /* model=auto as default */
3118#endif
3119 if (board_config == CXT5066_AUTO) 3132 if (board_config == CXT5066_AUTO)
3120 return patch_conexant_auto(codec); 3133 return patch_conexant_auto(codec);
3121 3134
@@ -3306,19 +3319,8 @@ static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
3306 3319
3307static const hda_nid_t cx_auto_adc_nids[] = { 0x14 }; 3320static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
3308 3321
3309/* get the connection index of @nid in the widget @mux */ 3322#define get_connection_index(codec, mux, nid)\
3310static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3323 snd_hda_get_conn_index(codec, mux, nid, 0)
3311 hda_nid_t nid)
3312{
3313 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3314 int i, nums;
3315
3316 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3317 for (i = 0; i < nums; i++)
3318 if (conn[i] == nid)
3319 return i;
3320 return -1;
3321}
3322 3324
3323/* get an unassigned DAC from the given list. 3325/* get an unassigned DAC from the given list.
3324 * Return the nid if found and reduce the DAC list, or return zero if 3326 * Return the nid if found and reduce the DAC list, or return zero if
@@ -3917,6 +3919,38 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
3917#define cx_auto_parse_beep(codec) 3919#define cx_auto_parse_beep(codec)
3918#endif 3920#endif
3919 3921
3922static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
3923{
3924 int i;
3925 for (i = 0; i < nums; i++)
3926 if (list[i] == nid)
3927 return true;
3928 return false;
3929}
3930
3931/* parse extra-EAPD that aren't assigned to any pins */
3932static void cx_auto_parse_eapd(struct hda_codec *codec)
3933{
3934 struct conexant_spec *spec = codec->spec;
3935 struct auto_pin_cfg *cfg = &spec->autocfg;
3936 hda_nid_t nid, end_nid;
3937
3938 end_nid = codec->start_nid + codec->num_nodes;
3939 for (nid = codec->start_nid; nid < end_nid; nid++) {
3940 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
3941 continue;
3942 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
3943 continue;
3944 if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3945 found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3946 found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs))
3947 continue;
3948 spec->eapds[spec->num_eapds++] = nid;
3949 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
3950 break;
3951 }
3952}
3953
3920static int cx_auto_parse_auto_config(struct hda_codec *codec) 3954static int cx_auto_parse_auto_config(struct hda_codec *codec)
3921{ 3955{
3922 struct conexant_spec *spec = codec->spec; 3956 struct conexant_spec *spec = codec->spec;
@@ -3930,6 +3964,7 @@ static int cx_auto_parse_auto_config(struct hda_codec *codec)
3930 cx_auto_parse_input(codec); 3964 cx_auto_parse_input(codec);
3931 cx_auto_parse_digital(codec); 3965 cx_auto_parse_digital(codec);
3932 cx_auto_parse_beep(codec); 3966 cx_auto_parse_beep(codec);
3967 cx_auto_parse_eapd(codec);
3933 return 0; 3968 return 0;
3934} 3969}
3935 3970
@@ -4017,6 +4052,8 @@ static void cx_auto_init_output(struct hda_codec *codec)
4017 } 4052 }
4018 } 4053 }
4019 cx_auto_update_speakers(codec); 4054 cx_auto_update_speakers(codec);
4055 /* turn on/off extra EAPDs, too */
4056 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4020} 4057}
4021 4058
4022static void cx_auto_init_input(struct hda_codec *codec) 4059static void cx_auto_init_input(struct hda_codec *codec)
@@ -4388,6 +4425,8 @@ static const struct hda_codec_preset snd_hda_preset_conexant[] = {
4388 .patch = patch_cxt5066 }, 4425 .patch = patch_cxt5066 },
4389 { .id = 0x14f15069, .name = "CX20585", 4426 { .id = 0x14f15069, .name = "CX20585",
4390 .patch = patch_cxt5066 }, 4427 .patch = patch_cxt5066 },
4428 { .id = 0x14f1506c, .name = "CX20588",
4429 .patch = patch_cxt5066 },
4391 { .id = 0x14f1506e, .name = "CX20590", 4430 { .id = 0x14f1506e, .name = "CX20590",
4392 .patch = patch_cxt5066 }, 4431 .patch = patch_cxt5066 },
4393 { .id = 0x14f15097, .name = "CX20631", 4432 { .id = 0x14f15097, .name = "CX20631",
@@ -4416,6 +4455,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15066");
4416MODULE_ALIAS("snd-hda-codec-id:14f15067"); 4455MODULE_ALIAS("snd-hda-codec-id:14f15067");
4417MODULE_ALIAS("snd-hda-codec-id:14f15068"); 4456MODULE_ALIAS("snd-hda-codec-id:14f15068");
4418MODULE_ALIAS("snd-hda-codec-id:14f15069"); 4457MODULE_ALIAS("snd-hda-codec-id:14f15069");
4458MODULE_ALIAS("snd-hda-codec-id:14f1506c");
4419MODULE_ALIAS("snd-hda-codec-id:14f1506e"); 4459MODULE_ALIAS("snd-hda-codec-id:14f1506e");
4420MODULE_ALIAS("snd-hda-codec-id:14f15097"); 4460MODULE_ALIAS("snd-hda-codec-id:14f15097");
4421MODULE_ALIAS("snd-hda-codec-id:14f15098"); 4461MODULE_ALIAS("snd-hda-codec-id:14f15098");
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index bd0ae697f9c..19cb72db9c3 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -43,7 +43,7 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
43 43
44/* 44/*
45 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device 45 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
46 * could support two independent pipes, each of them can be connected to one or 46 * could support N independent pipes, each of them can be connected to one or
47 * more ports (DVI, HDMI or DisplayPort). 47 * more ports (DVI, HDMI or DisplayPort).
48 * 48 *
49 * The HDA correspondence of pipes/ports are converter/pin nodes. 49 * The HDA correspondence of pipes/ports are converter/pin nodes.
@@ -51,30 +51,33 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
51#define MAX_HDMI_CVTS 4 51#define MAX_HDMI_CVTS 4
52#define MAX_HDMI_PINS 4 52#define MAX_HDMI_PINS 4
53 53
54struct hdmi_spec { 54struct hdmi_spec_per_cvt {
55 int num_cvts; 55 hda_nid_t cvt_nid;
56 int num_pins; 56 int assigned;
57 hda_nid_t cvt[MAX_HDMI_CVTS+1]; /* audio sources */ 57 unsigned int channels_min;
58 hda_nid_t pin[MAX_HDMI_PINS+1]; /* audio sinks */ 58 unsigned int channels_max;
59 u32 rates;
60 u64 formats;
61 unsigned int maxbps;
62};
59 63
60 /* 64struct hdmi_spec_per_pin {
61 * source connection for each pin 65 hda_nid_t pin_nid;
62 */ 66 int num_mux_nids;
63 hda_nid_t pin_cvt[MAX_HDMI_PINS+1]; 67 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
68 struct hdmi_eld sink_eld;
69};
64 70
65 /* 71struct hdmi_spec {
66 * HDMI sink attached to each pin 72 int num_cvts;
67 */ 73 struct hdmi_spec_per_cvt cvts[MAX_HDMI_CVTS];
68 struct hdmi_eld sink_eld[MAX_HDMI_PINS];
69 74
70 /* 75 int num_pins;
71 * export one pcm per pipe 76 struct hdmi_spec_per_pin pins[MAX_HDMI_PINS];
72 */ 77 struct hda_pcm pcm_rec[MAX_HDMI_PINS];
73 struct hda_pcm pcm_rec[MAX_HDMI_CVTS];
74 struct hda_pcm_stream codec_pcm_pars[MAX_HDMI_CVTS];
75 78
76 /* 79 /*
77 * ati/nvhdmi specific 80 * Non-generic ATI/NVIDIA specific
78 */ 81 */
79 struct hda_multi_out multiout; 82 struct hda_multi_out multiout;
80 const struct hda_pcm_stream *pcm_playback; 83 const struct hda_pcm_stream *pcm_playback;
@@ -284,15 +287,40 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
284 * HDMI routines 287 * HDMI routines
285 */ 288 */
286 289
287static int hda_node_index(hda_nid_t *nids, hda_nid_t nid) 290static int pin_nid_to_pin_index(struct hdmi_spec *spec, hda_nid_t pin_nid)
288{ 291{
289 int i; 292 int pin_idx;
290 293
291 for (i = 0; nids[i]; i++) 294 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
292 if (nids[i] == nid) 295 if (spec->pins[pin_idx].pin_nid == pin_nid)
293 return i; 296 return pin_idx;
294 297
295 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid); 298 snd_printk(KERN_WARNING "HDMI: pin nid %d not registered\n", pin_nid);
299 return -EINVAL;
300}
301
302static int hinfo_to_pin_index(struct hdmi_spec *spec,
303 struct hda_pcm_stream *hinfo)
304{
305 int pin_idx;
306
307 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
308 if (&spec->pcm_rec[pin_idx].stream[0] == hinfo)
309 return pin_idx;
310
311 snd_printk(KERN_WARNING "HDMI: hinfo %p not registered\n", hinfo);
312 return -EINVAL;
313}
314
315static int cvt_nid_to_cvt_index(struct hdmi_spec *spec, hda_nid_t cvt_nid)
316{
317 int cvt_idx;
318
319 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++)
320 if (spec->cvts[cvt_idx].cvt_nid == cvt_nid)
321 return cvt_idx;
322
323 snd_printk(KERN_WARNING "HDMI: cvt nid %d not registered\n", cvt_nid);
296 return -EINVAL; 324 return -EINVAL;
297} 325}
298 326
@@ -326,28 +354,28 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
326 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val); 354 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
327} 355}
328 356
329static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid) 357static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid)
330{ 358{
331 /* Unmute */ 359 /* Unmute */
332 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP) 360 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
333 snd_hda_codec_write(codec, pin_nid, 0, 361 snd_hda_codec_write(codec, pin_nid, 0,
334 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 362 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
335 /* Enable pin out */ 363 /* Disable pin out until stream is active*/
336 snd_hda_codec_write(codec, pin_nid, 0, 364 snd_hda_codec_write(codec, pin_nid, 0,
337 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 365 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
338} 366}
339 367
340static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid) 368static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid)
341{ 369{
342 return 1 + snd_hda_codec_read(codec, nid, 0, 370 return 1 + snd_hda_codec_read(codec, cvt_nid, 0,
343 AC_VERB_GET_CVT_CHAN_COUNT, 0); 371 AC_VERB_GET_CVT_CHAN_COUNT, 0);
344} 372}
345 373
346static void hdmi_set_channel_count(struct hda_codec *codec, 374static void hdmi_set_channel_count(struct hda_codec *codec,
347 hda_nid_t nid, int chs) 375 hda_nid_t cvt_nid, int chs)
348{ 376{
349 if (chs != hdmi_get_channel_count(codec, nid)) 377 if (chs != hdmi_get_channel_count(codec, cvt_nid))
350 snd_hda_codec_write(codec, nid, 0, 378 snd_hda_codec_write(codec, cvt_nid, 0,
351 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); 379 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
352} 380}
353 381
@@ -384,11 +412,8 @@ static void init_channel_allocations(void)
384 * 412 *
385 * TODO: it could select the wrong CA from multiple candidates. 413 * TODO: it could select the wrong CA from multiple candidates.
386*/ 414*/
387static int hdmi_channel_allocation(struct hda_codec *codec, hda_nid_t nid, 415static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels)
388 int channels)
389{ 416{
390 struct hdmi_spec *spec = codec->spec;
391 struct hdmi_eld *eld;
392 int i; 417 int i;
393 int ca = 0; 418 int ca = 0;
394 int spk_mask = 0; 419 int spk_mask = 0;
@@ -400,19 +425,6 @@ static int hdmi_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
400 if (channels <= 2) 425 if (channels <= 2)
401 return 0; 426 return 0;
402 427
403 i = hda_node_index(spec->pin_cvt, nid);
404 if (i < 0)
405 return 0;
406 eld = &spec->sink_eld[i];
407
408 /*
409 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
410 * in console or for audio devices. Assume the highest speakers
411 * configuration, to _not_ prohibit multi-channel audio playback.
412 */
413 if (!eld->spk_alloc)
414 eld->spk_alloc = 0xffff;
415
416 /* 428 /*
417 * expand ELD's speaker allocation mask 429 * expand ELD's speaker allocation mask
418 * 430 *
@@ -608,67 +620,63 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
608 return true; 620 return true;
609} 621}
610 622
611static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, 623static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
612 struct snd_pcm_substream *substream) 624 struct snd_pcm_substream *substream)
613{ 625{
614 struct hdmi_spec *spec = codec->spec; 626 struct hdmi_spec *spec = codec->spec;
615 hda_nid_t pin_nid; 627 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
628 hda_nid_t pin_nid = per_pin->pin_nid;
616 int channels = substream->runtime->channels; 629 int channels = substream->runtime->channels;
630 struct hdmi_eld *eld;
617 int ca; 631 int ca;
618 int i;
619 union audio_infoframe ai; 632 union audio_infoframe ai;
620 633
621 ca = hdmi_channel_allocation(codec, nid, channels); 634 eld = &spec->pins[pin_idx].sink_eld;
622 635 if (!eld->monitor_present)
623 for (i = 0; i < spec->num_pins; i++) { 636 return;
624 if (spec->pin_cvt[i] != nid)
625 continue;
626 if (!spec->sink_eld[i].monitor_present)
627 continue;
628 637
629 pin_nid = spec->pin[i]; 638 ca = hdmi_channel_allocation(eld, channels);
630 639
631 memset(&ai, 0, sizeof(ai)); 640 memset(&ai, 0, sizeof(ai));
632 if (spec->sink_eld[i].conn_type == 0) { /* HDMI */ 641 if (eld->conn_type == 0) { /* HDMI */
633 struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi; 642 struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi;
634 643
635 hdmi_ai->type = 0x84; 644 hdmi_ai->type = 0x84;
636 hdmi_ai->ver = 0x01; 645 hdmi_ai->ver = 0x01;
637 hdmi_ai->len = 0x0a; 646 hdmi_ai->len = 0x0a;
638 hdmi_ai->CC02_CT47 = channels - 1; 647 hdmi_ai->CC02_CT47 = channels - 1;
639 hdmi_ai->CA = ca; 648 hdmi_ai->CA = ca;
640 hdmi_checksum_audio_infoframe(hdmi_ai); 649 hdmi_checksum_audio_infoframe(hdmi_ai);
641 } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */ 650 } else if (eld->conn_type == 1) { /* DisplayPort */
642 struct dp_audio_infoframe *dp_ai = &ai.dp; 651 struct dp_audio_infoframe *dp_ai = &ai.dp;
643 652
644 dp_ai->type = 0x84; 653 dp_ai->type = 0x84;
645 dp_ai->len = 0x1b; 654 dp_ai->len = 0x1b;
646 dp_ai->ver = 0x11 << 2; 655 dp_ai->ver = 0x11 << 2;
647 dp_ai->CC02_CT47 = channels - 1; 656 dp_ai->CC02_CT47 = channels - 1;
648 dp_ai->CA = ca; 657 dp_ai->CA = ca;
649 } else { 658 } else {
650 snd_printd("HDMI: unknown connection type at pin %d\n", 659 snd_printd("HDMI: unknown connection type at pin %d\n",
651 pin_nid); 660 pin_nid);
652 continue; 661 return;
653 } 662 }
654 663
655 /* 664 /*
656 * sizeof(ai) is used instead of sizeof(*hdmi_ai) or 665 * sizeof(ai) is used instead of sizeof(*hdmi_ai) or
657 * sizeof(*dp_ai) to avoid partial match/update problems when 666 * sizeof(*dp_ai) to avoid partial match/update problems when
658 * the user switches between HDMI/DP monitors. 667 * the user switches between HDMI/DP monitors.
659 */ 668 */
660 if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes, 669 if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes,
661 sizeof(ai))) { 670 sizeof(ai))) {
662 snd_printdd("hdmi_setup_audio_infoframe: " 671 snd_printdd("hdmi_setup_audio_infoframe: "
663 "cvt=%d pin=%d channels=%d\n", 672 "pin=%d channels=%d\n",
664 nid, pin_nid, 673 pin_nid,
665 channels); 674 channels);
666 hdmi_setup_channel_mapping(codec, pin_nid, ca); 675 hdmi_setup_channel_mapping(codec, pin_nid, ca);
667 hdmi_stop_infoframe_trans(codec, pin_nid); 676 hdmi_stop_infoframe_trans(codec, pin_nid);
668 hdmi_fill_audio_infoframe(codec, pin_nid, 677 hdmi_fill_audio_infoframe(codec, pin_nid,
669 ai.bytes, sizeof(ai)); 678 ai.bytes, sizeof(ai));
670 hdmi_start_infoframe_trans(codec, pin_nid); 679 hdmi_start_infoframe_trans(codec, pin_nid);
671 }
672 } 680 }
673} 681}
674 682
@@ -686,17 +694,27 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
686 int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT; 694 int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT;
687 int pd = !!(res & AC_UNSOL_RES_PD); 695 int pd = !!(res & AC_UNSOL_RES_PD);
688 int eldv = !!(res & AC_UNSOL_RES_ELDV); 696 int eldv = !!(res & AC_UNSOL_RES_ELDV);
689 int index; 697 int pin_idx;
698 struct hdmi_eld *eld;
690 699
691 printk(KERN_INFO 700 printk(KERN_INFO
692 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 701 "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
693 pin_nid, pd, eldv); 702 codec->addr, pin_nid, pd, eldv);
694 703
695 index = hda_node_index(spec->pin, pin_nid); 704 pin_idx = pin_nid_to_pin_index(spec, pin_nid);
696 if (index < 0) 705 if (pin_idx < 0)
697 return; 706 return;
707 eld = &spec->pins[pin_idx].sink_eld;
698 708
699 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[index]); 709 hdmi_present_sense(codec, pin_nid, eld);
710
711 /*
712 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
713 * in console or for audio devices. Assume the highest speakers
714 * configuration, to _not_ prohibit multi-channel audio playback.
715 */
716 if (!eld->spk_alloc)
717 eld->spk_alloc = 0xffff;
700} 718}
701 719
702static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) 720static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -707,7 +725,8 @@ static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
707 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); 725 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
708 726
709 printk(KERN_INFO 727 printk(KERN_INFO
710 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", 728 "HDMI CP event: CODEC=%d PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
729 codec->addr,
711 tag, 730 tag,
712 subtag, 731 subtag,
713 cp_state, 732 cp_state,
@@ -727,7 +746,7 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
727 int tag = res >> AC_UNSOL_RES_TAG_SHIFT; 746 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
728 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; 747 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
729 748
730 if (hda_node_index(spec->pin, tag) < 0) { 749 if (pin_nid_to_pin_index(spec, tag) < 0) {
731 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag); 750 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
732 return; 751 return;
733 } 752 }
@@ -746,21 +765,14 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
746#define is_hbr_format(format) \ 765#define is_hbr_format(format) \
747 ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7) 766 ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7)
748 767
749static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, 768static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
750 u32 stream_tag, int format) 769 hda_nid_t pin_nid, u32 stream_tag, int format)
751{ 770{
752 struct hdmi_spec *spec = codec->spec;
753 int pinctl; 771 int pinctl;
754 int new_pinctl = 0; 772 int new_pinctl = 0;
755 int i;
756
757 for (i = 0; i < spec->num_pins; i++) {
758 if (spec->pin_cvt[i] != nid)
759 continue;
760 if (!(snd_hda_query_pin_caps(codec, spec->pin[i]) & AC_PINCAP_HBR))
761 continue;
762 773
763 pinctl = snd_hda_codec_read(codec, spec->pin[i], 0, 774 if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) {
775 pinctl = snd_hda_codec_read(codec, pin_nid, 0,
764 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 776 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
765 777
766 new_pinctl = pinctl & ~AC_PINCTL_EPT; 778 new_pinctl = pinctl & ~AC_PINCTL_EPT;
@@ -771,22 +783,22 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
771 783
772 snd_printdd("hdmi_setup_stream: " 784 snd_printdd("hdmi_setup_stream: "
773 "NID=0x%x, %spinctl=0x%x\n", 785 "NID=0x%x, %spinctl=0x%x\n",
774 spec->pin[i], 786 pin_nid,
775 pinctl == new_pinctl ? "" : "new-", 787 pinctl == new_pinctl ? "" : "new-",
776 new_pinctl); 788 new_pinctl);
777 789
778 if (pinctl != new_pinctl) 790 if (pinctl != new_pinctl)
779 snd_hda_codec_write(codec, spec->pin[i], 0, 791 snd_hda_codec_write(codec, pin_nid, 0,
780 AC_VERB_SET_PIN_WIDGET_CONTROL, 792 AC_VERB_SET_PIN_WIDGET_CONTROL,
781 new_pinctl); 793 new_pinctl);
782 }
783 794
795 }
784 if (is_hbr_format(format) && !new_pinctl) { 796 if (is_hbr_format(format) && !new_pinctl) {
785 snd_printdd("hdmi_setup_stream: HBR is not supported\n"); 797 snd_printdd("hdmi_setup_stream: HBR is not supported\n");
786 return -EINVAL; 798 return -EINVAL;
787 } 799 }
788 800
789 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 801 snd_hda_codec_setup_stream(codec, cvt_nid, stream_tag, 0, format);
790 return 0; 802 return 0;
791} 803}
792 804
@@ -798,37 +810,70 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
798 struct snd_pcm_substream *substream) 810 struct snd_pcm_substream *substream)
799{ 811{
800 struct hdmi_spec *spec = codec->spec; 812 struct hdmi_spec *spec = codec->spec;
801 struct hdmi_eld *eld;
802 struct hda_pcm_stream *codec_pars;
803 struct snd_pcm_runtime *runtime = substream->runtime; 813 struct snd_pcm_runtime *runtime = substream->runtime;
804 unsigned int idx; 814 int pin_idx, cvt_idx, mux_idx = 0;
815 struct hdmi_spec_per_pin *per_pin;
816 struct hdmi_eld *eld;
817 struct hdmi_spec_per_cvt *per_cvt = NULL;
818 int pinctl;
805 819
806 for (idx = 0; idx < spec->num_cvts; idx++) 820 /* Validate hinfo */
807 if (hinfo->nid == spec->cvt[idx]) 821 pin_idx = hinfo_to_pin_index(spec, hinfo);
808 break; 822 if (snd_BUG_ON(pin_idx < 0))
809 if (snd_BUG_ON(idx >= spec->num_cvts) ||
810 snd_BUG_ON(idx >= spec->num_pins))
811 return -EINVAL; 823 return -EINVAL;
824 per_pin = &spec->pins[pin_idx];
825 eld = &per_pin->sink_eld;
812 826
813 /* save the PCM info the codec provides */ 827 /* Dynamically assign converter to stream */
814 codec_pars = &spec->codec_pcm_pars[idx]; 828 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
815 if (!codec_pars->rates) 829 per_cvt = &spec->cvts[cvt_idx];
816 *codec_pars = *hinfo;
817 830
818 eld = &spec->sink_eld[idx]; 831 /* Must not already be assigned */
819 if (!static_hdmi_pcm && eld->eld_valid && eld->sad_count > 0) { 832 if (per_cvt->assigned)
820 hdmi_eld_update_pcm_info(eld, hinfo, codec_pars); 833 continue;
834 /* Must be in pin's mux's list of converters */
835 for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++)
836 if (per_pin->mux_nids[mux_idx] == per_cvt->cvt_nid)
837 break;
838 /* Not in mux list */
839 if (mux_idx == per_pin->num_mux_nids)
840 continue;
841 break;
842 }
843 /* No free converters */
844 if (cvt_idx == spec->num_cvts)
845 return -ENODEV;
846
847 /* Claim converter */
848 per_cvt->assigned = 1;
849 hinfo->nid = per_cvt->cvt_nid;
850
851 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
852 AC_VERB_SET_CONNECT_SEL,
853 mux_idx);
854 pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
855 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
856 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
857 AC_VERB_SET_PIN_WIDGET_CONTROL,
858 pinctl | PIN_OUT);
859 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
860
861 /* Initially set the converter's capabilities */
862 hinfo->channels_min = per_cvt->channels_min;
863 hinfo->channels_max = per_cvt->channels_max;
864 hinfo->rates = per_cvt->rates;
865 hinfo->formats = per_cvt->formats;
866 hinfo->maxbps = per_cvt->maxbps;
867
868 /* Restrict capabilities by ELD if this isn't disabled */
869 if (!static_hdmi_pcm && eld->eld_valid) {
870 snd_hdmi_eld_update_pcm_info(eld, hinfo);
821 if (hinfo->channels_min > hinfo->channels_max || 871 if (hinfo->channels_min > hinfo->channels_max ||
822 !hinfo->rates || !hinfo->formats) 872 !hinfo->rates || !hinfo->formats)
823 return -ENODEV; 873 return -ENODEV;
824 } else {
825 /* fallback to the codec default */
826 hinfo->channels_max = codec_pars->channels_max;
827 hinfo->rates = codec_pars->rates;
828 hinfo->formats = codec_pars->formats;
829 hinfo->maxbps = codec_pars->maxbps;
830 } 874 }
831 /* store the updated parameters */ 875
876 /* Store the updated parameters */
832 runtime->hw.channels_min = hinfo->channels_min; 877 runtime->hw.channels_min = hinfo->channels_min;
833 runtime->hw.channels_max = hinfo->channels_max; 878 runtime->hw.channels_max = hinfo->channels_max;
834 runtime->hw.formats = hinfo->formats; 879 runtime->hw.formats = hinfo->formats;
@@ -842,12 +887,11 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
842/* 887/*
843 * HDA/HDMI auto parsing 888 * HDA/HDMI auto parsing
844 */ 889 */
845static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid) 890static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
846{ 891{
847 struct hdmi_spec *spec = codec->spec; 892 struct hdmi_spec *spec = codec->spec;
848 hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; 893 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
849 int conn_len, curr; 894 hda_nid_t pin_nid = per_pin->pin_nid;
850 int index;
851 895
852 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) { 896 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
853 snd_printk(KERN_WARNING 897 snd_printk(KERN_WARNING
@@ -857,19 +901,9 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
857 return -EINVAL; 901 return -EINVAL;
858 } 902 }
859 903
860 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list, 904 per_pin->num_mux_nids = snd_hda_get_connections(codec, pin_nid,
861 HDA_MAX_CONNECTIONS); 905 per_pin->mux_nids,
862 if (conn_len > 1) 906 HDA_MAX_CONNECTIONS);
863 curr = snd_hda_codec_read(codec, pin_nid, 0,
864 AC_VERB_GET_CONNECT_SEL, 0);
865 else
866 curr = 0;
867
868 index = hda_node_index(spec->pin, pin_nid);
869 if (index < 0)
870 return -EINVAL;
871
872 spec->pin_cvt[index] = conn_list[curr];
873 907
874 return 0; 908 return 0;
875} 909}
@@ -896,8 +930,8 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
896 eld->eld_valid = 0; 930 eld->eld_valid = 0;
897 931
898 printk(KERN_INFO 932 printk(KERN_INFO
899 "HDMI status: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 933 "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
900 pin_nid, eld->monitor_present, eld->eld_valid); 934 codec->addr, pin_nid, eld->monitor_present, eld->eld_valid);
901 935
902 if (eld->eld_valid) 936 if (eld->eld_valid)
903 if (!snd_hdmi_get_eld(eld, codec, pin_nid)) 937 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
@@ -909,47 +943,75 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
909static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) 943static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
910{ 944{
911 struct hdmi_spec *spec = codec->spec; 945 struct hdmi_spec *spec = codec->spec;
946 unsigned int caps, config;
947 int pin_idx;
948 struct hdmi_spec_per_pin *per_pin;
949 struct hdmi_eld *eld;
912 int err; 950 int err;
913 951
914 if (spec->num_pins >= MAX_HDMI_PINS) { 952 caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP);
915 snd_printk(KERN_WARNING 953 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
916 "HDMI: no space for pin %d\n", pin_nid); 954 return 0;
955
956 config = snd_hda_codec_read(codec, pin_nid, 0,
957 AC_VERB_GET_CONFIG_DEFAULT, 0);
958 if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
959 return 0;
960
961 if (snd_BUG_ON(spec->num_pins >= MAX_HDMI_PINS))
917 return -E2BIG; 962 return -E2BIG;
918 } 963
964 pin_idx = spec->num_pins;
965 per_pin = &spec->pins[pin_idx];
966 eld = &per_pin->sink_eld;
967
968 per_pin->pin_nid = pin_nid;
919 969
920 err = snd_hda_input_jack_add(codec, pin_nid, 970 err = snd_hda_input_jack_add(codec, pin_nid,
921 SND_JACK_VIDEOOUT, NULL); 971 SND_JACK_VIDEOOUT, NULL);
922 if (err < 0) 972 if (err < 0)
923 return err; 973 return err;
924 974
925 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); 975 err = hdmi_read_pin_conn(codec, pin_idx);
976 if (err < 0)
977 return err;
926 978
927 spec->pin[spec->num_pins] = pin_nid;
928 spec->num_pins++; 979 spec->num_pins++;
929 980
930 return hdmi_read_pin_conn(codec, pin_nid); 981 hdmi_present_sense(codec, pin_nid, eld);
982
983 return 0;
931} 984}
932 985
933static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid) 986static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
934{ 987{
935 int i, found_pin = 0;
936 struct hdmi_spec *spec = codec->spec; 988 struct hdmi_spec *spec = codec->spec;
937 989 int cvt_idx;
938 for (i = 0; i < spec->num_pins; i++) 990 struct hdmi_spec_per_cvt *per_cvt;
939 if (nid == spec->pin_cvt[i]) { 991 unsigned int chans;
940 found_pin = 1; 992 int err;
941 break;
942 }
943
944 if (!found_pin) {
945 snd_printdd("HDMI: Skipping node %d (no connection)\n", nid);
946 return -EINVAL;
947 }
948 993
949 if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS)) 994 if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS))
950 return -E2BIG; 995 return -E2BIG;
951 996
952 spec->cvt[spec->num_cvts] = nid; 997 chans = get_wcaps(codec, cvt_nid);
998 chans = get_wcaps_channels(chans);
999
1000 cvt_idx = spec->num_cvts;
1001 per_cvt = &spec->cvts[cvt_idx];
1002
1003 per_cvt->cvt_nid = cvt_nid;
1004 per_cvt->channels_min = 2;
1005 if (chans <= 16)
1006 per_cvt->channels_max = chans;
1007
1008 err = snd_hda_query_supported_pcm(codec, cvt_nid,
1009 &per_cvt->rates,
1010 &per_cvt->formats,
1011 &per_cvt->maxbps);
1012 if (err < 0)
1013 return err;
1014
953 spec->num_cvts++; 1015 spec->num_cvts++;
954 1016
955 return 0; 1017 return 0;
@@ -959,8 +1021,6 @@ static int hdmi_parse_codec(struct hda_codec *codec)
959{ 1021{
960 hda_nid_t nid; 1022 hda_nid_t nid;
961 int i, nodes; 1023 int i, nodes;
962 int num_tmp_cvts = 0;
963 hda_nid_t tmp_cvt[MAX_HDMI_CVTS];
964 1024
965 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); 1025 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
966 if (!nid || nodes < 0) { 1026 if (!nid || nodes < 0) {
@@ -971,7 +1031,6 @@ static int hdmi_parse_codec(struct hda_codec *codec)
971 for (i = 0; i < nodes; i++, nid++) { 1031 for (i = 0; i < nodes; i++, nid++) {
972 unsigned int caps; 1032 unsigned int caps;
973 unsigned int type; 1033 unsigned int type;
974 unsigned int config;
975 1034
976 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); 1035 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
977 type = get_wcaps_type(caps); 1036 type = get_wcaps_type(caps);
@@ -981,32 +1040,14 @@ static int hdmi_parse_codec(struct hda_codec *codec)
981 1040
982 switch (type) { 1041 switch (type) {
983 case AC_WID_AUD_OUT: 1042 case AC_WID_AUD_OUT:
984 if (num_tmp_cvts >= MAX_HDMI_CVTS) { 1043 hdmi_add_cvt(codec, nid);
985 snd_printk(KERN_WARNING
986 "HDMI: no space for converter %d\n", nid);
987 continue;
988 }
989 tmp_cvt[num_tmp_cvts] = nid;
990 num_tmp_cvts++;
991 break; 1044 break;
992 case AC_WID_PIN: 1045 case AC_WID_PIN:
993 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
994 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
995 continue;
996
997 config = snd_hda_codec_read(codec, nid, 0,
998 AC_VERB_GET_CONFIG_DEFAULT, 0);
999 if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
1000 continue;
1001
1002 hdmi_add_pin(codec, nid); 1046 hdmi_add_pin(codec, nid);
1003 break; 1047 break;
1004 } 1048 }
1005 } 1049 }
1006 1050
1007 for (i = 0; i < num_tmp_cvts; i++)
1008 hdmi_add_cvt(codec, tmp_cvt[i]);
1009
1010 /* 1051 /*
1011 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event 1052 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
1012 * can be lost and presence sense verb will become inaccurate if the 1053 * can be lost and presence sense verb will become inaccurate if the
@@ -1023,7 +1064,7 @@ static int hdmi_parse_codec(struct hda_codec *codec)
1023 1064
1024/* 1065/*
1025 */ 1066 */
1026static char *generic_hdmi_pcm_names[MAX_HDMI_CVTS] = { 1067static char *generic_hdmi_pcm_names[MAX_HDMI_PINS] = {
1027 "HDMI 0", 1068 "HDMI 0",
1028 "HDMI 1", 1069 "HDMI 1",
1029 "HDMI 2", 1070 "HDMI 2",
@@ -1040,51 +1081,84 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1040 unsigned int format, 1081 unsigned int format,
1041 struct snd_pcm_substream *substream) 1082 struct snd_pcm_substream *substream)
1042{ 1083{
1043 hdmi_set_channel_count(codec, hinfo->nid, 1084 hda_nid_t cvt_nid = hinfo->nid;
1044 substream->runtime->channels); 1085 struct hdmi_spec *spec = codec->spec;
1086 int pin_idx = hinfo_to_pin_index(spec, hinfo);
1087 hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
1088
1089 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
1045 1090
1046 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); 1091 hdmi_setup_audio_infoframe(codec, pin_idx, substream);
1047 1092
1048 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); 1093 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
1049} 1094}
1050 1095
1051static const struct hda_pcm_stream generic_hdmi_pcm_playback = { 1096static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1052 .substreams = 1, 1097 struct hda_codec *codec,
1053 .channels_min = 2, 1098 struct snd_pcm_substream *substream)
1054 .ops = { 1099{
1055 .open = hdmi_pcm_open, 1100 struct hdmi_spec *spec = codec->spec;
1056 .prepare = generic_hdmi_playback_pcm_prepare, 1101 int cvt_idx, pin_idx;
1057 }, 1102 struct hdmi_spec_per_cvt *per_cvt;
1103 struct hdmi_spec_per_pin *per_pin;
1104 int pinctl;
1105
1106 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
1107
1108 if (hinfo->nid) {
1109 cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
1110 if (snd_BUG_ON(cvt_idx < 0))
1111 return -EINVAL;
1112 per_cvt = &spec->cvts[cvt_idx];
1113
1114 snd_BUG_ON(!per_cvt->assigned);
1115 per_cvt->assigned = 0;
1116 hinfo->nid = 0;
1117
1118 pin_idx = hinfo_to_pin_index(spec, hinfo);
1119 if (snd_BUG_ON(pin_idx < 0))
1120 return -EINVAL;
1121 per_pin = &spec->pins[pin_idx];
1122
1123 pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
1124 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1125 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
1126 AC_VERB_SET_PIN_WIDGET_CONTROL,
1127 pinctl & ~PIN_OUT);
1128 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1129 }
1130
1131 return 0;
1132}
1133
1134static const struct hda_pcm_ops generic_ops = {
1135 .open = hdmi_pcm_open,
1136 .prepare = generic_hdmi_playback_pcm_prepare,
1137 .cleanup = generic_hdmi_playback_pcm_cleanup,
1058}; 1138};
1059 1139
1060static int generic_hdmi_build_pcms(struct hda_codec *codec) 1140static int generic_hdmi_build_pcms(struct hda_codec *codec)
1061{ 1141{
1062 struct hdmi_spec *spec = codec->spec; 1142 struct hdmi_spec *spec = codec->spec;
1063 struct hda_pcm *info = spec->pcm_rec; 1143 int pin_idx;
1064 int i;
1065 1144
1066 codec->num_pcms = spec->num_cvts; 1145 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1067 codec->pcm_info = info; 1146 struct hda_pcm *info;
1068
1069 for (i = 0; i < codec->num_pcms; i++, info++) {
1070 unsigned int chans;
1071 struct hda_pcm_stream *pstr; 1147 struct hda_pcm_stream *pstr;
1072 1148
1073 chans = get_wcaps(codec, spec->cvt[i]); 1149 info = &spec->pcm_rec[pin_idx];
1074 chans = get_wcaps_channels(chans); 1150 info->name = generic_hdmi_pcm_names[pin_idx];
1075
1076 info->name = generic_hdmi_pcm_names[i];
1077 info->pcm_type = HDA_PCM_TYPE_HDMI; 1151 info->pcm_type = HDA_PCM_TYPE_HDMI;
1152
1078 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; 1153 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
1079 if (spec->pcm_playback) 1154 pstr->substreams = 1;
1080 *pstr = *spec->pcm_playback; 1155 pstr->ops = generic_ops;
1081 else 1156 /* other pstr fields are set in open */
1082 *pstr = generic_hdmi_pcm_playback;
1083 pstr->nid = spec->cvt[i];
1084 if (pstr->channels_max <= 2 && chans && chans <= 16)
1085 pstr->channels_max = chans;
1086 } 1157 }
1087 1158
1159 codec->num_pcms = spec->num_pins;
1160 codec->pcm_info = spec->pcm_rec;
1161
1088 return 0; 1162 return 0;
1089} 1163}
1090 1164
@@ -1092,12 +1166,16 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1092{ 1166{
1093 struct hdmi_spec *spec = codec->spec; 1167 struct hdmi_spec *spec = codec->spec;
1094 int err; 1168 int err;
1095 int i; 1169 int pin_idx;
1096 1170
1097 for (i = 0; i < codec->num_pcms; i++) { 1171 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1098 err = snd_hda_create_spdif_out_ctls(codec, spec->cvt[i]); 1172 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1173 err = snd_hda_create_spdif_out_ctls(codec,
1174 per_pin->pin_nid,
1175 per_pin->mux_nids[0]);
1099 if (err < 0) 1176 if (err < 0)
1100 return err; 1177 return err;
1178 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1101 } 1179 }
1102 1180
1103 return 0; 1181 return 0;
@@ -1106,13 +1184,19 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1106static int generic_hdmi_init(struct hda_codec *codec) 1184static int generic_hdmi_init(struct hda_codec *codec)
1107{ 1185{
1108 struct hdmi_spec *spec = codec->spec; 1186 struct hdmi_spec *spec = codec->spec;
1109 int i; 1187 int pin_idx;
1110 1188
1111 for (i = 0; spec->pin[i]; i++) { 1189 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1112 hdmi_enable_output(codec, spec->pin[i]); 1190 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1113 snd_hda_codec_write(codec, spec->pin[i], 0, 1191 hda_nid_t pin_nid = per_pin->pin_nid;
1192 struct hdmi_eld *eld = &per_pin->sink_eld;
1193
1194 hdmi_init_pin(codec, pin_nid);
1195 snd_hda_codec_write(codec, pin_nid, 0,
1114 AC_VERB_SET_UNSOLICITED_ENABLE, 1196 AC_VERB_SET_UNSOLICITED_ENABLE,
1115 AC_USRSP_EN | spec->pin[i]); 1197 AC_USRSP_EN | pin_nid);
1198
1199 snd_hda_eld_proc_new(codec, eld, pin_idx);
1116 } 1200 }
1117 return 0; 1201 return 0;
1118} 1202}
@@ -1120,10 +1204,14 @@ static int generic_hdmi_init(struct hda_codec *codec)
1120static void generic_hdmi_free(struct hda_codec *codec) 1204static void generic_hdmi_free(struct hda_codec *codec)
1121{ 1205{
1122 struct hdmi_spec *spec = codec->spec; 1206 struct hdmi_spec *spec = codec->spec;
1123 int i; 1207 int pin_idx;
1208
1209 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1210 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1211 struct hdmi_eld *eld = &per_pin->sink_eld;
1124 1212
1125 for (i = 0; i < spec->num_pins; i++) 1213 snd_hda_eld_proc_free(codec, eld);
1126 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]); 1214 }
1127 snd_hda_input_jack_free(codec); 1215 snd_hda_input_jack_free(codec);
1128 1216
1129 kfree(spec); 1217 kfree(spec);
@@ -1140,7 +1228,6 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = {
1140static int patch_generic_hdmi(struct hda_codec *codec) 1228static int patch_generic_hdmi(struct hda_codec *codec)
1141{ 1229{
1142 struct hdmi_spec *spec; 1230 struct hdmi_spec *spec;
1143 int i;
1144 1231
1145 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1232 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1146 if (spec == NULL) 1233 if (spec == NULL)
@@ -1154,15 +1241,69 @@ static int patch_generic_hdmi(struct hda_codec *codec)
1154 } 1241 }
1155 codec->patch_ops = generic_hdmi_patch_ops; 1242 codec->patch_ops = generic_hdmi_patch_ops;
1156 1243
1157 for (i = 0; i < spec->num_pins; i++)
1158 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
1159
1160 init_channel_allocations(); 1244 init_channel_allocations();
1161 1245
1162 return 0; 1246 return 0;
1163} 1247}
1164 1248
1165/* 1249/*
1250 * Shared non-generic implementations
1251 */
1252
1253static int simple_playback_build_pcms(struct hda_codec *codec)
1254{
1255 struct hdmi_spec *spec = codec->spec;
1256 struct hda_pcm *info = spec->pcm_rec;
1257 int i;
1258
1259 codec->num_pcms = spec->num_cvts;
1260 codec->pcm_info = info;
1261
1262 for (i = 0; i < codec->num_pcms; i++, info++) {
1263 unsigned int chans;
1264 struct hda_pcm_stream *pstr;
1265
1266 chans = get_wcaps(codec, spec->cvts[i].cvt_nid);
1267 chans = get_wcaps_channels(chans);
1268
1269 info->name = generic_hdmi_pcm_names[i];
1270 info->pcm_type = HDA_PCM_TYPE_HDMI;
1271 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
1272 snd_BUG_ON(!spec->pcm_playback);
1273 *pstr = *spec->pcm_playback;
1274 pstr->nid = spec->cvts[i].cvt_nid;
1275 if (pstr->channels_max <= 2 && chans && chans <= 16)
1276 pstr->channels_max = chans;
1277 }
1278
1279 return 0;
1280}
1281
1282static int simple_playback_build_controls(struct hda_codec *codec)
1283{
1284 struct hdmi_spec *spec = codec->spec;
1285 int err;
1286 int i;
1287
1288 for (i = 0; i < codec->num_pcms; i++) {
1289 err = snd_hda_create_spdif_out_ctls(codec,
1290 spec->cvts[i].cvt_nid,
1291 spec->cvts[i].cvt_nid);
1292 if (err < 0)
1293 return err;
1294 }
1295
1296 return 0;
1297}
1298
1299static void simple_playback_free(struct hda_codec *codec)
1300{
1301 struct hdmi_spec *spec = codec->spec;
1302
1303 kfree(spec);
1304}
1305
1306/*
1166 * Nvidia specific implementations 1307 * Nvidia specific implementations
1167 */ 1308 */
1168 1309
@@ -1352,6 +1493,9 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1352 int chs; 1493 int chs;
1353 unsigned int dataDCC1, dataDCC2, channel_id; 1494 unsigned int dataDCC1, dataDCC2, channel_id;
1354 int i; 1495 int i;
1496 struct hdmi_spec *spec = codec->spec;
1497 struct hda_spdif_out *spdif =
1498 snd_hda_spdif_out_of_nid(codec, spec->cvts[0].cvt_nid);
1355 1499
1356 mutex_lock(&codec->spdif_mutex); 1500 mutex_lock(&codec->spdif_mutex);
1357 1501
@@ -1361,12 +1505,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1361 dataDCC2 = 0x2; 1505 dataDCC2 = 0x2;
1362 1506
1363 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 1507 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
1364 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 1508 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
1365 snd_hda_codec_write(codec, 1509 snd_hda_codec_write(codec,
1366 nvhdmi_master_con_nid_7x, 1510 nvhdmi_master_con_nid_7x,
1367 0, 1511 0,
1368 AC_VERB_SET_DIGI_CONVERT_1, 1512 AC_VERB_SET_DIGI_CONVERT_1,
1369 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 1513 spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
1370 1514
1371 /* set the stream id */ 1515 /* set the stream id */
1372 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0, 1516 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
@@ -1378,12 +1522,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1378 1522
1379 /* turn on again (if needed) */ 1523 /* turn on again (if needed) */
1380 /* enable and set the channel status audio/data flag */ 1524 /* enable and set the channel status audio/data flag */
1381 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { 1525 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE)) {
1382 snd_hda_codec_write(codec, 1526 snd_hda_codec_write(codec,
1383 nvhdmi_master_con_nid_7x, 1527 nvhdmi_master_con_nid_7x,
1384 0, 1528 0,
1385 AC_VERB_SET_DIGI_CONVERT_1, 1529 AC_VERB_SET_DIGI_CONVERT_1,
1386 codec->spdif_ctls & 0xff); 1530 spdif->ctls & 0xff);
1387 snd_hda_codec_write(codec, 1531 snd_hda_codec_write(codec,
1388 nvhdmi_master_con_nid_7x, 1532 nvhdmi_master_con_nid_7x,
1389 0, 1533 0,
@@ -1400,12 +1544,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1400 *otherwise the IEC958 bits won't be updated 1544 *otherwise the IEC958 bits won't be updated
1401 */ 1545 */
1402 if (codec->spdif_status_reset && 1546 if (codec->spdif_status_reset &&
1403 (codec->spdif_ctls & AC_DIG1_ENABLE)) 1547 (spdif->ctls & AC_DIG1_ENABLE))
1404 snd_hda_codec_write(codec, 1548 snd_hda_codec_write(codec,
1405 nvhdmi_con_nids_7x[i], 1549 nvhdmi_con_nids_7x[i],
1406 0, 1550 0,
1407 AC_VERB_SET_DIGI_CONVERT_1, 1551 AC_VERB_SET_DIGI_CONVERT_1,
1408 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 1552 spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
1409 /* set the stream id */ 1553 /* set the stream id */
1410 snd_hda_codec_write(codec, 1554 snd_hda_codec_write(codec,
1411 nvhdmi_con_nids_7x[i], 1555 nvhdmi_con_nids_7x[i],
@@ -1421,12 +1565,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1421 /* turn on again (if needed) */ 1565 /* turn on again (if needed) */
1422 /* enable and set the channel status audio/data flag */ 1566 /* enable and set the channel status audio/data flag */
1423 if (codec->spdif_status_reset && 1567 if (codec->spdif_status_reset &&
1424 (codec->spdif_ctls & AC_DIG1_ENABLE)) { 1568 (spdif->ctls & AC_DIG1_ENABLE)) {
1425 snd_hda_codec_write(codec, 1569 snd_hda_codec_write(codec,
1426 nvhdmi_con_nids_7x[i], 1570 nvhdmi_con_nids_7x[i],
1427 0, 1571 0,
1428 AC_VERB_SET_DIGI_CONVERT_1, 1572 AC_VERB_SET_DIGI_CONVERT_1,
1429 codec->spdif_ctls & 0xff); 1573 spdif->ctls & 0xff);
1430 snd_hda_codec_write(codec, 1574 snd_hda_codec_write(codec,
1431 nvhdmi_con_nids_7x[i], 1575 nvhdmi_con_nids_7x[i],
1432 0, 1576 0,
@@ -1471,17 +1615,17 @@ static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
1471}; 1615};
1472 1616
1473static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { 1617static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
1474 .build_controls = generic_hdmi_build_controls, 1618 .build_controls = simple_playback_build_controls,
1475 .build_pcms = generic_hdmi_build_pcms, 1619 .build_pcms = simple_playback_build_pcms,
1476 .init = nvhdmi_7x_init, 1620 .init = nvhdmi_7x_init,
1477 .free = generic_hdmi_free, 1621 .free = simple_playback_free,
1478}; 1622};
1479 1623
1480static const struct hda_codec_ops nvhdmi_patch_ops_2ch = { 1624static const struct hda_codec_ops nvhdmi_patch_ops_2ch = {
1481 .build_controls = generic_hdmi_build_controls, 1625 .build_controls = simple_playback_build_controls,
1482 .build_pcms = generic_hdmi_build_pcms, 1626 .build_pcms = simple_playback_build_pcms,
1483 .init = nvhdmi_7x_init, 1627 .init = nvhdmi_7x_init,
1484 .free = generic_hdmi_free, 1628 .free = simple_playback_free,
1485}; 1629};
1486 1630
1487static int patch_nvhdmi_2ch(struct hda_codec *codec) 1631static int patch_nvhdmi_2ch(struct hda_codec *codec)
@@ -1498,7 +1642,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
1498 spec->multiout.max_channels = 2; 1642 spec->multiout.max_channels = 2;
1499 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; 1643 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
1500 spec->num_cvts = 1; 1644 spec->num_cvts = 1;
1501 spec->cvt[0] = nvhdmi_master_con_nid_7x; 1645 spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x;
1502 spec->pcm_playback = &nvhdmi_pcm_playback_2ch; 1646 spec->pcm_playback = &nvhdmi_pcm_playback_2ch;
1503 1647
1504 codec->patch_ops = nvhdmi_patch_ops_2ch; 1648 codec->patch_ops = nvhdmi_patch_ops_2ch;
@@ -1549,11 +1693,11 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1549 substream); 1693 substream);
1550 if (err < 0) 1694 if (err < 0)
1551 return err; 1695 return err;
1552 snd_hda_codec_write(codec, spec->cvt[0], 0, AC_VERB_SET_CVT_CHAN_COUNT, 1696 snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0,
1553 chans - 1); 1697 AC_VERB_SET_CVT_CHAN_COUNT, chans - 1);
1554 /* FIXME: XXX */ 1698 /* FIXME: XXX */
1555 for (i = 0; i < chans; i++) { 1699 for (i = 0; i < chans; i++) {
1556 snd_hda_codec_write(codec, spec->cvt[0], 0, 1700 snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0,
1557 AC_VERB_SET_HDMI_CHAN_SLOT, 1701 AC_VERB_SET_HDMI_CHAN_SLOT,
1558 (i << 4) | i); 1702 (i << 4) | i);
1559 } 1703 }
@@ -1584,18 +1728,18 @@ static int atihdmi_init(struct hda_codec *codec)
1584 1728
1585 snd_hda_sequence_write(codec, atihdmi_basic_init); 1729 snd_hda_sequence_write(codec, atihdmi_basic_init);
1586 /* SI codec requires to unmute the pin */ 1730 /* SI codec requires to unmute the pin */
1587 if (get_wcaps(codec, spec->pin[0]) & AC_WCAP_OUT_AMP) 1731 if (get_wcaps(codec, spec->pins[0].pin_nid) & AC_WCAP_OUT_AMP)
1588 snd_hda_codec_write(codec, spec->pin[0], 0, 1732 snd_hda_codec_write(codec, spec->pins[0].pin_nid, 0,
1589 AC_VERB_SET_AMP_GAIN_MUTE, 1733 AC_VERB_SET_AMP_GAIN_MUTE,
1590 AMP_OUT_UNMUTE); 1734 AMP_OUT_UNMUTE);
1591 return 0; 1735 return 0;
1592} 1736}
1593 1737
1594static const struct hda_codec_ops atihdmi_patch_ops = { 1738static const struct hda_codec_ops atihdmi_patch_ops = {
1595 .build_controls = generic_hdmi_build_controls, 1739 .build_controls = simple_playback_build_controls,
1596 .build_pcms = generic_hdmi_build_pcms, 1740 .build_pcms = simple_playback_build_pcms,
1597 .init = atihdmi_init, 1741 .init = atihdmi_init,
1598 .free = generic_hdmi_free, 1742 .free = simple_playback_free,
1599}; 1743};
1600 1744
1601 1745
@@ -1613,8 +1757,8 @@ static int patch_atihdmi(struct hda_codec *codec)
1613 spec->multiout.max_channels = 2; 1757 spec->multiout.max_channels = 2;
1614 spec->multiout.dig_out_nid = ATIHDMI_CVT_NID; 1758 spec->multiout.dig_out_nid = ATIHDMI_CVT_NID;
1615 spec->num_cvts = 1; 1759 spec->num_cvts = 1;
1616 spec->cvt[0] = ATIHDMI_CVT_NID; 1760 spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID;
1617 spec->pin[0] = ATIHDMI_PIN_NID; 1761 spec->pins[0].pin_nid = ATIHDMI_PIN_NID;
1618 spec->pcm_playback = &atihdmi_pcm_digital_playback; 1762 spec->pcm_playback = &atihdmi_pcm_digital_playback;
1619 1763
1620 codec->patch_ops = atihdmi_patch_ops; 1764 codec->patch_ops = atihdmi_patch_ops;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 7a4e10002f5..e125c60fe35 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Universal Interface for Intel High Definition Audio Codec 2 * Universal Interface for Intel High Definition Audio Codec
3 * 3 *
4 * HD audio interface patch for ALC 260/880/882 codecs 4 * HD audio interface patch for Realtek ALC codecs
5 * 5 *
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> 6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw> 7 * PeiSen Hou <pshou@realtek.com.tw>
@@ -33,236 +33,11 @@
33#include "hda_local.h" 33#include "hda_local.h"
34#include "hda_beep.h" 34#include "hda_beep.h"
35 35
36#define ALC880_FRONT_EVENT 0x01 36/* unsol event tags */
37#define ALC880_DCVOL_EVENT 0x02 37#define ALC_FRONT_EVENT 0x01
38#define ALC880_HP_EVENT 0x04 38#define ALC_DCVOL_EVENT 0x02
39#define ALC880_MIC_EVENT 0x08 39#define ALC_HP_EVENT 0x04
40 40#define ALC_MIC_EVENT 0x08
41/* ALC880 board config type */
42enum {
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 */
73enum {
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 */
91enum {
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 */
115enum {
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 */
132enum {
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 */
147enum {
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 */
161enum {
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 */
176enum {
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 */
205enum {
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 */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266 41
267/* for GPIO Poll */ 42/* for GPIO Poll */
268#define GPIO_MASK 0x03 43#define GPIO_MASK 0x03
@@ -276,14 +51,6 @@ enum {
276 ALC_INIT_GPIO3, 51 ALC_INIT_GPIO3,
277}; 52};
278 53
279struct 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
287struct alc_customize_define { 54struct alc_customize_define {
288 unsigned int sku_cfg; 55 unsigned int sku_cfg;
289 unsigned char port_connectivity; 56 unsigned char port_connectivity;
@@ -348,9 +115,9 @@ struct alc_spec {
348 const hda_nid_t *adc_nids; 115 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids; 116 const hda_nid_t *capsrc_nids;
350 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 117 hda_nid_t dig_in_nid; /* digital-in NID; optional */
118 hda_nid_t mixer_nid; /* analog-mixer NID */
351 119
352 /* capture setup for dynamic dual-adc switch */ 120 /* capture setup for dynamic dual-adc switch */
353 unsigned int cur_adc_idx;
354 hda_nid_t cur_adc; 121 hda_nid_t cur_adc;
355 unsigned int cur_adc_stream_tag; 122 unsigned int cur_adc_stream_tag;
356 unsigned int cur_adc_format; 123 unsigned int cur_adc_format;
@@ -359,9 +126,9 @@ struct alc_spec {
359 unsigned int num_mux_defs; 126 unsigned int num_mux_defs;
360 const struct hda_input_mux *input_mux; 127 const struct hda_input_mux *input_mux;
361 unsigned int cur_mux[3]; 128 unsigned int cur_mux[3];
362 struct alc_mic_route ext_mic; 129 hda_nid_t ext_mic_pin;
363 struct alc_mic_route dock_mic; 130 hda_nid_t dock_mic_pin;
364 struct alc_mic_route int_mic; 131 hda_nid_t int_mic_pin;
365 132
366 /* channel model */ 133 /* channel model */
367 const struct hda_channel_mode *channel_mode; 134 const struct hda_channel_mode *channel_mode;
@@ -381,6 +148,9 @@ struct alc_spec {
381 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 148 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
382 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; 149 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
383 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; 150 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
151 hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS];
152 unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS];
153 int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */
384 154
385 /* hooks */ 155 /* hooks */
386 void (*init_hook)(struct hda_codec *codec); 156 void (*init_hook)(struct hda_codec *codec);
@@ -395,6 +165,7 @@ struct alc_spec {
395 unsigned int line_jack_present:1; 165 unsigned int line_jack_present:1;
396 unsigned int master_mute:1; 166 unsigned int master_mute:1;
397 unsigned int auto_mic:1; 167 unsigned int auto_mic:1;
168 unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */
398 unsigned int automute:1; /* HP automute enabled */ 169 unsigned int automute:1; /* HP automute enabled */
399 unsigned int detect_line:1; /* Line-out detection enabled */ 170 unsigned int detect_line:1; /* Line-out detection enabled */
400 unsigned int automute_lines:1; /* automute line-out as well */ 171 unsigned int automute_lines:1; /* automute line-out as well */
@@ -402,8 +173,9 @@ struct alc_spec {
402 173
403 /* other flags */ 174 /* other flags */
404 unsigned int no_analog :1; /* digital I/O only */ 175 unsigned int no_analog :1; /* digital I/O only */
405 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 176 unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */
406 unsigned int single_input_src:1; 177 unsigned int single_input_src:1;
178 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
407 179
408 /* auto-mute control */ 180 /* auto-mute control */
409 int automute_mode; 181 int automute_mode;
@@ -432,39 +204,23 @@ struct alc_spec {
432 struct alc_multi_io multi_io[4]; 204 struct alc_multi_io multi_io[4];
433}; 205};
434 206
435/* 207#define ALC_MODEL_AUTO 0 /* common for all chips */
436 * configuration template - to be copied to the spec instance
437 */
438struct 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 208
209static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
210 int dir, unsigned int bits)
211{
212 if (!nid)
213 return false;
214 if (get_wcaps(codec, nid) & (1 << (dir + 1)))
215 if (query_amp_caps(codec, nid, dir) & bits)
216 return true;
217 return false;
218}
219
220#define nid_has_mute(codec, nid, dir) \
221 check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
222#define nid_has_volume(codec, nid, dir) \
223 check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)
468 224
469/* 225/*
470 * input MUX handling 226 * input MUX handling
@@ -493,388 +249,83 @@ static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
493 return 0; 249 return 0;
494} 250}
495 251
496static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 252static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
497 struct snd_ctl_elem_value *ucontrol) 253{
254 struct alc_spec *spec = codec->spec;
255 hda_nid_t new_adc = spec->adc_nids[spec->dyn_adc_idx[cur]];
256
257 if (spec->cur_adc && spec->cur_adc != new_adc) {
258 /* stream is running, let's swap the current ADC */
259 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
260 spec->cur_adc = new_adc;
261 snd_hda_codec_setup_stream(codec, new_adc,
262 spec->cur_adc_stream_tag, 0,
263 spec->cur_adc_format);
264 return true;
265 }
266 return false;
267}
268
269/* select the given imux item; either unmute exclusively or select the route */
270static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
271 unsigned int idx, bool force)
498{ 272{
499 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
500 struct alc_spec *spec = codec->spec; 273 struct alc_spec *spec = codec->spec;
501 const struct hda_input_mux *imux; 274 const struct hda_input_mux *imux;
502 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
503 unsigned int mux_idx; 275 unsigned int mux_idx;
504 hda_nid_t nid = spec->capsrc_nids ? 276 int i, type;
505 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 277 hda_nid_t nid;
506 unsigned int type;
507 278
508 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 279 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
509 imux = &spec->input_mux[mux_idx]; 280 imux = &spec->input_mux[mux_idx];
510 if (!imux->num_items && mux_idx > 0) 281 if (!imux->num_items && mux_idx > 0)
511 imux = &spec->input_mux[0]; 282 imux = &spec->input_mux[0];
512 283
284 if (idx >= imux->num_items)
285 idx = imux->num_items - 1;
286 if (spec->cur_mux[adc_idx] == idx && !force)
287 return 0;
288 spec->cur_mux[adc_idx] = idx;
289
290 if (spec->dyn_adc_switch) {
291 alc_dyn_adc_pcm_resetup(codec, idx);
292 adc_idx = spec->dyn_adc_idx[idx];
293 }
294
295 nid = spec->capsrc_nids ?
296 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
297
298 /* no selection? */
299 if (snd_hda_get_conn_list(codec, nid, NULL) <= 1)
300 return 1;
301
513 type = get_wcaps_type(get_wcaps(codec, nid)); 302 type = get_wcaps_type(get_wcaps(codec, nid));
514 if (type == AC_WID_AUD_MIX) { 303 if (type == AC_WID_AUD_MIX) {
515 /* Matrix-mixer style (e.g. ALC882) */ 304 /* 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++) { 305 for (i = 0; i < imux->num_items; i++) {
525 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 306 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
526 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 307 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
527 imux->items[i].index, 308 imux->items[i].index,
528 HDA_AMP_MUTE, v); 309 HDA_AMP_MUTE, v);
529 } 310 }
530 *cur_val = idx;
531 return 1;
532 } else { 311 } else {
533 /* MUX style (e.g. ALC880) */ 312 /* 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 */
542static 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
551static 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
561static 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 */
590static const char * const alc_pin_mode_names[] = {
591 "Mic 50pc bias", "Mic 80pc bias",
592 "Line in", "Line out", "Headphone out",
593};
594static 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 */
613static 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
625static 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
641static 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
661static 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, 313 snd_hda_codec_write_cache(codec, nid, 0,
680 AC_VERB_SET_PIN_WIDGET_CONTROL, 314 AC_VERB_SET_CONNECT_SEL,
681 alc_pin_mode_values[val]); 315 imux->items[idx].index);
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 } 316 }
705 return change; 317 return 1;
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
724static 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}
737static 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
779static 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}
792static 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
831static 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} 318}
844 319
845static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 320static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
846 struct snd_ctl_elem_value *ucontrol) 321 struct snd_ctl_elem_value *ucontrol)
847{ 322{
848 int change;
849 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 323 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
850 hda_nid_t nid = kcontrol->private_value & 0xffff; 324 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
851 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 325 return alc_mux_select(codec, adc_idx,
852 long val = *ucontrol->value.integer.value; 326 ucontrol->value.enumerated.item[0], false);
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} 327}
868 328
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/* 329/*
879 * set up the input pin config (depending on the given auto-pin type) 330 * set up the input pin config (depending on the given auto-pin type)
880 */ 331 */
@@ -903,29 +354,10 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
903 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 354 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
904} 355}
905 356
906static 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/* 357/*
358 * Append the given mixer and verb elements for the later use
359 * The mixer array is referred in build_controls(), and init_verbs are
360 * called in init().
929 */ 361 */
930static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) 362static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
931{ 363{
@@ -942,61 +374,8 @@ static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
942} 374}
943 375
944/* 376/*
945 * set up from the preset table 377 * GPIO setup tables, used in initialization
946 */ 378 */
947static 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 */ 379/* Enable GPIO mask and set output */
1001static const struct hda_verb alc_gpio1_init_verbs[] = { 380static const struct hda_verb alc_gpio1_init_verbs[] = {
1002 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 381 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
@@ -1051,14 +430,19 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1051 alc_fix_pll(codec); 430 alc_fix_pll(codec);
1052} 431}
1053 432
433/*
434 * Jack-reporting via input-jack layer
435 */
436
437/* initialization of jacks; currently checks only a few known pins */
1054static int alc_init_jacks(struct hda_codec *codec) 438static int alc_init_jacks(struct hda_codec *codec)
1055{ 439{
1056#ifdef CONFIG_SND_HDA_INPUT_JACK 440#ifdef CONFIG_SND_HDA_INPUT_JACK
1057 struct alc_spec *spec = codec->spec; 441 struct alc_spec *spec = codec->spec;
1058 int err; 442 int err;
1059 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 443 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1060 unsigned int mic_nid = spec->ext_mic.pin; 444 unsigned int mic_nid = spec->ext_mic_pin;
1061 unsigned int dock_nid = spec->dock_mic.pin; 445 unsigned int dock_nid = spec->dock_mic_pin;
1062 446
1063 if (hp_nid) { 447 if (hp_nid) {
1064 err = snd_hda_input_jack_add(codec, hp_nid, 448 err = snd_hda_input_jack_add(codec, hp_nid,
@@ -1086,7 +470,12 @@ static int alc_init_jacks(struct hda_codec *codec)
1086 return 0; 470 return 0;
1087} 471}
1088 472
1089static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 473/*
474 * Jack detections for HP auto-mute and mic-switch
475 */
476
477/* check each pin in the given array; returns true if any of them is plugged */
478static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1090{ 479{
1091 int i, present = 0; 480 int i, present = 0;
1092 481
@@ -1100,6 +489,7 @@ static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1100 return present; 489 return present;
1101} 490}
1102 491
492/* standard HP/line-out auto-mute helper */
1103static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, 493static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1104 bool mute, bool hp_out) 494 bool mute, bool hp_out)
1105{ 495{
@@ -1141,6 +531,13 @@ static void update_speakers(struct hda_codec *codec)
1141 struct alc_spec *spec = codec->spec; 531 struct alc_spec *spec = codec->spec;
1142 int on; 532 int on;
1143 533
534 /* Control HP pins/amps depending on master_mute state;
535 * in general, HP pins/amps control should be enabled in all cases,
536 * but currently set only for master_mute, just to be safe
537 */
538 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
539 spec->autocfg.hp_pins, spec->master_mute, true);
540
1144 if (!spec->automute) 541 if (!spec->automute)
1145 on = 0; 542 on = 0;
1146 else 543 else
@@ -1163,6 +560,7 @@ static void update_speakers(struct hda_codec *codec)
1163 spec->autocfg.line_out_pins, on, false); 560 spec->autocfg.line_out_pins, on, false);
1164} 561}
1165 562
563/* standard HP-automute helper */
1166static void alc_hp_automute(struct hda_codec *codec) 564static void alc_hp_automute(struct hda_codec *codec)
1167{ 565{
1168 struct alc_spec *spec = codec->spec; 566 struct alc_spec *spec = codec->spec;
@@ -1175,6 +573,7 @@ static void alc_hp_automute(struct hda_codec *codec)
1175 update_speakers(codec); 573 update_speakers(codec);
1176} 574}
1177 575
576/* standard line-out-automute helper */
1178static void alc_line_automute(struct hda_codec *codec) 577static void alc_line_automute(struct hda_codec *codec)
1179{ 578{
1180 struct alc_spec *spec = codec->spec; 579 struct alc_spec *spec = codec->spec;
@@ -1187,106 +586,33 @@ static void alc_line_automute(struct hda_codec *codec)
1187 update_speakers(codec); 586 update_speakers(codec);
1188} 587}
1189 588
1190static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 589#define get_connection_index(codec, mux, nid) \
1191 hda_nid_t nid) 590 snd_hda_get_conn_index(codec, mux, nid, 0)
1192{
1193 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1194 int i, nums;
1195
1196 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1197 for (i = 0; i < nums; i++)
1198 if (conn[i] == nid)
1199 return i;
1200 return -1;
1201}
1202
1203/* switch the current ADC according to the jack state */
1204static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1205{
1206 struct alc_spec *spec = codec->spec;
1207 unsigned int present;
1208 hda_nid_t new_adc;
1209
1210 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1211 if (present)
1212 spec->cur_adc_idx = 1;
1213 else
1214 spec->cur_adc_idx = 0;
1215 new_adc = spec->adc_nids[spec->cur_adc_idx];
1216 if (spec->cur_adc && spec->cur_adc != new_adc) {
1217 /* stream is running, let's swap the current ADC */
1218 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1219 spec->cur_adc = new_adc;
1220 snd_hda_codec_setup_stream(codec, new_adc,
1221 spec->cur_adc_stream_tag, 0,
1222 spec->cur_adc_format);
1223 }
1224}
1225 591
592/* standard mic auto-switch helper */
1226static void alc_mic_automute(struct hda_codec *codec) 593static void alc_mic_automute(struct hda_codec *codec)
1227{ 594{
1228 struct alc_spec *spec = codec->spec; 595 struct alc_spec *spec = codec->spec;
1229 struct alc_mic_route *dead1, *dead2, *alive; 596 hda_nid_t *pins = spec->imux_pins;
1230 unsigned int present, type;
1231 hda_nid_t cap_nid;
1232 597
1233 if (!spec->auto_mic) 598 if (!spec->auto_mic || !spec->auto_mic_valid_imux)
1234 return;
1235 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1236 return; 599 return;
1237 if (snd_BUG_ON(!spec->adc_nids)) 600 if (snd_BUG_ON(!spec->adc_nids))
1238 return; 601 return;
1239 602 if (snd_BUG_ON(spec->int_mic_idx < 0 || spec->ext_mic_idx < 0))
1240 if (spec->dual_adc_switch) {
1241 alc_dual_mic_adc_auto_switch(codec);
1242 return; 603 return;
1243 }
1244
1245 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1246 604
1247 alive = &spec->int_mic; 605 if (snd_hda_jack_detect(codec, pins[spec->ext_mic_idx]))
1248 dead1 = &spec->ext_mic; 606 alc_mux_select(codec, 0, spec->ext_mic_idx, false);
1249 dead2 = &spec->dock_mic; 607 else if (spec->dock_mic_idx >= 0 &&
1250 608 snd_hda_jack_detect(codec, pins[spec->dock_mic_idx]))
1251 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 609 alc_mux_select(codec, 0, spec->dock_mic_idx, false);
1252 if (present) { 610 else
1253 alive = &spec->ext_mic; 611 alc_mux_select(codec, 0, spec->int_mic_idx, false);
1254 dead1 = &spec->int_mic;
1255 dead2 = &spec->dock_mic;
1256 }
1257 if (!present && spec->dock_mic.pin > 0) {
1258 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1259 if (present) {
1260 alive = &spec->dock_mic;
1261 dead1 = &spec->int_mic;
1262 dead2 = &spec->ext_mic;
1263 }
1264 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1265 }
1266
1267 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1268 if (type == AC_WID_AUD_MIX) {
1269 /* Matrix-mixer style (e.g. ALC882) */
1270 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1271 alive->mux_idx,
1272 HDA_AMP_MUTE, 0);
1273 if (dead1->pin > 0)
1274 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1275 dead1->mux_idx,
1276 HDA_AMP_MUTE, HDA_AMP_MUTE);
1277 if (dead2->pin > 0)
1278 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1279 dead2->mux_idx,
1280 HDA_AMP_MUTE, HDA_AMP_MUTE);
1281 } else {
1282 /* MUX style (e.g. ALC880) */
1283 snd_hda_codec_write_cache(codec, cap_nid, 0,
1284 AC_VERB_SET_CONNECT_SEL,
1285 alive->mux_idx);
1286 }
1287 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1288 612
1289 /* FIXME: analog mixer */ 613 snd_hda_input_jack_report(codec, pins[spec->ext_mic_idx]);
614 if (spec->dock_mic_idx >= 0)
615 snd_hda_input_jack_report(codec, pins[spec->dock_mic_idx]);
1290} 616}
1291 617
1292/* unsolicited event for HP jack sensing */ 618/* unsolicited event for HP jack sensing */
@@ -1297,18 +623,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1297 else 623 else
1298 res >>= 26; 624 res >>= 26;
1299 switch (res) { 625 switch (res) {
1300 case ALC880_HP_EVENT: 626 case ALC_HP_EVENT:
1301 alc_hp_automute(codec); 627 alc_hp_automute(codec);
1302 break; 628 break;
1303 case ALC880_FRONT_EVENT: 629 case ALC_FRONT_EVENT:
1304 alc_line_automute(codec); 630 alc_line_automute(codec);
1305 break; 631 break;
1306 case ALC880_MIC_EVENT: 632 case ALC_MIC_EVENT:
1307 alc_mic_automute(codec); 633 alc_mic_automute(codec);
1308 break; 634 break;
1309 } 635 }
1310} 636}
1311 637
638/* call init functions of standard auto-mute helpers */
1312static void alc_inithook(struct hda_codec *codec) 639static void alc_inithook(struct hda_codec *codec)
1313{ 640{
1314 alc_hp_automute(codec); 641 alc_hp_automute(codec);
@@ -1334,6 +661,7 @@ static void alc888_coef_init(struct hda_codec *codec)
1334 AC_VERB_SET_PROC_COEF, 0x3030); 661 AC_VERB_SET_PROC_COEF, 0x3030);
1335} 662}
1336 663
664/* additional initialization for ALC889 variants */
1337static void alc889_coef_init(struct hda_codec *codec) 665static void alc889_coef_init(struct hda_codec *codec)
1338{ 666{
1339 unsigned int tmp; 667 unsigned int tmp;
@@ -1358,28 +686,12 @@ static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1358static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) 686static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1359{ 687{
1360 /* We currently only handle front, HP */ 688 /* We currently only handle front, HP */
1361 switch (codec->vendor_id) { 689 static hda_nid_t pins[] = {
1362 case 0x10ec0260: 690 0x0f, 0x10, 0x14, 0x15, 0
1363 set_eapd(codec, 0x0f, on); 691 };
1364 set_eapd(codec, 0x10, on); 692 hda_nid_t *p;
1365 break; 693 for (p = pins; *p; p++)
1366 case 0x10ec0262: 694 set_eapd(codec, *p, on);
1367 case 0x10ec0267:
1368 case 0x10ec0268:
1369 case 0x10ec0269:
1370 case 0x10ec0270:
1371 case 0x10ec0272:
1372 case 0x10ec0660:
1373 case 0x10ec0662:
1374 case 0x10ec0663:
1375 case 0x10ec0665:
1376 case 0x10ec0862:
1377 case 0x10ec0889:
1378 case 0x10ec0892:
1379 set_eapd(codec, 0x14, on);
1380 set_eapd(codec, 0x15, on);
1381 break;
1382 }
1383} 695}
1384 696
1385/* generic shutup callback; 697/* generic shutup callback;
@@ -1391,10 +703,12 @@ static void alc_eapd_shutup(struct hda_codec *codec)
1391 msleep(200); 703 msleep(200);
1392} 704}
1393 705
706/* generic EAPD initialization */
1394static void alc_auto_init_amp(struct hda_codec *codec, int type) 707static void alc_auto_init_amp(struct hda_codec *codec, int type)
1395{ 708{
1396 unsigned int tmp; 709 unsigned int tmp;
1397 710
711 alc_auto_setup_eapd(codec, true);
1398 switch (type) { 712 switch (type) {
1399 case ALC_INIT_GPIO1: 713 case ALC_INIT_GPIO1:
1400 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 714 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
@@ -1406,7 +720,6 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1406 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 720 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1407 break; 721 break;
1408 case ALC_INIT_DEFAULT: 722 case ALC_INIT_DEFAULT:
1409 alc_auto_setup_eapd(codec, true);
1410 switch (codec->vendor_id) { 723 switch (codec->vendor_id) {
1411 case 0x10ec0260: 724 case 0x10ec0260:
1412 snd_hda_codec_write(codec, 0x1a, 0, 725 snd_hda_codec_write(codec, 0x1a, 0,
@@ -1450,6 +763,9 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1450 } 763 }
1451} 764}
1452 765
766/*
767 * Auto-Mute mode mixer enum support
768 */
1453static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, 769static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1454 struct snd_ctl_elem_info *uinfo) 770 struct snd_ctl_elem_info *uinfo)
1455{ 771{
@@ -1536,7 +852,11 @@ static const struct snd_kcontrol_new alc_automute_mode_enum = {
1536 .put = alc_automute_mode_put, 852 .put = alc_automute_mode_put,
1537}; 853};
1538 854
1539static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec); 855static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
856{
857 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
858 return snd_array_new(&spec->kctls);
859}
1540 860
1541static int alc_add_automute_mode_enum(struct hda_codec *codec) 861static int alc_add_automute_mode_enum(struct hda_codec *codec)
1542{ 862{
@@ -1553,6 +873,10 @@ static int alc_add_automute_mode_enum(struct hda_codec *codec)
1553 return 0; 873 return 0;
1554} 874}
1555 875
876/*
877 * Check the availability of HP/line-out auto-mute;
878 * Set up appropriately if really supported
879 */
1556static void alc_init_auto_hp(struct hda_codec *codec) 880static void alc_init_auto_hp(struct hda_codec *codec)
1557{ 881{
1558 struct alc_spec *spec = codec->spec; 882 struct alc_spec *spec = codec->spec;
@@ -1571,13 +895,15 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1571 if (present == 3) 895 if (present == 3)
1572 spec->automute_hp_lo = 1; /* both HP and LO automute */ 896 spec->automute_hp_lo = 1; /* both HP and LO automute */
1573 897
1574 if (!cfg->speaker_pins[0]) { 898 if (!cfg->speaker_pins[0] &&
899 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
1575 memcpy(cfg->speaker_pins, cfg->line_out_pins, 900 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1576 sizeof(cfg->speaker_pins)); 901 sizeof(cfg->speaker_pins));
1577 cfg->speaker_outs = cfg->line_outs; 902 cfg->speaker_outs = cfg->line_outs;
1578 } 903 }
1579 904
1580 if (!cfg->hp_pins[0]) { 905 if (!cfg->hp_pins[0] &&
906 cfg->line_out_type == AUTO_PIN_HP_OUT) {
1581 memcpy(cfg->hp_pins, cfg->line_out_pins, 907 memcpy(cfg->hp_pins, cfg->line_out_pins,
1582 sizeof(cfg->hp_pins)); 908 sizeof(cfg->hp_pins));
1583 cfg->hp_outs = cfg->line_outs; 909 cfg->hp_outs = cfg->line_outs;
@@ -1591,11 +917,12 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1591 nid); 917 nid);
1592 snd_hda_codec_write_cache(codec, nid, 0, 918 snd_hda_codec_write_cache(codec, nid, 0,
1593 AC_VERB_SET_UNSOLICITED_ENABLE, 919 AC_VERB_SET_UNSOLICITED_ENABLE,
1594 AC_USRSP_EN | ALC880_HP_EVENT); 920 AC_USRSP_EN | ALC_HP_EVENT);
1595 spec->automute = 1; 921 spec->automute = 1;
1596 spec->automute_mode = ALC_AUTOMUTE_PIN; 922 spec->automute_mode = ALC_AUTOMUTE_PIN;
1597 } 923 }
1598 if (spec->automute && cfg->line_out_pins[0] && 924 if (spec->automute && cfg->line_out_pins[0] &&
925 cfg->speaker_pins[0] &&
1599 cfg->line_out_pins[0] != cfg->hp_pins[0] && 926 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1600 cfg->line_out_pins[0] != cfg->speaker_pins[0]) { 927 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1601 for (i = 0; i < cfg->line_outs; i++) { 928 for (i = 0; i < cfg->line_outs; i++) {
@@ -1606,7 +933,7 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1606 "on NID 0x%x\n", nid); 933 "on NID 0x%x\n", nid);
1607 snd_hda_codec_write_cache(codec, nid, 0, 934 snd_hda_codec_write_cache(codec, nid, 0,
1608 AC_VERB_SET_UNSOLICITED_ENABLE, 935 AC_VERB_SET_UNSOLICITED_ENABLE,
1609 AC_USRSP_EN | ALC880_FRONT_EVENT); 936 AC_USRSP_EN | ALC_FRONT_EVENT);
1610 spec->detect_line = 1; 937 spec->detect_line = 1;
1611 } 938 }
1612 spec->automute_lines = spec->detect_line; 939 spec->automute_lines = spec->detect_line;
@@ -1619,6 +946,132 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1619 } 946 }
1620} 947}
1621 948
949/* return the position of NID in the list, or -1 if not found */
950static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
951{
952 int i;
953 for (i = 0; i < nums; i++)
954 if (list[i] == nid)
955 return i;
956 return -1;
957}
958
959/* check whether dynamic ADC-switching is available */
960static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
961{
962 struct alc_spec *spec = codec->spec;
963 struct hda_input_mux *imux = &spec->private_imux[0];
964 int i, n, idx;
965 hda_nid_t cap, pin;
966
967 if (imux != spec->input_mux) /* no dynamic imux? */
968 return false;
969
970 for (n = 0; n < spec->num_adc_nids; n++) {
971 cap = spec->private_capsrc_nids[n];
972 for (i = 0; i < imux->num_items; i++) {
973 pin = spec->imux_pins[i];
974 if (!pin)
975 return false;
976 if (get_connection_index(codec, cap, pin) < 0)
977 break;
978 }
979 if (i >= imux->num_items)
980 return true; /* no ADC-switch is needed */
981 }
982
983 for (i = 0; i < imux->num_items; i++) {
984 pin = spec->imux_pins[i];
985 for (n = 0; n < spec->num_adc_nids; n++) {
986 cap = spec->private_capsrc_nids[n];
987 idx = get_connection_index(codec, cap, pin);
988 if (idx >= 0) {
989 imux->items[i].index = idx;
990 spec->dyn_adc_idx[i] = n;
991 break;
992 }
993 }
994 }
995
996 snd_printdd("realtek: enabling ADC switching\n");
997 spec->dyn_adc_switch = 1;
998 return true;
999}
1000
1001/* rebuild imux for matching with the given auto-mic pins (if not yet) */
1002static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
1003{
1004 struct alc_spec *spec = codec->spec;
1005 struct hda_input_mux *imux;
1006 static char * const texts[3] = {
1007 "Mic", "Internal Mic", "Dock Mic"
1008 };
1009 int i;
1010
1011 if (!spec->auto_mic)
1012 return false;
1013 imux = &spec->private_imux[0];
1014 if (spec->input_mux == imux)
1015 return true;
1016 spec->imux_pins[0] = spec->ext_mic_pin;
1017 spec->imux_pins[1] = spec->int_mic_pin;
1018 spec->imux_pins[2] = spec->dock_mic_pin;
1019 for (i = 0; i < 3; i++) {
1020 strcpy(imux->items[i].label, texts[i]);
1021 if (spec->imux_pins[i])
1022 imux->num_items = i + 1;
1023 }
1024 spec->num_mux_defs = 1;
1025 spec->input_mux = imux;
1026 return true;
1027}
1028
1029/* check whether all auto-mic pins are valid; setup indices if OK */
1030static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1031{
1032 struct alc_spec *spec = codec->spec;
1033 const struct hda_input_mux *imux;
1034
1035 if (!spec->auto_mic)
1036 return false;
1037 if (spec->auto_mic_valid_imux)
1038 return true; /* already checked */
1039
1040 /* fill up imux indices */
1041 if (!alc_check_dyn_adc_switch(codec)) {
1042 spec->auto_mic = 0;
1043 return false;
1044 }
1045
1046 imux = spec->input_mux;
1047 spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin,
1048 spec->imux_pins, imux->num_items);
1049 spec->int_mic_idx = find_idx_in_nid_list(spec->int_mic_pin,
1050 spec->imux_pins, imux->num_items);
1051 spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin,
1052 spec->imux_pins, imux->num_items);
1053 if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) {
1054 spec->auto_mic = 0;
1055 return false; /* no corresponding imux */
1056 }
1057
1058 snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0,
1059 AC_VERB_SET_UNSOLICITED_ENABLE,
1060 AC_USRSP_EN | ALC_MIC_EVENT);
1061 if (spec->dock_mic_pin)
1062 snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0,
1063 AC_VERB_SET_UNSOLICITED_ENABLE,
1064 AC_USRSP_EN | ALC_MIC_EVENT);
1065
1066 spec->auto_mic_valid_imux = 1;
1067 spec->auto_mic = 1;
1068 return true;
1069}
1070
1071/*
1072 * Check the availability of auto-mic switch;
1073 * Set up if really supported
1074 */
1622static void alc_init_auto_mic(struct hda_codec *codec) 1075static void alc_init_auto_mic(struct hda_codec *codec)
1623{ 1076{
1624 struct alc_spec *spec = codec->spec; 1077 struct alc_spec *spec = codec->spec;
@@ -1626,6 +1079,8 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1626 hda_nid_t fixed, ext, dock; 1079 hda_nid_t fixed, ext, dock;
1627 int i; 1080 int i;
1628 1081
1082 spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1;
1083
1629 fixed = ext = dock = 0; 1084 fixed = ext = dock = 0;
1630 for (i = 0; i < cfg->num_inputs; i++) { 1085 for (i = 0; i < cfg->num_inputs; i++) {
1631 hda_nid_t nid = cfg->inputs[i].pin; 1086 hda_nid_t nid = cfg->inputs[i].pin;
@@ -1667,21 +1122,32 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1667 return; /* no unsol support */ 1122 return; /* no unsol support */
1668 if (dock && !is_jack_detectable(codec, dock)) 1123 if (dock && !is_jack_detectable(codec, dock))
1669 return; /* no unsol support */ 1124 return; /* no unsol support */
1125
1126 /* check imux indices */
1127 spec->ext_mic_pin = ext;
1128 spec->int_mic_pin = fixed;
1129 spec->dock_mic_pin = dock;
1130
1131 spec->auto_mic = 1;
1132 if (!alc_auto_mic_check_imux(codec))
1133 return;
1134
1670 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", 1135 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1671 ext, fixed, dock); 1136 ext, fixed, dock);
1672 spec->ext_mic.pin = ext;
1673 spec->dock_mic.pin = dock;
1674 spec->int_mic.pin = fixed;
1675 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1676 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1677 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1678 spec->auto_mic = 1;
1679 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1680 AC_VERB_SET_UNSOLICITED_ENABLE,
1681 AC_USRSP_EN | ALC880_MIC_EVENT);
1682 spec->unsol_event = alc_sku_unsol_event; 1137 spec->unsol_event = alc_sku_unsol_event;
1683} 1138}
1684 1139
1140/* check the availabilities of auto-mute and auto-mic switches */
1141static void alc_auto_check_switches(struct hda_codec *codec)
1142{
1143 alc_init_auto_hp(codec);
1144 alc_init_auto_mic(codec);
1145}
1146
1147/*
1148 * Realtek SSID verification
1149 */
1150
1685/* Could be any non-zero and even value. When used as fixup, tells 1151/* Could be any non-zero and even value. When used as fixup, tells
1686 * the driver to ignore any present sku defines. 1152 * the driver to ignore any present sku defines.
1687 */ 1153 */
@@ -1752,6 +1218,12 @@ do_sku:
1752 return 0; 1218 return 0;
1753} 1219}
1754 1220
1221/* return true if the given NID is found in the list */
1222static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1223{
1224 return find_idx_in_nid_list(nid, list, nums) >= 0;
1225}
1226
1755/* check subsystem ID and set up device-specific initialization; 1227/* check subsystem ID and set up device-specific initialization;
1756 * return 1 if initialized, 0 if invalid SSID 1228 * return 1 if initialized, 0 if invalid SSID
1757 */ 1229 */
@@ -1861,27 +1333,24 @@ do_sku:
1861 nid = porti; 1333 nid = porti;
1862 else 1334 else
1863 return 1; 1335 return 1;
1864 for (i = 0; i < spec->autocfg.line_outs; i++) 1336 if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
1865 if (spec->autocfg.line_out_pins[i] == nid) 1337 spec->autocfg.line_outs))
1866 return 1; 1338 return 1;
1867 spec->autocfg.hp_pins[0] = nid; 1339 spec->autocfg.hp_pins[0] = nid;
1868 } 1340 }
1869 return 1; 1341 return 1;
1870} 1342}
1871 1343
1872static void alc_ssid_check(struct hda_codec *codec, 1344/* Check the validity of ALC subsystem-id
1873 hda_nid_t porta, hda_nid_t porte, 1345 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
1874 hda_nid_t portd, hda_nid_t porti) 1346static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
1875{ 1347{
1876 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) { 1348 if (!alc_subsystem_id(codec, ports[0], ports[1], ports[2], ports[3])) {
1877 struct alc_spec *spec = codec->spec; 1349 struct alc_spec *spec = codec->spec;
1878 snd_printd("realtek: " 1350 snd_printd("realtek: "
1879 "Enable default setup for auto mode as fallback\n"); 1351 "Enable default setup for auto mode as fallback\n");
1880 spec->init_amp = ALC_INIT_DEFAULT; 1352 spec->init_amp = ALC_INIT_DEFAULT;
1881 } 1353 }
1882
1883 alc_init_auto_hp(codec);
1884 alc_init_auto_mic(codec);
1885} 1354}
1886 1355
1887/* 1356/*
@@ -2029,6 +1498,9 @@ static void alc_pick_fixup(struct hda_codec *codec,
2029 } 1498 }
2030} 1499}
2031 1500
1501/*
1502 * COEF access helper functions
1503 */
2032static int alc_read_coef_idx(struct hda_codec *codec, 1504static int alc_read_coef_idx(struct hda_codec *codec,
2033 unsigned int coef_idx) 1505 unsigned int coef_idx)
2034{ 1506{
@@ -2049,20 +1521,32 @@ static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2049 coef_val); 1521 coef_val);
2050} 1522}
2051 1523
1524/*
1525 * Digital I/O handling
1526 */
1527
2052/* set right pin controls for digital I/O */ 1528/* set right pin controls for digital I/O */
2053static void alc_auto_init_digital(struct hda_codec *codec) 1529static void alc_auto_init_digital(struct hda_codec *codec)
2054{ 1530{
2055 struct alc_spec *spec = codec->spec; 1531 struct alc_spec *spec = codec->spec;
2056 int i; 1532 int i;
2057 hda_nid_t pin; 1533 hda_nid_t pin, dac;
2058 1534
2059 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1535 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2060 pin = spec->autocfg.dig_out_pins[i]; 1536 pin = spec->autocfg.dig_out_pins[i];
2061 if (pin) { 1537 if (!pin)
2062 snd_hda_codec_write(codec, pin, 0, 1538 continue;
2063 AC_VERB_SET_PIN_WIDGET_CONTROL, 1539 snd_hda_codec_write(codec, pin, 0,
2064 PIN_OUT); 1540 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2065 } 1541 if (!i)
1542 dac = spec->multiout.dig_out_nid;
1543 else
1544 dac = spec->slave_dig_outs[i - 1];
1545 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
1546 continue;
1547 snd_hda_codec_write(codec, dac, 0,
1548 AC_VERB_SET_AMP_GAIN_MUTE,
1549 AMP_OUT_UNMUTE);
2066 } 1550 }
2067 pin = spec->autocfg.dig_in_pin; 1551 pin = spec->autocfg.dig_in_pin;
2068 if (pin) 1552 if (pin)
@@ -2080,11 +1564,13 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
2080 1564
2081 /* support multiple SPDIFs; the secondary is set up as a slave */ 1565 /* support multiple SPDIFs; the secondary is set up as a slave */
2082 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1566 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1567 hda_nid_t conn[4];
2083 err = snd_hda_get_connections(codec, 1568 err = snd_hda_get_connections(codec,
2084 spec->autocfg.dig_out_pins[i], 1569 spec->autocfg.dig_out_pins[i],
2085 &dig_nid, 1); 1570 conn, ARRAY_SIZE(conn));
2086 if (err < 0) 1571 if (err < 0)
2087 continue; 1572 continue;
1573 dig_nid = conn[0]; /* assume the first element is audio-out */
2088 if (!i) { 1574 if (!i) {
2089 spec->multiout.dig_out_nid = dig_nid; 1575 spec->multiout.dig_out_nid = dig_nid;
2090 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 1576 spec->dig_out_type = spec->autocfg.dig_out_type[0];
@@ -2117,572 +1603,22 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
2117} 1603}
2118 1604
2119/* 1605/*
2120 * ALC888 1606 * capture mixer elements
2121 */ 1607 */
2122
2123/*
2124 * 2ch mode
2125 */
2126static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2127/* Mic-in jack as mic in */
2128 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2129 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2130/* Line-in jack as Line in */
2131 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2132 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2133/* Line-Out as Front */
2134 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2135 { } /* end */
2136};
2137
2138/*
2139 * 4ch mode
2140 */
2141static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2142/* Mic-in jack as mic in */
2143 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2144 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2145/* Line-in jack as Surround */
2146 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2147 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2148/* Line-Out as Front */
2149 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2150 { } /* end */
2151};
2152
2153/*
2154 * 6ch mode
2155 */
2156static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2157/* Mic-in jack as CLFE */
2158 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2159 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2160/* Line-in jack as Surround */
2161 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2162 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2163/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2164 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2165 { } /* end */
2166};
2167
2168/*
2169 * 8ch mode
2170 */
2171static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2172/* Mic-in jack as CLFE */
2173 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2174 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2175/* Line-in jack as Surround */
2176 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2177 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2178/* Line-Out as Side */
2179 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2180 { } /* end */
2181};
2182
2183static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2184 { 2, alc888_4ST_ch2_intel_init },
2185 { 4, alc888_4ST_ch4_intel_init },
2186 { 6, alc888_4ST_ch6_intel_init },
2187 { 8, alc888_4ST_ch8_intel_init },
2188};
2189
2190/*
2191 * ALC888 Fujitsu Siemens Amillo xa3530
2192 */
2193
2194static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2195/* Front Mic: set to PIN_IN (empty by default) */
2196 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2197/* Connect Internal HP to Front */
2198 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2199 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2200 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2201/* Connect Bass HP to Front */
2202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2203 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2204 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2205/* Connect Line-Out side jack (SPDIF) to Side */
2206 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2207 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2208 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2209/* Connect Mic jack to CLFE */
2210 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2211 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2212 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2213/* Connect Line-in jack to Surround */
2214 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2215 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2216 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2217/* Connect HP out jack to Front */
2218 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2219 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2220 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2221/* Enable unsolicited event for HP jack and Line-out jack */
2222 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2223 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2224 {}
2225};
2226
2227static void alc889_automute_setup(struct hda_codec *codec)
2228{
2229 struct alc_spec *spec = codec->spec;
2230
2231 spec->autocfg.hp_pins[0] = 0x15;
2232 spec->autocfg.speaker_pins[0] = 0x14;
2233 spec->autocfg.speaker_pins[1] = 0x16;
2234 spec->autocfg.speaker_pins[2] = 0x17;
2235 spec->autocfg.speaker_pins[3] = 0x19;
2236 spec->autocfg.speaker_pins[4] = 0x1a;
2237 spec->automute = 1;
2238 spec->automute_mode = ALC_AUTOMUTE_AMP;
2239}
2240
2241static void alc889_intel_init_hook(struct hda_codec *codec)
2242{
2243 alc889_coef_init(codec);
2244 alc_hp_automute(codec);
2245}
2246
2247static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2248{
2249 struct alc_spec *spec = codec->spec;
2250
2251 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2252 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2253 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2254 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2255 spec->automute = 1;
2256 spec->automute_mode = ALC_AUTOMUTE_AMP;
2257}
2258
2259/*
2260 * ALC888 Acer Aspire 4930G model
2261 */
2262
2263static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2264/* Front Mic: set to PIN_IN (empty by default) */
2265 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2266/* Unselect Front Mic by default in input mixer 3 */
2267 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2268/* Enable unsolicited event for HP jack */
2269 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2270/* Connect Internal HP to front */
2271 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2272 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2273 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2274/* Connect HP out to front */
2275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2276 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2277 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2278 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2279 { }
2280};
2281
2282/*
2283 * ALC888 Acer Aspire 6530G model
2284 */
2285
2286static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2287/* Route to built-in subwoofer as well as speakers */
2288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2290 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2291 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2292/* Bias voltage on for external mic port */
2293 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2294/* Front Mic: set to PIN_IN (empty by default) */
2295 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2296/* Unselect Front Mic by default in input mixer 3 */
2297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2298/* Enable unsolicited event for HP jack */
2299 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2300/* Enable speaker output */
2301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2302 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2303 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2304/* Enable headphone output */
2305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2306 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2308 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2309 { }
2310};
2311
2312/*
2313 *ALC888 Acer Aspire 7730G model
2314 */
2315
2316static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2317/* Bias voltage on for external mic port */
2318 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2319/* Front Mic: set to PIN_IN (empty by default) */
2320 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2321/* Unselect Front Mic by default in input mixer 3 */
2322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2323/* Enable unsolicited event for HP jack */
2324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2325/* Enable speaker output */
2326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2327 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2328 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2329/* Enable headphone output */
2330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2333 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2334/*Enable internal subwoofer */
2335 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2337 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2338 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2339 { }
2340};
2341
2342/*
2343 * ALC889 Acer Aspire 8930G model
2344 */
2345
2346static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2347/* Front Mic: set to PIN_IN (empty by default) */
2348 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2349/* Unselect Front Mic by default in input mixer 3 */
2350 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2351/* Enable unsolicited event for HP jack */
2352 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2353/* Connect Internal Front to Front */
2354 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2355 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2356 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2357/* Connect Internal Rear to Rear */
2358 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2359 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2360 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2361/* Connect Internal CLFE to CLFE */
2362 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2363 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2364 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2365/* Connect HP out to Front */
2366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2368 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2369/* Enable all DACs */
2370/* DAC DISABLE/MUTE 1? */
2371/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2372 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2373 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2374/* DAC DISABLE/MUTE 2? */
2375/* some bit here disables the other DACs. Init=0x4900 */
2376 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2377 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2378/* DMIC fix
2379 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2380 * which makes the stereo useless. However, either the mic or the ALC889
2381 * makes the signal become a difference/sum signal instead of standard
2382 * stereo, which is annoying. So instead we flip this bit which makes the
2383 * codec replicate the sum signal to both channels, turning it into a
2384 * normal mono mic.
2385 */
2386/* DMIC_CONTROL? Init value = 0x0001 */
2387 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2388 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2389 { }
2390};
2391
2392static const struct hda_input_mux alc888_2_capture_sources[2] = {
2393 /* Front mic only available on one ADC */
2394 {
2395 .num_items = 4,
2396 .items = {
2397 { "Mic", 0x0 },
2398 { "Line", 0x2 },
2399 { "CD", 0x4 },
2400 { "Front Mic", 0xb },
2401 },
2402 },
2403 {
2404 .num_items = 3,
2405 .items = {
2406 { "Mic", 0x0 },
2407 { "Line", 0x2 },
2408 { "CD", 0x4 },
2409 },
2410 }
2411};
2412
2413static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2414 /* Interal mic only available on one ADC */
2415 {
2416 .num_items = 5,
2417 .items = {
2418 { "Mic", 0x0 },
2419 { "Line In", 0x2 },
2420 { "CD", 0x4 },
2421 { "Input Mix", 0xa },
2422 { "Internal Mic", 0xb },
2423 },
2424 },
2425 {
2426 .num_items = 4,
2427 .items = {
2428 { "Mic", 0x0 },
2429 { "Line In", 0x2 },
2430 { "CD", 0x4 },
2431 { "Input Mix", 0xa },
2432 },
2433 }
2434};
2435
2436static const struct hda_input_mux alc889_capture_sources[3] = {
2437 /* Digital mic only available on first "ADC" */
2438 {
2439 .num_items = 5,
2440 .items = {
2441 { "Mic", 0x0 },
2442 { "Line", 0x2 },
2443 { "CD", 0x4 },
2444 { "Front Mic", 0xb },
2445 { "Input Mix", 0xa },
2446 },
2447 },
2448 {
2449 .num_items = 4,
2450 .items = {
2451 { "Mic", 0x0 },
2452 { "Line", 0x2 },
2453 { "CD", 0x4 },
2454 { "Input Mix", 0xa },
2455 },
2456 },
2457 {
2458 .num_items = 4,
2459 .items = {
2460 { "Mic", 0x0 },
2461 { "Line", 0x2 },
2462 { "CD", 0x4 },
2463 { "Input Mix", 0xa },
2464 },
2465 }
2466};
2467
2468static const struct snd_kcontrol_new alc888_base_mixer[] = {
2469 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2470 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2471 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2472 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2473 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2474 HDA_OUTPUT),
2475 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2476 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2477 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2478 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2479 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2480 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2481 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2482 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2483 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2484 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2485 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2487 { } /* end */
2488};
2489
2490static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2491 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2492 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2493 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2494 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2495 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2496 HDA_OUTPUT),
2497 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2498 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2499 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2500 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2501 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2502 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2503 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2504 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2505 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2507 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2508 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2509 { } /* end */
2510};
2511
2512static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2513 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2514 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2515 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2516 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2517 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2518 HDA_OUTPUT),
2519 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2520 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2521 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2522 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2523 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2524 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2525 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2526 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2527 { } /* end */
2528};
2529
2530
2531static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2532{
2533 struct alc_spec *spec = codec->spec;
2534
2535 spec->autocfg.hp_pins[0] = 0x15;
2536 spec->autocfg.speaker_pins[0] = 0x14;
2537 spec->autocfg.speaker_pins[1] = 0x16;
2538 spec->autocfg.speaker_pins[2] = 0x17;
2539 spec->automute = 1;
2540 spec->automute_mode = ALC_AUTOMUTE_AMP;
2541}
2542
2543static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2544{
2545 struct alc_spec *spec = codec->spec;
2546
2547 spec->autocfg.hp_pins[0] = 0x15;
2548 spec->autocfg.speaker_pins[0] = 0x14;
2549 spec->autocfg.speaker_pins[1] = 0x16;
2550 spec->autocfg.speaker_pins[2] = 0x17;
2551 spec->automute = 1;
2552 spec->automute_mode = ALC_AUTOMUTE_AMP;
2553}
2554
2555static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2556{
2557 struct alc_spec *spec = codec->spec;
2558
2559 spec->autocfg.hp_pins[0] = 0x15;
2560 spec->autocfg.speaker_pins[0] = 0x14;
2561 spec->autocfg.speaker_pins[1] = 0x16;
2562 spec->autocfg.speaker_pins[2] = 0x17;
2563 spec->automute = 1;
2564 spec->automute_mode = ALC_AUTOMUTE_AMP;
2565}
2566
2567static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2568{
2569 struct alc_spec *spec = codec->spec;
2570
2571 spec->autocfg.hp_pins[0] = 0x15;
2572 spec->autocfg.speaker_pins[0] = 0x14;
2573 spec->autocfg.speaker_pins[1] = 0x16;
2574 spec->autocfg.speaker_pins[2] = 0x1b;
2575 spec->automute = 1;
2576 spec->automute_mode = ALC_AUTOMUTE_AMP;
2577}
2578
2579/*
2580 * ALC880 3-stack model
2581 *
2582 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2583 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2584 * F-Mic = 0x1b, HP = 0x19
2585 */
2586
2587static const hda_nid_t alc880_dac_nids[4] = {
2588 /* front, rear, clfe, rear_surr */
2589 0x02, 0x05, 0x04, 0x03
2590};
2591
2592static const hda_nid_t alc880_adc_nids[3] = {
2593 /* ADC0-2 */
2594 0x07, 0x08, 0x09,
2595};
2596
2597/* The datasheet says the node 0x07 is connected from inputs,
2598 * but it shows zero connection in the real implementation on some devices.
2599 * Note: this is a 915GAV bug, fixed on 915GLV
2600 */
2601static const hda_nid_t alc880_adc_nids_alt[2] = {
2602 /* ADC1-2 */
2603 0x08, 0x09,
2604};
2605
2606#define ALC880_DIGOUT_NID 0x06
2607#define ALC880_DIGIN_NID 0x0a
2608
2609static const struct hda_input_mux alc880_capture_source = {
2610 .num_items = 4,
2611 .items = {
2612 { "Mic", 0x0 },
2613 { "Front Mic", 0x3 },
2614 { "Line", 0x2 },
2615 { "CD", 0x4 },
2616 },
2617};
2618
2619/* channel source setting (2/6 channel selection for 3-stack) */
2620/* 2ch mode */
2621static const struct hda_verb alc880_threestack_ch2_init[] = {
2622 /* set line-in to input, mute it */
2623 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2624 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2625 /* set mic-in to input vref 80%, mute it */
2626 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2627 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2628 { } /* end */
2629};
2630
2631/* 6ch mode */
2632static const struct hda_verb alc880_threestack_ch6_init[] = {
2633 /* set line-in to output, unmute it */
2634 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2635 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2636 /* set mic-in to output, unmute it */
2637 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2638 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2639 { } /* end */
2640};
2641
2642static const struct hda_channel_mode alc880_threestack_modes[2] = {
2643 { 2, alc880_threestack_ch2_init },
2644 { 6, alc880_threestack_ch6_init },
2645};
2646
2647static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2648 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2649 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2650 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2651 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2652 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2653 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2654 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2655 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2656 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2657 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2658 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2659 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2662 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2663 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2664 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2665 {
2666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2667 .name = "Channel Mode",
2668 .info = alc_ch_mode_info,
2669 .get = alc_ch_mode_get,
2670 .put = alc_ch_mode_put,
2671 },
2672 { } /* end */
2673};
2674
2675/* capture mixer elements */
2676static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 1608static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2677 struct snd_ctl_elem_info *uinfo) 1609 struct snd_ctl_elem_info *uinfo)
2678{ 1610{
2679 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1611 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2680 struct alc_spec *spec = codec->spec; 1612 struct alc_spec *spec = codec->spec;
1613 unsigned long val;
2681 int err; 1614 int err;
2682 1615
2683 mutex_lock(&codec->control_mutex); 1616 mutex_lock(&codec->control_mutex);
2684 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1617 if (spec->vol_in_capsrc)
2685 HDA_INPUT); 1618 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
1619 else
1620 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
1621 kcontrol->private_value = val;
2686 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 1622 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2687 mutex_unlock(&codec->control_mutex); 1623 mutex_unlock(&codec->control_mutex);
2688 return err; 1624 return err;
@@ -2693,11 +1629,15 @@ static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2693{ 1629{
2694 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1630 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2695 struct alc_spec *spec = codec->spec; 1631 struct alc_spec *spec = codec->spec;
1632 unsigned long val;
2696 int err; 1633 int err;
2697 1634
2698 mutex_lock(&codec->control_mutex); 1635 mutex_lock(&codec->control_mutex);
2699 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1636 if (spec->vol_in_capsrc)
2700 HDA_INPUT); 1637 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
1638 else
1639 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
1640 kcontrol->private_value = val;
2701 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 1641 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2702 mutex_unlock(&codec->control_mutex); 1642 mutex_unlock(&codec->control_mutex);
2703 return err; 1643 return err;
@@ -2708,17 +1648,35 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2708 1648
2709static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 1649static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2710 struct snd_ctl_elem_value *ucontrol, 1650 struct snd_ctl_elem_value *ucontrol,
2711 getput_call_t func) 1651 getput_call_t func, bool check_adc_switch)
2712{ 1652{
2713 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1653 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2714 struct alc_spec *spec = codec->spec; 1654 struct alc_spec *spec = codec->spec;
2715 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 1655 int i, err = 0;
2716 int err;
2717 1656
2718 mutex_lock(&codec->control_mutex); 1657 mutex_lock(&codec->control_mutex);
2719 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 1658 if (check_adc_switch && spec->dyn_adc_switch) {
2720 3, 0, HDA_INPUT); 1659 for (i = 0; i < spec->num_adc_nids; i++) {
2721 err = func(kcontrol, ucontrol); 1660 kcontrol->private_value =
1661 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
1662 3, 0, HDA_INPUT);
1663 err = func(kcontrol, ucontrol);
1664 if (err < 0)
1665 goto error;
1666 }
1667 } else {
1668 i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1669 if (spec->vol_in_capsrc)
1670 kcontrol->private_value =
1671 HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i],
1672 3, 0, HDA_OUTPUT);
1673 else
1674 kcontrol->private_value =
1675 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
1676 3, 0, HDA_INPUT);
1677 err = func(kcontrol, ucontrol);
1678 }
1679 error:
2722 mutex_unlock(&codec->control_mutex); 1680 mutex_unlock(&codec->control_mutex);
2723 return err; 1681 return err;
2724} 1682}
@@ -2727,14 +1685,14 @@ static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2727 struct snd_ctl_elem_value *ucontrol) 1685 struct snd_ctl_elem_value *ucontrol)
2728{ 1686{
2729 return alc_cap_getput_caller(kcontrol, ucontrol, 1687 return alc_cap_getput_caller(kcontrol, ucontrol,
2730 snd_hda_mixer_amp_volume_get); 1688 snd_hda_mixer_amp_volume_get, false);
2731} 1689}
2732 1690
2733static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, 1691static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2734 struct snd_ctl_elem_value *ucontrol) 1692 struct snd_ctl_elem_value *ucontrol)
2735{ 1693{
2736 return alc_cap_getput_caller(kcontrol, ucontrol, 1694 return alc_cap_getput_caller(kcontrol, ucontrol,
2737 snd_hda_mixer_amp_volume_put); 1695 snd_hda_mixer_amp_volume_put, true);
2738} 1696}
2739 1697
2740/* capture mixer elements */ 1698/* capture mixer elements */
@@ -2744,14 +1702,14 @@ static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2744 struct snd_ctl_elem_value *ucontrol) 1702 struct snd_ctl_elem_value *ucontrol)
2745{ 1703{
2746 return alc_cap_getput_caller(kcontrol, ucontrol, 1704 return alc_cap_getput_caller(kcontrol, ucontrol,
2747 snd_hda_mixer_amp_switch_get); 1705 snd_hda_mixer_amp_switch_get, false);
2748} 1706}
2749 1707
2750static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, 1708static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2751 struct snd_ctl_elem_value *ucontrol) 1709 struct snd_ctl_elem_value *ucontrol)
2752{ 1710{
2753 return alc_cap_getput_caller(kcontrol, ucontrol, 1711 return alc_cap_getput_caller(kcontrol, ucontrol,
2754 snd_hda_mixer_amp_switch_put); 1712 snd_hda_mixer_amp_switch_put, true);
2755} 1713}
2756 1714
2757#define _DEFINE_CAPMIX(num) \ 1715#define _DEFINE_CAPMIX(num) \
@@ -2810,335 +1768,6 @@ DEFINE_CAPMIX_NOSRC(2);
2810DEFINE_CAPMIX_NOSRC(3); 1768DEFINE_CAPMIX_NOSRC(3);
2811 1769
2812/* 1770/*
2813 * ALC880 5-stack model
2814 *
2815 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2816 * Side = 0x02 (0xd)
2817 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2818 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2819 */
2820
2821/* additional mixers to alc880_three_stack_mixer */
2822static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2823 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2824 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2825 { } /* end */
2826};
2827
2828/* channel source setting (6/8 channel selection for 5-stack) */
2829/* 6ch mode */
2830static const struct hda_verb alc880_fivestack_ch6_init[] = {
2831 /* set line-in to input, mute it */
2832 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2833 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2834 { } /* end */
2835};
2836
2837/* 8ch mode */
2838static const struct hda_verb alc880_fivestack_ch8_init[] = {
2839 /* set line-in to output, unmute it */
2840 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2841 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2842 { } /* end */
2843};
2844
2845static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2846 { 6, alc880_fivestack_ch6_init },
2847 { 8, alc880_fivestack_ch8_init },
2848};
2849
2850
2851/*
2852 * ALC880 6-stack model
2853 *
2854 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2855 * Side = 0x05 (0x0f)
2856 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2857 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2858 */
2859
2860static const hda_nid_t alc880_6st_dac_nids[4] = {
2861 /* front, rear, clfe, rear_surr */
2862 0x02, 0x03, 0x04, 0x05
2863};
2864
2865static const struct hda_input_mux alc880_6stack_capture_source = {
2866 .num_items = 4,
2867 .items = {
2868 { "Mic", 0x0 },
2869 { "Front Mic", 0x1 },
2870 { "Line", 0x2 },
2871 { "CD", 0x4 },
2872 },
2873};
2874
2875/* fixed 8-channels */
2876static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2877 { 8, NULL },
2878};
2879
2880static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2881 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2882 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2883 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2884 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2885 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2886 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2887 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2888 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2889 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2890 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2891 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2892 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2893 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2894 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2896 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2897 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2898 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2899 {
2900 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2901 .name = "Channel Mode",
2902 .info = alc_ch_mode_info,
2903 .get = alc_ch_mode_get,
2904 .put = alc_ch_mode_put,
2905 },
2906 { } /* end */
2907};
2908
2909
2910/*
2911 * ALC880 W810 model
2912 *
2913 * W810 has rear IO for:
2914 * Front (DAC 02)
2915 * Surround (DAC 03)
2916 * Center/LFE (DAC 04)
2917 * Digital out (06)
2918 *
2919 * The system also has a pair of internal speakers, and a headphone jack.
2920 * These are both connected to Line2 on the codec, hence to DAC 02.
2921 *
2922 * There is a variable resistor to control the speaker or headphone
2923 * volume. This is a hardware-only device without a software API.
2924 *
2925 * Plugging headphones in will disable the internal speakers. This is
2926 * implemented in hardware, not via the driver using jack sense. In
2927 * a similar fashion, plugging into the rear socket marked "front" will
2928 * disable both the speakers and headphones.
2929 *
2930 * For input, there's a microphone jack, and an "audio in" jack.
2931 * These may not do anything useful with this driver yet, because I
2932 * haven't setup any initialization verbs for these yet...
2933 */
2934
2935static const hda_nid_t alc880_w810_dac_nids[3] = {
2936 /* front, rear/surround, clfe */
2937 0x02, 0x03, 0x04
2938};
2939
2940/* fixed 6 channels */
2941static const struct hda_channel_mode alc880_w810_modes[1] = {
2942 { 6, NULL }
2943};
2944
2945/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2946static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2947 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2948 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2949 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2950 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2951 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2952 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2953 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2954 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2956 { } /* end */
2957};
2958
2959
2960/*
2961 * Z710V model
2962 *
2963 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2964 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2965 * Line = 0x1a
2966 */
2967
2968static const hda_nid_t alc880_z71v_dac_nids[1] = {
2969 0x02
2970};
2971#define ALC880_Z71V_HP_DAC 0x03
2972
2973/* fixed 2 channels */
2974static const struct hda_channel_mode alc880_2_jack_modes[1] = {
2975 { 2, NULL }
2976};
2977
2978static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
2979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2980 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2981 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2982 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2983 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2984 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2985 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2987 { } /* end */
2988};
2989
2990
2991/*
2992 * ALC880 F1734 model
2993 *
2994 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2995 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2996 */
2997
2998static const hda_nid_t alc880_f1734_dac_nids[1] = {
2999 0x03
3000};
3001#define ALC880_F1734_HP_DAC 0x02
3002
3003static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3004 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3005 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3006 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3007 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3008 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3009 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3011 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3012 { } /* end */
3013};
3014
3015static const struct hda_input_mux alc880_f1734_capture_source = {
3016 .num_items = 2,
3017 .items = {
3018 { "Mic", 0x1 },
3019 { "CD", 0x4 },
3020 },
3021};
3022
3023
3024/*
3025 * ALC880 ASUS model
3026 *
3027 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3028 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3029 * Mic = 0x18, Line = 0x1a
3030 */
3031
3032#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3033#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3034
3035static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3036 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3037 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3038 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3039 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3040 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3041 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3042 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3043 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3044 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3045 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3046 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3047 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3050 {
3051 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3052 .name = "Channel Mode",
3053 .info = alc_ch_mode_info,
3054 .get = alc_ch_mode_get,
3055 .put = alc_ch_mode_put,
3056 },
3057 { } /* end */
3058};
3059
3060/*
3061 * ALC880 ASUS W1V model
3062 *
3063 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3064 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3065 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3066 */
3067
3068/* additional mixers to alc880_asus_mixer */
3069static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3070 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3071 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3072 { } /* end */
3073};
3074
3075/* TCL S700 */
3076static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3077 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3078 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3079 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3080 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3081 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3082 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3083 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3084 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3085 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3086 { } /* end */
3087};
3088
3089/* Uniwill */
3090static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3091 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3092 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3093 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3094 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3095 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3096 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3097 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3098 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3099 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3100 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3101 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3102 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3104 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3105 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3106 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3107 {
3108 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3109 .name = "Channel Mode",
3110 .info = alc_ch_mode_info,
3111 .get = alc_ch_mode_get,
3112 .put = alc_ch_mode_put,
3113 },
3114 { } /* end */
3115};
3116
3117static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3118 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3119 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3120 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3121 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3122 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3123 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3125 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3126 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3127 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3128 { } /* end */
3129};
3130
3131static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3132 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3133 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3134 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3135 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3138 { } /* end */
3139};
3140
3141/*
3142 * virtual master controls 1771 * virtual master controls
3143 */ 1772 */
3144 1773
@@ -3217,6 +1846,7 @@ static int alc_build_controls(struct hda_codec *codec)
3217 } 1846 }
3218 if (spec->multiout.dig_out_nid) { 1847 if (spec->multiout.dig_out_nid) {
3219 err = snd_hda_create_spdif_out_ctls(codec, 1848 err = snd_hda_create_spdif_out_ctls(codec,
1849 spec->multiout.dig_out_nid,
3220 spec->multiout.dig_out_nid); 1850 spec->multiout.dig_out_nid);
3221 if (err < 0) 1851 if (err < 0)
3222 return err; 1852 return err;
@@ -3284,7 +1914,7 @@ static int alc_build_controls(struct hda_codec *codec)
3284 return err; 1914 return err;
3285 } 1915 }
3286 } 1916 }
3287 if (spec->cap_mixer) { 1917 if (spec->cap_mixer && spec->adc_nids) {
3288 const char *kname = kctl ? kctl->id.name : NULL; 1918 const char *kname = kctl ? kctl->id.name : NULL;
3289 for (knew = spec->cap_mixer; knew->name; knew++) { 1919 for (knew = spec->cap_mixer; knew->name; knew++) {
3290 if (kname && strcmp(knew->name, kname) == 0) 1920 if (kname && strcmp(knew->name, kname) == 0)
@@ -3348,789 +1978,6 @@ static int alc_build_controls(struct hda_codec *codec)
3348 1978
3349 1979
3350/* 1980/*
3351 * initialize the codec volumes, etc
3352 */
3353
3354/*
3355 * generic initialization of ADC, input mixers and output mixers
3356 */
3357static const struct hda_verb alc880_volume_init_verbs[] = {
3358 /*
3359 * Unmute ADC0-2 and set the default input to mic-in
3360 */
3361 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3362 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3363 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3364 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3365 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3366 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3367
3368 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3369 * mixer widget
3370 * Note: PASD motherboards uses the Line In 2 as the input for front
3371 * panel mic (mic 2)
3372 */
3373 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3374 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3375 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3376 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3377 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3378 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3379 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3380 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3381
3382 /*
3383 * Set up output mixers (0x0c - 0x0f)
3384 */
3385 /* set vol=0 to output mixers */
3386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3387 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3388 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3389 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3390 /* set up input amps for analog loopback */
3391 /* Amp Indices: DAC = 0, mixer = 1 */
3392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3394 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3395 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3396 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3397 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3398 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3399 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3400
3401 { }
3402};
3403
3404/*
3405 * 3-stack pin configuration:
3406 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3407 */
3408static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3409 /*
3410 * preset connection lists of input pins
3411 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3412 */
3413 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3414 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3415 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3416
3417 /*
3418 * Set pin mode and muting
3419 */
3420 /* set front pin widgets 0x14 for output */
3421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3422 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3423 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3425 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3426 /* Mic2 (as headphone out) for HP output */
3427 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3428 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3429 /* Line In pin widget for input */
3430 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3431 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3432 /* Line2 (as front mic) pin widget for input and vref at 80% */
3433 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3434 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3435 /* CD pin widget for input */
3436 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3437
3438 { }
3439};
3440
3441/*
3442 * 5-stack pin configuration:
3443 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3444 * line-in/side = 0x1a, f-mic = 0x1b
3445 */
3446static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3447 /*
3448 * preset connection lists of input pins
3449 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3450 */
3451 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3452 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3453
3454 /*
3455 * Set pin mode and muting
3456 */
3457 /* set pin widgets 0x14-0x17 for output */
3458 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3459 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3460 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3461 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3462 /* unmute pins for output (no gain on this amp) */
3463 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3464 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3465 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3466 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3467
3468 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3469 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3470 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3471 /* Mic2 (as headphone out) for HP output */
3472 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3473 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3474 /* Line In pin widget for input */
3475 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3476 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3477 /* Line2 (as front mic) pin widget for input and vref at 80% */
3478 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3479 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3480 /* CD pin widget for input */
3481 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3482
3483 { }
3484};
3485
3486/*
3487 * W810 pin configuration:
3488 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3489 */
3490static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3491 /* hphone/speaker input selector: front DAC */
3492 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3493
3494 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3495 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3496 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3498 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3499 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3500
3501 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3502 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3503
3504 { }
3505};
3506
3507/*
3508 * Z71V pin configuration:
3509 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3510 */
3511static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3512 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3513 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3515 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3516
3517 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3518 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3519 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3520 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3521
3522 { }
3523};
3524
3525/*
3526 * 6-stack pin configuration:
3527 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3528 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3529 */
3530static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3531 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3532
3533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3534 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3535 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3536 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3538 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3539 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3540 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541
3542 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3543 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3544 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3545 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3546 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3547 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3549 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3550 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3551
3552 { }
3553};
3554
3555/*
3556 * Uniwill pin configuration:
3557 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3558 * line = 0x1a
3559 */
3560static const struct hda_verb alc880_uniwill_init_verbs[] = {
3561 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3562
3563 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3564 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3565 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3566 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3567 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3568 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3569 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3570 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3571 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3573 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3574 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3575 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3576 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3577
3578 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3579 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3580 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3581 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3582 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3583 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3584 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3585 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3586 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3587
3588 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3589 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3590
3591 { }
3592};
3593
3594/*
3595* Uniwill P53
3596* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3597 */
3598static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3599 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3600
3601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3602 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3604 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3606 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3608 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3609 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3610 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3611 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3612 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3613
3614 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3615 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3616 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3617 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3618 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3619 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3620
3621 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3622 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3623
3624 { }
3625};
3626
3627static const struct hda_verb alc880_beep_init_verbs[] = {
3628 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3629 { }
3630};
3631
3632/* auto-toggle front mic */
3633static void alc88x_simple_mic_automute(struct hda_codec *codec)
3634{
3635 unsigned int present;
3636 unsigned char bits;
3637
3638 present = snd_hda_jack_detect(codec, 0x18);
3639 bits = present ? HDA_AMP_MUTE : 0;
3640 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3641}
3642
3643static void alc880_uniwill_setup(struct hda_codec *codec)
3644{
3645 struct alc_spec *spec = codec->spec;
3646
3647 spec->autocfg.hp_pins[0] = 0x14;
3648 spec->autocfg.speaker_pins[0] = 0x15;
3649 spec->autocfg.speaker_pins[0] = 0x16;
3650 spec->automute = 1;
3651 spec->automute_mode = ALC_AUTOMUTE_AMP;
3652}
3653
3654static void alc880_uniwill_init_hook(struct hda_codec *codec)
3655{
3656 alc_hp_automute(codec);
3657 alc88x_simple_mic_automute(codec);
3658}
3659
3660static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3661 unsigned int res)
3662{
3663 /* Looks like the unsol event is incompatible with the standard
3664 * definition. 4bit tag is placed at 28 bit!
3665 */
3666 switch (res >> 28) {
3667 case ALC880_MIC_EVENT:
3668 alc88x_simple_mic_automute(codec);
3669 break;
3670 default:
3671 alc_sku_unsol_event(codec, res);
3672 break;
3673 }
3674}
3675
3676static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3677{
3678 struct alc_spec *spec = codec->spec;
3679
3680 spec->autocfg.hp_pins[0] = 0x14;
3681 spec->autocfg.speaker_pins[0] = 0x15;
3682 spec->automute = 1;
3683 spec->automute_mode = ALC_AUTOMUTE_AMP;
3684}
3685
3686static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3687{
3688 unsigned int present;
3689
3690 present = snd_hda_codec_read(codec, 0x21, 0,
3691 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3692 present &= HDA_AMP_VOLMASK;
3693 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3694 HDA_AMP_VOLMASK, present);
3695 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3696 HDA_AMP_VOLMASK, present);
3697}
3698
3699static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3700 unsigned int res)
3701{
3702 /* Looks like the unsol event is incompatible with the standard
3703 * definition. 4bit tag is placed at 28 bit!
3704 */
3705 if ((res >> 28) == ALC880_DCVOL_EVENT)
3706 alc880_uniwill_p53_dcvol_automute(codec);
3707 else
3708 alc_sku_unsol_event(codec, res);
3709}
3710
3711/*
3712 * F1734 pin configuration:
3713 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3714 */
3715static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3716 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3717 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3718 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3719 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3720 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3721
3722 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3723 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3726
3727 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3731 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3733 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3734 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3735 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3736
3737 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3738 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3739
3740 { }
3741};
3742
3743/*
3744 * ASUS pin configuration:
3745 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3746 */
3747static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3748 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3749 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3750 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3751 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3752
3753 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3754 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3756 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3757 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3759 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3761
3762 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3763 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3765 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3766 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3768 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3769 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3770 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3771
3772 { }
3773};
3774
3775/* Enable GPIO mask and set output */
3776#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3777#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3778#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3779
3780/* Clevo m520g init */
3781static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3782 /* headphone output */
3783 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3784 /* line-out */
3785 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3786 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3787 /* Line-in */
3788 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3790 /* CD */
3791 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3792 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3793 /* Mic1 (rear panel) */
3794 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3795 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3796 /* Mic2 (front panel) */
3797 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3798 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3799 /* headphone */
3800 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3802 /* change to EAPD mode */
3803 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3804 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3805
3806 { }
3807};
3808
3809static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3810 /* change to EAPD mode */
3811 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3812 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3813
3814 /* Headphone output */
3815 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3816 /* Front output*/
3817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3818 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3819
3820 /* Line In pin widget for input */
3821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3822 /* CD pin widget for input */
3823 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3824 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3825 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3826
3827 /* change to EAPD mode */
3828 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3829 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3830
3831 { }
3832};
3833
3834/*
3835 * LG m1 express dual
3836 *
3837 * Pin assignment:
3838 * Rear Line-In/Out (blue): 0x14
3839 * Build-in Mic-In: 0x15
3840 * Speaker-out: 0x17
3841 * HP-Out (green): 0x1b
3842 * Mic-In/Out (red): 0x19
3843 * SPDIF-Out: 0x1e
3844 */
3845
3846/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3847static const hda_nid_t alc880_lg_dac_nids[3] = {
3848 0x05, 0x02, 0x03
3849};
3850
3851/* seems analog CD is not working */
3852static const struct hda_input_mux alc880_lg_capture_source = {
3853 .num_items = 3,
3854 .items = {
3855 { "Mic", 0x1 },
3856 { "Line", 0x5 },
3857 { "Internal Mic", 0x6 },
3858 },
3859};
3860
3861/* 2,4,6 channel modes */
3862static const struct hda_verb alc880_lg_ch2_init[] = {
3863 /* set line-in and mic-in to input */
3864 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3865 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3866 { }
3867};
3868
3869static const struct hda_verb alc880_lg_ch4_init[] = {
3870 /* set line-in to out and mic-in to input */
3871 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3872 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3873 { }
3874};
3875
3876static const struct hda_verb alc880_lg_ch6_init[] = {
3877 /* set line-in and mic-in to output */
3878 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3879 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3880 { }
3881};
3882
3883static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3884 { 2, alc880_lg_ch2_init },
3885 { 4, alc880_lg_ch4_init },
3886 { 6, alc880_lg_ch6_init },
3887};
3888
3889static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3890 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3891 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3892 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3893 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3894 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3895 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3896 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3897 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3902 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3903 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3904 {
3905 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3906 .name = "Channel Mode",
3907 .info = alc_ch_mode_info,
3908 .get = alc_ch_mode_get,
3909 .put = alc_ch_mode_put,
3910 },
3911 { } /* end */
3912};
3913
3914static const struct hda_verb alc880_lg_init_verbs[] = {
3915 /* set capture source to mic-in */
3916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3918 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3919 /* mute all amp mixer inputs */
3920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3923 /* line-in to input */
3924 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3925 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3926 /* built-in mic */
3927 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3928 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3929 /* speaker-out */
3930 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3931 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3932 /* mic-in to input */
3933 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3934 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3935 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3936 /* HP-out */
3937 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3938 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3939 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3940 /* jack sense */
3941 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3942 { }
3943};
3944
3945/* toggle speaker-output according to the hp-jack state */
3946static void alc880_lg_setup(struct hda_codec *codec)
3947{
3948 struct alc_spec *spec = codec->spec;
3949
3950 spec->autocfg.hp_pins[0] = 0x1b;
3951 spec->autocfg.speaker_pins[0] = 0x17;
3952 spec->automute = 1;
3953 spec->automute_mode = ALC_AUTOMUTE_AMP;
3954}
3955
3956/*
3957 * LG LW20
3958 *
3959 * Pin assignment:
3960 * Speaker-out: 0x14
3961 * Mic-In: 0x18
3962 * Built-in Mic-In: 0x19
3963 * Line-In: 0x1b
3964 * HP-Out: 0x1a
3965 * SPDIF-Out: 0x1e
3966 */
3967
3968static const struct hda_input_mux alc880_lg_lw_capture_source = {
3969 .num_items = 3,
3970 .items = {
3971 { "Mic", 0x0 },
3972 { "Internal Mic", 0x1 },
3973 { "Line In", 0x2 },
3974 },
3975};
3976
3977#define alc880_lg_lw_modes alc880_threestack_modes
3978
3979static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3980 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3981 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3982 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3983 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3984 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3985 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3986 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3987 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3988 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3989 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3990 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3992 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3993 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3994 {
3995 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3996 .name = "Channel Mode",
3997 .info = alc_ch_mode_info,
3998 .get = alc_ch_mode_get,
3999 .put = alc_ch_mode_put,
4000 },
4001 { } /* end */
4002};
4003
4004static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4005 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4006 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4007 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4008
4009 /* set capture source to mic-in */
4010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4011 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4012 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4014 /* speaker-out */
4015 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4016 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4017 /* HP-out */
4018 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4019 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4020 /* mic-in to input */
4021 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4022 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4023 /* built-in mic */
4024 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4025 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4026 /* jack sense */
4027 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4028 { }
4029};
4030
4031/* toggle speaker-output according to the hp-jack state */
4032static void alc880_lg_lw_setup(struct hda_codec *codec)
4033{
4034 struct alc_spec *spec = codec->spec;
4035
4036 spec->autocfg.hp_pins[0] = 0x1b;
4037 spec->autocfg.speaker_pins[0] = 0x14;
4038 spec->automute = 1;
4039 spec->automute_mode = ALC_AUTOMUTE_AMP;
4040}
4041
4042static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4043 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4044 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4045 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4046 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4047 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4048 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4049 { } /* end */
4050};
4051
4052static const struct hda_input_mux alc880_medion_rim_capture_source = {
4053 .num_items = 2,
4054 .items = {
4055 { "Mic", 0x0 },
4056 { "Internal Mic", 0x1 },
4057 },
4058};
4059
4060static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4061 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4062
4063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4064 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4065
4066 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4067 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4069 /* Mic2 (as headphone out) for HP output */
4070 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4071 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4072 /* Internal Speaker */
4073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4074 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4075
4076 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4077 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4078
4079 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4080 { }
4081};
4082
4083/* toggle speaker-output according to the hp-jack state */
4084static void alc880_medion_rim_automute(struct hda_codec *codec)
4085{
4086 struct alc_spec *spec = codec->spec;
4087 alc_hp_automute(codec);
4088 /* toggle EAPD */
4089 if (spec->jack_present)
4090 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4091 else
4092 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4093}
4094
4095static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4096 unsigned int res)
4097{
4098 /* Looks like the unsol event is incompatible with the standard
4099 * definition. 4bit tag is placed at 28 bit!
4100 */
4101 if ((res >> 28) == ALC880_HP_EVENT)
4102 alc880_medion_rim_automute(codec);
4103}
4104
4105static void alc880_medion_rim_setup(struct hda_codec *codec)
4106{
4107 struct alc_spec *spec = codec->spec;
4108
4109 spec->autocfg.hp_pins[0] = 0x14;
4110 spec->autocfg.speaker_pins[0] = 0x1b;
4111 spec->automute = 1;
4112 spec->automute_mode = ALC_AUTOMUTE_AMP;
4113}
4114
4115#ifdef CONFIG_SND_HDA_POWER_SAVE
4116static const struct hda_amp_list alc880_loopbacks[] = {
4117 { 0x0b, HDA_INPUT, 0 },
4118 { 0x0b, HDA_INPUT, 1 },
4119 { 0x0b, HDA_INPUT, 2 },
4120 { 0x0b, HDA_INPUT, 3 },
4121 { 0x0b, HDA_INPUT, 4 },
4122 { } /* end */
4123};
4124
4125static const struct hda_amp_list alc880_lg_loopbacks[] = {
4126 { 0x0b, HDA_INPUT, 1 },
4127 { 0x0b, HDA_INPUT, 6 },
4128 { 0x0b, HDA_INPUT, 7 },
4129 { } /* end */
4130};
4131#endif
4132
4133/*
4134 * Common callbacks 1981 * Common callbacks
4135 */ 1982 */
4136 1983
@@ -4176,7 +2023,7 @@ static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4176/* 2023/*
4177 * Analog playback callbacks 2024 * Analog playback callbacks
4178 */ 2025 */
4179static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 2026static int alc_playback_pcm_open(struct hda_pcm_stream *hinfo,
4180 struct hda_codec *codec, 2027 struct hda_codec *codec,
4181 struct snd_pcm_substream *substream) 2028 struct snd_pcm_substream *substream)
4182{ 2029{
@@ -4185,7 +2032,7 @@ static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4185 hinfo); 2032 hinfo);
4186} 2033}
4187 2034
4188static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2035static int alc_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4189 struct hda_codec *codec, 2036 struct hda_codec *codec,
4190 unsigned int stream_tag, 2037 unsigned int stream_tag,
4191 unsigned int format, 2038 unsigned int format,
@@ -4196,7 +2043,7 @@ static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4196 stream_tag, format, substream); 2043 stream_tag, format, substream);
4197} 2044}
4198 2045
4199static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2046static int alc_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4200 struct hda_codec *codec, 2047 struct hda_codec *codec,
4201 struct snd_pcm_substream *substream) 2048 struct snd_pcm_substream *substream)
4202{ 2049{
@@ -4207,7 +2054,7 @@ static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4207/* 2054/*
4208 * Digital out 2055 * Digital out
4209 */ 2056 */
4210static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 2057static int alc_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4211 struct hda_codec *codec, 2058 struct hda_codec *codec,
4212 struct snd_pcm_substream *substream) 2059 struct snd_pcm_substream *substream)
4213{ 2060{
@@ -4215,7 +2062,7 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4215 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 2062 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4216} 2063}
4217 2064
4218static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2065static int alc_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4219 struct hda_codec *codec, 2066 struct hda_codec *codec,
4220 unsigned int stream_tag, 2067 unsigned int stream_tag,
4221 unsigned int format, 2068 unsigned int format,
@@ -4226,7 +2073,7 @@ static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4226 stream_tag, format, substream); 2073 stream_tag, format, substream);
4227} 2074}
4228 2075
4229static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2076static int alc_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4230 struct hda_codec *codec, 2077 struct hda_codec *codec,
4231 struct snd_pcm_substream *substream) 2078 struct snd_pcm_substream *substream)
4232{ 2079{
@@ -4234,7 +2081,7 @@ static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4234 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 2081 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4235} 2082}
4236 2083
4237static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 2084static int alc_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4238 struct hda_codec *codec, 2085 struct hda_codec *codec,
4239 struct snd_pcm_substream *substream) 2086 struct snd_pcm_substream *substream)
4240{ 2087{
@@ -4245,7 +2092,7 @@ static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4245/* 2092/*
4246 * Analog capture 2093 * Analog capture
4247 */ 2094 */
4248static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 2095static int alc_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4249 struct hda_codec *codec, 2096 struct hda_codec *codec,
4250 unsigned int stream_tag, 2097 unsigned int stream_tag,
4251 unsigned int format, 2098 unsigned int format,
@@ -4258,7 +2105,7 @@ static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4258 return 0; 2105 return 0;
4259} 2106}
4260 2107
4261static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 2108static int alc_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4262 struct hda_codec *codec, 2109 struct hda_codec *codec,
4263 struct snd_pcm_substream *substream) 2110 struct snd_pcm_substream *substream)
4264{ 2111{
@@ -4270,21 +2117,21 @@ static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4270} 2117}
4271 2118
4272/* analog capture with dynamic dual-adc changes */ 2119/* analog capture with dynamic dual-adc changes */
4273static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 2120static int dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4274 struct hda_codec *codec, 2121 struct hda_codec *codec,
4275 unsigned int stream_tag, 2122 unsigned int stream_tag,
4276 unsigned int format, 2123 unsigned int format,
4277 struct snd_pcm_substream *substream) 2124 struct snd_pcm_substream *substream)
4278{ 2125{
4279 struct alc_spec *spec = codec->spec; 2126 struct alc_spec *spec = codec->spec;
4280 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; 2127 spec->cur_adc = spec->adc_nids[spec->dyn_adc_idx[spec->cur_mux[0]]];
4281 spec->cur_adc_stream_tag = stream_tag; 2128 spec->cur_adc_stream_tag = stream_tag;
4282 spec->cur_adc_format = format; 2129 spec->cur_adc_format = format;
4283 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 2130 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4284 return 0; 2131 return 0;
4285} 2132}
4286 2133
4287static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 2134static int dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4288 struct hda_codec *codec, 2135 struct hda_codec *codec,
4289 struct snd_pcm_substream *substream) 2136 struct snd_pcm_substream *substream)
4290{ 2137{
@@ -4294,70 +2141,70 @@ static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4294 return 0; 2141 return 0;
4295} 2142}
4296 2143
4297static const struct hda_pcm_stream dualmic_pcm_analog_capture = { 2144static const struct hda_pcm_stream dyn_adc_pcm_analog_capture = {
4298 .substreams = 1, 2145 .substreams = 1,
4299 .channels_min = 2, 2146 .channels_min = 2,
4300 .channels_max = 2, 2147 .channels_max = 2,
4301 .nid = 0, /* fill later */ 2148 .nid = 0, /* fill later */
4302 .ops = { 2149 .ops = {
4303 .prepare = dualmic_capture_pcm_prepare, 2150 .prepare = dyn_adc_capture_pcm_prepare,
4304 .cleanup = dualmic_capture_pcm_cleanup 2151 .cleanup = dyn_adc_capture_pcm_cleanup
4305 }, 2152 },
4306}; 2153};
4307 2154
4308/* 2155/*
4309 */ 2156 */
4310static const struct hda_pcm_stream alc880_pcm_analog_playback = { 2157static const struct hda_pcm_stream alc_pcm_analog_playback = {
4311 .substreams = 1, 2158 .substreams = 1,
4312 .channels_min = 2, 2159 .channels_min = 2,
4313 .channels_max = 8, 2160 .channels_max = 8,
4314 /* NID is set in alc_build_pcms */ 2161 /* NID is set in alc_build_pcms */
4315 .ops = { 2162 .ops = {
4316 .open = alc880_playback_pcm_open, 2163 .open = alc_playback_pcm_open,
4317 .prepare = alc880_playback_pcm_prepare, 2164 .prepare = alc_playback_pcm_prepare,
4318 .cleanup = alc880_playback_pcm_cleanup 2165 .cleanup = alc_playback_pcm_cleanup
4319 }, 2166 },
4320}; 2167};
4321 2168
4322static const struct hda_pcm_stream alc880_pcm_analog_capture = { 2169static const struct hda_pcm_stream alc_pcm_analog_capture = {
4323 .substreams = 1, 2170 .substreams = 1,
4324 .channels_min = 2, 2171 .channels_min = 2,
4325 .channels_max = 2, 2172 .channels_max = 2,
4326 /* NID is set in alc_build_pcms */ 2173 /* NID is set in alc_build_pcms */
4327}; 2174};
4328 2175
4329static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 2176static const struct hda_pcm_stream alc_pcm_analog_alt_playback = {
4330 .substreams = 1, 2177 .substreams = 1,
4331 .channels_min = 2, 2178 .channels_min = 2,
4332 .channels_max = 2, 2179 .channels_max = 2,
4333 /* NID is set in alc_build_pcms */ 2180 /* NID is set in alc_build_pcms */
4334}; 2181};
4335 2182
4336static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 2183static const struct hda_pcm_stream alc_pcm_analog_alt_capture = {
4337 .substreams = 2, /* can be overridden */ 2184 .substreams = 2, /* can be overridden */
4338 .channels_min = 2, 2185 .channels_min = 2,
4339 .channels_max = 2, 2186 .channels_max = 2,
4340 /* NID is set in alc_build_pcms */ 2187 /* NID is set in alc_build_pcms */
4341 .ops = { 2188 .ops = {
4342 .prepare = alc880_alt_capture_pcm_prepare, 2189 .prepare = alc_alt_capture_pcm_prepare,
4343 .cleanup = alc880_alt_capture_pcm_cleanup 2190 .cleanup = alc_alt_capture_pcm_cleanup
4344 }, 2191 },
4345}; 2192};
4346 2193
4347static const struct hda_pcm_stream alc880_pcm_digital_playback = { 2194static const struct hda_pcm_stream alc_pcm_digital_playback = {
4348 .substreams = 1, 2195 .substreams = 1,
4349 .channels_min = 2, 2196 .channels_min = 2,
4350 .channels_max = 2, 2197 .channels_max = 2,
4351 /* NID is set in alc_build_pcms */ 2198 /* NID is set in alc_build_pcms */
4352 .ops = { 2199 .ops = {
4353 .open = alc880_dig_playback_pcm_open, 2200 .open = alc_dig_playback_pcm_open,
4354 .close = alc880_dig_playback_pcm_close, 2201 .close = alc_dig_playback_pcm_close,
4355 .prepare = alc880_dig_playback_pcm_prepare, 2202 .prepare = alc_dig_playback_pcm_prepare,
4356 .cleanup = alc880_dig_playback_pcm_cleanup 2203 .cleanup = alc_dig_playback_pcm_cleanup
4357 }, 2204 },
4358}; 2205};
4359 2206
4360static const struct hda_pcm_stream alc880_pcm_digital_capture = { 2207static const struct hda_pcm_stream alc_pcm_digital_capture = {
4361 .substreams = 1, 2208 .substreams = 1,
4362 .channels_min = 2, 2209 .channels_min = 2,
4363 .channels_max = 2, 2210 .channels_max = 2,
@@ -4375,6 +2222,7 @@ static int alc_build_pcms(struct hda_codec *codec)
4375{ 2222{
4376 struct alc_spec *spec = codec->spec; 2223 struct alc_spec *spec = codec->spec;
4377 struct hda_pcm *info = spec->pcm_rec; 2224 struct hda_pcm *info = spec->pcm_rec;
2225 const struct hda_pcm_stream *p;
4378 int i; 2226 int i;
4379 2227
4380 codec->num_pcms = 1; 2228 codec->num_pcms = 1;
@@ -4387,16 +2235,22 @@ static int alc_build_pcms(struct hda_codec *codec)
4387 "%s Analog", codec->chip_name); 2235 "%s Analog", codec->chip_name);
4388 info->name = spec->stream_name_analog; 2236 info->name = spec->stream_name_analog;
4389 2237
4390 if (spec->stream_analog_playback) { 2238 if (spec->multiout.dac_nids > 0) {
4391 if (snd_BUG_ON(!spec->multiout.dac_nids)) 2239 p = spec->stream_analog_playback;
4392 return -EINVAL; 2240 if (!p)
4393 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 2241 p = &alc_pcm_analog_playback;
2242 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4394 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 2243 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4395 } 2244 }
4396 if (spec->stream_analog_capture) { 2245 if (spec->adc_nids) {
4397 if (snd_BUG_ON(!spec->adc_nids)) 2246 p = spec->stream_analog_capture;
4398 return -EINVAL; 2247 if (!p) {
4399 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2248 if (spec->dyn_adc_switch)
2249 p = &dyn_adc_pcm_analog_capture;
2250 else
2251 p = &alc_pcm_analog_capture;
2252 }
2253 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4400 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 2254 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4401 } 2255 }
4402 2256
@@ -4423,14 +2277,18 @@ static int alc_build_pcms(struct hda_codec *codec)
4423 info->pcm_type = spec->dig_out_type; 2277 info->pcm_type = spec->dig_out_type;
4424 else 2278 else
4425 info->pcm_type = HDA_PCM_TYPE_SPDIF; 2279 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4426 if (spec->multiout.dig_out_nid && 2280 if (spec->multiout.dig_out_nid) {
4427 spec->stream_digital_playback) { 2281 p = spec->stream_digital_playback;
4428 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 2282 if (!p)
2283 p = &alc_pcm_digital_playback;
2284 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4429 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 2285 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4430 } 2286 }
4431 if (spec->dig_in_nid && 2287 if (spec->dig_in_nid) {
4432 spec->stream_digital_capture) { 2288 p = spec->stream_digital_capture;
4433 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 2289 if (!p)
2290 p = &alc_pcm_digital_capture;
2291 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4434 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 2292 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4435 } 2293 }
4436 /* FIXME: do we need this for all Realtek codec models? */ 2294 /* FIXME: do we need this for all Realtek codec models? */
@@ -4444,14 +2302,15 @@ static int alc_build_pcms(struct hda_codec *codec)
4444 * model, configure a second analog capture-only PCM. 2302 * model, configure a second analog capture-only PCM.
4445 */ 2303 */
4446 /* Additional Analaog capture for index #2 */ 2304 /* Additional Analaog capture for index #2 */
4447 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 2305 if (spec->alt_dac_nid || spec->num_adc_nids > 1) {
4448 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4449 codec->num_pcms = 3; 2306 codec->num_pcms = 3;
4450 info = spec->pcm_rec + 2; 2307 info = spec->pcm_rec + 2;
4451 info->name = spec->stream_name_analog; 2308 info->name = spec->stream_name_analog;
4452 if (spec->alt_dac_nid) { 2309 if (spec->alt_dac_nid) {
4453 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 2310 p = spec->stream_analog_alt_playback;
4454 *spec->stream_analog_alt_playback; 2311 if (!p)
2312 p = &alc_pcm_analog_alt_playback;
2313 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4455 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 2314 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4456 spec->alt_dac_nid; 2315 spec->alt_dac_nid;
4457 } else { 2316 } else {
@@ -4459,9 +2318,11 @@ static int alc_build_pcms(struct hda_codec *codec)
4459 alc_pcm_null_stream; 2318 alc_pcm_null_stream;
4460 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 2319 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4461 } 2320 }
4462 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) { 2321 if (spec->num_adc_nids > 1) {
4463 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 2322 p = spec->stream_analog_alt_capture;
4464 *spec->stream_analog_alt_capture; 2323 if (!p)
2324 p = &alc_pcm_analog_alt_capture;
2325 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4465 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 2326 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4466 spec->adc_nids[1]; 2327 spec->adc_nids[1];
4467 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 2328 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
@@ -4528,7 +2389,7 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4528} 2389}
4529#endif 2390#endif
4530 2391
4531#ifdef SND_HDA_NEEDS_RESUME 2392#ifdef CONFIG_PM
4532static int alc_resume(struct hda_codec *codec) 2393static int alc_resume(struct hda_codec *codec)
4533{ 2394{
4534 msleep(150); /* to avoid pop noise */ 2395 msleep(150); /* to avoid pop noise */
@@ -4548,7 +2409,7 @@ static const struct hda_codec_ops alc_patch_ops = {
4548 .init = alc_init, 2409 .init = alc_init,
4549 .free = alc_free, 2410 .free = alc_free,
4550 .unsol_event = alc_unsol_event, 2411 .unsol_event = alc_unsol_event,
4551#ifdef SND_HDA_NEEDS_RESUME 2412#ifdef CONFIG_PM
4552 .resume = alc_resume, 2413 .resume = alc_resume,
4553#endif 2414#endif
4554#ifdef CONFIG_SND_HDA_POWER_SAVE 2415#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -4571,680 +2432,6 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name)
4571} 2432}
4572 2433
4573/* 2434/*
4574 * Test configuration for debugging
4575 *
4576 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4577 * enum controls.
4578 */
4579#ifdef CONFIG_SND_DEBUG
4580static const hda_nid_t alc880_test_dac_nids[4] = {
4581 0x02, 0x03, 0x04, 0x05
4582};
4583
4584static const struct hda_input_mux alc880_test_capture_source = {
4585 .num_items = 7,
4586 .items = {
4587 { "In-1", 0x0 },
4588 { "In-2", 0x1 },
4589 { "In-3", 0x2 },
4590 { "In-4", 0x3 },
4591 { "CD", 0x4 },
4592 { "Front", 0x5 },
4593 { "Surround", 0x6 },
4594 },
4595};
4596
4597static const struct hda_channel_mode alc880_test_modes[4] = {
4598 { 2, NULL },
4599 { 4, NULL },
4600 { 6, NULL },
4601 { 8, NULL },
4602};
4603
4604static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4605 struct snd_ctl_elem_info *uinfo)
4606{
4607 static const char * const texts[] = {
4608 "N/A", "Line Out", "HP Out",
4609 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4610 };
4611 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4612 uinfo->count = 1;
4613 uinfo->value.enumerated.items = 8;
4614 if (uinfo->value.enumerated.item >= 8)
4615 uinfo->value.enumerated.item = 7;
4616 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4617 return 0;
4618}
4619
4620static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4621 struct snd_ctl_elem_value *ucontrol)
4622{
4623 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4624 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4625 unsigned int pin_ctl, item = 0;
4626
4627 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4628 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4629 if (pin_ctl & AC_PINCTL_OUT_EN) {
4630 if (pin_ctl & AC_PINCTL_HP_EN)
4631 item = 2;
4632 else
4633 item = 1;
4634 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4635 switch (pin_ctl & AC_PINCTL_VREFEN) {
4636 case AC_PINCTL_VREF_HIZ: item = 3; break;
4637 case AC_PINCTL_VREF_50: item = 4; break;
4638 case AC_PINCTL_VREF_GRD: item = 5; break;
4639 case AC_PINCTL_VREF_80: item = 6; break;
4640 case AC_PINCTL_VREF_100: item = 7; break;
4641 }
4642 }
4643 ucontrol->value.enumerated.item[0] = item;
4644 return 0;
4645}
4646
4647static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4648 struct snd_ctl_elem_value *ucontrol)
4649{
4650 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4651 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4652 static const unsigned int ctls[] = {
4653 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4654 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4655 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4656 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4657 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4658 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4659 };
4660 unsigned int old_ctl, new_ctl;
4661
4662 old_ctl = snd_hda_codec_read(codec, nid, 0,
4663 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4664 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4665 if (old_ctl != new_ctl) {
4666 int val;
4667 snd_hda_codec_write_cache(codec, nid, 0,
4668 AC_VERB_SET_PIN_WIDGET_CONTROL,
4669 new_ctl);
4670 val = ucontrol->value.enumerated.item[0] >= 3 ?
4671 HDA_AMP_MUTE : 0;
4672 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4673 HDA_AMP_MUTE, val);
4674 return 1;
4675 }
4676 return 0;
4677}
4678
4679static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4680 struct snd_ctl_elem_info *uinfo)
4681{
4682 static const char * const texts[] = {
4683 "Front", "Surround", "CLFE", "Side"
4684 };
4685 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4686 uinfo->count = 1;
4687 uinfo->value.enumerated.items = 4;
4688 if (uinfo->value.enumerated.item >= 4)
4689 uinfo->value.enumerated.item = 3;
4690 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4691 return 0;
4692}
4693
4694static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4695 struct snd_ctl_elem_value *ucontrol)
4696{
4697 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4698 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4699 unsigned int sel;
4700
4701 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4702 ucontrol->value.enumerated.item[0] = sel & 3;
4703 return 0;
4704}
4705
4706static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4707 struct snd_ctl_elem_value *ucontrol)
4708{
4709 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4710 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4711 unsigned int sel;
4712
4713 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4714 if (ucontrol->value.enumerated.item[0] != sel) {
4715 sel = ucontrol->value.enumerated.item[0] & 3;
4716 snd_hda_codec_write_cache(codec, nid, 0,
4717 AC_VERB_SET_CONNECT_SEL, sel);
4718 return 1;
4719 }
4720 return 0;
4721}
4722
4723#define PIN_CTL_TEST(xname,nid) { \
4724 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4725 .name = xname, \
4726 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4727 .info = alc_test_pin_ctl_info, \
4728 .get = alc_test_pin_ctl_get, \
4729 .put = alc_test_pin_ctl_put, \
4730 .private_value = nid \
4731 }
4732
4733#define PIN_SRC_TEST(xname,nid) { \
4734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4735 .name = xname, \
4736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4737 .info = alc_test_pin_src_info, \
4738 .get = alc_test_pin_src_get, \
4739 .put = alc_test_pin_src_put, \
4740 .private_value = nid \
4741 }
4742
4743static const struct snd_kcontrol_new alc880_test_mixer[] = {
4744 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4745 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4746 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4747 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4748 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4749 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4750 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4751 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4752 PIN_CTL_TEST("Front Pin Mode", 0x14),
4753 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4754 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4755 PIN_CTL_TEST("Side Pin Mode", 0x17),
4756 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4757 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4758 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4759 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4760 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4761 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4762 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4763 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4764 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4765 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4766 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4767 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4768 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4769 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4770 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4771 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4772 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4773 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4774 {
4775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4776 .name = "Channel Mode",
4777 .info = alc_ch_mode_info,
4778 .get = alc_ch_mode_get,
4779 .put = alc_ch_mode_put,
4780 },
4781 { } /* end */
4782};
4783
4784static const struct hda_verb alc880_test_init_verbs[] = {
4785 /* Unmute inputs of 0x0c - 0x0f */
4786 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4788 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4789 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4790 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4791 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4792 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4793 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4794 /* Vol output for 0x0c-0x0f */
4795 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4796 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4797 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4798 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4799 /* Set output pins 0x14-0x17 */
4800 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4802 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4803 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4804 /* Unmute output pins 0x14-0x17 */
4805 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4806 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4807 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4808 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4809 /* Set input pins 0x18-0x1c */
4810 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4811 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4812 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4813 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4814 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4815 /* Mute input pins 0x18-0x1b */
4816 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4817 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4818 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4819 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4820 /* ADC set up */
4821 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4822 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4823 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4824 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4825 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4826 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4827 /* Analog input/passthru */
4828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4833 { }
4834};
4835#endif
4836
4837/*
4838 */
4839
4840static const char * const alc880_models[ALC880_MODEL_LAST] = {
4841 [ALC880_3ST] = "3stack",
4842 [ALC880_TCL_S700] = "tcl",
4843 [ALC880_3ST_DIG] = "3stack-digout",
4844 [ALC880_CLEVO] = "clevo",
4845 [ALC880_5ST] = "5stack",
4846 [ALC880_5ST_DIG] = "5stack-digout",
4847 [ALC880_W810] = "w810",
4848 [ALC880_Z71V] = "z71v",
4849 [ALC880_6ST] = "6stack",
4850 [ALC880_6ST_DIG] = "6stack-digout",
4851 [ALC880_ASUS] = "asus",
4852 [ALC880_ASUS_W1V] = "asus-w1v",
4853 [ALC880_ASUS_DIG] = "asus-dig",
4854 [ALC880_ASUS_DIG2] = "asus-dig2",
4855 [ALC880_UNIWILL_DIG] = "uniwill",
4856 [ALC880_UNIWILL_P53] = "uniwill-p53",
4857 [ALC880_FUJITSU] = "fujitsu",
4858 [ALC880_F1734] = "F1734",
4859 [ALC880_LG] = "lg",
4860 [ALC880_LG_LW] = "lg-lw",
4861 [ALC880_MEDION_RIM] = "medion",
4862#ifdef CONFIG_SND_DEBUG
4863 [ALC880_TEST] = "test",
4864#endif
4865 [ALC880_AUTO] = "auto",
4866};
4867
4868static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4869 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4870 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4871 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4872 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4873 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4874 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4875 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4876 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4877 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4878 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4879 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
4880 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4881 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4882 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4883 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4884 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4885 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4886 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4887 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4888 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4889 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4890 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4891 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4892 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4893 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4894 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4895 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4896 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4897 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4898 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4899 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4900 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4901 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4902 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4903 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4904 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4905 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4906 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4907 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4908 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4909 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4910 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4911 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4912 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4913 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4914 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4915 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4916 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4917 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4918 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4919 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4920 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4921 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4922 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4923 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4924 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4925 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4926 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4927 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4928 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4929 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4930 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4931 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4932 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4933 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4934 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4935 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4936 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4937 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4938 /* default Intel */
4939 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4940 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4941 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4942 {}
4943};
4944
4945/*
4946 * ALC880 codec presets
4947 */
4948static const struct alc_config_preset alc880_presets[] = {
4949 [ALC880_3ST] = {
4950 .mixers = { alc880_three_stack_mixer },
4951 .init_verbs = { alc880_volume_init_verbs,
4952 alc880_pin_3stack_init_verbs },
4953 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4954 .dac_nids = alc880_dac_nids,
4955 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4956 .channel_mode = alc880_threestack_modes,
4957 .need_dac_fix = 1,
4958 .input_mux = &alc880_capture_source,
4959 },
4960 [ALC880_3ST_DIG] = {
4961 .mixers = { alc880_three_stack_mixer },
4962 .init_verbs = { alc880_volume_init_verbs,
4963 alc880_pin_3stack_init_verbs },
4964 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4965 .dac_nids = alc880_dac_nids,
4966 .dig_out_nid = ALC880_DIGOUT_NID,
4967 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4968 .channel_mode = alc880_threestack_modes,
4969 .need_dac_fix = 1,
4970 .input_mux = &alc880_capture_source,
4971 },
4972 [ALC880_TCL_S700] = {
4973 .mixers = { alc880_tcl_s700_mixer },
4974 .init_verbs = { alc880_volume_init_verbs,
4975 alc880_pin_tcl_S700_init_verbs,
4976 alc880_gpio2_init_verbs },
4977 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4978 .dac_nids = alc880_dac_nids,
4979 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4980 .num_adc_nids = 1, /* single ADC */
4981 .hp_nid = 0x03,
4982 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4983 .channel_mode = alc880_2_jack_modes,
4984 .input_mux = &alc880_capture_source,
4985 },
4986 [ALC880_5ST] = {
4987 .mixers = { alc880_three_stack_mixer,
4988 alc880_five_stack_mixer},
4989 .init_verbs = { alc880_volume_init_verbs,
4990 alc880_pin_5stack_init_verbs },
4991 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4992 .dac_nids = alc880_dac_nids,
4993 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4994 .channel_mode = alc880_fivestack_modes,
4995 .input_mux = &alc880_capture_source,
4996 },
4997 [ALC880_5ST_DIG] = {
4998 .mixers = { alc880_three_stack_mixer,
4999 alc880_five_stack_mixer },
5000 .init_verbs = { alc880_volume_init_verbs,
5001 alc880_pin_5stack_init_verbs },
5002 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5003 .dac_nids = alc880_dac_nids,
5004 .dig_out_nid = ALC880_DIGOUT_NID,
5005 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5006 .channel_mode = alc880_fivestack_modes,
5007 .input_mux = &alc880_capture_source,
5008 },
5009 [ALC880_6ST] = {
5010 .mixers = { alc880_six_stack_mixer },
5011 .init_verbs = { alc880_volume_init_verbs,
5012 alc880_pin_6stack_init_verbs },
5013 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5014 .dac_nids = alc880_6st_dac_nids,
5015 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5016 .channel_mode = alc880_sixstack_modes,
5017 .input_mux = &alc880_6stack_capture_source,
5018 },
5019 [ALC880_6ST_DIG] = {
5020 .mixers = { alc880_six_stack_mixer },
5021 .init_verbs = { alc880_volume_init_verbs,
5022 alc880_pin_6stack_init_verbs },
5023 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5024 .dac_nids = alc880_6st_dac_nids,
5025 .dig_out_nid = ALC880_DIGOUT_NID,
5026 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5027 .channel_mode = alc880_sixstack_modes,
5028 .input_mux = &alc880_6stack_capture_source,
5029 },
5030 [ALC880_W810] = {
5031 .mixers = { alc880_w810_base_mixer },
5032 .init_verbs = { alc880_volume_init_verbs,
5033 alc880_pin_w810_init_verbs,
5034 alc880_gpio2_init_verbs },
5035 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5036 .dac_nids = alc880_w810_dac_nids,
5037 .dig_out_nid = ALC880_DIGOUT_NID,
5038 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5039 .channel_mode = alc880_w810_modes,
5040 .input_mux = &alc880_capture_source,
5041 },
5042 [ALC880_Z71V] = {
5043 .mixers = { alc880_z71v_mixer },
5044 .init_verbs = { alc880_volume_init_verbs,
5045 alc880_pin_z71v_init_verbs },
5046 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5047 .dac_nids = alc880_z71v_dac_nids,
5048 .dig_out_nid = ALC880_DIGOUT_NID,
5049 .hp_nid = 0x03,
5050 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5051 .channel_mode = alc880_2_jack_modes,
5052 .input_mux = &alc880_capture_source,
5053 },
5054 [ALC880_F1734] = {
5055 .mixers = { alc880_f1734_mixer },
5056 .init_verbs = { alc880_volume_init_verbs,
5057 alc880_pin_f1734_init_verbs },
5058 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5059 .dac_nids = alc880_f1734_dac_nids,
5060 .hp_nid = 0x02,
5061 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5062 .channel_mode = alc880_2_jack_modes,
5063 .input_mux = &alc880_f1734_capture_source,
5064 .unsol_event = alc880_uniwill_p53_unsol_event,
5065 .setup = alc880_uniwill_p53_setup,
5066 .init_hook = alc_hp_automute,
5067 },
5068 [ALC880_ASUS] = {
5069 .mixers = { alc880_asus_mixer },
5070 .init_verbs = { alc880_volume_init_verbs,
5071 alc880_pin_asus_init_verbs,
5072 alc880_gpio1_init_verbs },
5073 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5074 .dac_nids = alc880_asus_dac_nids,
5075 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5076 .channel_mode = alc880_asus_modes,
5077 .need_dac_fix = 1,
5078 .input_mux = &alc880_capture_source,
5079 },
5080 [ALC880_ASUS_DIG] = {
5081 .mixers = { alc880_asus_mixer },
5082 .init_verbs = { alc880_volume_init_verbs,
5083 alc880_pin_asus_init_verbs,
5084 alc880_gpio1_init_verbs },
5085 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5086 .dac_nids = alc880_asus_dac_nids,
5087 .dig_out_nid = ALC880_DIGOUT_NID,
5088 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5089 .channel_mode = alc880_asus_modes,
5090 .need_dac_fix = 1,
5091 .input_mux = &alc880_capture_source,
5092 },
5093 [ALC880_ASUS_DIG2] = {
5094 .mixers = { alc880_asus_mixer },
5095 .init_verbs = { alc880_volume_init_verbs,
5096 alc880_pin_asus_init_verbs,
5097 alc880_gpio2_init_verbs }, /* use GPIO2 */
5098 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5099 .dac_nids = alc880_asus_dac_nids,
5100 .dig_out_nid = ALC880_DIGOUT_NID,
5101 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5102 .channel_mode = alc880_asus_modes,
5103 .need_dac_fix = 1,
5104 .input_mux = &alc880_capture_source,
5105 },
5106 [ALC880_ASUS_W1V] = {
5107 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5108 .init_verbs = { alc880_volume_init_verbs,
5109 alc880_pin_asus_init_verbs,
5110 alc880_gpio1_init_verbs },
5111 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5112 .dac_nids = alc880_asus_dac_nids,
5113 .dig_out_nid = ALC880_DIGOUT_NID,
5114 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5115 .channel_mode = alc880_asus_modes,
5116 .need_dac_fix = 1,
5117 .input_mux = &alc880_capture_source,
5118 },
5119 [ALC880_UNIWILL_DIG] = {
5120 .mixers = { alc880_asus_mixer },
5121 .init_verbs = { alc880_volume_init_verbs,
5122 alc880_pin_asus_init_verbs },
5123 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5124 .dac_nids = alc880_asus_dac_nids,
5125 .dig_out_nid = ALC880_DIGOUT_NID,
5126 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5127 .channel_mode = alc880_asus_modes,
5128 .need_dac_fix = 1,
5129 .input_mux = &alc880_capture_source,
5130 },
5131 [ALC880_UNIWILL] = {
5132 .mixers = { alc880_uniwill_mixer },
5133 .init_verbs = { alc880_volume_init_verbs,
5134 alc880_uniwill_init_verbs },
5135 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5136 .dac_nids = alc880_asus_dac_nids,
5137 .dig_out_nid = ALC880_DIGOUT_NID,
5138 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5139 .channel_mode = alc880_threestack_modes,
5140 .need_dac_fix = 1,
5141 .input_mux = &alc880_capture_source,
5142 .unsol_event = alc880_uniwill_unsol_event,
5143 .setup = alc880_uniwill_setup,
5144 .init_hook = alc880_uniwill_init_hook,
5145 },
5146 [ALC880_UNIWILL_P53] = {
5147 .mixers = { alc880_uniwill_p53_mixer },
5148 .init_verbs = { alc880_volume_init_verbs,
5149 alc880_uniwill_p53_init_verbs },
5150 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5151 .dac_nids = alc880_asus_dac_nids,
5152 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5153 .channel_mode = alc880_threestack_modes,
5154 .input_mux = &alc880_capture_source,
5155 .unsol_event = alc880_uniwill_p53_unsol_event,
5156 .setup = alc880_uniwill_p53_setup,
5157 .init_hook = alc_hp_automute,
5158 },
5159 [ALC880_FUJITSU] = {
5160 .mixers = { alc880_fujitsu_mixer },
5161 .init_verbs = { alc880_volume_init_verbs,
5162 alc880_uniwill_p53_init_verbs,
5163 alc880_beep_init_verbs },
5164 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5165 .dac_nids = alc880_dac_nids,
5166 .dig_out_nid = ALC880_DIGOUT_NID,
5167 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5168 .channel_mode = alc880_2_jack_modes,
5169 .input_mux = &alc880_capture_source,
5170 .unsol_event = alc880_uniwill_p53_unsol_event,
5171 .setup = alc880_uniwill_p53_setup,
5172 .init_hook = alc_hp_automute,
5173 },
5174 [ALC880_CLEVO] = {
5175 .mixers = { alc880_three_stack_mixer },
5176 .init_verbs = { alc880_volume_init_verbs,
5177 alc880_pin_clevo_init_verbs },
5178 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5179 .dac_nids = alc880_dac_nids,
5180 .hp_nid = 0x03,
5181 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5182 .channel_mode = alc880_threestack_modes,
5183 .need_dac_fix = 1,
5184 .input_mux = &alc880_capture_source,
5185 },
5186 [ALC880_LG] = {
5187 .mixers = { alc880_lg_mixer },
5188 .init_verbs = { alc880_volume_init_verbs,
5189 alc880_lg_init_verbs },
5190 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5191 .dac_nids = alc880_lg_dac_nids,
5192 .dig_out_nid = ALC880_DIGOUT_NID,
5193 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5194 .channel_mode = alc880_lg_ch_modes,
5195 .need_dac_fix = 1,
5196 .input_mux = &alc880_lg_capture_source,
5197 .unsol_event = alc_sku_unsol_event,
5198 .setup = alc880_lg_setup,
5199 .init_hook = alc_hp_automute,
5200#ifdef CONFIG_SND_HDA_POWER_SAVE
5201 .loopbacks = alc880_lg_loopbacks,
5202#endif
5203 },
5204 [ALC880_LG_LW] = {
5205 .mixers = { alc880_lg_lw_mixer },
5206 .init_verbs = { alc880_volume_init_verbs,
5207 alc880_lg_lw_init_verbs },
5208 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5209 .dac_nids = alc880_dac_nids,
5210 .dig_out_nid = ALC880_DIGOUT_NID,
5211 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5212 .channel_mode = alc880_lg_lw_modes,
5213 .input_mux = &alc880_lg_lw_capture_source,
5214 .unsol_event = alc_sku_unsol_event,
5215 .setup = alc880_lg_lw_setup,
5216 .init_hook = alc_hp_automute,
5217 },
5218 [ALC880_MEDION_RIM] = {
5219 .mixers = { alc880_medion_rim_mixer },
5220 .init_verbs = { alc880_volume_init_verbs,
5221 alc880_medion_rim_init_verbs,
5222 alc_gpio2_init_verbs },
5223 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5224 .dac_nids = alc880_dac_nids,
5225 .dig_out_nid = ALC880_DIGOUT_NID,
5226 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5227 .channel_mode = alc880_2_jack_modes,
5228 .input_mux = &alc880_medion_rim_capture_source,
5229 .unsol_event = alc880_medion_rim_unsol_event,
5230 .setup = alc880_medion_rim_setup,
5231 .init_hook = alc880_medion_rim_automute,
5232 },
5233#ifdef CONFIG_SND_DEBUG
5234 [ALC880_TEST] = {
5235 .mixers = { alc880_test_mixer },
5236 .init_verbs = { alc880_test_init_verbs },
5237 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5238 .dac_nids = alc880_test_dac_nids,
5239 .dig_out_nid = ALC880_DIGOUT_NID,
5240 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5241 .channel_mode = alc880_test_modes,
5242 .input_mux = &alc880_test_capture_source,
5243 },
5244#endif
5245};
5246
5247/*
5248 * Automatic parse of I/O pins from the BIOS configuration 2435 * Automatic parse of I/O pins from the BIOS configuration
5249 */ 2436 */
5250 2437
@@ -5253,18 +2440,12 @@ enum {
5253 ALC_CTL_WIDGET_MUTE, 2440 ALC_CTL_WIDGET_MUTE,
5254 ALC_CTL_BIND_MUTE, 2441 ALC_CTL_BIND_MUTE,
5255}; 2442};
5256static const struct snd_kcontrol_new alc880_control_templates[] = { 2443static const struct snd_kcontrol_new alc_control_templates[] = {
5257 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2444 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5258 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2445 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5259 HDA_BIND_MUTE(NULL, 0, 0, 0), 2446 HDA_BIND_MUTE(NULL, 0, 0, 0),
5260}; 2447};
5261 2448
5262static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5263{
5264 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5265 return snd_array_new(&spec->kctls);
5266}
5267
5268/* add dynamic controls */ 2449/* add dynamic controls */
5269static int add_control(struct alc_spec *spec, int type, const char *name, 2450static int add_control(struct alc_spec *spec, int type, const char *name,
5270 int cidx, unsigned long val) 2451 int cidx, unsigned long val)
@@ -5274,7 +2455,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
5274 knew = alc_kcontrol_new(spec); 2455 knew = alc_kcontrol_new(spec);
5275 if (!knew) 2456 if (!knew)
5276 return -ENOMEM; 2457 return -ENOMEM;
5277 *knew = alc880_control_templates[type]; 2458 *knew = alc_control_templates[type];
5278 knew->name = kstrdup(name, GFP_KERNEL); 2459 knew->name = kstrdup(name, GFP_KERNEL);
5279 if (!knew->name) 2460 if (!knew->name)
5280 return -ENOMEM; 2461 return -ENOMEM;
@@ -5303,60 +2484,15 @@ static int add_control_with_pfx(struct alc_spec *spec, int type,
5303#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ 2484#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5304 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) 2485 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5305 2486
5306#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 2487static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5307#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 2488 bool can_be_master, int *index)
5308#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5309#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5310#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5311#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5312#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5313#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5314#define ALC880_PIN_CD_NID 0x1c
5315
5316/* fill in the dac_nids table from the parsed pin configuration */
5317static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5318 const struct auto_pin_cfg *cfg)
5319{
5320 hda_nid_t nid;
5321 int assigned[4];
5322 int i, j;
5323
5324 memset(assigned, 0, sizeof(assigned));
5325 spec->multiout.dac_nids = spec->private_dac_nids;
5326
5327 /* check the pins hardwired to audio widget */
5328 for (i = 0; i < cfg->line_outs; i++) {
5329 nid = cfg->line_out_pins[i];
5330 if (alc880_is_fixed_pin(nid)) {
5331 int idx = alc880_fixed_pin_idx(nid);
5332 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
5333 assigned[idx] = 1;
5334 }
5335 }
5336 /* left pins can be connect to any audio widget */
5337 for (i = 0; i < cfg->line_outs; i++) {
5338 nid = cfg->line_out_pins[i];
5339 if (alc880_is_fixed_pin(nid))
5340 continue;
5341 /* search for an empty channel */
5342 for (j = 0; j < cfg->line_outs; j++) {
5343 if (!assigned[j]) {
5344 spec->private_dac_nids[i] =
5345 alc880_idx_to_dac(j);
5346 assigned[j] = 1;
5347 break;
5348 }
5349 }
5350 }
5351 spec->multiout.num_dacs = cfg->line_outs;
5352 return 0;
5353}
5354
5355static const char *alc_get_line_out_pfx(struct alc_spec *spec,
5356 bool can_be_master)
5357{ 2489{
5358 struct auto_pin_cfg *cfg = &spec->autocfg; 2490 struct auto_pin_cfg *cfg = &spec->autocfg;
2491 static const char * const chname[4] = {
2492 "Front", "Surround", NULL /*CLFE*/, "Side"
2493 };
5359 2494
2495 *index = 0;
5360 if (cfg->line_outs == 1 && !spec->multi_ios && 2496 if (cfg->line_outs == 1 && !spec->multi_ios &&
5361 !cfg->hp_outs && !cfg->speaker_outs && can_be_master) 2497 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5362 return "Master"; 2498 return "Master";
@@ -5367,120 +2503,17 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec,
5367 return "Speaker"; 2503 return "Speaker";
5368 break; 2504 break;
5369 case AUTO_PIN_HP_OUT: 2505 case AUTO_PIN_HP_OUT:
2506 /* for multi-io case, only the primary out */
2507 if (ch && spec->multi_ios)
2508 break;
2509 *index = ch;
5370 return "Headphone"; 2510 return "Headphone";
5371 default: 2511 default:
5372 if (cfg->line_outs == 1 && !spec->multi_ios) 2512 if (cfg->line_outs == 1 && !spec->multi_ios)
5373 return "PCM"; 2513 return "PCM";
5374 break; 2514 break;
5375 } 2515 }
5376 return NULL; 2516 return chname[ch];
5377}
5378
5379/* add playback controls from the parsed DAC table */
5380static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5381 const struct auto_pin_cfg *cfg)
5382{
5383 static const char * const chname[4] = {
5384 "Front", "Surround", NULL /*CLFE*/, "Side"
5385 };
5386 const char *pfx = alc_get_line_out_pfx(spec, false);
5387 hda_nid_t nid;
5388 int i, err, noutputs;
5389
5390 noutputs = cfg->line_outs;
5391 if (spec->multi_ios > 0)
5392 noutputs += spec->multi_ios;
5393
5394 for (i = 0; i < noutputs; i++) {
5395 if (!spec->multiout.dac_nids[i])
5396 continue;
5397 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5398 if (!pfx && i == 2) {
5399 /* Center/LFE */
5400 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5401 "Center",
5402 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5403 HDA_OUTPUT));
5404 if (err < 0)
5405 return err;
5406 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5407 "LFE",
5408 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5409 HDA_OUTPUT));
5410 if (err < 0)
5411 return err;
5412 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5413 "Center",
5414 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5415 HDA_INPUT));
5416 if (err < 0)
5417 return err;
5418 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5419 "LFE",
5420 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5421 HDA_INPUT));
5422 if (err < 0)
5423 return err;
5424 } else {
5425 const char *name = pfx;
5426 int index = i;
5427 if (!name) {
5428 name = chname[i];
5429 index = 0;
5430 }
5431 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5432 name, index,
5433 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5434 HDA_OUTPUT));
5435 if (err < 0)
5436 return err;
5437 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5438 name, index,
5439 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5440 HDA_INPUT));
5441 if (err < 0)
5442 return err;
5443 }
5444 }
5445 return 0;
5446}
5447
5448/* add playback controls for speaker and HP outputs */
5449static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5450 const char *pfx)
5451{
5452 hda_nid_t nid;
5453 int err;
5454
5455 if (!pin)
5456 return 0;
5457
5458 if (alc880_is_fixed_pin(pin)) {
5459 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5460 /* specify the DAC as the extra output */
5461 if (!spec->multiout.hp_nid)
5462 spec->multiout.hp_nid = nid;
5463 else
5464 spec->multiout.extra_out_nid[0] = nid;
5465 /* control HP volume/switch on the output mixer amp */
5466 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5467 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5468 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5469 if (err < 0)
5470 return err;
5471 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5472 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5473 if (err < 0)
5474 return err;
5475 } else if (alc880_is_multi_pin(pin)) {
5476 /* set manual connection */
5477 /* we have only a switch on HP-out PIN */
5478 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5479 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5480 if (err < 0)
5481 return err;
5482 }
5483 return 0;
5484} 2517}
5485 2518
5486/* create input playback/capture controls for the given pin */ 2519/* create input playback/capture controls for the given pin */
@@ -5507,17 +2540,72 @@ static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5507 return (pincap & AC_PINCAP_IN) != 0; 2540 return (pincap & AC_PINCAP_IN) != 0;
5508} 2541}
5509 2542
2543/* Parse the codec tree and retrieve ADCs and corresponding capsrc MUXs */
2544static int alc_auto_fill_adc_caps(struct hda_codec *codec)
2545{
2546 struct alc_spec *spec = codec->spec;
2547 hda_nid_t nid;
2548 hda_nid_t *adc_nids = spec->private_adc_nids;
2549 hda_nid_t *cap_nids = spec->private_capsrc_nids;
2550 int max_nums = ARRAY_SIZE(spec->private_adc_nids);
2551 bool indep_capsrc = false;
2552 int i, nums = 0;
2553
2554 nid = codec->start_nid;
2555 for (i = 0; i < codec->num_nodes; i++, nid++) {
2556 hda_nid_t src;
2557 const hda_nid_t *list;
2558 unsigned int caps = get_wcaps(codec, nid);
2559 int type = get_wcaps_type(caps);
2560
2561 if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL))
2562 continue;
2563 adc_nids[nums] = nid;
2564 cap_nids[nums] = nid;
2565 src = nid;
2566 for (;;) {
2567 int n;
2568 type = get_wcaps_type(get_wcaps(codec, src));
2569 if (type == AC_WID_PIN)
2570 break;
2571 if (type == AC_WID_AUD_SEL) {
2572 cap_nids[nums] = src;
2573 indep_capsrc = true;
2574 break;
2575 }
2576 n = snd_hda_get_conn_list(codec, src, &list);
2577 if (n > 1) {
2578 cap_nids[nums] = src;
2579 indep_capsrc = true;
2580 break;
2581 } else if (n != 1)
2582 break;
2583 src = *list;
2584 }
2585 if (++nums >= max_nums)
2586 break;
2587 }
2588 spec->adc_nids = spec->private_adc_nids;
2589 spec->capsrc_nids = spec->private_capsrc_nids;
2590 spec->num_adc_nids = nums;
2591 return nums;
2592}
2593
5510/* create playback/capture controls for input pins */ 2594/* create playback/capture controls for input pins */
5511static int alc_auto_create_input_ctls(struct hda_codec *codec, 2595static int alc_auto_create_input_ctls(struct hda_codec *codec)
5512 const struct auto_pin_cfg *cfg,
5513 hda_nid_t mixer,
5514 hda_nid_t cap1, hda_nid_t cap2)
5515{ 2596{
5516 struct alc_spec *spec = codec->spec; 2597 struct alc_spec *spec = codec->spec;
2598 const struct auto_pin_cfg *cfg = &spec->autocfg;
2599 hda_nid_t mixer = spec->mixer_nid;
5517 struct hda_input_mux *imux = &spec->private_imux[0]; 2600 struct hda_input_mux *imux = &spec->private_imux[0];
5518 int i, err, idx, type_idx = 0; 2601 int num_adcs;
2602 int i, c, err, idx, type_idx = 0;
5519 const char *prev_label = NULL; 2603 const char *prev_label = NULL;
5520 2604
2605 num_adcs = alc_auto_fill_adc_caps(codec);
2606 if (num_adcs < 0)
2607 return 0;
2608
5521 for (i = 0; i < cfg->num_inputs; i++) { 2609 for (i = 0; i < cfg->num_inputs; i++) {
5522 hda_nid_t pin; 2610 hda_nid_t pin;
5523 const char *label; 2611 const char *label;
@@ -5544,21 +2632,22 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec,
5544 } 2632 }
5545 } 2633 }
5546 2634
5547 if (!cap1) 2635 for (c = 0; c < num_adcs; c++) {
5548 continue; 2636 hda_nid_t cap = spec->capsrc_nids ?
5549 idx = get_connection_index(codec, cap1, pin); 2637 spec->capsrc_nids[c] : spec->adc_nids[c];
5550 if (idx < 0 && cap2) 2638 idx = get_connection_index(codec, cap, pin);
5551 idx = get_connection_index(codec, cap2, pin); 2639 if (idx >= 0) {
5552 if (idx >= 0) 2640 spec->imux_pins[imux->num_items] = pin;
5553 snd_hda_add_imux_item(imux, label, idx, NULL); 2641 snd_hda_add_imux_item(imux, label, idx, NULL);
2642 break;
2643 }
2644 }
5554 } 2645 }
5555 return 0;
5556}
5557 2646
5558static int alc880_auto_create_input_ctls(struct hda_codec *codec, 2647 spec->num_mux_defs = 1;
5559 const struct auto_pin_cfg *cfg) 2648 spec->input_mux = imux;
5560{ 2649
5561 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09); 2650 return 0;
5562} 2651}
5563 2652
5564static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 2653static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
@@ -5567,25 +2656,11 @@ static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5567 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2656 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5568 pin_type); 2657 pin_type);
5569 /* unmute pin */ 2658 /* unmute pin */
5570 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 2659 if (nid_has_mute(codec, nid, HDA_OUTPUT))
2660 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5571 AMP_OUT_UNMUTE); 2661 AMP_OUT_UNMUTE);
5572} 2662}
5573 2663
5574static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5575 hda_nid_t nid, int pin_type,
5576 int dac_idx)
5577{
5578 alc_set_pin_output(codec, nid, pin_type);
5579 /* need the manual connection? */
5580 if (alc880_is_multi_pin(nid)) {
5581 struct alc_spec *spec = codec->spec;
5582 int idx = alc880_multi_pin_idx(nid);
5583 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5584 AC_VERB_SET_CONNECT_SEL,
5585 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5586 }
5587}
5588
5589static int get_pin_type(int line_out_type) 2664static int get_pin_type(int line_out_type)
5590{ 2665{
5591 if (line_out_type == AUTO_PIN_HP_OUT) 2666 if (line_out_type == AUTO_PIN_HP_OUT)
@@ -5594,177 +2669,732 @@ static int get_pin_type(int line_out_type)
5594 return PIN_OUT; 2669 return PIN_OUT;
5595} 2670}
5596 2671
5597static void alc880_auto_init_multi_out(struct hda_codec *codec) 2672static void alc_auto_init_analog_input(struct hda_codec *codec)
5598{ 2673{
5599 struct alc_spec *spec = codec->spec; 2674 struct alc_spec *spec = codec->spec;
2675 struct auto_pin_cfg *cfg = &spec->autocfg;
5600 int i; 2676 int i;
5601 2677
5602 for (i = 0; i < spec->autocfg.line_outs; i++) { 2678 for (i = 0; i < cfg->num_inputs; i++) {
5603 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 2679 hda_nid_t nid = cfg->inputs[i].pin;
5604 int pin_type = get_pin_type(spec->autocfg.line_out_type); 2680 if (alc_is_input_pin(codec, nid)) {
5605 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 2681 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
2682 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
2683 snd_hda_codec_write(codec, nid, 0,
2684 AC_VERB_SET_AMP_GAIN_MUTE,
2685 AMP_OUT_MUTE);
2686 }
2687 }
2688
2689 /* mute all loopback inputs */
2690 if (spec->mixer_nid) {
2691 int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
2692 for (i = 0; i < nums; i++)
2693 snd_hda_codec_write(codec, spec->mixer_nid, 0,
2694 AC_VERB_SET_AMP_GAIN_MUTE,
2695 AMP_IN_MUTE(i));
2696 }
2697}
2698
2699/* convert from MIX nid to DAC */
2700static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
2701{
2702 hda_nid_t list[5];
2703 int i, num;
2704
2705 if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_AUD_OUT)
2706 return nid;
2707 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
2708 for (i = 0; i < num; i++) {
2709 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
2710 return list[i];
5606 } 2711 }
2712 return 0;
2713}
2714
2715/* go down to the selector widget before the mixer */
2716static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
2717{
2718 hda_nid_t srcs[5];
2719 int num = snd_hda_get_connections(codec, pin, srcs,
2720 ARRAY_SIZE(srcs));
2721 if (num != 1 ||
2722 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
2723 return pin;
2724 return srcs[0];
5607} 2725}
5608 2726
5609static void alc880_auto_init_extra_out(struct hda_codec *codec) 2727/* get MIX nid connected to the given pin targeted to DAC */
2728static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
2729 hda_nid_t dac)
2730{
2731 hda_nid_t mix[5];
2732 int i, num;
2733
2734 pin = alc_go_down_to_selector(codec, pin);
2735 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2736 for (i = 0; i < num; i++) {
2737 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
2738 return mix[i];
2739 }
2740 return 0;
2741}
2742
2743/* select the connection from pin to DAC if needed */
2744static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
2745 hda_nid_t dac)
2746{
2747 hda_nid_t mix[5];
2748 int i, num;
2749
2750 pin = alc_go_down_to_selector(codec, pin);
2751 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2752 if (num < 2)
2753 return 0;
2754 for (i = 0; i < num; i++) {
2755 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
2756 snd_hda_codec_update_cache(codec, pin, 0,
2757 AC_VERB_SET_CONNECT_SEL, i);
2758 return 0;
2759 }
2760 }
2761 return 0;
2762}
2763
2764/* look for an empty DAC slot */
2765static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
5610{ 2766{
5611 struct alc_spec *spec = codec->spec; 2767 struct alc_spec *spec = codec->spec;
5612 hda_nid_t pin; 2768 hda_nid_t srcs[5];
2769 int i, num;
5613 2770
5614 pin = spec->autocfg.speaker_pins[0]; 2771 pin = alc_go_down_to_selector(codec, pin);
5615 if (pin) /* connect to front */ 2772 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
5616 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 2773 for (i = 0; i < num; i++) {
5617 pin = spec->autocfg.hp_pins[0]; 2774 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
5618 if (pin) /* connect to front */ 2775 if (!nid)
5619 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 2776 continue;
2777 if (found_in_nid_list(nid, spec->multiout.dac_nids,
2778 spec->multiout.num_dacs))
2779 continue;
2780 if (spec->multiout.hp_nid == nid)
2781 continue;
2782 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
2783 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2784 continue;
2785 return nid;
2786 }
2787 return 0;
5620} 2788}
5621 2789
5622static void alc880_auto_init_analog_input(struct hda_codec *codec) 2790static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
2791{
2792 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
2793 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
2794 return alc_auto_look_for_dac(codec, pin);
2795 return 0;
2796}
2797
2798/* fill in the dac_nids table from the parsed pin configuration */
2799static int alc_auto_fill_dac_nids(struct hda_codec *codec)
5623{ 2800{
5624 struct alc_spec *spec = codec->spec; 2801 struct alc_spec *spec = codec->spec;
5625 struct auto_pin_cfg *cfg = &spec->autocfg; 2802 const struct auto_pin_cfg *cfg = &spec->autocfg;
2803 bool redone = false;
5626 int i; 2804 int i;
5627 2805
5628 for (i = 0; i < cfg->num_inputs; i++) { 2806 again:
5629 hda_nid_t nid = cfg->inputs[i].pin; 2807 /* set num_dacs once to full for alc_auto_look_for_dac() */
5630 if (alc_is_input_pin(codec, nid)) { 2808 spec->multiout.num_dacs = cfg->line_outs;
5631 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 2809 spec->multiout.hp_nid = 0;
5632 if (nid != ALC880_PIN_CD_NID && 2810 spec->multiout.extra_out_nid[0] = 0;
5633 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 2811 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
5634 snd_hda_codec_write(codec, nid, 0, 2812 spec->multiout.dac_nids = spec->private_dac_nids;
5635 AC_VERB_SET_AMP_GAIN_MUTE, 2813
5636 AMP_OUT_MUTE); 2814 /* fill hard-wired DACs first */
2815 if (!redone) {
2816 for (i = 0; i < cfg->line_outs; i++)
2817 spec->private_dac_nids[i] =
2818 get_dac_if_single(codec, cfg->line_out_pins[i]);
2819 if (cfg->hp_outs)
2820 spec->multiout.hp_nid =
2821 get_dac_if_single(codec, cfg->hp_pins[0]);
2822 if (cfg->speaker_outs)
2823 spec->multiout.extra_out_nid[0] =
2824 get_dac_if_single(codec, cfg->speaker_pins[0]);
2825 }
2826
2827 for (i = 0; i < cfg->line_outs; i++) {
2828 hda_nid_t pin = cfg->line_out_pins[i];
2829 if (spec->private_dac_nids[i])
2830 continue;
2831 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
2832 if (!spec->private_dac_nids[i] && !redone) {
2833 /* if we can't find primary DACs, re-probe without
2834 * checking the hard-wired DACs
2835 */
2836 redone = true;
2837 goto again;
5637 } 2838 }
5638 } 2839 }
2840
2841 /* re-count num_dacs and squash invalid entries */
2842 spec->multiout.num_dacs = 0;
2843 for (i = 0; i < cfg->line_outs; i++) {
2844 if (spec->private_dac_nids[i])
2845 spec->multiout.num_dacs++;
2846 else
2847 memmove(spec->private_dac_nids + i,
2848 spec->private_dac_nids + i + 1,
2849 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
2850 }
2851
2852 if (cfg->hp_outs && !spec->multiout.hp_nid)
2853 spec->multiout.hp_nid =
2854 alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
2855 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
2856 spec->multiout.extra_out_nid[0] =
2857 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
2858
2859 return 0;
5639} 2860}
5640 2861
5641static void alc880_auto_init_input_src(struct hda_codec *codec) 2862static int alc_auto_add_vol_ctl(struct hda_codec *codec,
2863 const char *pfx, int cidx,
2864 hda_nid_t nid, unsigned int chs)
5642{ 2865{
5643 struct alc_spec *spec = codec->spec; 2866 if (!nid)
5644 int c; 2867 return 0;
5645 2868 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
5646 for (c = 0; c < spec->num_adc_nids; c++) { 2869 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
5647 unsigned int mux_idx;
5648 const struct hda_input_mux *imux;
5649 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5650 imux = &spec->input_mux[mux_idx];
5651 if (!imux->num_items && mux_idx > 0)
5652 imux = &spec->input_mux[0];
5653 if (imux)
5654 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5655 AC_VERB_SET_CONNECT_SEL,
5656 imux->items[0].index);
5657 }
5658} 2870}
5659 2871
5660static int alc_auto_add_multi_channel_mode(struct hda_codec *codec); 2872#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
2873 alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
5661 2874
5662/* parse the BIOS configuration and set up the alc_spec */ 2875/* create a mute-switch for the given mixer widget;
5663/* return 1 if successful, 0 if the proper config is not found, 2876 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
5664 * or a negative error code
5665 */ 2877 */
5666static int alc880_parse_auto_config(struct hda_codec *codec) 2878static int alc_auto_add_sw_ctl(struct hda_codec *codec,
2879 const char *pfx, int cidx,
2880 hda_nid_t nid, unsigned int chs)
2881{
2882 int wid_type;
2883 int type;
2884 unsigned long val;
2885 if (!nid)
2886 return 0;
2887 wid_type = get_wcaps_type(get_wcaps(codec, nid));
2888 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) {
2889 type = ALC_CTL_WIDGET_MUTE;
2890 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
2891 } else if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
2892 type = ALC_CTL_WIDGET_MUTE;
2893 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
2894 } else {
2895 type = ALC_CTL_BIND_MUTE;
2896 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
2897 }
2898 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
2899}
2900
2901#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
2902 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
2903
2904static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
2905 hda_nid_t pin, hda_nid_t dac)
2906{
2907 hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
2908 if (nid_has_mute(codec, pin, HDA_OUTPUT))
2909 return pin;
2910 else if (mix && nid_has_mute(codec, mix, HDA_INPUT))
2911 return mix;
2912 else if (nid_has_mute(codec, dac, HDA_OUTPUT))
2913 return dac;
2914 return 0;
2915}
2916
2917static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
2918 hda_nid_t pin, hda_nid_t dac)
2919{
2920 hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
2921 if (nid_has_volume(codec, dac, HDA_OUTPUT))
2922 return dac;
2923 else if (nid_has_volume(codec, mix, HDA_OUTPUT))
2924 return mix;
2925 else if (nid_has_volume(codec, pin, HDA_OUTPUT))
2926 return pin;
2927 return 0;
2928}
2929
2930/* add playback controls from the parsed DAC table */
2931static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
2932 const struct auto_pin_cfg *cfg)
5667{ 2933{
5668 struct alc_spec *spec = codec->spec; 2934 struct alc_spec *spec = codec->spec;
2935 int i, err, noutputs;
2936
2937 noutputs = cfg->line_outs;
2938 if (spec->multi_ios > 0)
2939 noutputs += spec->multi_ios;
2940
2941 for (i = 0; i < noutputs; i++) {
2942 const char *name;
2943 int index;
2944 hda_nid_t dac, pin;
2945 hda_nid_t sw, vol;
2946
2947 dac = spec->multiout.dac_nids[i];
2948 if (!dac)
2949 continue;
2950 if (i >= cfg->line_outs)
2951 pin = spec->multi_io[i - 1].pin;
2952 else
2953 pin = cfg->line_out_pins[i];
2954
2955 sw = alc_look_for_out_mute_nid(codec, pin, dac);
2956 vol = alc_look_for_out_vol_nid(codec, pin, dac);
2957 name = alc_get_line_out_pfx(spec, i, true, &index);
2958 if (!name) {
2959 /* Center/LFE */
2960 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
2961 if (err < 0)
2962 return err;
2963 err = alc_auto_add_vol_ctl(codec, "LFE", 0, vol, 2);
2964 if (err < 0)
2965 return err;
2966 err = alc_auto_add_sw_ctl(codec, "Center", 0, sw, 1);
2967 if (err < 0)
2968 return err;
2969 err = alc_auto_add_sw_ctl(codec, "LFE", 0, sw, 2);
2970 if (err < 0)
2971 return err;
2972 } else {
2973 err = alc_auto_add_stereo_vol(codec, name, index, vol);
2974 if (err < 0)
2975 return err;
2976 err = alc_auto_add_stereo_sw(codec, name, index, sw);
2977 if (err < 0)
2978 return err;
2979 }
2980 }
2981 return 0;
2982}
2983
2984/* add playback controls for speaker and HP outputs */
2985static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2986 hda_nid_t dac, const char *pfx)
2987{
2988 struct alc_spec *spec = codec->spec;
2989 hda_nid_t sw, vol;
5669 int err; 2990 int err;
5670 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5671 2991
5672 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 2992 if (!pin)
5673 alc880_ignore); 2993 return 0;
5674 if (err < 0) 2994 if (!dac) {
5675 return err; 2995 /* the corresponding DAC is already occupied */
5676 if (!spec->autocfg.line_outs) 2996 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
5677 return 0; /* can't find valid BIOS pin config */ 2997 return 0; /* no way */
2998 /* create a switch only */
2999 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
3000 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3001 }
5678 3002
5679 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 3003 sw = alc_look_for_out_mute_nid(codec, pin, dac);
5680 if (err < 0) 3004 vol = alc_look_for_out_vol_nid(codec, pin, dac);
5681 return err; 3005 err = alc_auto_add_stereo_vol(codec, pfx, 0, vol);
5682 err = alc_auto_add_multi_channel_mode(codec);
5683 if (err < 0)
5684 return err;
5685 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5686 if (err < 0) 3006 if (err < 0)
5687 return err; 3007 return err;
5688 err = alc880_auto_create_extra_out(spec, 3008 err = alc_auto_add_stereo_sw(codec, pfx, 0, sw);
5689 spec->autocfg.speaker_pins[0],
5690 "Speaker");
5691 if (err < 0)
5692 return err;
5693 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5694 "Headphone");
5695 if (err < 0)
5696 return err;
5697 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5698 if (err < 0) 3009 if (err < 0)
5699 return err; 3010 return err;
3011 return 0;
3012}
5700 3013
5701 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3014static int alc_auto_create_hp_out(struct hda_codec *codec)
3015{
3016 struct alc_spec *spec = codec->spec;
3017 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3018 spec->multiout.hp_nid,
3019 "Headphone");
3020}
5702 3021
5703 alc_auto_parse_digital(codec); 3022static int alc_auto_create_speaker_out(struct hda_codec *codec)
3023{
3024 struct alc_spec *spec = codec->spec;
3025 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
3026 spec->multiout.extra_out_nid[0],
3027 "Speaker");
3028}
5704 3029
5705 if (spec->kctls.list) 3030static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
5706 add_mixer(spec, spec->kctls.list); 3031 hda_nid_t pin, int pin_type,
3032 hda_nid_t dac)
3033{
3034 int i, num;
3035 hda_nid_t nid, mix = 0;
3036 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
3037
3038 alc_set_pin_output(codec, pin, pin_type);
3039 nid = alc_go_down_to_selector(codec, pin);
3040 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
3041 for (i = 0; i < num; i++) {
3042 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
3043 continue;
3044 mix = srcs[i];
3045 break;
3046 }
3047 if (!mix)
3048 return;
5707 3049
5708 add_verb(spec, alc880_volume_init_verbs); 3050 /* need the manual connection? */
3051 if (num > 1)
3052 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
3053 /* unmute mixer widget inputs */
3054 if (nid_has_mute(codec, mix, HDA_INPUT)) {
3055 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3056 AMP_IN_UNMUTE(0));
3057 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3058 AMP_IN_UNMUTE(1));
3059 }
3060 /* initialize volume */
3061 nid = alc_look_for_out_vol_nid(codec, pin, dac);
3062 if (nid)
3063 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3064 AMP_OUT_ZERO);
3065}
5709 3066
5710 spec->num_mux_defs = 1; 3067static void alc_auto_init_multi_out(struct hda_codec *codec)
5711 spec->input_mux = &spec->private_imux[0]; 3068{
3069 struct alc_spec *spec = codec->spec;
3070 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3071 int i;
3072
3073 for (i = 0; i <= HDA_SIDE; i++) {
3074 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3075 if (nid)
3076 alc_auto_set_output_and_unmute(codec, nid, pin_type,
3077 spec->multiout.dac_nids[i]);
3078 }
3079}
3080
3081static void alc_auto_init_extra_out(struct hda_codec *codec)
3082{
3083 struct alc_spec *spec = codec->spec;
3084 hda_nid_t pin;
3085
3086 pin = spec->autocfg.hp_pins[0];
3087 if (pin)
3088 alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
3089 spec->multiout.hp_nid);
3090 pin = spec->autocfg.speaker_pins[0];
3091 if (pin)
3092 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
3093 spec->multiout.extra_out_nid[0]);
3094}
3095
3096/*
3097 * multi-io helper
3098 */
3099static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3100 unsigned int location)
3101{
3102 struct alc_spec *spec = codec->spec;
3103 struct auto_pin_cfg *cfg = &spec->autocfg;
3104 int type, i, num_pins = 0;
3105
3106 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3107 for (i = 0; i < cfg->num_inputs; i++) {
3108 hda_nid_t nid = cfg->inputs[i].pin;
3109 hda_nid_t dac;
3110 unsigned int defcfg, caps;
3111 if (cfg->inputs[i].type != type)
3112 continue;
3113 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3114 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3115 continue;
3116 if (location && get_defcfg_location(defcfg) != location)
3117 continue;
3118 caps = snd_hda_query_pin_caps(codec, nid);
3119 if (!(caps & AC_PINCAP_OUT))
3120 continue;
3121 dac = alc_auto_look_for_dac(codec, nid);
3122 if (!dac)
3123 continue;
3124 spec->multi_io[num_pins].pin = nid;
3125 spec->multi_io[num_pins].dac = dac;
3126 num_pins++;
3127 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3128 }
3129 }
3130 spec->multiout.num_dacs = 1;
3131 if (num_pins < 2)
3132 return 0;
3133 return num_pins;
3134}
3135
3136static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
3137 struct snd_ctl_elem_info *uinfo)
3138{
3139 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3140 struct alc_spec *spec = codec->spec;
5712 3141
5713 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 3142 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3143 uinfo->count = 1;
3144 uinfo->value.enumerated.items = spec->multi_ios + 1;
3145 if (uinfo->value.enumerated.item > spec->multi_ios)
3146 uinfo->value.enumerated.item = spec->multi_ios;
3147 sprintf(uinfo->value.enumerated.name, "%dch",
3148 (uinfo->value.enumerated.item + 1) * 2);
3149 return 0;
3150}
5714 3151
3152static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
3153 struct snd_ctl_elem_value *ucontrol)
3154{
3155 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3156 struct alc_spec *spec = codec->spec;
3157 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
3158 return 0;
3159}
3160
3161static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
3162{
3163 struct alc_spec *spec = codec->spec;
3164 hda_nid_t nid = spec->multi_io[idx].pin;
3165
3166 if (!spec->multi_io[idx].ctl_in)
3167 spec->multi_io[idx].ctl_in =
3168 snd_hda_codec_read(codec, nid, 0,
3169 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3170 if (output) {
3171 snd_hda_codec_update_cache(codec, nid, 0,
3172 AC_VERB_SET_PIN_WIDGET_CONTROL,
3173 PIN_OUT);
3174 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3175 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3176 HDA_AMP_MUTE, 0);
3177 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
3178 } else {
3179 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3180 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3181 HDA_AMP_MUTE, HDA_AMP_MUTE);
3182 snd_hda_codec_update_cache(codec, nid, 0,
3183 AC_VERB_SET_PIN_WIDGET_CONTROL,
3184 spec->multi_io[idx].ctl_in);
3185 }
3186 return 0;
3187}
3188
3189static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
3190 struct snd_ctl_elem_value *ucontrol)
3191{
3192 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3193 struct alc_spec *spec = codec->spec;
3194 int i, ch;
3195
3196 ch = ucontrol->value.enumerated.item[0];
3197 if (ch < 0 || ch > spec->multi_ios)
3198 return -EINVAL;
3199 if (ch == (spec->ext_channel_count - 1) / 2)
3200 return 0;
3201 spec->ext_channel_count = (ch + 1) * 2;
3202 for (i = 0; i < spec->multi_ios; i++)
3203 alc_set_multi_io(codec, i, i < ch);
3204 spec->multiout.max_channels = spec->ext_channel_count;
3205 if (spec->need_dac_fix && !spec->const_channel_count)
3206 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
5715 return 1; 3207 return 1;
5716} 3208}
5717 3209
5718/* additional initialization for auto-configuration model */ 3210static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
5719static void alc880_auto_init(struct hda_codec *codec) 3211 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3212 .name = "Channel Mode",
3213 .info = alc_auto_ch_mode_info,
3214 .get = alc_auto_ch_mode_get,
3215 .put = alc_auto_ch_mode_put,
3216};
3217
3218static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
3219 int (*fill_dac)(struct hda_codec *))
5720{ 3220{
5721 struct alc_spec *spec = codec->spec; 3221 struct alc_spec *spec = codec->spec;
5722 alc880_auto_init_multi_out(codec); 3222 struct auto_pin_cfg *cfg = &spec->autocfg;
5723 alc880_auto_init_extra_out(codec); 3223 unsigned int location, defcfg;
5724 alc880_auto_init_analog_input(codec); 3224 int num_pins;
5725 alc880_auto_init_input_src(codec); 3225
5726 alc_auto_init_digital(codec); 3226 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
5727 if (spec->unsol_event) 3227 /* use HP as primary out */
5728 alc_inithook(codec); 3228 cfg->speaker_outs = cfg->line_outs;
3229 memcpy(cfg->speaker_pins, cfg->line_out_pins,
3230 sizeof(cfg->speaker_pins));
3231 cfg->line_outs = cfg->hp_outs;
3232 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
3233 cfg->hp_outs = 0;
3234 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
3235 cfg->line_out_type = AUTO_PIN_HP_OUT;
3236 if (fill_dac)
3237 fill_dac(codec);
3238 }
3239 if (cfg->line_outs != 1 ||
3240 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
3241 return 0;
3242
3243 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
3244 location = get_defcfg_location(defcfg);
3245
3246 num_pins = alc_auto_fill_multi_ios(codec, location);
3247 if (num_pins > 0) {
3248 struct snd_kcontrol_new *knew;
3249
3250 knew = alc_kcontrol_new(spec);
3251 if (!knew)
3252 return -ENOMEM;
3253 *knew = alc_auto_channel_mode_enum;
3254 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
3255 if (!knew->name)
3256 return -ENOMEM;
3257
3258 spec->multi_ios = num_pins;
3259 spec->ext_channel_count = 2;
3260 spec->multiout.num_dacs = num_pins + 1;
3261 }
3262 return 0;
5729} 3263}
5730 3264
5731/* check the ADC/MUX contains all input pins; some ADC/MUX contains only 3265/* filter out invalid adc_nids (and capsrc_nids) that don't give all
5732 * one of two digital mic pins, e.g. on ALC272 3266 * active input pins
5733 */ 3267 */
5734static void fixup_automic_adc(struct hda_codec *codec) 3268static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
5735{ 3269{
5736 struct alc_spec *spec = codec->spec; 3270 struct alc_spec *spec = codec->spec;
5737 int i; 3271 const struct hda_input_mux *imux;
3272 hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3273 hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3274 int i, n, nums;
5738 3275
5739 for (i = 0; i < spec->num_adc_nids; i++) { 3276 imux = spec->input_mux;
5740 hda_nid_t cap = spec->capsrc_nids ? 3277 if (!imux)
5741 spec->capsrc_nids[i] : spec->adc_nids[i]; 3278 return;
5742 int iidx, eidx; 3279 if (spec->dyn_adc_switch)
3280 return;
5743 3281
5744 iidx = get_connection_index(codec, cap, spec->int_mic.pin); 3282 nums = 0;
5745 if (iidx < 0) 3283 for (n = 0; n < spec->num_adc_nids; n++) {
5746 continue; 3284 hda_nid_t cap = spec->private_capsrc_nids[n];
5747 eidx = get_connection_index(codec, cap, spec->ext_mic.pin); 3285 int num_conns = snd_hda_get_conn_list(codec, cap, NULL);
5748 if (eidx < 0) 3286 for (i = 0; i < imux->num_items; i++) {
5749 continue; 3287 hda_nid_t pin = spec->imux_pins[i];
5750 spec->int_mic.mux_idx = iidx; 3288 if (pin) {
5751 spec->ext_mic.mux_idx = eidx; 3289 if (get_connection_index(codec, cap, pin) < 0)
5752 if (spec->capsrc_nids) 3290 break;
5753 spec->capsrc_nids += i; 3291 } else if (num_conns <= imux->items[i].index)
5754 spec->adc_nids += i; 3292 break;
5755 spec->num_adc_nids = 1; 3293 }
5756 /* optional dock-mic */ 3294 if (i >= imux->num_items) {
5757 eidx = get_connection_index(codec, cap, spec->dock_mic.pin); 3295 adc_nids[nums] = spec->private_adc_nids[n];
5758 if (eidx < 0) 3296 capsrc_nids[nums++] = cap;
5759 spec->dock_mic.pin = 0; 3297 }
5760 else 3298 }
5761 spec->dock_mic.mux_idx = eidx; 3299 if (!nums) {
3300 /* check whether ADC-switch is possible */
3301 if (!alc_check_dyn_adc_switch(codec)) {
3302 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
3303 " using fallback 0x%x\n",
3304 codec->chip_name, spec->private_adc_nids[0]);
3305 spec->num_adc_nids = 1;
3306 spec->auto_mic = 0;
3307 return;
3308 }
3309 } else if (nums != spec->num_adc_nids) {
3310 memcpy(spec->private_adc_nids, adc_nids,
3311 nums * sizeof(hda_nid_t));
3312 memcpy(spec->private_capsrc_nids, capsrc_nids,
3313 nums * sizeof(hda_nid_t));
3314 spec->num_adc_nids = nums;
3315 }
3316
3317 if (spec->auto_mic)
3318 alc_auto_mic_check_imux(codec); /* check auto-mic setups */
3319 else if (spec->input_mux->num_items == 1)
3320 spec->num_adc_nids = 1; /* reduce to a single ADC */
3321}
3322
3323/*
3324 * initialize ADC paths
3325 */
3326static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx)
3327{
3328 struct alc_spec *spec = codec->spec;
3329 hda_nid_t nid;
3330
3331 nid = spec->adc_nids[adc_idx];
3332 /* mute ADC */
3333 if (nid_has_mute(codec, nid, HDA_INPUT)) {
3334 snd_hda_codec_write(codec, nid, 0,
3335 AC_VERB_SET_AMP_GAIN_MUTE,
3336 AMP_IN_MUTE(0));
5762 return; 3337 return;
5763 } 3338 }
5764 snd_printd(KERN_INFO "hda_codec: %s: " 3339 if (!spec->capsrc_nids)
5765 "No ADC/MUX containing both 0x%x and 0x%x pins\n", 3340 return;
5766 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); 3341 nid = spec->capsrc_nids[adc_idx];
5767 spec->auto_mic = 0; /* disable auto-mic to be sure */ 3342 if (nid_has_mute(codec, nid, HDA_OUTPUT))
3343 snd_hda_codec_write(codec, nid, 0,
3344 AC_VERB_SET_AMP_GAIN_MUTE,
3345 AMP_OUT_MUTE);
3346}
3347
3348static void alc_auto_init_input_src(struct hda_codec *codec)
3349{
3350 struct alc_spec *spec = codec->spec;
3351 int c, nums;
3352
3353 for (c = 0; c < spec->num_adc_nids; c++)
3354 alc_auto_init_adc(codec, c);
3355 if (spec->dyn_adc_switch)
3356 nums = 1;
3357 else
3358 nums = spec->num_adc_nids;
3359 for (c = 0; c < nums; c++)
3360 alc_mux_select(codec, 0, spec->cur_mux[c], true);
3361}
3362
3363/* add mic boosts if needed */
3364static int alc_auto_add_mic_boost(struct hda_codec *codec)
3365{
3366 struct alc_spec *spec = codec->spec;
3367 struct auto_pin_cfg *cfg = &spec->autocfg;
3368 int i, err;
3369 int type_idx = 0;
3370 hda_nid_t nid;
3371 const char *prev_label = NULL;
3372
3373 for (i = 0; i < cfg->num_inputs; i++) {
3374 if (cfg->inputs[i].type > AUTO_PIN_MIC)
3375 break;
3376 nid = cfg->inputs[i].pin;
3377 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
3378 const char *label;
3379 char boost_label[32];
3380
3381 label = hda_get_autocfg_input_label(codec, cfg, i);
3382 if (prev_label && !strcmp(label, prev_label))
3383 type_idx++;
3384 else
3385 type_idx = 0;
3386 prev_label = label;
3387
3388 snprintf(boost_label, sizeof(boost_label),
3389 "%s Boost Volume", label);
3390 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3391 boost_label, type_idx,
3392 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
3393 if (err < 0)
3394 return err;
3395 }
3396 }
3397 return 0;
5768} 3398}
5769 3399
5770/* select or unmute the given capsrc route */ 3400/* select or unmute the given capsrc route */
@@ -5774,7 +3404,7 @@ static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5774 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { 3404 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5775 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, 3405 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5776 HDA_AMP_MUTE, 0); 3406 HDA_AMP_MUTE, 0);
5777 } else { 3407 } else if (snd_hda_get_conn_list(codec, cap, NULL) > 1) {
5778 snd_hda_codec_write_cache(codec, cap, 0, 3408 snd_hda_codec_write_cache(codec, cap, 0,
5779 AC_VERB_SET_CONNECT_SEL, idx); 3409 AC_VERB_SET_CONNECT_SEL, idx);
5780 } 3410 }
@@ -5802,46 +3432,17 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5802 return -1; /* not found */ 3432 return -1; /* not found */
5803} 3433}
5804 3434
5805/* choose the ADC/MUX containing the input pin and initialize the setup */
5806static void fixup_single_adc(struct hda_codec *codec)
5807{
5808 struct alc_spec *spec = codec->spec;
5809 struct auto_pin_cfg *cfg = &spec->autocfg;
5810 int i;
5811
5812 /* search for the input pin; there must be only one */
5813 if (cfg->num_inputs != 1)
5814 return;
5815 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5816 if (i >= 0) {
5817 /* use only this ADC */
5818 if (spec->capsrc_nids)
5819 spec->capsrc_nids += i;
5820 spec->adc_nids += i;
5821 spec->num_adc_nids = 1;
5822 spec->single_input_src = 1;
5823 }
5824}
5825
5826/* initialize dual adcs */
5827static void fixup_dual_adc_switch(struct hda_codec *codec)
5828{
5829 struct alc_spec *spec = codec->spec;
5830 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5831 init_capsrc_for_pin(codec, spec->dock_mic.pin);
5832 init_capsrc_for_pin(codec, spec->int_mic.pin);
5833}
5834
5835/* initialize some special cases for input sources */ 3435/* initialize some special cases for input sources */
5836static void alc_init_special_input_src(struct hda_codec *codec) 3436static void alc_init_special_input_src(struct hda_codec *codec)
5837{ 3437{
5838 struct alc_spec *spec = codec->spec; 3438 struct alc_spec *spec = codec->spec;
5839 if (spec->dual_adc_switch) 3439 int i;
5840 fixup_dual_adc_switch(codec); 3440
5841 else if (spec->single_input_src) 3441 for (i = 0; i < spec->autocfg.num_inputs; i++)
5842 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin); 3442 init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin);
5843} 3443}
5844 3444
3445/* assign appropriate capture mixers */
5845static void set_capture_mixer(struct hda_codec *codec) 3446static void set_capture_mixer(struct hda_codec *codec)
5846{ 3447{
5847 struct alc_spec *spec = codec->spec; 3448 struct alc_spec *spec = codec->spec;
@@ -5853,86 +3454,56 @@ static void set_capture_mixer(struct hda_codec *codec)
5853 alc_capture_mixer2, 3454 alc_capture_mixer2,
5854 alc_capture_mixer3 }, 3455 alc_capture_mixer3 },
5855 }; 3456 };
5856 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 3457
3458 /* check whether either of ADC or MUX has a volume control */
3459 if (!nid_has_volume(codec, spec->adc_nids[0], HDA_INPUT)) {
3460 if (!spec->capsrc_nids)
3461 return; /* no volume */
3462 if (!nid_has_volume(codec, spec->capsrc_nids[0], HDA_OUTPUT))
3463 return; /* no volume in capsrc, too */
3464 spec->vol_in_capsrc = 1;
3465 }
3466
3467 if (spec->num_adc_nids > 0) {
5857 int mux = 0; 3468 int mux = 0;
5858 int num_adcs = spec->num_adc_nids; 3469 int num_adcs = 0;
5859 if (spec->dual_adc_switch) 3470
3471 if (spec->input_mux && spec->input_mux->num_items > 1)
3472 mux = 1;
3473 if (spec->auto_mic) {
5860 num_adcs = 1; 3474 num_adcs = 1;
5861 else if (spec->auto_mic) 3475 mux = 0;
5862 fixup_automic_adc(codec); 3476 } else if (spec->dyn_adc_switch)
5863 else if (spec->input_mux) { 3477 num_adcs = 1;
5864 if (spec->input_mux->num_items > 1) 3478 if (!num_adcs) {
5865 mux = 1; 3479 if (spec->num_adc_nids > 3)
5866 else if (spec->input_mux->num_items == 1) 3480 spec->num_adc_nids = 3;
5867 fixup_single_adc(codec); 3481 else if (!spec->num_adc_nids)
3482 return;
3483 num_adcs = spec->num_adc_nids;
5868 } 3484 }
5869 spec->cap_mixer = caps[mux][num_adcs - 1]; 3485 spec->cap_mixer = caps[mux][num_adcs - 1];
5870 } 3486 }
5871} 3487}
5872 3488
5873/* fill adc_nids (and capsrc_nids) containing all active input pins */ 3489/*
5874static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids, 3490 * standard auto-parser initializations
5875 int num_nids) 3491 */
3492static void alc_auto_init_std(struct hda_codec *codec)
5876{ 3493{
5877 struct alc_spec *spec = codec->spec; 3494 struct alc_spec *spec = codec->spec;
5878 struct auto_pin_cfg *cfg = &spec->autocfg; 3495 alc_auto_init_multi_out(codec);
5879 int n; 3496 alc_auto_init_extra_out(codec);
5880 hda_nid_t fallback_adc = 0, fallback_cap = 0; 3497 alc_auto_init_analog_input(codec);
5881 3498 alc_auto_init_input_src(codec);
5882 for (n = 0; n < num_nids; n++) { 3499 alc_auto_init_digital(codec);
5883 hda_nid_t adc, cap; 3500 if (spec->unsol_event)
5884 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 3501 alc_inithook(codec);
5885 int nconns, i, j;
5886
5887 adc = nids[n];
5888 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5889 continue;
5890 cap = adc;
5891 nconns = snd_hda_get_connections(codec, cap, conn,
5892 ARRAY_SIZE(conn));
5893 if (nconns == 1) {
5894 cap = conn[0];
5895 nconns = snd_hda_get_connections(codec, cap, conn,
5896 ARRAY_SIZE(conn));
5897 }
5898 if (nconns <= 0)
5899 continue;
5900 if (!fallback_adc) {
5901 fallback_adc = adc;
5902 fallback_cap = cap;
5903 }
5904 for (i = 0; i < cfg->num_inputs; i++) {
5905 hda_nid_t nid = cfg->inputs[i].pin;
5906 for (j = 0; j < nconns; j++) {
5907 if (conn[j] == nid)
5908 break;
5909 }
5910 if (j >= nconns)
5911 break;
5912 }
5913 if (i >= cfg->num_inputs) {
5914 int num_adcs = spec->num_adc_nids;
5915 spec->private_adc_nids[num_adcs] = adc;
5916 spec->private_capsrc_nids[num_adcs] = cap;
5917 spec->num_adc_nids++;
5918 spec->adc_nids = spec->private_adc_nids;
5919 if (adc != cap)
5920 spec->capsrc_nids = spec->private_capsrc_nids;
5921 }
5922 }
5923 if (!spec->num_adc_nids) {
5924 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5925 " using fallback 0x%x\n",
5926 codec->chip_name, fallback_adc);
5927 spec->private_adc_nids[0] = fallback_adc;
5928 spec->adc_nids = spec->private_adc_nids;
5929 if (fallback_adc != fallback_cap) {
5930 spec->private_capsrc_nids[0] = fallback_cap;
5931 spec->capsrc_nids = spec->private_adc_nids;
5932 }
5933 }
5934} 3502}
5935 3503
3504/*
3505 * Digital-beep handlers
3506 */
5936#ifdef CONFIG_SND_HDA_INPUT_BEEP 3507#ifdef CONFIG_SND_HDA_INPUT_BEEP
5937#define set_beep_amp(spec, nid, idx, dir) \ 3508#define set_beep_amp(spec, nid, idx, dir) \
5938 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 3509 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
@@ -5960,1407 +3531,195 @@ static inline int has_cdefine_beep(struct hda_codec *codec)
5960#define has_cdefine_beep(codec) 0 3531#define has_cdefine_beep(codec) 0
5961#endif 3532#endif
5962 3533
5963/* 3534/* parse the BIOS configuration and set up the alc_spec */
5964 * OK, here we have finally the patch for ALC880 3535/* return 1 if successful, 0 if the proper config is not found,
3536 * or a negative error code
5965 */ 3537 */
5966 3538static int alc_parse_auto_config(struct hda_codec *codec,
5967static int patch_alc880(struct hda_codec *codec) 3539 const hda_nid_t *ignore_nids,
3540 const hda_nid_t *ssid_nids)
5968{ 3541{
5969 struct alc_spec *spec; 3542 struct alc_spec *spec = codec->spec;
5970 int board_config;
5971 int err; 3543 int err;
5972 3544
5973 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3545 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5974 if (spec == NULL) 3546 ignore_nids);
5975 return -ENOMEM; 3547 if (err < 0)
5976
5977 codec->spec = spec;
5978
5979 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5980 alc880_models,
5981 alc880_cfg_tbl);
5982 if (board_config < 0) {
5983 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5984 codec->chip_name);
5985 board_config = ALC880_AUTO;
5986 }
5987
5988 if (board_config == ALC880_AUTO) {
5989 /* automatic parse from the BIOS config */
5990 err = alc880_parse_auto_config(codec);
5991 if (err < 0) {
5992 alc_free(codec);
5993 return err;
5994 } else if (!err) {
5995 printk(KERN_INFO
5996 "hda_codec: Cannot set up configuration "
5997 "from BIOS. Using 3-stack mode...\n");
5998 board_config = ALC880_3ST;
5999 }
6000 }
6001
6002 err = snd_hda_attach_beep_device(codec, 0x1);
6003 if (err < 0) {
6004 alc_free(codec);
6005 return err; 3548 return err;
6006 } 3549 if (!spec->autocfg.line_outs) {
6007 3550 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
6008 if (board_config != ALC880_AUTO) 3551 spec->multiout.max_channels = 2;
6009 setup_preset(codec, &alc880_presets[board_config]); 3552 spec->no_analog = 1;
6010 3553 goto dig_only;
6011 spec->stream_analog_playback = &alc880_pcm_analog_playback;
6012 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6013 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6014
6015 spec->stream_digital_playback = &alc880_pcm_digital_playback;
6016 spec->stream_digital_capture = &alc880_pcm_digital_capture;
6017
6018 if (!spec->adc_nids && spec->input_mux) {
6019 /* check whether NID 0x07 is valid */
6020 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
6021 /* get type */
6022 wcap = get_wcaps_type(wcap);
6023 if (wcap != AC_WID_AUD_IN) {
6024 spec->adc_nids = alc880_adc_nids_alt;
6025 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
6026 } else {
6027 spec->adc_nids = alc880_adc_nids;
6028 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
6029 } 3554 }
3555 return 0; /* can't find valid BIOS pin config */
6030 } 3556 }
6031 set_capture_mixer(codec); 3557 err = alc_auto_fill_dac_nids(codec);
6032 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 3558 if (err < 0)
6033 3559 return err;
6034 spec->vmaster_nid = 0x0c; 3560 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
6035 3561 if (err < 0)
6036 codec->patch_ops = alc_patch_ops; 3562 return err;
6037 if (board_config == ALC880_AUTO) 3563 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
6038 spec->init_hook = alc880_auto_init; 3564 if (err < 0)
6039#ifdef CONFIG_SND_HDA_POWER_SAVE 3565 return err;
6040 if (!spec->loopback.amplist) 3566 err = alc_auto_create_hp_out(codec);
6041 spec->loopback.amplist = alc880_loopbacks; 3567 if (err < 0)
6042#endif 3568 return err;
6043 3569 err = alc_auto_create_speaker_out(codec);
6044 return 0; 3570 if (err < 0)
6045} 3571 return err;
6046 3572 err = alc_auto_create_input_ctls(codec);
6047 3573 if (err < 0)
6048/* 3574 return err;
6049 * ALC260 support
6050 */
6051
6052static const hda_nid_t alc260_dac_nids[1] = {
6053 /* front */
6054 0x02,
6055};
6056
6057static const hda_nid_t alc260_adc_nids[1] = {
6058 /* ADC0 */
6059 0x04,
6060};
6061
6062static const hda_nid_t alc260_adc_nids_alt[1] = {
6063 /* ADC1 */
6064 0x05,
6065};
6066
6067/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6068 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6069 */
6070static const hda_nid_t alc260_dual_adc_nids[2] = {
6071 /* ADC0, ADC1 */
6072 0x04, 0x05
6073};
6074
6075#define ALC260_DIGOUT_NID 0x03
6076#define ALC260_DIGIN_NID 0x06
6077
6078static const struct hda_input_mux alc260_capture_source = {
6079 .num_items = 4,
6080 .items = {
6081 { "Mic", 0x0 },
6082 { "Front Mic", 0x1 },
6083 { "Line", 0x2 },
6084 { "CD", 0x4 },
6085 },
6086};
6087
6088/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
6089 * headphone jack and the internal CD lines since these are the only pins at
6090 * which audio can appear. For flexibility, also allow the option of
6091 * recording the mixer output on the second ADC (ADC0 doesn't have a
6092 * connection to the mixer output).
6093 */
6094static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
6095 {
6096 .num_items = 3,
6097 .items = {
6098 { "Mic/Line", 0x0 },
6099 { "CD", 0x4 },
6100 { "Headphone", 0x2 },
6101 },
6102 },
6103 {
6104 .num_items = 4,
6105 .items = {
6106 { "Mic/Line", 0x0 },
6107 { "CD", 0x4 },
6108 { "Headphone", 0x2 },
6109 { "Mixer", 0x5 },
6110 },
6111 },
6112
6113};
6114
6115/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6116 * the Fujitsu S702x, but jacks are marked differently.
6117 */
6118static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6119 {
6120 .num_items = 4,
6121 .items = {
6122 { "Mic", 0x0 },
6123 { "Line", 0x2 },
6124 { "CD", 0x4 },
6125 { "Headphone", 0x5 },
6126 },
6127 },
6128 {
6129 .num_items = 5,
6130 .items = {
6131 { "Mic", 0x0 },
6132 { "Line", 0x2 },
6133 { "CD", 0x4 },
6134 { "Headphone", 0x6 },
6135 { "Mixer", 0x5 },
6136 },
6137 },
6138};
6139
6140/* Maxdata Favorit 100XS */
6141static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6142 {
6143 .num_items = 2,
6144 .items = {
6145 { "Line/Mic", 0x0 },
6146 { "CD", 0x4 },
6147 },
6148 },
6149 {
6150 .num_items = 3,
6151 .items = {
6152 { "Line/Mic", 0x0 },
6153 { "CD", 0x4 },
6154 { "Mixer", 0x5 },
6155 },
6156 },
6157};
6158
6159/*
6160 * This is just place-holder, so there's something for alc_build_pcms to look
6161 * at when it calculates the maximum number of channels. ALC260 has no mixer
6162 * element which allows changing the channel mode, so the verb list is
6163 * never used.
6164 */
6165static const struct hda_channel_mode alc260_modes[1] = {
6166 { 2, NULL },
6167};
6168
6169
6170/* Mixer combinations
6171 *
6172 * basic: base_output + input + pc_beep + capture
6173 * HP: base_output + input + capture_alt
6174 * HP_3013: hp_3013 + input + capture
6175 * fujitsu: fujitsu + capture
6176 * acer: acer + capture
6177 */
6178 3575
6179static const struct snd_kcontrol_new alc260_base_output_mixer[] = { 3576 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
6180 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6181 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6182 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6183 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6184 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6185 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6186 { } /* end */
6187};
6188 3577
6189static const struct snd_kcontrol_new alc260_input_mixer[] = { 3578 dig_only:
6190 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3579 alc_auto_parse_digital(codec);
6191 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6192 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6193 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6195 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6196 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6197 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6198 { } /* end */
6199};
6200 3580
6201/* update HP, line and mono out pins according to the master switch */ 3581 if (!spec->no_analog)
6202static void alc260_hp_master_update(struct hda_codec *codec) 3582 alc_remove_invalid_adc_nids(codec);
6203{
6204 struct alc_spec *spec = codec->spec;
6205 3583
6206 /* change HP pins */ 3584 if (ssid_nids)
6207 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), 3585 alc_ssid_check(codec, ssid_nids);
6208 spec->autocfg.hp_pins, spec->master_mute, true);
6209 update_speakers(codec);
6210}
6211 3586
6212static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 3587 if (!spec->no_analog) {
6213 struct snd_ctl_elem_value *ucontrol) 3588 alc_auto_check_switches(codec);
6214{ 3589 err = alc_auto_add_mic_boost(codec);
6215 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3590 if (err < 0)
6216 struct alc_spec *spec = codec->spec; 3591 return err;
6217 *ucontrol->value.integer.value = !spec->master_mute; 3592 }
6218 return 0;
6219}
6220 3593
6221static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 3594 if (spec->kctls.list)
6222 struct snd_ctl_elem_value *ucontrol) 3595 add_mixer(spec, spec->kctls.list);
6223{
6224 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6225 struct alc_spec *spec = codec->spec;
6226 int val = !*ucontrol->value.integer.value;
6227 3596
6228 if (val == spec->master_mute)
6229 return 0;
6230 spec->master_mute = val;
6231 alc260_hp_master_update(codec);
6232 return 1; 3597 return 1;
6233} 3598}
6234 3599
6235static const struct snd_kcontrol_new alc260_hp_output_mixer[] = { 3600static int alc880_parse_auto_config(struct hda_codec *codec)
6236 {
6237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6238 .name = "Master Playback Switch",
6239 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6240 .info = snd_ctl_boolean_mono_info,
6241 .get = alc260_hp_master_sw_get,
6242 .put = alc260_hp_master_sw_put,
6243 },
6244 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6245 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6246 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6247 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6248 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6249 HDA_OUTPUT),
6250 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6251 { } /* end */
6252};
6253
6254static const struct hda_verb alc260_hp_unsol_verbs[] = {
6255 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6256 {},
6257};
6258
6259static void alc260_hp_setup(struct hda_codec *codec)
6260{
6261 struct alc_spec *spec = codec->spec;
6262
6263 spec->autocfg.hp_pins[0] = 0x0f;
6264 spec->autocfg.speaker_pins[0] = 0x10;
6265 spec->autocfg.speaker_pins[1] = 0x11;
6266 spec->automute = 1;
6267 spec->automute_mode = ALC_AUTOMUTE_PIN;
6268}
6269
6270static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6271 {
6272 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6273 .name = "Master Playback Switch",
6274 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6275 .info = snd_ctl_boolean_mono_info,
6276 .get = alc260_hp_master_sw_get,
6277 .put = alc260_hp_master_sw_put,
6278 },
6279 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6280 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6281 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6282 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6283 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6285 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6286 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6287 { } /* end */
6288};
6289
6290static void alc260_hp_3013_setup(struct hda_codec *codec)
6291{
6292 struct alc_spec *spec = codec->spec;
6293
6294 spec->autocfg.hp_pins[0] = 0x15;
6295 spec->autocfg.speaker_pins[0] = 0x10;
6296 spec->autocfg.speaker_pins[1] = 0x11;
6297 spec->automute = 1;
6298 spec->automute_mode = ALC_AUTOMUTE_PIN;
6299}
6300
6301static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6302 .ops = &snd_hda_bind_vol,
6303 .values = {
6304 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6305 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6306 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6307 0
6308 },
6309};
6310
6311static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6312 .ops = &snd_hda_bind_sw,
6313 .values = {
6314 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6315 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6316 0
6317 },
6318};
6319
6320static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6321 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6322 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6323 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6324 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6325 { } /* end */
6326};
6327
6328static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6329 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6330 {},
6331};
6332
6333static void alc260_hp_3012_setup(struct hda_codec *codec)
6334{ 3601{
6335 struct alc_spec *spec = codec->spec; 3602 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
6336 3603 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6337 spec->autocfg.hp_pins[0] = 0x10; 3604 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
6338 spec->autocfg.speaker_pins[0] = 0x0f;
6339 spec->autocfg.speaker_pins[1] = 0x11;
6340 spec->autocfg.speaker_pins[2] = 0x15;
6341 spec->automute = 1;
6342 spec->automute_mode = ALC_AUTOMUTE_PIN;
6343} 3605}
6344 3606
6345/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 3607#ifdef CONFIG_SND_HDA_POWER_SAVE
6346 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 3608static const struct hda_amp_list alc880_loopbacks[] = {
6347 */ 3609 { 0x0b, HDA_INPUT, 0 },
6348static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 3610 { 0x0b, HDA_INPUT, 1 },
6349 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3611 { 0x0b, HDA_INPUT, 2 },
6350 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 3612 { 0x0b, HDA_INPUT, 3 },
6351 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3613 { 0x0b, HDA_INPUT, 4 },
6352 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6353 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6354 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6355 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6356 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6357 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6358 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6359 { } /* end */
6360};
6361
6362/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6363 * versions of the ALC260 don't act on requests to enable mic bias from NID
6364 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6365 * datasheet doesn't mention this restriction. At this stage it's not clear
6366 * whether this behaviour is intentional or is a hardware bug in chip
6367 * revisions available in early 2006. Therefore for now allow the
6368 * "Headphone Jack Mode" control to span all choices, but if it turns out
6369 * that the lack of mic bias for this NID is intentional we could change the
6370 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6371 *
6372 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6373 * don't appear to make the mic bias available from the "line" jack, even
6374 * though the NID used for this jack (0x14) can supply it. The theory is
6375 * that perhaps Acer have included blocking capacitors between the ALC260
6376 * and the output jack. If this turns out to be the case for all such
6377 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6378 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6379 *
6380 * The C20x Tablet series have a mono internal speaker which is controlled
6381 * via the chip's Mono sum widget and pin complex, so include the necessary
6382 * controls for such models. On models without a "mono speaker" the control
6383 * won't do anything.
6384 */
6385static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6386 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6387 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6388 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6389 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6390 HDA_OUTPUT),
6391 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6392 HDA_INPUT),
6393 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6394 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6395 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6396 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6397 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6398 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6399 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6400 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6401 { } /* end */
6402};
6403
6404/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6405 */
6406static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6407 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6408 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6409 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6410 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6411 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6412 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6413 { } /* end */
6414};
6415
6416/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6417 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6418 */
6419static const struct snd_kcontrol_new alc260_will_mixer[] = {
6420 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6421 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6422 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6423 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6424 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6425 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6426 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6427 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6428 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6429 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6430 { } /* end */
6431};
6432
6433/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6434 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6435 */
6436static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6437 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6438 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6440 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6441 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6442 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6443 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6444 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6445 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6446 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6447 { } /* end */ 3614 { } /* end */
6448}; 3615};
6449
6450/*
6451 * initialization verbs
6452 */
6453static const struct hda_verb alc260_init_verbs[] = {
6454 /* Line In pin widget for input */
6455 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6456 /* CD pin widget for input */
6457 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6458 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6459 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6460 /* Mic2 (front panel) pin widget for input and vref at 80% */
6461 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6462 /* LINE-2 is used for line-out in rear */
6463 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6464 /* select line-out */
6465 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6466 /* LINE-OUT pin */
6467 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6468 /* enable HP */
6469 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6470 /* enable Mono */
6471 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6472 /* mute capture amp left and right */
6473 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6474 /* set connection select to line in (default select for this ADC) */
6475 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6476 /* mute capture amp left and right */
6477 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6478 /* set connection select to line in (default select for this ADC) */
6479 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6480 /* set vol=0 Line-Out mixer amp left and right */
6481 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6482 /* unmute pin widget amp left and right (no gain on this amp) */
6483 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6484 /* set vol=0 HP mixer amp left and right */
6485 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6486 /* unmute pin widget amp left and right (no gain on this amp) */
6487 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6488 /* set vol=0 Mono mixer amp left and right */
6489 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6490 /* unmute pin widget amp left and right (no gain on this amp) */
6491 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6492 /* unmute LINE-2 out pin */
6493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6494 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6495 * Line In 2 = 0x03
6496 */
6497 /* mute analog inputs */
6498 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6503 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6504 /* mute Front out path */
6505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6506 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6507 /* mute Headphone out path */
6508 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6510 /* mute Mono out path */
6511 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6512 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6513 { }
6514};
6515
6516#if 0 /* should be identical with alc260_init_verbs? */
6517static const struct hda_verb alc260_hp_init_verbs[] = {
6518 /* Headphone and output */
6519 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6520 /* mono output */
6521 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6522 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6523 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6524 /* Mic2 (front panel) pin widget for input and vref at 80% */
6525 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6526 /* Line In pin widget for input */
6527 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6528 /* Line-2 pin widget for output */
6529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6530 /* CD pin widget for input */
6531 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6532 /* unmute amp left and right */
6533 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6534 /* set connection select to line in (default select for this ADC) */
6535 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6536 /* unmute Line-Out mixer amp left and right (volume = 0) */
6537 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6538 /* mute pin widget amp left and right (no gain on this amp) */
6539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6540 /* unmute HP mixer amp left and right (volume = 0) */
6541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6542 /* mute pin widget amp left and right (no gain on this amp) */
6543 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6544 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6545 * Line In 2 = 0x03
6546 */
6547 /* mute analog inputs */
6548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6553 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6554 /* Unmute Front out path */
6555 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6557 /* Unmute Headphone out path */
6558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6560 /* Unmute Mono out path */
6561 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6562 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6563 { }
6564};
6565#endif 3616#endif
6566 3617
6567static const struct hda_verb alc260_hp_3013_init_verbs[] = { 3618/*
6568 /* Line out and output */ 3619 * board setups
6569 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6570 /* mono output */
6571 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6572 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6573 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6574 /* Mic2 (front panel) pin widget for input and vref at 80% */
6575 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6576 /* Line In pin widget for input */
6577 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6578 /* Headphone pin widget for output */
6579 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6580 /* CD pin widget for input */
6581 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6582 /* unmute amp left and right */
6583 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6584 /* set connection select to line in (default select for this ADC) */
6585 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6586 /* unmute Line-Out mixer amp left and right (volume = 0) */
6587 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6588 /* mute pin widget amp left and right (no gain on this amp) */
6589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6590 /* unmute HP mixer amp left and right (volume = 0) */
6591 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6592 /* mute pin widget amp left and right (no gain on this amp) */
6593 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6594 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6595 * Line In 2 = 0x03
6596 */
6597 /* mute analog inputs */
6598 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6599 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6603 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6604 /* Unmute Front out path */
6605 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6607 /* Unmute Headphone out path */
6608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6609 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6610 /* Unmute Mono out path */
6611 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6612 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6613 { }
6614};
6615
6616/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6617 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6618 * audio = 0x16, internal speaker = 0x10.
6619 */
6620static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6621 /* Disable all GPIOs */
6622 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6623 /* Internal speaker is connected to headphone pin */
6624 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6625 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6626 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6627 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6628 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6629 /* Ensure all other unused pins are disabled and muted. */
6630 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6631 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6632 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6633 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6634 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6635 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6636 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6638
6639 /* Disable digital (SPDIF) pins */
6640 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6641 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6642
6643 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6644 * when acting as an output.
6645 */
6646 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6647
6648 /* Start with output sum widgets muted and their output gains at min */
6649 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6650 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6651 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6652 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6653 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6654 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6655 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6656 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6657 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6658
6659 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6660 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6661 /* Unmute Line1 pin widget output buffer since it starts as an output.
6662 * If the pin mode is changed by the user the pin mode control will
6663 * take care of enabling the pin's input/output buffers as needed.
6664 * Therefore there's no need to enable the input buffer at this
6665 * stage.
6666 */
6667 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6668 /* Unmute input buffer of pin widget used for Line-in (no equiv
6669 * mixer ctrl)
6670 */
6671 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6672
6673 /* Mute capture amp left and right */
6674 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6675 /* Set ADC connection select to match default mixer setting - line
6676 * in (on mic1 pin)
6677 */
6678 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6679
6680 /* Do the same for the second ADC: mute capture input amp and
6681 * set ADC connection to line in (on mic1 pin)
6682 */
6683 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6684 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6685
6686 /* Mute all inputs to mixer widget (even unconnected ones) */
6687 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6688 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6689 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6695
6696 { }
6697};
6698
6699/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6700 * similar laptops (adapted from Fujitsu init verbs).
6701 */
6702static const struct hda_verb alc260_acer_init_verbs[] = {
6703 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6704 * the headphone jack. Turn this on and rely on the standard mute
6705 * methods whenever the user wants to turn these outputs off.
6706 */
6707 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6708 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6709 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6710 /* Internal speaker/Headphone jack is connected to Line-out pin */
6711 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6712 /* Internal microphone/Mic jack is connected to Mic1 pin */
6713 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6714 /* Line In jack is connected to Line1 pin */
6715 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6716 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6717 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6718 /* Ensure all other unused pins are disabled and muted. */
6719 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6720 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6721 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6722 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6723 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6725 /* Disable digital (SPDIF) pins */
6726 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6727 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6728
6729 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6730 * bus when acting as outputs.
6731 */
6732 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6733 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6734
6735 /* Start with output sum widgets muted and their output gains at min */
6736 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6737 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6738 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6739 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6740 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6741 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6742 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6743 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6744 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6745
6746 /* Unmute Line-out pin widget amp left and right
6747 * (no equiv mixer ctrl)
6748 */
6749 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6750 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6751 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6752 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6753 * inputs. If the pin mode is changed by the user the pin mode control
6754 * will take care of enabling the pin's input/output buffers as needed.
6755 * Therefore there's no need to enable the input buffer at this
6756 * stage.
6757 */
6758 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6760
6761 /* Mute capture amp left and right */
6762 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6763 /* Set ADC connection select to match default mixer setting - mic
6764 * (on mic1 pin)
6765 */
6766 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6767
6768 /* Do similar with the second ADC: mute capture input amp and
6769 * set ADC connection to mic to match ALSA's default state.
6770 */
6771 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6772 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6773
6774 /* Mute all inputs to mixer widget (even unconnected ones) */
6775 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6776 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6777 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6778 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6783
6784 { }
6785};
6786
6787/* Initialisation sequence for Maxdata Favorit 100XS
6788 * (adapted from Acer init verbs).
6789 */
6790static const struct hda_verb alc260_favorit100_init_verbs[] = {
6791 /* GPIO 0 enables the output jack.
6792 * Turn this on and rely on the standard mute
6793 * methods whenever the user wants to turn these outputs off.
6794 */
6795 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6796 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6797 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6798 /* Line/Mic input jack is connected to Mic1 pin */
6799 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6800 /* Ensure all other unused pins are disabled and muted. */
6801 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6802 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6803 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6804 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6805 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6806 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6807 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6808 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6809 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6810 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6811 /* Disable digital (SPDIF) pins */
6812 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6813 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6814
6815 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6816 * bus when acting as outputs.
6817 */
6818 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6819 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6820
6821 /* Start with output sum widgets muted and their output gains at min */
6822 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6823 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6824 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6825 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6826 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6827 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6828 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6829 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6830 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6831
6832 /* Unmute Line-out pin widget amp left and right
6833 * (no equiv mixer ctrl)
6834 */
6835 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6836 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6837 * inputs. If the pin mode is changed by the user the pin mode control
6838 * will take care of enabling the pin's input/output buffers as needed.
6839 * Therefore there's no need to enable the input buffer at this
6840 * stage.
6841 */
6842 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6843
6844 /* Mute capture amp left and right */
6845 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6846 /* Set ADC connection select to match default mixer setting - mic
6847 * (on mic1 pin)
6848 */
6849 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6850
6851 /* Do similar with the second ADC: mute capture input amp and
6852 * set ADC connection to mic to match ALSA's default state.
6853 */
6854 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6855 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6856
6857 /* Mute all inputs to mixer widget (even unconnected ones) */
6858 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6859 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6860 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6862 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6863 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6864 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6865 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6866
6867 { }
6868};
6869
6870static const struct hda_verb alc260_will_verbs[] = {
6871 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6872 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6873 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6874 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6875 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6876 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6877 {}
6878};
6879
6880static const struct hda_verb alc260_replacer_672v_verbs[] = {
6881 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6882 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6883 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6884
6885 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6886 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6887 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6888
6889 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6890 {}
6891};
6892
6893/* toggle speaker-output according to the hp-jack state */
6894static void alc260_replacer_672v_automute(struct hda_codec *codec)
6895{
6896 unsigned int present;
6897
6898 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6899 present = snd_hda_jack_detect(codec, 0x0f);
6900 if (present) {
6901 snd_hda_codec_write_cache(codec, 0x01, 0,
6902 AC_VERB_SET_GPIO_DATA, 1);
6903 snd_hda_codec_write_cache(codec, 0x0f, 0,
6904 AC_VERB_SET_PIN_WIDGET_CONTROL,
6905 PIN_HP);
6906 } else {
6907 snd_hda_codec_write_cache(codec, 0x01, 0,
6908 AC_VERB_SET_GPIO_DATA, 0);
6909 snd_hda_codec_write_cache(codec, 0x0f, 0,
6910 AC_VERB_SET_PIN_WIDGET_CONTROL,
6911 PIN_OUT);
6912 }
6913}
6914
6915static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6916 unsigned int res)
6917{
6918 if ((res >> 26) == ALC880_HP_EVENT)
6919 alc260_replacer_672v_automute(codec);
6920}
6921
6922static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6923 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6924 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6925 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6926 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6927 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6928 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6929 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6930 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6931 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6932 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6933 {}
6934};
6935
6936/* Test configuration for debugging, modelled after the ALC880 test
6937 * configuration.
6938 */
6939#ifdef CONFIG_SND_DEBUG
6940static const hda_nid_t alc260_test_dac_nids[1] = {
6941 0x02,
6942};
6943static const hda_nid_t alc260_test_adc_nids[2] = {
6944 0x04, 0x05,
6945};
6946/* For testing the ALC260, each input MUX needs its own definition since
6947 * the signal assignments are different. This assumes that the first ADC
6948 * is NID 0x04.
6949 */ 3620 */
6950static const struct hda_input_mux alc260_test_capture_sources[2] = { 3621#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
6951 { 3622#define alc_board_config \
6952 .num_items = 7, 3623 snd_hda_check_board_config
6953 .items = { 3624#define alc_board_codec_sid_config \
6954 { "MIC1 pin", 0x0 }, 3625 snd_hda_check_board_codec_sid_config
6955 { "MIC2 pin", 0x1 }, 3626#include "alc_quirks.c"
6956 { "LINE1 pin", 0x2 }, 3627#else
6957 { "LINE2 pin", 0x3 }, 3628#define alc_board_config(codec, nums, models, tbl) -1
6958 { "CD pin", 0x4 }, 3629#define alc_board_codec_sid_config(codec, nums, models, tbl) -1
6959 { "LINE-OUT pin", 0x5 }, 3630#define setup_preset(codec, x) /* NOP */
6960 { "HP-OUT pin", 0x6 },
6961 },
6962 },
6963 {
6964 .num_items = 8,
6965 .items = {
6966 { "MIC1 pin", 0x0 },
6967 { "MIC2 pin", 0x1 },
6968 { "LINE1 pin", 0x2 },
6969 { "LINE2 pin", 0x3 },
6970 { "CD pin", 0x4 },
6971 { "Mixer", 0x5 },
6972 { "LINE-OUT pin", 0x6 },
6973 { "HP-OUT pin", 0x7 },
6974 },
6975 },
6976};
6977static const struct snd_kcontrol_new alc260_test_mixer[] = {
6978 /* Output driver widgets */
6979 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6980 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6981 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6982 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6983 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6984 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6985
6986 /* Modes for retasking pin widgets
6987 * Note: the ALC260 doesn't seem to act on requests to enable mic
6988 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6989 * mention this restriction. At this stage it's not clear whether
6990 * this behaviour is intentional or is a hardware bug in chip
6991 * revisions available at least up until early 2006. Therefore for
6992 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6993 * choices, but if it turns out that the lack of mic bias for these
6994 * NIDs is intentional we could change their modes from
6995 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6996 */
6997 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6998 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6999 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7000 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7001 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7002 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7003
7004 /* Loopback mixer controls */
7005 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7006 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7007 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7008 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7009 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7010 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7011 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7012 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7013 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7014 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7015 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7016 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7017 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7018 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
7019
7020 /* Controls for GPIO pins, assuming they are configured as outputs */
7021 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7022 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7023 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7024 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7025
7026 /* Switches to allow the digital IO pins to be enabled. The datasheet
7027 * is ambigious as to which NID is which; testing on laptops which
7028 * make this output available should provide clarification.
7029 */
7030 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7031 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7032
7033 /* A switch allowing EAPD to be enabled. Some laptops seem to use
7034 * this output to turn on an external amplifier.
7035 */
7036 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7037 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7038
7039 { } /* end */
7040};
7041static const struct hda_verb alc260_test_init_verbs[] = {
7042 /* Enable all GPIOs as outputs with an initial value of 0 */
7043 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7044 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7045 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7046
7047 /* Enable retasking pins as output, initially without power amp */
7048 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7049 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7050 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7051 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7052 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7053 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7054
7055 /* Disable digital (SPDIF) pins initially, but users can enable
7056 * them via a mixer switch. In the case of SPDIF-out, this initverb
7057 * payload also sets the generation to 0, output to be in "consumer"
7058 * PCM format, copyright asserted, no pre-emphasis and no validity
7059 * control.
7060 */
7061 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7062 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7063
7064 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7065 * OUT1 sum bus when acting as an output.
7066 */
7067 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7068 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7069 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7070 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7071
7072 /* Start with output sum widgets muted and their output gains at min */
7073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7074 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7075 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7076 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7077 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7078 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7079 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7080 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7081 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7082
7083 /* Unmute retasking pin widget output buffers since the default
7084 * state appears to be output. As the pin mode is changed by the
7085 * user the pin mode control will take care of enabling the pin's
7086 * input/output buffers as needed.
7087 */
7088 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7089 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7090 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7091 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7092 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7093 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7094 /* Also unmute the mono-out pin widget */
7095 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7096
7097 /* Mute capture amp left and right */
7098 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7099 /* Set ADC connection select to match default mixer setting (mic1
7100 * pin)
7101 */
7102 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7103
7104 /* Do the same for the second ADC: mute capture input amp and
7105 * set ADC connection to mic1 pin
7106 */
7107 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7108 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7109
7110 /* Mute all inputs to mixer widget (even unconnected ones) */
7111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7113 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7117 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7119
7120 { }
7121};
7122#endif 3631#endif
7123 3632
7124#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7125#define alc260_pcm_analog_capture alc880_pcm_analog_capture
7126
7127#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7128#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7129
7130/* 3633/*
7131 * for BIOS auto-configuration 3634 * OK, here we have finally the patch for ALC880
7132 */ 3635 */
3636#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3637#include "alc880_quirks.c"
3638#endif
7133 3639
7134static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 3640static int patch_alc880(struct hda_codec *codec)
7135 const char *pfx, int *vol_bits)
7136{ 3641{
7137 hda_nid_t nid_vol; 3642 struct alc_spec *spec;
7138 unsigned long vol_val, sw_val; 3643 int board_config;
7139 int err; 3644 int err;
7140 3645
7141 if (nid >= 0x0f && nid < 0x11) { 3646 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7142 nid_vol = nid - 0x7; 3647 if (spec == NULL)
7143 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 3648 return -ENOMEM;
7144 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7145 } else if (nid == 0x11) {
7146 nid_vol = nid - 0x7;
7147 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7148 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7149 } else if (nid >= 0x12 && nid <= 0x15) {
7150 nid_vol = 0x08;
7151 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7152 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7153 } else
7154 return 0; /* N/A */
7155
7156 if (!(*vol_bits & (1 << nid_vol))) {
7157 /* first control for the volume widget */
7158 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
7159 if (err < 0)
7160 return err;
7161 *vol_bits |= (1 << nid_vol);
7162 }
7163 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
7164 if (err < 0)
7165 return err;
7166 return 1;
7167}
7168 3649
7169/* add playback controls from the parsed DAC table */ 3650 codec->spec = spec;
7170static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7171 const struct auto_pin_cfg *cfg)
7172{
7173 hda_nid_t nid;
7174 int err;
7175 int vols = 0;
7176 3651
7177 spec->multiout.num_dacs = 1; 3652 spec->mixer_nid = 0x0b;
7178 spec->multiout.dac_nids = spec->private_dac_nids; 3653 spec->need_dac_fix = 1;
7179 spec->private_dac_nids[0] = 0x02;
7180
7181 nid = cfg->line_out_pins[0];
7182 if (nid) {
7183 const char *pfx;
7184 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7185 pfx = "Master";
7186 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7187 pfx = "Speaker";
7188 else
7189 pfx = "Front";
7190 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
7191 if (err < 0)
7192 return err;
7193 }
7194 3654
7195 nid = cfg->speaker_pins[0]; 3655 board_config = alc_board_config(codec, ALC880_MODEL_LAST,
7196 if (nid) { 3656 alc880_models, alc880_cfg_tbl);
7197 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 3657 if (board_config < 0) {
7198 if (err < 0) 3658 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7199 return err; 3659 codec->chip_name);
3660 board_config = ALC_MODEL_AUTO;
7200 } 3661 }
7201 3662
7202 nid = cfg->hp_pins[0]; 3663 if (board_config == ALC_MODEL_AUTO) {
7203 if (nid) { 3664 /* automatic parse from the BIOS config */
7204 err = alc260_add_playback_controls(spec, nid, "Headphone", 3665 err = alc880_parse_auto_config(codec);
7205 &vols); 3666 if (err < 0) {
7206 if (err < 0) 3667 alc_free(codec);
7207 return err; 3668 return err;
3669 }
3670#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3671 else if (!err) {
3672 printk(KERN_INFO
3673 "hda_codec: Cannot set up configuration "
3674 "from BIOS. Using 3-stack mode...\n");
3675 board_config = ALC880_3ST;
3676 }
3677#endif
7208 } 3678 }
7209 return 0;
7210}
7211 3679
7212/* create playback/capture controls for input pins */ 3680 if (board_config != ALC_MODEL_AUTO)
7213static int alc260_auto_create_input_ctls(struct hda_codec *codec, 3681 setup_preset(codec, &alc880_presets[board_config]);
7214 const struct auto_pin_cfg *cfg)
7215{
7216 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
7217}
7218 3682
7219static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 3683 if (!spec->no_analog && !spec->adc_nids) {
7220 hda_nid_t nid, int pin_type, 3684 alc_auto_fill_adc_caps(codec);
7221 int sel_idx) 3685 alc_rebuild_imux_for_auto_mic(codec);
7222{ 3686 alc_remove_invalid_adc_nids(codec);
7223 alc_set_pin_output(codec, nid, pin_type);
7224 /* need the manual connection? */
7225 if (nid >= 0x12) {
7226 int idx = nid - 0x12;
7227 snd_hda_codec_write(codec, idx + 0x0b, 0,
7228 AC_VERB_SET_CONNECT_SEL, sel_idx);
7229 } 3687 }
7230}
7231 3688
7232static void alc260_auto_init_multi_out(struct hda_codec *codec) 3689 if (!spec->no_analog && !spec->cap_mixer)
7233{ 3690 set_capture_mixer(codec);
7234 struct alc_spec *spec = codec->spec;
7235 hda_nid_t nid;
7236 3691
7237 nid = spec->autocfg.line_out_pins[0]; 3692 if (!spec->no_analog) {
7238 if (nid) { 3693 err = snd_hda_attach_beep_device(codec, 0x1);
7239 int pin_type = get_pin_type(spec->autocfg.line_out_type); 3694 if (err < 0) {
7240 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 3695 alc_free(codec);
3696 return err;
3697 }
3698 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7241 } 3699 }
7242 3700
7243 nid = spec->autocfg.speaker_pins[0]; 3701 spec->vmaster_nid = 0x0c;
7244 if (nid)
7245 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7246
7247 nid = spec->autocfg.hp_pins[0];
7248 if (nid)
7249 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7250}
7251 3702
7252#define ALC260_PIN_CD_NID 0x16 3703 codec->patch_ops = alc_patch_ops;
7253static void alc260_auto_init_analog_input(struct hda_codec *codec) 3704 if (board_config == ALC_MODEL_AUTO)
7254{ 3705 spec->init_hook = alc_auto_init_std;
7255 struct alc_spec *spec = codec->spec; 3706#ifdef CONFIG_SND_HDA_POWER_SAVE
7256 struct auto_pin_cfg *cfg = &spec->autocfg; 3707 if (!spec->loopback.amplist)
7257 int i; 3708 spec->loopback.amplist = alc880_loopbacks;
3709#endif
7258 3710
7259 for (i = 0; i < cfg->num_inputs; i++) { 3711 return 0;
7260 hda_nid_t nid = cfg->inputs[i].pin;
7261 if (nid >= 0x12) {
7262 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
7263 if (nid != ALC260_PIN_CD_NID &&
7264 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
7265 snd_hda_codec_write(codec, nid, 0,
7266 AC_VERB_SET_AMP_GAIN_MUTE,
7267 AMP_OUT_MUTE);
7268 }
7269 }
7270} 3712}
7271 3713
7272#define alc260_auto_init_input_src alc880_auto_init_input_src
7273 3714
7274/* 3715/*
7275 * generic initialization of ADC, input mixers and output mixers 3716 * ALC260 support
7276 */ 3717 */
7277static const struct hda_verb alc260_volume_init_verbs[] = {
7278 /*
7279 * Unmute ADC0-1 and set the default input to mic-in
7280 */
7281 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7282 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7283 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7284 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7285
7286 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7287 * mixer widget
7288 * Note: PASD motherboards uses the Line In 2 as the input for
7289 * front panel mic (mic 2)
7290 */
7291 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7292 /* mute analog inputs */
7293 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7294 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7295 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7296 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7297 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7298
7299 /*
7300 * Set up output mixers (0x08 - 0x0a)
7301 */
7302 /* set vol=0 to output mixers */
7303 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7304 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7305 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7306 /* set up input amps for analog loopback */
7307 /* Amp Indices: DAC = 0, mixer = 1 */
7308 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7309 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7310 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7311 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7312 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7313 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7314
7315 { }
7316};
7317
7318static int alc260_parse_auto_config(struct hda_codec *codec) 3718static int alc260_parse_auto_config(struct hda_codec *codec)
7319{ 3719{
7320 struct alc_spec *spec = codec->spec;
7321 int err;
7322 static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; 3720 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7323 3721 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
7324 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3722 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
7325 alc260_ignore);
7326 if (err < 0)
7327 return err;
7328 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7329 if (err < 0)
7330 return err;
7331 if (!spec->kctls.list)
7332 return 0; /* can't find valid BIOS pin config */
7333 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7334 if (err < 0)
7335 return err;
7336
7337 spec->multiout.max_channels = 2;
7338
7339 if (spec->autocfg.dig_outs)
7340 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7341 if (spec->kctls.list)
7342 add_mixer(spec, spec->kctls.list);
7343
7344 add_verb(spec, alc260_volume_init_verbs);
7345
7346 spec->num_mux_defs = 1;
7347 spec->input_mux = &spec->private_imux[0];
7348
7349 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7350
7351 return 1;
7352}
7353
7354/* additional initialization for auto-configuration model */
7355static void alc260_auto_init(struct hda_codec *codec)
7356{
7357 struct alc_spec *spec = codec->spec;
7358 alc260_auto_init_multi_out(codec);
7359 alc260_auto_init_analog_input(codec);
7360 alc260_auto_init_input_src(codec);
7361 alc_auto_init_digital(codec);
7362 if (spec->unsol_event)
7363 alc_inithook(codec);
7364} 3723}
7365 3724
7366#ifdef CONFIG_SND_HDA_POWER_SAVE 3725#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -7397,186 +3756,10 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7397}; 3756};
7398 3757
7399/* 3758/*
7400 * ALC260 configurations
7401 */ 3759 */
7402static const char * const alc260_models[ALC260_MODEL_LAST] = { 3760#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
7403 [ALC260_BASIC] = "basic", 3761#include "alc260_quirks.c"
7404 [ALC260_HP] = "hp",
7405 [ALC260_HP_3013] = "hp-3013",
7406 [ALC260_HP_DC7600] = "hp-dc7600",
7407 [ALC260_FUJITSU_S702X] = "fujitsu",
7408 [ALC260_ACER] = "acer",
7409 [ALC260_WILL] = "will",
7410 [ALC260_REPLACER_672V] = "replacer",
7411 [ALC260_FAVORIT100] = "favorit100",
7412#ifdef CONFIG_SND_DEBUG
7413 [ALC260_TEST] = "test",
7414#endif
7415 [ALC260_AUTO] = "auto",
7416};
7417
7418static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7419 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7420 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7421 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7422 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7423 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7424 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7425 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7426 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7427 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7428 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7429 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7430 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7431 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7432 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7433 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7434 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7435 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7436 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7437 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7438 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7439 {}
7440};
7441
7442static const struct alc_config_preset alc260_presets[] = {
7443 [ALC260_BASIC] = {
7444 .mixers = { alc260_base_output_mixer,
7445 alc260_input_mixer },
7446 .init_verbs = { alc260_init_verbs },
7447 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7448 .dac_nids = alc260_dac_nids,
7449 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7450 .adc_nids = alc260_dual_adc_nids,
7451 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7452 .channel_mode = alc260_modes,
7453 .input_mux = &alc260_capture_source,
7454 },
7455 [ALC260_HP] = {
7456 .mixers = { alc260_hp_output_mixer,
7457 alc260_input_mixer },
7458 .init_verbs = { alc260_init_verbs,
7459 alc260_hp_unsol_verbs },
7460 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7461 .dac_nids = alc260_dac_nids,
7462 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7463 .adc_nids = alc260_adc_nids_alt,
7464 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7465 .channel_mode = alc260_modes,
7466 .input_mux = &alc260_capture_source,
7467 .unsol_event = alc_sku_unsol_event,
7468 .setup = alc260_hp_setup,
7469 .init_hook = alc_inithook,
7470 },
7471 [ALC260_HP_DC7600] = {
7472 .mixers = { alc260_hp_dc7600_mixer,
7473 alc260_input_mixer },
7474 .init_verbs = { alc260_init_verbs,
7475 alc260_hp_dc7600_verbs },
7476 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7477 .dac_nids = alc260_dac_nids,
7478 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7479 .adc_nids = alc260_adc_nids_alt,
7480 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7481 .channel_mode = alc260_modes,
7482 .input_mux = &alc260_capture_source,
7483 .unsol_event = alc_sku_unsol_event,
7484 .setup = alc260_hp_3012_setup,
7485 .init_hook = alc_inithook,
7486 },
7487 [ALC260_HP_3013] = {
7488 .mixers = { alc260_hp_3013_mixer,
7489 alc260_input_mixer },
7490 .init_verbs = { alc260_hp_3013_init_verbs,
7491 alc260_hp_3013_unsol_verbs },
7492 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7493 .dac_nids = alc260_dac_nids,
7494 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7495 .adc_nids = alc260_adc_nids_alt,
7496 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7497 .channel_mode = alc260_modes,
7498 .input_mux = &alc260_capture_source,
7499 .unsol_event = alc_sku_unsol_event,
7500 .setup = alc260_hp_3013_setup,
7501 .init_hook = alc_inithook,
7502 },
7503 [ALC260_FUJITSU_S702X] = {
7504 .mixers = { alc260_fujitsu_mixer },
7505 .init_verbs = { alc260_fujitsu_init_verbs },
7506 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7507 .dac_nids = alc260_dac_nids,
7508 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7509 .adc_nids = alc260_dual_adc_nids,
7510 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7511 .channel_mode = alc260_modes,
7512 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7513 .input_mux = alc260_fujitsu_capture_sources,
7514 },
7515 [ALC260_ACER] = {
7516 .mixers = { alc260_acer_mixer },
7517 .init_verbs = { alc260_acer_init_verbs },
7518 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7519 .dac_nids = alc260_dac_nids,
7520 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7521 .adc_nids = alc260_dual_adc_nids,
7522 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7523 .channel_mode = alc260_modes,
7524 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7525 .input_mux = alc260_acer_capture_sources,
7526 },
7527 [ALC260_FAVORIT100] = {
7528 .mixers = { alc260_favorit100_mixer },
7529 .init_verbs = { alc260_favorit100_init_verbs },
7530 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7531 .dac_nids = alc260_dac_nids,
7532 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7533 .adc_nids = alc260_dual_adc_nids,
7534 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7535 .channel_mode = alc260_modes,
7536 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7537 .input_mux = alc260_favorit100_capture_sources,
7538 },
7539 [ALC260_WILL] = {
7540 .mixers = { alc260_will_mixer },
7541 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7542 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7543 .dac_nids = alc260_dac_nids,
7544 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7545 .adc_nids = alc260_adc_nids,
7546 .dig_out_nid = ALC260_DIGOUT_NID,
7547 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7548 .channel_mode = alc260_modes,
7549 .input_mux = &alc260_capture_source,
7550 },
7551 [ALC260_REPLACER_672V] = {
7552 .mixers = { alc260_replacer_672v_mixer },
7553 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7554 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7555 .dac_nids = alc260_dac_nids,
7556 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7557 .adc_nids = alc260_adc_nids,
7558 .dig_out_nid = ALC260_DIGOUT_NID,
7559 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7560 .channel_mode = alc260_modes,
7561 .input_mux = &alc260_capture_source,
7562 .unsol_event = alc260_replacer_672v_unsol_event,
7563 .init_hook = alc260_replacer_672v_automute,
7564 },
7565#ifdef CONFIG_SND_DEBUG
7566 [ALC260_TEST] = {
7567 .mixers = { alc260_test_mixer },
7568 .init_verbs = { alc260_test_init_verbs },
7569 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7570 .dac_nids = alc260_test_dac_nids,
7571 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7572 .adc_nids = alc260_test_adc_nids,
7573 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7574 .channel_mode = alc260_modes,
7575 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7576 .input_mux = alc260_test_capture_sources,
7577 },
7578#endif 3762#endif
7579};
7580 3763
7581static int patch_alc260(struct hda_codec *codec) 3764static int patch_alc260(struct hda_codec *codec)
7582{ 3765{
@@ -7589,73 +3772,66 @@ static int patch_alc260(struct hda_codec *codec)
7589 3772
7590 codec->spec = spec; 3773 codec->spec = spec;
7591 3774
7592 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 3775 spec->mixer_nid = 0x07;
7593 alc260_models, 3776
7594 alc260_cfg_tbl); 3777 board_config = alc_board_config(codec, ALC260_MODEL_LAST,
3778 alc260_models, alc260_cfg_tbl);
7595 if (board_config < 0) { 3779 if (board_config < 0) {
7596 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 3780 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7597 codec->chip_name); 3781 codec->chip_name);
7598 board_config = ALC260_AUTO; 3782 board_config = ALC_MODEL_AUTO;
7599 } 3783 }
7600 3784
7601 if (board_config == ALC260_AUTO) { 3785 if (board_config == ALC_MODEL_AUTO) {
7602 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); 3786 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7603 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 3787 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7604 } 3788 }
7605 3789
7606 if (board_config == ALC260_AUTO) { 3790 if (board_config == ALC_MODEL_AUTO) {
7607 /* automatic parse from the BIOS config */ 3791 /* automatic parse from the BIOS config */
7608 err = alc260_parse_auto_config(codec); 3792 err = alc260_parse_auto_config(codec);
7609 if (err < 0) { 3793 if (err < 0) {
7610 alc_free(codec); 3794 alc_free(codec);
7611 return err; 3795 return err;
7612 } else if (!err) { 3796 }
3797#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3798 else if (!err) {
7613 printk(KERN_INFO 3799 printk(KERN_INFO
7614 "hda_codec: Cannot set up configuration " 3800 "hda_codec: Cannot set up configuration "
7615 "from BIOS. Using base mode...\n"); 3801 "from BIOS. Using base mode...\n");
7616 board_config = ALC260_BASIC; 3802 board_config = ALC260_BASIC;
7617 } 3803 }
3804#endif
7618 } 3805 }
7619 3806
7620 err = snd_hda_attach_beep_device(codec, 0x1); 3807 if (board_config != ALC_MODEL_AUTO)
7621 if (err < 0) { 3808 setup_preset(codec, &alc260_presets[board_config]);
7622 alc_free(codec); 3809
7623 return err; 3810 if (!spec->no_analog && !spec->adc_nids) {
3811 alc_auto_fill_adc_caps(codec);
3812 alc_rebuild_imux_for_auto_mic(codec);
3813 alc_remove_invalid_adc_nids(codec);
7624 } 3814 }
7625 3815
7626 if (board_config != ALC260_AUTO) 3816 if (!spec->no_analog && !spec->cap_mixer)
7627 setup_preset(codec, &alc260_presets[board_config]); 3817 set_capture_mixer(codec);
7628 3818
7629 spec->stream_analog_playback = &alc260_pcm_analog_playback; 3819 if (!spec->no_analog) {
7630 spec->stream_analog_capture = &alc260_pcm_analog_capture; 3820 err = snd_hda_attach_beep_device(codec, 0x1);
7631 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture; 3821 if (err < 0) {
7632 3822 alc_free(codec);
7633 spec->stream_digital_playback = &alc260_pcm_digital_playback; 3823 return err;
7634 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7635
7636 if (!spec->adc_nids && spec->input_mux) {
7637 /* check whether NID 0x04 is valid */
7638 unsigned int wcap = get_wcaps(codec, 0x04);
7639 wcap = get_wcaps_type(wcap);
7640 /* get type */
7641 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7642 spec->adc_nids = alc260_adc_nids_alt;
7643 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7644 } else {
7645 spec->adc_nids = alc260_adc_nids;
7646 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7647 } 3824 }
3825 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7648 } 3826 }
7649 set_capture_mixer(codec);
7650 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7651 3827
7652 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 3828 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7653 3829
7654 spec->vmaster_nid = 0x08; 3830 spec->vmaster_nid = 0x08;
7655 3831
7656 codec->patch_ops = alc_patch_ops; 3832 codec->patch_ops = alc_patch_ops;
7657 if (board_config == ALC260_AUTO) 3833 if (board_config == ALC_MODEL_AUTO)
7658 spec->init_hook = alc260_auto_init; 3834 spec->init_hook = alc_auto_init_std;
7659 spec->shutup = alc_eapd_shutup; 3835 spec->shutup = alc_eapd_shutup;
7660#ifdef CONFIG_SND_HDA_POWER_SAVE 3836#ifdef CONFIG_SND_HDA_POWER_SAVE
7661 if (!spec->loopback.amplist) 3837 if (!spec->loopback.amplist)
@@ -7677,3299 +3853,10 @@ static int patch_alc260(struct hda_codec *codec)
7677 * In addition, an independent DAC for the multi-playback (not used in this 3853 * In addition, an independent DAC for the multi-playback (not used in this
7678 * driver yet). 3854 * driver yet).
7679 */ 3855 */
7680#define ALC882_DIGOUT_NID 0x06
7681#define ALC882_DIGIN_NID 0x0a
7682#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7683#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7684#define ALC1200_DIGOUT_NID 0x10
7685
7686
7687static const struct hda_channel_mode alc882_ch_modes[1] = {
7688 { 8, NULL }
7689};
7690
7691/* DACs */
7692static const hda_nid_t alc882_dac_nids[4] = {
7693 /* front, rear, clfe, rear_surr */
7694 0x02, 0x03, 0x04, 0x05
7695};
7696#define alc883_dac_nids alc882_dac_nids
7697
7698/* ADCs */
7699#define alc882_adc_nids alc880_adc_nids
7700#define alc882_adc_nids_alt alc880_adc_nids_alt
7701#define alc883_adc_nids alc882_adc_nids_alt
7702static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7703static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7704#define alc889_adc_nids alc880_adc_nids
7705
7706static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7707static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7708#define alc883_capsrc_nids alc882_capsrc_nids_alt
7709static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7710#define alc889_capsrc_nids alc882_capsrc_nids
7711
7712/* input MUX */
7713/* FIXME: should be a matrix-type input source selection */
7714
7715static const struct hda_input_mux alc882_capture_source = {
7716 .num_items = 4,
7717 .items = {
7718 { "Mic", 0x0 },
7719 { "Front Mic", 0x1 },
7720 { "Line", 0x2 },
7721 { "CD", 0x4 },
7722 },
7723};
7724
7725#define alc883_capture_source alc882_capture_source
7726
7727static const struct hda_input_mux alc889_capture_source = {
7728 .num_items = 3,
7729 .items = {
7730 { "Front Mic", 0x0 },
7731 { "Mic", 0x3 },
7732 { "Line", 0x2 },
7733 },
7734};
7735
7736static const struct hda_input_mux mb5_capture_source = {
7737 .num_items = 3,
7738 .items = {
7739 { "Mic", 0x1 },
7740 { "Line", 0x7 },
7741 { "CD", 0x4 },
7742 },
7743};
7744
7745static const struct hda_input_mux macmini3_capture_source = {
7746 .num_items = 2,
7747 .items = {
7748 { "Line", 0x2 },
7749 { "CD", 0x4 },
7750 },
7751};
7752
7753static const struct hda_input_mux alc883_3stack_6ch_intel = {
7754 .num_items = 4,
7755 .items = {
7756 { "Mic", 0x1 },
7757 { "Front Mic", 0x0 },
7758 { "Line", 0x2 },
7759 { "CD", 0x4 },
7760 },
7761};
7762
7763static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7764 .num_items = 2,
7765 .items = {
7766 { "Mic", 0x1 },
7767 { "Line", 0x2 },
7768 },
7769};
7770
7771static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7772 .num_items = 4,
7773 .items = {
7774 { "Mic", 0x0 },
7775 { "Internal Mic", 0x1 },
7776 { "Line", 0x2 },
7777 { "CD", 0x4 },
7778 },
7779};
7780
7781static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7782 .num_items = 2,
7783 .items = {
7784 { "Mic", 0x0 },
7785 { "Internal Mic", 0x1 },
7786 },
7787};
7788
7789static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7790 .num_items = 3,
7791 .items = {
7792 { "Mic", 0x0 },
7793 { "Front Mic", 0x1 },
7794 { "Line", 0x4 },
7795 },
7796};
7797
7798static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7799 .num_items = 2,
7800 .items = {
7801 { "Mic", 0x0 },
7802 { "Line", 0x2 },
7803 },
7804};
7805
7806static const struct hda_input_mux alc889A_mb31_capture_source = {
7807 .num_items = 2,
7808 .items = {
7809 { "Mic", 0x0 },
7810 /* Front Mic (0x01) unused */
7811 { "Line", 0x2 },
7812 /* Line 2 (0x03) unused */
7813 /* CD (0x04) unused? */
7814 },
7815};
7816
7817static const struct hda_input_mux alc889A_imac91_capture_source = {
7818 .num_items = 2,
7819 .items = {
7820 { "Mic", 0x01 },
7821 { "Line", 0x2 }, /* Not sure! */
7822 },
7823};
7824
7825/*
7826 * 2ch mode
7827 */
7828static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7829 { 2, NULL }
7830};
7831
7832/*
7833 * 2ch mode
7834 */
7835static const struct hda_verb alc882_3ST_ch2_init[] = {
7836 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7837 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7838 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7839 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7840 { } /* end */
7841};
7842
7843/*
7844 * 4ch mode
7845 */
7846static const struct hda_verb alc882_3ST_ch4_init[] = {
7847 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7848 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7849 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7850 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7851 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7852 { } /* end */
7853};
7854
7855/*
7856 * 6ch mode
7857 */
7858static const struct hda_verb alc882_3ST_ch6_init[] = {
7859 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7860 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7861 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7862 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7863 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7864 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7865 { } /* end */
7866};
7867
7868static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7869 { 2, alc882_3ST_ch2_init },
7870 { 4, alc882_3ST_ch4_init },
7871 { 6, alc882_3ST_ch6_init },
7872};
7873
7874#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7875
7876/*
7877 * 2ch mode
7878 */
7879static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7880 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7881 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7882 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7883 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7884 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7885 { } /* end */
7886};
7887
7888/*
7889 * 4ch mode
7890 */
7891static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7892 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7893 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7894 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7895 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7896 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7897 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7898 { } /* end */
7899};
7900
7901/*
7902 * 6ch mode
7903 */
7904static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7905 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7906 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7908 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
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
7915static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7916 { 2, alc883_3ST_ch2_clevo_init },
7917 { 4, alc883_3ST_ch4_clevo_init },
7918 { 6, alc883_3ST_ch6_clevo_init },
7919};
7920
7921
7922/*
7923 * 6ch mode
7924 */
7925static const struct hda_verb alc882_sixstack_ch6_init[] = {
7926 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7927 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7928 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7929 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7930 { } /* end */
7931};
7932
7933/*
7934 * 8ch mode
7935 */
7936static const struct hda_verb alc882_sixstack_ch8_init[] = {
7937 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7938 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7940 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7941 { } /* end */
7942};
7943
7944static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7945 { 6, alc882_sixstack_ch6_init },
7946 { 8, alc882_sixstack_ch8_init },
7947};
7948
7949
7950/* Macbook Air 2,1 */
7951
7952static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7953 { 2, NULL },
7954};
7955
7956/*
7957 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7958 */
7959
7960/*
7961 * 2ch mode
7962 */
7963static const struct hda_verb alc885_mbp_ch2_init[] = {
7964 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7965 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7966 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7967 { } /* end */
7968};
7969
7970/*
7971 * 4ch mode
7972 */
7973static const struct hda_verb alc885_mbp_ch4_init[] = {
7974 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7975 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7976 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7977 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7978 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7979 { } /* end */
7980};
7981
7982static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7983 { 2, alc885_mbp_ch2_init },
7984 { 4, alc885_mbp_ch4_init },
7985};
7986
7987/*
7988 * 2ch
7989 * Speakers/Woofer/HP = Front
7990 * LineIn = Input
7991 */
7992static const struct hda_verb alc885_mb5_ch2_init[] = {
7993 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7994 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7995 { } /* end */
7996};
7997
7998/*
7999 * 6ch mode
8000 * Speakers/HP = Front
8001 * Woofer = LFE
8002 * LineIn = Surround
8003 */
8004static const struct hda_verb alc885_mb5_ch6_init[] = {
8005 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8006 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8007 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8008 { } /* end */
8009};
8010
8011static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
8012 { 2, alc885_mb5_ch2_init },
8013 { 6, alc885_mb5_ch6_init },
8014};
8015
8016#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
8017
8018/*
8019 * 2ch mode
8020 */
8021static const struct hda_verb alc883_4ST_ch2_init[] = {
8022 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8023 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8024 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8025 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8026 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8027 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8028 { } /* end */
8029};
8030
8031/*
8032 * 4ch mode
8033 */
8034static const struct hda_verb alc883_4ST_ch4_init[] = {
8035 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8036 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8037 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8038 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8039 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8040 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8041 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8042 { } /* end */
8043};
8044
8045/*
8046 * 6ch mode
8047 */
8048static const struct hda_verb alc883_4ST_ch6_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_OUT },
8052 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8053 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8054 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8055 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8056 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8057 { } /* end */
8058};
8059
8060/*
8061 * 8ch mode
8062 */
8063static const struct hda_verb alc883_4ST_ch8_init[] = {
8064 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8065 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8066 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8067 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8068 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8069 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8070 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8071 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8072 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8073 { } /* end */
8074};
8075
8076static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
8077 { 2, alc883_4ST_ch2_init },
8078 { 4, alc883_4ST_ch4_init },
8079 { 6, alc883_4ST_ch6_init },
8080 { 8, alc883_4ST_ch8_init },
8081};
8082
8083
8084/*
8085 * 2ch mode
8086 */
8087static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
8088 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8089 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8090 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8091 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8092 { } /* end */
8093};
8094
8095/*
8096 * 4ch mode
8097 */
8098static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
8099 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8100 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8101 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8102 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8103 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8104 { } /* end */
8105};
8106
8107/*
8108 * 6ch mode
8109 */
8110static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
8111 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8112 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8113 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8114 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8115 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8116 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8117 { } /* end */
8118};
8119
8120static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
8121 { 2, alc883_3ST_ch2_intel_init },
8122 { 4, alc883_3ST_ch4_intel_init },
8123 { 6, alc883_3ST_ch6_intel_init },
8124};
8125
8126/*
8127 * 2ch mode
8128 */
8129static const struct hda_verb alc889_ch2_intel_init[] = {
8130 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8131 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8132 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8133 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8134 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8135 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8136 { } /* end */
8137};
8138
8139/*
8140 * 6ch mode
8141 */
8142static const struct hda_verb alc889_ch6_intel_init[] = {
8143 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8144 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8145 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8146 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8147 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8148 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8149 { } /* end */
8150};
8151
8152/*
8153 * 8ch mode
8154 */
8155static const struct hda_verb alc889_ch8_intel_init[] = {
8156 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8157 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8158 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8159 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8160 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
8161 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8162 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8163 { } /* end */
8164};
8165
8166static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
8167 { 2, alc889_ch2_intel_init },
8168 { 6, alc889_ch6_intel_init },
8169 { 8, alc889_ch8_intel_init },
8170};
8171
8172/*
8173 * 6ch mode
8174 */
8175static const struct hda_verb alc883_sixstack_ch6_init[] = {
8176 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8177 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8178 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8179 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8180 { } /* end */
8181};
8182
8183/*
8184 * 8ch mode
8185 */
8186static const struct hda_verb alc883_sixstack_ch8_init[] = {
8187 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8188 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8189 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8190 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8191 { } /* end */
8192};
8193
8194static const struct hda_channel_mode alc883_sixstack_modes[2] = {
8195 { 6, alc883_sixstack_ch6_init },
8196 { 8, alc883_sixstack_ch8_init },
8197};
8198
8199
8200/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8201 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8202 */
8203static const struct snd_kcontrol_new alc882_base_mixer[] = {
8204 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8205 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8206 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8207 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8208 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8209 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8210 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8211 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8212 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8213 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8214 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8215 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8216 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8217 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8218 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8219 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8220 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8221 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8222 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8223 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8224 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8225 { } /* end */
8226};
8227
8228/* Macbook Air 2,1 same control for HP and internal Speaker */
8229
8230static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8231 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8232 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8233 { }
8234};
8235
8236
8237static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8238 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8239 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8240 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8241 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8242 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8243 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8244 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8245 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8246 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8247 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8248 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8249 { } /* end */
8250};
8251
8252static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8253 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8254 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8255 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8256 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8257 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8258 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8259 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8260 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8261 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8262 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8264 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8265 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8266 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8267 { } /* end */
8268};
8269
8270static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8271 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8272 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8273 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8274 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8275 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8276 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8277 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8278 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8279 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8280 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8281 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8282 { } /* end */
8283};
8284
8285static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8286 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8287 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8288 { } /* end */
8289};
8290
8291
8292static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8293 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8294 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8295 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8296 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8297 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8298 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8299 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8300 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8301 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8302 { } /* end */
8303};
8304
8305static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8306 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8307 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8308 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
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_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8315 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8316 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8317 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8318 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8319 { } /* end */
8320};
8321
8322/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8323 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8324 */
8325static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8326 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8327 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8329 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8330 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8331 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8332 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8333 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8334 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8335 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8336 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8337 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8338 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8339 { } /* end */
8340};
8341
8342static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8343 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8344 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8346 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8347 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8348 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8349 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8351 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8352 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8353 { } /* end */
8354};
8355
8356static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8357 {
8358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8359 .name = "Channel Mode",
8360 .info = alc_ch_mode_info,
8361 .get = alc_ch_mode_get,
8362 .put = alc_ch_mode_put,
8363 },
8364 { } /* end */
8365};
8366
8367static const struct hda_verb alc882_base_init_verbs[] = {
8368 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8371 /* Rear mixer */
8372 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8374 /* CLFE mixer */
8375 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8377 /* Side mixer */
8378 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8380
8381 /* Front Pin: output 0 (0x0c) */
8382 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8383 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8384 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8385 /* Rear Pin: output 1 (0x0d) */
8386 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8387 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8388 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8389 /* CLFE Pin: output 2 (0x0e) */
8390 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8391 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8392 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8393 /* Side Pin: output 3 (0x0f) */
8394 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8395 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8396 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8397 /* Mic (rear) pin: input vref at 80% */
8398 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8399 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8400 /* Front Mic pin: input vref at 80% */
8401 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8402 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8403 /* Line In pin: input */
8404 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8405 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8406 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8407 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8408 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8409 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8410 /* CD pin widget for input */
8411 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8412
8413 /* FIXME: use matrix-type input source selection */
8414 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8415 /* Input mixer2 */
8416 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8417 /* Input mixer3 */
8418 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8419 /* ADC2: mute amp left and right */
8420 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8421 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8422 /* ADC3: mute amp left and right */
8423 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8424 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8425
8426 { }
8427};
8428
8429static const struct hda_verb alc882_adc1_init_verbs[] = {
8430 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8431 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8432 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8433 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8434 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8435 /* ADC1: mute amp left and right */
8436 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8437 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8438 { }
8439};
8440
8441static const struct hda_verb alc882_eapd_verbs[] = {
8442 /* change to EAPD mode */
8443 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8444 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8445 { }
8446};
8447
8448static const struct hda_verb alc889_eapd_verbs[] = {
8449 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8450 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8451 { }
8452};
8453
8454static const struct hda_verb alc_hp15_unsol_verbs[] = {
8455 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8456 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8457 {}
8458};
8459
8460static const struct hda_verb alc885_init_verbs[] = {
8461 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8464 /* Rear mixer */
8465 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8466 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8467 /* CLFE mixer */
8468 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8470 /* Side mixer */
8471 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8473
8474 /* Front HP Pin: output 0 (0x0c) */
8475 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8476 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8477 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8478 /* Front Pin: output 0 (0x0c) */
8479 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8480 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8481 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8482 /* Rear Pin: output 1 (0x0d) */
8483 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8484 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8485 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8486 /* CLFE Pin: output 2 (0x0e) */
8487 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8488 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8489 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8490 /* Side Pin: output 3 (0x0f) */
8491 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8492 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8493 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8494 /* Mic (rear) pin: input vref at 80% */
8495 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8496 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8497 /* Front Mic pin: input vref at 80% */
8498 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8499 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8500 /* Line In pin: input */
8501 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8502 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8503
8504 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8505 /* Input mixer1 */
8506 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8507 /* Input mixer2 */
8508 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8509 /* Input mixer3 */
8510 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8511 /* ADC2: mute amp left and right */
8512 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8513 /* ADC3: mute amp left and right */
8514 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8515
8516 { }
8517};
8518
8519static const struct hda_verb alc885_init_input_verbs[] = {
8520 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8523 { }
8524};
8525
8526
8527/* Unmute Selector 24h and set the default input to front mic */
8528static const struct hda_verb alc889_init_input_verbs[] = {
8529 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8531 { }
8532};
8533
8534
8535#define alc883_init_verbs alc882_base_init_verbs
8536
8537/* Mac Pro test */
8538static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8539 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8540 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8542 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8543 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8544 /* FIXME: this looks suspicious...
8545 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8546 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8547 */
8548 { } /* end */
8549};
8550
8551static const struct hda_verb alc882_macpro_init_verbs[] = {
8552 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8553 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8554 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8556 /* Front Pin: output 0 (0x0c) */
8557 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8559 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8560 /* Front Mic pin: input vref at 80% */
8561 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8562 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8563 /* Speaker: output */
8564 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8565 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8566 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8567 /* Headphone output (output 0 - 0x0c) */
8568 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8569 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8570 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8571
8572 /* FIXME: use matrix-type input source selection */
8573 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8574 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8575 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8576 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8578 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8579 /* Input mixer2 */
8580 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8581 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8582 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8584 /* Input mixer3 */
8585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8589 /* ADC1: mute amp left and right */
8590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8591 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8592 /* ADC2: mute amp left and right */
8593 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8594 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8595 /* ADC3: mute amp left and right */
8596 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8597 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8598
8599 { }
8600};
8601
8602/* Macbook 5,1 */
8603static const struct hda_verb alc885_mb5_init_verbs[] = {
8604 /* DACs */
8605 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8606 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8607 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8608 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8609 /* Front mixer */
8610 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8613 /* Surround mixer */
8614 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8617 /* LFE mixer */
8618 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8619 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8620 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8621 /* HP mixer */
8622 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8623 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8624 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8625 /* Front Pin (0x0c) */
8626 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8627 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8628 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8629 /* LFE Pin (0x0e) */
8630 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8631 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8632 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8633 /* HP Pin (0x0f) */
8634 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8635 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8636 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8637 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8638 /* Front Mic pin: input vref at 80% */
8639 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8640 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8641 /* Line In pin */
8642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8644
8645 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8648 { }
8649};
8650
8651/* Macmini 3,1 */
8652static const struct hda_verb alc885_macmini3_init_verbs[] = {
8653 /* DACs */
8654 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8655 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8656 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8657 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8658 /* Front mixer */
8659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8662 /* Surround mixer */
8663 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8666 /* LFE mixer */
8667 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8670 /* HP mixer */
8671 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8672 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8673 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8674 /* Front Pin (0x0c) */
8675 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8676 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8677 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8678 /* LFE Pin (0x0e) */
8679 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8680 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8681 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8682 /* HP Pin (0x0f) */
8683 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8684 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8685 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8686 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8687 /* Line In pin */
8688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8690
8691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8695 { }
8696};
8697
8698
8699static const struct hda_verb alc885_mba21_init_verbs[] = {
8700 /*Internal and HP Speaker Mixer*/
8701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8704 /*Internal Speaker Pin (0x0c)*/
8705 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8706 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8707 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8708 /* HP Pin: output 0 (0x0e) */
8709 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8710 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8711 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8712 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8713 /* Line in (is hp when jack connected)*/
8714 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8715 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8716
8717 { }
8718 };
8719
8720
8721/* Macbook Pro rev3 */
8722static const struct hda_verb alc885_mbp3_init_verbs[] = {
8723 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8727 /* Rear mixer */
8728 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8729 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8730 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8731 /* HP mixer */
8732 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8735 /* Front Pin: output 0 (0x0c) */
8736 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8737 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8738 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8739 /* HP Pin: output 0 (0x0e) */
8740 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8741 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8742 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8743 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8744 /* Mic (rear) pin: input vref at 80% */
8745 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8746 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8747 /* Front Mic pin: input vref at 80% */
8748 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8749 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8750 /* Line In pin: use output 1 when in LineOut mode */
8751 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8752 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8753 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8754
8755 /* FIXME: use matrix-type input source selection */
8756 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8757 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8758 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8762 /* Input mixer2 */
8763 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8767 /* Input mixer3 */
8768 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8772 /* ADC1: mute amp left and right */
8773 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8774 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8775 /* ADC2: mute amp left and right */
8776 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8777 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8778 /* ADC3: mute amp left and right */
8779 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8780 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8781
8782 { }
8783};
8784
8785/* iMac 9,1 */
8786static const struct hda_verb alc885_imac91_init_verbs[] = {
8787 /* Internal Speaker Pin (0x0c) */
8788 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8789 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8790 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8791 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8792 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8793 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8794 /* HP Pin: Rear */
8795 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8796 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8797 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8798 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8799 /* Line in Rear */
8800 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8801 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8802 /* Front Mic pin: input vref at 80% */
8803 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8804 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8805 /* Rear mixer */
8806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8809 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8813 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8814 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8815 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8816 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8817 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8818 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8819 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8820 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8821 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8822 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8823 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8826 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8827 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8828 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8830 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8831 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8832 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8833 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8834 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8835 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8836 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8837 { }
8838};
8839
8840/* iMac 24 mixer. */
8841static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8842 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8843 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8844 { } /* end */
8845};
8846
8847/* iMac 24 init verbs. */
8848static const struct hda_verb alc885_imac24_init_verbs[] = {
8849 /* Internal speakers: output 0 (0x0c) */
8850 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8851 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8852 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8853 /* Internal speakers: output 0 (0x0c) */
8854 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8855 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8856 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8857 /* Headphone: output 0 (0x0c) */
8858 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8859 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8860 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8861 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8862 /* Front Mic: input vref at 80% */
8863 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8864 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8865 { }
8866};
8867
8868/* Toggle speaker-output according to the hp-jack state */
8869static void alc885_imac24_setup(struct hda_codec *codec)
8870{
8871 struct alc_spec *spec = codec->spec;
8872
8873 spec->autocfg.hp_pins[0] = 0x14;
8874 spec->autocfg.speaker_pins[0] = 0x18;
8875 spec->autocfg.speaker_pins[1] = 0x1a;
8876 spec->automute = 1;
8877 spec->automute_mode = ALC_AUTOMUTE_AMP;
8878}
8879
8880#define alc885_mb5_setup alc885_imac24_setup
8881#define alc885_macmini3_setup alc885_imac24_setup
8882
8883/* Macbook Air 2,1 */
8884static void alc885_mba21_setup(struct hda_codec *codec)
8885{
8886 struct alc_spec *spec = codec->spec;
8887
8888 spec->autocfg.hp_pins[0] = 0x14;
8889 spec->autocfg.speaker_pins[0] = 0x18;
8890 spec->automute = 1;
8891 spec->automute_mode = ALC_AUTOMUTE_AMP;
8892}
8893
8894
8895
8896static void alc885_mbp3_setup(struct hda_codec *codec)
8897{
8898 struct alc_spec *spec = codec->spec;
8899
8900 spec->autocfg.hp_pins[0] = 0x15;
8901 spec->autocfg.speaker_pins[0] = 0x14;
8902 spec->automute = 1;
8903 spec->automute_mode = ALC_AUTOMUTE_AMP;
8904}
8905
8906static void alc885_imac91_setup(struct hda_codec *codec)
8907{
8908 struct alc_spec *spec = codec->spec;
8909
8910 spec->autocfg.hp_pins[0] = 0x14;
8911 spec->autocfg.speaker_pins[0] = 0x18;
8912 spec->autocfg.speaker_pins[1] = 0x1a;
8913 spec->automute = 1;
8914 spec->automute_mode = ALC_AUTOMUTE_AMP;
8915}
8916
8917static const struct hda_verb alc882_targa_verbs[] = {
8918 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8920
8921 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8922 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8923
8924 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8925 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8926 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8927
8928 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8929 { } /* end */
8930};
8931
8932/* toggle speaker-output according to the hp-jack state */
8933static void alc882_targa_automute(struct hda_codec *codec)
8934{
8935 struct alc_spec *spec = codec->spec;
8936 alc_hp_automute(codec);
8937 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8938 spec->jack_present ? 1 : 3);
8939}
8940
8941static void alc882_targa_setup(struct hda_codec *codec)
8942{
8943 struct alc_spec *spec = codec->spec;
8944
8945 spec->autocfg.hp_pins[0] = 0x14;
8946 spec->autocfg.speaker_pins[0] = 0x1b;
8947 spec->automute = 1;
8948 spec->automute_mode = ALC_AUTOMUTE_AMP;
8949}
8950
8951static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8952{
8953 if ((res >> 26) == ALC880_HP_EVENT)
8954 alc882_targa_automute(codec);
8955}
8956
8957static const struct hda_verb alc882_asus_a7j_verbs[] = {
8958 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8960
8961 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8962 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8963 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8964
8965 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8966 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8967 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8968
8969 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8970 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8971 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8972 { } /* end */
8973};
8974
8975static const struct hda_verb alc882_asus_a7m_verbs[] = {
8976 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8978
8979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8980 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8981 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8982
8983 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8984 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8985 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8986
8987 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8988 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8989 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8990 { } /* end */
8991};
8992
8993static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8994{
8995 unsigned int gpiostate, gpiomask, gpiodir;
8996
8997 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8998 AC_VERB_GET_GPIO_DATA, 0);
8999
9000 if (!muted)
9001 gpiostate |= (1 << pin);
9002 else
9003 gpiostate &= ~(1 << pin);
9004
9005 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9006 AC_VERB_GET_GPIO_MASK, 0);
9007 gpiomask |= (1 << pin);
9008
9009 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9010 AC_VERB_GET_GPIO_DIRECTION, 0);
9011 gpiodir |= (1 << pin);
9012
9013
9014 snd_hda_codec_write(codec, codec->afg, 0,
9015 AC_VERB_SET_GPIO_MASK, gpiomask);
9016 snd_hda_codec_write(codec, codec->afg, 0,
9017 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9018
9019 msleep(1);
9020
9021 snd_hda_codec_write(codec, codec->afg, 0,
9022 AC_VERB_SET_GPIO_DATA, gpiostate);
9023}
9024
9025/* set up GPIO at initialization */
9026static void alc885_macpro_init_hook(struct hda_codec *codec)
9027{
9028 alc882_gpio_mute(codec, 0, 0);
9029 alc882_gpio_mute(codec, 1, 0);
9030}
9031
9032/* set up GPIO and update auto-muting at initialization */
9033static void alc885_imac24_init_hook(struct hda_codec *codec)
9034{
9035 alc885_macpro_init_hook(codec);
9036 alc_hp_automute(codec);
9037}
9038
9039/*
9040 * generic initialization of ADC, input mixers and output mixers
9041 */
9042static const struct hda_verb alc883_auto_init_verbs[] = {
9043 /*
9044 * Unmute ADC0-2 and set the default input to mic-in
9045 */
9046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9048 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9049 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9050
9051 /*
9052 * Set up output mixers (0x0c - 0x0f)
9053 */
9054 /* set vol=0 to output mixers */
9055 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9056 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9057 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9058 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9059 /* set up input amps for analog loopback */
9060 /* Amp Indices: DAC = 0, mixer = 1 */
9061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9064 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9066 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9067 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9069 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9070 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9071
9072 /* FIXME: use matrix-type input source selection */
9073 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9074 /* Input mixer2 */
9075 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9076 /* Input mixer3 */
9077 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9078 { }
9079};
9080
9081/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
9082static const struct hda_verb alc889A_mb31_ch2_init[] = {
9083 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9084 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9086 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9087 { } /* end */
9088};
9089
9090/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
9091static const struct hda_verb alc889A_mb31_ch4_init[] = {
9092 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9093 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9094 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9095 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9096 { } /* end */
9097};
9098
9099/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
9100static const struct hda_verb alc889A_mb31_ch5_init[] = {
9101 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9102 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9103 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9104 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9105 { } /* end */
9106};
9107
9108/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
9109static const struct hda_verb alc889A_mb31_ch6_init[] = {
9110 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9111 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9112 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9113 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9114 { } /* end */
9115};
9116
9117static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
9118 { 2, alc889A_mb31_ch2_init },
9119 { 4, alc889A_mb31_ch4_init },
9120 { 5, alc889A_mb31_ch5_init },
9121 { 6, alc889A_mb31_ch6_init },
9122};
9123
9124static const struct hda_verb alc883_medion_eapd_verbs[] = {
9125 /* eanable EAPD on medion laptop */
9126 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9127 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9128 { }
9129};
9130
9131#define alc883_base_mixer alc882_base_mixer
9132
9133static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
9134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9135 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9136 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9137 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9138 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9139 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9142 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9145 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9146 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9147 { } /* end */
9148};
9149
9150static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
9151 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9152 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9153 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9154 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
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("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9159 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9160 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9161 { } /* end */
9162};
9163
9164static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_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
9178static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9179 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9180 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9181 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9182 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9183 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9184 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9185 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9186 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9187 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9188 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9189 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9190 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9191 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9192 { } /* end */
9193};
9194
9195static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9196 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9197 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9198 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9199 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9200 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9201 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9202 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9203 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9204 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9205 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9206 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9207 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9208 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9209 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9210 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9212 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9213 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9214 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9215 { } /* end */
9216};
9217
9218static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
9219 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9220 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9221 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9222 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9223 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9224 HDA_OUTPUT),
9225 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9226 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9227 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9228 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9229 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9230 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9236 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9237 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9238 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9239 { } /* end */
9240};
9241
9242static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9243 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9245 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9246 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9247 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9248 HDA_OUTPUT),
9249 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9250 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9251 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9252 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9253 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9254 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9255 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9256 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9257 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9258 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9259 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9260 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9261 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9262 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9263 { } /* end */
9264};
9265
9266static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9270 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9271 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9272 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9273 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9274 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9276 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9277 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9278 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9279 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9280 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9281 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9282 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9283 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9284 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9285 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9286 { } /* end */
9287};
9288
9289static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9290 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9291 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9292 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9293 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9294 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9295 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9296 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9297 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9298 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9299 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9300 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9301 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9305 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9307 { } /* end */
9308};
9309
9310static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9311 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9312 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9313 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9314 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9315 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9316 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9317 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9318 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9319 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9320 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9321 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9322 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9323 { } /* end */
9324};
9325
9326static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9327 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9328 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9329 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9330 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9331 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9332 { } /* end */
9333};
9334
9335static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9336 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9337 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9338 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9339 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9340 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9342 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9343 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9344 { } /* end */
9345};
9346
9347static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9348 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9349 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9351 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9352 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9354 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9355 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9356 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9357 { } /* end */
9358};
9359
9360static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9361 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9362 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9363 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9364 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9365 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9366 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9367 { } /* end */
9368};
9369
9370static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9371 /* Unmute front mixer */
9372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9374
9375 /* Set speaker pin to front mixer */
9376 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9377
9378 /* Init headphone pin */
9379 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9380 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9381 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9382 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9383
9384 { } /* end */
9385};
9386
9387/* toggle speaker-output according to the hp-jack state */
9388static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9389{
9390 struct alc_spec *spec = codec->spec;
9391
9392 spec->autocfg.hp_pins[0] = 0x1a;
9393 spec->autocfg.speaker_pins[0] = 0x15;
9394 spec->automute = 1;
9395 spec->automute_mode = ALC_AUTOMUTE_AMP;
9396}
9397
9398static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9399 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9400 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9402 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9403 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9405 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9406 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9407 { } /* end */
9408};
9409
9410static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9411 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9412 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9414 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9415 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9416 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9417 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9418 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9419 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9420 { } /* end */
9421};
9422
9423static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9424 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9425 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9426 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9427 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9428 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9429 0x0d, 1, 0x0, HDA_OUTPUT),
9430 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9431 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9432 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9433 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9434 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9437 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9438 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9440 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9441 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9442 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9443 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9444 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9445 { } /* end */
9446};
9447
9448static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9449 /* Output mixers */
9450 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9451 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9452 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9453 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9454 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9455 HDA_OUTPUT),
9456 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9457 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9458 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9459 /* Output switches */
9460 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9461 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9462 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9463 /* Boost mixers */
9464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9465 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9466 /* Input mixers */
9467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9469 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9470 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9471 { } /* end */
9472};
9473
9474static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9475 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9476 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9477 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9478 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9479 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9480 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9481 { } /* end */
9482};
9483
9484static const struct hda_bind_ctls alc883_bind_cap_vol = {
9485 .ops = &snd_hda_bind_vol,
9486 .values = {
9487 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9488 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9489 0
9490 },
9491};
9492
9493static const struct hda_bind_ctls alc883_bind_cap_switch = {
9494 .ops = &snd_hda_bind_sw,
9495 .values = {
9496 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9497 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9498 0
9499 },
9500};
9501
9502static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9503 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9504 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9509 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9511 { } /* end */
9512};
9513
9514static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9515 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9516 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9517 {
9518 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9519 /* .name = "Capture Source", */
9520 .name = "Input Source",
9521 .count = 1,
9522 .info = alc_mux_enum_info,
9523 .get = alc_mux_enum_get,
9524 .put = alc_mux_enum_put,
9525 },
9526 { } /* end */
9527};
9528
9529static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9530 {
9531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9532 .name = "Channel Mode",
9533 .info = alc_ch_mode_info,
9534 .get = alc_ch_mode_get,
9535 .put = alc_ch_mode_put,
9536 },
9537 { } /* end */
9538};
9539
9540/* toggle speaker-output according to the hp-jack state */
9541static void alc883_mitac_setup(struct hda_codec *codec)
9542{
9543 struct alc_spec *spec = codec->spec;
9544
9545 spec->autocfg.hp_pins[0] = 0x15;
9546 spec->autocfg.speaker_pins[0] = 0x14;
9547 spec->autocfg.speaker_pins[1] = 0x17;
9548 spec->automute = 1;
9549 spec->automute_mode = ALC_AUTOMUTE_AMP;
9550}
9551
9552static const struct hda_verb alc883_mitac_verbs[] = {
9553 /* HP */
9554 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9556 /* Subwoofer */
9557 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9558 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9559
9560 /* enable unsolicited event */
9561 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9562 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9563
9564 { } /* end */
9565};
9566
9567static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9568 /* HP */
9569 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9571 /* Int speaker */
9572 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9573
9574 /* enable unsolicited event */
9575 /*
9576 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9577 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9578 */
9579
9580 { } /* end */
9581};
9582
9583static const struct hda_verb alc883_clevo_m720_verbs[] = {
9584 /* HP */
9585 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9586 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9587 /* Int speaker */
9588 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9590
9591 /* enable unsolicited event */
9592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9593 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9594
9595 { } /* end */
9596};
9597
9598static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9599 /* HP */
9600 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9602 /* Subwoofer */
9603 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9604 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9605
9606 /* enable unsolicited event */
9607 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9608
9609 { } /* end */
9610};
9611
9612static const struct hda_verb alc883_targa_verbs[] = {
9613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9615
9616 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9618
9619/* Connect Line-Out side jack (SPDIF) to Side */
9620 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9621 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9622 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9623/* Connect Mic jack to CLFE */
9624 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9626 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9627/* Connect Line-in jack to Surround */
9628 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9629 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9630 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9631/* Connect HP out jack to Front */
9632 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9633 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9634 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9635
9636 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9637
9638 { } /* end */
9639};
9640
9641static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9642 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9643 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9644 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9645 { } /* end */
9646};
9647
9648static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9649 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9650 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9651 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9653 { } /* end */
9654};
9655
9656static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9657 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9658 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9659 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9660 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9661 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9662 { } /* end */
9663};
9664
9665static const struct hda_verb alc883_haier_w66_verbs[] = {
9666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9668
9669 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9670
9671 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9672 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9673 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9674 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9675 { } /* end */
9676};
9677
9678static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9679 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9681 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9683 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9684 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9685 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9686 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9687 { } /* end */
9688};
9689
9690static const struct hda_verb alc888_6st_dell_verbs[] = {
9691 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9692 { }
9693};
9694
9695static const struct hda_verb alc883_vaiott_verbs[] = {
9696 /* HP */
9697 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9698 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9699
9700 /* enable unsolicited event */
9701 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9702
9703 { } /* end */
9704};
9705
9706static void alc888_3st_hp_setup(struct hda_codec *codec)
9707{
9708 struct alc_spec *spec = codec->spec;
9709
9710 spec->autocfg.hp_pins[0] = 0x1b;
9711 spec->autocfg.speaker_pins[0] = 0x14;
9712 spec->autocfg.speaker_pins[1] = 0x16;
9713 spec->autocfg.speaker_pins[2] = 0x18;
9714 spec->automute = 1;
9715 spec->automute_mode = ALC_AUTOMUTE_AMP;
9716}
9717
9718static const struct hda_verb alc888_3st_hp_verbs[] = {
9719 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9720 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9721 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9722 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9723 { } /* end */
9724};
9725
9726/*
9727 * 2ch mode
9728 */
9729static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9730 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9731 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9732 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9733 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9734 { } /* end */
9735};
9736
9737/*
9738 * 4ch mode
9739 */
9740static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9741 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9742 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9743 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9744 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9745 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9746 { } /* end */
9747};
9748
9749/*
9750 * 6ch mode
9751 */
9752static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9753 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9754 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9755 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9756 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9757 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9758 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9759 { } /* end */
9760};
9761
9762static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9763 { 2, alc888_3st_hp_2ch_init },
9764 { 4, alc888_3st_hp_4ch_init },
9765 { 6, alc888_3st_hp_6ch_init },
9766};
9767
9768static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9769{
9770 struct alc_spec *spec = codec->spec;
9771
9772 spec->autocfg.hp_pins[0] = 0x1b;
9773 spec->autocfg.line_out_pins[0] = 0x14;
9774 spec->autocfg.speaker_pins[0] = 0x15;
9775 spec->automute = 1;
9776 spec->automute_mode = ALC_AUTOMUTE_AMP;
9777}
9778
9779/* toggle speaker-output according to the hp-jack state */
9780static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9781{
9782 struct alc_spec *spec = codec->spec;
9783
9784 spec->autocfg.hp_pins[0] = 0x14;
9785 spec->autocfg.speaker_pins[0] = 0x15;
9786 spec->automute = 1;
9787 spec->automute_mode = ALC_AUTOMUTE_AMP;
9788}
9789
9790/* toggle speaker-output according to the hp-jack state */
9791#define alc883_targa_init_hook alc882_targa_init_hook
9792#define alc883_targa_unsol_event alc882_targa_unsol_event
9793
9794static void alc883_clevo_m720_setup(struct hda_codec *codec)
9795{
9796 struct alc_spec *spec = codec->spec;
9797
9798 spec->autocfg.hp_pins[0] = 0x15;
9799 spec->autocfg.speaker_pins[0] = 0x14;
9800 spec->automute = 1;
9801 spec->automute_mode = ALC_AUTOMUTE_AMP;
9802}
9803
9804static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9805{
9806 alc_hp_automute(codec);
9807 alc88x_simple_mic_automute(codec);
9808}
9809
9810static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9811 unsigned int res)
9812{
9813 switch (res >> 26) {
9814 case ALC880_MIC_EVENT:
9815 alc88x_simple_mic_automute(codec);
9816 break;
9817 default:
9818 alc_sku_unsol_event(codec, res);
9819 break;
9820 }
9821}
9822
9823/* toggle speaker-output according to the hp-jack state */
9824static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9825{
9826 struct alc_spec *spec = codec->spec;
9827
9828 spec->autocfg.hp_pins[0] = 0x14;
9829 spec->autocfg.speaker_pins[0] = 0x15;
9830 spec->automute = 1;
9831 spec->automute_mode = ALC_AUTOMUTE_AMP;
9832}
9833
9834static void alc883_haier_w66_setup(struct hda_codec *codec)
9835{
9836 struct alc_spec *spec = codec->spec;
9837
9838 spec->autocfg.hp_pins[0] = 0x1b;
9839 spec->autocfg.speaker_pins[0] = 0x14;
9840 spec->automute = 1;
9841 spec->automute_mode = ALC_AUTOMUTE_AMP;
9842}
9843
9844static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9845{
9846 struct alc_spec *spec = codec->spec;
9847
9848 spec->autocfg.hp_pins[0] = 0x1b;
9849 spec->autocfg.line_out_pins[0] = 0x14;
9850 spec->autocfg.speaker_pins[0] = 0x15;
9851 spec->automute = 1;
9852 spec->detect_line = 1;
9853 spec->automute_lines = 1;
9854 spec->automute_mode = ALC_AUTOMUTE_AMP;
9855}
9856
9857/* toggle speaker-output according to the hp-jack state */
9858static void alc883_acer_aspire_setup(struct hda_codec *codec)
9859{
9860 struct alc_spec *spec = codec->spec;
9861
9862 spec->autocfg.hp_pins[0] = 0x14;
9863 spec->autocfg.speaker_pins[0] = 0x15;
9864 spec->autocfg.speaker_pins[1] = 0x16;
9865 spec->automute = 1;
9866 spec->automute_mode = ALC_AUTOMUTE_AMP;
9867}
9868
9869static const struct hda_verb alc883_acer_eapd_verbs[] = {
9870 /* HP Pin: output 0 (0x0c) */
9871 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9872 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9873 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9874 /* Front Pin: output 0 (0x0c) */
9875 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9876 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9877 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9878 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9879 /* eanable EAPD on medion laptop */
9880 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9881 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9882 /* enable unsolicited event */
9883 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9884 { }
9885};
9886
9887static void alc888_6st_dell_setup(struct hda_codec *codec)
9888{
9889 struct alc_spec *spec = codec->spec;
9890
9891 spec->autocfg.hp_pins[0] = 0x1b;
9892 spec->autocfg.speaker_pins[0] = 0x14;
9893 spec->autocfg.speaker_pins[1] = 0x15;
9894 spec->autocfg.speaker_pins[2] = 0x16;
9895 spec->autocfg.speaker_pins[3] = 0x17;
9896 spec->automute = 1;
9897 spec->automute_mode = ALC_AUTOMUTE_AMP;
9898}
9899
9900static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9901{
9902 struct alc_spec *spec = codec->spec;
9903
9904 spec->autocfg.hp_pins[0] = 0x1b;
9905 spec->autocfg.speaker_pins[0] = 0x14;
9906 spec->autocfg.speaker_pins[1] = 0x15;
9907 spec->autocfg.speaker_pins[2] = 0x16;
9908 spec->autocfg.speaker_pins[3] = 0x17;
9909 spec->autocfg.speaker_pins[4] = 0x1a;
9910 spec->automute = 1;
9911 spec->automute_mode = ALC_AUTOMUTE_AMP;
9912}
9913
9914static void alc883_vaiott_setup(struct hda_codec *codec)
9915{
9916 struct alc_spec *spec = codec->spec;
9917
9918 spec->autocfg.hp_pins[0] = 0x15;
9919 spec->autocfg.speaker_pins[0] = 0x14;
9920 spec->autocfg.speaker_pins[1] = 0x17;
9921 spec->automute = 1;
9922 spec->automute_mode = ALC_AUTOMUTE_AMP;
9923}
9924
9925static const struct hda_verb alc888_asus_m90v_verbs[] = {
9926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9927 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9928 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9929 /* enable unsolicited event */
9930 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9931 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9932 { } /* end */
9933};
9934
9935static void alc883_mode2_setup(struct hda_codec *codec)
9936{
9937 struct alc_spec *spec = codec->spec;
9938
9939 spec->autocfg.hp_pins[0] = 0x1b;
9940 spec->autocfg.speaker_pins[0] = 0x14;
9941 spec->autocfg.speaker_pins[1] = 0x15;
9942 spec->autocfg.speaker_pins[2] = 0x16;
9943 spec->ext_mic.pin = 0x18;
9944 spec->int_mic.pin = 0x19;
9945 spec->ext_mic.mux_idx = 0;
9946 spec->int_mic.mux_idx = 1;
9947 spec->auto_mic = 1;
9948 spec->automute = 1;
9949 spec->automute_mode = ALC_AUTOMUTE_AMP;
9950}
9951
9952static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9956 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9958 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9959 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9960 /* enable unsolicited event */
9961 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9962 { } /* end */
9963};
9964
9965static void alc883_eee1601_inithook(struct hda_codec *codec)
9966{
9967 struct alc_spec *spec = codec->spec;
9968
9969 spec->autocfg.hp_pins[0] = 0x14;
9970 spec->autocfg.speaker_pins[0] = 0x1b;
9971 alc_hp_automute(codec);
9972}
9973
9974static const struct hda_verb alc889A_mb31_verbs[] = {
9975 /* Init rear pin (used as headphone output) */
9976 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9977 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9978 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9979 /* Init line pin (used as output in 4ch and 6ch mode) */
9980 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9981 /* Init line 2 pin (used as headphone out by default) */
9982 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9983 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9984 { } /* end */
9985};
9986
9987/* Mute speakers according to the headphone jack state */
9988static void alc889A_mb31_automute(struct hda_codec *codec)
9989{
9990 unsigned int present;
9991
9992 /* Mute only in 2ch or 4ch mode */
9993 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9994 == 0x00) {
9995 present = snd_hda_jack_detect(codec, 0x15);
9996 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9997 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9998 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9999 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10000 }
10001}
10002
10003static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
10004{
10005 if ((res >> 26) == ALC880_HP_EVENT)
10006 alc889A_mb31_automute(codec);
10007}
10008
10009
10010#ifdef CONFIG_SND_HDA_POWER_SAVE 3856#ifdef CONFIG_SND_HDA_POWER_SAVE
10011#define alc882_loopbacks alc880_loopbacks 3857#define alc882_loopbacks alc880_loopbacks
10012#endif 3858#endif
10013 3859
10014/* pcm configuration: identical with ALC880 */
10015#define alc882_pcm_analog_playback alc880_pcm_analog_playback
10016#define alc882_pcm_analog_capture alc880_pcm_analog_capture
10017#define alc882_pcm_digital_playback alc880_pcm_digital_playback
10018#define alc882_pcm_digital_capture alc880_pcm_digital_capture
10019
10020static const hda_nid_t alc883_slave_dig_outs[] = {
10021 ALC1200_DIGOUT_NID, 0,
10022};
10023
10024static const hda_nid_t alc1200_slave_dig_outs[] = {
10025 ALC883_DIGOUT_NID, 0,
10026};
10027
10028/*
10029 * configuration and preset
10030 */
10031static const char * const alc882_models[ALC882_MODEL_LAST] = {
10032 [ALC882_3ST_DIG] = "3stack-dig",
10033 [ALC882_6ST_DIG] = "6stack-dig",
10034 [ALC882_ARIMA] = "arima",
10035 [ALC882_W2JC] = "w2jc",
10036 [ALC882_TARGA] = "targa",
10037 [ALC882_ASUS_A7J] = "asus-a7j",
10038 [ALC882_ASUS_A7M] = "asus-a7m",
10039 [ALC885_MACPRO] = "macpro",
10040 [ALC885_MB5] = "mb5",
10041 [ALC885_MACMINI3] = "macmini3",
10042 [ALC885_MBA21] = "mba21",
10043 [ALC885_MBP3] = "mbp3",
10044 [ALC885_IMAC24] = "imac24",
10045 [ALC885_IMAC91] = "imac91",
10046 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
10047 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10048 [ALC883_3ST_6ch] = "3stack-6ch",
10049 [ALC883_6ST_DIG] = "alc883-6stack-dig",
10050 [ALC883_TARGA_DIG] = "targa-dig",
10051 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
10052 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
10053 [ALC883_ACER] = "acer",
10054 [ALC883_ACER_ASPIRE] = "acer-aspire",
10055 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
10056 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
10057 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
10058 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
10059 [ALC883_MEDION] = "medion",
10060 [ALC883_MEDION_WIM2160] = "medion-wim2160",
10061 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
10062 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
10063 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10064 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
10065 [ALC888_LENOVO_SKY] = "lenovo-sky",
10066 [ALC883_HAIER_W66] = "haier-w66",
10067 [ALC888_3ST_HP] = "3stack-hp",
10068 [ALC888_6ST_DELL] = "6stack-dell",
10069 [ALC883_MITAC] = "mitac",
10070 [ALC883_CLEVO_M540R] = "clevo-m540r",
10071 [ALC883_CLEVO_M720] = "clevo-m720",
10072 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
10073 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
10074 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
10075 [ALC889A_INTEL] = "intel-alc889a",
10076 [ALC889_INTEL] = "intel-x58",
10077 [ALC1200_ASUS_P5Q] = "asus-p5q",
10078 [ALC889A_MB31] = "mb31",
10079 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
10080 [ALC882_AUTO] = "auto",
10081};
10082
10083static const struct snd_pci_quirk alc882_cfg_tbl[] = {
10084 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10085
10086 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
10087 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
10088 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
10089 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10090 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
10091 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
10092 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10093 ALC888_ACER_ASPIRE_4930G),
10094 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
10095 ALC888_ACER_ASPIRE_4930G),
10096 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10097 ALC888_ACER_ASPIRE_8930G),
10098 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10099 ALC888_ACER_ASPIRE_8930G),
10100 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10101 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
10102 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
10103 ALC888_ACER_ASPIRE_6530G),
10104 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
10105 ALC888_ACER_ASPIRE_6530G),
10106 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10107 ALC888_ACER_ASPIRE_7730G),
10108 /* default Acer -- disabled as it causes more problems.
10109 * model=auto should work fine now
10110 */
10111 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
10112
10113 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
10114
10115 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
10116 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10117 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
10118 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
10119 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
10120 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
10121
10122 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10123 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10124 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
10125 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
10126 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10127 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10128 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
10129 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
10130 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
10131 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
10132 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
10133
10134 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
10135 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
10136 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
10137 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
10138 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10139 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
10140 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
10141 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
10142 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
10143
10144 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
10145 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
10146 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
10147 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
10148 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
10149 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
10150 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
10151 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
10152 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
10153 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
10154 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10155 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
10156 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
10157 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
10158 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
10159 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10160 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10161 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
10162 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
10163 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
10164 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10165 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10166 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
10167 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
10168 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
10169 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10170 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
10171 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
10172 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
10173 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
10174 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
10175
10176 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
10177 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
10178 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10179 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
10180 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
10181 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
10182 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
10183 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
10184 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
10185 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
10186 ALC883_FUJITSU_PI2515),
10187 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
10188 ALC888_FUJITSU_XA3530),
10189 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
10190 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10191 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10192 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10193 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
10194 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
10195 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
10196 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
10197
10198 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10199 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
10200 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
10201 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10202 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10203 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
10204 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
10205
10206 {}
10207};
10208
10209/* codec SSID table for Intel Mac */
10210static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
10211 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10212 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10213 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10214 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10215 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10216 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10217 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
10218 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
10219 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
10220 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
10221 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
10222 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10223 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10224 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
10225 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
10226 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
10227 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
10228 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10229 * so apparently no perfect solution yet
10230 */
10231 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
10232 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
10233 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
10234 {} /* terminator */
10235};
10236
10237static const struct alc_config_preset alc882_presets[] = {
10238 [ALC882_3ST_DIG] = {
10239 .mixers = { alc882_base_mixer },
10240 .init_verbs = { alc882_base_init_verbs,
10241 alc882_adc1_init_verbs },
10242 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10243 .dac_nids = alc882_dac_nids,
10244 .dig_out_nid = ALC882_DIGOUT_NID,
10245 .dig_in_nid = ALC882_DIGIN_NID,
10246 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10247 .channel_mode = alc882_ch_modes,
10248 .need_dac_fix = 1,
10249 .input_mux = &alc882_capture_source,
10250 },
10251 [ALC882_6ST_DIG] = {
10252 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10253 .init_verbs = { alc882_base_init_verbs,
10254 alc882_adc1_init_verbs },
10255 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10256 .dac_nids = alc882_dac_nids,
10257 .dig_out_nid = ALC882_DIGOUT_NID,
10258 .dig_in_nid = ALC882_DIGIN_NID,
10259 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10260 .channel_mode = alc882_sixstack_modes,
10261 .input_mux = &alc882_capture_source,
10262 },
10263 [ALC882_ARIMA] = {
10264 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10265 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10266 alc882_eapd_verbs },
10267 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10268 .dac_nids = alc882_dac_nids,
10269 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10270 .channel_mode = alc882_sixstack_modes,
10271 .input_mux = &alc882_capture_source,
10272 },
10273 [ALC882_W2JC] = {
10274 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10275 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10276 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10277 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10278 .dac_nids = alc882_dac_nids,
10279 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10280 .channel_mode = alc880_threestack_modes,
10281 .need_dac_fix = 1,
10282 .input_mux = &alc882_capture_source,
10283 .dig_out_nid = ALC882_DIGOUT_NID,
10284 },
10285 [ALC885_MBA21] = {
10286 .mixers = { alc885_mba21_mixer },
10287 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10288 .num_dacs = 2,
10289 .dac_nids = alc882_dac_nids,
10290 .channel_mode = alc885_mba21_ch_modes,
10291 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10292 .input_mux = &alc882_capture_source,
10293 .unsol_event = alc_sku_unsol_event,
10294 .setup = alc885_mba21_setup,
10295 .init_hook = alc_hp_automute,
10296 },
10297 [ALC885_MBP3] = {
10298 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10299 .init_verbs = { alc885_mbp3_init_verbs,
10300 alc880_gpio1_init_verbs },
10301 .num_dacs = 2,
10302 .dac_nids = alc882_dac_nids,
10303 .hp_nid = 0x04,
10304 .channel_mode = alc885_mbp_4ch_modes,
10305 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10306 .input_mux = &alc882_capture_source,
10307 .dig_out_nid = ALC882_DIGOUT_NID,
10308 .dig_in_nid = ALC882_DIGIN_NID,
10309 .unsol_event = alc_sku_unsol_event,
10310 .setup = alc885_mbp3_setup,
10311 .init_hook = alc_hp_automute,
10312 },
10313 [ALC885_MB5] = {
10314 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10315 .init_verbs = { alc885_mb5_init_verbs,
10316 alc880_gpio1_init_verbs },
10317 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10318 .dac_nids = alc882_dac_nids,
10319 .channel_mode = alc885_mb5_6ch_modes,
10320 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10321 .input_mux = &mb5_capture_source,
10322 .dig_out_nid = ALC882_DIGOUT_NID,
10323 .dig_in_nid = ALC882_DIGIN_NID,
10324 .unsol_event = alc_sku_unsol_event,
10325 .setup = alc885_mb5_setup,
10326 .init_hook = alc_hp_automute,
10327 },
10328 [ALC885_MACMINI3] = {
10329 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10330 .init_verbs = { alc885_macmini3_init_verbs,
10331 alc880_gpio1_init_verbs },
10332 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10333 .dac_nids = alc882_dac_nids,
10334 .channel_mode = alc885_macmini3_6ch_modes,
10335 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10336 .input_mux = &macmini3_capture_source,
10337 .dig_out_nid = ALC882_DIGOUT_NID,
10338 .dig_in_nid = ALC882_DIGIN_NID,
10339 .unsol_event = alc_sku_unsol_event,
10340 .setup = alc885_macmini3_setup,
10341 .init_hook = alc_hp_automute,
10342 },
10343 [ALC885_MACPRO] = {
10344 .mixers = { alc882_macpro_mixer },
10345 .init_verbs = { alc882_macpro_init_verbs },
10346 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10347 .dac_nids = alc882_dac_nids,
10348 .dig_out_nid = ALC882_DIGOUT_NID,
10349 .dig_in_nid = ALC882_DIGIN_NID,
10350 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10351 .channel_mode = alc882_ch_modes,
10352 .input_mux = &alc882_capture_source,
10353 .init_hook = alc885_macpro_init_hook,
10354 },
10355 [ALC885_IMAC24] = {
10356 .mixers = { alc885_imac24_mixer },
10357 .init_verbs = { alc885_imac24_init_verbs },
10358 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10359 .dac_nids = alc882_dac_nids,
10360 .dig_out_nid = ALC882_DIGOUT_NID,
10361 .dig_in_nid = ALC882_DIGIN_NID,
10362 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10363 .channel_mode = alc882_ch_modes,
10364 .input_mux = &alc882_capture_source,
10365 .unsol_event = alc_sku_unsol_event,
10366 .setup = alc885_imac24_setup,
10367 .init_hook = alc885_imac24_init_hook,
10368 },
10369 [ALC885_IMAC91] = {
10370 .mixers = {alc885_imac91_mixer},
10371 .init_verbs = { alc885_imac91_init_verbs,
10372 alc880_gpio1_init_verbs },
10373 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10374 .dac_nids = alc882_dac_nids,
10375 .channel_mode = alc885_mba21_ch_modes,
10376 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10377 .input_mux = &alc889A_imac91_capture_source,
10378 .dig_out_nid = ALC882_DIGOUT_NID,
10379 .dig_in_nid = ALC882_DIGIN_NID,
10380 .unsol_event = alc_sku_unsol_event,
10381 .setup = alc885_imac91_setup,
10382 .init_hook = alc_hp_automute,
10383 },
10384 [ALC882_TARGA] = {
10385 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10386 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10387 alc880_gpio3_init_verbs, alc882_targa_verbs},
10388 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10389 .dac_nids = alc882_dac_nids,
10390 .dig_out_nid = ALC882_DIGOUT_NID,
10391 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10392 .adc_nids = alc882_adc_nids,
10393 .capsrc_nids = alc882_capsrc_nids,
10394 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10395 .channel_mode = alc882_3ST_6ch_modes,
10396 .need_dac_fix = 1,
10397 .input_mux = &alc882_capture_source,
10398 .unsol_event = alc_sku_unsol_event,
10399 .setup = alc882_targa_setup,
10400 .init_hook = alc882_targa_automute,
10401 },
10402 [ALC882_ASUS_A7J] = {
10403 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10404 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10405 alc882_asus_a7j_verbs},
10406 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10407 .dac_nids = alc882_dac_nids,
10408 .dig_out_nid = ALC882_DIGOUT_NID,
10409 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10410 .adc_nids = alc882_adc_nids,
10411 .capsrc_nids = alc882_capsrc_nids,
10412 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10413 .channel_mode = alc882_3ST_6ch_modes,
10414 .need_dac_fix = 1,
10415 .input_mux = &alc882_capture_source,
10416 },
10417 [ALC882_ASUS_A7M] = {
10418 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10419 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10420 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10421 alc882_asus_a7m_verbs },
10422 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10423 .dac_nids = alc882_dac_nids,
10424 .dig_out_nid = ALC882_DIGOUT_NID,
10425 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10426 .channel_mode = alc880_threestack_modes,
10427 .need_dac_fix = 1,
10428 .input_mux = &alc882_capture_source,
10429 },
10430 [ALC883_3ST_2ch_DIG] = {
10431 .mixers = { alc883_3ST_2ch_mixer },
10432 .init_verbs = { alc883_init_verbs },
10433 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10434 .dac_nids = alc883_dac_nids,
10435 .dig_out_nid = ALC883_DIGOUT_NID,
10436 .dig_in_nid = ALC883_DIGIN_NID,
10437 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10438 .channel_mode = alc883_3ST_2ch_modes,
10439 .input_mux = &alc883_capture_source,
10440 },
10441 [ALC883_3ST_6ch_DIG] = {
10442 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10443 .init_verbs = { alc883_init_verbs },
10444 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10445 .dac_nids = alc883_dac_nids,
10446 .dig_out_nid = ALC883_DIGOUT_NID,
10447 .dig_in_nid = ALC883_DIGIN_NID,
10448 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10449 .channel_mode = alc883_3ST_6ch_modes,
10450 .need_dac_fix = 1,
10451 .input_mux = &alc883_capture_source,
10452 },
10453 [ALC883_3ST_6ch] = {
10454 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10455 .init_verbs = { alc883_init_verbs },
10456 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10457 .dac_nids = alc883_dac_nids,
10458 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10459 .channel_mode = alc883_3ST_6ch_modes,
10460 .need_dac_fix = 1,
10461 .input_mux = &alc883_capture_source,
10462 },
10463 [ALC883_3ST_6ch_INTEL] = {
10464 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10465 .init_verbs = { alc883_init_verbs },
10466 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10467 .dac_nids = alc883_dac_nids,
10468 .dig_out_nid = ALC883_DIGOUT_NID,
10469 .dig_in_nid = ALC883_DIGIN_NID,
10470 .slave_dig_outs = alc883_slave_dig_outs,
10471 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10472 .channel_mode = alc883_3ST_6ch_intel_modes,
10473 .need_dac_fix = 1,
10474 .input_mux = &alc883_3stack_6ch_intel,
10475 },
10476 [ALC889A_INTEL] = {
10477 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10478 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10479 alc_hp15_unsol_verbs },
10480 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10481 .dac_nids = alc883_dac_nids,
10482 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10483 .adc_nids = alc889_adc_nids,
10484 .dig_out_nid = ALC883_DIGOUT_NID,
10485 .dig_in_nid = ALC883_DIGIN_NID,
10486 .slave_dig_outs = alc883_slave_dig_outs,
10487 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10488 .channel_mode = alc889_8ch_intel_modes,
10489 .capsrc_nids = alc889_capsrc_nids,
10490 .input_mux = &alc889_capture_source,
10491 .setup = alc889_automute_setup,
10492 .init_hook = alc_hp_automute,
10493 .unsol_event = alc_sku_unsol_event,
10494 .need_dac_fix = 1,
10495 },
10496 [ALC889_INTEL] = {
10497 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10498 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10499 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10500 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10501 .dac_nids = alc883_dac_nids,
10502 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10503 .adc_nids = alc889_adc_nids,
10504 .dig_out_nid = ALC883_DIGOUT_NID,
10505 .dig_in_nid = ALC883_DIGIN_NID,
10506 .slave_dig_outs = alc883_slave_dig_outs,
10507 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10508 .channel_mode = alc889_8ch_intel_modes,
10509 .capsrc_nids = alc889_capsrc_nids,
10510 .input_mux = &alc889_capture_source,
10511 .setup = alc889_automute_setup,
10512 .init_hook = alc889_intel_init_hook,
10513 .unsol_event = alc_sku_unsol_event,
10514 .need_dac_fix = 1,
10515 },
10516 [ALC883_6ST_DIG] = {
10517 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10518 .init_verbs = { alc883_init_verbs },
10519 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10520 .dac_nids = alc883_dac_nids,
10521 .dig_out_nid = ALC883_DIGOUT_NID,
10522 .dig_in_nid = ALC883_DIGIN_NID,
10523 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10524 .channel_mode = alc883_sixstack_modes,
10525 .input_mux = &alc883_capture_source,
10526 },
10527 [ALC883_TARGA_DIG] = {
10528 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10529 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10530 alc883_targa_verbs},
10531 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10532 .dac_nids = alc883_dac_nids,
10533 .dig_out_nid = ALC883_DIGOUT_NID,
10534 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10535 .channel_mode = alc883_3ST_6ch_modes,
10536 .need_dac_fix = 1,
10537 .input_mux = &alc883_capture_source,
10538 .unsol_event = alc883_targa_unsol_event,
10539 .setup = alc882_targa_setup,
10540 .init_hook = alc882_targa_automute,
10541 },
10542 [ALC883_TARGA_2ch_DIG] = {
10543 .mixers = { alc883_targa_2ch_mixer},
10544 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10545 alc883_targa_verbs},
10546 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10547 .dac_nids = alc883_dac_nids,
10548 .adc_nids = alc883_adc_nids_alt,
10549 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10550 .capsrc_nids = alc883_capsrc_nids,
10551 .dig_out_nid = ALC883_DIGOUT_NID,
10552 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10553 .channel_mode = alc883_3ST_2ch_modes,
10554 .input_mux = &alc883_capture_source,
10555 .unsol_event = alc883_targa_unsol_event,
10556 .setup = alc882_targa_setup,
10557 .init_hook = alc882_targa_automute,
10558 },
10559 [ALC883_TARGA_8ch_DIG] = {
10560 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10561 alc883_chmode_mixer },
10562 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10563 alc883_targa_verbs },
10564 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10565 .dac_nids = alc883_dac_nids,
10566 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10567 .adc_nids = alc883_adc_nids_rev,
10568 .capsrc_nids = alc883_capsrc_nids_rev,
10569 .dig_out_nid = ALC883_DIGOUT_NID,
10570 .dig_in_nid = ALC883_DIGIN_NID,
10571 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10572 .channel_mode = alc883_4ST_8ch_modes,
10573 .need_dac_fix = 1,
10574 .input_mux = &alc883_capture_source,
10575 .unsol_event = alc883_targa_unsol_event,
10576 .setup = alc882_targa_setup,
10577 .init_hook = alc882_targa_automute,
10578 },
10579 [ALC883_ACER] = {
10580 .mixers = { alc883_base_mixer },
10581 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10582 * and the headphone jack. Turn this on and rely on the
10583 * standard mute methods whenever the user wants to turn
10584 * these outputs off.
10585 */
10586 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10587 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10588 .dac_nids = alc883_dac_nids,
10589 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10590 .channel_mode = alc883_3ST_2ch_modes,
10591 .input_mux = &alc883_capture_source,
10592 },
10593 [ALC883_ACER_ASPIRE] = {
10594 .mixers = { alc883_acer_aspire_mixer },
10595 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10596 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10597 .dac_nids = alc883_dac_nids,
10598 .dig_out_nid = ALC883_DIGOUT_NID,
10599 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10600 .channel_mode = alc883_3ST_2ch_modes,
10601 .input_mux = &alc883_capture_source,
10602 .unsol_event = alc_sku_unsol_event,
10603 .setup = alc883_acer_aspire_setup,
10604 .init_hook = alc_hp_automute,
10605 },
10606 [ALC888_ACER_ASPIRE_4930G] = {
10607 .mixers = { alc888_acer_aspire_4930g_mixer,
10608 alc883_chmode_mixer },
10609 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10610 alc888_acer_aspire_4930g_verbs },
10611 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10612 .dac_nids = alc883_dac_nids,
10613 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10614 .adc_nids = alc883_adc_nids_rev,
10615 .capsrc_nids = alc883_capsrc_nids_rev,
10616 .dig_out_nid = ALC883_DIGOUT_NID,
10617 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10618 .channel_mode = alc883_3ST_6ch_modes,
10619 .need_dac_fix = 1,
10620 .const_channel_count = 6,
10621 .num_mux_defs =
10622 ARRAY_SIZE(alc888_2_capture_sources),
10623 .input_mux = alc888_2_capture_sources,
10624 .unsol_event = alc_sku_unsol_event,
10625 .setup = alc888_acer_aspire_4930g_setup,
10626 .init_hook = alc_hp_automute,
10627 },
10628 [ALC888_ACER_ASPIRE_6530G] = {
10629 .mixers = { alc888_acer_aspire_6530_mixer },
10630 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10631 alc888_acer_aspire_6530g_verbs },
10632 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10633 .dac_nids = alc883_dac_nids,
10634 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10635 .adc_nids = alc883_adc_nids_rev,
10636 .capsrc_nids = alc883_capsrc_nids_rev,
10637 .dig_out_nid = ALC883_DIGOUT_NID,
10638 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10639 .channel_mode = alc883_3ST_2ch_modes,
10640 .num_mux_defs =
10641 ARRAY_SIZE(alc888_2_capture_sources),
10642 .input_mux = alc888_acer_aspire_6530_sources,
10643 .unsol_event = alc_sku_unsol_event,
10644 .setup = alc888_acer_aspire_6530g_setup,
10645 .init_hook = alc_hp_automute,
10646 },
10647 [ALC888_ACER_ASPIRE_8930G] = {
10648 .mixers = { alc889_acer_aspire_8930g_mixer,
10649 alc883_chmode_mixer },
10650 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10651 alc889_acer_aspire_8930g_verbs,
10652 alc889_eapd_verbs},
10653 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10654 .dac_nids = alc883_dac_nids,
10655 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10656 .adc_nids = alc889_adc_nids,
10657 .capsrc_nids = alc889_capsrc_nids,
10658 .dig_out_nid = ALC883_DIGOUT_NID,
10659 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10660 .channel_mode = alc883_3ST_6ch_modes,
10661 .need_dac_fix = 1,
10662 .const_channel_count = 6,
10663 .num_mux_defs =
10664 ARRAY_SIZE(alc889_capture_sources),
10665 .input_mux = alc889_capture_sources,
10666 .unsol_event = alc_sku_unsol_event,
10667 .setup = alc889_acer_aspire_8930g_setup,
10668 .init_hook = alc_hp_automute,
10669#ifdef CONFIG_SND_HDA_POWER_SAVE
10670 .power_hook = alc_power_eapd,
10671#endif
10672 },
10673 [ALC888_ACER_ASPIRE_7730G] = {
10674 .mixers = { alc883_3ST_6ch_mixer,
10675 alc883_chmode_mixer },
10676 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10677 alc888_acer_aspire_7730G_verbs },
10678 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10679 .dac_nids = alc883_dac_nids,
10680 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10681 .adc_nids = alc883_adc_nids_rev,
10682 .capsrc_nids = alc883_capsrc_nids_rev,
10683 .dig_out_nid = ALC883_DIGOUT_NID,
10684 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10685 .channel_mode = alc883_3ST_6ch_modes,
10686 .need_dac_fix = 1,
10687 .const_channel_count = 6,
10688 .input_mux = &alc883_capture_source,
10689 .unsol_event = alc_sku_unsol_event,
10690 .setup = alc888_acer_aspire_7730g_setup,
10691 .init_hook = alc_hp_automute,
10692 },
10693 [ALC883_MEDION] = {
10694 .mixers = { alc883_fivestack_mixer,
10695 alc883_chmode_mixer },
10696 .init_verbs = { alc883_init_verbs,
10697 alc883_medion_eapd_verbs },
10698 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10699 .dac_nids = alc883_dac_nids,
10700 .adc_nids = alc883_adc_nids_alt,
10701 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10702 .capsrc_nids = alc883_capsrc_nids,
10703 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10704 .channel_mode = alc883_sixstack_modes,
10705 .input_mux = &alc883_capture_source,
10706 },
10707 [ALC883_MEDION_WIM2160] = {
10708 .mixers = { alc883_medion_wim2160_mixer },
10709 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10710 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10711 .dac_nids = alc883_dac_nids,
10712 .dig_out_nid = ALC883_DIGOUT_NID,
10713 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10714 .adc_nids = alc883_adc_nids,
10715 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10716 .channel_mode = alc883_3ST_2ch_modes,
10717 .input_mux = &alc883_capture_source,
10718 .unsol_event = alc_sku_unsol_event,
10719 .setup = alc883_medion_wim2160_setup,
10720 .init_hook = alc_hp_automute,
10721 },
10722 [ALC883_LAPTOP_EAPD] = {
10723 .mixers = { alc883_base_mixer },
10724 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10725 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10726 .dac_nids = alc883_dac_nids,
10727 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10728 .channel_mode = alc883_3ST_2ch_modes,
10729 .input_mux = &alc883_capture_source,
10730 },
10731 [ALC883_CLEVO_M540R] = {
10732 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10733 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10734 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10735 .dac_nids = alc883_dac_nids,
10736 .dig_out_nid = ALC883_DIGOUT_NID,
10737 .dig_in_nid = ALC883_DIGIN_NID,
10738 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10739 .channel_mode = alc883_3ST_6ch_clevo_modes,
10740 .need_dac_fix = 1,
10741 .input_mux = &alc883_capture_source,
10742 /* This machine has the hardware HP auto-muting, thus
10743 * we need no software mute via unsol event
10744 */
10745 },
10746 [ALC883_CLEVO_M720] = {
10747 .mixers = { alc883_clevo_m720_mixer },
10748 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10749 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10750 .dac_nids = alc883_dac_nids,
10751 .dig_out_nid = ALC883_DIGOUT_NID,
10752 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10753 .channel_mode = alc883_3ST_2ch_modes,
10754 .input_mux = &alc883_capture_source,
10755 .unsol_event = alc883_clevo_m720_unsol_event,
10756 .setup = alc883_clevo_m720_setup,
10757 .init_hook = alc883_clevo_m720_init_hook,
10758 },
10759 [ALC883_LENOVO_101E_2ch] = {
10760 .mixers = { alc883_lenovo_101e_2ch_mixer},
10761 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10762 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10763 .dac_nids = alc883_dac_nids,
10764 .adc_nids = alc883_adc_nids_alt,
10765 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10766 .capsrc_nids = alc883_capsrc_nids,
10767 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10768 .channel_mode = alc883_3ST_2ch_modes,
10769 .input_mux = &alc883_lenovo_101e_capture_source,
10770 .setup = alc883_lenovo_101e_setup,
10771 .unsol_event = alc_sku_unsol_event,
10772 .init_hook = alc_inithook,
10773 },
10774 [ALC883_LENOVO_NB0763] = {
10775 .mixers = { alc883_lenovo_nb0763_mixer },
10776 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10777 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10778 .dac_nids = alc883_dac_nids,
10779 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10780 .channel_mode = alc883_3ST_2ch_modes,
10781 .need_dac_fix = 1,
10782 .input_mux = &alc883_lenovo_nb0763_capture_source,
10783 .unsol_event = alc_sku_unsol_event,
10784 .setup = alc883_lenovo_nb0763_setup,
10785 .init_hook = alc_hp_automute,
10786 },
10787 [ALC888_LENOVO_MS7195_DIG] = {
10788 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10789 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10790 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10791 .dac_nids = alc883_dac_nids,
10792 .dig_out_nid = ALC883_DIGOUT_NID,
10793 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10794 .channel_mode = alc883_3ST_6ch_modes,
10795 .need_dac_fix = 1,
10796 .input_mux = &alc883_capture_source,
10797 .unsol_event = alc_sku_unsol_event,
10798 .setup = alc888_lenovo_ms7195_setup,
10799 .init_hook = alc_inithook,
10800 },
10801 [ALC883_HAIER_W66] = {
10802 .mixers = { alc883_targa_2ch_mixer},
10803 .init_verbs = { alc883_init_verbs, alc883_haier_w66_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_2ch_modes),
10808 .channel_mode = alc883_3ST_2ch_modes,
10809 .input_mux = &alc883_capture_source,
10810 .unsol_event = alc_sku_unsol_event,
10811 .setup = alc883_haier_w66_setup,
10812 .init_hook = alc_hp_automute,
10813 },
10814 [ALC888_3ST_HP] = {
10815 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10816 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10817 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10818 .dac_nids = alc883_dac_nids,
10819 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10820 .channel_mode = alc888_3st_hp_modes,
10821 .need_dac_fix = 1,
10822 .input_mux = &alc883_capture_source,
10823 .unsol_event = alc_sku_unsol_event,
10824 .setup = alc888_3st_hp_setup,
10825 .init_hook = alc_hp_automute,
10826 },
10827 [ALC888_6ST_DELL] = {
10828 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10829 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10830 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10831 .dac_nids = alc883_dac_nids,
10832 .dig_out_nid = ALC883_DIGOUT_NID,
10833 .dig_in_nid = ALC883_DIGIN_NID,
10834 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10835 .channel_mode = alc883_sixstack_modes,
10836 .input_mux = &alc883_capture_source,
10837 .unsol_event = alc_sku_unsol_event,
10838 .setup = alc888_6st_dell_setup,
10839 .init_hook = alc_hp_automute,
10840 },
10841 [ALC883_MITAC] = {
10842 .mixers = { alc883_mitac_mixer },
10843 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10844 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10845 .dac_nids = alc883_dac_nids,
10846 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10847 .channel_mode = alc883_3ST_2ch_modes,
10848 .input_mux = &alc883_capture_source,
10849 .unsol_event = alc_sku_unsol_event,
10850 .setup = alc883_mitac_setup,
10851 .init_hook = alc_hp_automute,
10852 },
10853 [ALC883_FUJITSU_PI2515] = {
10854 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10855 .init_verbs = { alc883_init_verbs,
10856 alc883_2ch_fujitsu_pi2515_verbs},
10857 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10858 .dac_nids = alc883_dac_nids,
10859 .dig_out_nid = ALC883_DIGOUT_NID,
10860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10861 .channel_mode = alc883_3ST_2ch_modes,
10862 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10863 .unsol_event = alc_sku_unsol_event,
10864 .setup = alc883_2ch_fujitsu_pi2515_setup,
10865 .init_hook = alc_hp_automute,
10866 },
10867 [ALC888_FUJITSU_XA3530] = {
10868 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10869 .init_verbs = { alc883_init_verbs,
10870 alc888_fujitsu_xa3530_verbs },
10871 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10872 .dac_nids = alc883_dac_nids,
10873 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10874 .adc_nids = alc883_adc_nids_rev,
10875 .capsrc_nids = alc883_capsrc_nids_rev,
10876 .dig_out_nid = ALC883_DIGOUT_NID,
10877 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10878 .channel_mode = alc888_4ST_8ch_intel_modes,
10879 .num_mux_defs =
10880 ARRAY_SIZE(alc888_2_capture_sources),
10881 .input_mux = alc888_2_capture_sources,
10882 .unsol_event = alc_sku_unsol_event,
10883 .setup = alc888_fujitsu_xa3530_setup,
10884 .init_hook = alc_hp_automute,
10885 },
10886 [ALC888_LENOVO_SKY] = {
10887 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10888 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10889 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10890 .dac_nids = alc883_dac_nids,
10891 .dig_out_nid = ALC883_DIGOUT_NID,
10892 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10893 .channel_mode = alc883_sixstack_modes,
10894 .need_dac_fix = 1,
10895 .input_mux = &alc883_lenovo_sky_capture_source,
10896 .unsol_event = alc_sku_unsol_event,
10897 .setup = alc888_lenovo_sky_setup,
10898 .init_hook = alc_hp_automute,
10899 },
10900 [ALC888_ASUS_M90V] = {
10901 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10902 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10903 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10904 .dac_nids = alc883_dac_nids,
10905 .dig_out_nid = ALC883_DIGOUT_NID,
10906 .dig_in_nid = ALC883_DIGIN_NID,
10907 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10908 .channel_mode = alc883_3ST_6ch_modes,
10909 .need_dac_fix = 1,
10910 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10911 .unsol_event = alc_sku_unsol_event,
10912 .setup = alc883_mode2_setup,
10913 .init_hook = alc_inithook,
10914 },
10915 [ALC888_ASUS_EEE1601] = {
10916 .mixers = { alc883_asus_eee1601_mixer },
10917 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10918 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10919 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10920 .dac_nids = alc883_dac_nids,
10921 .dig_out_nid = ALC883_DIGOUT_NID,
10922 .dig_in_nid = ALC883_DIGIN_NID,
10923 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10924 .channel_mode = alc883_3ST_2ch_modes,
10925 .need_dac_fix = 1,
10926 .input_mux = &alc883_asus_eee1601_capture_source,
10927 .unsol_event = alc_sku_unsol_event,
10928 .init_hook = alc883_eee1601_inithook,
10929 },
10930 [ALC1200_ASUS_P5Q] = {
10931 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10932 .init_verbs = { alc883_init_verbs },
10933 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10934 .dac_nids = alc883_dac_nids,
10935 .dig_out_nid = ALC1200_DIGOUT_NID,
10936 .dig_in_nid = ALC883_DIGIN_NID,
10937 .slave_dig_outs = alc1200_slave_dig_outs,
10938 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10939 .channel_mode = alc883_sixstack_modes,
10940 .input_mux = &alc883_capture_source,
10941 },
10942 [ALC889A_MB31] = {
10943 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10944 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10945 alc880_gpio1_init_verbs },
10946 .adc_nids = alc883_adc_nids,
10947 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10948 .capsrc_nids = alc883_capsrc_nids,
10949 .dac_nids = alc883_dac_nids,
10950 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10951 .channel_mode = alc889A_mb31_6ch_modes,
10952 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10953 .input_mux = &alc889A_mb31_capture_source,
10954 .dig_out_nid = ALC883_DIGOUT_NID,
10955 .unsol_event = alc889A_mb31_unsol_event,
10956 .init_hook = alc889A_mb31_automute,
10957 },
10958 [ALC883_SONY_VAIO_TT] = {
10959 .mixers = { alc883_vaiott_mixer },
10960 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10961 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10962 .dac_nids = alc883_dac_nids,
10963 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10964 .channel_mode = alc883_3ST_2ch_modes,
10965 .input_mux = &alc883_capture_source,
10966 .unsol_event = alc_sku_unsol_event,
10967 .setup = alc883_vaiott_setup,
10968 .init_hook = alc_hp_automute,
10969 },
10970};
10971
10972
10973/* 3860/*
10974 * Pin config fixes 3861 * Pin config fixes
10975 */ 3862 */
@@ -11022,255 +3909,19 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
11022/* 3909/*
11023 * BIOS auto configuration 3910 * BIOS auto configuration
11024 */ 3911 */
11025static int alc882_auto_create_input_ctls(struct hda_codec *codec,
11026 const struct auto_pin_cfg *cfg)
11027{
11028 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
11029}
11030
11031static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
11032 hda_nid_t nid, int pin_type,
11033 hda_nid_t dac)
11034{
11035 int idx;
11036
11037 /* set as output */
11038 alc_set_pin_output(codec, nid, pin_type);
11039
11040 if (dac == 0x25)
11041 idx = 4;
11042 else if (dac >= 0x02 && dac <= 0x05)
11043 idx = dac - 2;
11044 else
11045 return;
11046 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
11047}
11048
11049static void alc882_auto_init_multi_out(struct hda_codec *codec)
11050{
11051 struct alc_spec *spec = codec->spec;
11052 int i;
11053
11054 for (i = 0; i <= HDA_SIDE; i++) {
11055 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11056 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11057 if (nid)
11058 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
11059 spec->multiout.dac_nids[i]);
11060 }
11061}
11062
11063static void alc882_auto_init_hp_out(struct hda_codec *codec)
11064{
11065 struct alc_spec *spec = codec->spec;
11066 hda_nid_t pin, dac;
11067 int i;
11068
11069 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11070 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11071 pin = spec->autocfg.hp_pins[i];
11072 if (!pin)
11073 break;
11074 dac = spec->multiout.hp_nid;
11075 if (!dac)
11076 dac = spec->multiout.dac_nids[0]; /* to front */
11077 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11078 }
11079 }
11080
11081 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11082 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11083 pin = spec->autocfg.speaker_pins[i];
11084 if (!pin)
11085 break;
11086 dac = spec->multiout.extra_out_nid[0];
11087 if (!dac)
11088 dac = spec->multiout.dac_nids[0]; /* to front */
11089 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11090 }
11091 }
11092}
11093
11094static void alc882_auto_init_analog_input(struct hda_codec *codec)
11095{
11096 struct alc_spec *spec = codec->spec;
11097 struct auto_pin_cfg *cfg = &spec->autocfg;
11098 int i;
11099
11100 for (i = 0; i < cfg->num_inputs; i++) {
11101 hda_nid_t nid = cfg->inputs[i].pin;
11102 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
11103 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11104 snd_hda_codec_write(codec, nid, 0,
11105 AC_VERB_SET_AMP_GAIN_MUTE,
11106 AMP_OUT_MUTE);
11107 }
11108}
11109
11110static void alc882_auto_init_input_src(struct hda_codec *codec)
11111{
11112 struct alc_spec *spec = codec->spec;
11113 int c;
11114
11115 for (c = 0; c < spec->num_adc_nids; c++) {
11116 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11117 hda_nid_t nid = spec->capsrc_nids[c];
11118 unsigned int mux_idx;
11119 const struct hda_input_mux *imux;
11120 int conns, mute, idx, item;
11121
11122 /* mute ADC */
11123 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11124 AC_VERB_SET_AMP_GAIN_MUTE,
11125 AMP_IN_MUTE(0));
11126
11127 conns = snd_hda_get_connections(codec, nid, conn_list,
11128 ARRAY_SIZE(conn_list));
11129 if (conns < 0)
11130 continue;
11131 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11132 imux = &spec->input_mux[mux_idx];
11133 if (!imux->num_items && mux_idx > 0)
11134 imux = &spec->input_mux[0];
11135 for (idx = 0; idx < conns; idx++) {
11136 /* if the current connection is the selected one,
11137 * unmute it as default - otherwise mute it
11138 */
11139 mute = AMP_IN_MUTE(idx);
11140 for (item = 0; item < imux->num_items; item++) {
11141 if (imux->items[item].index == idx) {
11142 if (spec->cur_mux[c] == item)
11143 mute = AMP_IN_UNMUTE(idx);
11144 break;
11145 }
11146 }
11147 /* check if we have a selector or mixer
11148 * we could check for the widget type instead, but
11149 * just check for Amp-In presence (in case of mixer
11150 * without amp-in there is something wrong, this
11151 * function shouldn't be used or capsrc nid is wrong)
11152 */
11153 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
11154 snd_hda_codec_write(codec, nid, 0,
11155 AC_VERB_SET_AMP_GAIN_MUTE,
11156 mute);
11157 else if (mute != AMP_IN_MUTE(idx))
11158 snd_hda_codec_write(codec, nid, 0,
11159 AC_VERB_SET_CONNECT_SEL,
11160 idx);
11161 }
11162 }
11163}
11164
11165/* add mic boosts if needed */
11166static int alc_auto_add_mic_boost(struct hda_codec *codec)
11167{
11168 struct alc_spec *spec = codec->spec;
11169 struct auto_pin_cfg *cfg = &spec->autocfg;
11170 int i, err;
11171 int type_idx = 0;
11172 hda_nid_t nid;
11173 const char *prev_label = NULL;
11174
11175 for (i = 0; i < cfg->num_inputs; i++) {
11176 if (cfg->inputs[i].type > AUTO_PIN_MIC)
11177 break;
11178 nid = cfg->inputs[i].pin;
11179 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
11180 const char *label;
11181 char boost_label[32];
11182
11183 label = hda_get_autocfg_input_label(codec, cfg, i);
11184 if (prev_label && !strcmp(label, prev_label))
11185 type_idx++;
11186 else
11187 type_idx = 0;
11188 prev_label = label;
11189
11190 snprintf(boost_label, sizeof(boost_label),
11191 "%s Boost Volume", label);
11192 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11193 boost_label, type_idx,
11194 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11195 if (err < 0)
11196 return err;
11197 }
11198 }
11199 return 0;
11200}
11201
11202/* almost identical with ALC880 parser... */ 3912/* almost identical with ALC880 parser... */
11203static int alc882_parse_auto_config(struct hda_codec *codec) 3913static int alc882_parse_auto_config(struct hda_codec *codec)
11204{ 3914{
11205 struct alc_spec *spec = codec->spec;
11206 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 3915 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
11207 int err; 3916 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
11208 3917 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
11209 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11210 alc882_ignore);
11211 if (err < 0)
11212 return err;
11213 if (!spec->autocfg.line_outs)
11214 return 0; /* can't find valid BIOS pin config */
11215
11216 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11217 if (err < 0)
11218 return err;
11219 err = alc_auto_add_multi_channel_mode(codec);
11220 if (err < 0)
11221 return err;
11222 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
11223 if (err < 0)
11224 return err;
11225 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11226 "Headphone");
11227 if (err < 0)
11228 return err;
11229 err = alc880_auto_create_extra_out(spec,
11230 spec->autocfg.speaker_pins[0],
11231 "Speaker");
11232 if (err < 0)
11233 return err;
11234 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
11235 if (err < 0)
11236 return err;
11237
11238 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11239
11240 alc_auto_parse_digital(codec);
11241
11242 if (spec->kctls.list)
11243 add_mixer(spec, spec->kctls.list);
11244
11245 add_verb(spec, alc883_auto_init_verbs);
11246 /* if ADC 0x07 is available, initialize it, too */
11247 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
11248 add_verb(spec, alc882_adc1_init_verbs);
11249
11250 spec->num_mux_defs = 1;
11251 spec->input_mux = &spec->private_imux[0];
11252
11253 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11254
11255 err = alc_auto_add_mic_boost(codec);
11256 if (err < 0)
11257 return err;
11258
11259 return 1; /* config found */
11260} 3918}
11261 3919
11262/* additional initialization for auto-configuration model */ 3920/*
11263static void alc882_auto_init(struct hda_codec *codec) 3921 */
11264{ 3922#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
11265 struct alc_spec *spec = codec->spec; 3923#include "alc882_quirks.c"
11266 alc882_auto_init_multi_out(codec); 3924#endif
11267 alc882_auto_init_hp_out(codec);
11268 alc882_auto_init_analog_input(codec);
11269 alc882_auto_init_input_src(codec);
11270 alc_auto_init_digital(codec);
11271 if (spec->unsol_event)
11272 alc_inithook(codec);
11273}
11274 3925
11275static int patch_alc882(struct hda_codec *codec) 3926static int patch_alc882(struct hda_codec *codec)
11276{ 3927{
@@ -11283,6 +3934,8 @@ static int patch_alc882(struct hda_codec *codec)
11283 3934
11284 codec->spec = spec; 3935 codec->spec = spec;
11285 3936
3937 spec->mixer_nid = 0x0b;
3938
11286 switch (codec->vendor_id) { 3939 switch (codec->vendor_id) {
11287 case 0x10ec0882: 3940 case 0x10ec0882:
11288 case 0x10ec0885: 3941 case 0x10ec0885:
@@ -11293,106 +3946,71 @@ static int patch_alc882(struct hda_codec *codec)
11293 break; 3946 break;
11294 } 3947 }
11295 3948
11296 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 3949 board_config = alc_board_config(codec, ALC882_MODEL_LAST,
11297 alc882_models, 3950 alc882_models, alc882_cfg_tbl);
11298 alc882_cfg_tbl);
11299 3951
11300 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 3952 if (board_config < 0)
11301 board_config = snd_hda_check_board_codec_sid_config(codec, 3953 board_config = alc_board_codec_sid_config(codec,
11302 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 3954 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11303 3955
11304 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 3956 if (board_config < 0) {
11305 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 3957 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11306 codec->chip_name); 3958 codec->chip_name);
11307 board_config = ALC882_AUTO; 3959 board_config = ALC_MODEL_AUTO;
11308 } 3960 }
11309 3961
11310 if (board_config == ALC882_AUTO) { 3962 if (board_config == ALC_MODEL_AUTO) {
11311 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); 3963 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11312 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 3964 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11313 } 3965 }
11314 3966
11315 alc_auto_parse_customize_define(codec); 3967 alc_auto_parse_customize_define(codec);
11316 3968
11317 if (board_config == ALC882_AUTO) { 3969 if (board_config == ALC_MODEL_AUTO) {
11318 /* automatic parse from the BIOS config */ 3970 /* automatic parse from the BIOS config */
11319 err = alc882_parse_auto_config(codec); 3971 err = alc882_parse_auto_config(codec);
11320 if (err < 0) { 3972 if (err < 0) {
11321 alc_free(codec); 3973 alc_free(codec);
11322 return err; 3974 return err;
11323 } else if (!err) { 3975 }
3976#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3977 else if (!err) {
11324 printk(KERN_INFO 3978 printk(KERN_INFO
11325 "hda_codec: Cannot set up configuration " 3979 "hda_codec: Cannot set up configuration "
11326 "from BIOS. Using base mode...\n"); 3980 "from BIOS. Using base mode...\n");
11327 board_config = ALC882_3ST_DIG; 3981 board_config = ALC882_3ST_DIG;
11328 } 3982 }
3983#endif
11329 } 3984 }
11330 3985
11331 if (has_cdefine_beep(codec)) { 3986 if (board_config != ALC_MODEL_AUTO)
11332 err = snd_hda_attach_beep_device(codec, 0x1);
11333 if (err < 0) {
11334 alc_free(codec);
11335 return err;
11336 }
11337 }
11338
11339 if (board_config != ALC882_AUTO)
11340 setup_preset(codec, &alc882_presets[board_config]); 3987 setup_preset(codec, &alc882_presets[board_config]);
11341 3988
11342 spec->stream_analog_playback = &alc882_pcm_analog_playback; 3989 if (!spec->no_analog && !spec->adc_nids) {
11343 spec->stream_analog_capture = &alc882_pcm_analog_capture; 3990 alc_auto_fill_adc_caps(codec);
11344 /* FIXME: setup DAC5 */ 3991 alc_rebuild_imux_for_auto_mic(codec);
11345 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 3992 alc_remove_invalid_adc_nids(codec);
11346 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11347
11348 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11349 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11350
11351 if (!spec->adc_nids && spec->input_mux) {
11352 int i, j;
11353 spec->num_adc_nids = 0;
11354 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11355 const struct hda_input_mux *imux = spec->input_mux;
11356 hda_nid_t cap;
11357 hda_nid_t items[16];
11358 hda_nid_t nid = alc882_adc_nids[i];
11359 unsigned int wcap = get_wcaps(codec, nid);
11360 /* get type */
11361 wcap = get_wcaps_type(wcap);
11362 if (wcap != AC_WID_AUD_IN)
11363 continue;
11364 spec->private_adc_nids[spec->num_adc_nids] = nid;
11365 err = snd_hda_get_connections(codec, nid, &cap, 1);
11366 if (err < 0)
11367 continue;
11368 err = snd_hda_get_connections(codec, cap, items,
11369 ARRAY_SIZE(items));
11370 if (err < 0)
11371 continue;
11372 for (j = 0; j < imux->num_items; j++)
11373 if (imux->items[j].index >= err)
11374 break;
11375 if (j < imux->num_items)
11376 continue;
11377 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11378 spec->num_adc_nids++;
11379 }
11380 spec->adc_nids = spec->private_adc_nids;
11381 spec->capsrc_nids = spec->private_capsrc_nids;
11382 } 3993 }
11383 3994
11384 set_capture_mixer(codec); 3995 if (!spec->no_analog && !spec->cap_mixer)
3996 set_capture_mixer(codec);
11385 3997
11386 if (has_cdefine_beep(codec)) 3998 if (!spec->no_analog && has_cdefine_beep(codec)) {
3999 err = snd_hda_attach_beep_device(codec, 0x1);
4000 if (err < 0) {
4001 alc_free(codec);
4002 return err;
4003 }
11387 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4004 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4005 }
11388 4006
11389 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4007 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11390 4008
11391 spec->vmaster_nid = 0x0c; 4009 spec->vmaster_nid = 0x0c;
11392 4010
11393 codec->patch_ops = alc_patch_ops; 4011 codec->patch_ops = alc_patch_ops;
11394 if (board_config == ALC882_AUTO) 4012 if (board_config == ALC_MODEL_AUTO)
11395 spec->init_hook = alc882_auto_init; 4013 spec->init_hook = alc_auto_init_std;
11396 4014
11397 alc_init_jacks(codec); 4015 alc_init_jacks(codec);
11398#ifdef CONFIG_SND_HDA_POWER_SAVE 4016#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -11407,1197 +4025,19 @@ static int patch_alc882(struct hda_codec *codec)
11407/* 4025/*
11408 * ALC262 support 4026 * ALC262 support
11409 */ 4027 */
11410 4028static int alc262_parse_auto_config(struct hda_codec *codec)
11411#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11412#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11413
11414#define alc262_dac_nids alc260_dac_nids
11415#define alc262_adc_nids alc882_adc_nids
11416#define alc262_adc_nids_alt alc882_adc_nids_alt
11417#define alc262_capsrc_nids alc882_capsrc_nids
11418#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11419
11420#define alc262_modes alc260_modes
11421#define alc262_capture_source alc882_capture_source
11422
11423static const hda_nid_t alc262_dmic_adc_nids[1] = {
11424 /* ADC0 */
11425 0x09
11426};
11427
11428static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11429
11430static const struct snd_kcontrol_new alc262_base_mixer[] = {
11431 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11432 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11433 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11434 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11435 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11436 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11439 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11440 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11441 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11442 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11443 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11444 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11445 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11446 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11447 { } /* end */
11448};
11449
11450/* update HP, line and mono-out pins according to the master switch */
11451#define alc262_hp_master_update alc260_hp_master_update
11452
11453static void alc262_hp_bpc_setup(struct hda_codec *codec)
11454{
11455 struct alc_spec *spec = codec->spec;
11456
11457 spec->autocfg.hp_pins[0] = 0x1b;
11458 spec->autocfg.speaker_pins[0] = 0x16;
11459 spec->automute = 1;
11460 spec->automute_mode = ALC_AUTOMUTE_PIN;
11461}
11462
11463static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11464{
11465 struct alc_spec *spec = codec->spec;
11466
11467 spec->autocfg.hp_pins[0] = 0x15;
11468 spec->autocfg.speaker_pins[0] = 0x16;
11469 spec->automute = 1;
11470 spec->automute_mode = ALC_AUTOMUTE_PIN;
11471}
11472
11473#define alc262_hp_master_sw_get alc260_hp_master_sw_get
11474#define alc262_hp_master_sw_put alc260_hp_master_sw_put
11475
11476#define ALC262_HP_MASTER_SWITCH \
11477 { \
11478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11479 .name = "Master Playback Switch", \
11480 .info = snd_ctl_boolean_mono_info, \
11481 .get = alc262_hp_master_sw_get, \
11482 .put = alc262_hp_master_sw_put, \
11483 }, \
11484 { \
11485 .iface = NID_MAPPING, \
11486 .name = "Master Playback Switch", \
11487 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11488 }
11489
11490
11491static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11492 ALC262_HP_MASTER_SWITCH,
11493 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11494 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11495 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11496 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11497 HDA_OUTPUT),
11498 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11499 HDA_OUTPUT),
11500 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11501 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11502 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11503 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11504 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11505 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11508 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11509 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11510 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11511 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11512 { } /* end */
11513};
11514
11515static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11516 ALC262_HP_MASTER_SWITCH,
11517 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11518 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11519 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11520 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11521 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11522 HDA_OUTPUT),
11523 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11524 HDA_OUTPUT),
11525 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11526 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11527 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11528 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11529 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11530 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11531 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11532 { } /* end */
11533};
11534
11535static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11536 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11537 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11538 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11539 { } /* end */
11540};
11541
11542/* mute/unmute internal speaker according to the hp jack and mute state */
11543static void alc262_hp_t5735_setup(struct hda_codec *codec)
11544{
11545 struct alc_spec *spec = codec->spec;
11546
11547 spec->autocfg.hp_pins[0] = 0x15;
11548 spec->autocfg.speaker_pins[0] = 0x14;
11549 spec->automute = 1;
11550 spec->automute_mode = ALC_AUTOMUTE_PIN;
11551}
11552
11553static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11554 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11555 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11556 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11557 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11558 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11559 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11560 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11561 { } /* end */
11562};
11563
11564static const struct hda_verb alc262_hp_t5735_verbs[] = {
11565 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11566 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11567
11568 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11569 { }
11570};
11571
11572static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11575 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11576 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11577 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11578 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11579 { } /* end */
11580};
11581
11582static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11583 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11584 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11585 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11586 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11588 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11589 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11590 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11591 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11592 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11593 {}
11594};
11595
11596static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11597 .num_items = 1,
11598 .items = {
11599 { "Line", 0x1 },
11600 },
11601};
11602
11603/* bind hp and internal speaker mute (with plug check) as master switch */
11604#define alc262_hippo_master_update alc262_hp_master_update
11605#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11606#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11607
11608#define ALC262_HIPPO_MASTER_SWITCH \
11609 { \
11610 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11611 .name = "Master Playback Switch", \
11612 .info = snd_ctl_boolean_mono_info, \
11613 .get = alc262_hippo_master_sw_get, \
11614 .put = alc262_hippo_master_sw_put, \
11615 }, \
11616 { \
11617 .iface = NID_MAPPING, \
11618 .name = "Master Playback Switch", \
11619 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11620 (SUBDEV_SPEAKER(0) << 16), \
11621 }
11622
11623static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11624 ALC262_HIPPO_MASTER_SWITCH,
11625 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11626 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11627 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11628 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11629 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11630 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11631 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11632 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11633 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11634 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11635 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11636 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11637 { } /* end */
11638};
11639
11640static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11641 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11642 ALC262_HIPPO_MASTER_SWITCH,
11643 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11644 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11645 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11646 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11649 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11650 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11651 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11652 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11653 { } /* end */
11654};
11655
11656/* mute/unmute internal speaker according to the hp jack and mute state */
11657static void alc262_hippo_setup(struct hda_codec *codec)
11658{
11659 struct alc_spec *spec = codec->spec;
11660
11661 spec->autocfg.hp_pins[0] = 0x15;
11662 spec->autocfg.speaker_pins[0] = 0x14;
11663 spec->automute = 1;
11664 spec->automute_mode = ALC_AUTOMUTE_AMP;
11665}
11666
11667static void alc262_hippo1_setup(struct hda_codec *codec)
11668{
11669 struct alc_spec *spec = codec->spec;
11670
11671 spec->autocfg.hp_pins[0] = 0x1b;
11672 spec->autocfg.speaker_pins[0] = 0x14;
11673 spec->automute = 1;
11674 spec->automute_mode = ALC_AUTOMUTE_AMP;
11675}
11676
11677
11678static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11679 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11680 ALC262_HIPPO_MASTER_SWITCH,
11681 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11682 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11683 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11684 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11685 { } /* end */
11686};
11687
11688static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11689 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11690 ALC262_HIPPO_MASTER_SWITCH,
11691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11693 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11694 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11695 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11696 { } /* end */
11697};
11698
11699static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11700 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11701 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11702 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11703 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11704 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11705 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
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("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11709 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11710 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11711 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11712 { } /* end */
11713};
11714
11715static const struct hda_verb alc262_tyan_verbs[] = {
11716 /* Headphone automute */
11717 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11718 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11719 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11720
11721 /* P11 AUX_IN, white 4-pin connector */
11722 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11723 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11724 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11725 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11726
11727 {}
11728};
11729
11730/* unsolicited event for HP jack sensing */
11731static void alc262_tyan_setup(struct hda_codec *codec)
11732{
11733 struct alc_spec *spec = codec->spec;
11734
11735 spec->autocfg.hp_pins[0] = 0x1b;
11736 spec->autocfg.speaker_pins[0] = 0x15;
11737 spec->automute = 1;
11738 spec->automute_mode = ALC_AUTOMUTE_AMP;
11739}
11740
11741
11742#define alc262_capture_mixer alc882_capture_mixer
11743#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11744
11745/*
11746 * generic initialization of ADC, input mixers and output mixers
11747 */
11748static const struct hda_verb alc262_init_verbs[] = {
11749 /*
11750 * Unmute ADC0-2 and set the default input to mic-in
11751 */
11752 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11753 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11754 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11755 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11756 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11757 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11758
11759 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11760 * mixer widget
11761 * Note: PASD motherboards uses the Line In 2 as the input for
11762 * front panel mic (mic 2)
11763 */
11764 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11765 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11766 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11769 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11770
11771 /*
11772 * Set up output mixers (0x0c - 0x0e)
11773 */
11774 /* set vol=0 to output mixers */
11775 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11776 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11777 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11778 /* set up input amps for analog loopback */
11779 /* Amp Indices: DAC = 0, mixer = 1 */
11780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11782 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11783 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11784 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11785 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11786
11787 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11788 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11789 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11790 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11791 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11792 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11793
11794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11795 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11796 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11797 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11798 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11799
11800 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11801 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11802
11803 /* FIXME: use matrix-type input source selection */
11804 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11805 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11806 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11810 /* Input mixer2 */
11811 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11812 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11813 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11814 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11815 /* Input mixer3 */
11816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11820
11821 { }
11822};
11823
11824static const struct hda_verb alc262_eapd_verbs[] = {
11825 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11826 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11827 { }
11828};
11829
11830static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11831 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11832 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11833 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11834
11835 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11836 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11837 {}
11838};
11839
11840static const struct hda_verb alc262_sony_unsol_verbs[] = {
11841 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11842 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11843 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11844
11845 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11847 {}
11848};
11849
11850static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11851 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11852 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11853 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11854 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11856 { } /* end */
11857};
11858
11859static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11860 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11861 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11862 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11863 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11864 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11865 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11866 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11867 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11868 {}
11869};
11870
11871static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11872{
11873 struct alc_spec *spec = codec->spec;
11874
11875 spec->autocfg.hp_pins[0] = 0x15;
11876 spec->autocfg.speaker_pins[0] = 0x14;
11877 spec->ext_mic.pin = 0x18;
11878 spec->ext_mic.mux_idx = 0;
11879 spec->int_mic.pin = 0x12;
11880 spec->int_mic.mux_idx = 9;
11881 spec->auto_mic = 1;
11882 spec->automute = 1;
11883 spec->automute_mode = ALC_AUTOMUTE_PIN;
11884}
11885
11886/*
11887 * nec model
11888 * 0x15 = headphone
11889 * 0x16 = internal speaker
11890 * 0x18 = external mic
11891 */
11892
11893static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11894 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11895 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11896
11897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11899 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11900
11901 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11902 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11903 { } /* end */
11904};
11905
11906static const struct hda_verb alc262_nec_verbs[] = {
11907 /* Unmute Speaker */
11908 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11909
11910 /* Headphone */
11911 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11913
11914 /* External mic to headphone */
11915 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11916 /* External mic to speaker */
11917 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11918 {}
11919};
11920
11921/*
11922 * fujitsu model
11923 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11924 * 0x1b = port replicator headphone out
11925 */
11926
11927#define ALC_HP_EVENT 0x37
11928
11929static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11930 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11931 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11932 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11933 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11934 {}
11935};
11936
11937static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11938 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11939 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11940 {}
11941};
11942
11943static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11944 /* Front Mic pin: input vref at 50% */
11945 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11946 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11947 {}
11948};
11949
11950static const struct hda_input_mux alc262_fujitsu_capture_source = {
11951 .num_items = 3,
11952 .items = {
11953 { "Mic", 0x0 },
11954 { "Internal Mic", 0x1 },
11955 { "CD", 0x4 },
11956 },
11957};
11958
11959static const struct hda_input_mux alc262_HP_capture_source = {
11960 .num_items = 5,
11961 .items = {
11962 { "Mic", 0x0 },
11963 { "Front Mic", 0x1 },
11964 { "Line", 0x2 },
11965 { "CD", 0x4 },
11966 { "AUX IN", 0x6 },
11967 },
11968};
11969
11970static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11971 .num_items = 4,
11972 .items = {
11973 { "Mic", 0x0 },
11974 { "Front Mic", 0x2 },
11975 { "Line", 0x1 },
11976 { "CD", 0x4 },
11977 },
11978};
11979
11980static void alc262_fujitsu_setup(struct hda_codec *codec)
11981{
11982 struct alc_spec *spec = codec->spec;
11983
11984 spec->autocfg.hp_pins[0] = 0x14;
11985 spec->autocfg.hp_pins[1] = 0x1b;
11986 spec->autocfg.speaker_pins[0] = 0x15;
11987 spec->automute = 1;
11988 spec->automute_mode = ALC_AUTOMUTE_AMP;
11989}
11990
11991/* bind volumes of both NID 0x0c and 0x0d */
11992static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11993 .ops = &snd_hda_bind_vol,
11994 .values = {
11995 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11996 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11997 0
11998 },
11999};
12000
12001static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
12002 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12003 {
12004 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12005 .name = "Master Playback Switch",
12006 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12007 .info = snd_ctl_boolean_mono_info,
12008 .get = alc262_hp_master_sw_get,
12009 .put = alc262_hp_master_sw_put,
12010 },
12011 {
12012 .iface = NID_MAPPING,
12013 .name = "Master Playback Switch",
12014 .private_value = 0x1b,
12015 },
12016 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12017 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12018 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12021 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12022 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12023 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12024 { } /* end */
12025};
12026
12027static void alc262_lenovo_3000_setup(struct hda_codec *codec)
12028{
12029 struct alc_spec *spec = codec->spec;
12030
12031 spec->autocfg.hp_pins[0] = 0x1b;
12032 spec->autocfg.speaker_pins[0] = 0x14;
12033 spec->autocfg.speaker_pins[1] = 0x16;
12034 spec->automute = 1;
12035 spec->automute_mode = ALC_AUTOMUTE_AMP;
12036}
12037
12038static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
12039 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12040 {
12041 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12042 .name = "Master Playback Switch",
12043 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
12044 .info = snd_ctl_boolean_mono_info,
12045 .get = alc262_hp_master_sw_get,
12046 .put = alc262_hp_master_sw_put,
12047 },
12048 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12049 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12050 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12052 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12053 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12054 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12055 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12056 { } /* end */
12057};
12058
12059static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
12060 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12061 ALC262_HIPPO_MASTER_SWITCH,
12062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12063 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12064 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12065 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12066 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12067 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12068 { } /* end */
12069};
12070
12071/* additional init verbs for Benq laptops */
12072static const struct hda_verb alc262_EAPD_verbs[] = {
12073 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12074 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12075 {}
12076};
12077
12078static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
12079 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12080 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12081
12082 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12083 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12084 {}
12085};
12086
12087/* Samsung Q1 Ultra Vista model setup */
12088static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
12089 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12090 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
12091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12093 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12094 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
12095 { } /* end */
12096};
12097
12098static const struct hda_verb alc262_ultra_verbs[] = {
12099 /* output mixer */
12100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12103 /* speaker */
12104 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12105 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12107 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12108 /* HP */
12109 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12110 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12112 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12113 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12114 /* internal mic */
12115 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12116 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12117 /* ADC, choose mic */
12118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12119 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12120 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12123 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12124 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12125 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12126 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12127 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12128 {}
12129};
12130
12131/* mute/unmute internal speaker according to the hp jack and mute state */
12132static void alc262_ultra_automute(struct hda_codec *codec)
12133{
12134 struct alc_spec *spec = codec->spec;
12135 unsigned int mute;
12136
12137 mute = 0;
12138 /* auto-mute only when HP is used as HP */
12139 if (!spec->cur_mux[0]) {
12140 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12141 if (spec->jack_present)
12142 mute = HDA_AMP_MUTE;
12143 }
12144 /* mute/unmute internal speaker */
12145 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12146 HDA_AMP_MUTE, mute);
12147 /* mute/unmute HP */
12148 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12149 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12150}
12151
12152/* unsolicited event for HP jack sensing */
12153static void alc262_ultra_unsol_event(struct hda_codec *codec,
12154 unsigned int res)
12155{
12156 if ((res >> 26) != ALC880_HP_EVENT)
12157 return;
12158 alc262_ultra_automute(codec);
12159}
12160
12161static const struct hda_input_mux alc262_ultra_capture_source = {
12162 .num_items = 2,
12163 .items = {
12164 { "Mic", 0x1 },
12165 { "Headphone", 0x7 },
12166 },
12167};
12168
12169static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12170 struct snd_ctl_elem_value *ucontrol)
12171{
12172 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12173 struct alc_spec *spec = codec->spec;
12174 int ret;
12175
12176 ret = alc_mux_enum_put(kcontrol, ucontrol);
12177 if (!ret)
12178 return 0;
12179 /* reprogram the HP pin as mic or HP according to the input source */
12180 snd_hda_codec_write_cache(codec, 0x15, 0,
12181 AC_VERB_SET_PIN_WIDGET_CONTROL,
12182 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12183 alc262_ultra_automute(codec); /* mute/unmute HP */
12184 return ret;
12185}
12186
12187static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12188 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12189 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12190 {
12191 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12192 .name = "Capture Source",
12193 .info = alc_mux_enum_info,
12194 .get = alc_mux_enum_get,
12195 .put = alc262_ultra_mux_enum_put,
12196 },
12197 {
12198 .iface = NID_MAPPING,
12199 .name = "Capture Source",
12200 .private_value = 0x15,
12201 },
12202 { } /* end */
12203};
12204
12205/* We use two mixers depending on the output pin; 0x16 is a mono output
12206 * and thus it's bound with a different mixer.
12207 * This function returns which mixer amp should be used.
12208 */
12209static int alc262_check_volbit(hda_nid_t nid)
12210{
12211 if (!nid)
12212 return 0;
12213 else if (nid == 0x16)
12214 return 2;
12215 else
12216 return 1;
12217}
12218
12219static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12220 const char *pfx, int *vbits, int idx)
12221{
12222 unsigned long val;
12223 int vbit;
12224
12225 vbit = alc262_check_volbit(nid);
12226 if (!vbit)
12227 return 0;
12228 if (*vbits & vbit) /* a volume control for this mixer already there */
12229 return 0;
12230 *vbits |= vbit;
12231 if (vbit == 2)
12232 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12233 else
12234 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12235 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12236}
12237
12238static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12239 const char *pfx, int idx)
12240{
12241 unsigned long val;
12242
12243 if (!nid)
12244 return 0;
12245 if (nid == 0x16)
12246 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12247 else
12248 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12249 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12250}
12251
12252/* add playback controls from the parsed DAC table */
12253static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12254 const struct auto_pin_cfg *cfg)
12255{ 4029{
12256 const char *pfx; 4030 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12257 int vbits; 4031 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
12258 int i, err; 4032 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
12259
12260 spec->multiout.num_dacs = 1; /* only use one dac */
12261 spec->multiout.dac_nids = spec->private_dac_nids;
12262 spec->private_dac_nids[0] = 2;
12263
12264 pfx = alc_get_line_out_pfx(spec, true);
12265 if (!pfx)
12266 pfx = "Front";
12267 for (i = 0; i < 2; i++) {
12268 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12269 if (err < 0)
12270 return err;
12271 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12272 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12273 "Speaker", i);
12274 if (err < 0)
12275 return err;
12276 }
12277 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12278 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12279 "Headphone", i);
12280 if (err < 0)
12281 return err;
12282 }
12283 }
12284
12285 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12286 alc262_check_volbit(cfg->speaker_pins[0]) |
12287 alc262_check_volbit(cfg->hp_pins[0]);
12288 if (vbits == 1 || vbits == 2)
12289 pfx = "Master"; /* only one mixer is used */
12290 vbits = 0;
12291 for (i = 0; i < 2; i++) {
12292 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12293 &vbits, i);
12294 if (err < 0)
12295 return err;
12296 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12297 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12298 "Speaker", &vbits, i);
12299 if (err < 0)
12300 return err;
12301 }
12302 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12303 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12304 "Headphone", &vbits, i);
12305 if (err < 0)
12306 return err;
12307 }
12308 }
12309 return 0;
12310} 4033}
12311 4034
12312#define alc262_auto_create_input_ctls \
12313 alc882_auto_create_input_ctls
12314
12315/*
12316 * generic initialization of ADC, input mixers and output mixers
12317 */
12318static const struct hda_verb alc262_volume_init_verbs[] = {
12319 /*
12320 * Unmute ADC0-2 and set the default input to mic-in
12321 */
12322 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12324 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12325 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12326 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12327 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12328
12329 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12330 * mixer widget
12331 * Note: PASD motherboards uses the Line In 2 as the input for
12332 * front panel mic (mic 2)
12333 */
12334 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12335 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12340
12341 /*
12342 * Set up output mixers (0x0c - 0x0f)
12343 */
12344 /* set vol=0 to output mixers */
12345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12346 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12347 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12348
12349 /* set up input amps for analog loopback */
12350 /* Amp Indices: DAC = 0, mixer = 1 */
12351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12353 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12354 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12356 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12357
12358 /* FIXME: use matrix-type input source selection */
12359 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12360 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12361 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12362 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12363 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12364 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12365 /* Input mixer2 */
12366 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12367 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12368 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12369 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12370 /* Input mixer3 */
12371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12375
12376 { }
12377};
12378
12379static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
12380 /*
12381 * Unmute ADC0-2 and set the default input to mic-in
12382 */
12383 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12384 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12385 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12386 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12387 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12388 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12389
12390 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12391 * mixer widget
12392 * Note: PASD motherboards uses the Line In 2 as the input for
12393 * front panel mic (mic 2)
12394 */
12395 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12396 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12403
12404 /*
12405 * Set up output mixers (0x0c - 0x0e)
12406 */
12407 /* set vol=0 to output mixers */
12408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12409 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12410 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12411
12412 /* set up input amps for analog loopback */
12413 /* Amp Indices: DAC = 0, mixer = 1 */
12414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12420
12421 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12424
12425 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12426 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12427
12428 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12429 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12430
12431 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12432 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12433 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12434 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12435 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12436
12437 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12438 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12439 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12440 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12441 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12442 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12443
12444
12445 /* FIXME: use matrix-type input source selection */
12446 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12447 /* Input mixer1: only unmute Mic */
12448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12457 /* Input mixer2 */
12458 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12459 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12461 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12467 /* Input mixer3 */
12468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12477
12478 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12479
12480 { }
12481};
12482
12483static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12484 /*
12485 * Unmute ADC0-2 and set the default input to mic-in
12486 */
12487 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12489 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12490 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12491 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12492 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12493
12494 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12495 * mixer widget
12496 * Note: PASD motherboards uses the Line In 2 as the input for front
12497 * panel mic (mic 2)
12498 */
12499 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12501 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12502 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12503 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12504 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12505 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12506 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12507 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12508 /*
12509 * Set up output mixers (0x0c - 0x0e)
12510 */
12511 /* set vol=0 to output mixers */
12512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12514 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12515
12516 /* set up input amps for analog loopback */
12517 /* Amp Indices: DAC = 0, mixer = 1 */
12518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12520 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12521 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12522 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12523 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12524
12525
12526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12527 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12528 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12529 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12530 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12531 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12532 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12533
12534 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12535 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12536
12537 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12538 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12539
12540 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12541 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12542 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12543 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12544 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12545 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12546
12547 /* FIXME: use matrix-type input source selection */
12548 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12549 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12550 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12551 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12552 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12553 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12554 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12555 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12556 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12557 /* Input mixer2 */
12558 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12563 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12565 /* Input mixer3 */
12566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12568 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12569 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12571 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12573
12574 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12575
12576 { }
12577};
12578
12579static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12580
12581 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12582 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12583 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12584
12585 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12586 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12587 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12588 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12589
12590 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12593 {}
12594};
12595
12596/* 4035/*
12597 * Pin config fixes 4036 * Pin config fixes
12598 */ 4037 */
12599enum { 4038enum {
12600 PINFIX_FSC_H270, 4039 PINFIX_FSC_H270,
4040 PINFIX_HP_Z200,
12601}; 4041};
12602 4042
12603static const struct alc_fixup alc262_fixups[] = { 4043static const struct alc_fixup alc262_fixups[] = {
@@ -12610,9 +4050,17 @@ static const struct alc_fixup alc262_fixups[] = {
12610 { } 4050 { }
12611 } 4051 }
12612 }, 4052 },
4053 [PINFIX_HP_Z200] = {
4054 .type = ALC_FIXUP_PINS,
4055 .v.pins = (const struct alc_pincfg[]) {
4056 { 0x16, 0x99130120 }, /* internal speaker */
4057 { }
4058 }
4059 },
12613}; 4060};
12614 4061
12615static const struct snd_pci_quirk alc262_fixup_tbl[] = { 4062static const struct snd_pci_quirk alc262_fixup_tbl[] = {
4063 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
12616 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), 4064 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12617 {} 4065 {}
12618}; 4066};
@@ -12622,394 +4070,11 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12622#define alc262_loopbacks alc880_loopbacks 4070#define alc262_loopbacks alc880_loopbacks
12623#endif 4071#endif
12624 4072
12625/* pcm configuration: identical with ALC880 */
12626#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12627#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12628#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12629#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12630
12631/* 4073/*
12632 * BIOS auto configuration
12633 */ 4074 */
12634static int alc262_parse_auto_config(struct hda_codec *codec) 4075#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
12635{ 4076#include "alc262_quirks.c"
12636 struct alc_spec *spec = codec->spec;
12637 int err;
12638 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12639
12640 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12641 alc262_ignore);
12642 if (err < 0)
12643 return err;
12644 if (!spec->autocfg.line_outs) {
12645 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12646 spec->multiout.max_channels = 2;
12647 spec->no_analog = 1;
12648 goto dig_only;
12649 }
12650 return 0; /* can't find valid BIOS pin config */
12651 }
12652 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12653 if (err < 0)
12654 return err;
12655 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12656 if (err < 0)
12657 return err;
12658
12659 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12660
12661 dig_only:
12662 alc_auto_parse_digital(codec);
12663
12664 if (spec->kctls.list)
12665 add_mixer(spec, spec->kctls.list);
12666
12667 add_verb(spec, alc262_volume_init_verbs);
12668 spec->num_mux_defs = 1;
12669 spec->input_mux = &spec->private_imux[0];
12670
12671 err = alc_auto_add_mic_boost(codec);
12672 if (err < 0)
12673 return err;
12674
12675 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12676
12677 return 1;
12678}
12679
12680#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12681#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12682#define alc262_auto_init_analog_input alc882_auto_init_analog_input
12683#define alc262_auto_init_input_src alc882_auto_init_input_src
12684
12685
12686/* init callback for auto-configuration model -- overriding the default init */
12687static void alc262_auto_init(struct hda_codec *codec)
12688{
12689 struct alc_spec *spec = codec->spec;
12690 alc262_auto_init_multi_out(codec);
12691 alc262_auto_init_hp_out(codec);
12692 alc262_auto_init_analog_input(codec);
12693 alc262_auto_init_input_src(codec);
12694 alc_auto_init_digital(codec);
12695 if (spec->unsol_event)
12696 alc_inithook(codec);
12697}
12698
12699/*
12700 * configuration and preset
12701 */
12702static const char * const alc262_models[ALC262_MODEL_LAST] = {
12703 [ALC262_BASIC] = "basic",
12704 [ALC262_HIPPO] = "hippo",
12705 [ALC262_HIPPO_1] = "hippo_1",
12706 [ALC262_FUJITSU] = "fujitsu",
12707 [ALC262_HP_BPC] = "hp-bpc",
12708 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12709 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12710 [ALC262_HP_RP5700] = "hp-rp5700",
12711 [ALC262_BENQ_ED8] = "benq",
12712 [ALC262_BENQ_T31] = "benq-t31",
12713 [ALC262_SONY_ASSAMD] = "sony-assamd",
12714 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12715 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12716 [ALC262_ULTRA] = "ultra",
12717 [ALC262_LENOVO_3000] = "lenovo-3000",
12718 [ALC262_NEC] = "nec",
12719 [ALC262_TYAN] = "tyan",
12720 [ALC262_AUTO] = "auto",
12721};
12722
12723static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12724 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12725 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12726 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12727 ALC262_HP_BPC),
12728 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12729 ALC262_HP_BPC),
12730 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12731 ALC262_HP_BPC),
12732 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12733 ALC262_HP_BPC),
12734 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12735 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12736 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12737 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12738 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12739 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12740 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12741 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12742 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12743 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12744 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12745 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12746 ALC262_HP_TC_T5735),
12747 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12748 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12749 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12750 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12751 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12752 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12753 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12754 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12755#if 0 /* disable the quirk since model=auto works better in recent versions */
12756 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12757 ALC262_SONY_ASSAMD),
12758#endif 4077#endif
12759 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12760 ALC262_TOSHIBA_RX1),
12761 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12762 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12763 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12764 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12765 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12766 ALC262_ULTRA),
12767 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12768 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12769 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12770 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12771 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12772 {}
12773};
12774
12775static const struct alc_config_preset alc262_presets[] = {
12776 [ALC262_BASIC] = {
12777 .mixers = { alc262_base_mixer },
12778 .init_verbs = { alc262_init_verbs },
12779 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12780 .dac_nids = alc262_dac_nids,
12781 .hp_nid = 0x03,
12782 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12783 .channel_mode = alc262_modes,
12784 .input_mux = &alc262_capture_source,
12785 },
12786 [ALC262_HIPPO] = {
12787 .mixers = { alc262_hippo_mixer },
12788 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12789 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12790 .dac_nids = alc262_dac_nids,
12791 .hp_nid = 0x03,
12792 .dig_out_nid = ALC262_DIGOUT_NID,
12793 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12794 .channel_mode = alc262_modes,
12795 .input_mux = &alc262_capture_source,
12796 .unsol_event = alc_sku_unsol_event,
12797 .setup = alc262_hippo_setup,
12798 .init_hook = alc_inithook,
12799 },
12800 [ALC262_HIPPO_1] = {
12801 .mixers = { alc262_hippo1_mixer },
12802 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12803 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12804 .dac_nids = alc262_dac_nids,
12805 .hp_nid = 0x02,
12806 .dig_out_nid = ALC262_DIGOUT_NID,
12807 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12808 .channel_mode = alc262_modes,
12809 .input_mux = &alc262_capture_source,
12810 .unsol_event = alc_sku_unsol_event,
12811 .setup = alc262_hippo1_setup,
12812 .init_hook = alc_inithook,
12813 },
12814 [ALC262_FUJITSU] = {
12815 .mixers = { alc262_fujitsu_mixer },
12816 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12817 alc262_fujitsu_unsol_verbs },
12818 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12819 .dac_nids = alc262_dac_nids,
12820 .hp_nid = 0x03,
12821 .dig_out_nid = ALC262_DIGOUT_NID,
12822 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12823 .channel_mode = alc262_modes,
12824 .input_mux = &alc262_fujitsu_capture_source,
12825 .unsol_event = alc_sku_unsol_event,
12826 .setup = alc262_fujitsu_setup,
12827 .init_hook = alc_inithook,
12828 },
12829 [ALC262_HP_BPC] = {
12830 .mixers = { alc262_HP_BPC_mixer },
12831 .init_verbs = { alc262_HP_BPC_init_verbs },
12832 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12833 .dac_nids = alc262_dac_nids,
12834 .hp_nid = 0x03,
12835 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12836 .channel_mode = alc262_modes,
12837 .input_mux = &alc262_HP_capture_source,
12838 .unsol_event = alc_sku_unsol_event,
12839 .setup = alc262_hp_bpc_setup,
12840 .init_hook = alc_inithook,
12841 },
12842 [ALC262_HP_BPC_D7000_WF] = {
12843 .mixers = { alc262_HP_BPC_WildWest_mixer },
12844 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12845 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12846 .dac_nids = alc262_dac_nids,
12847 .hp_nid = 0x03,
12848 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12849 .channel_mode = alc262_modes,
12850 .input_mux = &alc262_HP_D7000_capture_source,
12851 .unsol_event = alc_sku_unsol_event,
12852 .setup = alc262_hp_wildwest_setup,
12853 .init_hook = alc_inithook,
12854 },
12855 [ALC262_HP_BPC_D7000_WL] = {
12856 .mixers = { alc262_HP_BPC_WildWest_mixer,
12857 alc262_HP_BPC_WildWest_option_mixer },
12858 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12859 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12860 .dac_nids = alc262_dac_nids,
12861 .hp_nid = 0x03,
12862 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12863 .channel_mode = alc262_modes,
12864 .input_mux = &alc262_HP_D7000_capture_source,
12865 .unsol_event = alc_sku_unsol_event,
12866 .setup = alc262_hp_wildwest_setup,
12867 .init_hook = alc_inithook,
12868 },
12869 [ALC262_HP_TC_T5735] = {
12870 .mixers = { alc262_hp_t5735_mixer },
12871 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12872 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12873 .dac_nids = alc262_dac_nids,
12874 .hp_nid = 0x03,
12875 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12876 .channel_mode = alc262_modes,
12877 .input_mux = &alc262_capture_source,
12878 .unsol_event = alc_sku_unsol_event,
12879 .setup = alc262_hp_t5735_setup,
12880 .init_hook = alc_inithook,
12881 },
12882 [ALC262_HP_RP5700] = {
12883 .mixers = { alc262_hp_rp5700_mixer },
12884 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12885 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12886 .dac_nids = alc262_dac_nids,
12887 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12888 .channel_mode = alc262_modes,
12889 .input_mux = &alc262_hp_rp5700_capture_source,
12890 },
12891 [ALC262_BENQ_ED8] = {
12892 .mixers = { alc262_base_mixer },
12893 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12894 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12895 .dac_nids = alc262_dac_nids,
12896 .hp_nid = 0x03,
12897 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12898 .channel_mode = alc262_modes,
12899 .input_mux = &alc262_capture_source,
12900 },
12901 [ALC262_SONY_ASSAMD] = {
12902 .mixers = { alc262_sony_mixer },
12903 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12904 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12905 .dac_nids = alc262_dac_nids,
12906 .hp_nid = 0x02,
12907 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12908 .channel_mode = alc262_modes,
12909 .input_mux = &alc262_capture_source,
12910 .unsol_event = alc_sku_unsol_event,
12911 .setup = alc262_hippo_setup,
12912 .init_hook = alc_inithook,
12913 },
12914 [ALC262_BENQ_T31] = {
12915 .mixers = { alc262_benq_t31_mixer },
12916 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12917 alc_hp15_unsol_verbs },
12918 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12919 .dac_nids = alc262_dac_nids,
12920 .hp_nid = 0x03,
12921 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12922 .channel_mode = alc262_modes,
12923 .input_mux = &alc262_capture_source,
12924 .unsol_event = alc_sku_unsol_event,
12925 .setup = alc262_hippo_setup,
12926 .init_hook = alc_inithook,
12927 },
12928 [ALC262_ULTRA] = {
12929 .mixers = { alc262_ultra_mixer },
12930 .cap_mixer = alc262_ultra_capture_mixer,
12931 .init_verbs = { alc262_ultra_verbs },
12932 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12933 .dac_nids = alc262_dac_nids,
12934 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12935 .channel_mode = alc262_modes,
12936 .input_mux = &alc262_ultra_capture_source,
12937 .adc_nids = alc262_adc_nids, /* ADC0 */
12938 .capsrc_nids = alc262_capsrc_nids,
12939 .num_adc_nids = 1, /* single ADC */
12940 .unsol_event = alc262_ultra_unsol_event,
12941 .init_hook = alc262_ultra_automute,
12942 },
12943 [ALC262_LENOVO_3000] = {
12944 .mixers = { alc262_lenovo_3000_mixer },
12945 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12946 alc262_lenovo_3000_unsol_verbs,
12947 alc262_lenovo_3000_init_verbs },
12948 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12949 .dac_nids = alc262_dac_nids,
12950 .hp_nid = 0x03,
12951 .dig_out_nid = ALC262_DIGOUT_NID,
12952 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12953 .channel_mode = alc262_modes,
12954 .input_mux = &alc262_fujitsu_capture_source,
12955 .unsol_event = alc_sku_unsol_event,
12956 .setup = alc262_lenovo_3000_setup,
12957 .init_hook = alc_inithook,
12958 },
12959 [ALC262_NEC] = {
12960 .mixers = { alc262_nec_mixer },
12961 .init_verbs = { alc262_nec_verbs },
12962 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12963 .dac_nids = alc262_dac_nids,
12964 .hp_nid = 0x03,
12965 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12966 .channel_mode = alc262_modes,
12967 .input_mux = &alc262_capture_source,
12968 },
12969 [ALC262_TOSHIBA_S06] = {
12970 .mixers = { alc262_toshiba_s06_mixer },
12971 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12972 alc262_eapd_verbs },
12973 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12974 .capsrc_nids = alc262_dmic_capsrc_nids,
12975 .dac_nids = alc262_dac_nids,
12976 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12977 .num_adc_nids = 1, /* single ADC */
12978 .dig_out_nid = ALC262_DIGOUT_NID,
12979 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12980 .channel_mode = alc262_modes,
12981 .unsol_event = alc_sku_unsol_event,
12982 .setup = alc262_toshiba_s06_setup,
12983 .init_hook = alc_inithook,
12984 },
12985 [ALC262_TOSHIBA_RX1] = {
12986 .mixers = { alc262_toshiba_rx1_mixer },
12987 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12988 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12989 .dac_nids = alc262_dac_nids,
12990 .hp_nid = 0x03,
12991 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12992 .channel_mode = alc262_modes,
12993 .input_mux = &alc262_capture_source,
12994 .unsol_event = alc_sku_unsol_event,
12995 .setup = alc262_hippo_setup,
12996 .init_hook = alc_inithook,
12997 },
12998 [ALC262_TYAN] = {
12999 .mixers = { alc262_tyan_mixer },
13000 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
13001 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
13002 .dac_nids = alc262_dac_nids,
13003 .hp_nid = 0x02,
13004 .dig_out_nid = ALC262_DIGOUT_NID,
13005 .num_channel_mode = ARRAY_SIZE(alc262_modes),
13006 .channel_mode = alc262_modes,
13007 .input_mux = &alc262_capture_source,
13008 .unsol_event = alc_sku_unsol_event,
13009 .setup = alc262_tyan_setup,
13010 .init_hook = alc_hp_automute,
13011 },
13012};
13013 4078
13014static int patch_alc262(struct hda_codec *codec) 4079static int patch_alc262(struct hda_codec *codec)
13015{ 4080{
@@ -13022,6 +4087,9 @@ static int patch_alc262(struct hda_codec *codec)
13022 return -ENOMEM; 4087 return -ENOMEM;
13023 4088
13024 codec->spec = spec; 4089 codec->spec = spec;
4090
4091 spec->mixer_nid = 0x0b;
4092
13025#if 0 4093#if 0
13026 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 4094 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
13027 * under-run 4095 * under-run
@@ -13038,96 +4106,65 @@ static int patch_alc262(struct hda_codec *codec)
13038 4106
13039 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 4107 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
13040 4108
13041 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 4109 board_config = alc_board_config(codec, ALC262_MODEL_LAST,
13042 alc262_models, 4110 alc262_models, alc262_cfg_tbl);
13043 alc262_cfg_tbl);
13044 4111
13045 if (board_config < 0) { 4112 if (board_config < 0) {
13046 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4113 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13047 codec->chip_name); 4114 codec->chip_name);
13048 board_config = ALC262_AUTO; 4115 board_config = ALC_MODEL_AUTO;
13049 } 4116 }
13050 4117
13051 if (board_config == ALC262_AUTO) { 4118 if (board_config == ALC_MODEL_AUTO) {
13052 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); 4119 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13053 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4120 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13054 } 4121 }
13055 4122
13056 if (board_config == ALC262_AUTO) { 4123 if (board_config == ALC_MODEL_AUTO) {
13057 /* automatic parse from the BIOS config */ 4124 /* automatic parse from the BIOS config */
13058 err = alc262_parse_auto_config(codec); 4125 err = alc262_parse_auto_config(codec);
13059 if (err < 0) { 4126 if (err < 0) {
13060 alc_free(codec); 4127 alc_free(codec);
13061 return err; 4128 return err;
13062 } else if (!err) { 4129 }
4130#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4131 else if (!err) {
13063 printk(KERN_INFO 4132 printk(KERN_INFO
13064 "hda_codec: Cannot set up configuration " 4133 "hda_codec: Cannot set up configuration "
13065 "from BIOS. Using base mode...\n"); 4134 "from BIOS. Using base mode...\n");
13066 board_config = ALC262_BASIC; 4135 board_config = ALC262_BASIC;
13067 } 4136 }
4137#endif
13068 } 4138 }
13069 4139
4140 if (board_config != ALC_MODEL_AUTO)
4141 setup_preset(codec, &alc262_presets[board_config]);
4142
4143 if (!spec->no_analog && !spec->adc_nids) {
4144 alc_auto_fill_adc_caps(codec);
4145 alc_rebuild_imux_for_auto_mic(codec);
4146 alc_remove_invalid_adc_nids(codec);
4147 }
4148
4149 if (!spec->no_analog && !spec->cap_mixer)
4150 set_capture_mixer(codec);
4151
13070 if (!spec->no_analog && has_cdefine_beep(codec)) { 4152 if (!spec->no_analog && has_cdefine_beep(codec)) {
13071 err = snd_hda_attach_beep_device(codec, 0x1); 4153 err = snd_hda_attach_beep_device(codec, 0x1);
13072 if (err < 0) { 4154 if (err < 0) {
13073 alc_free(codec); 4155 alc_free(codec);
13074 return err; 4156 return err;
13075 } 4157 }
13076 }
13077
13078 if (board_config != ALC262_AUTO)
13079 setup_preset(codec, &alc262_presets[board_config]);
13080
13081 spec->stream_analog_playback = &alc262_pcm_analog_playback;
13082 spec->stream_analog_capture = &alc262_pcm_analog_capture;
13083
13084 spec->stream_digital_playback = &alc262_pcm_digital_playback;
13085 spec->stream_digital_capture = &alc262_pcm_digital_capture;
13086
13087 if (!spec->adc_nids && spec->input_mux) {
13088 int i;
13089 /* check whether the digital-mic has to be supported */
13090 for (i = 0; i < spec->input_mux->num_items; i++) {
13091 if (spec->input_mux->items[i].index >= 9)
13092 break;
13093 }
13094 if (i < spec->input_mux->num_items) {
13095 /* use only ADC0 */
13096 spec->adc_nids = alc262_dmic_adc_nids;
13097 spec->num_adc_nids = 1;
13098 spec->capsrc_nids = alc262_dmic_capsrc_nids;
13099 } else {
13100 /* all analog inputs */
13101 /* check whether NID 0x07 is valid */
13102 unsigned int wcap = get_wcaps(codec, 0x07);
13103
13104 /* get type */
13105 wcap = get_wcaps_type(wcap);
13106 if (wcap != AC_WID_AUD_IN) {
13107 spec->adc_nids = alc262_adc_nids_alt;
13108 spec->num_adc_nids =
13109 ARRAY_SIZE(alc262_adc_nids_alt);
13110 spec->capsrc_nids = alc262_capsrc_nids_alt;
13111 } else {
13112 spec->adc_nids = alc262_adc_nids;
13113 spec->num_adc_nids =
13114 ARRAY_SIZE(alc262_adc_nids);
13115 spec->capsrc_nids = alc262_capsrc_nids;
13116 }
13117 }
13118 }
13119 if (!spec->cap_mixer && !spec->no_analog)
13120 set_capture_mixer(codec);
13121 if (!spec->no_analog && has_cdefine_beep(codec))
13122 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4158 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4159 }
13123 4160
13124 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4161 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13125 4162
13126 spec->vmaster_nid = 0x0c; 4163 spec->vmaster_nid = 0x0c;
13127 4164
13128 codec->patch_ops = alc_patch_ops; 4165 codec->patch_ops = alc_patch_ops;
13129 if (board_config == ALC262_AUTO) 4166 if (board_config == ALC_MODEL_AUTO)
13130 spec->init_hook = alc262_auto_init; 4167 spec->init_hook = alc_auto_init_std;
13131 spec->shutup = alc_eapd_shutup; 4168 spec->shutup = alc_eapd_shutup;
13132 4169
13133 alc_init_jacks(codec); 4170 alc_init_jacks(codec);
@@ -13140,51 +4177,8 @@ static int patch_alc262(struct hda_codec *codec)
13140} 4177}
13141 4178
13142/* 4179/*
13143 * ALC268 channel source setting (2 channel) 4180 * ALC268
13144 */ 4181 */
13145#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13146#define alc268_modes alc260_modes
13147
13148static const hda_nid_t alc268_dac_nids[2] = {
13149 /* front, hp */
13150 0x02, 0x03
13151};
13152
13153static const hda_nid_t alc268_adc_nids[2] = {
13154 /* ADC0-1 */
13155 0x08, 0x07
13156};
13157
13158static const hda_nid_t alc268_adc_nids_alt[1] = {
13159 /* ADC0 */
13160 0x08
13161};
13162
13163static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13164
13165static const struct snd_kcontrol_new alc268_base_mixer[] = {
13166 /* output mixer control */
13167 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13168 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13169 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13170 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13171 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13172 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13173 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13174 { }
13175};
13176
13177static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13178 /* output mixer control */
13179 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13180 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13181 ALC262_HIPPO_MASTER_SWITCH,
13182 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13183 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13184 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13185 { }
13186};
13187
13188/* bind Beep switches of both NID 0x0f and 0x10 */ 4182/* bind Beep switches of both NID 0x0f and 0x10 */
13189static const struct hda_bind_ctls alc268_bind_beep_sw = { 4183static const struct hda_bind_ctls alc268_bind_beep_sw = {
13190 .ops = &snd_hda_bind_sw, 4184 .ops = &snd_hda_bind_sw,
@@ -13201,847 +4195,36 @@ static const struct snd_kcontrol_new alc268_beep_mixer[] = {
13201 { } 4195 { }
13202}; 4196};
13203 4197
13204static const struct hda_verb alc268_eapd_verbs[] = { 4198/* set PCBEEP vol = 0, mute connections */
13205 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 4199static const struct hda_verb alc268_beep_init_verbs[] = {
13206 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13207 { }
13208};
13209
13210/* Toshiba specific */
13211static const struct hda_verb alc268_toshiba_verbs[] = {
13212 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13213 { } /* end */
13214};
13215
13216/* Acer specific */
13217/* bind volumes of both NID 0x02 and 0x03 */
13218static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
13219 .ops = &snd_hda_bind_vol,
13220 .values = {
13221 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13222 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13223 0
13224 },
13225};
13226
13227static void alc268_acer_setup(struct hda_codec *codec)
13228{
13229 struct alc_spec *spec = codec->spec;
13230
13231 spec->autocfg.hp_pins[0] = 0x14;
13232 spec->autocfg.speaker_pins[0] = 0x15;
13233 spec->automute = 1;
13234 spec->automute_mode = ALC_AUTOMUTE_AMP;
13235}
13236
13237#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13238#define alc268_acer_master_sw_put alc262_hp_master_sw_put
13239
13240static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13241 /* output mixer control */
13242 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13243 {
13244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13245 .name = "Master Playback Switch",
13246 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13247 .info = snd_ctl_boolean_mono_info,
13248 .get = alc268_acer_master_sw_get,
13249 .put = alc268_acer_master_sw_put,
13250 },
13251 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13252 { }
13253};
13254
13255static const struct snd_kcontrol_new alc268_acer_mixer[] = {
13256 /* output mixer control */
13257 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13258 {
13259 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13260 .name = "Master Playback Switch",
13261 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13262 .info = snd_ctl_boolean_mono_info,
13263 .get = alc268_acer_master_sw_get,
13264 .put = alc268_acer_master_sw_put,
13265 },
13266 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13267 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13268 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13269 { }
13270};
13271
13272static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13273 /* output mixer control */
13274 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13275 {
13276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13277 .name = "Master Playback Switch",
13278 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13279 .info = snd_ctl_boolean_mono_info,
13280 .get = alc268_acer_master_sw_get,
13281 .put = alc268_acer_master_sw_put,
13282 },
13283 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13284 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13285 { }
13286};
13287
13288static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
13289 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13292 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13293 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13294 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13295 { }
13296};
13297
13298static const struct hda_verb alc268_acer_verbs[] = {
13299 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13300 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13302 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13303 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13304 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13305 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13306 { }
13307};
13308
13309/* unsolicited event for HP jack sensing */
13310#define alc268_toshiba_setup alc262_hippo_setup
13311
13312static void alc268_acer_lc_setup(struct hda_codec *codec)
13313{
13314 struct alc_spec *spec = codec->spec;
13315 spec->autocfg.hp_pins[0] = 0x15;
13316 spec->autocfg.speaker_pins[0] = 0x14;
13317 spec->automute_mixer_nid[0] = 0x0f;
13318 spec->automute = 1;
13319 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13320 spec->ext_mic.pin = 0x18;
13321 spec->ext_mic.mux_idx = 0;
13322 spec->int_mic.pin = 0x12;
13323 spec->int_mic.mux_idx = 6;
13324 spec->auto_mic = 1;
13325}
13326
13327static const struct snd_kcontrol_new alc268_dell_mixer[] = {
13328 /* output mixer control */
13329 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13330 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13331 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13333 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13334 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13335 { }
13336};
13337
13338static const struct hda_verb alc268_dell_verbs[] = {
13339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13341 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13342 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13343 { }
13344};
13345
13346/* mute/unmute internal speaker according to the hp jack and mute state */
13347static void alc268_dell_setup(struct hda_codec *codec)
13348{
13349 struct alc_spec *spec = codec->spec;
13350
13351 spec->autocfg.hp_pins[0] = 0x15;
13352 spec->autocfg.speaker_pins[0] = 0x14;
13353 spec->ext_mic.pin = 0x18;
13354 spec->ext_mic.mux_idx = 0;
13355 spec->int_mic.pin = 0x19;
13356 spec->int_mic.mux_idx = 1;
13357 spec->auto_mic = 1;
13358 spec->automute = 1;
13359 spec->automute_mode = ALC_AUTOMUTE_PIN;
13360}
13361
13362static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13363 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13364 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13365 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13366 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13367 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13368 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13369 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13370 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13371 { }
13372};
13373
13374static const struct hda_verb alc267_quanta_il1_verbs[] = {
13375 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13376 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13377 { }
13378};
13379
13380static void alc267_quanta_il1_setup(struct hda_codec *codec)
13381{
13382 struct alc_spec *spec = codec->spec;
13383 spec->autocfg.hp_pins[0] = 0x15;
13384 spec->autocfg.speaker_pins[0] = 0x14;
13385 spec->ext_mic.pin = 0x18;
13386 spec->ext_mic.mux_idx = 0;
13387 spec->int_mic.pin = 0x19;
13388 spec->int_mic.mux_idx = 1;
13389 spec->auto_mic = 1;
13390 spec->automute = 1;
13391 spec->automute_mode = ALC_AUTOMUTE_PIN;
13392}
13393
13394/*
13395 * generic initialization of ADC, input mixers and output mixers
13396 */
13397static const struct hda_verb alc268_base_init_verbs[] = {
13398 /* Unmute DAC0-1 and set vol = 0 */
13399 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13400 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13401
13402 /*
13403 * Set up output mixers (0x0c - 0x0e)
13404 */
13405 /* set vol=0 to output mixers */
13406 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13407 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13408
13409 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13410 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13411
13412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13413 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13414 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13415 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13416 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13417 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13418 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13419 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13420
13421 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13423 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13424 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13426
13427 /* set PCBEEP vol = 0, mute connections */
13428 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4200 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13429 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4201 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13430 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4202 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13431
13432 /* Unmute Selector 23h,24h and set the default input to mic-in */
13433
13434 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13435 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13436 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13437 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13438
13439 { } 4203 { }
13440}; 4204};
13441 4205
13442/* 4206/*
13443 * generic initialization of ADC, input mixers and output mixers
13444 */
13445static const struct hda_verb alc268_volume_init_verbs[] = {
13446 /* set output DAC */
13447 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13448 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13449
13450 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13451 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13452 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13453 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13454 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13455
13456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13457 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13458 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459
13460 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13462
13463 /* set PCBEEP vol = 0, mute connections */
13464 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13465 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13466 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13467
13468 { }
13469};
13470
13471static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13472 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13473 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13474 { } /* end */
13475};
13476
13477static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13478 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13479 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13480 _DEFINE_CAPSRC(1),
13481 { } /* end */
13482};
13483
13484static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13485 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13486 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13487 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13488 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13489 _DEFINE_CAPSRC(2),
13490 { } /* end */
13491};
13492
13493static const struct hda_input_mux alc268_capture_source = {
13494 .num_items = 4,
13495 .items = {
13496 { "Mic", 0x0 },
13497 { "Front Mic", 0x1 },
13498 { "Line", 0x2 },
13499 { "CD", 0x3 },
13500 },
13501};
13502
13503static const struct hda_input_mux alc268_acer_capture_source = {
13504 .num_items = 3,
13505 .items = {
13506 { "Mic", 0x0 },
13507 { "Internal Mic", 0x1 },
13508 { "Line", 0x2 },
13509 },
13510};
13511
13512static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13513 .num_items = 3,
13514 .items = {
13515 { "Mic", 0x0 },
13516 { "Internal Mic", 0x6 },
13517 { "Line", 0x2 },
13518 },
13519};
13520
13521#ifdef CONFIG_SND_DEBUG
13522static const struct snd_kcontrol_new alc268_test_mixer[] = {
13523 /* Volume widgets */
13524 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13525 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13526 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13527 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13528 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13529 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13530 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13531 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13532 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13533 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13534 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13535 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13536 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13537 /* The below appears problematic on some hardwares */
13538 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13539 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13540 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13541 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13542 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13543
13544 /* Modes for retasking pin widgets */
13545 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13546 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13547 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13548 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13549
13550 /* Controls for GPIO pins, assuming they are configured as outputs */
13551 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13552 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13553 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13554 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13555
13556 /* Switches to allow the digital SPDIF output pin to be enabled.
13557 * The ALC268 does not have an SPDIF input.
13558 */
13559 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13560
13561 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13562 * this output to turn on an external amplifier.
13563 */
13564 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13565 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13566
13567 { } /* end */
13568};
13569#endif
13570
13571/* create input playback/capture controls for the given pin */
13572static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13573 const char *ctlname, int idx)
13574{
13575 hda_nid_t dac;
13576 int err;
13577
13578 switch (nid) {
13579 case 0x14:
13580 case 0x16:
13581 dac = 0x02;
13582 break;
13583 case 0x15:
13584 case 0x1a: /* ALC259/269 only */
13585 case 0x1b: /* ALC259/269 only */
13586 case 0x21: /* ALC269vb has this pin, too */
13587 dac = 0x03;
13588 break;
13589 default:
13590 snd_printd(KERN_WARNING "hda_codec: "
13591 "ignoring pin 0x%x as unknown\n", nid);
13592 return 0;
13593 }
13594 if (spec->multiout.dac_nids[0] != dac &&
13595 spec->multiout.dac_nids[1] != dac) {
13596 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13597 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13598 HDA_OUTPUT));
13599 if (err < 0)
13600 return err;
13601 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13602 }
13603
13604 if (nid != 0x16)
13605 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13606 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13607 else /* mono */
13608 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13609 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13610 if (err < 0)
13611 return err;
13612 return 0;
13613}
13614
13615/* add playback controls from the parsed DAC table */
13616static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13617 const struct auto_pin_cfg *cfg)
13618{
13619 hda_nid_t nid;
13620 int err;
13621
13622 spec->multiout.dac_nids = spec->private_dac_nids;
13623
13624 nid = cfg->line_out_pins[0];
13625 if (nid) {
13626 const char *name;
13627 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13628 name = "Speaker";
13629 else
13630 name = "Front";
13631 err = alc268_new_analog_output(spec, nid, name, 0);
13632 if (err < 0)
13633 return err;
13634 }
13635
13636 nid = cfg->speaker_pins[0];
13637 if (nid == 0x1d) {
13638 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13639 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13640 if (err < 0)
13641 return err;
13642 } else if (nid) {
13643 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13644 if (err < 0)
13645 return err;
13646 }
13647 nid = cfg->hp_pins[0];
13648 if (nid) {
13649 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13650 if (err < 0)
13651 return err;
13652 }
13653
13654 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13655 if (nid == 0x16) {
13656 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13657 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13658 if (err < 0)
13659 return err;
13660 }
13661 return 0;
13662}
13663
13664/* create playback/capture controls for input pins */
13665static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13666 const struct auto_pin_cfg *cfg)
13667{
13668 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13669}
13670
13671static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13672 hda_nid_t nid, int pin_type)
13673{
13674 int idx;
13675
13676 alc_set_pin_output(codec, nid, pin_type);
13677 if (nid == 0x14 || nid == 0x16)
13678 idx = 0;
13679 else
13680 idx = 1;
13681 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13682}
13683
13684static void alc268_auto_init_multi_out(struct hda_codec *codec)
13685{
13686 struct alc_spec *spec = codec->spec;
13687 int i;
13688
13689 for (i = 0; i < spec->autocfg.line_outs; i++) {
13690 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13691 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13692 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13693 }
13694}
13695
13696static void alc268_auto_init_hp_out(struct hda_codec *codec)
13697{
13698 struct alc_spec *spec = codec->spec;
13699 hda_nid_t pin;
13700 int i;
13701
13702 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13703 pin = spec->autocfg.hp_pins[i];
13704 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13705 }
13706 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13707 pin = spec->autocfg.speaker_pins[i];
13708 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13709 }
13710 if (spec->autocfg.mono_out_pin)
13711 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13712 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13713}
13714
13715static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13716{
13717 struct alc_spec *spec = codec->spec;
13718 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13719 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13720 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13721 unsigned int dac_vol1, dac_vol2;
13722
13723 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13724 snd_hda_codec_write(codec, speaker_nid, 0,
13725 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13726 /* mute mixer inputs from 0x1d */
13727 snd_hda_codec_write(codec, 0x0f, 0,
13728 AC_VERB_SET_AMP_GAIN_MUTE,
13729 AMP_IN_UNMUTE(1));
13730 snd_hda_codec_write(codec, 0x10, 0,
13731 AC_VERB_SET_AMP_GAIN_MUTE,
13732 AMP_IN_UNMUTE(1));
13733 } else {
13734 /* unmute mixer inputs from 0x1d */
13735 snd_hda_codec_write(codec, 0x0f, 0,
13736 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13737 snd_hda_codec_write(codec, 0x10, 0,
13738 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13739 }
13740
13741 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13742 if (line_nid == 0x14)
13743 dac_vol2 = AMP_OUT_ZERO;
13744 else if (line_nid == 0x15)
13745 dac_vol1 = AMP_OUT_ZERO;
13746 if (hp_nid == 0x14)
13747 dac_vol2 = AMP_OUT_ZERO;
13748 else if (hp_nid == 0x15)
13749 dac_vol1 = AMP_OUT_ZERO;
13750 if (line_nid != 0x16 || hp_nid != 0x16 ||
13751 spec->autocfg.line_out_pins[1] != 0x16 ||
13752 spec->autocfg.line_out_pins[2] != 0x16)
13753 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13754
13755 snd_hda_codec_write(codec, 0x02, 0,
13756 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13757 snd_hda_codec_write(codec, 0x03, 0,
13758 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13759}
13760
13761/* pcm configuration: identical with ALC880 */
13762#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13763#define alc268_pcm_analog_capture alc880_pcm_analog_capture
13764#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13765#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13766
13767/*
13768 * BIOS auto configuration 4207 * BIOS auto configuration
13769 */ 4208 */
13770static int alc268_parse_auto_config(struct hda_codec *codec) 4209static int alc268_parse_auto_config(struct hda_codec *codec)
13771{ 4210{
4211 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
13772 struct alc_spec *spec = codec->spec; 4212 struct alc_spec *spec = codec->spec;
13773 int err; 4213 int err = alc_parse_auto_config(codec, NULL, alc268_ssids);
13774 static const hda_nid_t alc268_ignore[] = { 0 }; 4214 if (err > 0) {
13775 4215 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) {
13776 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4216 add_mixer(spec, alc268_beep_mixer);
13777 alc268_ignore); 4217 add_verb(spec, alc268_beep_init_verbs);
13778 if (err < 0)
13779 return err;
13780 if (!spec->autocfg.line_outs) {
13781 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13782 spec->multiout.max_channels = 2;
13783 spec->no_analog = 1;
13784 goto dig_only;
13785 } 4218 }
13786 return 0; /* can't find valid BIOS pin config */
13787 } 4219 }
13788 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 4220 return err;
13789 if (err < 0)
13790 return err;
13791 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13792 if (err < 0)
13793 return err;
13794
13795 spec->multiout.max_channels = 2;
13796
13797 dig_only:
13798 /* digital only support output */
13799 alc_auto_parse_digital(codec);
13800 if (spec->kctls.list)
13801 add_mixer(spec, spec->kctls.list);
13802
13803 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13804 add_mixer(spec, alc268_beep_mixer);
13805
13806 add_verb(spec, alc268_volume_init_verbs);
13807 spec->num_mux_defs = 2;
13808 spec->input_mux = &spec->private_imux[0];
13809
13810 err = alc_auto_add_mic_boost(codec);
13811 if (err < 0)
13812 return err;
13813
13814 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13815
13816 return 1;
13817}
13818
13819#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13820#define alc268_auto_init_input_src alc882_auto_init_input_src
13821
13822/* init callback for auto-configuration model -- overriding the default init */
13823static void alc268_auto_init(struct hda_codec *codec)
13824{
13825 struct alc_spec *spec = codec->spec;
13826 alc268_auto_init_multi_out(codec);
13827 alc268_auto_init_hp_out(codec);
13828 alc268_auto_init_mono_speaker_out(codec);
13829 alc268_auto_init_analog_input(codec);
13830 alc268_auto_init_input_src(codec);
13831 alc_auto_init_digital(codec);
13832 if (spec->unsol_event)
13833 alc_inithook(codec);
13834} 4221}
13835 4222
13836/* 4223/*
13837 * configuration and preset
13838 */ 4224 */
13839static const char * const alc268_models[ALC268_MODEL_LAST] = { 4225#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
13840 [ALC267_QUANTA_IL1] = "quanta-il1", 4226#include "alc268_quirks.c"
13841 [ALC268_3ST] = "3stack",
13842 [ALC268_TOSHIBA] = "toshiba",
13843 [ALC268_ACER] = "acer",
13844 [ALC268_ACER_DMIC] = "acer-dmic",
13845 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13846 [ALC268_DELL] = "dell",
13847 [ALC268_ZEPTO] = "zepto",
13848#ifdef CONFIG_SND_DEBUG
13849 [ALC268_TEST] = "test",
13850#endif 4227#endif
13851 [ALC268_AUTO] = "auto",
13852};
13853
13854static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13855 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13856 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13857 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13858 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13859 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13860 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13861 ALC268_ACER_ASPIRE_ONE),
13862 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13863 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13864 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13865 /* almost compatible with toshiba but with optional digital outs;
13866 * auto-probing seems working fine
13867 */
13868 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13869 ALC268_AUTO),
13870 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13871 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13872 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13873 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
13874 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13875 {}
13876};
13877
13878/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13879static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13880 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13881 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13882 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13883 ALC268_TOSHIBA),
13884 {}
13885};
13886
13887static const struct alc_config_preset alc268_presets[] = {
13888 [ALC267_QUANTA_IL1] = {
13889 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13890 alc268_capture_nosrc_mixer },
13891 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13892 alc267_quanta_il1_verbs },
13893 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13894 .dac_nids = alc268_dac_nids,
13895 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13896 .adc_nids = alc268_adc_nids_alt,
13897 .hp_nid = 0x03,
13898 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13899 .channel_mode = alc268_modes,
13900 .unsol_event = alc_sku_unsol_event,
13901 .setup = alc267_quanta_il1_setup,
13902 .init_hook = alc_inithook,
13903 },
13904 [ALC268_3ST] = {
13905 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13906 alc268_beep_mixer },
13907 .init_verbs = { alc268_base_init_verbs },
13908 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13909 .dac_nids = alc268_dac_nids,
13910 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13911 .adc_nids = alc268_adc_nids_alt,
13912 .capsrc_nids = alc268_capsrc_nids,
13913 .hp_nid = 0x03,
13914 .dig_out_nid = ALC268_DIGOUT_NID,
13915 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13916 .channel_mode = alc268_modes,
13917 .input_mux = &alc268_capture_source,
13918 },
13919 [ALC268_TOSHIBA] = {
13920 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13921 alc268_beep_mixer },
13922 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13923 alc268_toshiba_verbs },
13924 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13925 .dac_nids = alc268_dac_nids,
13926 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13927 .adc_nids = alc268_adc_nids_alt,
13928 .capsrc_nids = alc268_capsrc_nids,
13929 .hp_nid = 0x03,
13930 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13931 .channel_mode = alc268_modes,
13932 .input_mux = &alc268_capture_source,
13933 .unsol_event = alc_sku_unsol_event,
13934 .setup = alc268_toshiba_setup,
13935 .init_hook = alc_inithook,
13936 },
13937 [ALC268_ACER] = {
13938 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13939 alc268_beep_mixer },
13940 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13941 alc268_acer_verbs },
13942 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13943 .dac_nids = alc268_dac_nids,
13944 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13945 .adc_nids = alc268_adc_nids_alt,
13946 .capsrc_nids = alc268_capsrc_nids,
13947 .hp_nid = 0x02,
13948 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13949 .channel_mode = alc268_modes,
13950 .input_mux = &alc268_acer_capture_source,
13951 .unsol_event = alc_sku_unsol_event,
13952 .setup = alc268_acer_setup,
13953 .init_hook = alc_inithook,
13954 },
13955 [ALC268_ACER_DMIC] = {
13956 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13957 alc268_beep_mixer },
13958 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13959 alc268_acer_verbs },
13960 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13961 .dac_nids = alc268_dac_nids,
13962 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13963 .adc_nids = alc268_adc_nids_alt,
13964 .capsrc_nids = alc268_capsrc_nids,
13965 .hp_nid = 0x02,
13966 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13967 .channel_mode = alc268_modes,
13968 .input_mux = &alc268_acer_dmic_capture_source,
13969 .unsol_event = alc_sku_unsol_event,
13970 .setup = alc268_acer_setup,
13971 .init_hook = alc_inithook,
13972 },
13973 [ALC268_ACER_ASPIRE_ONE] = {
13974 .mixers = { alc268_acer_aspire_one_mixer,
13975 alc268_beep_mixer,
13976 alc268_capture_nosrc_mixer },
13977 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13978 alc268_acer_aspire_one_verbs },
13979 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13980 .dac_nids = alc268_dac_nids,
13981 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13982 .adc_nids = alc268_adc_nids_alt,
13983 .capsrc_nids = alc268_capsrc_nids,
13984 .hp_nid = 0x03,
13985 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13986 .channel_mode = alc268_modes,
13987 .unsol_event = alc_sku_unsol_event,
13988 .setup = alc268_acer_lc_setup,
13989 .init_hook = alc_inithook,
13990 },
13991 [ALC268_DELL] = {
13992 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13993 alc268_capture_nosrc_mixer },
13994 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13995 alc268_dell_verbs },
13996 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13997 .dac_nids = alc268_dac_nids,
13998 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13999 .adc_nids = alc268_adc_nids_alt,
14000 .capsrc_nids = alc268_capsrc_nids,
14001 .hp_nid = 0x02,
14002 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14003 .channel_mode = alc268_modes,
14004 .unsol_event = alc_sku_unsol_event,
14005 .setup = alc268_dell_setup,
14006 .init_hook = alc_inithook,
14007 },
14008 [ALC268_ZEPTO] = {
14009 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
14010 alc268_beep_mixer },
14011 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14012 alc268_toshiba_verbs },
14013 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14014 .dac_nids = alc268_dac_nids,
14015 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14016 .adc_nids = alc268_adc_nids_alt,
14017 .capsrc_nids = alc268_capsrc_nids,
14018 .hp_nid = 0x03,
14019 .dig_out_nid = ALC268_DIGOUT_NID,
14020 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14021 .channel_mode = alc268_modes,
14022 .input_mux = &alc268_capture_source,
14023 .unsol_event = alc_sku_unsol_event,
14024 .setup = alc268_toshiba_setup,
14025 .init_hook = alc_inithook,
14026 },
14027#ifdef CONFIG_SND_DEBUG
14028 [ALC268_TEST] = {
14029 .mixers = { alc268_test_mixer, alc268_capture_mixer },
14030 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14031 alc268_volume_init_verbs },
14032 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14033 .dac_nids = alc268_dac_nids,
14034 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14035 .adc_nids = alc268_adc_nids_alt,
14036 .capsrc_nids = alc268_capsrc_nids,
14037 .hp_nid = 0x03,
14038 .dig_out_nid = ALC268_DIGOUT_NID,
14039 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14040 .channel_mode = alc268_modes,
14041 .input_mux = &alc268_capture_source,
14042 },
14043#endif
14044};
14045 4228
14046static int patch_alc268(struct hda_codec *codec) 4229static int patch_alc268(struct hda_codec *codec)
14047{ 4230{
@@ -14055,43 +4238,41 @@ static int patch_alc268(struct hda_codec *codec)
14055 4238
14056 codec->spec = spec; 4239 codec->spec = spec;
14057 4240
14058 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 4241 /* ALC268 has no aa-loopback mixer */
14059 alc268_models, 4242
14060 alc268_cfg_tbl); 4243 board_config = alc_board_config(codec, ALC268_MODEL_LAST,
4244 alc268_models, alc268_cfg_tbl);
14061 4245
14062 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 4246 if (board_config < 0)
14063 board_config = snd_hda_check_board_codec_sid_config(codec, 4247 board_config = alc_board_codec_sid_config(codec,
14064 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 4248 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
14065 4249
14066 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 4250 if (board_config < 0) {
14067 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4251 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14068 codec->chip_name); 4252 codec->chip_name);
14069 board_config = ALC268_AUTO; 4253 board_config = ALC_MODEL_AUTO;
14070 } 4254 }
14071 4255
14072 if (board_config == ALC268_AUTO) { 4256 if (board_config == ALC_MODEL_AUTO) {
14073 /* automatic parse from the BIOS config */ 4257 /* automatic parse from the BIOS config */
14074 err = alc268_parse_auto_config(codec); 4258 err = alc268_parse_auto_config(codec);
14075 if (err < 0) { 4259 if (err < 0) {
14076 alc_free(codec); 4260 alc_free(codec);
14077 return err; 4261 return err;
14078 } else if (!err) { 4262 }
4263#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4264 else if (!err) {
14079 printk(KERN_INFO 4265 printk(KERN_INFO
14080 "hda_codec: Cannot set up configuration " 4266 "hda_codec: Cannot set up configuration "
14081 "from BIOS. Using base mode...\n"); 4267 "from BIOS. Using base mode...\n");
14082 board_config = ALC268_3ST; 4268 board_config = ALC268_3ST;
14083 } 4269 }
4270#endif
14084 } 4271 }
14085 4272
14086 if (board_config != ALC268_AUTO) 4273 if (board_config != ALC_MODEL_AUTO)
14087 setup_preset(codec, &alc268_presets[board_config]); 4274 setup_preset(codec, &alc268_presets[board_config]);
14088 4275
14089 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14090 spec->stream_analog_capture = &alc268_pcm_analog_capture;
14091 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14092
14093 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14094
14095 has_beep = 0; 4276 has_beep = 0;
14096 for (i = 0; i < spec->num_mixers; i++) { 4277 for (i = 0; i < spec->num_mixers; i++) {
14097 if (spec->mixers[i] == alc268_beep_mixer) { 4278 if (spec->mixers[i] == alc268_beep_mixer) {
@@ -14115,35 +4296,20 @@ static int patch_alc268(struct hda_codec *codec)
14115 (0 << AC_AMPCAP_MUTE_SHIFT)); 4296 (0 << AC_AMPCAP_MUTE_SHIFT));
14116 } 4297 }
14117 4298
14118 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 4299 if (!spec->no_analog && !spec->adc_nids) {
14119 /* check whether NID 0x07 is valid */ 4300 alc_auto_fill_adc_caps(codec);
14120 unsigned int wcap = get_wcaps(codec, 0x07); 4301 alc_rebuild_imux_for_auto_mic(codec);
14121 4302 alc_remove_invalid_adc_nids(codec);
14122 spec->capsrc_nids = alc268_capsrc_nids;
14123 /* get type */
14124 wcap = get_wcaps_type(wcap);
14125 if (spec->auto_mic ||
14126 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14127 spec->adc_nids = alc268_adc_nids_alt;
14128 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14129 if (spec->auto_mic)
14130 fixup_automic_adc(codec);
14131 if (spec->auto_mic || spec->input_mux->num_items == 1)
14132 add_mixer(spec, alc268_capture_nosrc_mixer);
14133 else
14134 add_mixer(spec, alc268_capture_alt_mixer);
14135 } else {
14136 spec->adc_nids = alc268_adc_nids;
14137 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14138 add_mixer(spec, alc268_capture_mixer);
14139 }
14140 } 4303 }
14141 4304
4305 if (!spec->no_analog && !spec->cap_mixer)
4306 set_capture_mixer(codec);
4307
14142 spec->vmaster_nid = 0x02; 4308 spec->vmaster_nid = 0x02;
14143 4309
14144 codec->patch_ops = alc_patch_ops; 4310 codec->patch_ops = alc_patch_ops;
14145 if (board_config == ALC268_AUTO) 4311 if (board_config == ALC_MODEL_AUTO)
14146 spec->init_hook = alc268_auto_init; 4312 spec->init_hook = alc_auto_init_std;
14147 spec->shutup = alc_eapd_shutup; 4313 spec->shutup = alc_eapd_shutup;
14148 4314
14149 alc_init_jacks(codec); 4315 alc_init_jacks(codec);
@@ -14152,498 +4318,12 @@ static int patch_alc268(struct hda_codec *codec)
14152} 4318}
14153 4319
14154/* 4320/*
14155 * ALC269 channel source setting (2 channel) 4321 * ALC269
14156 */ 4322 */
14157#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14158
14159#define alc269_dac_nids alc260_dac_nids
14160
14161static const hda_nid_t alc269_adc_nids[1] = {
14162 /* ADC1 */
14163 0x08,
14164};
14165
14166static const hda_nid_t alc269_capsrc_nids[1] = {
14167 0x23,
14168};
14169
14170static const hda_nid_t alc269vb_adc_nids[1] = {
14171 /* ADC1 */
14172 0x09,
14173};
14174
14175static const hda_nid_t alc269vb_capsrc_nids[1] = {
14176 0x22,
14177};
14178
14179static const hda_nid_t alc269_adc_candidates[] = {
14180 0x08, 0x09, 0x07, 0x11,
14181};
14182
14183#define alc269_modes alc260_modes
14184#define alc269_capture_source alc880_lg_lw_capture_source
14185
14186static const struct snd_kcontrol_new alc269_base_mixer[] = {
14187 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14188 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14189 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14190 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14191 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14192 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14194 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14195 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14196 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14197 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14198 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14199 { } /* end */
14200};
14201
14202static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14203 /* output mixer control */
14204 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14205 {
14206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14207 .name = "Master Playback Switch",
14208 .subdevice = HDA_SUBDEV_AMP_FLAG,
14209 .info = snd_hda_mixer_amp_switch_info,
14210 .get = snd_hda_mixer_amp_switch_get,
14211 .put = alc268_acer_master_sw_put,
14212 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14213 },
14214 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14216 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14217 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14218 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14219 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14220 { }
14221};
14222
14223static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14224 /* output mixer control */
14225 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14226 {
14227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14228 .name = "Master Playback Switch",
14229 .subdevice = HDA_SUBDEV_AMP_FLAG,
14230 .info = snd_hda_mixer_amp_switch_info,
14231 .get = snd_hda_mixer_amp_switch_get,
14232 .put = alc268_acer_master_sw_put,
14233 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14234 },
14235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14236 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14237 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14238 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14239 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14240 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14241 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14242 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14243 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14244 { }
14245};
14246
14247static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
14248 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14249 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14250 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14251 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14252 { } /* end */
14253};
14254
14255static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14256 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14257 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14259 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14260 { } /* end */
14261};
14262
14263static const struct snd_kcontrol_new alc269_asus_mixer[] = {
14264 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14265 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14266 { } /* end */
14267};
14268
14269/* capture mixer elements */
14270static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14271 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14272 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14274 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14275 { } /* end */
14276};
14277
14278static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14279 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14280 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14281 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14282 { } /* end */
14283};
14284
14285static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14286 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14287 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14288 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14289 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14290 { } /* end */
14291};
14292
14293static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14294 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14295 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14296 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14297 { } /* end */
14298};
14299
14300/* FSC amilo */
14301#define alc269_fujitsu_mixer alc269_laptop_mixer
14302
14303static const struct hda_verb alc269_quanta_fl1_verbs[] = {
14304 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14305 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14306 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14307 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14308 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14309 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14310 { }
14311};
14312
14313static const struct hda_verb alc269_lifebook_verbs[] = {
14314 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14315 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14316 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14317 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14318 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14319 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14320 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14321 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14322 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14323 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14324 { }
14325};
14326
14327/* toggle speaker-output according to the hp-jack state */
14328static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14329{
14330 alc_hp_automute(codec);
14331
14332 snd_hda_codec_write(codec, 0x20, 0,
14333 AC_VERB_SET_COEF_INDEX, 0x0c);
14334 snd_hda_codec_write(codec, 0x20, 0,
14335 AC_VERB_SET_PROC_COEF, 0x680);
14336
14337 snd_hda_codec_write(codec, 0x20, 0,
14338 AC_VERB_SET_COEF_INDEX, 0x0c);
14339 snd_hda_codec_write(codec, 0x20, 0,
14340 AC_VERB_SET_PROC_COEF, 0x480);
14341}
14342
14343#define alc269_lifebook_speaker_automute \
14344 alc269_quanta_fl1_speaker_automute
14345
14346static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14347{
14348 unsigned int present_laptop;
14349 unsigned int present_dock;
14350
14351 present_laptop = snd_hda_jack_detect(codec, 0x18);
14352 present_dock = snd_hda_jack_detect(codec, 0x1b);
14353
14354 /* Laptop mic port overrides dock mic port, design decision */
14355 if (present_dock)
14356 snd_hda_codec_write(codec, 0x23, 0,
14357 AC_VERB_SET_CONNECT_SEL, 0x3);
14358 if (present_laptop)
14359 snd_hda_codec_write(codec, 0x23, 0,
14360 AC_VERB_SET_CONNECT_SEL, 0x0);
14361 if (!present_dock && !present_laptop)
14362 snd_hda_codec_write(codec, 0x23, 0,
14363 AC_VERB_SET_CONNECT_SEL, 0x1);
14364}
14365
14366static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14367 unsigned int res)
14368{
14369 switch (res >> 26) {
14370 case ALC880_HP_EVENT:
14371 alc269_quanta_fl1_speaker_automute(codec);
14372 break;
14373 case ALC880_MIC_EVENT:
14374 alc_mic_automute(codec);
14375 break;
14376 }
14377}
14378
14379static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14380 unsigned int res)
14381{
14382 if ((res >> 26) == ALC880_HP_EVENT)
14383 alc269_lifebook_speaker_automute(codec);
14384 if ((res >> 26) == ALC880_MIC_EVENT)
14385 alc269_lifebook_mic_autoswitch(codec);
14386}
14387
14388static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14389{
14390 struct alc_spec *spec = codec->spec;
14391 spec->autocfg.hp_pins[0] = 0x15;
14392 spec->autocfg.speaker_pins[0] = 0x14;
14393 spec->automute_mixer_nid[0] = 0x0c;
14394 spec->automute = 1;
14395 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14396 spec->ext_mic.pin = 0x18;
14397 spec->ext_mic.mux_idx = 0;
14398 spec->int_mic.pin = 0x19;
14399 spec->int_mic.mux_idx = 1;
14400 spec->auto_mic = 1;
14401}
14402
14403static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14404{
14405 alc269_quanta_fl1_speaker_automute(codec);
14406 alc_mic_automute(codec);
14407}
14408
14409static void alc269_lifebook_setup(struct hda_codec *codec)
14410{
14411 struct alc_spec *spec = codec->spec;
14412 spec->autocfg.hp_pins[0] = 0x15;
14413 spec->autocfg.hp_pins[1] = 0x1a;
14414 spec->autocfg.speaker_pins[0] = 0x14;
14415 spec->automute_mixer_nid[0] = 0x0c;
14416 spec->automute = 1;
14417 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14418}
14419
14420static void alc269_lifebook_init_hook(struct hda_codec *codec)
14421{
14422 alc269_lifebook_speaker_automute(codec);
14423 alc269_lifebook_mic_autoswitch(codec);
14424}
14425
14426static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14427 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14428 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14429 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14431 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14432 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14433 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14434 {}
14435};
14436
14437static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
14438 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14439 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14440 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14441 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14442 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14443 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14444 {}
14445};
14446
14447static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14448 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14449 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14450 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14451 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14453 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14454 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14455 {}
14456};
14457
14458static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14459 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14460 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14461 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14462 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14463 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14464 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14465 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14466 {}
14467};
14468
14469static const struct hda_verb alc271_acer_dmic_verbs[] = {
14470 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14471 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14472 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14473 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14474 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14475 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14476 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14477 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14478 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14479 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14480 { }
14481};
14482
14483static void alc269_laptop_amic_setup(struct hda_codec *codec)
14484{
14485 struct alc_spec *spec = codec->spec;
14486 spec->autocfg.hp_pins[0] = 0x15;
14487 spec->autocfg.speaker_pins[0] = 0x14;
14488 spec->automute_mixer_nid[0] = 0x0c;
14489 spec->automute = 1;
14490 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14491 spec->ext_mic.pin = 0x18;
14492 spec->ext_mic.mux_idx = 0;
14493 spec->int_mic.pin = 0x19;
14494 spec->int_mic.mux_idx = 1;
14495 spec->auto_mic = 1;
14496}
14497
14498static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14499{
14500 struct alc_spec *spec = codec->spec;
14501 spec->autocfg.hp_pins[0] = 0x15;
14502 spec->autocfg.speaker_pins[0] = 0x14;
14503 spec->automute_mixer_nid[0] = 0x0c;
14504 spec->automute = 1;
14505 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14506 spec->ext_mic.pin = 0x18;
14507 spec->ext_mic.mux_idx = 0;
14508 spec->int_mic.pin = 0x12;
14509 spec->int_mic.mux_idx = 5;
14510 spec->auto_mic = 1;
14511}
14512
14513static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14514{
14515 struct alc_spec *spec = codec->spec;
14516 spec->autocfg.hp_pins[0] = 0x21;
14517 spec->autocfg.speaker_pins[0] = 0x14;
14518 spec->automute_mixer_nid[0] = 0x0c;
14519 spec->automute = 1;
14520 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14521 spec->ext_mic.pin = 0x18;
14522 spec->ext_mic.mux_idx = 0;
14523 spec->int_mic.pin = 0x19;
14524 spec->int_mic.mux_idx = 1;
14525 spec->auto_mic = 1;
14526}
14527
14528static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14529{
14530 struct alc_spec *spec = codec->spec;
14531 spec->autocfg.hp_pins[0] = 0x21;
14532 spec->autocfg.speaker_pins[0] = 0x14;
14533 spec->automute_mixer_nid[0] = 0x0c;
14534 spec->automute = 1;
14535 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14536 spec->ext_mic.pin = 0x18;
14537 spec->ext_mic.mux_idx = 0;
14538 spec->int_mic.pin = 0x12;
14539 spec->int_mic.mux_idx = 6;
14540 spec->auto_mic = 1;
14541}
14542
14543/*
14544 * generic initialization of ADC, input mixers and output mixers
14545 */
14546static const struct hda_verb alc269_init_verbs[] = {
14547 /*
14548 * Unmute ADC0 and set the default input to mic-in
14549 */
14550 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14551
14552 /*
14553 * Set up output mixers (0x02 - 0x03)
14554 */
14555 /* set vol=0 to output mixers */
14556 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14557 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14558
14559 /* set up input amps for analog loopback */
14560 /* Amp Indices: DAC = 0, mixer = 1 */
14561 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14563 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14564 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14565 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14566 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14567
14568 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14570 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14571 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14572 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14573 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14574 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14575
14576 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14578
14579 /* FIXME: use Mux-type input source selection */
14580 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14581 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14582 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14583
14584 /* set EAPD */
14585 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14586 { }
14587};
14588
14589static const struct hda_verb alc269vb_init_verbs[] = {
14590 /*
14591 * Unmute ADC0 and set the default input to mic-in
14592 */
14593 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14594
14595 /*
14596 * Set up output mixers (0x02 - 0x03)
14597 */
14598 /* set vol=0 to output mixers */
14599 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14600 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14601
14602 /* set up input amps for analog loopback */
14603 /* Amp Indices: DAC = 0, mixer = 1 */
14604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14608 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14609 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14610
14611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14612 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14613 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14614 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14615 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14616 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14618
14619 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14620 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14621
14622 /* FIXME: use Mux-type input source selection */
14623 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14624 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14625 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14626
14627 /* set EAPD */
14628 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14629 { }
14630};
14631
14632#define alc269_auto_create_multi_out_ctls \
14633 alc268_auto_create_multi_out_ctls
14634#define alc269_auto_create_input_ctls \
14635 alc268_auto_create_input_ctls
14636
14637#ifdef CONFIG_SND_HDA_POWER_SAVE 4323#ifdef CONFIG_SND_HDA_POWER_SAVE
14638#define alc269_loopbacks alc880_loopbacks 4324#define alc269_loopbacks alc880_loopbacks
14639#endif 4325#endif
14640 4326
14641/* pcm configuration: identical with ALC880 */
14642#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14643#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14644#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14645#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14646
14647static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 4327static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14648 .substreams = 1, 4328 .substreams = 1,
14649 .channels_min = 2, 4329 .channels_min = 2,
@@ -14651,9 +4331,9 @@ static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14651 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 4331 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14652 /* NID is set in alc_build_pcms */ 4332 /* NID is set in alc_build_pcms */
14653 .ops = { 4333 .ops = {
14654 .open = alc880_playback_pcm_open, 4334 .open = alc_playback_pcm_open,
14655 .prepare = alc880_playback_pcm_prepare, 4335 .prepare = alc_playback_pcm_prepare,
14656 .cleanup = alc880_playback_pcm_cleanup 4336 .cleanup = alc_playback_pcm_cleanup
14657 }, 4337 },
14658}; 4338};
14659 4339
@@ -14694,44 +4374,11 @@ static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14694} 4374}
14695#endif /* CONFIG_SND_HDA_POWER_SAVE */ 4375#endif /* CONFIG_SND_HDA_POWER_SAVE */
14696 4376
14697static int alc275_setup_dual_adc(struct hda_codec *codec)
14698{
14699 struct alc_spec *spec = codec->spec;
14700
14701 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14702 return 0;
14703 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14704 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14705 if (spec->ext_mic.pin <= 0x12) {
14706 spec->private_adc_nids[0] = 0x08;
14707 spec->private_adc_nids[1] = 0x11;
14708 spec->private_capsrc_nids[0] = 0x23;
14709 spec->private_capsrc_nids[1] = 0x22;
14710 } else {
14711 spec->private_adc_nids[0] = 0x11;
14712 spec->private_adc_nids[1] = 0x08;
14713 spec->private_capsrc_nids[0] = 0x22;
14714 spec->private_capsrc_nids[1] = 0x23;
14715 }
14716 spec->adc_nids = spec->private_adc_nids;
14717 spec->capsrc_nids = spec->private_capsrc_nids;
14718 spec->num_adc_nids = 2;
14719 spec->dual_adc_switch = 1;
14720 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14721 spec->adc_nids[0], spec->adc_nids[1]);
14722 return 1;
14723 }
14724 return 0;
14725}
14726
14727/* different alc269-variants */ 4377/* different alc269-variants */
14728enum { 4378enum {
14729 ALC269_TYPE_NORMAL, 4379 ALC269_TYPE_ALC269VA,
14730 ALC269_TYPE_ALC258,
14731 ALC269_TYPE_ALC259,
14732 ALC269_TYPE_ALC269VB, 4380 ALC269_TYPE_ALC269VB,
14733 ALC269_TYPE_ALC270, 4381 ALC269_TYPE_ALC269VC,
14734 ALC269_TYPE_ALC271X,
14735}; 4382};
14736 4383
14737/* 4384/*
@@ -14739,76 +4386,14 @@ enum {
14739 */ 4386 */
14740static int alc269_parse_auto_config(struct hda_codec *codec) 4387static int alc269_parse_auto_config(struct hda_codec *codec)
14741{ 4388{
14742 struct alc_spec *spec = codec->spec;
14743 int err;
14744 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 4389 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14745 4390 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
14746 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4391 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
14747 alc269_ignore);
14748 if (err < 0)
14749 return err;
14750
14751 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14752 if (err < 0)
14753 return err;
14754 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14755 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14756 else
14757 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14758 0x22, 0);
14759 if (err < 0)
14760 return err;
14761
14762 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14763
14764 alc_auto_parse_digital(codec);
14765
14766 if (spec->kctls.list)
14767 add_mixer(spec, spec->kctls.list);
14768
14769 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14770 add_verb(spec, alc269vb_init_verbs);
14771 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14772 } else {
14773 add_verb(spec, alc269_init_verbs);
14774 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14775 }
14776
14777 spec->num_mux_defs = 1;
14778 spec->input_mux = &spec->private_imux[0];
14779
14780 if (!alc275_setup_dual_adc(codec))
14781 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14782 sizeof(alc269_adc_candidates));
14783
14784 err = alc_auto_add_mic_boost(codec);
14785 if (err < 0)
14786 return err;
14787
14788 if (!spec->cap_mixer && !spec->no_analog)
14789 set_capture_mixer(codec);
14790
14791 return 1;
14792}
14793
14794#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14795#define alc269_auto_init_hp_out alc268_auto_init_hp_out
14796#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14797#define alc269_auto_init_input_src alc882_auto_init_input_src
14798
14799
14800/* init callback for auto-configuration model -- overriding the default init */
14801static void alc269_auto_init(struct hda_codec *codec)
14802{
14803 struct alc_spec *spec = codec->spec; 4392 struct alc_spec *spec = codec->spec;
14804 alc269_auto_init_multi_out(codec); 4393 const hda_nid_t *ssids = spec->codec_variant == ALC269_TYPE_ALC269VA ?
14805 alc269_auto_init_hp_out(codec); 4394 alc269va_ssids : alc269_ssids;
14806 alc269_auto_init_analog_input(codec); 4395
14807 if (!spec->dual_adc_switch) 4396 return alc_parse_auto_config(codec, alc269_ignore, ssids);
14808 alc269_auto_init_input_src(codec);
14809 alc_auto_init_digital(codec);
14810 if (spec->unsol_event)
14811 alc_inithook(codec);
14812} 4397}
14813 4398
14814static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) 4399static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
@@ -14831,7 +4416,7 @@ static void alc269_shutup(struct hda_codec *codec)
14831 } 4416 }
14832} 4417}
14833 4418
14834#ifdef SND_HDA_NEEDS_RESUME 4419#ifdef CONFIG_PM
14835static int alc269_resume(struct hda_codec *codec) 4420static int alc269_resume(struct hda_codec *codec)
14836{ 4421{
14837 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 4422 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
@@ -14854,7 +4439,7 @@ static int alc269_resume(struct hda_codec *codec)
14854 hda_call_check_power_status(codec, 0x01); 4439 hda_call_check_power_status(codec, 0x01);
14855 return 0; 4440 return 0;
14856} 4441}
14857#endif /* SND_HDA_NEEDS_RESUME */ 4442#endif /* CONFIG_PM */
14858 4443
14859static void alc269_fixup_hweq(struct hda_codec *codec, 4444static void alc269_fixup_hweq(struct hda_codec *codec,
14860 const struct alc_fixup *fix, int action) 4445 const struct alc_fixup *fix, int action)
@@ -14884,6 +4469,21 @@ static void alc271_fixup_dmic(struct hda_codec *codec,
14884 snd_hda_sequence_write(codec, verbs); 4469 snd_hda_sequence_write(codec, verbs);
14885} 4470}
14886 4471
4472static void alc269_fixup_pcm_44k(struct hda_codec *codec,
4473 const struct alc_fixup *fix, int action)
4474{
4475 struct alc_spec *spec = codec->spec;
4476
4477 if (action != ALC_FIXUP_ACT_PROBE)
4478 return;
4479
4480 /* Due to a hardware problem on Lenovo Ideadpad, we need to
4481 * fix the sample rate of analog I/O to 44.1kHz
4482 */
4483 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
4484 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
4485}
4486
14887enum { 4487enum {
14888 ALC269_FIXUP_SONY_VAIO, 4488 ALC269_FIXUP_SONY_VAIO,
14889 ALC275_FIXUP_SONY_VAIO_GPIO2, 4489 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -14893,6 +4493,7 @@ enum {
14893 ALC269_FIXUP_LENOVO_EAPD, 4493 ALC269_FIXUP_LENOVO_EAPD,
14894 ALC275_FIXUP_SONY_HWEQ, 4494 ALC275_FIXUP_SONY_HWEQ,
14895 ALC271_FIXUP_DMIC, 4495 ALC271_FIXUP_DMIC,
4496 ALC269_FIXUP_PCM_44K,
14896}; 4497};
14897 4498
14898static const struct alc_fixup alc269_fixups[] = { 4499static const struct alc_fixup alc269_fixups[] = {
@@ -14951,9 +4552,14 @@ static const struct alc_fixup alc269_fixups[] = {
14951 .type = ALC_FIXUP_FUNC, 4552 .type = ALC_FIXUP_FUNC,
14952 .v.func = alc271_fixup_dmic, 4553 .v.func = alc271_fixup_dmic,
14953 }, 4554 },
4555 [ALC269_FIXUP_PCM_44K] = {
4556 .type = ALC_FIXUP_FUNC,
4557 .v.func = alc269_fixup_pcm_44k,
4558 },
14954}; 4559};
14955 4560
14956static const struct snd_pci_quirk alc269_fixup_tbl[] = { 4561static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4562 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14957 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), 4563 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14958 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 4564 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14959 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 4565 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
@@ -14965,209 +4571,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14965 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 4571 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14966 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), 4572 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14967 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), 4573 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14968 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 4574 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
14969 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 4575 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14970 {} 4576 {}
14971}; 4577};
14972 4578
14973 4579
14974/*
14975 * configuration and preset
14976 */
14977static const char * const alc269_models[ALC269_MODEL_LAST] = {
14978 [ALC269_BASIC] = "basic",
14979 [ALC269_QUANTA_FL1] = "quanta",
14980 [ALC269_AMIC] = "laptop-amic",
14981 [ALC269_DMIC] = "laptop-dmic",
14982 [ALC269_FUJITSU] = "fujitsu",
14983 [ALC269_LIFEBOOK] = "lifebook",
14984 [ALC269_AUTO] = "auto",
14985};
14986
14987static const struct snd_pci_quirk alc269_cfg_tbl[] = {
14988 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14989 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14990 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14991 ALC269_AMIC),
14992 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14993 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14994 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14995 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14996 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14997 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14998 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14999 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15000 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
15001 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
15002 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15003 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15004 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15005 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15006 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15007 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15008 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15009 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15010 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15011 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15012 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15013 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15014 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15015 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15016 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15017 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15018 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15019 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15020 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15021 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15022 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15023 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15024 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15025 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15026 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15027 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
15028 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
15029 ALC269_DMIC),
15030 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
15031 ALC269_DMIC),
15032 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15033 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
15034 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
15035 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
15036 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15037 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15038 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15039 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15040 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15041 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
15042 {}
15043};
15044
15045static const struct alc_config_preset alc269_presets[] = {
15046 [ALC269_BASIC] = {
15047 .mixers = { alc269_base_mixer },
15048 .init_verbs = { alc269_init_verbs },
15049 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15050 .dac_nids = alc269_dac_nids,
15051 .hp_nid = 0x03,
15052 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15053 .channel_mode = alc269_modes,
15054 .input_mux = &alc269_capture_source,
15055 },
15056 [ALC269_QUANTA_FL1] = {
15057 .mixers = { alc269_quanta_fl1_mixer },
15058 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15059 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15060 .dac_nids = alc269_dac_nids,
15061 .hp_nid = 0x03,
15062 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15063 .channel_mode = alc269_modes,
15064 .input_mux = &alc269_capture_source,
15065 .unsol_event = alc269_quanta_fl1_unsol_event,
15066 .setup = alc269_quanta_fl1_setup,
15067 .init_hook = alc269_quanta_fl1_init_hook,
15068 },
15069 [ALC269_AMIC] = {
15070 .mixers = { alc269_laptop_mixer },
15071 .cap_mixer = alc269_laptop_analog_capture_mixer,
15072 .init_verbs = { alc269_init_verbs,
15073 alc269_laptop_amic_init_verbs },
15074 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15075 .dac_nids = alc269_dac_nids,
15076 .hp_nid = 0x03,
15077 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15078 .channel_mode = alc269_modes,
15079 .unsol_event = alc_sku_unsol_event,
15080 .setup = alc269_laptop_amic_setup,
15081 .init_hook = alc_inithook,
15082 },
15083 [ALC269_DMIC] = {
15084 .mixers = { alc269_laptop_mixer },
15085 .cap_mixer = alc269_laptop_digital_capture_mixer,
15086 .init_verbs = { alc269_init_verbs,
15087 alc269_laptop_dmic_init_verbs },
15088 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15089 .dac_nids = alc269_dac_nids,
15090 .hp_nid = 0x03,
15091 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15092 .channel_mode = alc269_modes,
15093 .unsol_event = alc_sku_unsol_event,
15094 .setup = alc269_laptop_dmic_setup,
15095 .init_hook = alc_inithook,
15096 },
15097 [ALC269VB_AMIC] = {
15098 .mixers = { alc269vb_laptop_mixer },
15099 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15100 .init_verbs = { alc269vb_init_verbs,
15101 alc269vb_laptop_amic_init_verbs },
15102 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15103 .dac_nids = alc269_dac_nids,
15104 .hp_nid = 0x03,
15105 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15106 .channel_mode = alc269_modes,
15107 .unsol_event = alc_sku_unsol_event,
15108 .setup = alc269vb_laptop_amic_setup,
15109 .init_hook = alc_inithook,
15110 },
15111 [ALC269VB_DMIC] = {
15112 .mixers = { alc269vb_laptop_mixer },
15113 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15114 .init_verbs = { alc269vb_init_verbs,
15115 alc269vb_laptop_dmic_init_verbs },
15116 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15117 .dac_nids = alc269_dac_nids,
15118 .hp_nid = 0x03,
15119 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15120 .channel_mode = alc269_modes,
15121 .unsol_event = alc_sku_unsol_event,
15122 .setup = alc269vb_laptop_dmic_setup,
15123 .init_hook = alc_inithook,
15124 },
15125 [ALC269_FUJITSU] = {
15126 .mixers = { alc269_fujitsu_mixer },
15127 .cap_mixer = alc269_laptop_digital_capture_mixer,
15128 .init_verbs = { alc269_init_verbs,
15129 alc269_laptop_dmic_init_verbs },
15130 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15131 .dac_nids = alc269_dac_nids,
15132 .hp_nid = 0x03,
15133 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15134 .channel_mode = alc269_modes,
15135 .unsol_event = alc_sku_unsol_event,
15136 .setup = alc269_laptop_dmic_setup,
15137 .init_hook = alc_inithook,
15138 },
15139 [ALC269_LIFEBOOK] = {
15140 .mixers = { alc269_lifebook_mixer },
15141 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15142 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15143 .dac_nids = alc269_dac_nids,
15144 .hp_nid = 0x03,
15145 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15146 .channel_mode = alc269_modes,
15147 .input_mux = &alc269_capture_source,
15148 .unsol_event = alc269_lifebook_unsol_event,
15149 .setup = alc269_lifebook_setup,
15150 .init_hook = alc269_lifebook_init_hook,
15151 },
15152 [ALC271_ACER] = {
15153 .mixers = { alc269_asus_mixer },
15154 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15155 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15156 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15157 .dac_nids = alc269_dac_nids,
15158 .adc_nids = alc262_dmic_adc_nids,
15159 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15160 .capsrc_nids = alc262_dmic_capsrc_nids,
15161 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15162 .channel_mode = alc269_modes,
15163 .input_mux = &alc269_capture_source,
15164 .dig_out_nid = ALC880_DIGOUT_NID,
15165 .unsol_event = alc_sku_unsol_event,
15166 .setup = alc269vb_laptop_dmic_setup,
15167 .init_hook = alc_inithook,
15168 },
15169};
15170
15171static int alc269_fill_coef(struct hda_codec *codec) 4580static int alc269_fill_coef(struct hda_codec *codec)
15172{ 4581{
15173 int val; 4582 int val;
@@ -15210,6 +4619,12 @@ static int alc269_fill_coef(struct hda_codec *codec)
15210 return 0; 4619 return 0;
15211} 4620}
15212 4621
4622/*
4623 */
4624#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4625#include "alc269_quirks.c"
4626#endif
4627
15213static int patch_alc269(struct hda_codec *codec) 4628static int patch_alc269(struct hda_codec *codec)
15214{ 4629{
15215 struct alc_spec *spec; 4630 struct alc_spec *spec;
@@ -15222,116 +4637,105 @@ static int patch_alc269(struct hda_codec *codec)
15222 4637
15223 codec->spec = spec; 4638 codec->spec = spec;
15224 4639
4640 spec->mixer_nid = 0x0b;
4641
15225 alc_auto_parse_customize_define(codec); 4642 alc_auto_parse_customize_define(codec);
15226 4643
15227 if (codec->vendor_id == 0x10ec0269) { 4644 if (codec->vendor_id == 0x10ec0269) {
4645 spec->codec_variant = ALC269_TYPE_ALC269VA;
15228 coef = alc_read_coef_idx(codec, 0); 4646 coef = alc_read_coef_idx(codec, 0);
15229 if ((coef & 0x00f0) == 0x0010) { 4647 if ((coef & 0x00f0) == 0x0010) {
15230 if (codec->bus->pci->subsystem_vendor == 0x1025 && 4648 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15231 spec->cdefine.platform_type == 1) { 4649 spec->cdefine.platform_type == 1) {
15232 alc_codec_rename(codec, "ALC271X"); 4650 alc_codec_rename(codec, "ALC271X");
15233 spec->codec_variant = ALC269_TYPE_ALC271X;
15234 } else if ((coef & 0xf000) == 0x1000) {
15235 spec->codec_variant = ALC269_TYPE_ALC270;
15236 } else if ((coef & 0xf000) == 0x2000) { 4651 } else if ((coef & 0xf000) == 0x2000) {
15237 alc_codec_rename(codec, "ALC259"); 4652 alc_codec_rename(codec, "ALC259");
15238 spec->codec_variant = ALC269_TYPE_ALC259;
15239 } else if ((coef & 0xf000) == 0x3000) { 4653 } else if ((coef & 0xf000) == 0x3000) {
15240 alc_codec_rename(codec, "ALC258"); 4654 alc_codec_rename(codec, "ALC258");
15241 spec->codec_variant = ALC269_TYPE_ALC258; 4655 } else if ((coef & 0xfff0) == 0x3010) {
4656 alc_codec_rename(codec, "ALC277");
15242 } else { 4657 } else {
15243 alc_codec_rename(codec, "ALC269VB"); 4658 alc_codec_rename(codec, "ALC269VB");
15244 spec->codec_variant = ALC269_TYPE_ALC269VB;
15245 } 4659 }
4660 spec->codec_variant = ALC269_TYPE_ALC269VB;
4661 } else if ((coef & 0x00f0) == 0x0020) {
4662 if (coef == 0xa023)
4663 alc_codec_rename(codec, "ALC259");
4664 else if (coef == 0x6023)
4665 alc_codec_rename(codec, "ALC281X");
4666 else if (codec->bus->pci->subsystem_vendor == 0x17aa &&
4667 codec->bus->pci->subsystem_device == 0x21f3)
4668 alc_codec_rename(codec, "ALC3202");
4669 else
4670 alc_codec_rename(codec, "ALC269VC");
4671 spec->codec_variant = ALC269_TYPE_ALC269VC;
15246 } else 4672 } else
15247 alc_fix_pll_init(codec, 0x20, 0x04, 15); 4673 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15248 alc269_fill_coef(codec); 4674 alc269_fill_coef(codec);
15249 } 4675 }
15250 4676
15251 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 4677 board_config = alc_board_config(codec, ALC269_MODEL_LAST,
15252 alc269_models, 4678 alc269_models, alc269_cfg_tbl);
15253 alc269_cfg_tbl);
15254 4679
15255 if (board_config < 0) { 4680 if (board_config < 0) {
15256 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4681 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15257 codec->chip_name); 4682 codec->chip_name);
15258 board_config = ALC269_AUTO; 4683 board_config = ALC_MODEL_AUTO;
15259 } 4684 }
15260 4685
15261 if (board_config == ALC269_AUTO) { 4686 if (board_config == ALC_MODEL_AUTO) {
15262 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups); 4687 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15263 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4688 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15264 } 4689 }
15265 4690
15266 if (board_config == ALC269_AUTO) { 4691 if (board_config == ALC_MODEL_AUTO) {
15267 /* automatic parse from the BIOS config */ 4692 /* automatic parse from the BIOS config */
15268 err = alc269_parse_auto_config(codec); 4693 err = alc269_parse_auto_config(codec);
15269 if (err < 0) { 4694 if (err < 0) {
15270 alc_free(codec); 4695 alc_free(codec);
15271 return err; 4696 return err;
15272 } else if (!err) { 4697 }
4698#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4699 else if (!err) {
15273 printk(KERN_INFO 4700 printk(KERN_INFO
15274 "hda_codec: Cannot set up configuration " 4701 "hda_codec: Cannot set up configuration "
15275 "from BIOS. Using base mode...\n"); 4702 "from BIOS. Using base mode...\n");
15276 board_config = ALC269_BASIC; 4703 board_config = ALC269_BASIC;
15277 } 4704 }
4705#endif
15278 } 4706 }
15279 4707
15280 if (has_cdefine_beep(codec)) { 4708 if (board_config != ALC_MODEL_AUTO)
15281 err = snd_hda_attach_beep_device(codec, 0x1);
15282 if (err < 0) {
15283 alc_free(codec);
15284 return err;
15285 }
15286 }
15287
15288 if (board_config != ALC269_AUTO)
15289 setup_preset(codec, &alc269_presets[board_config]); 4709 setup_preset(codec, &alc269_presets[board_config]);
15290 4710
15291 if (board_config == ALC269_QUANTA_FL1) { 4711 if (!spec->no_analog && !spec->adc_nids) {
15292 /* Due to a hardware problem on Lenovo Ideadpad, we need to 4712 alc_auto_fill_adc_caps(codec);
15293 * fix the sample rate of analog I/O to 44.1kHz 4713 alc_rebuild_imux_for_auto_mic(codec);
15294 */ 4714 alc_remove_invalid_adc_nids(codec);
15295 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15296 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15297 } else if (spec->dual_adc_switch) {
15298 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15299 /* switch ADC dynamically */
15300 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15301 } else {
15302 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15303 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15304 }
15305 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15306 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15307
15308 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15309 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15310 spec->adc_nids = alc269_adc_nids;
15311 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15312 spec->capsrc_nids = alc269_capsrc_nids;
15313 } else {
15314 spec->adc_nids = alc269vb_adc_nids;
15315 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15316 spec->capsrc_nids = alc269vb_capsrc_nids;
15317 }
15318 } 4715 }
15319 4716
15320 if (!spec->cap_mixer) 4717 if (!spec->no_analog && !spec->cap_mixer)
15321 set_capture_mixer(codec); 4718 set_capture_mixer(codec);
15322 if (has_cdefine_beep(codec)) 4719
4720 if (!spec->no_analog && has_cdefine_beep(codec)) {
4721 err = snd_hda_attach_beep_device(codec, 0x1);
4722 if (err < 0) {
4723 alc_free(codec);
4724 return err;
4725 }
15323 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 4726 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
4727 }
15324 4728
15325 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4729 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15326 4730
15327 spec->vmaster_nid = 0x02; 4731 spec->vmaster_nid = 0x02;
15328 4732
15329 codec->patch_ops = alc_patch_ops; 4733 codec->patch_ops = alc_patch_ops;
15330#ifdef SND_HDA_NEEDS_RESUME 4734#ifdef CONFIG_PM
15331 codec->patch_ops.resume = alc269_resume; 4735 codec->patch_ops.resume = alc269_resume;
15332#endif 4736#endif
15333 if (board_config == ALC269_AUTO) 4737 if (board_config == ALC_MODEL_AUTO)
15334 spec->init_hook = alc269_auto_init; 4738 spec->init_hook = alc_auto_init_std;
15335 spec->shutup = alc269_shutup; 4739 spec->shutup = alc269_shutup;
15336 4740
15337 alc_init_jacks(codec); 4741 alc_init_jacks(codec);
@@ -15346,883 +4750,14 @@ static int patch_alc269(struct hda_codec *codec)
15346} 4750}
15347 4751
15348/* 4752/*
15349 * ALC861 channel source setting (2/6 channel selection for 3-stack) 4753 * ALC861
15350 */
15351
15352/*
15353 * set the path ways for 2 channel output
15354 * need to set the codec line out and mic 1 pin widgets to inputs
15355 */
15356static const struct hda_verb alc861_threestack_ch2_init[] = {
15357 /* set pin widget 1Ah (line in) for input */
15358 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15359 /* set pin widget 18h (mic1/2) for input, for mic also enable
15360 * the vref
15361 */
15362 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15363
15364 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15365#if 0
15366 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15367 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15368#endif
15369 { } /* end */
15370};
15371/*
15372 * 6ch mode
15373 * need to set the codec line out and mic 1 pin widgets to outputs
15374 */
15375static const struct hda_verb alc861_threestack_ch6_init[] = {
15376 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15377 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15378 /* set pin widget 18h (mic1) for output (CLFE)*/
15379 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15380
15381 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15382 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15383
15384 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15385#if 0
15386 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15387 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15388#endif
15389 { } /* end */
15390};
15391
15392static const struct hda_channel_mode alc861_threestack_modes[2] = {
15393 { 2, alc861_threestack_ch2_init },
15394 { 6, alc861_threestack_ch6_init },
15395};
15396/* Set mic1 as input and unmute the mixer */
15397static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15398 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15399 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15400 { } /* end */
15401};
15402/* Set mic1 as output and mute mixer */
15403static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15404 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15405 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15406 { } /* end */
15407};
15408
15409static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15410 { 2, alc861_uniwill_m31_ch2_init },
15411 { 4, alc861_uniwill_m31_ch4_init },
15412};
15413
15414/* Set mic1 and line-in as input and unmute the mixer */
15415static const struct hda_verb alc861_asus_ch2_init[] = {
15416 /* set pin widget 1Ah (line in) for input */
15417 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15418 /* set pin widget 18h (mic1/2) for input, for mic also enable
15419 * the vref
15420 */
15421 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15422
15423 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15424#if 0
15425 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15426 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15427#endif
15428 { } /* end */
15429};
15430/* Set mic1 nad line-in as output and mute mixer */
15431static const struct hda_verb alc861_asus_ch6_init[] = {
15432 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15433 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15434 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15435 /* set pin widget 18h (mic1) for output (CLFE)*/
15436 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15437 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15438 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15439 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15440
15441 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15442#if 0
15443 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15444 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15445#endif
15446 { } /* end */
15447};
15448
15449static const struct hda_channel_mode alc861_asus_modes[2] = {
15450 { 2, alc861_asus_ch2_init },
15451 { 6, alc861_asus_ch6_init },
15452};
15453
15454/* patch-ALC861 */
15455
15456static const struct snd_kcontrol_new alc861_base_mixer[] = {
15457 /* output mixer control */
15458 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15459 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15460 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15461 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15462 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15463
15464 /*Input mixer control */
15465 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15466 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15467 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15468 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15469 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15470 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15472 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15473 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15474 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15475
15476 { } /* end */
15477};
15478
15479static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
15480 /* output mixer control */
15481 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15482 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15483 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15484 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15485 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15486
15487 /* Input mixer control */
15488 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15489 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15490 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15491 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15492 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15493 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15495 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15496 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15497 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15498
15499 {
15500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15501 .name = "Channel Mode",
15502 .info = alc_ch_mode_info,
15503 .get = alc_ch_mode_get,
15504 .put = alc_ch_mode_put,
15505 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15506 },
15507 { } /* end */
15508};
15509
15510static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15511 /* output mixer control */
15512 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15514 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15515
15516 { } /* end */
15517};
15518
15519static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15520 /* output mixer control */
15521 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15522 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15523 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15524 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15525 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15526
15527 /* Input mixer control */
15528 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15529 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15530 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15531 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15532 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15533 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15535 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15536 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15537 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15538
15539 {
15540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15541 .name = "Channel Mode",
15542 .info = alc_ch_mode_info,
15543 .get = alc_ch_mode_get,
15544 .put = alc_ch_mode_put,
15545 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15546 },
15547 { } /* end */
15548};
15549
15550static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15551 /* output mixer control */
15552 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15553 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15554 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15555 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15556 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15557
15558 /* Input mixer control */
15559 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15560 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15561 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15562 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15563 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15564 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15565 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15566 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15567 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15568 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15569
15570 {
15571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15572 .name = "Channel Mode",
15573 .info = alc_ch_mode_info,
15574 .get = alc_ch_mode_get,
15575 .put = alc_ch_mode_put,
15576 .private_value = ARRAY_SIZE(alc861_asus_modes),
15577 },
15578 { }
15579};
15580
15581/* additional mixer */
15582static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15583 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15584 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15585 { }
15586};
15587
15588/*
15589 * generic initialization of ADC, input mixers and output mixers
15590 */
15591static const struct hda_verb alc861_base_init_verbs[] = {
15592 /*
15593 * Unmute ADC0 and set the default input to mic-in
15594 */
15595 /* port-A for surround (rear panel) */
15596 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15597 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15598 /* port-B for mic-in (rear panel) with vref */
15599 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15600 /* port-C for line-in (rear panel) */
15601 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15602 /* port-D for Front */
15603 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15604 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15605 /* port-E for HP out (front panel) */
15606 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15607 /* route front PCM to HP */
15608 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15609 /* port-F for mic-in (front panel) with vref */
15610 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15611 /* port-G for CLFE (rear panel) */
15612 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15613 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15614 /* port-H for side (rear panel) */
15615 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15616 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15617 /* CD-in */
15618 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15619 /* route front mic to ADC1*/
15620 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15621 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15622
15623 /* Unmute DAC0~3 & spdif out*/
15624 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15625 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15626 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15627 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15628 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15629
15630 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15631 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15632 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15633 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15634 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15635
15636 /* Unmute Stereo Mixer 15 */
15637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15640 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15641
15642 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15643 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15644 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15645 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15646 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15647 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15648 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15649 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15650 /* hp used DAC 3 (Front) */
15651 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15652 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15653
15654 { }
15655};
15656
15657static const struct hda_verb alc861_threestack_init_verbs[] = {
15658 /*
15659 * Unmute ADC0 and set the default input to mic-in
15660 */
15661 /* port-A for surround (rear panel) */
15662 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15663 /* port-B for mic-in (rear panel) with vref */
15664 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15665 /* port-C for line-in (rear panel) */
15666 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15667 /* port-D for Front */
15668 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15669 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15670 /* port-E for HP out (front panel) */
15671 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15672 /* route front PCM to HP */
15673 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15674 /* port-F for mic-in (front panel) with vref */
15675 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15676 /* port-G for CLFE (rear panel) */
15677 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15678 /* port-H for side (rear panel) */
15679 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15680 /* CD-in */
15681 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15682 /* route front mic to ADC1*/
15683 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15684 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15685 /* Unmute DAC0~3 & spdif out*/
15686 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15687 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15688 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15689 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15691
15692 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15693 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15694 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15695 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15696 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15697
15698 /* Unmute Stereo Mixer 15 */
15699 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15700 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15701 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15702 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15703
15704 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15705 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15706 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15707 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15708 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15709 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15710 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15711 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15712 /* hp used DAC 3 (Front) */
15713 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15714 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15715 { }
15716};
15717
15718static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15719 /*
15720 * Unmute ADC0 and set the default input to mic-in
15721 */
15722 /* port-A for surround (rear panel) */
15723 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15724 /* port-B for mic-in (rear panel) with vref */
15725 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15726 /* port-C for line-in (rear panel) */
15727 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15728 /* port-D for Front */
15729 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15730 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15731 /* port-E for HP out (front panel) */
15732 /* this has to be set to VREF80 */
15733 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15734 /* route front PCM to HP */
15735 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15736 /* port-F for mic-in (front panel) with vref */
15737 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15738 /* port-G for CLFE (rear panel) */
15739 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15740 /* port-H for side (rear panel) */
15741 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15742 /* CD-in */
15743 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15744 /* route front mic to ADC1*/
15745 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15746 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15747 /* Unmute DAC0~3 & spdif out*/
15748 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15749 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15750 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15751 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15752 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15753
15754 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15755 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15756 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15757 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15758 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15759
15760 /* Unmute Stereo Mixer 15 */
15761 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15762 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15764 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15765
15766 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15767 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15768 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15769 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15770 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15772 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15773 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15774 /* hp used DAC 3 (Front) */
15775 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15776 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15777 { }
15778};
15779
15780static const struct hda_verb alc861_asus_init_verbs[] = {
15781 /*
15782 * Unmute ADC0 and set the default input to mic-in
15783 */
15784 /* port-A for surround (rear panel)
15785 * according to codec#0 this is the HP jack
15786 */
15787 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15788 /* route front PCM to HP */
15789 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15790 /* port-B for mic-in (rear panel) with vref */
15791 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15792 /* port-C for line-in (rear panel) */
15793 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15794 /* port-D for Front */
15795 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15796 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15797 /* port-E for HP out (front panel) */
15798 /* this has to be set to VREF80 */
15799 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15800 /* route front PCM to HP */
15801 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15802 /* port-F for mic-in (front panel) with vref */
15803 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15804 /* port-G for CLFE (rear panel) */
15805 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15806 /* port-H for side (rear panel) */
15807 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15808 /* CD-in */
15809 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15810 /* route front mic to ADC1*/
15811 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15812 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15813 /* Unmute DAC0~3 & spdif out*/
15814 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15815 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15816 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15817 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15819 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15820 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15821 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15822 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15823 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15824
15825 /* Unmute Stereo Mixer 15 */
15826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15829 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15830
15831 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15832 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15833 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15834 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15836 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15838 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15839 /* hp used DAC 3 (Front) */
15840 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15841 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15842 { }
15843};
15844
15845/* additional init verbs for ASUS laptops */
15846static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15847 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15848 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15849 { }
15850};
15851
15852/*
15853 * generic initialization of ADC, input mixers and output mixers
15854 */ 4754 */
15855static const struct hda_verb alc861_auto_init_verbs[] = {
15856 /*
15857 * Unmute ADC0 and set the default input to mic-in
15858 */
15859 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15860 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15861
15862 /* Unmute DAC0~3 & spdif out*/
15863 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15864 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15865 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15866 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15868
15869 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15870 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15871 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15872 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15873 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15874
15875 /* Unmute Stereo Mixer 15 */
15876 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15877 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15878 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15879 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15880
15881 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15882 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15883 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15884 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15885 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15886 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15887 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15888 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15889
15890 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15891 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15892 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15893 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15894 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15895 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15896 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15897 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15898
15899 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
15900
15901 { }
15902};
15903
15904static const struct hda_verb alc861_toshiba_init_verbs[] = {
15905 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15906
15907 { }
15908};
15909
15910/* toggle speaker-output according to the hp-jack state */
15911static void alc861_toshiba_automute(struct hda_codec *codec)
15912{
15913 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15914
15915 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15916 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15917 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15918 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15919}
15920
15921static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15922 unsigned int res)
15923{
15924 if ((res >> 26) == ALC880_HP_EVENT)
15925 alc861_toshiba_automute(codec);
15926}
15927
15928/* pcm configuration: identical with ALC880 */
15929#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15930#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15931#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15932#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15933
15934
15935#define ALC861_DIGOUT_NID 0x07
15936
15937static const struct hda_channel_mode alc861_8ch_modes[1] = {
15938 { 8, NULL }
15939};
15940
15941static const hda_nid_t alc861_dac_nids[4] = {
15942 /* front, surround, clfe, side */
15943 0x03, 0x06, 0x05, 0x04
15944};
15945
15946static const hda_nid_t alc660_dac_nids[3] = {
15947 /* front, clfe, surround */
15948 0x03, 0x05, 0x06
15949};
15950
15951static const hda_nid_t alc861_adc_nids[1] = {
15952 /* ADC0-2 */
15953 0x08,
15954};
15955
15956static const struct hda_input_mux alc861_capture_source = {
15957 .num_items = 5,
15958 .items = {
15959 { "Mic", 0x0 },
15960 { "Front Mic", 0x3 },
15961 { "Line", 0x1 },
15962 { "CD", 0x4 },
15963 { "Mixer", 0x5 },
15964 },
15965};
15966
15967static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15968{
15969 struct alc_spec *spec = codec->spec;
15970 hda_nid_t mix, srcs[5];
15971 int i, j, num;
15972
15973 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15974 return 0;
15975 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15976 if (num < 0)
15977 return 0;
15978 for (i = 0; i < num; i++) {
15979 unsigned int type;
15980 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15981 if (type != AC_WID_AUD_OUT)
15982 continue;
15983 for (j = 0; j < spec->multiout.num_dacs; j++)
15984 if (spec->multiout.dac_nids[j] == srcs[i])
15985 break;
15986 if (j >= spec->multiout.num_dacs)
15987 return srcs[i];
15988 }
15989 return 0;
15990}
15991
15992/* fill in the dac_nids table from the parsed pin configuration */
15993static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15994 const struct auto_pin_cfg *cfg)
15995{
15996 struct alc_spec *spec = codec->spec;
15997 int i;
15998 hda_nid_t nid, dac;
15999
16000 spec->multiout.dac_nids = spec->private_dac_nids;
16001 for (i = 0; i < cfg->line_outs; i++) {
16002 nid = cfg->line_out_pins[i];
16003 dac = alc861_look_for_dac(codec, nid);
16004 if (!dac)
16005 continue;
16006 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
16007 }
16008 return 0;
16009}
16010
16011static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16012 hda_nid_t nid, int idx, unsigned int chs)
16013{
16014 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
16015 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16016}
16017
16018#define alc861_create_out_sw(codec, pfx, nid, chs) \
16019 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16020
16021/* add playback controls from the parsed DAC table */
16022static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
16023 const struct auto_pin_cfg *cfg)
16024{
16025 struct alc_spec *spec = codec->spec;
16026 static const char * const chname[4] = {
16027 "Front", "Surround", NULL /*CLFE*/, "Side"
16028 };
16029 const char *pfx = alc_get_line_out_pfx(spec, true);
16030 hda_nid_t nid;
16031 int i, err, noutputs;
16032
16033 noutputs = cfg->line_outs;
16034 if (spec->multi_ios > 0)
16035 noutputs += spec->multi_ios;
16036
16037 for (i = 0; i < noutputs; i++) {
16038 nid = spec->multiout.dac_nids[i];
16039 if (!nid)
16040 continue;
16041 if (!pfx && i == 2) {
16042 /* Center/LFE */
16043 err = alc861_create_out_sw(codec, "Center", nid, 1);
16044 if (err < 0)
16045 return err;
16046 err = alc861_create_out_sw(codec, "LFE", nid, 2);
16047 if (err < 0)
16048 return err;
16049 } else {
16050 const char *name = pfx;
16051 int index = i;
16052 if (!name) {
16053 name = chname[i];
16054 index = 0;
16055 }
16056 err = __alc861_create_out_sw(codec, name, nid, index, 3);
16057 if (err < 0)
16058 return err;
16059 }
16060 }
16061 return 0;
16062}
16063
16064static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
16065{
16066 struct alc_spec *spec = codec->spec;
16067 int err;
16068 hda_nid_t nid;
16069
16070 if (!pin)
16071 return 0;
16072
16073 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
16074 nid = alc861_look_for_dac(codec, pin);
16075 if (nid) {
16076 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16077 if (err < 0)
16078 return err;
16079 spec->multiout.hp_nid = nid;
16080 }
16081 }
16082 return 0;
16083}
16084
16085/* create playback/capture controls for input pins */
16086static int alc861_auto_create_input_ctls(struct hda_codec *codec,
16087 const struct auto_pin_cfg *cfg)
16088{
16089 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
16090}
16091
16092static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16093 hda_nid_t nid,
16094 int pin_type, hda_nid_t dac)
16095{
16096 hda_nid_t mix, srcs[5];
16097 int i, num;
16098
16099 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16100 pin_type);
16101 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16102 AMP_OUT_UNMUTE);
16103 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16104 return;
16105 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16106 if (num < 0)
16107 return;
16108 for (i = 0; i < num; i++) {
16109 unsigned int mute;
16110 if (srcs[i] == dac || srcs[i] == 0x15)
16111 mute = AMP_IN_UNMUTE(i);
16112 else
16113 mute = AMP_IN_MUTE(i);
16114 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16115 mute);
16116 }
16117}
16118
16119static void alc861_auto_init_multi_out(struct hda_codec *codec)
16120{
16121 struct alc_spec *spec = codec->spec;
16122 int i;
16123
16124 for (i = 0; i < spec->autocfg.line_outs; i++) {
16125 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16126 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16127 if (nid)
16128 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
16129 spec->multiout.dac_nids[i]);
16130 }
16131}
16132 4755
16133static void alc861_auto_init_hp_out(struct hda_codec *codec)
16134{
16135 struct alc_spec *spec = codec->spec;
16136
16137 if (spec->autocfg.hp_outs)
16138 alc861_auto_set_output_and_unmute(codec,
16139 spec->autocfg.hp_pins[0],
16140 PIN_HP,
16141 spec->multiout.hp_nid);
16142 if (spec->autocfg.speaker_outs)
16143 alc861_auto_set_output_and_unmute(codec,
16144 spec->autocfg.speaker_pins[0],
16145 PIN_OUT,
16146 spec->multiout.dac_nids[0]);
16147}
16148
16149static void alc861_auto_init_analog_input(struct hda_codec *codec)
16150{
16151 struct alc_spec *spec = codec->spec;
16152 struct auto_pin_cfg *cfg = &spec->autocfg;
16153 int i;
16154
16155 for (i = 0; i < cfg->num_inputs; i++) {
16156 hda_nid_t nid = cfg->inputs[i].pin;
16157 if (nid >= 0x0c && nid <= 0x11)
16158 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16159 }
16160}
16161
16162/* parse the BIOS configuration and set up the alc_spec */
16163/* return 1 if successful, 0 if the proper config is not found,
16164 * or a negative error code
16165 */
16166static int alc861_parse_auto_config(struct hda_codec *codec) 4756static int alc861_parse_auto_config(struct hda_codec *codec)
16167{ 4757{
16168 struct alc_spec *spec = codec->spec;
16169 int err;
16170 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 4758 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16171 4759 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
16172 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4760 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
16173 alc861_ignore);
16174 if (err < 0)
16175 return err;
16176 if (!spec->autocfg.line_outs)
16177 return 0; /* can't find valid BIOS pin config */
16178
16179 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16180 if (err < 0)
16181 return err;
16182 err = alc_auto_add_multi_channel_mode(codec);
16183 if (err < 0)
16184 return err;
16185 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16186 if (err < 0)
16187 return err;
16188 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16189 if (err < 0)
16190 return err;
16191 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16192 if (err < 0)
16193 return err;
16194
16195 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16196
16197 alc_auto_parse_digital(codec);
16198
16199 if (spec->kctls.list)
16200 add_mixer(spec, spec->kctls.list);
16201
16202 add_verb(spec, alc861_auto_init_verbs);
16203
16204 spec->num_mux_defs = 1;
16205 spec->input_mux = &spec->private_imux[0];
16206
16207 spec->adc_nids = alc861_adc_nids;
16208 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16209 set_capture_mixer(codec);
16210
16211 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16212
16213 return 1;
16214}
16215
16216/* additional initialization for auto-configuration model */
16217static void alc861_auto_init(struct hda_codec *codec)
16218{
16219 struct alc_spec *spec = codec->spec;
16220 alc861_auto_init_multi_out(codec);
16221 alc861_auto_init_hp_out(codec);
16222 alc861_auto_init_analog_input(codec);
16223 alc_auto_init_digital(codec);
16224 if (spec->unsol_event)
16225 alc_inithook(codec);
16226} 4761}
16227 4762
16228#ifdef CONFIG_SND_HDA_POWER_SAVE 4763#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -16236,152 +4771,6 @@ static const struct hda_amp_list alc861_loopbacks[] = {
16236#endif 4771#endif
16237 4772
16238 4773
16239/*
16240 * configuration and preset
16241 */
16242static const char * const alc861_models[ALC861_MODEL_LAST] = {
16243 [ALC861_3ST] = "3stack",
16244 [ALC660_3ST] = "3stack-660",
16245 [ALC861_3ST_DIG] = "3stack-dig",
16246 [ALC861_6ST_DIG] = "6stack-dig",
16247 [ALC861_UNIWILL_M31] = "uniwill-m31",
16248 [ALC861_TOSHIBA] = "toshiba",
16249 [ALC861_ASUS] = "asus",
16250 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16251 [ALC861_AUTO] = "auto",
16252};
16253
16254static const struct snd_pci_quirk alc861_cfg_tbl[] = {
16255 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16256 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16257 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16258 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16259 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16260 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16261 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16262 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16263 * Any other models that need this preset?
16264 */
16265 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16266 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16267 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16268 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16269 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16270 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16271 /* FIXME: the below seems conflict */
16272 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16273 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16274 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16275 {}
16276};
16277
16278static const struct alc_config_preset alc861_presets[] = {
16279 [ALC861_3ST] = {
16280 .mixers = { alc861_3ST_mixer },
16281 .init_verbs = { alc861_threestack_init_verbs },
16282 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16283 .dac_nids = alc861_dac_nids,
16284 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16285 .channel_mode = alc861_threestack_modes,
16286 .need_dac_fix = 1,
16287 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16288 .adc_nids = alc861_adc_nids,
16289 .input_mux = &alc861_capture_source,
16290 },
16291 [ALC861_3ST_DIG] = {
16292 .mixers = { alc861_base_mixer },
16293 .init_verbs = { alc861_threestack_init_verbs },
16294 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16295 .dac_nids = alc861_dac_nids,
16296 .dig_out_nid = ALC861_DIGOUT_NID,
16297 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16298 .channel_mode = alc861_threestack_modes,
16299 .need_dac_fix = 1,
16300 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16301 .adc_nids = alc861_adc_nids,
16302 .input_mux = &alc861_capture_source,
16303 },
16304 [ALC861_6ST_DIG] = {
16305 .mixers = { alc861_base_mixer },
16306 .init_verbs = { alc861_base_init_verbs },
16307 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16308 .dac_nids = alc861_dac_nids,
16309 .dig_out_nid = ALC861_DIGOUT_NID,
16310 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16311 .channel_mode = alc861_8ch_modes,
16312 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16313 .adc_nids = alc861_adc_nids,
16314 .input_mux = &alc861_capture_source,
16315 },
16316 [ALC660_3ST] = {
16317 .mixers = { alc861_3ST_mixer },
16318 .init_verbs = { alc861_threestack_init_verbs },
16319 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16320 .dac_nids = alc660_dac_nids,
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_UNIWILL_M31] = {
16329 .mixers = { alc861_uniwill_m31_mixer },
16330 .init_verbs = { alc861_uniwill_m31_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_uniwill_m31_modes),
16335 .channel_mode = alc861_uniwill_m31_modes,
16336 .need_dac_fix = 1,
16337 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16338 .adc_nids = alc861_adc_nids,
16339 .input_mux = &alc861_capture_source,
16340 },
16341 [ALC861_TOSHIBA] = {
16342 .mixers = { alc861_toshiba_mixer },
16343 .init_verbs = { alc861_base_init_verbs,
16344 alc861_toshiba_init_verbs },
16345 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16346 .dac_nids = alc861_dac_nids,
16347 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16348 .channel_mode = alc883_3ST_2ch_modes,
16349 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16350 .adc_nids = alc861_adc_nids,
16351 .input_mux = &alc861_capture_source,
16352 .unsol_event = alc861_toshiba_unsol_event,
16353 .init_hook = alc861_toshiba_automute,
16354 },
16355 [ALC861_ASUS] = {
16356 .mixers = { alc861_asus_mixer },
16357 .init_verbs = { alc861_asus_init_verbs },
16358 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16359 .dac_nids = alc861_dac_nids,
16360 .dig_out_nid = ALC861_DIGOUT_NID,
16361 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16362 .channel_mode = alc861_asus_modes,
16363 .need_dac_fix = 1,
16364 .hp_nid = 0x06,
16365 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16366 .adc_nids = alc861_adc_nids,
16367 .input_mux = &alc861_capture_source,
16368 },
16369 [ALC861_ASUS_LAPTOP] = {
16370 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16371 .init_verbs = { alc861_asus_init_verbs,
16372 alc861_asus_laptop_init_verbs },
16373 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16374 .dac_nids = alc861_dac_nids,
16375 .dig_out_nid = ALC861_DIGOUT_NID,
16376 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16377 .channel_mode = alc883_3ST_2ch_modes,
16378 .need_dac_fix = 1,
16379 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16380 .adc_nids = alc861_adc_nids,
16381 .input_mux = &alc861_capture_source,
16382 },
16383};
16384
16385/* Pin config fixes */ 4774/* Pin config fixes */
16386enum { 4775enum {
16387 PINFIX_FSC_AMILO_PI1505, 4776 PINFIX_FSC_AMILO_PI1505,
@@ -16403,6 +4792,12 @@ static const struct snd_pci_quirk alc861_fixup_tbl[] = {
16403 {} 4792 {}
16404}; 4793};
16405 4794
4795/*
4796 */
4797#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4798#include "alc861_quirks.c"
4799#endif
4800
16406static int patch_alc861(struct hda_codec *codec) 4801static int patch_alc861(struct hda_codec *codec)
16407{ 4802{
16408 struct alc_spec *spec; 4803 struct alc_spec *spec;
@@ -16415,61 +4810,67 @@ static int patch_alc861(struct hda_codec *codec)
16415 4810
16416 codec->spec = spec; 4811 codec->spec = spec;
16417 4812
16418 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 4813 spec->mixer_nid = 0x15;
16419 alc861_models, 4814
16420 alc861_cfg_tbl); 4815 board_config = alc_board_config(codec, ALC861_MODEL_LAST,
4816 alc861_models, alc861_cfg_tbl);
16421 4817
16422 if (board_config < 0) { 4818 if (board_config < 0) {
16423 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4819 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16424 codec->chip_name); 4820 codec->chip_name);
16425 board_config = ALC861_AUTO; 4821 board_config = ALC_MODEL_AUTO;
16426 } 4822 }
16427 4823
16428 if (board_config == ALC861_AUTO) { 4824 if (board_config == ALC_MODEL_AUTO) {
16429 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); 4825 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16430 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4826 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16431 } 4827 }
16432 4828
16433 if (board_config == ALC861_AUTO) { 4829 if (board_config == ALC_MODEL_AUTO) {
16434 /* automatic parse from the BIOS config */ 4830 /* automatic parse from the BIOS config */
16435 err = alc861_parse_auto_config(codec); 4831 err = alc861_parse_auto_config(codec);
16436 if (err < 0) { 4832 if (err < 0) {
16437 alc_free(codec); 4833 alc_free(codec);
16438 return err; 4834 return err;
16439 } else if (!err) { 4835 }
4836#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4837 else if (!err) {
16440 printk(KERN_INFO 4838 printk(KERN_INFO
16441 "hda_codec: Cannot set up configuration " 4839 "hda_codec: Cannot set up configuration "
16442 "from BIOS. Using base mode...\n"); 4840 "from BIOS. Using base mode...\n");
16443 board_config = ALC861_3ST_DIG; 4841 board_config = ALC861_3ST_DIG;
16444 } 4842 }
4843#endif
16445 } 4844 }
16446 4845
16447 err = snd_hda_attach_beep_device(codec, 0x23); 4846 if (board_config != ALC_MODEL_AUTO)
16448 if (err < 0) {
16449 alc_free(codec);
16450 return err;
16451 }
16452
16453 if (board_config != ALC861_AUTO)
16454 setup_preset(codec, &alc861_presets[board_config]); 4847 setup_preset(codec, &alc861_presets[board_config]);
16455 4848
16456 spec->stream_analog_playback = &alc861_pcm_analog_playback; 4849 if (!spec->no_analog && !spec->adc_nids) {
16457 spec->stream_analog_capture = &alc861_pcm_analog_capture; 4850 alc_auto_fill_adc_caps(codec);
16458 4851 alc_rebuild_imux_for_auto_mic(codec);
16459 spec->stream_digital_playback = &alc861_pcm_digital_playback; 4852 alc_remove_invalid_adc_nids(codec);
16460 spec->stream_digital_capture = &alc861_pcm_digital_capture; 4853 }
16461 4854
16462 if (!spec->cap_mixer) 4855 if (!spec->no_analog && !spec->cap_mixer)
16463 set_capture_mixer(codec); 4856 set_capture_mixer(codec);
16464 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 4857
4858 if (!spec->no_analog) {
4859 err = snd_hda_attach_beep_device(codec, 0x23);
4860 if (err < 0) {
4861 alc_free(codec);
4862 return err;
4863 }
4864 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
4865 }
16465 4866
16466 spec->vmaster_nid = 0x03; 4867 spec->vmaster_nid = 0x03;
16467 4868
16468 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4869 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16469 4870
16470 codec->patch_ops = alc_patch_ops; 4871 codec->patch_ops = alc_patch_ops;
16471 if (board_config == ALC861_AUTO) { 4872 if (board_config == ALC_MODEL_AUTO) {
16472 spec->init_hook = alc861_auto_init; 4873 spec->init_hook = alc_auto_init_std;
16473#ifdef CONFIG_SND_HDA_POWER_SAVE 4874#ifdef CONFIG_SND_HDA_POWER_SAVE
16474 spec->power_hook = alc_power_eapd; 4875 spec->power_hook = alc_power_eapd;
16475#endif 4876#endif
@@ -16489,871 +4890,15 @@ static int patch_alc861(struct hda_codec *codec)
16489 * 4890 *
16490 * In addition, an independent DAC 4891 * In addition, an independent DAC
16491 */ 4892 */
16492#define ALC861VD_DIGOUT_NID 0x06
16493
16494static const hda_nid_t alc861vd_dac_nids[4] = {
16495 /* front, surr, clfe, side surr */
16496 0x02, 0x03, 0x04, 0x05
16497};
16498
16499/* dac_nids for ALC660vd are in a different order - according to
16500 * Realtek's driver.
16501 * This should probably result in a different mixer for 6stack models
16502 * of ALC660vd codecs, but for now there is only 3stack mixer
16503 * - and it is the same as in 861vd.
16504 * adc_nids in ALC660vd are (is) the same as in 861vd
16505 */
16506static const hda_nid_t alc660vd_dac_nids[3] = {
16507 /* front, rear, clfe, rear_surr */
16508 0x02, 0x04, 0x03
16509};
16510
16511static const hda_nid_t alc861vd_adc_nids[1] = {
16512 /* ADC0 */
16513 0x09,
16514};
16515
16516static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16517
16518/* input MUX */
16519/* FIXME: should be a matrix-type input source selection */
16520static const struct hda_input_mux alc861vd_capture_source = {
16521 .num_items = 4,
16522 .items = {
16523 { "Mic", 0x0 },
16524 { "Front Mic", 0x1 },
16525 { "Line", 0x2 },
16526 { "CD", 0x4 },
16527 },
16528};
16529
16530static const struct hda_input_mux alc861vd_dallas_capture_source = {
16531 .num_items = 2,
16532 .items = {
16533 { "Mic", 0x0 },
16534 { "Internal Mic", 0x1 },
16535 },
16536};
16537
16538static const struct hda_input_mux alc861vd_hp_capture_source = {
16539 .num_items = 2,
16540 .items = {
16541 { "Front Mic", 0x0 },
16542 { "ATAPI Mic", 0x1 },
16543 },
16544};
16545
16546/*
16547 * 2ch mode
16548 */
16549static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16550 { 2, NULL }
16551};
16552
16553/*
16554 * 6ch mode
16555 */
16556static const struct hda_verb alc861vd_6stack_ch6_init[] = {
16557 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16558 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16559 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16560 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16561 { } /* end */
16562};
16563
16564/*
16565 * 8ch mode
16566 */
16567static const struct hda_verb alc861vd_6stack_ch8_init[] = {
16568 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16569 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16570 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16571 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16572 { } /* end */
16573};
16574
16575static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
16576 { 6, alc861vd_6stack_ch6_init },
16577 { 8, alc861vd_6stack_ch8_init },
16578};
16579
16580static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16581 {
16582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16583 .name = "Channel Mode",
16584 .info = alc_ch_mode_info,
16585 .get = alc_ch_mode_get,
16586 .put = alc_ch_mode_put,
16587 },
16588 { } /* end */
16589};
16590
16591/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16592 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16593 */
16594static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16595 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16596 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16597
16598 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16599 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16600
16601 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16602 HDA_OUTPUT),
16603 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16604 HDA_OUTPUT),
16605 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16606 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16607
16608 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16609 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16610
16611 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16612
16613 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16614 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16615 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16616
16617 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16618 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16619 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16620
16621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16623
16624 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16625 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16626
16627 { } /* end */
16628};
16629
16630static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16631 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16632 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16633
16634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16635
16636 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16639
16640 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16641 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16642 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16643
16644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16646
16647 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16648 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16649
16650 { } /* end */
16651};
16652
16653static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16654 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16655 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16656 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
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("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16669 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16670
16671 { } /* end */
16672};
16673
16674/* Pin assignment: Speaker=0x14, HP = 0x15,
16675 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16676 */
16677static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16678 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16679 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16680 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16681 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16682 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16683 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16684 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16685 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16686 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16687 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16688 { } /* end */
16689};
16690
16691/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16692 * Front Mic=0x18, ATAPI Mic = 0x19,
16693 */
16694static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16695 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16696 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16697 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16698 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16699 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16700 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16701 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16702 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16703
16704 { } /* end */
16705};
16706
16707/*
16708 * generic initialization of ADC, input mixers and output mixers
16709 */
16710static const struct hda_verb alc861vd_volume_init_verbs[] = {
16711 /*
16712 * Unmute ADC0 and set the default input to mic-in
16713 */
16714 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16715 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16716
16717 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16718 * the analog-loopback mixer widget
16719 */
16720 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16726
16727 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16729 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16732
16733 /*
16734 * Set up output mixers (0x02 - 0x05)
16735 */
16736 /* set vol=0 to output mixers */
16737 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16738 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16739 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16740 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16741
16742 /* set up input amps for analog loopback */
16743 /* Amp Indices: DAC = 0, mixer = 1 */
16744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16746 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16747 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16749 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16750 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16751 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16752
16753 { }
16754};
16755
16756/*
16757 * 3-stack pin configuration:
16758 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16759 */
16760static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16761 /*
16762 * Set pin mode and muting
16763 */
16764 /* set front pin widgets 0x14 for output */
16765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16767 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16768
16769 /* Mic (rear) pin: input vref at 80% */
16770 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16772 /* Front Mic pin: input vref at 80% */
16773 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16774 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16775 /* Line In pin: input */
16776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16777 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16778 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16779 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16780 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16781 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16782 /* CD pin widget for input */
16783 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16784
16785 { }
16786};
16787
16788/*
16789 * 6-stack pin configuration:
16790 */
16791static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16792 /*
16793 * Set pin mode and muting
16794 */
16795 /* set front pin widgets 0x14 for output */
16796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16798 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16799
16800 /* Rear Pin: output 1 (0x0d) */
16801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16803 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16804 /* CLFE Pin: output 2 (0x0e) */
16805 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16806 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16807 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16808 /* Side Pin: output 3 (0x0f) */
16809 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16810 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16811 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16812
16813 /* Mic (rear) pin: input vref at 80% */
16814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16815 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16816 /* Front Mic pin: input vref at 80% */
16817 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16818 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16819 /* Line In pin: input */
16820 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16821 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16822 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16823 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16824 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16825 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16826 /* CD pin widget for input */
16827 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16828
16829 { }
16830};
16831
16832static const struct hda_verb alc861vd_eapd_verbs[] = {
16833 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16834 { }
16835};
16836
16837static const struct hda_verb alc660vd_eapd_verbs[] = {
16838 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16839 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16840 { }
16841};
16842
16843static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16846 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16847 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16848 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16849 {}
16850};
16851
16852static void alc861vd_lenovo_setup(struct hda_codec *codec)
16853{
16854 struct alc_spec *spec = codec->spec;
16855 spec->autocfg.hp_pins[0] = 0x1b;
16856 spec->autocfg.speaker_pins[0] = 0x14;
16857 spec->automute = 1;
16858 spec->automute_mode = ALC_AUTOMUTE_AMP;
16859}
16860
16861static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16862{
16863 alc_hp_automute(codec);
16864 alc88x_simple_mic_automute(codec);
16865}
16866
16867static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16868 unsigned int res)
16869{
16870 switch (res >> 26) {
16871 case ALC880_MIC_EVENT:
16872 alc88x_simple_mic_automute(codec);
16873 break;
16874 default:
16875 alc_sku_unsol_event(codec, res);
16876 break;
16877 }
16878}
16879
16880static const struct hda_verb alc861vd_dallas_verbs[] = {
16881 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16882 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16883 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16884 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16885
16886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16888 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16889 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16890 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16891 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16892 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16893 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16894
16895 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16896 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16897 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16898 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16899 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16901 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16902 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16903
16904 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16905 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16906 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16907 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16908 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16909 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16910 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16911 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16912
16913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16917
16918 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16919 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16920 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16921
16922 { } /* end */
16923};
16924
16925/* toggle speaker-output according to the hp-jack state */
16926static void alc861vd_dallas_setup(struct hda_codec *codec)
16927{
16928 struct alc_spec *spec = codec->spec;
16929
16930 spec->autocfg.hp_pins[0] = 0x15;
16931 spec->autocfg.speaker_pins[0] = 0x14;
16932 spec->automute = 1;
16933 spec->automute_mode = ALC_AUTOMUTE_AMP;
16934}
16935
16936#ifdef CONFIG_SND_HDA_POWER_SAVE 4893#ifdef CONFIG_SND_HDA_POWER_SAVE
16937#define alc861vd_loopbacks alc880_loopbacks 4894#define alc861vd_loopbacks alc880_loopbacks
16938#endif 4895#endif
16939 4896
16940/* pcm configuration: identical with ALC880 */
16941#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16942#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16943#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16944#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16945
16946/*
16947 * configuration and preset
16948 */
16949static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16950 [ALC660VD_3ST] = "3stack-660",
16951 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16952 [ALC660VD_ASUS_V1S] = "asus-v1s",
16953 [ALC861VD_3ST] = "3stack",
16954 [ALC861VD_3ST_DIG] = "3stack-digout",
16955 [ALC861VD_6ST_DIG] = "6stack-digout",
16956 [ALC861VD_LENOVO] = "lenovo",
16957 [ALC861VD_DALLAS] = "dallas",
16958 [ALC861VD_HP] = "hp",
16959 [ALC861VD_AUTO] = "auto",
16960};
16961
16962static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16963 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16964 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16965 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16966 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16967 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16968 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16969 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16970 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16971 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16972 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16973 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16974 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16975 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16976 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16977 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16978 {}
16979};
16980
16981static const struct alc_config_preset alc861vd_presets[] = {
16982 [ALC660VD_3ST] = {
16983 .mixers = { alc861vd_3st_mixer },
16984 .init_verbs = { alc861vd_volume_init_verbs,
16985 alc861vd_3stack_init_verbs },
16986 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16987 .dac_nids = alc660vd_dac_nids,
16988 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16989 .channel_mode = alc861vd_3stack_2ch_modes,
16990 .input_mux = &alc861vd_capture_source,
16991 },
16992 [ALC660VD_3ST_DIG] = {
16993 .mixers = { alc861vd_3st_mixer },
16994 .init_verbs = { alc861vd_volume_init_verbs,
16995 alc861vd_3stack_init_verbs },
16996 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16997 .dac_nids = alc660vd_dac_nids,
16998 .dig_out_nid = ALC861VD_DIGOUT_NID,
16999 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17000 .channel_mode = alc861vd_3stack_2ch_modes,
17001 .input_mux = &alc861vd_capture_source,
17002 },
17003 [ALC861VD_3ST] = {
17004 .mixers = { alc861vd_3st_mixer },
17005 .init_verbs = { alc861vd_volume_init_verbs,
17006 alc861vd_3stack_init_verbs },
17007 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17008 .dac_nids = alc861vd_dac_nids,
17009 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17010 .channel_mode = alc861vd_3stack_2ch_modes,
17011 .input_mux = &alc861vd_capture_source,
17012 },
17013 [ALC861VD_3ST_DIG] = {
17014 .mixers = { alc861vd_3st_mixer },
17015 .init_verbs = { alc861vd_volume_init_verbs,
17016 alc861vd_3stack_init_verbs },
17017 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17018 .dac_nids = alc861vd_dac_nids,
17019 .dig_out_nid = ALC861VD_DIGOUT_NID,
17020 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17021 .channel_mode = alc861vd_3stack_2ch_modes,
17022 .input_mux = &alc861vd_capture_source,
17023 },
17024 [ALC861VD_6ST_DIG] = {
17025 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17026 .init_verbs = { alc861vd_volume_init_verbs,
17027 alc861vd_6stack_init_verbs },
17028 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17029 .dac_nids = alc861vd_dac_nids,
17030 .dig_out_nid = ALC861VD_DIGOUT_NID,
17031 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17032 .channel_mode = alc861vd_6stack_modes,
17033 .input_mux = &alc861vd_capture_source,
17034 },
17035 [ALC861VD_LENOVO] = {
17036 .mixers = { alc861vd_lenovo_mixer },
17037 .init_verbs = { alc861vd_volume_init_verbs,
17038 alc861vd_3stack_init_verbs,
17039 alc861vd_eapd_verbs,
17040 alc861vd_lenovo_unsol_verbs },
17041 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17042 .dac_nids = alc660vd_dac_nids,
17043 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17044 .channel_mode = alc861vd_3stack_2ch_modes,
17045 .input_mux = &alc861vd_capture_source,
17046 .unsol_event = alc861vd_lenovo_unsol_event,
17047 .setup = alc861vd_lenovo_setup,
17048 .init_hook = alc861vd_lenovo_init_hook,
17049 },
17050 [ALC861VD_DALLAS] = {
17051 .mixers = { alc861vd_dallas_mixer },
17052 .init_verbs = { alc861vd_dallas_verbs },
17053 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17054 .dac_nids = alc861vd_dac_nids,
17055 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17056 .channel_mode = alc861vd_3stack_2ch_modes,
17057 .input_mux = &alc861vd_dallas_capture_source,
17058 .unsol_event = alc_sku_unsol_event,
17059 .setup = alc861vd_dallas_setup,
17060 .init_hook = alc_hp_automute,
17061 },
17062 [ALC861VD_HP] = {
17063 .mixers = { alc861vd_hp_mixer },
17064 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17065 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17066 .dac_nids = alc861vd_dac_nids,
17067 .dig_out_nid = ALC861VD_DIGOUT_NID,
17068 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17069 .channel_mode = alc861vd_3stack_2ch_modes,
17070 .input_mux = &alc861vd_hp_capture_source,
17071 .unsol_event = alc_sku_unsol_event,
17072 .setup = alc861vd_dallas_setup,
17073 .init_hook = alc_hp_automute,
17074 },
17075 [ALC660VD_ASUS_V1S] = {
17076 .mixers = { alc861vd_lenovo_mixer },
17077 .init_verbs = { alc861vd_volume_init_verbs,
17078 alc861vd_3stack_init_verbs,
17079 alc861vd_eapd_verbs,
17080 alc861vd_lenovo_unsol_verbs },
17081 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17082 .dac_nids = alc660vd_dac_nids,
17083 .dig_out_nid = ALC861VD_DIGOUT_NID,
17084 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17085 .channel_mode = alc861vd_3stack_2ch_modes,
17086 .input_mux = &alc861vd_capture_source,
17087 .unsol_event = alc861vd_lenovo_unsol_event,
17088 .setup = alc861vd_lenovo_setup,
17089 .init_hook = alc861vd_lenovo_init_hook,
17090 },
17091};
17092
17093/*
17094 * BIOS auto configuration
17095 */
17096static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17097 const struct auto_pin_cfg *cfg)
17098{
17099 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
17100}
17101
17102
17103static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17104 hda_nid_t nid, int pin_type, int dac_idx)
17105{
17106 alc_set_pin_output(codec, nid, pin_type);
17107}
17108
17109static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17110{
17111 struct alc_spec *spec = codec->spec;
17112 int i;
17113
17114 for (i = 0; i <= HDA_SIDE; i++) {
17115 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17116 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17117 if (nid)
17118 alc861vd_auto_set_output_and_unmute(codec, nid,
17119 pin_type, i);
17120 }
17121}
17122
17123
17124static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17125{
17126 struct alc_spec *spec = codec->spec;
17127 hda_nid_t pin;
17128
17129 pin = spec->autocfg.hp_pins[0];
17130 if (pin) /* connect to front and use dac 0 */
17131 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17132 pin = spec->autocfg.speaker_pins[0];
17133 if (pin)
17134 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17135}
17136
17137#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17138
17139static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17140{
17141 struct alc_spec *spec = codec->spec;
17142 struct auto_pin_cfg *cfg = &spec->autocfg;
17143 int i;
17144
17145 for (i = 0; i < cfg->num_inputs; i++) {
17146 hda_nid_t nid = cfg->inputs[i].pin;
17147 if (alc_is_input_pin(codec, nid)) {
17148 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
17149 if (nid != ALC861VD_PIN_CD_NID &&
17150 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17151 snd_hda_codec_write(codec, nid, 0,
17152 AC_VERB_SET_AMP_GAIN_MUTE,
17153 AMP_OUT_MUTE);
17154 }
17155 }
17156}
17157
17158#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17159
17160#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17161#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17162
17163/* add playback controls from the parsed DAC table */
17164/* Based on ALC880 version. But ALC861VD has separate,
17165 * different NIDs for mute/unmute switch and volume control */
17166static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17167 const struct auto_pin_cfg *cfg)
17168{
17169 static const char * const chname[4] = {
17170 "Front", "Surround", "CLFE", "Side"
17171 };
17172 const char *pfx = alc_get_line_out_pfx(spec, true);
17173 hda_nid_t nid_v, nid_s;
17174 int i, err, noutputs;
17175
17176 noutputs = cfg->line_outs;
17177 if (spec->multi_ios > 0)
17178 noutputs += spec->multi_ios;
17179
17180 for (i = 0; i < noutputs; i++) {
17181 if (!spec->multiout.dac_nids[i])
17182 continue;
17183 nid_v = alc861vd_idx_to_mixer_vol(
17184 alc880_dac_to_idx(
17185 spec->multiout.dac_nids[i]));
17186 nid_s = alc861vd_idx_to_mixer_switch(
17187 alc880_dac_to_idx(
17188 spec->multiout.dac_nids[i]));
17189
17190 if (!pfx && i == 2) {
17191 /* Center/LFE */
17192 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17193 "Center",
17194 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17195 HDA_OUTPUT));
17196 if (err < 0)
17197 return err;
17198 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17199 "LFE",
17200 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17201 HDA_OUTPUT));
17202 if (err < 0)
17203 return err;
17204 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17205 "Center",
17206 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17207 HDA_INPUT));
17208 if (err < 0)
17209 return err;
17210 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17211 "LFE",
17212 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17213 HDA_INPUT));
17214 if (err < 0)
17215 return err;
17216 } else {
17217 const char *name = pfx;
17218 int index = i;
17219 if (!name) {
17220 name = chname[i];
17221 index = 0;
17222 }
17223 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17224 name, index,
17225 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17226 HDA_OUTPUT));
17227 if (err < 0)
17228 return err;
17229 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17230 name, index,
17231 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17232 HDA_INPUT));
17233 if (err < 0)
17234 return err;
17235 }
17236 }
17237 return 0;
17238}
17239
17240/* add playback controls for speaker and HP outputs */
17241/* Based on ALC880 version. But ALC861VD has separate,
17242 * different NIDs for mute/unmute switch and volume control */
17243static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17244 hda_nid_t pin, const char *pfx)
17245{
17246 hda_nid_t nid_v, nid_s;
17247 int err;
17248
17249 if (!pin)
17250 return 0;
17251
17252 if (alc880_is_fixed_pin(pin)) {
17253 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17254 /* specify the DAC as the extra output */
17255 if (!spec->multiout.hp_nid)
17256 spec->multiout.hp_nid = nid_v;
17257 else
17258 spec->multiout.extra_out_nid[0] = nid_v;
17259 /* control HP volume/switch on the output mixer amp */
17260 nid_v = alc861vd_idx_to_mixer_vol(
17261 alc880_fixed_pin_idx(pin));
17262 nid_s = alc861vd_idx_to_mixer_switch(
17263 alc880_fixed_pin_idx(pin));
17264
17265 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17266 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17267 if (err < 0)
17268 return err;
17269 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17270 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17271 if (err < 0)
17272 return err;
17273 } else if (alc880_is_multi_pin(pin)) {
17274 /* set manual connection */
17275 /* we have only a switch on HP-out PIN */
17276 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17277 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17278 if (err < 0)
17279 return err;
17280 }
17281 return 0;
17282}
17283
17284/* parse the BIOS configuration and set up the alc_spec
17285 * return 1 if successful, 0 if the proper config is not found,
17286 * or a negative error code
17287 * Based on ALC880 version - had to change it to override
17288 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17289static int alc861vd_parse_auto_config(struct hda_codec *codec) 4897static int alc861vd_parse_auto_config(struct hda_codec *codec)
17290{ 4898{
17291 struct alc_spec *spec = codec->spec;
17292 int err;
17293 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 4899 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17294 4900 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
17295 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4901 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
17296 alc861vd_ignore);
17297 if (err < 0)
17298 return err;
17299 if (!spec->autocfg.line_outs)
17300 return 0; /* can't find valid BIOS pin config */
17301
17302 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17303 if (err < 0)
17304 return err;
17305 err = alc_auto_add_multi_channel_mode(codec);
17306 if (err < 0)
17307 return err;
17308 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17309 if (err < 0)
17310 return err;
17311 err = alc861vd_auto_create_extra_out(spec,
17312 spec->autocfg.speaker_pins[0],
17313 "Speaker");
17314 if (err < 0)
17315 return err;
17316 err = alc861vd_auto_create_extra_out(spec,
17317 spec->autocfg.hp_pins[0],
17318 "Headphone");
17319 if (err < 0)
17320 return err;
17321 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17322 if (err < 0)
17323 return err;
17324
17325 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17326
17327 alc_auto_parse_digital(codec);
17328
17329 if (spec->kctls.list)
17330 add_mixer(spec, spec->kctls.list);
17331
17332 add_verb(spec, alc861vd_volume_init_verbs);
17333
17334 spec->num_mux_defs = 1;
17335 spec->input_mux = &spec->private_imux[0];
17336
17337 err = alc_auto_add_mic_boost(codec);
17338 if (err < 0)
17339 return err;
17340
17341 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17342
17343 return 1;
17344}
17345
17346/* additional initialization for auto-configuration model */
17347static void alc861vd_auto_init(struct hda_codec *codec)
17348{
17349 struct alc_spec *spec = codec->spec;
17350 alc861vd_auto_init_multi_out(codec);
17351 alc861vd_auto_init_hp_out(codec);
17352 alc861vd_auto_init_analog_input(codec);
17353 alc861vd_auto_init_input_src(codec);
17354 alc_auto_init_digital(codec);
17355 if (spec->unsol_event)
17356 alc_inithook(codec);
17357} 4902}
17358 4903
17359enum { 4904enum {
@@ -17378,6 +4923,18 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17378 {} 4923 {}
17379}; 4924};
17380 4925
4926static const struct hda_verb alc660vd_eapd_verbs[] = {
4927 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
4928 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
4929 { }
4930};
4931
4932/*
4933 */
4934#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4935#include "alc861vd_quirks.c"
4936#endif
4937
17381static int patch_alc861vd(struct hda_codec *codec) 4938static int patch_alc861vd(struct hda_codec *codec)
17382{ 4939{
17383 struct alc_spec *spec; 4940 struct alc_spec *spec;
@@ -17389,42 +4946,40 @@ static int patch_alc861vd(struct hda_codec *codec)
17389 4946
17390 codec->spec = spec; 4947 codec->spec = spec;
17391 4948
17392 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 4949 spec->mixer_nid = 0x0b;
17393 alc861vd_models,
17394 alc861vd_cfg_tbl);
17395 4950
17396 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 4951 board_config = alc_board_config(codec, ALC861VD_MODEL_LAST,
4952 alc861vd_models, alc861vd_cfg_tbl);
4953
4954 if (board_config < 0) {
17397 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4955 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17398 codec->chip_name); 4956 codec->chip_name);
17399 board_config = ALC861VD_AUTO; 4957 board_config = ALC_MODEL_AUTO;
17400 } 4958 }
17401 4959
17402 if (board_config == ALC861VD_AUTO) { 4960 if (board_config == ALC_MODEL_AUTO) {
17403 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); 4961 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17404 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4962 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17405 } 4963 }
17406 4964
17407 if (board_config == ALC861VD_AUTO) { 4965 if (board_config == ALC_MODEL_AUTO) {
17408 /* automatic parse from the BIOS config */ 4966 /* automatic parse from the BIOS config */
17409 err = alc861vd_parse_auto_config(codec); 4967 err = alc861vd_parse_auto_config(codec);
17410 if (err < 0) { 4968 if (err < 0) {
17411 alc_free(codec); 4969 alc_free(codec);
17412 return err; 4970 return err;
17413 } else if (!err) { 4971 }
4972#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4973 else if (!err) {
17414 printk(KERN_INFO 4974 printk(KERN_INFO
17415 "hda_codec: Cannot set up configuration " 4975 "hda_codec: Cannot set up configuration "
17416 "from BIOS. Using base mode...\n"); 4976 "from BIOS. Using base mode...\n");
17417 board_config = ALC861VD_3ST; 4977 board_config = ALC861VD_3ST;
17418 } 4978 }
4979#endif
17419 } 4980 }
17420 4981
17421 err = snd_hda_attach_beep_device(codec, 0x23); 4982 if (board_config != ALC_MODEL_AUTO)
17422 if (err < 0) {
17423 alc_free(codec);
17424 return err;
17425 }
17426
17427 if (board_config != ALC861VD_AUTO)
17428 setup_preset(codec, &alc861vd_presets[board_config]); 4983 setup_preset(codec, &alc861vd_presets[board_config]);
17429 4984
17430 if (codec->vendor_id == 0x10ec0660) { 4985 if (codec->vendor_id == 0x10ec0660) {
@@ -17432,21 +4987,23 @@ static int patch_alc861vd(struct hda_codec *codec)
17432 add_verb(spec, alc660vd_eapd_verbs); 4987 add_verb(spec, alc660vd_eapd_verbs);
17433 } 4988 }
17434 4989
17435 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 4990 if (!spec->no_analog && !spec->adc_nids) {
17436 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 4991 alc_auto_fill_adc_caps(codec);
4992 alc_rebuild_imux_for_auto_mic(codec);
4993 alc_remove_invalid_adc_nids(codec);
4994 }
17437 4995
17438 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 4996 if (!spec->no_analog && !spec->cap_mixer)
17439 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 4997 set_capture_mixer(codec);
17440 4998
17441 if (!spec->adc_nids) { 4999 if (!spec->no_analog) {
17442 spec->adc_nids = alc861vd_adc_nids; 5000 err = snd_hda_attach_beep_device(codec, 0x23);
17443 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 5001 if (err < 0) {
5002 alc_free(codec);
5003 return err;
5004 }
5005 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17444 } 5006 }
17445 if (!spec->capsrc_nids)
17446 spec->capsrc_nids = alc861vd_capsrc_nids;
17447
17448 set_capture_mixer(codec);
17449 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17450 5007
17451 spec->vmaster_nid = 0x02; 5008 spec->vmaster_nid = 0x02;
17452 5009
@@ -17454,8 +5011,8 @@ static int patch_alc861vd(struct hda_codec *codec)
17454 5011
17455 codec->patch_ops = alc_patch_ops; 5012 codec->patch_ops = alc_patch_ops;
17456 5013
17457 if (board_config == ALC861VD_AUTO) 5014 if (board_config == ALC_MODEL_AUTO)
17458 spec->init_hook = alc861vd_auto_init; 5015 spec->init_hook = alc_auto_init_std;
17459 spec->shutup = alc_eapd_shutup; 5016 spec->shutup = alc_eapd_shutup;
17460#ifdef CONFIG_SND_HDA_POWER_SAVE 5017#ifdef CONFIG_SND_HDA_POWER_SAVE
17461 if (!spec->loopback.amplist) 5018 if (!spec->loopback.amplist)
@@ -17476,1943 +5033,27 @@ static int patch_alc861vd(struct hda_codec *codec)
17476 * In addition, an independent DAC for the multi-playback (not used in this 5033 * In addition, an independent DAC for the multi-playback (not used in this
17477 * driver yet). 5034 * driver yet).
17478 */ 5035 */
17479#define ALC662_DIGOUT_NID 0x06
17480#define ALC662_DIGIN_NID 0x0a
17481
17482static const hda_nid_t alc662_dac_nids[3] = {
17483 /* front, rear, clfe */
17484 0x02, 0x03, 0x04
17485};
17486
17487static const hda_nid_t alc272_dac_nids[2] = {
17488 0x02, 0x03
17489};
17490
17491static const hda_nid_t alc662_adc_nids[2] = {
17492 /* ADC1-2 */
17493 0x09, 0x08
17494};
17495
17496static const hda_nid_t alc272_adc_nids[1] = {
17497 /* ADC1-2 */
17498 0x08,
17499};
17500
17501static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17502static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17503
17504
17505/* input MUX */
17506/* FIXME: should be a matrix-type input source selection */
17507static const struct hda_input_mux alc662_capture_source = {
17508 .num_items = 4,
17509 .items = {
17510 { "Mic", 0x0 },
17511 { "Front Mic", 0x1 },
17512 { "Line", 0x2 },
17513 { "CD", 0x4 },
17514 },
17515};
17516
17517static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
17518 .num_items = 2,
17519 .items = {
17520 { "Mic", 0x1 },
17521 { "Line", 0x2 },
17522 },
17523};
17524
17525static const struct hda_input_mux alc663_capture_source = {
17526 .num_items = 3,
17527 .items = {
17528 { "Mic", 0x0 },
17529 { "Front Mic", 0x1 },
17530 { "Line", 0x2 },
17531 },
17532};
17533
17534#if 0 /* set to 1 for testing other input sources below */
17535static const struct hda_input_mux alc272_nc10_capture_source = {
17536 .num_items = 16,
17537 .items = {
17538 { "Autoselect Mic", 0x0 },
17539 { "Internal Mic", 0x1 },
17540 { "In-0x02", 0x2 },
17541 { "In-0x03", 0x3 },
17542 { "In-0x04", 0x4 },
17543 { "In-0x05", 0x5 },
17544 { "In-0x06", 0x6 },
17545 { "In-0x07", 0x7 },
17546 { "In-0x08", 0x8 },
17547 { "In-0x09", 0x9 },
17548 { "In-0x0a", 0x0a },
17549 { "In-0x0b", 0x0b },
17550 { "In-0x0c", 0x0c },
17551 { "In-0x0d", 0x0d },
17552 { "In-0x0e", 0x0e },
17553 { "In-0x0f", 0x0f },
17554 },
17555};
17556#endif
17557
17558/*
17559 * 2ch mode
17560 */
17561static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17562 { 2, NULL }
17563};
17564
17565/*
17566 * 2ch mode
17567 */
17568static const struct hda_verb alc662_3ST_ch2_init[] = {
17569 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17570 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17571 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17572 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17573 { } /* end */
17574};
17575
17576/*
17577 * 6ch mode
17578 */
17579static const struct hda_verb alc662_3ST_ch6_init[] = {
17580 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17581 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17582 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17583 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17584 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17585 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17586 { } /* end */
17587};
17588
17589static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17590 { 2, alc662_3ST_ch2_init },
17591 { 6, alc662_3ST_ch6_init },
17592};
17593
17594/*
17595 * 2ch mode
17596 */
17597static const struct hda_verb alc662_sixstack_ch6_init[] = {
17598 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17599 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17600 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17601 { } /* end */
17602};
17603
17604/*
17605 * 6ch mode
17606 */
17607static const struct hda_verb alc662_sixstack_ch8_init[] = {
17608 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17609 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17610 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17611 { } /* end */
17612};
17613
17614static const struct hda_channel_mode alc662_5stack_modes[2] = {
17615 { 2, alc662_sixstack_ch6_init },
17616 { 6, alc662_sixstack_ch8_init },
17617};
17618
17619/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17620 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17621 */
17622
17623static const struct snd_kcontrol_new alc662_base_mixer[] = {
17624 /* output mixer control */
17625 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17626 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17627 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17628 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17629 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17630 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17631 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17632 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17633 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17634
17635 /*Input mixer control */
17636 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17637 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17638 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17639 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17640 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17641 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17642 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17643 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17644 { } /* end */
17645};
17646
17647static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17648 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17649 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17651 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17652 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17653 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17654 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17657 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17658 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17659 { } /* end */
17660};
17661
17662static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17663 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17664 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17665 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17666 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17667 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17668 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17669 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17670 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17672 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17673 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17674 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17675 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17676 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17678 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17679 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17680 { } /* end */
17681};
17682
17683static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17684 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17685 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17686 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17687 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17688 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17689 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17690 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17691 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17693 { } /* end */
17694};
17695
17696static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17697 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17698 ALC262_HIPPO_MASTER_SWITCH,
17699
17700 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17702 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17703
17704 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17705 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17706 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17707 { } /* end */
17708};
17709
17710static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17711 ALC262_HIPPO_MASTER_SWITCH,
17712 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17713 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17714 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17715 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17716 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17717 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17718 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17721 { } /* end */
17722};
17723
17724static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17725 .ops = &snd_hda_bind_vol,
17726 .values = {
17727 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17728 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17729 0
17730 },
17731};
17732
17733static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17734 .ops = &snd_hda_bind_sw,
17735 .values = {
17736 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17737 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17738 0
17739 },
17740};
17741
17742static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17743 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17744 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17745 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17746 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17747 { } /* end */
17748};
17749
17750static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17751 .ops = &snd_hda_bind_sw,
17752 .values = {
17753 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17754 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17755 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17756 0
17757 },
17758};
17759
17760static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17761 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17762 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17764 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17765 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17766 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17767
17768 { } /* end */
17769};
17770
17771static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17772 .ops = &snd_hda_bind_sw,
17773 .values = {
17774 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17775 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17776 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17777 0
17778 },
17779};
17780
17781static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17782 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17783 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17785 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17786 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17787 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17788 { } /* end */
17789};
17790
17791static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17792 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17793 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17794 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17797 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17798 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17799 { } /* end */
17800};
17801
17802static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17803 .ops = &snd_hda_bind_vol,
17804 .values = {
17805 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17806 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17807 0
17808 },
17809};
17810
17811static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17812 .ops = &snd_hda_bind_sw,
17813 .values = {
17814 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17815 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17816 0
17817 },
17818};
17819
17820static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17821 HDA_BIND_VOL("Master Playback Volume",
17822 &alc663_asus_two_bind_master_vol),
17823 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17824 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17825 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17826 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17827 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17828 { } /* end */
17829};
17830
17831static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17832 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17833 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17834 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17837 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17838 { } /* end */
17839};
17840
17841static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17842 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17843 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17844 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17845 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17846 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17847
17848 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17849 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17850 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17851 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17852 { } /* end */
17853};
17854
17855static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17856 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17857 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17858 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17859
17860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17861 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17862 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17863 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17864 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17865 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17866 { } /* end */
17867};
17868
17869static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17870 .ops = &snd_hda_bind_sw,
17871 .values = {
17872 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17873 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17874 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17875 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17876 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17877 0
17878 },
17879};
17880
17881static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17882 .ops = &snd_hda_bind_sw,
17883 .values = {
17884 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17885 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17886 0
17887 },
17888};
17889
17890static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17891 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17892 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17893 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17894 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17895 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17896 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17897 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17900 { } /* end */
17901};
17902
17903static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17904 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17905 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17906 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17907 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17908 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17909 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17910 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17911 { } /* end */
17912};
17913
17914
17915static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17916 {
17917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17918 .name = "Channel Mode",
17919 .info = alc_ch_mode_info,
17920 .get = alc_ch_mode_get,
17921 .put = alc_ch_mode_put,
17922 },
17923 { } /* end */
17924};
17925
17926static const struct hda_verb alc662_init_verbs[] = {
17927 /* ADC: mute amp left and right */
17928 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17929 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17930
17931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17935 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17937
17938 /* Front Pin: output 0 (0x0c) */
17939 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17940 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17941
17942 /* Rear Pin: output 1 (0x0d) */
17943 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17944 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17945
17946 /* CLFE Pin: output 2 (0x0e) */
17947 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17948 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17949
17950 /* Mic (rear) pin: input vref at 80% */
17951 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17952 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17953 /* Front Mic pin: input vref at 80% */
17954 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17955 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17956 /* Line In pin: input */
17957 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17958 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17959 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17960 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17961 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17962 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17963 /* CD pin widget for input */
17964 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17965
17966 /* FIXME: use matrix-type input source selection */
17967 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17968 /* Input mixer */
17969 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17970 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17971
17972 { }
17973};
17974
17975static const struct hda_verb alc662_eapd_init_verbs[] = {
17976 /* always trun on EAPD */
17977 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17978 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17979 { }
17980};
17981
17982static const struct hda_verb alc662_sue_init_verbs[] = {
17983 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17984 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17985 {}
17986};
17987
17988static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17989 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17990 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17991 {}
17992};
17993
17994/* Set Unsolicited Event*/
17995static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17996 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17997 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17998 {}
17999};
18000
18001static const struct hda_verb alc663_m51va_init_verbs[] = {
18002 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18003 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18004 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18005 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18006 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18009 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18010 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18011 {}
18012};
18013
18014static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
18015 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18016 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18017 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18020 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18021 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18022 {}
18023};
18024
18025static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18026 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18027 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18028 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18029 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18030 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18032 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18033 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18034 {}
18035};
18036
18037static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
18038 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18039 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18040 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18041 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18043 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18044 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18045 {}
18046};
18047
18048static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18049 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18050 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18051 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18052 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18054 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18055 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18058 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18059 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18060 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18061 {}
18062};
18063
18064static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18065 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18066 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18067 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18068 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18069 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18070 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18071 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18074 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18075 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18076 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18077 {}
18078};
18079
18080static const struct hda_verb alc663_g71v_init_verbs[] = {
18081 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18082 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18083 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18084
18085 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18086 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18087 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18088
18089 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18090 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18091 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18092 {}
18093};
18094
18095static const struct hda_verb alc663_g50v_init_verbs[] = {
18096 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18097 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18098 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18099
18100 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18101 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18102 {}
18103};
18104
18105static const struct hda_verb alc662_ecs_init_verbs[] = {
18106 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18107 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18108 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18109 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18110 {}
18111};
18112
18113static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
18114 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18115 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18117 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18118 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18119 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18120 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18121 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18123 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18124 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18125 {}
18126};
18127
18128static const struct hda_verb alc272_dell_init_verbs[] = {
18129 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18130 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18131 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18132 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18133 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18134 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18135 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18136 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18137 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18138 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18139 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18140 {}
18141};
18142
18143static const struct hda_verb alc663_mode7_init_verbs[] = {
18144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18146 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18147 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18148 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18149 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18150 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18151 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18152 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18153 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18156 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18157 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18158 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18159 {}
18160};
18161
18162static const struct hda_verb alc663_mode8_init_verbs[] = {
18163 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18165 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18166 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18167 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18168 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18169 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18170 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18171 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18172 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18173 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18174 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18175 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18176 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18177 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18178 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18179 {}
18180};
18181
18182static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18183 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18184 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18185 { } /* end */
18186};
18187
18188static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18189 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18190 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18191 { } /* end */
18192};
18193
18194static void alc662_lenovo_101e_setup(struct hda_codec *codec)
18195{
18196 struct alc_spec *spec = codec->spec;
18197
18198 spec->autocfg.hp_pins[0] = 0x1b;
18199 spec->autocfg.line_out_pins[0] = 0x14;
18200 spec->autocfg.speaker_pins[0] = 0x15;
18201 spec->automute = 1;
18202 spec->detect_line = 1;
18203 spec->automute_lines = 1;
18204 spec->automute_mode = ALC_AUTOMUTE_AMP;
18205}
18206
18207static void alc662_eeepc_setup(struct hda_codec *codec)
18208{
18209 struct alc_spec *spec = codec->spec;
18210
18211 alc262_hippo1_setup(codec);
18212 spec->ext_mic.pin = 0x18;
18213 spec->ext_mic.mux_idx = 0;
18214 spec->int_mic.pin = 0x19;
18215 spec->int_mic.mux_idx = 1;
18216 spec->auto_mic = 1;
18217}
18218
18219static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18220{
18221 struct alc_spec *spec = codec->spec;
18222
18223 spec->autocfg.hp_pins[0] = 0x14;
18224 spec->autocfg.speaker_pins[0] = 0x1b;
18225 spec->automute = 1;
18226 spec->automute_mode = ALC_AUTOMUTE_AMP;
18227}
18228
18229static void alc663_m51va_setup(struct hda_codec *codec)
18230{
18231 struct alc_spec *spec = codec->spec;
18232 spec->autocfg.hp_pins[0] = 0x21;
18233 spec->autocfg.speaker_pins[0] = 0x14;
18234 spec->automute_mixer_nid[0] = 0x0c;
18235 spec->automute = 1;
18236 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18237 spec->ext_mic.pin = 0x18;
18238 spec->ext_mic.mux_idx = 0;
18239 spec->int_mic.pin = 0x12;
18240 spec->int_mic.mux_idx = 9;
18241 spec->auto_mic = 1;
18242}
18243
18244/* ***************** Mode1 ******************************/
18245static void alc663_mode1_setup(struct hda_codec *codec)
18246{
18247 struct alc_spec *spec = codec->spec;
18248 spec->autocfg.hp_pins[0] = 0x21;
18249 spec->autocfg.speaker_pins[0] = 0x14;
18250 spec->automute_mixer_nid[0] = 0x0c;
18251 spec->automute = 1;
18252 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18253 spec->ext_mic.pin = 0x18;
18254 spec->ext_mic.mux_idx = 0;
18255 spec->int_mic.pin = 0x19;
18256 spec->int_mic.mux_idx = 1;
18257 spec->auto_mic = 1;
18258}
18259
18260/* ***************** Mode2 ******************************/
18261static void alc662_mode2_setup(struct hda_codec *codec)
18262{
18263 struct alc_spec *spec = codec->spec;
18264 spec->autocfg.hp_pins[0] = 0x1b;
18265 spec->autocfg.speaker_pins[0] = 0x14;
18266 spec->automute = 1;
18267 spec->automute_mode = ALC_AUTOMUTE_PIN;
18268 spec->ext_mic.pin = 0x18;
18269 spec->ext_mic.mux_idx = 0;
18270 spec->int_mic.pin = 0x19;
18271 spec->int_mic.mux_idx = 1;
18272 spec->auto_mic = 1;
18273}
18274
18275/* ***************** Mode3 ******************************/
18276static void alc663_mode3_setup(struct hda_codec *codec)
18277{
18278 struct alc_spec *spec = codec->spec;
18279 spec->autocfg.hp_pins[0] = 0x21;
18280 spec->autocfg.hp_pins[0] = 0x15;
18281 spec->autocfg.speaker_pins[0] = 0x14;
18282 spec->automute = 1;
18283 spec->automute_mode = ALC_AUTOMUTE_PIN;
18284 spec->ext_mic.pin = 0x18;
18285 spec->ext_mic.mux_idx = 0;
18286 spec->int_mic.pin = 0x19;
18287 spec->int_mic.mux_idx = 1;
18288 spec->auto_mic = 1;
18289}
18290
18291/* ***************** Mode4 ******************************/
18292static void alc663_mode4_setup(struct hda_codec *codec)
18293{
18294 struct alc_spec *spec = codec->spec;
18295 spec->autocfg.hp_pins[0] = 0x21;
18296 spec->autocfg.speaker_pins[0] = 0x14;
18297 spec->autocfg.speaker_pins[1] = 0x16;
18298 spec->automute_mixer_nid[0] = 0x0c;
18299 spec->automute_mixer_nid[1] = 0x0e;
18300 spec->automute = 1;
18301 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18302 spec->ext_mic.pin = 0x18;
18303 spec->ext_mic.mux_idx = 0;
18304 spec->int_mic.pin = 0x19;
18305 spec->int_mic.mux_idx = 1;
18306 spec->auto_mic = 1;
18307}
18308
18309/* ***************** Mode5 ******************************/
18310static void alc663_mode5_setup(struct hda_codec *codec)
18311{
18312 struct alc_spec *spec = codec->spec;
18313 spec->autocfg.hp_pins[0] = 0x15;
18314 spec->autocfg.speaker_pins[0] = 0x14;
18315 spec->autocfg.speaker_pins[1] = 0x16;
18316 spec->automute_mixer_nid[0] = 0x0c;
18317 spec->automute_mixer_nid[1] = 0x0e;
18318 spec->automute = 1;
18319 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18320 spec->ext_mic.pin = 0x18;
18321 spec->ext_mic.mux_idx = 0;
18322 spec->int_mic.pin = 0x19;
18323 spec->int_mic.mux_idx = 1;
18324 spec->auto_mic = 1;
18325}
18326
18327/* ***************** Mode6 ******************************/
18328static void alc663_mode6_setup(struct hda_codec *codec)
18329{
18330 struct alc_spec *spec = codec->spec;
18331 spec->autocfg.hp_pins[0] = 0x1b;
18332 spec->autocfg.hp_pins[0] = 0x15;
18333 spec->autocfg.speaker_pins[0] = 0x14;
18334 spec->automute_mixer_nid[0] = 0x0c;
18335 spec->automute = 1;
18336 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18337 spec->ext_mic.pin = 0x18;
18338 spec->ext_mic.mux_idx = 0;
18339 spec->int_mic.pin = 0x19;
18340 spec->int_mic.mux_idx = 1;
18341 spec->auto_mic = 1;
18342}
18343
18344/* ***************** Mode7 ******************************/
18345static void alc663_mode7_setup(struct hda_codec *codec)
18346{
18347 struct alc_spec *spec = codec->spec;
18348 spec->autocfg.hp_pins[0] = 0x1b;
18349 spec->autocfg.hp_pins[0] = 0x21;
18350 spec->autocfg.speaker_pins[0] = 0x14;
18351 spec->autocfg.speaker_pins[0] = 0x17;
18352 spec->automute = 1;
18353 spec->automute_mode = ALC_AUTOMUTE_PIN;
18354 spec->ext_mic.pin = 0x18;
18355 spec->ext_mic.mux_idx = 0;
18356 spec->int_mic.pin = 0x19;
18357 spec->int_mic.mux_idx = 1;
18358 spec->auto_mic = 1;
18359}
18360
18361/* ***************** Mode8 ******************************/
18362static void alc663_mode8_setup(struct hda_codec *codec)
18363{
18364 struct alc_spec *spec = codec->spec;
18365 spec->autocfg.hp_pins[0] = 0x21;
18366 spec->autocfg.hp_pins[1] = 0x15;
18367 spec->autocfg.speaker_pins[0] = 0x14;
18368 spec->autocfg.speaker_pins[0] = 0x17;
18369 spec->automute = 1;
18370 spec->automute_mode = ALC_AUTOMUTE_PIN;
18371 spec->ext_mic.pin = 0x18;
18372 spec->ext_mic.mux_idx = 0;
18373 spec->int_mic.pin = 0x12;
18374 spec->int_mic.mux_idx = 9;
18375 spec->auto_mic = 1;
18376}
18377
18378static void alc663_g71v_setup(struct hda_codec *codec)
18379{
18380 struct alc_spec *spec = codec->spec;
18381 spec->autocfg.hp_pins[0] = 0x21;
18382 spec->autocfg.line_out_pins[0] = 0x15;
18383 spec->autocfg.speaker_pins[0] = 0x14;
18384 spec->automute = 1;
18385 spec->automute_mode = ALC_AUTOMUTE_AMP;
18386 spec->detect_line = 1;
18387 spec->automute_lines = 1;
18388 spec->ext_mic.pin = 0x18;
18389 spec->ext_mic.mux_idx = 0;
18390 spec->int_mic.pin = 0x12;
18391 spec->int_mic.mux_idx = 9;
18392 spec->auto_mic = 1;
18393}
18394
18395#define alc663_g50v_setup alc663_m51va_setup
18396
18397static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
18398 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18399 ALC262_HIPPO_MASTER_SWITCH,
18400
18401 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18402 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18403 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18404
18405 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18406 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18407 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18408 { } /* end */
18409};
18410
18411static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
18412 /* Master Playback automatically created from Speaker and Headphone */
18413 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18414 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18415 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18416 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18417
18418 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18419 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18420 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18421
18422 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18423 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18424 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18425 { } /* end */
18426};
18427
18428#ifdef CONFIG_SND_HDA_POWER_SAVE 5036#ifdef CONFIG_SND_HDA_POWER_SAVE
18429#define alc662_loopbacks alc880_loopbacks 5037#define alc662_loopbacks alc880_loopbacks
18430#endif 5038#endif
18431 5039
18432
18433/* pcm configuration: identical with ALC880 */
18434#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18435#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18436#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18437#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18438
18439/*
18440 * configuration and preset
18441 */
18442static const char * const alc662_models[ALC662_MODEL_LAST] = {
18443 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18444 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18445 [ALC662_3ST_6ch] = "3stack-6ch",
18446 [ALC662_5ST_DIG] = "5stack-dig",
18447 [ALC662_LENOVO_101E] = "lenovo-101e",
18448 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18449 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18450 [ALC662_ECS] = "ecs",
18451 [ALC663_ASUS_M51VA] = "m51va",
18452 [ALC663_ASUS_G71V] = "g71v",
18453 [ALC663_ASUS_H13] = "h13",
18454 [ALC663_ASUS_G50V] = "g50v",
18455 [ALC663_ASUS_MODE1] = "asus-mode1",
18456 [ALC662_ASUS_MODE2] = "asus-mode2",
18457 [ALC663_ASUS_MODE3] = "asus-mode3",
18458 [ALC663_ASUS_MODE4] = "asus-mode4",
18459 [ALC663_ASUS_MODE5] = "asus-mode5",
18460 [ALC663_ASUS_MODE6] = "asus-mode6",
18461 [ALC663_ASUS_MODE7] = "asus-mode7",
18462 [ALC663_ASUS_MODE8] = "asus-mode8",
18463 [ALC272_DELL] = "dell",
18464 [ALC272_DELL_ZM1] = "dell-zm1",
18465 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
18466 [ALC662_AUTO] = "auto",
18467};
18468
18469static const struct snd_pci_quirk alc662_cfg_tbl[] = {
18470 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18471 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18472 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18473 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18474 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18475 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18476 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18477 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18478 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18479 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18480 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18481 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18482 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18483 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18484 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18485 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18486 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18487 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18488 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18489 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18490 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18491 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18492 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18493 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18494 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18495 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18496 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18497 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18498 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18499 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18500 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18501 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18502 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18503 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18504 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18505 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18506 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18507 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18508 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18509 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18510 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18511 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18512 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18513 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18514 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18515 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18516 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18517 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18518 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18519 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18520 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18521 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18522 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18523 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18524 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18525 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18526 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18527 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18528 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18529 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18530 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18531 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18532 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18533 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18534 ALC662_3ST_6ch_DIG),
18535 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18536 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18537 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18538 ALC662_3ST_6ch_DIG),
18539 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18540 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18541 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18542 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18543 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18544 ALC662_3ST_6ch_DIG),
18545 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18546 ALC663_ASUS_H13),
18547 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
18548 {}
18549};
18550
18551static const struct alc_config_preset alc662_presets[] = {
18552 [ALC662_3ST_2ch_DIG] = {
18553 .mixers = { alc662_3ST_2ch_mixer },
18554 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18555 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18556 .dac_nids = alc662_dac_nids,
18557 .dig_out_nid = ALC662_DIGOUT_NID,
18558 .dig_in_nid = ALC662_DIGIN_NID,
18559 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18560 .channel_mode = alc662_3ST_2ch_modes,
18561 .input_mux = &alc662_capture_source,
18562 },
18563 [ALC662_3ST_6ch_DIG] = {
18564 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18565 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18566 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18567 .dac_nids = alc662_dac_nids,
18568 .dig_out_nid = ALC662_DIGOUT_NID,
18569 .dig_in_nid = ALC662_DIGIN_NID,
18570 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18571 .channel_mode = alc662_3ST_6ch_modes,
18572 .need_dac_fix = 1,
18573 .input_mux = &alc662_capture_source,
18574 },
18575 [ALC662_3ST_6ch] = {
18576 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18577 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18578 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18579 .dac_nids = alc662_dac_nids,
18580 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18581 .channel_mode = alc662_3ST_6ch_modes,
18582 .need_dac_fix = 1,
18583 .input_mux = &alc662_capture_source,
18584 },
18585 [ALC662_5ST_DIG] = {
18586 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18587 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18588 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18589 .dac_nids = alc662_dac_nids,
18590 .dig_out_nid = ALC662_DIGOUT_NID,
18591 .dig_in_nid = ALC662_DIGIN_NID,
18592 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18593 .channel_mode = alc662_5stack_modes,
18594 .input_mux = &alc662_capture_source,
18595 },
18596 [ALC662_LENOVO_101E] = {
18597 .mixers = { alc662_lenovo_101e_mixer },
18598 .init_verbs = { alc662_init_verbs,
18599 alc662_eapd_init_verbs,
18600 alc662_sue_init_verbs },
18601 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18602 .dac_nids = alc662_dac_nids,
18603 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18604 .channel_mode = alc662_3ST_2ch_modes,
18605 .input_mux = &alc662_lenovo_101e_capture_source,
18606 .unsol_event = alc_sku_unsol_event,
18607 .setup = alc662_lenovo_101e_setup,
18608 .init_hook = alc_inithook,
18609 },
18610 [ALC662_ASUS_EEEPC_P701] = {
18611 .mixers = { alc662_eeepc_p701_mixer },
18612 .init_verbs = { alc662_init_verbs,
18613 alc662_eapd_init_verbs,
18614 alc662_eeepc_sue_init_verbs },
18615 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18616 .dac_nids = alc662_dac_nids,
18617 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18618 .channel_mode = alc662_3ST_2ch_modes,
18619 .unsol_event = alc_sku_unsol_event,
18620 .setup = alc662_eeepc_setup,
18621 .init_hook = alc_inithook,
18622 },
18623 [ALC662_ASUS_EEEPC_EP20] = {
18624 .mixers = { alc662_eeepc_ep20_mixer,
18625 alc662_chmode_mixer },
18626 .init_verbs = { alc662_init_verbs,
18627 alc662_eapd_init_verbs,
18628 alc662_eeepc_ep20_sue_init_verbs },
18629 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18630 .dac_nids = alc662_dac_nids,
18631 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18632 .channel_mode = alc662_3ST_6ch_modes,
18633 .input_mux = &alc662_lenovo_101e_capture_source,
18634 .unsol_event = alc_sku_unsol_event,
18635 .setup = alc662_eeepc_ep20_setup,
18636 .init_hook = alc_inithook,
18637 },
18638 [ALC662_ECS] = {
18639 .mixers = { alc662_ecs_mixer },
18640 .init_verbs = { alc662_init_verbs,
18641 alc662_eapd_init_verbs,
18642 alc662_ecs_init_verbs },
18643 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18644 .dac_nids = alc662_dac_nids,
18645 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18646 .channel_mode = alc662_3ST_2ch_modes,
18647 .unsol_event = alc_sku_unsol_event,
18648 .setup = alc662_eeepc_setup,
18649 .init_hook = alc_inithook,
18650 },
18651 [ALC663_ASUS_M51VA] = {
18652 .mixers = { alc663_m51va_mixer },
18653 .init_verbs = { alc662_init_verbs,
18654 alc662_eapd_init_verbs,
18655 alc663_m51va_init_verbs },
18656 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18657 .dac_nids = alc662_dac_nids,
18658 .dig_out_nid = ALC662_DIGOUT_NID,
18659 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18660 .channel_mode = alc662_3ST_2ch_modes,
18661 .unsol_event = alc_sku_unsol_event,
18662 .setup = alc663_m51va_setup,
18663 .init_hook = alc_inithook,
18664 },
18665 [ALC663_ASUS_G71V] = {
18666 .mixers = { alc663_g71v_mixer },
18667 .init_verbs = { alc662_init_verbs,
18668 alc662_eapd_init_verbs,
18669 alc663_g71v_init_verbs },
18670 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18671 .dac_nids = alc662_dac_nids,
18672 .dig_out_nid = ALC662_DIGOUT_NID,
18673 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18674 .channel_mode = alc662_3ST_2ch_modes,
18675 .unsol_event = alc_sku_unsol_event,
18676 .setup = alc663_g71v_setup,
18677 .init_hook = alc_inithook,
18678 },
18679 [ALC663_ASUS_H13] = {
18680 .mixers = { alc663_m51va_mixer },
18681 .init_verbs = { alc662_init_verbs,
18682 alc662_eapd_init_verbs,
18683 alc663_m51va_init_verbs },
18684 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18685 .dac_nids = alc662_dac_nids,
18686 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18687 .channel_mode = alc662_3ST_2ch_modes,
18688 .setup = alc663_m51va_setup,
18689 .unsol_event = alc_sku_unsol_event,
18690 .init_hook = alc_inithook,
18691 },
18692 [ALC663_ASUS_G50V] = {
18693 .mixers = { alc663_g50v_mixer },
18694 .init_verbs = { alc662_init_verbs,
18695 alc662_eapd_init_verbs,
18696 alc663_g50v_init_verbs },
18697 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18698 .dac_nids = alc662_dac_nids,
18699 .dig_out_nid = ALC662_DIGOUT_NID,
18700 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18701 .channel_mode = alc662_3ST_6ch_modes,
18702 .input_mux = &alc663_capture_source,
18703 .unsol_event = alc_sku_unsol_event,
18704 .setup = alc663_g50v_setup,
18705 .init_hook = alc_inithook,
18706 },
18707 [ALC663_ASUS_MODE1] = {
18708 .mixers = { alc663_m51va_mixer },
18709 .cap_mixer = alc662_auto_capture_mixer,
18710 .init_verbs = { alc662_init_verbs,
18711 alc662_eapd_init_verbs,
18712 alc663_21jd_amic_init_verbs },
18713 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18714 .hp_nid = 0x03,
18715 .dac_nids = alc662_dac_nids,
18716 .dig_out_nid = ALC662_DIGOUT_NID,
18717 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18718 .channel_mode = alc662_3ST_2ch_modes,
18719 .unsol_event = alc_sku_unsol_event,
18720 .setup = alc663_mode1_setup,
18721 .init_hook = alc_inithook,
18722 },
18723 [ALC662_ASUS_MODE2] = {
18724 .mixers = { alc662_1bjd_mixer },
18725 .cap_mixer = alc662_auto_capture_mixer,
18726 .init_verbs = { alc662_init_verbs,
18727 alc662_eapd_init_verbs,
18728 alc662_1bjd_amic_init_verbs },
18729 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18730 .dac_nids = alc662_dac_nids,
18731 .dig_out_nid = ALC662_DIGOUT_NID,
18732 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18733 .channel_mode = alc662_3ST_2ch_modes,
18734 .unsol_event = alc_sku_unsol_event,
18735 .setup = alc662_mode2_setup,
18736 .init_hook = alc_inithook,
18737 },
18738 [ALC663_ASUS_MODE3] = {
18739 .mixers = { alc663_two_hp_m1_mixer },
18740 .cap_mixer = alc662_auto_capture_mixer,
18741 .init_verbs = { alc662_init_verbs,
18742 alc662_eapd_init_verbs,
18743 alc663_two_hp_amic_m1_init_verbs },
18744 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18745 .hp_nid = 0x03,
18746 .dac_nids = alc662_dac_nids,
18747 .dig_out_nid = ALC662_DIGOUT_NID,
18748 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18749 .channel_mode = alc662_3ST_2ch_modes,
18750 .unsol_event = alc_sku_unsol_event,
18751 .setup = alc663_mode3_setup,
18752 .init_hook = alc_inithook,
18753 },
18754 [ALC663_ASUS_MODE4] = {
18755 .mixers = { alc663_asus_21jd_clfe_mixer },
18756 .cap_mixer = alc662_auto_capture_mixer,
18757 .init_verbs = { alc662_init_verbs,
18758 alc662_eapd_init_verbs,
18759 alc663_21jd_amic_init_verbs},
18760 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18761 .hp_nid = 0x03,
18762 .dac_nids = alc662_dac_nids,
18763 .dig_out_nid = ALC662_DIGOUT_NID,
18764 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18765 .channel_mode = alc662_3ST_2ch_modes,
18766 .unsol_event = alc_sku_unsol_event,
18767 .setup = alc663_mode4_setup,
18768 .init_hook = alc_inithook,
18769 },
18770 [ALC663_ASUS_MODE5] = {
18771 .mixers = { alc663_asus_15jd_clfe_mixer },
18772 .cap_mixer = alc662_auto_capture_mixer,
18773 .init_verbs = { alc662_init_verbs,
18774 alc662_eapd_init_verbs,
18775 alc663_15jd_amic_init_verbs },
18776 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18777 .hp_nid = 0x03,
18778 .dac_nids = alc662_dac_nids,
18779 .dig_out_nid = ALC662_DIGOUT_NID,
18780 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18781 .channel_mode = alc662_3ST_2ch_modes,
18782 .unsol_event = alc_sku_unsol_event,
18783 .setup = alc663_mode5_setup,
18784 .init_hook = alc_inithook,
18785 },
18786 [ALC663_ASUS_MODE6] = {
18787 .mixers = { alc663_two_hp_m2_mixer },
18788 .cap_mixer = alc662_auto_capture_mixer,
18789 .init_verbs = { alc662_init_verbs,
18790 alc662_eapd_init_verbs,
18791 alc663_two_hp_amic_m2_init_verbs },
18792 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18793 .hp_nid = 0x03,
18794 .dac_nids = alc662_dac_nids,
18795 .dig_out_nid = ALC662_DIGOUT_NID,
18796 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18797 .channel_mode = alc662_3ST_2ch_modes,
18798 .unsol_event = alc_sku_unsol_event,
18799 .setup = alc663_mode6_setup,
18800 .init_hook = alc_inithook,
18801 },
18802 [ALC663_ASUS_MODE7] = {
18803 .mixers = { alc663_mode7_mixer },
18804 .cap_mixer = alc662_auto_capture_mixer,
18805 .init_verbs = { alc662_init_verbs,
18806 alc662_eapd_init_verbs,
18807 alc663_mode7_init_verbs },
18808 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18809 .hp_nid = 0x03,
18810 .dac_nids = alc662_dac_nids,
18811 .dig_out_nid = ALC662_DIGOUT_NID,
18812 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18813 .channel_mode = alc662_3ST_2ch_modes,
18814 .unsol_event = alc_sku_unsol_event,
18815 .setup = alc663_mode7_setup,
18816 .init_hook = alc_inithook,
18817 },
18818 [ALC663_ASUS_MODE8] = {
18819 .mixers = { alc663_mode8_mixer },
18820 .cap_mixer = alc662_auto_capture_mixer,
18821 .init_verbs = { alc662_init_verbs,
18822 alc662_eapd_init_verbs,
18823 alc663_mode8_init_verbs },
18824 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18825 .hp_nid = 0x03,
18826 .dac_nids = alc662_dac_nids,
18827 .dig_out_nid = ALC662_DIGOUT_NID,
18828 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18829 .channel_mode = alc662_3ST_2ch_modes,
18830 .unsol_event = alc_sku_unsol_event,
18831 .setup = alc663_mode8_setup,
18832 .init_hook = alc_inithook,
18833 },
18834 [ALC272_DELL] = {
18835 .mixers = { alc663_m51va_mixer },
18836 .cap_mixer = alc272_auto_capture_mixer,
18837 .init_verbs = { alc662_init_verbs,
18838 alc662_eapd_init_verbs,
18839 alc272_dell_init_verbs },
18840 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18841 .dac_nids = alc272_dac_nids,
18842 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18843 .adc_nids = alc272_adc_nids,
18844 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18845 .capsrc_nids = alc272_capsrc_nids,
18846 .channel_mode = alc662_3ST_2ch_modes,
18847 .unsol_event = alc_sku_unsol_event,
18848 .setup = alc663_m51va_setup,
18849 .init_hook = alc_inithook,
18850 },
18851 [ALC272_DELL_ZM1] = {
18852 .mixers = { alc663_m51va_mixer },
18853 .cap_mixer = alc662_auto_capture_mixer,
18854 .init_verbs = { alc662_init_verbs,
18855 alc662_eapd_init_verbs,
18856 alc272_dell_zm1_init_verbs },
18857 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18858 .dac_nids = alc272_dac_nids,
18859 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18860 .adc_nids = alc662_adc_nids,
18861 .num_adc_nids = 1,
18862 .capsrc_nids = alc662_capsrc_nids,
18863 .channel_mode = alc662_3ST_2ch_modes,
18864 .unsol_event = alc_sku_unsol_event,
18865 .setup = alc663_m51va_setup,
18866 .init_hook = alc_inithook,
18867 },
18868 [ALC272_SAMSUNG_NC10] = {
18869 .mixers = { alc272_nc10_mixer },
18870 .init_verbs = { alc662_init_verbs,
18871 alc662_eapd_init_verbs,
18872 alc663_21jd_amic_init_verbs },
18873 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18874 .dac_nids = alc272_dac_nids,
18875 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18876 .channel_mode = alc662_3ST_2ch_modes,
18877 /*.input_mux = &alc272_nc10_capture_source,*/
18878 .unsol_event = alc_sku_unsol_event,
18879 .setup = alc663_mode4_setup,
18880 .init_hook = alc_inithook,
18881 },
18882};
18883
18884
18885/* 5040/*
18886 * BIOS auto configuration 5041 * BIOS auto configuration
18887 */ 5042 */
18888 5043
18889/* convert from MIX nid to DAC */
18890static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18891{
18892 hda_nid_t list[5];
18893 int i, num;
18894
18895 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18896 for (i = 0; i < num; i++) {
18897 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18898 return list[i];
18899 }
18900 return 0;
18901}
18902
18903/* go down to the selector widget before the mixer */
18904static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18905{
18906 hda_nid_t srcs[5];
18907 int num = snd_hda_get_connections(codec, pin, srcs,
18908 ARRAY_SIZE(srcs));
18909 if (num != 1 ||
18910 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18911 return pin;
18912 return srcs[0];
18913}
18914
18915/* get MIX nid connected to the given pin targeted to DAC */
18916static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18917 hda_nid_t dac)
18918{
18919 hda_nid_t mix[5];
18920 int i, num;
18921
18922 pin = alc_go_down_to_selector(codec, pin);
18923 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18924 for (i = 0; i < num; i++) {
18925 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18926 return mix[i];
18927 }
18928 return 0;
18929}
18930
18931/* select the connection from pin to DAC if needed */
18932static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18933 hda_nid_t dac)
18934{
18935 hda_nid_t mix[5];
18936 int i, num;
18937
18938 pin = alc_go_down_to_selector(codec, pin);
18939 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18940 if (num < 2)
18941 return 0;
18942 for (i = 0; i < num; i++) {
18943 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18944 snd_hda_codec_update_cache(codec, pin, 0,
18945 AC_VERB_SET_CONNECT_SEL, i);
18946 return 0;
18947 }
18948 }
18949 return 0;
18950}
18951
18952/* look for an empty DAC slot */
18953static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18954{
18955 struct alc_spec *spec = codec->spec;
18956 hda_nid_t srcs[5];
18957 int i, j, num;
18958
18959 pin = alc_go_down_to_selector(codec, pin);
18960 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18961 for (i = 0; i < num; i++) {
18962 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18963 if (!nid)
18964 continue;
18965 for (j = 0; j < spec->multiout.num_dacs; j++)
18966 if (spec->multiout.dac_nids[j] == nid)
18967 break;
18968 if (j >= spec->multiout.num_dacs)
18969 return nid;
18970 }
18971 return 0;
18972}
18973
18974/* fill in the dac_nids table from the parsed pin configuration */
18975static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18976 const struct auto_pin_cfg *cfg)
18977{
18978 struct alc_spec *spec = codec->spec;
18979 int i;
18980 hda_nid_t dac;
18981
18982 spec->multiout.dac_nids = spec->private_dac_nids;
18983 for (i = 0; i < cfg->line_outs; i++) {
18984 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
18985 if (!dac)
18986 continue;
18987 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
18988 }
18989 return 0;
18990}
18991
18992static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18993 hda_nid_t nid, int idx, unsigned int chs)
18994{
18995 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
18996 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18997}
18998
18999static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19000 hda_nid_t nid, int idx, unsigned int chs)
19001{
19002 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19003 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19004}
19005
19006#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19007 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19008#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19009 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19010#define alc662_add_stereo_vol(spec, pfx, nid) \
19011 alc662_add_vol_ctl(spec, pfx, nid, 3)
19012#define alc662_add_stereo_sw(spec, pfx, nid) \
19013 alc662_add_sw_ctl(spec, pfx, nid, 3)
19014
19015/* add playback controls from the parsed DAC table */
19016static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19017 const struct auto_pin_cfg *cfg)
19018{
19019 struct alc_spec *spec = codec->spec;
19020 static const char * const chname[4] = {
19021 "Front", "Surround", NULL /*CLFE*/, "Side"
19022 };
19023 const char *pfx = alc_get_line_out_pfx(spec, true);
19024 hda_nid_t nid, mix, pin;
19025 int i, err, noutputs;
19026
19027 noutputs = cfg->line_outs;
19028 if (spec->multi_ios > 0)
19029 noutputs += spec->multi_ios;
19030
19031 for (i = 0; i < noutputs; i++) {
19032 nid = spec->multiout.dac_nids[i];
19033 if (!nid)
19034 continue;
19035 if (i >= cfg->line_outs)
19036 pin = spec->multi_io[i - 1].pin;
19037 else
19038 pin = cfg->line_out_pins[i];
19039 mix = alc_auto_dac_to_mix(codec, pin, nid);
19040 if (!mix)
19041 continue;
19042 if (!pfx && i == 2) {
19043 /* Center/LFE */
19044 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19045 if (err < 0)
19046 return err;
19047 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
19048 if (err < 0)
19049 return err;
19050 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
19051 if (err < 0)
19052 return err;
19053 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
19054 if (err < 0)
19055 return err;
19056 } else {
19057 const char *name = pfx;
19058 int index = i;
19059 if (!name) {
19060 name = chname[i];
19061 index = 0;
19062 }
19063 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
19064 if (err < 0)
19065 return err;
19066 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
19067 if (err < 0)
19068 return err;
19069 }
19070 }
19071 return 0;
19072}
19073
19074/* add playback controls for speaker and HP outputs */
19075/* return DAC nid if any new DAC is assigned */
19076static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19077 const char *pfx)
19078{
19079 struct alc_spec *spec = codec->spec;
19080 hda_nid_t nid, mix;
19081 int err;
19082
19083 if (!pin)
19084 return 0;
19085 nid = alc_auto_look_for_dac(codec, pin);
19086 if (!nid) {
19087 /* the corresponding DAC is already occupied */
19088 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19089 return 0; /* no way */
19090 /* create a switch only */
19091 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
19092 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19093 }
19094
19095 mix = alc_auto_dac_to_mix(codec, pin, nid);
19096 if (!mix)
19097 return 0;
19098 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19099 if (err < 0)
19100 return err;
19101 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19102 if (err < 0)
19103 return err;
19104 return nid;
19105}
19106
19107/* create playback/capture controls for input pins */
19108#define alc662_auto_create_input_ctls \
19109 alc882_auto_create_input_ctls
19110
19111static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19112 hda_nid_t nid, int pin_type,
19113 hda_nid_t dac)
19114{
19115 int i, num;
19116 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19117
19118 alc_set_pin_output(codec, nid, pin_type);
19119 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19120 for (i = 0; i < num; i++) {
19121 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
19122 continue;
19123 /* need the manual connection? */
19124 if (num > 1)
19125 snd_hda_codec_write(codec, nid, 0,
19126 AC_VERB_SET_CONNECT_SEL, i);
19127 /* unmute mixer widget inputs */
19128 snd_hda_codec_write(codec, srcs[i], 0,
19129 AC_VERB_SET_AMP_GAIN_MUTE,
19130 AMP_IN_UNMUTE(0));
19131 snd_hda_codec_write(codec, srcs[i], 0,
19132 AC_VERB_SET_AMP_GAIN_MUTE,
19133 AMP_IN_UNMUTE(1));
19134 return;
19135 }
19136}
19137
19138static void alc662_auto_init_multi_out(struct hda_codec *codec)
19139{
19140 struct alc_spec *spec = codec->spec;
19141 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19142 int i;
19143
19144 for (i = 0; i <= HDA_SIDE; i++) {
19145 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19146 if (nid)
19147 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
19148 spec->multiout.dac_nids[i]);
19149 }
19150}
19151
19152static void alc662_auto_init_hp_out(struct hda_codec *codec)
19153{
19154 struct alc_spec *spec = codec->spec;
19155 hda_nid_t pin;
19156
19157 pin = spec->autocfg.hp_pins[0];
19158 if (pin)
19159 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19160 spec->multiout.hp_nid);
19161 pin = spec->autocfg.speaker_pins[0];
19162 if (pin)
19163 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19164 spec->multiout.extra_out_nid[0]);
19165}
19166
19167#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19168
19169static void alc662_auto_init_analog_input(struct hda_codec *codec)
19170{
19171 struct alc_spec *spec = codec->spec;
19172 struct auto_pin_cfg *cfg = &spec->autocfg;
19173 int i;
19174
19175 for (i = 0; i < cfg->num_inputs; i++) {
19176 hda_nid_t nid = cfg->inputs[i].pin;
19177 if (alc_is_input_pin(codec, nid)) {
19178 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
19179 if (nid != ALC662_PIN_CD_NID &&
19180 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
19181 snd_hda_codec_write(codec, nid, 0,
19182 AC_VERB_SET_AMP_GAIN_MUTE,
19183 AMP_OUT_MUTE);
19184 }
19185 }
19186}
19187
19188#define alc662_auto_init_input_src alc882_auto_init_input_src
19189
19190/*
19191 * multi-io helper
19192 */
19193static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19194 unsigned int location)
19195{
19196 struct alc_spec *spec = codec->spec;
19197 struct auto_pin_cfg *cfg = &spec->autocfg;
19198 int type, i, num_pins = 0;
19199
19200 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19201 for (i = 0; i < cfg->num_inputs; i++) {
19202 hda_nid_t nid = cfg->inputs[i].pin;
19203 hda_nid_t dac;
19204 unsigned int defcfg, caps;
19205 if (cfg->inputs[i].type != type)
19206 continue;
19207 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19208 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19209 continue;
19210 if (location && get_defcfg_location(defcfg) != location)
19211 continue;
19212 caps = snd_hda_query_pin_caps(codec, nid);
19213 if (!(caps & AC_PINCAP_OUT))
19214 continue;
19215 dac = alc_auto_look_for_dac(codec, nid);
19216 if (!dac)
19217 continue;
19218 spec->multi_io[num_pins].pin = nid;
19219 spec->multi_io[num_pins].dac = dac;
19220 num_pins++;
19221 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19222 }
19223 }
19224 spec->multiout.num_dacs = 1;
19225 if (num_pins < 2)
19226 return 0;
19227 return num_pins;
19228}
19229
19230static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19231 struct snd_ctl_elem_info *uinfo)
19232{
19233 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19234 struct alc_spec *spec = codec->spec;
19235
19236 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19237 uinfo->count = 1;
19238 uinfo->value.enumerated.items = spec->multi_ios + 1;
19239 if (uinfo->value.enumerated.item > spec->multi_ios)
19240 uinfo->value.enumerated.item = spec->multi_ios;
19241 sprintf(uinfo->value.enumerated.name, "%dch",
19242 (uinfo->value.enumerated.item + 1) * 2);
19243 return 0;
19244}
19245
19246static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19247 struct snd_ctl_elem_value *ucontrol)
19248{
19249 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19250 struct alc_spec *spec = codec->spec;
19251 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19252 return 0;
19253}
19254
19255static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19256{
19257 struct alc_spec *spec = codec->spec;
19258 hda_nid_t nid = spec->multi_io[idx].pin;
19259
19260 if (!spec->multi_io[idx].ctl_in)
19261 spec->multi_io[idx].ctl_in =
19262 snd_hda_codec_read(codec, nid, 0,
19263 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19264 if (output) {
19265 snd_hda_codec_update_cache(codec, nid, 0,
19266 AC_VERB_SET_PIN_WIDGET_CONTROL,
19267 PIN_OUT);
19268 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19269 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19270 HDA_AMP_MUTE, 0);
19271 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19272 } else {
19273 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19274 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19275 HDA_AMP_MUTE, HDA_AMP_MUTE);
19276 snd_hda_codec_update_cache(codec, nid, 0,
19277 AC_VERB_SET_PIN_WIDGET_CONTROL,
19278 spec->multi_io[idx].ctl_in);
19279 }
19280 return 0;
19281}
19282
19283static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19284 struct snd_ctl_elem_value *ucontrol)
19285{
19286 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19287 struct alc_spec *spec = codec->spec;
19288 int i, ch;
19289
19290 ch = ucontrol->value.enumerated.item[0];
19291 if (ch < 0 || ch > spec->multi_ios)
19292 return -EINVAL;
19293 if (ch == (spec->ext_channel_count - 1) / 2)
19294 return 0;
19295 spec->ext_channel_count = (ch + 1) * 2;
19296 for (i = 0; i < spec->multi_ios; i++)
19297 alc_set_multi_io(codec, i, i < ch);
19298 spec->multiout.max_channels = spec->ext_channel_count;
19299 return 1;
19300}
19301
19302static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
19303 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19304 .name = "Channel Mode",
19305 .info = alc_auto_ch_mode_info,
19306 .get = alc_auto_ch_mode_get,
19307 .put = alc_auto_ch_mode_put,
19308};
19309
19310static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19311{
19312 struct alc_spec *spec = codec->spec;
19313 struct auto_pin_cfg *cfg = &spec->autocfg;
19314 unsigned int location, defcfg;
19315 int num_pins;
19316
19317 if (cfg->line_outs != 1 ||
19318 cfg->line_out_type != AUTO_PIN_LINE_OUT)
19319 return 0;
19320
19321 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19322 location = get_defcfg_location(defcfg);
19323
19324 num_pins = alc_auto_fill_multi_ios(codec, location);
19325 if (num_pins > 0) {
19326 struct snd_kcontrol_new *knew;
19327
19328 knew = alc_kcontrol_new(spec);
19329 if (!knew)
19330 return -ENOMEM;
19331 *knew = alc_auto_channel_mode_enum;
19332 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19333 if (!knew->name)
19334 return -ENOMEM;
19335
19336 spec->multi_ios = num_pins;
19337 spec->ext_channel_count = 2;
19338 spec->multiout.num_dacs = num_pins + 1;
19339 }
19340 return 0;
19341}
19342
19343static int alc662_parse_auto_config(struct hda_codec *codec) 5044static int alc662_parse_auto_config(struct hda_codec *codec)
19344{ 5045{
19345 struct alc_spec *spec = codec->spec;
19346 int err;
19347 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 5046 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19348 5047 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
19349 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5048 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
19350 alc662_ignore); 5049 const hda_nid_t *ssids;
19351 if (err < 0)
19352 return err;
19353 if (!spec->autocfg.line_outs)
19354 return 0; /* can't find valid BIOS pin config */
19355
19356 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19357 if (err < 0)
19358 return err;
19359 err = alc_auto_add_multi_channel_mode(codec);
19360 if (err < 0)
19361 return err;
19362 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19363 if (err < 0)
19364 return err;
19365 err = alc662_auto_create_extra_out(codec,
19366 spec->autocfg.speaker_pins[0],
19367 "Speaker");
19368 if (err < 0)
19369 return err;
19370 if (err)
19371 spec->multiout.extra_out_nid[0] = err;
19372 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19373 "Headphone");
19374 if (err < 0)
19375 return err;
19376 if (err)
19377 spec->multiout.hp_nid = err;
19378 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19379 if (err < 0)
19380 return err;
19381
19382 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19383
19384 alc_auto_parse_digital(codec);
19385
19386 if (spec->kctls.list)
19387 add_mixer(spec, spec->kctls.list);
19388
19389 spec->num_mux_defs = 1;
19390 spec->input_mux = &spec->private_imux[0];
19391
19392 err = alc_auto_add_mic_boost(codec);
19393 if (err < 0)
19394 return err;
19395 5050
19396 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 5051 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19397 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 5052 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19398 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); 5053 ssids = alc663_ssids;
19399 else 5054 else
19400 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 5055 ssids = alc662_ssids;
19401 5056 return alc_parse_auto_config(codec, alc662_ignore, ssids);
19402 return 1;
19403}
19404
19405/* additional initialization for auto-configuration model */
19406static void alc662_auto_init(struct hda_codec *codec)
19407{
19408 struct alc_spec *spec = codec->spec;
19409 alc662_auto_init_multi_out(codec);
19410 alc662_auto_init_hp_out(codec);
19411 alc662_auto_init_analog_input(codec);
19412 alc662_auto_init_input_src(codec);
19413 alc_auto_init_digital(codec);
19414 if (spec->unsol_event)
19415 alc_inithook(codec);
19416} 5057}
19417 5058
19418static void alc272_fixup_mario(struct hda_codec *codec, 5059static void alc272_fixup_mario(struct hda_codec *codec,
@@ -19435,6 +5076,7 @@ enum {
19435 ALC272_FIXUP_MARIO, 5076 ALC272_FIXUP_MARIO,
19436 ALC662_FIXUP_CZC_P10T, 5077 ALC662_FIXUP_CZC_P10T,
19437 ALC662_FIXUP_SKU_IGNORE, 5078 ALC662_FIXUP_SKU_IGNORE,
5079 ALC662_FIXUP_HP_RP5800,
19438}; 5080};
19439 5081
19440static const struct alc_fixup alc662_fixups[] = { 5082static const struct alc_fixup alc662_fixups[] = {
@@ -19467,12 +5109,22 @@ static const struct alc_fixup alc662_fixups[] = {
19467 .type = ALC_FIXUP_SKU, 5109 .type = ALC_FIXUP_SKU,
19468 .v.sku = ALC_FIXUP_SKU_IGNORE, 5110 .v.sku = ALC_FIXUP_SKU_IGNORE,
19469 }, 5111 },
5112 [ALC662_FIXUP_HP_RP5800] = {
5113 .type = ALC_FIXUP_PINS,
5114 .v.pins = (const struct alc_pincfg[]) {
5115 { 0x14, 0x0221201f }, /* HP out */
5116 { }
5117 },
5118 .chained = true,
5119 .chain_id = ALC662_FIXUP_SKU_IGNORE
5120 },
19470}; 5121};
19471 5122
19472static const struct snd_pci_quirk alc662_fixup_tbl[] = { 5123static const struct snd_pci_quirk alc662_fixup_tbl[] = {
19473 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 5124 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19474 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 5125 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
19475 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 5126 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
5127 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
19476 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 5128 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19477 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 5129 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19478 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 5130 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
@@ -19486,6 +5138,12 @@ static const struct alc_model_fixup alc662_fixup_models[] = {
19486}; 5138};
19487 5139
19488 5140
5141/*
5142 */
5143#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5144#include "alc662_quirks.c"
5145#endif
5146
19489static int patch_alc662(struct hda_codec *codec) 5147static int patch_alc662(struct hda_codec *codec)
19490{ 5148{
19491 struct alc_spec *spec; 5149 struct alc_spec *spec;
@@ -19498,6 +5156,8 @@ static int patch_alc662(struct hda_codec *codec)
19498 5156
19499 codec->spec = spec; 5157 codec->spec = spec;
19500 5158
5159 spec->mixer_nid = 0x0b;
5160
19501 alc_auto_parse_customize_define(codec); 5161 alc_auto_parse_customize_define(codec);
19502 5162
19503 alc_fix_pll_init(codec, 0x20, 0x04, 15); 5163 alc_fix_pll_init(codec, 0x20, 0x04, 15);
@@ -19512,16 +5172,15 @@ static int patch_alc662(struct hda_codec *codec)
19512 else if (coef == 0x4011) 5172 else if (coef == 0x4011)
19513 alc_codec_rename(codec, "ALC656"); 5173 alc_codec_rename(codec, "ALC656");
19514 5174
19515 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 5175 board_config = alc_board_config(codec, ALC662_MODEL_LAST,
19516 alc662_models, 5176 alc662_models, alc662_cfg_tbl);
19517 alc662_cfg_tbl);
19518 if (board_config < 0) { 5177 if (board_config < 0) {
19519 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5178 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19520 codec->chip_name); 5179 codec->chip_name);
19521 board_config = ALC662_AUTO; 5180 board_config = ALC_MODEL_AUTO;
19522 } 5181 }
19523 5182
19524 if (board_config == ALC662_AUTO) { 5183 if (board_config == ALC_MODEL_AUTO) {
19525 alc_pick_fixup(codec, alc662_fixup_models, 5184 alc_pick_fixup(codec, alc662_fixup_models,
19526 alc662_fixup_tbl, alc662_fixups); 5185 alc662_fixup_tbl, alc662_fixups);
19527 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5186 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
@@ -19530,42 +5189,35 @@ static int patch_alc662(struct hda_codec *codec)
19530 if (err < 0) { 5189 if (err < 0) {
19531 alc_free(codec); 5190 alc_free(codec);
19532 return err; 5191 return err;
19533 } else if (!err) { 5192 }
5193#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5194 else if (!err) {
19534 printk(KERN_INFO 5195 printk(KERN_INFO
19535 "hda_codec: Cannot set up configuration " 5196 "hda_codec: Cannot set up configuration "
19536 "from BIOS. Using base mode...\n"); 5197 "from BIOS. Using base mode...\n");
19537 board_config = ALC662_3ST_2ch_DIG; 5198 board_config = ALC662_3ST_2ch_DIG;
19538 } 5199 }
5200#endif
19539 } 5201 }
19540 5202
19541 if (has_cdefine_beep(codec)) { 5203 if (board_config != ALC_MODEL_AUTO)
19542 err = snd_hda_attach_beep_device(codec, 0x1);
19543 if (err < 0) {
19544 alc_free(codec);
19545 return err;
19546 }
19547 }
19548
19549 if (board_config != ALC662_AUTO)
19550 setup_preset(codec, &alc662_presets[board_config]); 5204 setup_preset(codec, &alc662_presets[board_config]);
19551 5205
19552 spec->stream_analog_playback = &alc662_pcm_analog_playback; 5206 if (!spec->no_analog && !spec->adc_nids) {
19553 spec->stream_analog_capture = &alc662_pcm_analog_capture; 5207 alc_auto_fill_adc_caps(codec);
19554 5208 alc_rebuild_imux_for_auto_mic(codec);
19555 spec->stream_digital_playback = &alc662_pcm_digital_playback; 5209 alc_remove_invalid_adc_nids(codec);
19556 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19557
19558 if (!spec->adc_nids) {
19559 spec->adc_nids = alc662_adc_nids;
19560 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19561 } 5210 }
19562 if (!spec->capsrc_nids)
19563 spec->capsrc_nids = alc662_capsrc_nids;
19564 5211
19565 if (!spec->cap_mixer) 5212 if (!spec->no_analog && !spec->cap_mixer)
19566 set_capture_mixer(codec); 5213 set_capture_mixer(codec);
19567 5214
19568 if (has_cdefine_beep(codec)) { 5215 if (!spec->no_analog && has_cdefine_beep(codec)) {
5216 err = snd_hda_attach_beep_device(codec, 0x1);
5217 if (err < 0) {
5218 alc_free(codec);
5219 return err;
5220 }
19569 switch (codec->vendor_id) { 5221 switch (codec->vendor_id) {
19570 case 0x10ec0662: 5222 case 0x10ec0662:
19571 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5223 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
@@ -19585,8 +5237,8 @@ static int patch_alc662(struct hda_codec *codec)
19585 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 5237 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19586 5238
19587 codec->patch_ops = alc_patch_ops; 5239 codec->patch_ops = alc_patch_ops;
19588 if (board_config == ALC662_AUTO) 5240 if (board_config == ALC_MODEL_AUTO)
19589 spec->init_hook = alc662_auto_init; 5241 spec->init_hook = alc_auto_init_std;
19590 spec->shutup = alc_eapd_shutup; 5242 spec->shutup = alc_eapd_shutup;
19591 5243
19592 alc_init_jacks(codec); 5244 alc_init_jacks(codec);
@@ -19628,389 +5280,17 @@ static int patch_alc899(struct hda_codec *codec)
19628/* 5280/*
19629 * ALC680 support 5281 * ALC680 support
19630 */ 5282 */
19631#define ALC680_DIGIN_NID ALC880_DIGIN_NID
19632#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19633#define alc680_modes alc260_modes
19634
19635static const hda_nid_t alc680_dac_nids[3] = {
19636 /* Lout1, Lout2, hp */
19637 0x02, 0x03, 0x04
19638};
19639
19640static const hda_nid_t alc680_adc_nids[3] = {
19641 /* ADC0-2 */
19642 /* DMIC, MIC, Line-in*/
19643 0x07, 0x08, 0x09
19644};
19645
19646/*
19647 * Analog capture ADC cgange
19648 */
19649static void alc680_rec_autoswitch(struct hda_codec *codec)
19650{
19651 struct alc_spec *spec = codec->spec;
19652 struct auto_pin_cfg *cfg = &spec->autocfg;
19653 int pin_found = 0;
19654 int type_found = AUTO_PIN_LAST;
19655 hda_nid_t nid;
19656 int i;
19657
19658 for (i = 0; i < cfg->num_inputs; i++) {
19659 nid = cfg->inputs[i].pin;
19660 if (!is_jack_detectable(codec, nid))
19661 continue;
19662 if (snd_hda_jack_detect(codec, nid)) {
19663 if (cfg->inputs[i].type < type_found) {
19664 type_found = cfg->inputs[i].type;
19665 pin_found = nid;
19666 }
19667 }
19668 }
19669
19670 nid = 0x07;
19671 if (pin_found)
19672 snd_hda_get_connections(codec, pin_found, &nid, 1);
19673
19674 if (nid != spec->cur_adc)
19675 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19676 spec->cur_adc = nid;
19677 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19678 spec->cur_adc_format);
19679}
19680
19681static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19682 struct hda_codec *codec,
19683 unsigned int stream_tag,
19684 unsigned int format,
19685 struct snd_pcm_substream *substream)
19686{
19687 struct alc_spec *spec = codec->spec;
19688
19689 spec->cur_adc = 0x07;
19690 spec->cur_adc_stream_tag = stream_tag;
19691 spec->cur_adc_format = format;
19692
19693 alc680_rec_autoswitch(codec);
19694 return 0;
19695}
19696
19697static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19698 struct hda_codec *codec,
19699 struct snd_pcm_substream *substream)
19700{
19701 snd_hda_codec_cleanup_stream(codec, 0x07);
19702 snd_hda_codec_cleanup_stream(codec, 0x08);
19703 snd_hda_codec_cleanup_stream(codec, 0x09);
19704 return 0;
19705}
19706
19707static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19708 .substreams = 1, /* can be overridden */
19709 .channels_min = 2,
19710 .channels_max = 2,
19711 /* NID is set in alc_build_pcms */
19712 .ops = {
19713 .prepare = alc680_capture_pcm_prepare,
19714 .cleanup = alc680_capture_pcm_cleanup
19715 },
19716};
19717
19718static const struct snd_kcontrol_new alc680_base_mixer[] = {
19719 /* output mixer control */
19720 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19721 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19723 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19724 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19725 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19726 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19727 { }
19728};
19729
19730static const struct hda_bind_ctls alc680_bind_cap_vol = {
19731 .ops = &snd_hda_bind_vol,
19732 .values = {
19733 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19734 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19735 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19736 0
19737 },
19738};
19739
19740static const struct hda_bind_ctls alc680_bind_cap_switch = {
19741 .ops = &snd_hda_bind_sw,
19742 .values = {
19743 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19744 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19745 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19746 0
19747 },
19748};
19749
19750static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19751 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19752 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19753 { } /* end */
19754};
19755
19756/*
19757 * generic initialization of ADC, input mixers and output mixers
19758 */
19759static const struct hda_verb alc680_init_verbs[] = {
19760 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19761 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19762 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19763
19764 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19768 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19769 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19770
19771 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19772 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19773 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19774 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19775 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19776
19777 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19778 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19779 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19780 5283
19781 { }
19782};
19783
19784/* toggle speaker-output according to the hp-jack state */
19785static void alc680_base_setup(struct hda_codec *codec)
19786{
19787 struct alc_spec *spec = codec->spec;
19788
19789 spec->autocfg.hp_pins[0] = 0x16;
19790 spec->autocfg.speaker_pins[0] = 0x14;
19791 spec->autocfg.speaker_pins[1] = 0x15;
19792 spec->autocfg.num_inputs = 2;
19793 spec->autocfg.inputs[0].pin = 0x18;
19794 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19795 spec->autocfg.inputs[1].pin = 0x19;
19796 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19797 spec->automute = 1;
19798 spec->automute_mode = ALC_AUTOMUTE_AMP;
19799}
19800
19801static void alc680_unsol_event(struct hda_codec *codec,
19802 unsigned int res)
19803{
19804 if ((res >> 26) == ALC880_HP_EVENT)
19805 alc_hp_automute(codec);
19806 if ((res >> 26) == ALC880_MIC_EVENT)
19807 alc680_rec_autoswitch(codec);
19808}
19809
19810static void alc680_inithook(struct hda_codec *codec)
19811{
19812 alc_hp_automute(codec);
19813 alc680_rec_autoswitch(codec);
19814}
19815
19816/* create input playback/capture controls for the given pin */
19817static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19818 const char *ctlname, int idx)
19819{
19820 hda_nid_t dac;
19821 int err;
19822
19823 switch (nid) {
19824 case 0x14:
19825 dac = 0x02;
19826 break;
19827 case 0x15:
19828 dac = 0x03;
19829 break;
19830 case 0x16:
19831 dac = 0x04;
19832 break;
19833 default:
19834 return 0;
19835 }
19836 if (spec->multiout.dac_nids[0] != dac &&
19837 spec->multiout.dac_nids[1] != dac) {
19838 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19839 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19840 HDA_OUTPUT));
19841 if (err < 0)
19842 return err;
19843
19844 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19845 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19846
19847 if (err < 0)
19848 return err;
19849 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19850 }
19851
19852 return 0;
19853}
19854
19855/* add playback controls from the parsed DAC table */
19856static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19857 const struct auto_pin_cfg *cfg)
19858{
19859 hda_nid_t nid;
19860 int err;
19861
19862 spec->multiout.dac_nids = spec->private_dac_nids;
19863
19864 nid = cfg->line_out_pins[0];
19865 if (nid) {
19866 const char *name;
19867 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19868 name = "Speaker";
19869 else
19870 name = "Front";
19871 err = alc680_new_analog_output(spec, nid, name, 0);
19872 if (err < 0)
19873 return err;
19874 }
19875
19876 nid = cfg->speaker_pins[0];
19877 if (nid) {
19878 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19879 if (err < 0)
19880 return err;
19881 }
19882 nid = cfg->hp_pins[0];
19883 if (nid) {
19884 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19885 if (err < 0)
19886 return err;
19887 }
19888
19889 return 0;
19890}
19891
19892static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19893 hda_nid_t nid, int pin_type)
19894{
19895 alc_set_pin_output(codec, nid, pin_type);
19896}
19897
19898static void alc680_auto_init_multi_out(struct hda_codec *codec)
19899{
19900 struct alc_spec *spec = codec->spec;
19901 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19902 if (nid) {
19903 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19904 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19905 }
19906}
19907
19908static void alc680_auto_init_hp_out(struct hda_codec *codec)
19909{
19910 struct alc_spec *spec = codec->spec;
19911 hda_nid_t pin;
19912
19913 pin = spec->autocfg.hp_pins[0];
19914 if (pin)
19915 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19916 pin = spec->autocfg.speaker_pins[0];
19917 if (pin)
19918 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19919}
19920
19921/* pcm configuration: identical with ALC880 */
19922#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19923#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19924#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19925#define alc680_pcm_digital_playback alc880_pcm_digital_playback
19926#define alc680_pcm_digital_capture alc880_pcm_digital_capture
19927
19928/*
19929 * BIOS auto configuration
19930 */
19931static int alc680_parse_auto_config(struct hda_codec *codec) 5284static int alc680_parse_auto_config(struct hda_codec *codec)
19932{ 5285{
19933 struct alc_spec *spec = codec->spec; 5286 return alc_parse_auto_config(codec, NULL, NULL);
19934 int err;
19935 static const hda_nid_t alc680_ignore[] = { 0 };
19936
19937 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19938 alc680_ignore);
19939 if (err < 0)
19940 return err;
19941
19942 if (!spec->autocfg.line_outs) {
19943 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19944 spec->multiout.max_channels = 2;
19945 spec->no_analog = 1;
19946 goto dig_only;
19947 }
19948 return 0; /* can't find valid BIOS pin config */
19949 }
19950 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19951 if (err < 0)
19952 return err;
19953
19954 spec->multiout.max_channels = 2;
19955
19956 dig_only:
19957 /* digital only support output */
19958 alc_auto_parse_digital(codec);
19959 if (spec->kctls.list)
19960 add_mixer(spec, spec->kctls.list);
19961
19962 add_verb(spec, alc680_init_verbs);
19963
19964 err = alc_auto_add_mic_boost(codec);
19965 if (err < 0)
19966 return err;
19967
19968 return 1;
19969}
19970
19971#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19972
19973/* init callback for auto-configuration model -- overriding the default init */
19974static void alc680_auto_init(struct hda_codec *codec)
19975{
19976 struct alc_spec *spec = codec->spec;
19977 alc680_auto_init_multi_out(codec);
19978 alc680_auto_init_hp_out(codec);
19979 alc680_auto_init_analog_input(codec);
19980 alc_auto_init_digital(codec);
19981 if (spec->unsol_event)
19982 alc_inithook(codec);
19983} 5287}
19984 5288
19985/* 5289/*
19986 * configuration and preset
19987 */ 5290 */
19988static const char * const alc680_models[ALC680_MODEL_LAST] = { 5291#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
19989 [ALC680_BASE] = "base", 5292#include "alc680_quirks.c"
19990 [ALC680_AUTO] = "auto", 5293#endif
19991};
19992
19993static const struct snd_pci_quirk alc680_cfg_tbl[] = {
19994 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19995 {}
19996};
19997
19998static const struct alc_config_preset alc680_presets[] = {
19999 [ALC680_BASE] = {
20000 .mixers = { alc680_base_mixer },
20001 .cap_mixer = alc680_master_capture_mixer,
20002 .init_verbs = { alc680_init_verbs },
20003 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
20004 .dac_nids = alc680_dac_nids,
20005 .dig_out_nid = ALC680_DIGOUT_NID,
20006 .num_channel_mode = ARRAY_SIZE(alc680_modes),
20007 .channel_mode = alc680_modes,
20008 .unsol_event = alc680_unsol_event,
20009 .setup = alc680_base_setup,
20010 .init_hook = alc680_inithook,
20011
20012 },
20013};
20014 5294
20015static int patch_alc680(struct hda_codec *codec) 5295static int patch_alc680(struct hda_codec *codec)
20016{ 5296{
@@ -20024,51 +5304,55 @@ static int patch_alc680(struct hda_codec *codec)
20024 5304
20025 codec->spec = spec; 5305 codec->spec = spec;
20026 5306
20027 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 5307 /* ALC680 has no aa-loopback mixer */
20028 alc680_models, 5308
20029 alc680_cfg_tbl); 5309 board_config = alc_board_config(codec, ALC680_MODEL_LAST,
5310 alc680_models, alc680_cfg_tbl);
20030 5311
20031 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 5312 if (board_config < 0) {
20032 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5313 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20033 codec->chip_name); 5314 codec->chip_name);
20034 board_config = ALC680_AUTO; 5315 board_config = ALC_MODEL_AUTO;
20035 } 5316 }
20036 5317
20037 if (board_config == ALC680_AUTO) { 5318 if (board_config == ALC_MODEL_AUTO) {
20038 /* automatic parse from the BIOS config */ 5319 /* automatic parse from the BIOS config */
20039 err = alc680_parse_auto_config(codec); 5320 err = alc680_parse_auto_config(codec);
20040 if (err < 0) { 5321 if (err < 0) {
20041 alc_free(codec); 5322 alc_free(codec);
20042 return err; 5323 return err;
20043 } else if (!err) { 5324 }
5325#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5326 else if (!err) {
20044 printk(KERN_INFO 5327 printk(KERN_INFO
20045 "hda_codec: Cannot set up configuration " 5328 "hda_codec: Cannot set up configuration "
20046 "from BIOS. Using base mode...\n"); 5329 "from BIOS. Using base mode...\n");
20047 board_config = ALC680_BASE; 5330 board_config = ALC680_BASE;
20048 } 5331 }
5332#endif
20049 } 5333 }
20050 5334
20051 if (board_config != ALC680_AUTO) 5335 if (board_config != ALC_MODEL_AUTO) {
20052 setup_preset(codec, &alc680_presets[board_config]); 5336 setup_preset(codec, &alc680_presets[board_config]);
5337#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5338 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
5339#endif
5340 }
20053 5341
20054 spec->stream_analog_playback = &alc680_pcm_analog_playback; 5342 if (!spec->no_analog && !spec->adc_nids) {
20055 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; 5343 alc_auto_fill_adc_caps(codec);
20056 spec->stream_digital_playback = &alc680_pcm_digital_playback; 5344 alc_rebuild_imux_for_auto_mic(codec);
20057 spec->stream_digital_capture = &alc680_pcm_digital_capture; 5345 alc_remove_invalid_adc_nids(codec);
20058
20059 if (!spec->adc_nids) {
20060 spec->adc_nids = alc680_adc_nids;
20061 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20062 } 5346 }
20063 5347
20064 if (!spec->cap_mixer) 5348 if (!spec->no_analog && !spec->cap_mixer)
20065 set_capture_mixer(codec); 5349 set_capture_mixer(codec);
20066 5350
20067 spec->vmaster_nid = 0x02; 5351 spec->vmaster_nid = 0x02;
20068 5352
20069 codec->patch_ops = alc_patch_ops; 5353 codec->patch_ops = alc_patch_ops;
20070 if (board_config == ALC680_AUTO) 5354 if (board_config == ALC_MODEL_AUTO)
20071 spec->init_hook = alc680_auto_init; 5355 spec->init_hook = alc_auto_init_std;
20072 5356
20073 return 0; 5357 return 0;
20074} 5358}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 7f81cc2274f..aa376b59c00 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -95,6 +95,7 @@ enum {
95 STAC_92HD83XXX_PWR_REF, 95 STAC_92HD83XXX_PWR_REF,
96 STAC_DELL_S14, 96 STAC_DELL_S14,
97 STAC_92HD83XXX_HP, 97 STAC_92HD83XXX_HP,
98 STAC_92HD83XXX_HP_cNB11_INTQUAD,
98 STAC_HP_DV7_4000, 99 STAC_HP_DV7_4000,
99 STAC_92HD83XXX_MODELS 100 STAC_92HD83XXX_MODELS
100}; 101};
@@ -212,6 +213,7 @@ struct sigmatel_spec {
212 unsigned int gpio_mute; 213 unsigned int gpio_mute;
213 unsigned int gpio_led; 214 unsigned int gpio_led;
214 unsigned int gpio_led_polarity; 215 unsigned int gpio_led_polarity;
216 unsigned int vref_led;
215 217
216 /* stream */ 218 /* stream */
217 unsigned int stream_delay; 219 unsigned int stream_delay;
@@ -671,6 +673,30 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
671 return 0; 673 return 0;
672} 674}
673 675
676static int stac_vrefout_set(struct hda_codec *codec,
677 hda_nid_t nid, unsigned int new_vref)
678{
679 int error, pinctl;
680
681 snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref);
682 pinctl = snd_hda_codec_read(codec, nid, 0,
683 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
684
685 if (pinctl < 0)
686 return pinctl;
687
688 pinctl &= 0xff;
689 pinctl &= ~AC_PINCTL_VREFEN;
690 pinctl |= (new_vref & AC_PINCTL_VREFEN);
691
692 error = snd_hda_codec_write_cache(codec, nid, 0,
693 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
694 if (error < 0)
695 return error;
696
697 return 1;
698}
699
674static unsigned int stac92xx_vref_set(struct hda_codec *codec, 700static unsigned int stac92xx_vref_set(struct hda_codec *codec,
675 hda_nid_t nid, unsigned int new_vref) 701 hda_nid_t nid, unsigned int new_vref)
676{ 702{
@@ -1112,7 +1138,9 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1112 } 1138 }
1113 1139
1114 if (spec->multiout.dig_out_nid) { 1140 if (spec->multiout.dig_out_nid) {
1115 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 1141 err = snd_hda_create_spdif_out_ctls(codec,
1142 spec->multiout.dig_out_nid,
1143 spec->multiout.dig_out_nid);
1116 if (err < 0) 1144 if (err < 0)
1117 return err; 1145 return err;
1118 err = snd_hda_create_spdif_share_sw(codec, 1146 err = snd_hda_create_spdif_share_sw(codec,
@@ -1634,10 +1662,17 @@ static const unsigned int hp_dv7_4000_pin_configs[10] = {
1634 0x40f000f0, 0x40f000f0, 1662 0x40f000f0, 0x40f000f0,
1635}; 1663};
1636 1664
1665static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
1666 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
1667 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
1668 0x40f000f0, 0x40f000f0,
1669};
1670
1637static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { 1671static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1638 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, 1672 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
1639 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, 1673 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
1640 [STAC_DELL_S14] = dell_s14_pin_configs, 1674 [STAC_DELL_S14] = dell_s14_pin_configs,
1675 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
1641 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, 1676 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
1642}; 1677};
1643 1678
@@ -1647,6 +1682,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1647 [STAC_92HD83XXX_PWR_REF] = "mic-ref", 1682 [STAC_92HD83XXX_PWR_REF] = "mic-ref",
1648 [STAC_DELL_S14] = "dell-s14", 1683 [STAC_DELL_S14] = "dell-s14",
1649 [STAC_92HD83XXX_HP] = "hp", 1684 [STAC_92HD83XXX_HP] = "hp",
1685 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
1650 [STAC_HP_DV7_4000] = "hp-dv7-4000", 1686 [STAC_HP_DV7_4000] = "hp-dv7-4000",
1651}; 1687};
1652 1688
@@ -1659,7 +1695,47 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1659 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, 1695 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
1660 "unknown Dell", STAC_DELL_S14), 1696 "unknown Dell", STAC_DELL_S14),
1661 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, 1697 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600,
1662 "HP", STAC_92HD83XXX_HP), 1698 "HP", STAC_92HD83XXX_HP),
1699 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
1700 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1701 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
1702 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1703 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
1704 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1705 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
1706 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1707 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
1708 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1709 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
1710 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1711 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
1712 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1713 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
1714 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1715 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
1716 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1717 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
1718 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1719 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
1720 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1721 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
1722 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1723 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
1724 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1725 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
1726 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1727 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
1728 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1729 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
1730 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1731 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
1732 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1733 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
1734 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1735 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
1736 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1737 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
1738 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1663 {} /* terminator */ 1739 {} /* terminator */
1664}; 1740};
1665 1741
@@ -3406,30 +3482,9 @@ static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
3406 return 0; 3482 return 0;
3407} 3483}
3408 3484
3409static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3485/* look for NID recursively */
3410 hda_nid_t nid) 3486#define get_connection_index(codec, mux, nid) \
3411{ 3487 snd_hda_get_conn_index(codec, mux, nid, 1)
3412 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3413 int i, nums;
3414
3415 if (!(get_wcaps(codec, mux) & AC_WCAP_CONN_LIST))
3416 return -1;
3417
3418 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3419 for (i = 0; i < nums; i++)
3420 if (conn[i] == nid)
3421 return i;
3422
3423 for (i = 0; i < nums; i++) {
3424 unsigned int wid_caps = get_wcaps(codec, conn[i]);
3425 unsigned int wid_type = get_wcaps_type(wid_caps);
3426
3427 if (wid_type != AC_WID_PIN && wid_type != AC_WID_AUD_MIX)
3428 if (get_connection_index(codec, conn[i], nid) >= 0)
3429 return i;
3430 }
3431 return -1;
3432}
3433 3488
3434/* create a volume assigned to the given pin (only if supported) */ 3489/* create a volume assigned to the given pin (only if supported) */
3435/* return 1 if the volume control is created */ 3490/* return 1 if the volume control is created */
@@ -4039,6 +4094,8 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
4039{ 4094{
4040 unsigned int gpiostate, gpiomask, gpiodir; 4095 unsigned int gpiostate, gpiomask, gpiodir;
4041 4096
4097 snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
4098
4042 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 4099 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
4043 AC_VERB_GET_GPIO_DATA, 0); 4100 AC_VERB_GET_GPIO_DATA, 0);
4044 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask); 4101 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
@@ -4228,10 +4285,12 @@ static void stac_store_hints(struct hda_codec *codec)
4228 spec->eapd_switch = val; 4285 spec->eapd_switch = val;
4229 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); 4286 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
4230 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { 4287 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
4231 spec->gpio_mask |= spec->gpio_led; 4288 if (spec->gpio_led <= 8) {
4232 spec->gpio_dir |= spec->gpio_led; 4289 spec->gpio_mask |= spec->gpio_led;
4233 if (spec->gpio_led_polarity) 4290 spec->gpio_dir |= spec->gpio_led;
4234 spec->gpio_data |= spec->gpio_led; 4291 if (spec->gpio_led_polarity)
4292 spec->gpio_data |= spec->gpio_led;
4293 }
4235 } 4294 }
4236} 4295}
4237 4296
@@ -4401,11 +4460,26 @@ static void stac92xx_free_kctls(struct hda_codec *codec)
4401 snd_array_free(&spec->kctls); 4460 snd_array_free(&spec->kctls);
4402} 4461}
4403 4462
4463static void stac92xx_shutup_pins(struct hda_codec *codec)
4464{
4465 unsigned int i, def_conf;
4466
4467 if (codec->bus->shutdown)
4468 return;
4469 for (i = 0; i < codec->init_pins.used; i++) {
4470 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
4471 def_conf = snd_hda_codec_get_pincfg(codec, pin->nid);
4472 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
4473 snd_hda_codec_write(codec, pin->nid, 0,
4474 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
4475 }
4476}
4477
4404static void stac92xx_shutup(struct hda_codec *codec) 4478static void stac92xx_shutup(struct hda_codec *codec)
4405{ 4479{
4406 struct sigmatel_spec *spec = codec->spec; 4480 struct sigmatel_spec *spec = codec->spec;
4407 4481
4408 snd_hda_shutup_pins(codec); 4482 stac92xx_shutup_pins(codec);
4409 4483
4410 if (spec->eapd_mask) 4484 if (spec->eapd_mask)
4411 stac_gpio_set(codec, spec->gpio_mask, 4485 stac_gpio_set(codec, spec->gpio_mask,
@@ -4803,10 +4877,11 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4803 if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { 4877 if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
4804 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, 4878 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
4805 NULL, dev))) { 4879 NULL, dev))) {
4806 if (sscanf(dev->name, "HP_Mute_LED_%d_%d", 4880 if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
4807 &spec->gpio_led_polarity, 4881 &spec->gpio_led_polarity,
4808 &spec->gpio_led) == 2) { 4882 &spec->gpio_led) == 2) {
4809 spec->gpio_led = 1 << spec->gpio_led; 4883 if (spec->gpio_led < 4)
4884 spec->gpio_led = 1 << spec->gpio_led;
4810 return 1; 4885 return 1;
4811 } 4886 }
4812 if (sscanf(dev->name, "HP_Mute_LED_%d", 4887 if (sscanf(dev->name, "HP_Mute_LED_%d",
@@ -4904,7 +4979,7 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
4904#define stac927x_proc_hook NULL 4979#define stac927x_proc_hook NULL
4905#endif 4980#endif
4906 4981
4907#ifdef SND_HDA_NEEDS_RESUME 4982#ifdef CONFIG_PM
4908static int stac92xx_resume(struct hda_codec *codec) 4983static int stac92xx_resume(struct hda_codec *codec)
4909{ 4984{
4910 struct sigmatel_spec *spec = codec->spec; 4985 struct sigmatel_spec *spec = codec->spec;
@@ -4920,29 +4995,81 @@ static int stac92xx_resume(struct hda_codec *codec)
4920 stac_issue_unsol_event(codec, 4995 stac_issue_unsol_event(codec,
4921 spec->autocfg.line_out_pins[0]); 4996 spec->autocfg.line_out_pins[0]);
4922 } 4997 }
4998 return 0;
4999}
5000
5001static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
5002{
5003 stac92xx_shutup(codec);
5004 return 0;
5005}
5006
5007#ifdef CONFIG_SND_HDA_POWER_SAVE
5008static int stac92xx_pre_resume(struct hda_codec *codec)
5009{
5010 struct sigmatel_spec *spec = codec->spec;
5011
4923 /* sync mute LED */ 5012 /* sync mute LED */
4924 if (spec->gpio_led) 5013 if (spec->gpio_led) {
4925 hda_call_check_power_status(codec, 0x01); 5014 if (spec->gpio_led <= 8) {
5015 stac_gpio_set(codec, spec->gpio_mask,
5016 spec->gpio_dir, spec->gpio_data);
5017 } else {
5018 stac_vrefout_set(codec,
5019 spec->gpio_led, spec->vref_led);
5020 }
5021 }
5022 return 0;
5023}
5024
5025static int stac92xx_post_suspend(struct hda_codec *codec)
5026{
5027 struct sigmatel_spec *spec = codec->spec;
5028 if (spec->gpio_led > 8) {
5029 /* with vref-out pin used for mute led control
5030 * codec AFG is prevented from D3 state, but on
5031 * system suspend it can (and should) be used
5032 */
5033 snd_hda_codec_read(codec, codec->afg, 0,
5034 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5035 }
4926 return 0; 5036 return 0;
4927} 5037}
4928 5038
5039static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
5040 unsigned int power_state)
5041{
5042 unsigned int afg_power_state = power_state;
5043 struct sigmatel_spec *spec = codec->spec;
5044
5045 if (power_state == AC_PWRST_D3) {
5046 if (spec->gpio_led > 8) {
5047 /* with vref-out pin used for mute led control
5048 * codec AFG is prevented from D3 state
5049 */
5050 afg_power_state = AC_PWRST_D1;
5051 }
5052 /* this delay seems necessary to avoid click noise at power-down */
5053 msleep(100);
5054 }
5055 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
5056 afg_power_state);
5057 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
5058}
5059
4929/* 5060/*
4930 * using power check for controlling mute led of HP notebooks 5061 * For this feature CONFIG_SND_HDA_POWER_SAVE is needed
4931 * check for mute state only on Speakers (nid = 0x10) 5062 * as mute LED state is updated in check_power_status hook
4932 *
4933 * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise
4934 * the LED is NOT working properly !
4935 *
4936 * Changed name to reflect that it now works for any designated
4937 * model, not just HP HDX.
4938 */ 5063 */
4939 5064static int stac92xx_update_led_status(struct hda_codec *codec)
4940#ifdef CONFIG_SND_HDA_POWER_SAVE
4941static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4942 hda_nid_t nid)
4943{ 5065{
4944 struct sigmatel_spec *spec = codec->spec; 5066 struct sigmatel_spec *spec = codec->spec;
4945 int i, muted = 1; 5067 int i, num_ext_dacs, muted = 1;
5068 unsigned int muted_lvl, notmtd_lvl;
5069 hda_nid_t nid;
5070
5071 if (!spec->gpio_led)
5072 return 0;
4946 5073
4947 for (i = 0; i < spec->multiout.num_dacs; i++) { 5074 for (i = 0; i < spec->multiout.num_dacs; i++) {
4948 nid = spec->multiout.dac_nids[i]; 5075 nid = spec->multiout.dac_nids[i];
@@ -4952,27 +5079,58 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4952 break; 5079 break;
4953 } 5080 }
4954 } 5081 }
4955 if (muted) 5082 if (muted && spec->multiout.hp_nid)
4956 spec->gpio_data &= ~spec->gpio_led; /* orange */ 5083 if (!(snd_hda_codec_amp_read(codec,
4957 else 5084 spec->multiout.hp_nid, 0, HDA_OUTPUT, 0) &
4958 spec->gpio_data |= spec->gpio_led; /* white */ 5085 HDA_AMP_MUTE)) {
4959 5086 muted = 0; /* HP is not muted */
4960 if (!spec->gpio_led_polarity) { 5087 }
4961 /* LED state is inverted on these systems */ 5088 num_ext_dacs = ARRAY_SIZE(spec->multiout.extra_out_nid);
4962 spec->gpio_data ^= spec->gpio_led; 5089 for (i = 0; muted && i < num_ext_dacs; i++) {
5090 nid = spec->multiout.extra_out_nid[i];
5091 if (nid == 0)
5092 break;
5093 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
5094 HDA_AMP_MUTE)) {
5095 muted = 0; /* extra output is not muted */
5096 }
4963 } 5097 }
5098 /*polarity defines *not* muted state level*/
5099 if (spec->gpio_led <= 8) {
5100 if (muted)
5101 spec->gpio_data &= ~spec->gpio_led; /* orange */
5102 else
5103 spec->gpio_data |= spec->gpio_led; /* white */
4964 5104
4965 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); 5105 if (!spec->gpio_led_polarity) {
5106 /* LED state is inverted on these systems */
5107 spec->gpio_data ^= spec->gpio_led;
5108 }
5109 stac_gpio_set(codec, spec->gpio_mask,
5110 spec->gpio_dir, spec->gpio_data);
5111 } else {
5112 notmtd_lvl = spec->gpio_led_polarity ?
5113 AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_GRD;
5114 muted_lvl = spec->gpio_led_polarity ?
5115 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
5116 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5117 stac_vrefout_set(codec, spec->gpio_led, spec->vref_led);
5118 }
4966 return 0; 5119 return 0;
4967} 5120}
4968#endif
4969 5121
4970static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 5122/*
5123 * use power check for controlling mute led of HP notebooks
5124 */
5125static int stac92xx_check_power_status(struct hda_codec *codec,
5126 hda_nid_t nid)
4971{ 5127{
4972 stac92xx_shutup(codec); 5128 stac92xx_update_led_status(codec);
5129
4973 return 0; 5130 return 0;
4974} 5131}
4975#endif 5132#endif /* CONFIG_SND_HDA_POWER_SAVE */
5133#endif /* CONFIG_PM */
4976 5134
4977static const struct hda_codec_ops stac92xx_patch_ops = { 5135static const struct hda_codec_ops stac92xx_patch_ops = {
4978 .build_controls = stac92xx_build_controls, 5136 .build_controls = stac92xx_build_controls,
@@ -4980,7 +5138,7 @@ static const struct hda_codec_ops stac92xx_patch_ops = {
4980 .init = stac92xx_init, 5138 .init = stac92xx_init,
4981 .free = stac92xx_free, 5139 .free = stac92xx_free,
4982 .unsol_event = stac92xx_unsol_event, 5140 .unsol_event = stac92xx_unsol_event,
4983#ifdef SND_HDA_NEEDS_RESUME 5141#ifdef CONFIG_PM
4984 .suspend = stac92xx_suspend, 5142 .suspend = stac92xx_suspend,
4985 .resume = stac92xx_resume, 5143 .resume = stac92xx_resume,
4986#endif 5144#endif
@@ -5496,12 +5654,19 @@ again:
5496 5654
5497#ifdef CONFIG_SND_HDA_POWER_SAVE 5655#ifdef CONFIG_SND_HDA_POWER_SAVE
5498 if (spec->gpio_led) { 5656 if (spec->gpio_led) {
5499 spec->gpio_mask |= spec->gpio_led; 5657 if (spec->gpio_led <= 8) {
5500 spec->gpio_dir |= spec->gpio_led; 5658 spec->gpio_mask |= spec->gpio_led;
5501 spec->gpio_data |= spec->gpio_led; 5659 spec->gpio_dir |= spec->gpio_led;
5502 /* register check_power_status callback. */ 5660 spec->gpio_data |= spec->gpio_led;
5661 } else {
5662 codec->patch_ops.set_power_state =
5663 stac92xx_set_power_state;
5664 codec->patch_ops.post_suspend =
5665 stac92xx_post_suspend;
5666 }
5667 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5503 codec->patch_ops.check_power_status = 5668 codec->patch_ops.check_power_status =
5504 stac92xx_hp_check_power_status; 5669 stac92xx_check_power_status;
5505 } 5670 }
5506#endif 5671#endif
5507 5672
@@ -5824,12 +5989,19 @@ again:
5824 5989
5825#ifdef CONFIG_SND_HDA_POWER_SAVE 5990#ifdef CONFIG_SND_HDA_POWER_SAVE
5826 if (spec->gpio_led) { 5991 if (spec->gpio_led) {
5827 spec->gpio_mask |= spec->gpio_led; 5992 if (spec->gpio_led <= 8) {
5828 spec->gpio_dir |= spec->gpio_led; 5993 spec->gpio_mask |= spec->gpio_led;
5829 spec->gpio_data |= spec->gpio_led; 5994 spec->gpio_dir |= spec->gpio_led;
5830 /* register check_power_status callback. */ 5995 spec->gpio_data |= spec->gpio_led;
5996 } else {
5997 codec->patch_ops.set_power_state =
5998 stac92xx_set_power_state;
5999 codec->patch_ops.post_suspend =
6000 stac92xx_post_suspend;
6001 }
6002 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5831 codec->patch_ops.check_power_status = 6003 codec->patch_ops.check_power_status =
5832 stac92xx_hp_check_power_status; 6004 stac92xx_check_power_status;
5833 } 6005 }
5834#endif 6006#endif
5835 6007
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 605c99e1e52..84d8798bf33 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -54,36 +54,10 @@
54#include "hda_codec.h" 54#include "hda_codec.h"
55#include "hda_local.h" 55#include "hda_local.h"
56 56
57#define NID_MAPPING (-1)
58
59/* amp values */
60#define AMP_VAL_IDX_SHIFT 19
61#define AMP_VAL_IDX_MASK (0x0f<<19)
62
63/* Pin Widget NID */ 57/* Pin Widget NID */
64#define VT1708_HP_NID 0x13
65#define VT1708_DIGOUT_NID 0x14
66#define VT1708_DIGIN_NID 0x16
67#define VT1708_DIGIN_PIN 0x26
68#define VT1708_HP_PIN_NID 0x20 58#define VT1708_HP_PIN_NID 0x20
69#define VT1708_CD_PIN_NID 0x24 59#define VT1708_CD_PIN_NID 0x24
70 60
71#define VT1709_HP_DAC_NID 0x28
72#define VT1709_DIGOUT_NID 0x13
73#define VT1709_DIGIN_NID 0x17
74#define VT1709_DIGIN_PIN 0x25
75
76#define VT1708B_HP_NID 0x25
77#define VT1708B_DIGOUT_NID 0x12
78#define VT1708B_DIGIN_NID 0x15
79#define VT1708B_DIGIN_PIN 0x21
80
81#define VT1708S_HP_NID 0x25
82#define VT1708S_DIGOUT_NID 0x12
83
84#define VT1702_HP_NID 0x17
85#define VT1702_DIGOUT_NID 0x11
86
87enum VIA_HDA_CODEC { 61enum VIA_HDA_CODEC {
88 UNKNOWN = -1, 62 UNKNOWN = -1,
89 VT1708, 63 VT1708,
@@ -107,6 +81,39 @@ enum VIA_HDA_CODEC {
107 (spec)->codec_type == VT1812 ||\ 81 (spec)->codec_type == VT1812 ||\
108 (spec)->codec_type == VT1802) 82 (spec)->codec_type == VT1802)
109 83
84#define MAX_NID_PATH_DEPTH 5
85
86/* output-path: DAC -> ... -> pin
87 * idx[] contains the source index number of the next widget;
88 * e.g. idx[0] is the index of the DAC selected by path[1] widget
89 * multi[] indicates whether it's a selector widget with multi-connectors
90 * (i.e. the connection selection is mandatory)
91 * vol_ctl and mute_ctl contains the NIDs for the assigned mixers
92 */
93struct nid_path {
94 int depth;
95 hda_nid_t path[MAX_NID_PATH_DEPTH];
96 unsigned char idx[MAX_NID_PATH_DEPTH];
97 unsigned char multi[MAX_NID_PATH_DEPTH];
98 unsigned int vol_ctl;
99 unsigned int mute_ctl;
100};
101
102/* input-path */
103struct via_input {
104 hda_nid_t pin; /* input-pin or aa-mix */
105 int adc_idx; /* ADC index to be used */
106 int mux_idx; /* MUX index (if any) */
107 const char *label; /* input-source label */
108};
109
110#define VIA_MAX_ADCS 3
111
112enum {
113 STREAM_MULTI_OUT = (1 << 0),
114 STREAM_INDEP_HP = (1 << 1),
115};
116
110struct via_spec { 117struct via_spec {
111 /* codec parameterization */ 118 /* codec parameterization */
112 const struct snd_kcontrol_new *mixers[6]; 119 const struct snd_kcontrol_new *mixers[6];
@@ -115,28 +122,66 @@ struct via_spec {
115 const struct hda_verb *init_verbs[5]; 122 const struct hda_verb *init_verbs[5];
116 unsigned int num_iverbs; 123 unsigned int num_iverbs;
117 124
118 char *stream_name_analog; 125 char stream_name_analog[32];
126 char stream_name_hp[32];
119 const struct hda_pcm_stream *stream_analog_playback; 127 const struct hda_pcm_stream *stream_analog_playback;
120 const struct hda_pcm_stream *stream_analog_capture; 128 const struct hda_pcm_stream *stream_analog_capture;
121 129
122 char *stream_name_digital; 130 char stream_name_digital[32];
123 const struct hda_pcm_stream *stream_digital_playback; 131 const struct hda_pcm_stream *stream_digital_playback;
124 const struct hda_pcm_stream *stream_digital_capture; 132 const struct hda_pcm_stream *stream_digital_capture;
125 133
126 /* playback */ 134 /* playback */
127 struct hda_multi_out multiout; 135 struct hda_multi_out multiout;
128 hda_nid_t slave_dig_outs[2]; 136 hda_nid_t slave_dig_outs[2];
137 hda_nid_t hp_dac_nid;
138 hda_nid_t speaker_dac_nid;
139 int hp_indep_shared; /* indep HP-DAC is shared with side ch */
140 int opened_streams; /* STREAM_* bits */
141 int active_streams; /* STREAM_* bits */
142 int aamix_mode; /* loopback is enabled for output-path? */
143
144 /* Output-paths:
145 * There are different output-paths depending on the setup.
146 * out_path, hp_path and speaker_path are primary paths. If both
147 * direct DAC and aa-loopback routes are available, these contain
148 * the former paths. Meanwhile *_mix_path contain the paths with
149 * loopback mixer. (Since the loopback is only for front channel,
150 * no out_mix_path for surround channels.)
151 * The HP output has another path, hp_indep_path, which is used in
152 * the independent-HP mode.
153 */
154 struct nid_path out_path[HDA_SIDE + 1];
155 struct nid_path out_mix_path;
156 struct nid_path hp_path;
157 struct nid_path hp_mix_path;
158 struct nid_path hp_indep_path;
159 struct nid_path speaker_path;
160 struct nid_path speaker_mix_path;
129 161
130 /* capture */ 162 /* capture */
131 unsigned int num_adc_nids; 163 unsigned int num_adc_nids;
132 const hda_nid_t *adc_nids; 164 hda_nid_t adc_nids[VIA_MAX_ADCS];
133 hda_nid_t mux_nids[3]; 165 hda_nid_t mux_nids[VIA_MAX_ADCS];
166 hda_nid_t aa_mix_nid;
134 hda_nid_t dig_in_nid; 167 hda_nid_t dig_in_nid;
135 hda_nid_t dig_in_pin;
136 168
137 /* capture source */ 169 /* capture source */
138 const struct hda_input_mux *input_mux; 170 bool dyn_adc_switch;
139 unsigned int cur_mux[3]; 171 int num_inputs;
172 struct via_input inputs[AUTO_CFG_MAX_INS + 1];
173 unsigned int cur_mux[VIA_MAX_ADCS];
174
175 /* dynamic DAC switching */
176 unsigned int cur_dac_stream_tag;
177 unsigned int cur_dac_format;
178 unsigned int cur_hp_stream_tag;
179 unsigned int cur_hp_format;
180
181 /* dynamic ADC switching */
182 hda_nid_t cur_adc;
183 unsigned int cur_adc_stream_tag;
184 unsigned int cur_adc_format;
140 185
141 /* PCM information */ 186 /* PCM information */
142 struct hda_pcm pcm_rec[3]; 187 struct hda_pcm pcm_rec[3];
@@ -144,28 +189,38 @@ struct via_spec {
144 /* dynamic controls, init_verbs and input_mux */ 189 /* dynamic controls, init_verbs and input_mux */
145 struct auto_pin_cfg autocfg; 190 struct auto_pin_cfg autocfg;
146 struct snd_array kctls; 191 struct snd_array kctls;
147 struct hda_input_mux private_imux[2];
148 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 192 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
149 193
150 /* HP mode source */ 194 /* HP mode source */
151 const struct hda_input_mux *hp_mux;
152 unsigned int hp_independent_mode; 195 unsigned int hp_independent_mode;
153 unsigned int hp_independent_mode_index;
154 unsigned int smart51_enabled;
155 unsigned int dmic_enabled; 196 unsigned int dmic_enabled;
197 unsigned int no_pin_power_ctl;
156 enum VIA_HDA_CODEC codec_type; 198 enum VIA_HDA_CODEC codec_type;
157 199
200 /* smart51 setup */
201 unsigned int smart51_nums;
202 hda_nid_t smart51_pins[2];
203 int smart51_idxs[2];
204 const char *smart51_labels[2];
205 unsigned int smart51_enabled;
206
158 /* work to check hp jack state */ 207 /* work to check hp jack state */
159 struct hda_codec *codec; 208 struct hda_codec *codec;
160 struct delayed_work vt1708_hp_work; 209 struct delayed_work vt1708_hp_work;
161 int vt1708_jack_detectect; 210 int vt1708_jack_detect;
162 int vt1708_hp_present; 211 int vt1708_hp_present;
163 212
164 void (*set_widgets_power_state)(struct hda_codec *codec); 213 void (*set_widgets_power_state)(struct hda_codec *codec);
165 214
166#ifdef CONFIG_SND_HDA_POWER_SAVE
167 struct hda_loopback_check loopback; 215 struct hda_loopback_check loopback;
168#endif 216 int num_loopbacks;
217 struct hda_amp_list loopback_list[8];
218
219 /* bind capture-volume */
220 struct hda_bind_ctls *bind_cap_vol;
221 struct hda_bind_ctls *bind_cap_sw;
222
223 struct mutex config_mutex;
169}; 224};
170 225
171static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); 226static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
@@ -177,6 +232,7 @@ static struct via_spec * via_new_spec(struct hda_codec *codec)
177 if (spec == NULL) 232 if (spec == NULL)
178 return NULL; 233 return NULL;
179 234
235 mutex_init(&spec->config_mutex);
180 codec->spec = spec; 236 codec->spec = spec;
181 spec->codec = codec; 237 spec->codec = codec;
182 spec->codec_type = get_codec_type(codec); 238 spec->codec_type = get_codec_type(codec);
@@ -237,33 +293,23 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
237#define VIA_JACK_EVENT 0x20 293#define VIA_JACK_EVENT 0x20
238#define VIA_HP_EVENT 0x01 294#define VIA_HP_EVENT 0x01
239#define VIA_GPIO_EVENT 0x02 295#define VIA_GPIO_EVENT 0x02
240#define VIA_MONO_EVENT 0x03 296#define VIA_LINE_EVENT 0x03
241#define VIA_SPEAKER_EVENT 0x04
242#define VIA_BIND_HP_EVENT 0x05
243 297
244enum { 298enum {
245 VIA_CTL_WIDGET_VOL, 299 VIA_CTL_WIDGET_VOL,
246 VIA_CTL_WIDGET_MUTE, 300 VIA_CTL_WIDGET_MUTE,
247 VIA_CTL_WIDGET_ANALOG_MUTE, 301 VIA_CTL_WIDGET_ANALOG_MUTE,
248 VIA_CTL_WIDGET_BIND_PIN_MUTE,
249}; 302};
250 303
251enum { 304static void analog_low_current_mode(struct hda_codec *codec);
252 AUTO_SEQ_FRONT = 0, 305static bool is_aa_path_mute(struct hda_codec *codec);
253 AUTO_SEQ_SURROUND,
254 AUTO_SEQ_CENLFE,
255 AUTO_SEQ_SIDE
256};
257
258static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
259static int is_aa_path_mute(struct hda_codec *codec);
260 306
261static void vt1708_start_hp_work(struct via_spec *spec) 307static void vt1708_start_hp_work(struct via_spec *spec)
262{ 308{
263 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) 309 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
264 return; 310 return;
265 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 311 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
266 !spec->vt1708_jack_detectect); 312 !spec->vt1708_jack_detect);
267 if (!delayed_work_pending(&spec->vt1708_hp_work)) 313 if (!delayed_work_pending(&spec->vt1708_hp_work))
268 schedule_delayed_work(&spec->vt1708_hp_work, 314 schedule_delayed_work(&spec->vt1708_hp_work,
269 msecs_to_jiffies(100)); 315 msecs_to_jiffies(100));
@@ -277,7 +323,7 @@ static void vt1708_stop_hp_work(struct via_spec *spec)
277 && !is_aa_path_mute(spec->codec)) 323 && !is_aa_path_mute(spec->codec))
278 return; 324 return;
279 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 325 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
280 !spec->vt1708_jack_detectect); 326 !spec->vt1708_jack_detect);
281 cancel_delayed_work_sync(&spec->vt1708_hp_work); 327 cancel_delayed_work_sync(&spec->vt1708_hp_work);
282} 328}
283 329
@@ -295,7 +341,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
295 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 341 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
296 342
297 set_widgets_power_state(codec); 343 set_widgets_power_state(codec);
298 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1); 344 analog_low_current_mode(snd_kcontrol_chip(kcontrol));
299 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { 345 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
300 if (is_aa_path_mute(codec)) 346 if (is_aa_path_mute(codec))
301 vt1708_start_hp_work(codec->spec); 347 vt1708_start_hp_work(codec->spec);
@@ -315,168 +361,44 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
315 .put = analog_input_switch_put, \ 361 .put = analog_input_switch_put, \
316 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) } 362 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
317 363
318static void via_hp_bind_automute(struct hda_codec *codec);
319
320static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
321 struct snd_ctl_elem_value *ucontrol)
322{
323 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
324 struct via_spec *spec = codec->spec;
325 int i;
326 int change = 0;
327
328 long *valp = ucontrol->value.integer.value;
329 int lmute, rmute;
330 if (strstr(kcontrol->id.name, "Switch") == NULL) {
331 snd_printd("Invalid control!\n");
332 return change;
333 }
334 change = snd_hda_mixer_amp_switch_put(kcontrol,
335 ucontrol);
336 /* Get mute value */
337 lmute = *valp ? 0 : HDA_AMP_MUTE;
338 valp++;
339 rmute = *valp ? 0 : HDA_AMP_MUTE;
340
341 /* Set hp pins */
342 if (!spec->hp_independent_mode) {
343 for (i = 0; i < spec->autocfg.hp_outs; i++) {
344 snd_hda_codec_amp_update(
345 codec, spec->autocfg.hp_pins[i],
346 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
347 lmute);
348 snd_hda_codec_amp_update(
349 codec, spec->autocfg.hp_pins[i],
350 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
351 rmute);
352 }
353 }
354
355 if (!lmute && !rmute) {
356 /* Line Outs */
357 for (i = 0; i < spec->autocfg.line_outs; i++)
358 snd_hda_codec_amp_stereo(
359 codec, spec->autocfg.line_out_pins[i],
360 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
361 /* Speakers */
362 for (i = 0; i < spec->autocfg.speaker_outs; i++)
363 snd_hda_codec_amp_stereo(
364 codec, spec->autocfg.speaker_pins[i],
365 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
366 /* unmute */
367 via_hp_bind_automute(codec);
368
369 } else {
370 if (lmute) {
371 /* Mute all left channels */
372 for (i = 1; i < spec->autocfg.line_outs; i++)
373 snd_hda_codec_amp_update(
374 codec,
375 spec->autocfg.line_out_pins[i],
376 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
377 lmute);
378 for (i = 0; i < spec->autocfg.speaker_outs; i++)
379 snd_hda_codec_amp_update(
380 codec,
381 spec->autocfg.speaker_pins[i],
382 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
383 lmute);
384 }
385 if (rmute) {
386 /* mute all right channels */
387 for (i = 1; i < spec->autocfg.line_outs; i++)
388 snd_hda_codec_amp_update(
389 codec,
390 spec->autocfg.line_out_pins[i],
391 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
392 rmute);
393 for (i = 0; i < spec->autocfg.speaker_outs; i++)
394 snd_hda_codec_amp_update(
395 codec,
396 spec->autocfg.speaker_pins[i],
397 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
398 rmute);
399 }
400 }
401 return change;
402}
403
404#define BIND_PIN_MUTE \
405 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
406 .name = NULL, \
407 .index = 0, \
408 .info = snd_hda_mixer_amp_switch_info, \
409 .get = snd_hda_mixer_amp_switch_get, \
410 .put = bind_pin_switch_put, \
411 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
412
413static const struct snd_kcontrol_new via_control_templates[] = { 364static const struct snd_kcontrol_new via_control_templates[] = {
414 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 365 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
415 HDA_CODEC_MUTE(NULL, 0, 0, 0), 366 HDA_CODEC_MUTE(NULL, 0, 0, 0),
416 ANALOG_INPUT_MUTE, 367 ANALOG_INPUT_MUTE,
417 BIND_PIN_MUTE,
418};
419
420static const hda_nid_t vt1708_adc_nids[2] = {
421 /* ADC1-2 */
422 0x15, 0x27
423}; 368};
424 369
425static const hda_nid_t vt1709_adc_nids[3] = {
426 /* ADC1-2 */
427 0x14, 0x15, 0x16
428};
429 370
430static const hda_nid_t vt1708B_adc_nids[2] = { 371/* add dynamic controls */
431 /* ADC1-2 */ 372static struct snd_kcontrol_new *__via_clone_ctl(struct via_spec *spec,
432 0x13, 0x14 373 const struct snd_kcontrol_new *tmpl,
433}; 374 const char *name)
434 375{
435static const hda_nid_t vt1708S_adc_nids[2] = { 376 struct snd_kcontrol_new *knew;
436 /* ADC1-2 */
437 0x13, 0x14
438};
439
440static const hda_nid_t vt1702_adc_nids[3] = {
441 /* ADC1-2 */
442 0x12, 0x20, 0x1F
443};
444
445static const hda_nid_t vt1718S_adc_nids[2] = {
446 /* ADC1-2 */
447 0x10, 0x11
448};
449
450static const hda_nid_t vt1716S_adc_nids[2] = {
451 /* ADC1-2 */
452 0x13, 0x14
453};
454
455static const hda_nid_t vt2002P_adc_nids[2] = {
456 /* ADC1-2 */
457 0x10, 0x11
458};
459
460static const hda_nid_t vt1812_adc_nids[2] = {
461 /* ADC1-2 */
462 0x10, 0x11
463};
464 377
378 snd_array_init(&spec->kctls, sizeof(*knew), 32);
379 knew = snd_array_new(&spec->kctls);
380 if (!knew)
381 return NULL;
382 *knew = *tmpl;
383 if (!name)
384 name = tmpl->name;
385 if (name) {
386 knew->name = kstrdup(name, GFP_KERNEL);
387 if (!knew->name)
388 return NULL;
389 }
390 return knew;
391}
465 392
466/* add dynamic controls */
467static int __via_add_control(struct via_spec *spec, int type, const char *name, 393static int __via_add_control(struct via_spec *spec, int type, const char *name,
468 int idx, unsigned long val) 394 int idx, unsigned long val)
469{ 395{
470 struct snd_kcontrol_new *knew; 396 struct snd_kcontrol_new *knew;
471 397
472 snd_array_init(&spec->kctls, sizeof(*knew), 32); 398 knew = __via_clone_ctl(spec, &via_control_templates[type], name);
473 knew = snd_array_new(&spec->kctls);
474 if (!knew) 399 if (!knew)
475 return -ENOMEM; 400 return -ENOMEM;
476 *knew = via_control_templates[type]; 401 knew->index = idx;
477 knew->name = kstrdup(name, GFP_KERNEL);
478 if (!knew->name)
479 return -ENOMEM;
480 if (get_amp_nid_(val)) 402 if (get_amp_nid_(val))
481 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 403 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
482 knew->private_value = val; 404 knew->private_value = val;
@@ -486,21 +408,7 @@ static int __via_add_control(struct via_spec *spec, int type, const char *name,
486#define via_add_control(spec, type, name, val) \ 408#define via_add_control(spec, type, name, val) \
487 __via_add_control(spec, type, name, 0, val) 409 __via_add_control(spec, type, name, 0, val)
488 410
489static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, 411#define via_clone_control(spec, tmpl) __via_clone_ctl(spec, tmpl, NULL)
490 const struct snd_kcontrol_new *tmpl)
491{
492 struct snd_kcontrol_new *knew;
493
494 snd_array_init(&spec->kctls, sizeof(*knew), 32);
495 knew = snd_array_new(&spec->kctls);
496 if (!knew)
497 return NULL;
498 *knew = *tmpl;
499 knew->name = kstrdup(tmpl->name, GFP_KERNEL);
500 if (!knew->name)
501 return NULL;
502 return knew;
503}
504 412
505static void via_free_kctls(struct hda_codec *codec) 413static void via_free_kctls(struct hda_codec *codec)
506{ 414{
@@ -535,58 +443,208 @@ static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
535 return 0; 443 return 0;
536} 444}
537 445
538static void via_auto_set_output_and_unmute(struct hda_codec *codec, 446#define get_connection_index(codec, mux, nid) \
539 hda_nid_t nid, int pin_type, 447 snd_hda_get_conn_index(codec, mux, nid, 0)
540 int dac_idx) 448
449static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
450 unsigned int mask)
451{
452 unsigned int caps;
453 if (!nid)
454 return false;
455 caps = get_wcaps(codec, nid);
456 if (dir == HDA_INPUT)
457 caps &= AC_WCAP_IN_AMP;
458 else
459 caps &= AC_WCAP_OUT_AMP;
460 if (!caps)
461 return false;
462 if (query_amp_caps(codec, nid, dir) & mask)
463 return true;
464 return false;
465}
466
467#define have_mute(codec, nid, dir) \
468 check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
469
470/* enable/disable the output-route mixers */
471static void activate_output_mix(struct hda_codec *codec, struct nid_path *path,
472 hda_nid_t mix_nid, int idx, bool enable)
473{
474 int i, num, val;
475
476 if (!path)
477 return;
478 num = snd_hda_get_conn_list(codec, mix_nid, NULL);
479 for (i = 0; i < num; i++) {
480 if (i == idx)
481 val = AMP_IN_UNMUTE(i);
482 else
483 val = AMP_IN_MUTE(i);
484 snd_hda_codec_write(codec, mix_nid, 0,
485 AC_VERB_SET_AMP_GAIN_MUTE, val);
486 }
487}
488
489/* enable/disable the output-route */
490static void activate_output_path(struct hda_codec *codec, struct nid_path *path,
491 bool enable, bool force)
492{
493 struct via_spec *spec = codec->spec;
494 int i;
495 for (i = 0; i < path->depth; i++) {
496 hda_nid_t src, dst;
497 int idx = path->idx[i];
498 src = path->path[i];
499 if (i < path->depth - 1)
500 dst = path->path[i + 1];
501 else
502 dst = 0;
503 if (enable && path->multi[i])
504 snd_hda_codec_write(codec, dst, 0,
505 AC_VERB_SET_CONNECT_SEL, idx);
506 if (!force && (dst == spec->aa_mix_nid))
507 continue;
508 if (have_mute(codec, dst, HDA_INPUT))
509 activate_output_mix(codec, path, dst, idx, enable);
510 if (!force && (src == path->vol_ctl || src == path->mute_ctl))
511 continue;
512 if (have_mute(codec, src, HDA_OUTPUT)) {
513 int val = enable ? AMP_OUT_UNMUTE : AMP_OUT_MUTE;
514 snd_hda_codec_write(codec, src, 0,
515 AC_VERB_SET_AMP_GAIN_MUTE, val);
516 }
517 }
518}
519
520/* set the given pin as output */
521static void init_output_pin(struct hda_codec *codec, hda_nid_t pin,
522 int pin_type)
541{ 523{
542 /* set as output */ 524 if (!pin)
543 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 525 return;
526 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
544 pin_type); 527 pin_type);
545 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 528 if (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD)
546 AMP_OUT_UNMUTE); 529 snd_hda_codec_write(codec, pin, 0,
547 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
548 snd_hda_codec_write(codec, nid, 0,
549 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 530 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
550} 531}
551 532
533static void via_auto_init_output(struct hda_codec *codec,
534 struct nid_path *path, int pin_type)
535{
536 unsigned int caps;
537 hda_nid_t pin;
538
539 if (!path->depth)
540 return;
541 pin = path->path[path->depth - 1];
542
543 init_output_pin(codec, pin, pin_type);
544 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
545 if (caps & AC_AMPCAP_MUTE) {
546 unsigned int val;
547 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
548 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
549 AMP_OUT_MUTE | val);
550 }
551 activate_output_path(codec, path, true, true); /* force on */
552}
552 553
553static void via_auto_init_multi_out(struct hda_codec *codec) 554static void via_auto_init_multi_out(struct hda_codec *codec)
554{ 555{
555 struct via_spec *spec = codec->spec; 556 struct via_spec *spec = codec->spec;
557 struct nid_path *path;
556 int i; 558 int i;
557 559
558 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 560 for (i = 0; i < spec->autocfg.line_outs + spec->smart51_nums; i++) {
559 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 561 path = &spec->out_path[i];
560 if (nid) 562 if (!i && spec->aamix_mode && spec->out_mix_path.depth)
561 via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); 563 path = &spec->out_mix_path;
564 via_auto_init_output(codec, path, PIN_OUT);
565 }
566}
567
568/* deactivate the inactive headphone-paths */
569static void deactivate_hp_paths(struct hda_codec *codec)
570{
571 struct via_spec *spec = codec->spec;
572 int shared = spec->hp_indep_shared;
573
574 if (spec->hp_independent_mode) {
575 activate_output_path(codec, &spec->hp_path, false, false);
576 activate_output_path(codec, &spec->hp_mix_path, false, false);
577 if (shared)
578 activate_output_path(codec, &spec->out_path[shared],
579 false, false);
580 } else if (spec->aamix_mode || !spec->hp_path.depth) {
581 activate_output_path(codec, &spec->hp_indep_path, false, false);
582 activate_output_path(codec, &spec->hp_path, false, false);
583 } else {
584 activate_output_path(codec, &spec->hp_indep_path, false, false);
585 activate_output_path(codec, &spec->hp_mix_path, false, false);
562 } 586 }
563} 587}
564 588
565static void via_auto_init_hp_out(struct hda_codec *codec) 589static void via_auto_init_hp_out(struct hda_codec *codec)
566{ 590{
567 struct via_spec *spec = codec->spec; 591 struct via_spec *spec = codec->spec;
568 hda_nid_t pin;
569 int i;
570 592
571 for (i = 0; i < spec->autocfg.hp_outs; i++) { 593 if (!spec->hp_path.depth) {
572 pin = spec->autocfg.hp_pins[i]; 594 via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP);
573 if (pin) /* connect to front */ 595 return;
574 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 596 }
597 deactivate_hp_paths(codec);
598 if (spec->hp_independent_mode)
599 via_auto_init_output(codec, &spec->hp_indep_path, PIN_HP);
600 else if (spec->aamix_mode)
601 via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP);
602 else
603 via_auto_init_output(codec, &spec->hp_path, PIN_HP);
604}
605
606static void via_auto_init_speaker_out(struct hda_codec *codec)
607{
608 struct via_spec *spec = codec->spec;
609
610 if (!spec->autocfg.speaker_outs)
611 return;
612 if (!spec->speaker_path.depth) {
613 via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT);
614 return;
615 }
616 if (!spec->aamix_mode) {
617 activate_output_path(codec, &spec->speaker_mix_path,
618 false, false);
619 via_auto_init_output(codec, &spec->speaker_path, PIN_OUT);
620 } else {
621 activate_output_path(codec, &spec->speaker_path, false, false);
622 via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT);
575 } 623 }
576} 624}
577 625
578static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin); 626static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin);
627static void via_hp_automute(struct hda_codec *codec);
579 628
580static void via_auto_init_analog_input(struct hda_codec *codec) 629static void via_auto_init_analog_input(struct hda_codec *codec)
581{ 630{
582 struct via_spec *spec = codec->spec; 631 struct via_spec *spec = codec->spec;
583 const struct auto_pin_cfg *cfg = &spec->autocfg; 632 const struct auto_pin_cfg *cfg = &spec->autocfg;
633 hda_nid_t conn[HDA_MAX_CONNECTIONS];
584 unsigned int ctl; 634 unsigned int ctl;
585 int i; 635 int i, num_conns;
586 636
637 /* init ADCs */
638 for (i = 0; i < spec->num_adc_nids; i++) {
639 snd_hda_codec_write(codec, spec->adc_nids[i], 0,
640 AC_VERB_SET_AMP_GAIN_MUTE,
641 AMP_IN_UNMUTE(0));
642 }
643
644 /* init pins */
587 for (i = 0; i < cfg->num_inputs; i++) { 645 for (i = 0; i < cfg->num_inputs; i++) {
588 hda_nid_t nid = cfg->inputs[i].pin; 646 hda_nid_t nid = cfg->inputs[i].pin;
589 if (spec->smart51_enabled && is_smart51_pins(spec, nid)) 647 if (spec->smart51_enabled && is_smart51_pins(codec, nid))
590 ctl = PIN_OUT; 648 ctl = PIN_OUT;
591 else if (cfg->inputs[i].type == AUTO_PIN_MIC) 649 else if (cfg->inputs[i].type == AUTO_PIN_MIC)
592 ctl = PIN_VREF50; 650 ctl = PIN_VREF50;
@@ -595,6 +653,32 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
595 snd_hda_codec_write(codec, nid, 0, 653 snd_hda_codec_write(codec, nid, 0,
596 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl); 654 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
597 } 655 }
656
657 /* init input-src */
658 for (i = 0; i < spec->num_adc_nids; i++) {
659 int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx;
660 if (spec->mux_nids[adc_idx]) {
661 int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx;
662 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
663 AC_VERB_SET_CONNECT_SEL,
664 mux_idx);
665 }
666 if (spec->dyn_adc_switch)
667 break; /* only one input-src */
668 }
669
670 /* init aa-mixer */
671 if (!spec->aa_mix_nid)
672 return;
673 num_conns = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
674 ARRAY_SIZE(conn));
675 for (i = 0; i < num_conns; i++) {
676 unsigned int caps = get_wcaps(codec, conn[i]);
677 if (get_wcaps_type(caps) == AC_WID_PIN)
678 snd_hda_codec_write(codec, spec->aa_mix_nid, 0,
679 AC_VERB_SET_AMP_GAIN_MUTE,
680 AMP_IN_MUTE(i));
681 }
598} 682}
599 683
600static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, 684static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
@@ -605,9 +689,13 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
605 unsigned no_presence = (def_conf & AC_DEFCFG_MISC) 689 unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
606 >> AC_DEFCFG_MISC_SHIFT 690 >> AC_DEFCFG_MISC_SHIFT
607 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */ 691 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
608 unsigned present = snd_hda_jack_detect(codec, nid);
609 struct via_spec *spec = codec->spec; 692 struct via_spec *spec = codec->spec;
610 if ((spec->smart51_enabled && is_smart51_pins(spec, nid)) 693 unsigned present = 0;
694
695 no_presence |= spec->no_pin_power_ctl;
696 if (!no_presence)
697 present = snd_hda_jack_detect(codec, nid);
698 if ((spec->smart51_enabled && is_smart51_pins(codec, nid))
611 || ((no_presence || present) 699 || ((no_presence || present)
612 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) { 700 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
613 *affected_parm = AC_PWRST_D0; /* if it's connected */ 701 *affected_parm = AC_PWRST_D0; /* if it's connected */
@@ -618,124 +706,139 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
618 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); 706 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
619} 707}
620 708
621/* 709static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
622 * input MUX handling 710 struct snd_ctl_elem_info *uinfo)
623 */
624static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
625 struct snd_ctl_elem_info *uinfo)
626{ 711{
627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 712 static const char * const texts[] = {
628 struct via_spec *spec = codec->spec; 713 "Disabled", "Enabled"
629 return snd_hda_input_mux_info(spec->input_mux, uinfo); 714 };
715
716 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
717 uinfo->count = 1;
718 uinfo->value.enumerated.items = 2;
719 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
720 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
721 strcpy(uinfo->value.enumerated.name,
722 texts[uinfo->value.enumerated.item]);
723 return 0;
630} 724}
631 725
632static int via_mux_enum_get(struct snd_kcontrol *kcontrol, 726static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
633 struct snd_ctl_elem_value *ucontrol) 727 struct snd_ctl_elem_value *ucontrol)
634{ 728{
635 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
636 struct via_spec *spec = codec->spec; 730 struct via_spec *spec = codec->spec;
637 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 731 ucontrol->value.enumerated.item[0] = !spec->no_pin_power_ctl;
638
639 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
640 return 0; 732 return 0;
641} 733}
642 734
643static int via_mux_enum_put(struct snd_kcontrol *kcontrol, 735static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
644 struct snd_ctl_elem_value *ucontrol) 736 struct snd_ctl_elem_value *ucontrol)
645{ 737{
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 738 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 struct via_spec *spec = codec->spec; 739 struct via_spec *spec = codec->spec;
648 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 740 unsigned int val = !ucontrol->value.enumerated.item[0];
649 int ret;
650 741
651 if (!spec->mux_nids[adc_idx]) 742 if (val == spec->no_pin_power_ctl)
652 return -EINVAL; 743 return 0;
653 /* switch to D0 beofre change index */ 744 spec->no_pin_power_ctl = val;
654 if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0,
655 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
656 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
657 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
658
659 ret = snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
660 spec->mux_nids[adc_idx],
661 &spec->cur_mux[adc_idx]);
662 /* update jack power state */
663 set_widgets_power_state(codec); 745 set_widgets_power_state(codec);
664 746 return 1;
665 return ret;
666} 747}
667 748
749static const struct snd_kcontrol_new via_pin_power_ctl_enum = {
750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
751 .name = "Dynamic Power-Control",
752 .info = via_pin_power_ctl_info,
753 .get = via_pin_power_ctl_get,
754 .put = via_pin_power_ctl_put,
755};
756
757
668static int via_independent_hp_info(struct snd_kcontrol *kcontrol, 758static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_info *uinfo) 759 struct snd_ctl_elem_info *uinfo)
670{ 760{
671 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 761 static const char * const texts[] = { "OFF", "ON" };
672 struct via_spec *spec = codec->spec; 762
673 return snd_hda_input_mux_info(spec->hp_mux, uinfo); 763 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
764 uinfo->count = 1;
765 uinfo->value.enumerated.items = 2;
766 if (uinfo->value.enumerated.item >= 2)
767 uinfo->value.enumerated.item = 1;
768 strcpy(uinfo->value.enumerated.name,
769 texts[uinfo->value.enumerated.item]);
770 return 0;
674} 771}
675 772
676static int via_independent_hp_get(struct snd_kcontrol *kcontrol, 773static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
677 struct snd_ctl_elem_value *ucontrol) 774 struct snd_ctl_elem_value *ucontrol)
678{ 775{
679 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 776 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
680 hda_nid_t nid = kcontrol->private_value; 777 struct via_spec *spec = codec->spec;
681 unsigned int pinsel;
682
683 /* use !! to translate conn sel 2 for VT1718S */
684 pinsel = !!snd_hda_codec_read(codec, nid, 0,
685 AC_VERB_GET_CONNECT_SEL,
686 0x00);
687 ucontrol->value.enumerated.item[0] = pinsel;
688 778
779 ucontrol->value.enumerated.item[0] = spec->hp_independent_mode;
689 return 0; 780 return 0;
690} 781}
691 782
692static void activate_ctl(struct hda_codec *codec, const char *name, int active) 783/* adjust spec->multiout setup according to the current flags */
784static void setup_playback_multi_pcm(struct via_spec *spec)
693{ 785{
694 struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name); 786 const struct auto_pin_cfg *cfg = &spec->autocfg;
695 if (ctl) { 787 spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums;
696 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 788 spec->multiout.hp_nid = 0;
697 ctl->vd[0].access |= active 789 if (!spec->hp_independent_mode) {
698 ? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE; 790 if (!spec->hp_indep_shared)
699 snd_ctl_notify(codec->bus->card, 791 spec->multiout.hp_nid = spec->hp_dac_nid;
700 SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id); 792 } else {
701 } 793 if (spec->hp_indep_shared)
702} 794 spec->multiout.num_dacs = cfg->line_outs - 1;
703
704static hda_nid_t side_mute_channel(struct via_spec *spec)
705{
706 switch (spec->codec_type) {
707 case VT1708: return 0x1b;
708 case VT1709_10CH: return 0x29;
709 case VT1708B_8CH: /* fall thru */
710 case VT1708S: return 0x27;
711 case VT2002P: return 0x19;
712 case VT1802: return 0x15;
713 case VT1812: return 0x15;
714 default: return 0;
715 } 795 }
716} 796}
717 797
718static int update_side_mute_status(struct hda_codec *codec) 798/* update DAC setups according to indep-HP switch;
799 * this function is called only when indep-HP is modified
800 */
801static void switch_indep_hp_dacs(struct hda_codec *codec)
719{ 802{
720 /* mute side channel */
721 struct via_spec *spec = codec->spec; 803 struct via_spec *spec = codec->spec;
722 unsigned int parm; 804 int shared = spec->hp_indep_shared;
723 hda_nid_t sw3 = side_mute_channel(spec); 805 hda_nid_t shared_dac, hp_dac;
724 806
725 if (sw3) { 807 if (!spec->opened_streams)
726 if (VT2002P_COMPATIBLE(spec)) 808 return;
727 parm = spec->hp_independent_mode ? 809
728 AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1); 810 shared_dac = shared ? spec->multiout.dac_nids[shared] : 0;
729 else 811 hp_dac = spec->hp_dac_nid;
730 parm = spec->hp_independent_mode ? 812 if (spec->hp_independent_mode) {
731 AMP_OUT_MUTE : AMP_OUT_UNMUTE; 813 /* switch to indep-HP mode */
732 snd_hda_codec_write(codec, sw3, 0, 814 if (spec->active_streams & STREAM_MULTI_OUT) {
733 AC_VERB_SET_AMP_GAIN_MUTE, parm); 815 __snd_hda_codec_cleanup_stream(codec, hp_dac, 1);
734 if (spec->codec_type == VT1812) 816 __snd_hda_codec_cleanup_stream(codec, shared_dac, 1);
735 snd_hda_codec_write(codec, 0x1d, 0, 817 }
736 AC_VERB_SET_AMP_GAIN_MUTE, parm); 818 if (spec->active_streams & STREAM_INDEP_HP)
819 snd_hda_codec_setup_stream(codec, hp_dac,
820 spec->cur_hp_stream_tag, 0,
821 spec->cur_hp_format);
822 } else {
823 /* back to HP or shared-DAC */
824 if (spec->active_streams & STREAM_INDEP_HP)
825 __snd_hda_codec_cleanup_stream(codec, hp_dac, 1);
826 if (spec->active_streams & STREAM_MULTI_OUT) {
827 hda_nid_t dac;
828 int ch;
829 if (shared_dac) { /* reset mutli-ch DAC */
830 dac = shared_dac;
831 ch = shared * 2;
832 } else { /* reset HP DAC */
833 dac = hp_dac;
834 ch = 0;
835 }
836 snd_hda_codec_setup_stream(codec, dac,
837 spec->cur_dac_stream_tag, ch,
838 spec->cur_dac_format);
839 }
737 } 840 }
738 return 0; 841 setup_playback_multi_pcm(spec);
739} 842}
740 843
741static int via_independent_hp_put(struct snd_kcontrol *kcontrol, 844static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
@@ -743,55 +846,46 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
743{ 846{
744 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 847 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
745 struct via_spec *spec = codec->spec; 848 struct via_spec *spec = codec->spec;
746 hda_nid_t nid = kcontrol->private_value; 849 int cur, shared;
747 unsigned int pinsel = ucontrol->value.enumerated.item[0];
748 /* Get Independent Mode index of headphone pin widget */
749 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
750 ? 1 : 0;
751 if (spec->codec_type == VT1718S)
752 snd_hda_codec_write(codec, nid, 0,
753 AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
754 else
755 snd_hda_codec_write(codec, nid, 0,
756 AC_VERB_SET_CONNECT_SEL, pinsel);
757 850
758 if (spec->codec_type == VT1812) 851 mutex_lock(&spec->config_mutex);
759 snd_hda_codec_write(codec, 0x35, 0, 852 cur = !!ucontrol->value.enumerated.item[0];
760 AC_VERB_SET_CONNECT_SEL, pinsel); 853 if (spec->hp_independent_mode == cur) {
761 if (spec->multiout.hp_nid && spec->multiout.hp_nid 854 mutex_unlock(&spec->config_mutex);
762 != spec->multiout.dac_nids[HDA_FRONT]) 855 return 0;
763 snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
764 0, 0, 0);
765
766 update_side_mute_status(codec);
767 /* update HP volume/swtich active state */
768 if (spec->codec_type == VT1708S
769 || spec->codec_type == VT1702
770 || spec->codec_type == VT1718S
771 || spec->codec_type == VT1716S
772 || VT2002P_COMPATIBLE(spec)) {
773 activate_ctl(codec, "Headphone Playback Volume",
774 spec->hp_independent_mode);
775 activate_ctl(codec, "Headphone Playback Switch",
776 spec->hp_independent_mode);
777 } 856 }
857 spec->hp_independent_mode = cur;
858 shared = spec->hp_indep_shared;
859 deactivate_hp_paths(codec);
860 if (cur)
861 activate_output_path(codec, &spec->hp_indep_path, true, false);
862 else {
863 if (shared)
864 activate_output_path(codec, &spec->out_path[shared],
865 true, false);
866 if (spec->aamix_mode || !spec->hp_path.depth)
867 activate_output_path(codec, &spec->hp_mix_path,
868 true, false);
869 else
870 activate_output_path(codec, &spec->hp_path,
871 true, false);
872 }
873
874 switch_indep_hp_dacs(codec);
875 mutex_unlock(&spec->config_mutex);
876
778 /* update jack power state */ 877 /* update jack power state */
779 set_widgets_power_state(codec); 878 set_widgets_power_state(codec);
780 return 0; 879 via_hp_automute(codec);
880 return 1;
781} 881}
782 882
783static const struct snd_kcontrol_new via_hp_mixer[2] = { 883static const struct snd_kcontrol_new via_hp_mixer = {
784 { 884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 885 .name = "Independent HP",
786 .name = "Independent HP", 886 .info = via_independent_hp_info,
787 .info = via_independent_hp_info, 887 .get = via_independent_hp_get,
788 .get = via_independent_hp_get, 888 .put = via_independent_hp_put,
789 .put = via_independent_hp_put,
790 },
791 {
792 .iface = NID_MAPPING,
793 .name = "Independent HP",
794 },
795}; 889};
796 890
797static int via_hp_build(struct hda_codec *codec) 891static int via_hp_build(struct hda_codec *codec)
@@ -799,58 +893,28 @@ static int via_hp_build(struct hda_codec *codec)
799 struct via_spec *spec = codec->spec; 893 struct via_spec *spec = codec->spec;
800 struct snd_kcontrol_new *knew; 894 struct snd_kcontrol_new *knew;
801 hda_nid_t nid; 895 hda_nid_t nid;
802 int nums;
803 hda_nid_t conn[HDA_MAX_CONNECTIONS];
804 896
805 switch (spec->codec_type) { 897 nid = spec->autocfg.hp_pins[0];
806 case VT1718S: 898 knew = via_clone_control(spec, &via_hp_mixer);
807 nid = 0x34;
808 break;
809 case VT2002P:
810 case VT1802:
811 nid = 0x35;
812 break;
813 case VT1812:
814 nid = 0x3d;
815 break;
816 default:
817 nid = spec->autocfg.hp_pins[0];
818 break;
819 }
820
821 if (spec->codec_type != VT1708) {
822 nums = snd_hda_get_connections(codec, nid,
823 conn, HDA_MAX_CONNECTIONS);
824 if (nums <= 1)
825 return 0;
826 }
827
828 knew = via_clone_control(spec, &via_hp_mixer[0]);
829 if (knew == NULL) 899 if (knew == NULL)
830 return -ENOMEM; 900 return -ENOMEM;
831 901
832 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; 902 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
833 knew->private_value = nid;
834
835 knew = via_clone_control(spec, &via_hp_mixer[1]);
836 if (knew == NULL)
837 return -ENOMEM;
838 knew->subdevice = side_mute_channel(spec);
839 903
840 return 0; 904 return 0;
841} 905}
842 906
843static void notify_aa_path_ctls(struct hda_codec *codec) 907static void notify_aa_path_ctls(struct hda_codec *codec)
844{ 908{
909 struct via_spec *spec = codec->spec;
845 int i; 910 int i;
846 struct snd_ctl_elem_id id; 911
847 const char *labels[] = {"Mic", "Front Mic", "Line", "Rear Mic"}; 912 for (i = 0; i < spec->smart51_nums; i++) {
848 struct snd_kcontrol *ctl; 913 struct snd_kcontrol *ctl;
849 914 struct snd_ctl_elem_id id;
850 memset(&id, 0, sizeof(id)); 915 memset(&id, 0, sizeof(id));
851 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 916 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
852 for (i = 0; i < ARRAY_SIZE(labels); i++) { 917 sprintf(id.name, "%s Playback Volume", spec->smart51_labels[i]);
853 sprintf(id.name, "%s Playback Volume", labels[i]);
854 ctl = snd_hda_find_mixer_ctl(codec, id.name); 918 ctl = snd_hda_find_mixer_ctl(codec, id.name);
855 if (ctl) 919 if (ctl)
856 snd_ctl_notify(codec->bus->card, 920 snd_ctl_notify(codec->bus->card,
@@ -862,66 +926,28 @@ static void notify_aa_path_ctls(struct hda_codec *codec)
862static void mute_aa_path(struct hda_codec *codec, int mute) 926static void mute_aa_path(struct hda_codec *codec, int mute)
863{ 927{
864 struct via_spec *spec = codec->spec; 928 struct via_spec *spec = codec->spec;
865 hda_nid_t nid_mixer; 929 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
866 int start_idx;
867 int end_idx;
868 int i; 930 int i;
869 /* get nid of MW0 and start & end index */ 931
870 switch (spec->codec_type) {
871 case VT1708:
872 nid_mixer = 0x17;
873 start_idx = 2;
874 end_idx = 4;
875 break;
876 case VT1709_10CH:
877 case VT1709_6CH:
878 nid_mixer = 0x18;
879 start_idx = 2;
880 end_idx = 4;
881 break;
882 case VT1708B_8CH:
883 case VT1708B_4CH:
884 case VT1708S:
885 case VT1716S:
886 nid_mixer = 0x16;
887 start_idx = 2;
888 end_idx = 4;
889 break;
890 case VT1718S:
891 nid_mixer = 0x21;
892 start_idx = 1;
893 end_idx = 3;
894 break;
895 default:
896 return;
897 }
898 /* check AA path's mute status */ 932 /* check AA path's mute status */
899 for (i = start_idx; i <= end_idx; i++) { 933 for (i = 0; i < spec->smart51_nums; i++) {
900 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE; 934 if (spec->smart51_idxs[i] < 0)
901 snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i, 935 continue;
936 snd_hda_codec_amp_stereo(codec, spec->aa_mix_nid,
937 HDA_INPUT, spec->smart51_idxs[i],
902 HDA_AMP_MUTE, val); 938 HDA_AMP_MUTE, val);
903 } 939 }
904} 940}
905static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin) 941
942static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin)
906{ 943{
907 const struct auto_pin_cfg *cfg = &spec->autocfg; 944 struct via_spec *spec = codec->spec;
908 int i; 945 int i;
909 946
910 for (i = 0; i < cfg->num_inputs; i++) { 947 for (i = 0; i < spec->smart51_nums; i++)
911 if (pin == cfg->inputs[i].pin) 948 if (spec->smart51_pins[i] == pin)
912 return cfg->inputs[i].type <= AUTO_PIN_LINE_IN; 949 return true;
913 } 950 return false;
914 return 0;
915}
916
917static int via_smart51_info(struct snd_kcontrol *kcontrol,
918 struct snd_ctl_elem_info *uinfo)
919{
920 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
921 uinfo->count = 1;
922 uinfo->value.integer.min = 0;
923 uinfo->value.integer.max = 1;
924 return 0;
925} 951}
926 952
927static int via_smart51_get(struct snd_kcontrol *kcontrol, 953static int via_smart51_get(struct snd_kcontrol *kcontrol,
@@ -929,23 +955,8 @@ static int via_smart51_get(struct snd_kcontrol *kcontrol,
929{ 955{
930 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 956 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
931 struct via_spec *spec = codec->spec; 957 struct via_spec *spec = codec->spec;
932 const struct auto_pin_cfg *cfg = &spec->autocfg;
933 int on = 1;
934 int i;
935 958
936 for (i = 0; i < cfg->num_inputs; i++) { 959 *ucontrol->value.integer.value = spec->smart51_enabled;
937 hda_nid_t nid = cfg->inputs[i].pin;
938 int ctl = snd_hda_codec_read(codec, nid, 0,
939 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
940 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
941 continue;
942 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
943 spec->hp_independent_mode && spec->codec_type != VT1718S)
944 continue; /* ignore FMic for independent HP */
945 if ((ctl & AC_PINCTL_IN_EN) && !(ctl & AC_PINCTL_OUT_EN))
946 on = 0;
947 }
948 *ucontrol->value.integer.value = on;
949 return 0; 960 return 0;
950} 961}
951 962
@@ -954,21 +965,14 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
954{ 965{
955 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 966 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
956 struct via_spec *spec = codec->spec; 967 struct via_spec *spec = codec->spec;
957 const struct auto_pin_cfg *cfg = &spec->autocfg;
958 int out_in = *ucontrol->value.integer.value 968 int out_in = *ucontrol->value.integer.value
959 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN; 969 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
960 int i; 970 int i;
961 971
962 for (i = 0; i < cfg->num_inputs; i++) { 972 for (i = 0; i < spec->smart51_nums; i++) {
963 hda_nid_t nid = cfg->inputs[i].pin; 973 hda_nid_t nid = spec->smart51_pins[i];
964 unsigned int parm; 974 unsigned int parm;
965 975
966 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
967 continue;
968 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
969 spec->hp_independent_mode && spec->codec_type != VT1718S)
970 continue; /* don't retask FMic for independent HP */
971
972 parm = snd_hda_codec_read(codec, nid, 0, 976 parm = snd_hda_codec_read(codec, nid, 0,
973 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 977 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
974 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); 978 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
@@ -980,171 +984,59 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
980 mute_aa_path(codec, 1); 984 mute_aa_path(codec, 1);
981 notify_aa_path_ctls(codec); 985 notify_aa_path_ctls(codec);
982 } 986 }
983 if (spec->codec_type == VT1718S) {
984 snd_hda_codec_amp_stereo(
985 codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
986 HDA_AMP_UNMUTE);
987 }
988 if (cfg->inputs[i].type == AUTO_PIN_MIC) {
989 if (spec->codec_type == VT1708S
990 || spec->codec_type == VT1716S) {
991 /* input = index 1 (AOW3) */
992 snd_hda_codec_write(
993 codec, nid, 0,
994 AC_VERB_SET_CONNECT_SEL, 1);
995 snd_hda_codec_amp_stereo(
996 codec, nid, HDA_OUTPUT,
997 0, HDA_AMP_MUTE, HDA_AMP_UNMUTE);
998 }
999 }
1000 } 987 }
1001 spec->smart51_enabled = *ucontrol->value.integer.value; 988 spec->smart51_enabled = *ucontrol->value.integer.value;
1002 set_widgets_power_state(codec); 989 set_widgets_power_state(codec);
1003 return 1; 990 return 1;
1004} 991}
1005 992
1006static const struct snd_kcontrol_new via_smart51_mixer[2] = { 993static const struct snd_kcontrol_new via_smart51_mixer = {
1007 { 994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1008 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 995 .name = "Smart 5.1",
1009 .name = "Smart 5.1", 996 .count = 1,
1010 .count = 1, 997 .info = snd_ctl_boolean_mono_info,
1011 .info = via_smart51_info, 998 .get = via_smart51_get,
1012 .get = via_smart51_get, 999 .put = via_smart51_put,
1013 .put = via_smart51_put,
1014 },
1015 {
1016 .iface = NID_MAPPING,
1017 .name = "Smart 5.1",
1018 }
1019}; 1000};
1020 1001
1021static int via_smart51_build(struct via_spec *spec) 1002static int via_smart51_build(struct hda_codec *codec)
1022{ 1003{
1023 struct snd_kcontrol_new *knew; 1004 struct via_spec *spec = codec->spec;
1024 const struct auto_pin_cfg *cfg = &spec->autocfg;
1025 hda_nid_t nid;
1026 int i;
1027 1005
1028 if (!cfg) 1006 if (!spec->smart51_nums)
1029 return 0; 1007 return 0;
1030 if (cfg->line_outs > 2) 1008 if (!via_clone_control(spec, &via_smart51_mixer))
1031 return 0;
1032
1033 knew = via_clone_control(spec, &via_smart51_mixer[0]);
1034 if (knew == NULL)
1035 return -ENOMEM; 1009 return -ENOMEM;
1036
1037 for (i = 0; i < cfg->num_inputs; i++) {
1038 nid = cfg->inputs[i].pin;
1039 if (cfg->inputs[i].type <= AUTO_PIN_LINE_IN) {
1040 knew = via_clone_control(spec, &via_smart51_mixer[1]);
1041 if (knew == NULL)
1042 return -ENOMEM;
1043 knew->subdevice = nid;
1044 break;
1045 }
1046 }
1047
1048 return 0; 1010 return 0;
1049} 1011}
1050 1012
1051/* capture mixer elements */ 1013/* check AA path's mute status */
1052static const struct snd_kcontrol_new vt1708_capture_mixer[] = { 1014static bool is_aa_path_mute(struct hda_codec *codec)
1053 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
1054 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
1055 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
1056 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
1057 {
1058 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1059 /* The multiple "Capture Source" controls confuse alsamixer
1060 * So call somewhat different..
1061 */
1062 /* .name = "Capture Source", */
1063 .name = "Input Source",
1064 .count = 1,
1065 .info = via_mux_enum_info,
1066 .get = via_mux_enum_get,
1067 .put = via_mux_enum_put,
1068 },
1069 { } /* end */
1070};
1071
1072/* check AA path's mute statue */
1073static int is_aa_path_mute(struct hda_codec *codec)
1074{ 1015{
1075 int mute = 1;
1076 hda_nid_t nid_mixer;
1077 int start_idx;
1078 int end_idx;
1079 int i;
1080 struct via_spec *spec = codec->spec; 1016 struct via_spec *spec = codec->spec;
1081 /* get nid of MW0 and start & end index */ 1017 const struct hda_amp_list *p;
1082 switch (spec->codec_type) { 1018 int i, ch, v;
1083 case VT1708B_8CH: 1019
1084 case VT1708B_4CH: 1020 for (i = 0; i < spec->num_loopbacks; i++) {
1085 case VT1708S: 1021 p = &spec->loopback_list[i];
1086 case VT1716S: 1022 for (ch = 0; ch < 2; ch++) {
1087 nid_mixer = 0x16; 1023 v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
1088 start_idx = 2; 1024 p->idx);
1089 end_idx = 4; 1025 if (!(v & HDA_AMP_MUTE) && v > 0)
1090 break; 1026 return false;
1091 case VT1702:
1092 nid_mixer = 0x1a;
1093 start_idx = 1;
1094 end_idx = 3;
1095 break;
1096 case VT1718S:
1097 nid_mixer = 0x21;
1098 start_idx = 1;
1099 end_idx = 3;
1100 break;
1101 case VT2002P:
1102 case VT1812:
1103 case VT1802:
1104 nid_mixer = 0x21;
1105 start_idx = 0;
1106 end_idx = 2;
1107 break;
1108 default:
1109 return 0;
1110 }
1111 /* check AA path's mute status */
1112 for (i = start_idx; i <= end_idx; i++) {
1113 unsigned int con_list = snd_hda_codec_read(
1114 codec, nid_mixer, 0, AC_VERB_GET_CONNECT_LIST, i/4*4);
1115 int shift = 8 * (i % 4);
1116 hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift;
1117 unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin);
1118 if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) {
1119 /* check mute status while the pin is connected */
1120 int mute_l = snd_hda_codec_amp_read(codec, nid_mixer, 0,
1121 HDA_INPUT, i) >> 7;
1122 int mute_r = snd_hda_codec_amp_read(codec, nid_mixer, 1,
1123 HDA_INPUT, i) >> 7;
1124 if (!mute_l || !mute_r) {
1125 mute = 0;
1126 break;
1127 }
1128 } 1027 }
1129 } 1028 }
1130 return mute; 1029 return true;
1131} 1030}
1132 1031
1133/* enter/exit analog low-current mode */ 1032/* enter/exit analog low-current mode */
1134static void analog_low_current_mode(struct hda_codec *codec, int stream_idle) 1033static void analog_low_current_mode(struct hda_codec *codec)
1135{ 1034{
1136 struct via_spec *spec = codec->spec; 1035 struct via_spec *spec = codec->spec;
1137 static int saved_stream_idle = 1; /* saved stream idle status */ 1036 bool enable;
1138 int enable = is_aa_path_mute(codec); 1037 unsigned int verb, parm;
1139 unsigned int verb = 0;
1140 unsigned int parm = 0;
1141 1038
1142 if (stream_idle == -1) /* stream status did not change */ 1039 enable = is_aa_path_mute(codec) && (spec->opened_streams != 0);
1143 enable = enable && saved_stream_idle;
1144 else {
1145 enable = enable && stream_idle;
1146 saved_stream_idle = stream_idle;
1147 }
1148 1040
1149 /* decide low current mode's verb & parameter */ 1041 /* decide low current mode's verb & parameter */
1150 switch (spec->codec_type) { 1042 switch (spec->codec_type) {
@@ -1179,119 +1071,69 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1179/* 1071/*
1180 * generic initialization of ADC, input mixers and output mixers 1072 * generic initialization of ADC, input mixers and output mixers
1181 */ 1073 */
1182static const struct hda_verb vt1708_volume_init_verbs[] = { 1074static const struct hda_verb vt1708_init_verbs[] = {
1183 /*
1184 * Unmute ADC0-1 and set the default input to mic-in
1185 */
1186 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1187 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1188
1189
1190 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1191 * mixer widget
1192 */
1193 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1194 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1195 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1196 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1197 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1198 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1199
1200 /*
1201 * Set up output mixers (0x19 - 0x1b)
1202 */
1203 /* set vol=0 to output mixers */
1204 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1205 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1206 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1207
1208 /* Setup default input MW0 to PW4 */
1209 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1210 /* PW9 Output enable */
1211 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1212 /* power down jack detect function */ 1075 /* power down jack detect function */
1213 {0x1, 0xf81, 0x1}, 1076 {0x1, 0xf81, 0x1},
1214 { } 1077 { }
1215}; 1078};
1216 1079
1217static int via_playback_pcm_open(struct hda_pcm_stream *hinfo, 1080static void set_stream_open(struct hda_codec *codec, int bit, bool active)
1081{
1082 struct via_spec *spec = codec->spec;
1083
1084 if (active)
1085 spec->opened_streams |= bit;
1086 else
1087 spec->opened_streams &= ~bit;
1088 analog_low_current_mode(codec);
1089}
1090
1091static int via_playback_multi_pcm_open(struct hda_pcm_stream *hinfo,
1218 struct hda_codec *codec, 1092 struct hda_codec *codec,
1219 struct snd_pcm_substream *substream) 1093 struct snd_pcm_substream *substream)
1220{ 1094{
1221 struct via_spec *spec = codec->spec; 1095 struct via_spec *spec = codec->spec;
1222 int idle = substream->pstr->substream_opened == 1 1096 const struct auto_pin_cfg *cfg = &spec->autocfg;
1223 && substream->ref_count == 0; 1097 int err;
1224 analog_low_current_mode(codec, idle); 1098
1225 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 1099 spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums;
1226 hinfo); 1100 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1101 set_stream_open(codec, STREAM_MULTI_OUT, true);
1102 err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1103 hinfo);
1104 if (err < 0) {
1105 set_stream_open(codec, STREAM_MULTI_OUT, false);
1106 return err;
1107 }
1108 return 0;
1227} 1109}
1228 1110
1229static void playback_multi_pcm_prep_0(struct hda_codec *codec, 1111static int via_playback_multi_pcm_close(struct hda_pcm_stream *hinfo,
1230 unsigned int stream_tag, 1112 struct hda_codec *codec,
1231 unsigned int format, 1113 struct snd_pcm_substream *substream)
1232 struct snd_pcm_substream *substream) 1114{
1115 set_stream_open(codec, STREAM_MULTI_OUT, false);
1116 return 0;
1117}
1118
1119static int via_playback_hp_pcm_open(struct hda_pcm_stream *hinfo,
1120 struct hda_codec *codec,
1121 struct snd_pcm_substream *substream)
1233{ 1122{
1234 struct via_spec *spec = codec->spec; 1123 struct via_spec *spec = codec->spec;
1235 struct hda_multi_out *mout = &spec->multiout;
1236 const hda_nid_t *nids = mout->dac_nids;
1237 int chs = substream->runtime->channels;
1238 int i;
1239 1124
1240 mutex_lock(&codec->spdif_mutex); 1125 if (snd_BUG_ON(!spec->hp_dac_nid))
1241 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { 1126 return -EINVAL;
1242 if (chs == 2 && 1127 set_stream_open(codec, STREAM_INDEP_HP, true);
1243 snd_hda_is_supported_format(codec, mout->dig_out_nid, 1128 return 0;
1244 format) && 1129}
1245 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { 1130
1246 mout->dig_out_used = HDA_DIG_ANALOG_DUP; 1131static int via_playback_hp_pcm_close(struct hda_pcm_stream *hinfo,
1247 /* turn off SPDIF once; otherwise the IEC958 bits won't 1132 struct hda_codec *codec,
1248 * be updated */ 1133 struct snd_pcm_substream *substream)
1249 if (codec->spdif_ctls & AC_DIG1_ENABLE) 1134{
1250 snd_hda_codec_write(codec, mout->dig_out_nid, 0, 1135 set_stream_open(codec, STREAM_INDEP_HP, false);
1251 AC_VERB_SET_DIGI_CONVERT_1, 1136 return 0;
1252 codec->spdif_ctls &
1253 ~AC_DIG1_ENABLE & 0xff);
1254 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1255 stream_tag, 0, format);
1256 /* turn on again (if needed) */
1257 if (codec->spdif_ctls & AC_DIG1_ENABLE)
1258 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1259 AC_VERB_SET_DIGI_CONVERT_1,
1260 codec->spdif_ctls & 0xff);
1261 } else {
1262 mout->dig_out_used = 0;
1263 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1264 0, 0, 0);
1265 }
1266 }
1267 mutex_unlock(&codec->spdif_mutex);
1268
1269 /* front */
1270 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
1271 0, format);
1272
1273 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
1274 && !spec->hp_independent_mode)
1275 /* headphone out will just decode front left/right (stereo) */
1276 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
1277 0, format);
1278
1279 /* extra outputs copied from front */
1280 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1281 if (mout->extra_out_nid[i])
1282 snd_hda_codec_setup_stream(codec,
1283 mout->extra_out_nid[i],
1284 stream_tag, 0, format);
1285
1286 /* surrounds */
1287 for (i = 1; i < mout->num_dacs; i++) {
1288 if (chs >= (i + 1) * 2) /* independent out */
1289 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1290 i * 2, format);
1291 else /* copy front */
1292 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1293 0, format);
1294 }
1295} 1137}
1296 1138
1297static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, 1139static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
@@ -1301,18 +1143,36 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1301 struct snd_pcm_substream *substream) 1143 struct snd_pcm_substream *substream)
1302{ 1144{
1303 struct via_spec *spec = codec->spec; 1145 struct via_spec *spec = codec->spec;
1304 struct hda_multi_out *mout = &spec->multiout;
1305 const hda_nid_t *nids = mout->dac_nids;
1306 1146
1307 if (substream->number == 0) 1147 mutex_lock(&spec->config_mutex);
1308 playback_multi_pcm_prep_0(codec, stream_tag, format, 1148 setup_playback_multi_pcm(spec);
1309 substream); 1149 snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
1310 else { 1150 format, substream);
1311 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && 1151 /* remember for dynamic DAC switch with indep-HP */
1312 spec->hp_independent_mode) 1152 spec->active_streams |= STREAM_MULTI_OUT;
1313 snd_hda_codec_setup_stream(codec, mout->hp_nid, 1153 spec->cur_dac_stream_tag = stream_tag;
1314 stream_tag, 0, format); 1154 spec->cur_dac_format = format;
1315 } 1155 mutex_unlock(&spec->config_mutex);
1156 vt1708_start_hp_work(spec);
1157 return 0;
1158}
1159
1160static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo,
1161 struct hda_codec *codec,
1162 unsigned int stream_tag,
1163 unsigned int format,
1164 struct snd_pcm_substream *substream)
1165{
1166 struct via_spec *spec = codec->spec;
1167
1168 mutex_lock(&spec->config_mutex);
1169 if (spec->hp_independent_mode)
1170 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid,
1171 stream_tag, 0, format);
1172 spec->active_streams |= STREAM_INDEP_HP;
1173 spec->cur_hp_stream_tag = stream_tag;
1174 spec->cur_hp_format = format;
1175 mutex_unlock(&spec->config_mutex);
1316 vt1708_start_hp_work(spec); 1176 vt1708_start_hp_work(spec);
1317 return 0; 1177 return 0;
1318} 1178}
@@ -1322,37 +1182,26 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1322 struct snd_pcm_substream *substream) 1182 struct snd_pcm_substream *substream)
1323{ 1183{
1324 struct via_spec *spec = codec->spec; 1184 struct via_spec *spec = codec->spec;
1325 struct hda_multi_out *mout = &spec->multiout;
1326 const hda_nid_t *nids = mout->dac_nids;
1327 int i;
1328 1185
1329 if (substream->number == 0) { 1186 mutex_lock(&spec->config_mutex);
1330 for (i = 0; i < mout->num_dacs; i++) 1187 snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1331 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); 1188 spec->active_streams &= ~STREAM_MULTI_OUT;
1332 1189 mutex_unlock(&spec->config_mutex);
1333 if (mout->hp_nid && !spec->hp_independent_mode) 1190 vt1708_stop_hp_work(spec);
1334 snd_hda_codec_setup_stream(codec, mout->hp_nid, 1191 return 0;
1335 0, 0, 0); 1192}
1336 1193
1337 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) 1194static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo,
1338 if (mout->extra_out_nid[i]) 1195 struct hda_codec *codec,
1339 snd_hda_codec_setup_stream(codec, 1196 struct snd_pcm_substream *substream)
1340 mout->extra_out_nid[i], 1197{
1341 0, 0, 0); 1198 struct via_spec *spec = codec->spec;
1342 mutex_lock(&codec->spdif_mutex); 1199
1343 if (mout->dig_out_nid && 1200 mutex_lock(&spec->config_mutex);
1344 mout->dig_out_used == HDA_DIG_ANALOG_DUP) { 1201 if (spec->hp_independent_mode)
1345 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 1202 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0);
1346 0, 0, 0); 1203 spec->active_streams &= ~STREAM_INDEP_HP;
1347 mout->dig_out_used = 0; 1204 mutex_unlock(&spec->config_mutex);
1348 }
1349 mutex_unlock(&codec->spdif_mutex);
1350 } else {
1351 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1352 spec->hp_independent_mode)
1353 snd_hda_codec_setup_stream(codec, mout->hp_nid,
1354 0, 0, 0);
1355 }
1356 vt1708_stop_hp_work(spec); 1205 vt1708_stop_hp_work(spec);
1357 return 0; 1206 return 0;
1358} 1207}
@@ -1421,47 +1270,127 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1421 return 0; 1270 return 0;
1422} 1271}
1423 1272
1424static const struct hda_pcm_stream vt1708_pcm_analog_playback = { 1273/* analog capture with dynamic ADC switching */
1425 .substreams = 2, 1274static int via_dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1275 struct hda_codec *codec,
1276 unsigned int stream_tag,
1277 unsigned int format,
1278 struct snd_pcm_substream *substream)
1279{
1280 struct via_spec *spec = codec->spec;
1281 int adc_idx = spec->inputs[spec->cur_mux[0]].adc_idx;
1282
1283 mutex_lock(&spec->config_mutex);
1284 spec->cur_adc = spec->adc_nids[adc_idx];
1285 spec->cur_adc_stream_tag = stream_tag;
1286 spec->cur_adc_format = format;
1287 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
1288 mutex_unlock(&spec->config_mutex);
1289 return 0;
1290}
1291
1292static int via_dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1293 struct hda_codec *codec,
1294 struct snd_pcm_substream *substream)
1295{
1296 struct via_spec *spec = codec->spec;
1297
1298 mutex_lock(&spec->config_mutex);
1299 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1300 spec->cur_adc = 0;
1301 mutex_unlock(&spec->config_mutex);
1302 return 0;
1303}
1304
1305/* re-setup the stream if running; called from input-src put */
1306static bool via_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
1307{
1308 struct via_spec *spec = codec->spec;
1309 int adc_idx = spec->inputs[cur].adc_idx;
1310 hda_nid_t adc = spec->adc_nids[adc_idx];
1311 bool ret = false;
1312
1313 mutex_lock(&spec->config_mutex);
1314 if (spec->cur_adc && spec->cur_adc != adc) {
1315 /* stream is running, let's swap the current ADC */
1316 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1317 spec->cur_adc = adc;
1318 snd_hda_codec_setup_stream(codec, adc,
1319 spec->cur_adc_stream_tag, 0,
1320 spec->cur_adc_format);
1321 ret = true;
1322 }
1323 mutex_unlock(&spec->config_mutex);
1324 return ret;
1325}
1326
1327static const struct hda_pcm_stream via_pcm_analog_playback = {
1328 .substreams = 1,
1426 .channels_min = 2, 1329 .channels_min = 2,
1427 .channels_max = 8, 1330 .channels_max = 8,
1428 .nid = 0x10, /* NID to query formats and rates */ 1331 /* NID is set in via_build_pcms */
1429 .ops = { 1332 .ops = {
1430 .open = via_playback_pcm_open, 1333 .open = via_playback_multi_pcm_open,
1334 .close = via_playback_multi_pcm_close,
1431 .prepare = via_playback_multi_pcm_prepare, 1335 .prepare = via_playback_multi_pcm_prepare,
1432 .cleanup = via_playback_multi_pcm_cleanup 1336 .cleanup = via_playback_multi_pcm_cleanup
1433 }, 1337 },
1434}; 1338};
1435 1339
1340static const struct hda_pcm_stream via_pcm_hp_playback = {
1341 .substreams = 1,
1342 .channels_min = 2,
1343 .channels_max = 2,
1344 /* NID is set in via_build_pcms */
1345 .ops = {
1346 .open = via_playback_hp_pcm_open,
1347 .close = via_playback_hp_pcm_close,
1348 .prepare = via_playback_hp_pcm_prepare,
1349 .cleanup = via_playback_hp_pcm_cleanup
1350 },
1351};
1352
1436static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { 1353static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1437 .substreams = 2, 1354 .substreams = 1,
1438 .channels_min = 2, 1355 .channels_min = 2,
1439 .channels_max = 8, 1356 .channels_max = 8,
1440 .nid = 0x10, /* NID to query formats and rates */ 1357 /* NID is set in via_build_pcms */
1441 /* We got noisy outputs on the right channel on VT1708 when 1358 /* We got noisy outputs on the right channel on VT1708 when
1442 * 24bit samples are used. Until any workaround is found, 1359 * 24bit samples are used. Until any workaround is found,
1443 * disable the 24bit format, so far. 1360 * disable the 24bit format, so far.
1444 */ 1361 */
1445 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1362 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1446 .ops = { 1363 .ops = {
1447 .open = via_playback_pcm_open, 1364 .open = via_playback_multi_pcm_open,
1365 .close = via_playback_multi_pcm_close,
1448 .prepare = via_playback_multi_pcm_prepare, 1366 .prepare = via_playback_multi_pcm_prepare,
1449 .cleanup = via_playback_multi_pcm_cleanup 1367 .cleanup = via_playback_multi_pcm_cleanup
1450 }, 1368 },
1451}; 1369};
1452 1370
1453static const struct hda_pcm_stream vt1708_pcm_analog_capture = { 1371static const struct hda_pcm_stream via_pcm_analog_capture = {
1454 .substreams = 2, 1372 .substreams = 1, /* will be changed in via_build_pcms() */
1455 .channels_min = 2, 1373 .channels_min = 2,
1456 .channels_max = 2, 1374 .channels_max = 2,
1457 .nid = 0x15, /* NID to query formats and rates */ 1375 /* NID is set in via_build_pcms */
1458 .ops = { 1376 .ops = {
1459 .prepare = via_capture_pcm_prepare, 1377 .prepare = via_capture_pcm_prepare,
1460 .cleanup = via_capture_pcm_cleanup 1378 .cleanup = via_capture_pcm_cleanup
1461 }, 1379 },
1462}; 1380};
1463 1381
1464static const struct hda_pcm_stream vt1708_pcm_digital_playback = { 1382static const struct hda_pcm_stream via_pcm_dyn_adc_analog_capture = {
1383 .substreams = 1,
1384 .channels_min = 2,
1385 .channels_max = 2,
1386 /* NID is set in via_build_pcms */
1387 .ops = {
1388 .prepare = via_dyn_adc_capture_pcm_prepare,
1389 .cleanup = via_dyn_adc_capture_pcm_cleanup,
1390 },
1391};
1392
1393static const struct hda_pcm_stream via_pcm_digital_playback = {
1465 .substreams = 1, 1394 .substreams = 1,
1466 .channels_min = 2, 1395 .channels_min = 2,
1467 .channels_max = 2, 1396 .channels_max = 2,
@@ -1474,19 +1403,47 @@ static const struct hda_pcm_stream vt1708_pcm_digital_playback = {
1474 }, 1403 },
1475}; 1404};
1476 1405
1477static const struct hda_pcm_stream vt1708_pcm_digital_capture = { 1406static const struct hda_pcm_stream via_pcm_digital_capture = {
1478 .substreams = 1, 1407 .substreams = 1,
1479 .channels_min = 2, 1408 .channels_min = 2,
1480 .channels_max = 2, 1409 .channels_max = 2,
1481}; 1410};
1482 1411
1412/*
1413 * slave controls for virtual master
1414 */
1415static const char * const via_slave_vols[] = {
1416 "Front Playback Volume",
1417 "Surround Playback Volume",
1418 "Center Playback Volume",
1419 "LFE Playback Volume",
1420 "Side Playback Volume",
1421 "Headphone Playback Volume",
1422 "Speaker Playback Volume",
1423 NULL,
1424};
1425
1426static const char * const via_slave_sws[] = {
1427 "Front Playback Switch",
1428 "Surround Playback Switch",
1429 "Center Playback Switch",
1430 "LFE Playback Switch",
1431 "Side Playback Switch",
1432 "Headphone Playback Switch",
1433 "Speaker Playback Switch",
1434 NULL,
1435};
1436
1483static int via_build_controls(struct hda_codec *codec) 1437static int via_build_controls(struct hda_codec *codec)
1484{ 1438{
1485 struct via_spec *spec = codec->spec; 1439 struct via_spec *spec = codec->spec;
1486 struct snd_kcontrol *kctl; 1440 struct snd_kcontrol *kctl;
1487 const struct snd_kcontrol_new *knew;
1488 int err, i; 1441 int err, i;
1489 1442
1443 if (spec->set_widgets_power_state)
1444 if (!via_clone_control(spec, &via_pin_power_ctl_enum))
1445 return -ENOMEM;
1446
1490 for (i = 0; i < spec->num_mixers; i++) { 1447 for (i = 0; i < spec->num_mixers; i++) {
1491 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1448 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1492 if (err < 0) 1449 if (err < 0)
@@ -1495,6 +1452,7 @@ static int via_build_controls(struct hda_codec *codec)
1495 1452
1496 if (spec->multiout.dig_out_nid) { 1453 if (spec->multiout.dig_out_nid) {
1497 err = snd_hda_create_spdif_out_ctls(codec, 1454 err = snd_hda_create_spdif_out_ctls(codec,
1455 spec->multiout.dig_out_nid,
1498 spec->multiout.dig_out_nid); 1456 spec->multiout.dig_out_nid);
1499 if (err < 0) 1457 if (err < 0)
1500 return err; 1458 return err;
@@ -1510,6 +1468,23 @@ static int via_build_controls(struct hda_codec *codec)
1510 return err; 1468 return err;
1511 } 1469 }
1512 1470
1471 /* if we have no master control, let's create it */
1472 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1473 unsigned int vmaster_tlv[4];
1474 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1475 HDA_OUTPUT, vmaster_tlv);
1476 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1477 vmaster_tlv, via_slave_vols);
1478 if (err < 0)
1479 return err;
1480 }
1481 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1482 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1483 NULL, via_slave_sws);
1484 if (err < 0)
1485 return err;
1486 }
1487
1513 /* assign Capture Source enums to NID */ 1488 /* assign Capture Source enums to NID */
1514 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 1489 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1515 for (i = 0; kctl && i < kctl->count; i++) { 1490 for (i = 0; kctl && i < kctl->count; i++) {
@@ -1518,22 +1493,9 @@ static int via_build_controls(struct hda_codec *codec)
1518 return err; 1493 return err;
1519 } 1494 }
1520 1495
1521 /* other nid->control mapping */
1522 for (i = 0; i < spec->num_mixers; i++) {
1523 for (knew = spec->mixers[i]; knew->name; knew++) {
1524 if (knew->iface != NID_MAPPING)
1525 continue;
1526 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1527 if (kctl == NULL)
1528 continue;
1529 err = snd_hda_add_nid(codec, kctl, 0,
1530 knew->subdevice);
1531 }
1532 }
1533
1534 /* init power states */ 1496 /* init power states */
1535 set_widgets_power_state(codec); 1497 set_widgets_power_state(codec);
1536 analog_low_current_mode(codec, 1); 1498 analog_low_current_mode(codec);
1537 1499
1538 via_free_kctls(codec); /* no longer needed */ 1500 via_free_kctls(codec); /* no longer needed */
1539 return 0; 1501 return 0;
@@ -1547,36 +1509,71 @@ static int via_build_pcms(struct hda_codec *codec)
1547 codec->num_pcms = 1; 1509 codec->num_pcms = 1;
1548 codec->pcm_info = info; 1510 codec->pcm_info = info;
1549 1511
1512 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
1513 "%s Analog", codec->chip_name);
1550 info->name = spec->stream_name_analog; 1514 info->name = spec->stream_name_analog;
1515
1516 if (!spec->stream_analog_playback)
1517 spec->stream_analog_playback = &via_pcm_analog_playback;
1551 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 1518 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1552 *(spec->stream_analog_playback); 1519 *spec->stream_analog_playback;
1553 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 1520 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1554 spec->multiout.dac_nids[0]; 1521 spec->multiout.dac_nids[0];
1555 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1556 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1557
1558 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 1522 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1559 spec->multiout.max_channels; 1523 spec->multiout.max_channels;
1560 1524
1525 if (!spec->stream_analog_capture) {
1526 if (spec->dyn_adc_switch)
1527 spec->stream_analog_capture =
1528 &via_pcm_dyn_adc_analog_capture;
1529 else
1530 spec->stream_analog_capture = &via_pcm_analog_capture;
1531 }
1532 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1533 *spec->stream_analog_capture;
1534 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1535 if (!spec->dyn_adc_switch)
1536 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
1537 spec->num_adc_nids;
1538
1561 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 1539 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1562 codec->num_pcms++; 1540 codec->num_pcms++;
1563 info++; 1541 info++;
1542 snprintf(spec->stream_name_digital,
1543 sizeof(spec->stream_name_digital),
1544 "%s Digital", codec->chip_name);
1564 info->name = spec->stream_name_digital; 1545 info->name = spec->stream_name_digital;
1565 info->pcm_type = HDA_PCM_TYPE_SPDIF; 1546 info->pcm_type = HDA_PCM_TYPE_SPDIF;
1566 if (spec->multiout.dig_out_nid) { 1547 if (spec->multiout.dig_out_nid) {
1548 if (!spec->stream_digital_playback)
1549 spec->stream_digital_playback =
1550 &via_pcm_digital_playback;
1567 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 1551 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1568 *(spec->stream_digital_playback); 1552 *spec->stream_digital_playback;
1569 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 1553 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1570 spec->multiout.dig_out_nid; 1554 spec->multiout.dig_out_nid;
1571 } 1555 }
1572 if (spec->dig_in_nid) { 1556 if (spec->dig_in_nid) {
1557 if (!spec->stream_digital_capture)
1558 spec->stream_digital_capture =
1559 &via_pcm_digital_capture;
1573 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 1560 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1574 *(spec->stream_digital_capture); 1561 *spec->stream_digital_capture;
1575 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 1562 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1576 spec->dig_in_nid; 1563 spec->dig_in_nid;
1577 } 1564 }
1578 } 1565 }
1579 1566
1567 if (spec->hp_dac_nid) {
1568 codec->num_pcms++;
1569 info++;
1570 snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp),
1571 "%s HP", codec->chip_name);
1572 info->name = spec->stream_name_hp;
1573 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback;
1574 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1575 spec->hp_dac_nid;
1576 }
1580 return 0; 1577 return 0;
1581} 1578}
1582 1579
@@ -1589,57 +1586,62 @@ static void via_free(struct hda_codec *codec)
1589 1586
1590 via_free_kctls(codec); 1587 via_free_kctls(codec);
1591 vt1708_stop_hp_work(spec); 1588 vt1708_stop_hp_work(spec);
1592 kfree(codec->spec); 1589 kfree(spec->bind_cap_vol);
1590 kfree(spec->bind_cap_sw);
1591 kfree(spec);
1593} 1592}
1594 1593
1595/* mute internal speaker if HP is plugged */ 1594/* mute/unmute outputs */
1596static void via_hp_automute(struct hda_codec *codec) 1595static void toggle_output_mutes(struct hda_codec *codec, int num_pins,
1596 hda_nid_t *pins, bool mute)
1597{ 1597{
1598 unsigned int present = 0; 1598 int i;
1599 struct via_spec *spec = codec->spec; 1599 for (i = 0; i < num_pins; i++) {
1600 1600 unsigned int parm = snd_hda_codec_read(codec, pins[i], 0,
1601 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 1601 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1602 1602 if (parm & AC_PINCTL_IN_EN)
1603 if (!spec->hp_independent_mode) { 1603 continue;
1604 struct snd_ctl_elem_id id; 1604 if (mute)
1605 /* auto mute */ 1605 parm &= ~AC_PINCTL_OUT_EN;
1606 snd_hda_codec_amp_stereo( 1606 else
1607 codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0, 1607 parm |= AC_PINCTL_OUT_EN;
1608 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 1608 snd_hda_codec_write(codec, pins[i], 0,
1609 /* notify change */ 1609 AC_VERB_SET_PIN_WIDGET_CONTROL, parm);
1610 memset(&id, 0, sizeof(id));
1611 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1612 strcpy(id.name, "Front Playback Switch");
1613 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1614 &id);
1615 } 1610 }
1616} 1611}
1617 1612
1618/* mute mono out if HP or Line out is plugged */ 1613/* mute internal speaker if line-out is plugged */
1619static void via_mono_automute(struct hda_codec *codec) 1614static void via_line_automute(struct hda_codec *codec, int present)
1620{ 1615{
1621 unsigned int hp_present, lineout_present;
1622 struct via_spec *spec = codec->spec; 1616 struct via_spec *spec = codec->spec;
1623 1617
1624 if (spec->codec_type != VT1716S) 1618 if (!spec->autocfg.speaker_outs)
1625 return; 1619 return;
1626 1620 if (!present)
1627 lineout_present = snd_hda_jack_detect(codec, 1621 present = snd_hda_jack_detect(codec,
1628 spec->autocfg.line_out_pins[0]); 1622 spec->autocfg.line_out_pins[0]);
1623 toggle_output_mutes(codec, spec->autocfg.speaker_outs,
1624 spec->autocfg.speaker_pins,
1625 present);
1626}
1629 1627
1630 /* Mute Mono Out if Line Out is plugged */ 1628/* mute internal speaker if HP is plugged */
1631 if (lineout_present) { 1629static void via_hp_automute(struct hda_codec *codec)
1632 snd_hda_codec_amp_stereo( 1630{
1633 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE); 1631 int present = 0;
1634 return; 1632 int nums;
1635 } 1633 struct via_spec *spec = codec->spec;
1636 1634
1637 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 1635 if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0])
1636 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
1638 1637
1639 if (!spec->hp_independent_mode) 1638 if (spec->smart51_enabled)
1640 snd_hda_codec_amp_stereo( 1639 nums = spec->autocfg.line_outs + spec->smart51_nums;
1641 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, 1640 else
1642 hp_present ? HDA_AMP_MUTE : 0); 1641 nums = spec->autocfg.line_outs;
1642 toggle_output_mutes(codec, nums, spec->autocfg.line_out_pins, present);
1643
1644 via_line_automute(codec, present);
1643} 1645}
1644 1646
1645static void via_gpio_control(struct hda_codec *codec) 1647static void via_gpio_control(struct hda_codec *codec)
@@ -1664,9 +1666,9 @@ static void via_gpio_control(struct hda_codec *codec)
1664 1666
1665 if (gpio_data == 0x02) { 1667 if (gpio_data == 0x02) {
1666 /* unmute line out */ 1668 /* unmute line out */
1667 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0], 1669 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1668 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0); 1670 AC_VERB_SET_PIN_WIDGET_CONTROL,
1669 1671 PIN_OUT);
1670 if (vol_counter & 0x20) { 1672 if (vol_counter & 0x20) {
1671 /* decrease volume */ 1673 /* decrease volume */
1672 if (vol > master_vol) 1674 if (vol > master_vol)
@@ -1683,73 +1685,12 @@ static void via_gpio_control(struct hda_codec *codec)
1683 } 1685 }
1684 } else if (!(gpio_data & 0x02)) { 1686 } else if (!(gpio_data & 0x02)) {
1685 /* mute line out */ 1687 /* mute line out */
1686 snd_hda_codec_amp_stereo(codec, 1688 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1687 spec->autocfg.line_out_pins[0], 1689 AC_VERB_SET_PIN_WIDGET_CONTROL,
1688 HDA_OUTPUT, 0, HDA_AMP_MUTE, 1690 0);
1689 HDA_AMP_MUTE);
1690 }
1691}
1692
1693/* mute Internal-Speaker if HP is plugged */
1694static void via_speaker_automute(struct hda_codec *codec)
1695{
1696 unsigned int hp_present;
1697 struct via_spec *spec = codec->spec;
1698
1699 if (!VT2002P_COMPATIBLE(spec))
1700 return;
1701
1702 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
1703
1704 if (!spec->hp_independent_mode) {
1705 struct snd_ctl_elem_id id;
1706 snd_hda_codec_amp_stereo(
1707 codec, spec->autocfg.speaker_pins[0], HDA_OUTPUT, 0,
1708 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
1709 /* notify change */
1710 memset(&id, 0, sizeof(id));
1711 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1712 strcpy(id.name, "Speaker Playback Switch");
1713 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1714 &id);
1715 }
1716}
1717
1718/* mute line-out and internal speaker if HP is plugged */
1719static void via_hp_bind_automute(struct hda_codec *codec)
1720{
1721 /* use long instead of int below just to avoid an internal compiler
1722 * error with gcc 4.0.x
1723 */
1724 unsigned long hp_present, present = 0;
1725 struct via_spec *spec = codec->spec;
1726 int i;
1727
1728 if (!spec->autocfg.hp_pins[0] || !spec->autocfg.line_out_pins[0])
1729 return;
1730
1731 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
1732
1733 present = snd_hda_jack_detect(codec, spec->autocfg.line_out_pins[0]);
1734
1735 if (!spec->hp_independent_mode) {
1736 /* Mute Line-Outs */
1737 for (i = 0; i < spec->autocfg.line_outs; i++)
1738 snd_hda_codec_amp_stereo(
1739 codec, spec->autocfg.line_out_pins[i],
1740 HDA_OUTPUT, 0,
1741 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
1742 if (hp_present)
1743 present = hp_present;
1744 } 1691 }
1745 /* Speakers */
1746 for (i = 0; i < spec->autocfg.speaker_outs; i++)
1747 snd_hda_codec_amp_stereo(
1748 codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0,
1749 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1750} 1692}
1751 1693
1752
1753/* unsolicited event for jack sensing */ 1694/* unsolicited event for jack sensing */
1754static void via_unsol_event(struct hda_codec *codec, 1695static void via_unsol_event(struct hda_codec *codec,
1755 unsigned int res) 1696 unsigned int res)
@@ -1761,46 +1702,13 @@ static void via_unsol_event(struct hda_codec *codec,
1761 1702
1762 res &= ~VIA_JACK_EVENT; 1703 res &= ~VIA_JACK_EVENT;
1763 1704
1764 if (res == VIA_HP_EVENT) 1705 if (res == VIA_HP_EVENT || res == VIA_LINE_EVENT)
1765 via_hp_automute(codec); 1706 via_hp_automute(codec);
1766 else if (res == VIA_GPIO_EVENT) 1707 else if (res == VIA_GPIO_EVENT)
1767 via_gpio_control(codec); 1708 via_gpio_control(codec);
1768 else if (res == VIA_MONO_EVENT)
1769 via_mono_automute(codec);
1770 else if (res == VIA_SPEAKER_EVENT)
1771 via_speaker_automute(codec);
1772 else if (res == VIA_BIND_HP_EVENT)
1773 via_hp_bind_automute(codec);
1774} 1709}
1775 1710
1776static int via_init(struct hda_codec *codec) 1711#ifdef CONFIG_PM
1777{
1778 struct via_spec *spec = codec->spec;
1779 int i;
1780 for (i = 0; i < spec->num_iverbs; i++)
1781 snd_hda_sequence_write(codec, spec->init_verbs[i]);
1782
1783 /* Lydia Add for EAPD enable */
1784 if (!spec->dig_in_nid) { /* No Digital In connection */
1785 if (spec->dig_in_pin) {
1786 snd_hda_codec_write(codec, spec->dig_in_pin, 0,
1787 AC_VERB_SET_PIN_WIDGET_CONTROL,
1788 PIN_OUT);
1789 snd_hda_codec_write(codec, spec->dig_in_pin, 0,
1790 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
1791 }
1792 } else /* enable SPDIF-input pin */
1793 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
1794 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
1795
1796 /* assign slave outs */
1797 if (spec->slave_dig_outs[0])
1798 codec->slave_dig_outs = spec->slave_dig_outs;
1799
1800 return 0;
1801}
1802
1803#ifdef SND_HDA_NEEDS_RESUME
1804static int via_suspend(struct hda_codec *codec, pm_message_t state) 1712static int via_suspend(struct hda_codec *codec, pm_message_t state)
1805{ 1713{
1806 struct via_spec *spec = codec->spec; 1714 struct via_spec *spec = codec->spec;
@@ -1819,12 +1727,16 @@ static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1819 1727
1820/* 1728/*
1821 */ 1729 */
1730
1731static int via_init(struct hda_codec *codec);
1732
1822static const struct hda_codec_ops via_patch_ops = { 1733static const struct hda_codec_ops via_patch_ops = {
1823 .build_controls = via_build_controls, 1734 .build_controls = via_build_controls,
1824 .build_pcms = via_build_pcms, 1735 .build_pcms = via_build_pcms,
1825 .init = via_init, 1736 .init = via_init,
1826 .free = via_free, 1737 .free = via_free,
1827#ifdef SND_HDA_NEEDS_RESUME 1738 .unsol_event = via_unsol_event,
1739#ifdef CONFIG_PM
1828 .suspend = via_suspend, 1740 .suspend = via_suspend,
1829#endif 1741#endif
1830#ifdef CONFIG_SND_HDA_POWER_SAVE 1742#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -1832,237 +1744,835 @@ static const struct hda_codec_ops via_patch_ops = {
1832#endif 1744#endif
1833}; 1745};
1834 1746
1835/* fill in the dac_nids table from the parsed pin configuration */ 1747static bool is_empty_dac(struct hda_codec *codec, hda_nid_t dac)
1836static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
1837 const struct auto_pin_cfg *cfg)
1838{ 1748{
1749 struct via_spec *spec = codec->spec;
1839 int i; 1750 int i;
1840 hda_nid_t nid;
1841 1751
1842 spec->multiout.num_dacs = cfg->line_outs; 1752 for (i = 0; i < spec->multiout.num_dacs; i++) {
1753 if (spec->multiout.dac_nids[i] == dac)
1754 return false;
1755 }
1756 if (spec->hp_dac_nid == dac)
1757 return false;
1758 return true;
1759}
1843 1760
1844 spec->multiout.dac_nids = spec->private_dac_nids; 1761static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1762 hda_nid_t target_dac, int with_aa_mix,
1763 struct nid_path *path, int depth)
1764{
1765 struct via_spec *spec = codec->spec;
1766 hda_nid_t conn[8];
1767 int i, nums;
1768
1769 if (nid == spec->aa_mix_nid) {
1770 if (!with_aa_mix)
1771 return false;
1772 with_aa_mix = 2; /* mark aa-mix is included */
1773 }
1845 1774
1846 for (i = 0; i < 4; i++) { 1775 nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn));
1776 for (i = 0; i < nums; i++) {
1777 if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT)
1778 continue;
1779 if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) {
1780 /* aa-mix is requested but not included? */
1781 if (!(spec->aa_mix_nid && with_aa_mix == 1))
1782 goto found;
1783 }
1784 }
1785 if (depth >= MAX_NID_PATH_DEPTH)
1786 return false;
1787 for (i = 0; i < nums; i++) {
1788 unsigned int type;
1789 type = get_wcaps_type(get_wcaps(codec, conn[i]));
1790 if (type == AC_WID_AUD_OUT)
1791 continue;
1792 if (__parse_output_path(codec, conn[i], target_dac,
1793 with_aa_mix, path, depth + 1))
1794 goto found;
1795 }
1796 return false;
1797
1798 found:
1799 path->path[path->depth] = conn[i];
1800 path->idx[path->depth] = i;
1801 if (nums > 1 && get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX)
1802 path->multi[path->depth] = 1;
1803 path->depth++;
1804 return true;
1805}
1806
1807static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1808 hda_nid_t target_dac, int with_aa_mix,
1809 struct nid_path *path)
1810{
1811 if (__parse_output_path(codec, nid, target_dac, with_aa_mix, path, 1)) {
1812 path->path[path->depth] = nid;
1813 path->depth++;
1814 snd_printdd("output-path: depth=%d, %02x/%02x/%02x/%02x/%02x\n",
1815 path->depth, path->path[0], path->path[1],
1816 path->path[2], path->path[3], path->path[4]);
1817 return true;
1818 }
1819 return false;
1820}
1821
1822static int via_auto_fill_dac_nids(struct hda_codec *codec)
1823{
1824 struct via_spec *spec = codec->spec;
1825 const struct auto_pin_cfg *cfg = &spec->autocfg;
1826 int i, dac_num;
1827 hda_nid_t nid;
1828
1829 spec->multiout.dac_nids = spec->private_dac_nids;
1830 dac_num = 0;
1831 for (i = 0; i < cfg->line_outs; i++) {
1832 hda_nid_t dac = 0;
1847 nid = cfg->line_out_pins[i]; 1833 nid = cfg->line_out_pins[i];
1848 if (nid) { 1834 if (!nid)
1849 /* config dac list */ 1835 continue;
1850 switch (i) { 1836 if (parse_output_path(codec, nid, 0, 0, &spec->out_path[i]))
1851 case AUTO_SEQ_FRONT: 1837 dac = spec->out_path[i].path[0];
1852 spec->private_dac_nids[i] = 0x10; 1838 if (!i && parse_output_path(codec, nid, dac, 1,
1853 break; 1839 &spec->out_mix_path))
1854 case AUTO_SEQ_CENLFE: 1840 dac = spec->out_mix_path.path[0];
1855 spec->private_dac_nids[i] = 0x12; 1841 if (dac) {
1856 break; 1842 spec->private_dac_nids[i] = dac;
1857 case AUTO_SEQ_SURROUND: 1843 dac_num++;
1858 spec->private_dac_nids[i] = 0x11;
1859 break;
1860 case AUTO_SEQ_SIDE:
1861 spec->private_dac_nids[i] = 0x13;
1862 break;
1863 }
1864 } 1844 }
1865 } 1845 }
1846 if (!spec->out_path[0].depth && spec->out_mix_path.depth) {
1847 spec->out_path[0] = spec->out_mix_path;
1848 spec->out_mix_path.depth = 0;
1849 }
1850 spec->multiout.num_dacs = dac_num;
1851 return 0;
1852}
1866 1853
1854static int create_ch_ctls(struct hda_codec *codec, const char *pfx,
1855 int chs, bool check_dac, struct nid_path *path)
1856{
1857 struct via_spec *spec = codec->spec;
1858 char name[32];
1859 hda_nid_t dac, pin, sel, nid;
1860 int err;
1861
1862 dac = check_dac ? path->path[0] : 0;
1863 pin = path->path[path->depth - 1];
1864 sel = path->depth > 1 ? path->path[1] : 0;
1865
1866 if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1867 nid = dac;
1868 else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1869 nid = pin;
1870 else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1871 nid = sel;
1872 else
1873 nid = 0;
1874 if (nid) {
1875 sprintf(name, "%s Playback Volume", pfx);
1876 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1877 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1878 if (err < 0)
1879 return err;
1880 path->vol_ctl = nid;
1881 }
1882
1883 if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_MUTE))
1884 nid = dac;
1885 else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_MUTE))
1886 nid = pin;
1887 else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_MUTE))
1888 nid = sel;
1889 else
1890 nid = 0;
1891 if (nid) {
1892 sprintf(name, "%s Playback Switch", pfx);
1893 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1894 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1895 if (err < 0)
1896 return err;
1897 path->mute_ctl = nid;
1898 }
1867 return 0; 1899 return 0;
1868} 1900}
1869 1901
1902static void mangle_smart51(struct hda_codec *codec)
1903{
1904 struct via_spec *spec = codec->spec;
1905 struct auto_pin_cfg *cfg = &spec->autocfg;
1906 struct auto_pin_cfg_item *ins = cfg->inputs;
1907 int i, j, nums, attr;
1908 int pins[AUTO_CFG_MAX_INS];
1909
1910 for (attr = INPUT_PIN_ATTR_REAR; attr >= INPUT_PIN_ATTR_NORMAL; attr--) {
1911 nums = 0;
1912 for (i = 0; i < cfg->num_inputs; i++) {
1913 unsigned int def;
1914 if (ins[i].type > AUTO_PIN_LINE_IN)
1915 continue;
1916 def = snd_hda_codec_get_pincfg(codec, ins[i].pin);
1917 if (snd_hda_get_input_pin_attr(def) != attr)
1918 continue;
1919 for (j = 0; j < nums; j++)
1920 if (ins[pins[j]].type < ins[i].type) {
1921 memmove(pins + j + 1, pins + j,
1922 (nums - j) * sizeof(int));
1923 break;
1924 }
1925 pins[j] = i;
1926 nums++;
1927 }
1928 if (cfg->line_outs + nums < 3)
1929 continue;
1930 for (i = 0; i < nums; i++) {
1931 hda_nid_t pin = ins[pins[i]].pin;
1932 spec->smart51_pins[spec->smart51_nums++] = pin;
1933 cfg->line_out_pins[cfg->line_outs++] = pin;
1934 if (cfg->line_outs == 3)
1935 break;
1936 }
1937 return;
1938 }
1939}
1940
1941static void copy_path_mixer_ctls(struct nid_path *dst, struct nid_path *src)
1942{
1943 dst->vol_ctl = src->vol_ctl;
1944 dst->mute_ctl = src->mute_ctl;
1945}
1946
1870/* add playback controls from the parsed DAC table */ 1947/* add playback controls from the parsed DAC table */
1871static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, 1948static int via_auto_create_multi_out_ctls(struct hda_codec *codec)
1872 const struct auto_pin_cfg *cfg)
1873{ 1949{
1874 char name[32]; 1950 struct via_spec *spec = codec->spec;
1951 struct auto_pin_cfg *cfg = &spec->autocfg;
1952 struct nid_path *path;
1875 static const char * const chname[4] = { 1953 static const char * const chname[4] = {
1876 "Front", "Surround", "C/LFE", "Side" 1954 "Front", "Surround", "C/LFE", "Side"
1877 }; 1955 };
1878 hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b}; 1956 int i, idx, err;
1879 int i, err; 1957 int old_line_outs;
1880
1881 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1882 nid = cfg->line_out_pins[i];
1883 1958
1884 if (!nid) 1959 /* check smart51 */
1885 continue; 1960 old_line_outs = cfg->line_outs;
1886 1961 if (cfg->line_outs == 1)
1887 nid_vol = nid_vols[i]; 1962 mangle_smart51(codec);
1888 1963
1889 if (i == AUTO_SEQ_CENLFE) { 1964 err = via_auto_fill_dac_nids(codec);
1890 /* Center/LFE */ 1965 if (err < 0)
1891 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1966 return err;
1892 "Center Playback Volume",
1893 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1894 HDA_OUTPUT));
1895 if (err < 0)
1896 return err;
1897 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1898 "LFE Playback Volume",
1899 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1900 HDA_OUTPUT));
1901 if (err < 0)
1902 return err;
1903 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1904 "Center Playback Switch",
1905 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1906 HDA_OUTPUT));
1907 if (err < 0)
1908 return err;
1909 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1910 "LFE Playback Switch",
1911 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1912 HDA_OUTPUT));
1913 if (err < 0)
1914 return err;
1915 } else if (i == AUTO_SEQ_FRONT) {
1916 /* add control to mixer index 0 */
1917 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1918 "Master Front Playback Volume",
1919 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1920 HDA_INPUT));
1921 if (err < 0)
1922 return err;
1923 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1924 "Master Front Playback Switch",
1925 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1926 HDA_INPUT));
1927 if (err < 0)
1928 return err;
1929 1967
1930 /* add control to PW3 */ 1968 if (spec->multiout.num_dacs < 3) {
1931 sprintf(name, "%s Playback Volume", chname[i]); 1969 spec->smart51_nums = 0;
1932 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1970 cfg->line_outs = old_line_outs;
1933 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 1971 }
1934 HDA_OUTPUT)); 1972 for (i = 0; i < cfg->line_outs; i++) {
1973 hda_nid_t pin, dac;
1974 pin = cfg->line_out_pins[i];
1975 dac = spec->multiout.dac_nids[i];
1976 if (!pin || !dac)
1977 continue;
1978 path = spec->out_path + i;
1979 if (i == HDA_CLFE) {
1980 err = create_ch_ctls(codec, "Center", 1, true, path);
1935 if (err < 0) 1981 if (err < 0)
1936 return err; 1982 return err;
1937 sprintf(name, "%s Playback Switch", chname[i]); 1983 err = create_ch_ctls(codec, "LFE", 2, true, path);
1938 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1939 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1940 HDA_OUTPUT));
1941 if (err < 0) 1984 if (err < 0)
1942 return err; 1985 return err;
1943 } else { 1986 } else {
1944 sprintf(name, "%s Playback Volume", chname[i]); 1987 const char *pfx = chname[i];
1945 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1988 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
1946 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 1989 cfg->line_outs == 1)
1947 HDA_OUTPUT)); 1990 pfx = "Speaker";
1948 if (err < 0) 1991 err = create_ch_ctls(codec, pfx, 3, true, path);
1949 return err;
1950 sprintf(name, "%s Playback Switch", chname[i]);
1951 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1952 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1953 HDA_OUTPUT));
1954 if (err < 0) 1992 if (err < 0)
1955 return err; 1993 return err;
1956 } 1994 }
1995 if (path != spec->out_path + i)
1996 copy_path_mixer_ctls(&spec->out_path[i], path);
1997 if (path == spec->out_path && spec->out_mix_path.depth)
1998 copy_path_mixer_ctls(&spec->out_mix_path, path);
1999 }
2000
2001 idx = get_connection_index(codec, spec->aa_mix_nid,
2002 spec->multiout.dac_nids[0]);
2003 if (idx >= 0) {
2004 /* add control to mixer */
2005 const char *name;
2006 name = spec->out_mix_path.depth ?
2007 "PCM Loopback Playback Volume" : "PCM Playback Volume";
2008 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2009 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
2010 idx, HDA_INPUT));
2011 if (err < 0)
2012 return err;
2013 name = spec->out_mix_path.depth ?
2014 "PCM Loopback Playback Switch" : "PCM Playback Switch";
2015 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2016 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
2017 idx, HDA_INPUT));
2018 if (err < 0)
2019 return err;
1957 } 2020 }
1958 2021
2022 cfg->line_outs = old_line_outs;
2023
1959 return 0; 2024 return 0;
1960} 2025}
1961 2026
1962static void create_hp_imux(struct via_spec *spec) 2027static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
1963{ 2028{
1964 int i; 2029 struct via_spec *spec = codec->spec;
1965 struct hda_input_mux *imux = &spec->private_imux[1]; 2030 struct nid_path *path;
1966 static const char * const texts[] = { "OFF", "ON", NULL}; 2031 bool check_dac;
2032 int i, err;
2033
2034 if (!pin)
2035 return 0;
2036
2037 if (!parse_output_path(codec, pin, 0, 0, &spec->hp_indep_path)) {
2038 for (i = HDA_SIDE; i >= HDA_CLFE; i--) {
2039 if (i < spec->multiout.num_dacs &&
2040 parse_output_path(codec, pin,
2041 spec->multiout.dac_nids[i], 0,
2042 &spec->hp_indep_path)) {
2043 spec->hp_indep_shared = i;
2044 break;
2045 }
2046 }
2047 }
2048 if (spec->hp_indep_path.depth) {
2049 spec->hp_dac_nid = spec->hp_indep_path.path[0];
2050 if (!spec->hp_indep_shared)
2051 spec->hp_path = spec->hp_indep_path;
2052 }
2053 /* optionally check front-path w/o AA-mix */
2054 if (!spec->hp_path.depth)
2055 parse_output_path(codec, pin,
2056 spec->multiout.dac_nids[HDA_FRONT], 0,
2057 &spec->hp_path);
1967 2058
1968 /* for hp mode select */ 2059 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
1969 for (i = 0; texts[i]; i++) 2060 1, &spec->hp_mix_path) && !spec->hp_path.depth)
1970 snd_hda_add_imux_item(imux, texts[i], i, NULL); 2061 return 0;
1971 2062
1972 spec->hp_mux = &spec->private_imux[1]; 2063 if (spec->hp_path.depth) {
2064 path = &spec->hp_path;
2065 check_dac = true;
2066 } else {
2067 path = &spec->hp_mix_path;
2068 check_dac = false;
2069 }
2070 err = create_ch_ctls(codec, "Headphone", 3, check_dac, path);
2071 if (err < 0)
2072 return err;
2073 if (check_dac)
2074 copy_path_mixer_ctls(&spec->hp_mix_path, path);
2075 else
2076 copy_path_mixer_ctls(&spec->hp_path, path);
2077 if (spec->hp_indep_path.depth)
2078 copy_path_mixer_ctls(&spec->hp_indep_path, path);
2079 return 0;
1973} 2080}
1974 2081
1975static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 2082static int via_auto_create_speaker_ctls(struct hda_codec *codec)
1976{ 2083{
2084 struct via_spec *spec = codec->spec;
2085 struct nid_path *path;
2086 bool check_dac;
2087 hda_nid_t pin, dac;
1977 int err; 2088 int err;
1978 2089
1979 if (!pin) 2090 pin = spec->autocfg.speaker_pins[0];
2091 if (!spec->autocfg.speaker_outs || !pin)
2092 return 0;
2093
2094 if (parse_output_path(codec, pin, 0, 0, &spec->speaker_path))
2095 dac = spec->speaker_path.path[0];
2096 if (!dac)
2097 parse_output_path(codec, pin,
2098 spec->multiout.dac_nids[HDA_FRONT], 0,
2099 &spec->speaker_path);
2100 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
2101 1, &spec->speaker_mix_path) && !dac)
2102 return 0;
2103
2104 /* no AA-path for front? */
2105 if (!spec->out_mix_path.depth && spec->speaker_mix_path.depth)
2106 dac = 0;
2107
2108 spec->speaker_dac_nid = dac;
2109 spec->multiout.extra_out_nid[0] = dac;
2110 if (dac) {
2111 path = &spec->speaker_path;
2112 check_dac = true;
2113 } else {
2114 path = &spec->speaker_mix_path;
2115 check_dac = false;
2116 }
2117 err = create_ch_ctls(codec, "Speaker", 3, check_dac, path);
2118 if (err < 0)
2119 return err;
2120 if (check_dac)
2121 copy_path_mixer_ctls(&spec->speaker_mix_path, path);
2122 else
2123 copy_path_mixer_ctls(&spec->speaker_path, path);
2124 return 0;
2125}
2126
2127#define via_aamix_ctl_info via_pin_power_ctl_info
2128
2129static int via_aamix_ctl_get(struct snd_kcontrol *kcontrol,
2130 struct snd_ctl_elem_value *ucontrol)
2131{
2132 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2133 struct via_spec *spec = codec->spec;
2134 ucontrol->value.enumerated.item[0] = spec->aamix_mode;
2135 return 0;
2136}
2137
2138static void update_aamix_paths(struct hda_codec *codec, int do_mix,
2139 struct nid_path *nomix, struct nid_path *mix)
2140{
2141 if (do_mix) {
2142 activate_output_path(codec, nomix, false, false);
2143 activate_output_path(codec, mix, true, false);
2144 } else {
2145 activate_output_path(codec, mix, false, false);
2146 activate_output_path(codec, nomix, true, false);
2147 }
2148}
2149
2150static int via_aamix_ctl_put(struct snd_kcontrol *kcontrol,
2151 struct snd_ctl_elem_value *ucontrol)
2152{
2153 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2154 struct via_spec *spec = codec->spec;
2155 unsigned int val = ucontrol->value.enumerated.item[0];
2156
2157 if (val == spec->aamix_mode)
2158 return 0;
2159 spec->aamix_mode = val;
2160 /* update front path */
2161 update_aamix_paths(codec, val, &spec->out_path[0], &spec->out_mix_path);
2162 /* update HP path */
2163 if (!spec->hp_independent_mode) {
2164 update_aamix_paths(codec, val, &spec->hp_path,
2165 &spec->hp_mix_path);
2166 }
2167 /* update speaker path */
2168 update_aamix_paths(codec, val, &spec->speaker_path,
2169 &spec->speaker_mix_path);
2170 return 1;
2171}
2172
2173static const struct snd_kcontrol_new via_aamix_ctl_enum = {
2174 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2175 .name = "Loopback Mixing",
2176 .info = via_aamix_ctl_info,
2177 .get = via_aamix_ctl_get,
2178 .put = via_aamix_ctl_put,
2179};
2180
2181static int via_auto_create_loopback_switch(struct hda_codec *codec)
2182{
2183 struct via_spec *spec = codec->spec;
2184
2185 if (!spec->aa_mix_nid || !spec->out_mix_path.depth)
2186 return 0; /* no loopback switching available */
2187 if (!via_clone_control(spec, &via_aamix_ctl_enum))
2188 return -ENOMEM;
2189 return 0;
2190}
2191
2192/* look for ADCs */
2193static int via_fill_adcs(struct hda_codec *codec)
2194{
2195 struct via_spec *spec = codec->spec;
2196 hda_nid_t nid = codec->start_nid;
2197 int i;
2198
2199 for (i = 0; i < codec->num_nodes; i++, nid++) {
2200 unsigned int wcaps = get_wcaps(codec, nid);
2201 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2202 continue;
2203 if (wcaps & AC_WCAP_DIGITAL)
2204 continue;
2205 if (!(wcaps & AC_WCAP_CONN_LIST))
2206 continue;
2207 if (spec->num_adc_nids >= ARRAY_SIZE(spec->adc_nids))
2208 return -ENOMEM;
2209 spec->adc_nids[spec->num_adc_nids++] = nid;
2210 }
2211 return 0;
2212}
2213
2214/* input-src control */
2215static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
2216 struct snd_ctl_elem_info *uinfo)
2217{
2218 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2219 struct via_spec *spec = codec->spec;
2220
2221 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2222 uinfo->count = 1;
2223 uinfo->value.enumerated.items = spec->num_inputs;
2224 if (uinfo->value.enumerated.item >= spec->num_inputs)
2225 uinfo->value.enumerated.item = spec->num_inputs - 1;
2226 strcpy(uinfo->value.enumerated.name,
2227 spec->inputs[uinfo->value.enumerated.item].label);
2228 return 0;
2229}
2230
2231static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
2232 struct snd_ctl_elem_value *ucontrol)
2233{
2234 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2235 struct via_spec *spec = codec->spec;
2236 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2237
2238 ucontrol->value.enumerated.item[0] = spec->cur_mux[idx];
2239 return 0;
2240}
2241
2242static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
2243 struct snd_ctl_elem_value *ucontrol)
2244{
2245 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2246 struct via_spec *spec = codec->spec;
2247 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2248 hda_nid_t mux;
2249 int cur;
2250
2251 cur = ucontrol->value.enumerated.item[0];
2252 if (cur < 0 || cur >= spec->num_inputs)
2253 return -EINVAL;
2254 if (spec->cur_mux[idx] == cur)
1980 return 0; 2255 return 0;
2256 spec->cur_mux[idx] = cur;
2257 if (spec->dyn_adc_switch) {
2258 int adc_idx = spec->inputs[cur].adc_idx;
2259 mux = spec->mux_nids[adc_idx];
2260 via_dyn_adc_pcm_resetup(codec, cur);
2261 } else {
2262 mux = spec->mux_nids[idx];
2263 if (snd_BUG_ON(!mux))
2264 return -EINVAL;
2265 }
2266
2267 if (mux) {
2268 /* switch to D0 beofre change index */
2269 if (snd_hda_codec_read(codec, mux, 0,
2270 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
2271 snd_hda_codec_write(codec, mux, 0,
2272 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2273 snd_hda_codec_write(codec, mux, 0,
2274 AC_VERB_SET_CONNECT_SEL,
2275 spec->inputs[cur].mux_idx);
2276 }
2277
2278 /* update jack power state */
2279 set_widgets_power_state(codec);
2280 return 0;
2281}
2282
2283static const struct snd_kcontrol_new via_input_src_ctl = {
2284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2285 /* The multiple "Capture Source" controls confuse alsamixer
2286 * So call somewhat different..
2287 */
2288 /* .name = "Capture Source", */
2289 .name = "Input Source",
2290 .info = via_mux_enum_info,
2291 .get = via_mux_enum_get,
2292 .put = via_mux_enum_put,
2293};
2294
2295static int create_input_src_ctls(struct hda_codec *codec, int count)
2296{
2297 struct via_spec *spec = codec->spec;
2298 struct snd_kcontrol_new *knew;
2299
2300 if (spec->num_inputs <= 1 || !count)
2301 return 0; /* no need for single src */
2302
2303 knew = via_clone_control(spec, &via_input_src_ctl);
2304 if (!knew)
2305 return -ENOMEM;
2306 knew->count = count;
2307 return 0;
2308}
2309
2310/* add the powersave loopback-list entry */
2311static void add_loopback_list(struct via_spec *spec, hda_nid_t mix, int idx)
2312{
2313 struct hda_amp_list *list;
1981 2314
1982 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */ 2315 if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
1983 spec->hp_independent_mode_index = 1; 2316 return;
2317 list = spec->loopback_list + spec->num_loopbacks;
2318 list->nid = mix;
2319 list->dir = HDA_INPUT;
2320 list->idx = idx;
2321 spec->num_loopbacks++;
2322 spec->loopback.amplist = spec->loopback_list;
2323}
1984 2324
1985 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2325static bool is_reachable_nid(struct hda_codec *codec, hda_nid_t src,
1986 "Headphone Playback Volume", 2326 hda_nid_t dst)
1987 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 2327{
2328 return snd_hda_get_conn_index(codec, src, dst, 1) >= 0;
2329}
2330
2331/* add the input-route to the given pin */
2332static bool add_input_route(struct hda_codec *codec, hda_nid_t pin)
2333{
2334 struct via_spec *spec = codec->spec;
2335 int c, idx;
2336
2337 spec->inputs[spec->num_inputs].adc_idx = -1;
2338 spec->inputs[spec->num_inputs].pin = pin;
2339 for (c = 0; c < spec->num_adc_nids; c++) {
2340 if (spec->mux_nids[c]) {
2341 idx = get_connection_index(codec, spec->mux_nids[c],
2342 pin);
2343 if (idx < 0)
2344 continue;
2345 spec->inputs[spec->num_inputs].mux_idx = idx;
2346 } else {
2347 if (!is_reachable_nid(codec, spec->adc_nids[c], pin))
2348 continue;
2349 }
2350 spec->inputs[spec->num_inputs].adc_idx = c;
2351 /* Can primary ADC satisfy all inputs? */
2352 if (!spec->dyn_adc_switch &&
2353 spec->num_inputs > 0 && spec->inputs[0].adc_idx != c) {
2354 snd_printd(KERN_INFO
2355 "via: dynamic ADC switching enabled\n");
2356 spec->dyn_adc_switch = 1;
2357 }
2358 return true;
2359 }
2360 return false;
2361}
2362
2363static int get_mux_nids(struct hda_codec *codec);
2364
2365/* parse input-routes; fill ADCs, MUXs and input-src entries */
2366static int parse_analog_inputs(struct hda_codec *codec)
2367{
2368 struct via_spec *spec = codec->spec;
2369 const struct auto_pin_cfg *cfg = &spec->autocfg;
2370 int i, err;
2371
2372 err = via_fill_adcs(codec);
1988 if (err < 0) 2373 if (err < 0)
1989 return err; 2374 return err;
1990 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2375 err = get_mux_nids(codec);
1991 "Headphone Playback Switch",
1992 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1993 if (err < 0) 2376 if (err < 0)
1994 return err; 2377 return err;
1995 2378
1996 create_hp_imux(spec); 2379 /* fill all input-routes */
2380 for (i = 0; i < cfg->num_inputs; i++) {
2381 if (add_input_route(codec, cfg->inputs[i].pin))
2382 spec->inputs[spec->num_inputs++].label =
2383 hda_get_autocfg_input_label(codec, cfg, i);
2384 }
2385
2386 /* check for internal loopback recording */
2387 if (spec->aa_mix_nid &&
2388 add_input_route(codec, spec->aa_mix_nid))
2389 spec->inputs[spec->num_inputs++].label = "Stereo Mixer";
1997 2390
1998 return 0; 2391 return 0;
1999} 2392}
2000 2393
2001/* create playback/capture controls for input pins */ 2394/* create analog-loopback volume/switch controls */
2002static int vt_auto_create_analog_input_ctls(struct hda_codec *codec, 2395static int create_loopback_ctls(struct hda_codec *codec)
2003 const struct auto_pin_cfg *cfg,
2004 hda_nid_t cap_nid,
2005 const hda_nid_t pin_idxs[],
2006 int num_idxs)
2007{ 2396{
2008 struct via_spec *spec = codec->spec; 2397 struct via_spec *spec = codec->spec;
2009 struct hda_input_mux *imux = &spec->private_imux[0]; 2398 const struct auto_pin_cfg *cfg = &spec->autocfg;
2010 int i, err, idx, type, type_idx = 0; 2399 const char *prev_label = NULL;
2400 int type_idx = 0;
2401 int i, j, err, idx;
2011 2402
2012 /* for internal loopback recording select */ 2403 if (!spec->aa_mix_nid)
2013 for (idx = 0; idx < num_idxs; idx++) { 2404 return 0;
2014 if (pin_idxs[idx] == 0xff) { 2405
2015 snd_hda_add_imux_item(imux, "Stereo Mixer", idx, NULL); 2406 for (i = 0; i < cfg->num_inputs; i++) {
2016 break; 2407 hda_nid_t pin = cfg->inputs[i].pin;
2408 const char *label = hda_get_autocfg_input_label(codec, cfg, i);
2409
2410 if (prev_label && !strcmp(label, prev_label))
2411 type_idx++;
2412 else
2413 type_idx = 0;
2414 prev_label = label;
2415 idx = get_connection_index(codec, spec->aa_mix_nid, pin);
2416 if (idx >= 0) {
2417 err = via_new_analog_input(spec, label, type_idx,
2418 idx, spec->aa_mix_nid);
2419 if (err < 0)
2420 return err;
2421 add_loopback_list(spec, spec->aa_mix_nid, idx);
2422 }
2423
2424 /* remember the label for smart51 control */
2425 for (j = 0; j < spec->smart51_nums; j++) {
2426 if (spec->smart51_pins[j] == pin) {
2427 spec->smart51_idxs[j] = idx;
2428 spec->smart51_labels[j] = label;
2429 break;
2430 }
2017 } 2431 }
2018 } 2432 }
2433 return 0;
2434}
2435
2436/* create mic-boost controls (if present) */
2437static int create_mic_boost_ctls(struct hda_codec *codec)
2438{
2439 struct via_spec *spec = codec->spec;
2440 const struct auto_pin_cfg *cfg = &spec->autocfg;
2441 int i, err;
2019 2442
2020 for (i = 0; i < cfg->num_inputs; i++) { 2443 for (i = 0; i < cfg->num_inputs; i++) {
2444 hda_nid_t pin = cfg->inputs[i].pin;
2445 unsigned int caps;
2021 const char *label; 2446 const char *label;
2022 type = cfg->inputs[i].type; 2447 char name[32];
2023 for (idx = 0; idx < num_idxs; idx++) 2448
2024 if (pin_idxs[idx] == cfg->inputs[i].pin) 2449 if (cfg->inputs[i].type != AUTO_PIN_MIC)
2025 break; 2450 continue;
2026 if (idx >= num_idxs) 2451 caps = query_amp_caps(codec, pin, HDA_INPUT);
2452 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS))
2027 continue; 2453 continue;
2028 if (i > 0 && type == cfg->inputs[i - 1].type)
2029 type_idx++;
2030 else
2031 type_idx = 0;
2032 label = hda_get_autocfg_input_label(codec, cfg, i); 2454 label = hda_get_autocfg_input_label(codec, cfg, i);
2033 if (spec->codec_type == VT1708S || 2455 snprintf(name, sizeof(name), "%s Boost Volume", label);
2034 spec->codec_type == VT1702 || 2456 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2035 spec->codec_type == VT1716S) 2457 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT));
2036 err = via_new_analog_input(spec, label, type_idx, 2458 if (err < 0)
2037 idx+1, cap_nid); 2459 return err;
2038 else 2460 }
2039 err = via_new_analog_input(spec, label, type_idx, 2461 return 0;
2040 idx, cap_nid); 2462}
2463
2464/* create capture and input-src controls for multiple streams */
2465static int create_multi_adc_ctls(struct hda_codec *codec)
2466{
2467 struct via_spec *spec = codec->spec;
2468 int i, err;
2469
2470 /* create capture mixer elements */
2471 for (i = 0; i < spec->num_adc_nids; i++) {
2472 hda_nid_t adc = spec->adc_nids[i];
2473 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL,
2474 "Capture Volume", i,
2475 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
2476 HDA_INPUT));
2477 if (err < 0)
2478 return err;
2479 err = __via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2480 "Capture Switch", i,
2481 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
2482 HDA_INPUT));
2041 if (err < 0) 2483 if (err < 0)
2042 return err; 2484 return err;
2043 snd_hda_add_imux_item(imux, label, idx, NULL);
2044 } 2485 }
2486
2487 /* input-source control */
2488 for (i = 0; i < spec->num_adc_nids; i++)
2489 if (!spec->mux_nids[i])
2490 break;
2491 err = create_input_src_ctls(codec, i);
2492 if (err < 0)
2493 return err;
2045 return 0; 2494 return 0;
2046} 2495}
2047 2496
2048/* create playback/capture controls for input pins */ 2497/* bind capture volume/switch */
2049static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec, 2498static struct snd_kcontrol_new via_bind_cap_vol_ctl =
2050 const struct auto_pin_cfg *cfg) 2499 HDA_BIND_VOL("Capture Volume", 0);
2500static struct snd_kcontrol_new via_bind_cap_sw_ctl =
2501 HDA_BIND_SW("Capture Switch", 0);
2502
2503static int init_bind_ctl(struct via_spec *spec, struct hda_bind_ctls **ctl_ret,
2504 struct hda_ctl_ops *ops)
2051{ 2505{
2052 static const hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 }; 2506 struct hda_bind_ctls *ctl;
2053 return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs, 2507 int i;
2054 ARRAY_SIZE(pin_idxs)); 2508
2509 ctl = kzalloc(sizeof(*ctl) + sizeof(long) * 4, GFP_KERNEL);
2510 if (!ctl)
2511 return -ENOMEM;
2512 ctl->ops = ops;
2513 for (i = 0; i < spec->num_adc_nids; i++)
2514 ctl->values[i] =
2515 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 3, 0, HDA_INPUT);
2516 *ctl_ret = ctl;
2517 return 0;
2055} 2518}
2056 2519
2057#ifdef CONFIG_SND_HDA_POWER_SAVE 2520/* create capture and input-src controls for dynamic ADC-switch case */
2058static const struct hda_amp_list vt1708_loopbacks[] = { 2521static int create_dyn_adc_ctls(struct hda_codec *codec)
2059 { 0x17, HDA_INPUT, 1 }, 2522{
2060 { 0x17, HDA_INPUT, 2 }, 2523 struct via_spec *spec = codec->spec;
2061 { 0x17, HDA_INPUT, 3 }, 2524 struct snd_kcontrol_new *knew;
2062 { 0x17, HDA_INPUT, 4 }, 2525 int err;
2063 { } /* end */ 2526
2064}; 2527 /* set up the bind capture ctls */
2065#endif 2528 err = init_bind_ctl(spec, &spec->bind_cap_vol, &snd_hda_bind_vol);
2529 if (err < 0)
2530 return err;
2531 err = init_bind_ctl(spec, &spec->bind_cap_sw, &snd_hda_bind_sw);
2532 if (err < 0)
2533 return err;
2534
2535 /* create capture mixer elements */
2536 knew = via_clone_control(spec, &via_bind_cap_vol_ctl);
2537 if (!knew)
2538 return -ENOMEM;
2539 knew->private_value = (long)spec->bind_cap_vol;
2540
2541 knew = via_clone_control(spec, &via_bind_cap_sw_ctl);
2542 if (!knew)
2543 return -ENOMEM;
2544 knew->private_value = (long)spec->bind_cap_sw;
2545
2546 /* input-source control */
2547 err = create_input_src_ctls(codec, 1);
2548 if (err < 0)
2549 return err;
2550 return 0;
2551}
2552
2553/* parse and create capture-related stuff */
2554static int via_auto_create_analog_input_ctls(struct hda_codec *codec)
2555{
2556 struct via_spec *spec = codec->spec;
2557 int err;
2558
2559 err = parse_analog_inputs(codec);
2560 if (err < 0)
2561 return err;
2562 if (spec->dyn_adc_switch)
2563 err = create_dyn_adc_ctls(codec);
2564 else
2565 err = create_multi_adc_ctls(codec);
2566 if (err < 0)
2567 return err;
2568 err = create_loopback_ctls(codec);
2569 if (err < 0)
2570 return err;
2571 err = create_mic_boost_ctls(codec);
2572 if (err < 0)
2573 return err;
2574 return 0;
2575}
2066 2576
2067static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid) 2577static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2068{ 2578{
@@ -2081,7 +2591,7 @@ static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2081 return; 2591 return;
2082} 2592}
2083 2593
2084static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol, 2594static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol,
2085 struct snd_ctl_elem_value *ucontrol) 2595 struct snd_ctl_elem_value *ucontrol)
2086{ 2596{
2087 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2597 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -2089,13 +2599,13 @@ static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
2089 2599
2090 if (spec->codec_type != VT1708) 2600 if (spec->codec_type != VT1708)
2091 return 0; 2601 return 0;
2092 spec->vt1708_jack_detectect = 2602 spec->vt1708_jack_detect =
2093 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1); 2603 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2094 ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect; 2604 ucontrol->value.integer.value[0] = spec->vt1708_jack_detect;
2095 return 0; 2605 return 0;
2096} 2606}
2097 2607
2098static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol, 2608static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
2099 struct snd_ctl_elem_value *ucontrol) 2609 struct snd_ctl_elem_value *ucontrol)
2100{ 2610{
2101 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2611 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -2104,98 +2614,150 @@ static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
2104 2614
2105 if (spec->codec_type != VT1708) 2615 if (spec->codec_type != VT1708)
2106 return 0; 2616 return 0;
2107 spec->vt1708_jack_detectect = ucontrol->value.integer.value[0]; 2617 spec->vt1708_jack_detect = ucontrol->value.integer.value[0];
2108 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8)) 2618 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
2109 == !spec->vt1708_jack_detectect; 2619 == !spec->vt1708_jack_detect;
2110 if (spec->vt1708_jack_detectect) { 2620 if (spec->vt1708_jack_detect) {
2111 mute_aa_path(codec, 1); 2621 mute_aa_path(codec, 1);
2112 notify_aa_path_ctls(codec); 2622 notify_aa_path_ctls(codec);
2113 } 2623 }
2114 return change; 2624 return change;
2115} 2625}
2116 2626
2117static const struct snd_kcontrol_new vt1708_jack_detectect[] = { 2627static const struct snd_kcontrol_new vt1708_jack_detect_ctl = {
2118 { 2628 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2119 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2629 .name = "Jack Detect",
2120 .name = "Jack Detect", 2630 .count = 1,
2121 .count = 1, 2631 .info = snd_ctl_boolean_mono_info,
2122 .info = snd_ctl_boolean_mono_info, 2632 .get = vt1708_jack_detect_get,
2123 .get = vt1708_jack_detectect_get, 2633 .put = vt1708_jack_detect_put,
2124 .put = vt1708_jack_detectect_put,
2125 },
2126 {} /* end */
2127}; 2634};
2128 2635
2129static int vt1708_parse_auto_config(struct hda_codec *codec) 2636static void fill_dig_outs(struct hda_codec *codec);
2637static void fill_dig_in(struct hda_codec *codec);
2638
2639static int via_parse_auto_config(struct hda_codec *codec)
2130{ 2640{
2131 struct via_spec *spec = codec->spec; 2641 struct via_spec *spec = codec->spec;
2132 int err; 2642 int err;
2133 2643
2134 /* Add HP and CD pin config connect bit re-config action */
2135 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2136 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2137
2138 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 2644 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2139 if (err < 0) 2645 if (err < 0)
2140 return err; 2646 return err;
2141 err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
2142 if (err < 0)
2143 return err;
2144 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 2647 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2145 return 0; /* can't find valid BIOS pin config */ 2648 return -EINVAL;
2146 2649
2147 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg); 2650 err = via_auto_create_multi_out_ctls(codec);
2148 if (err < 0) 2651 if (err < 0)
2149 return err; 2652 return err;
2150 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 2653 err = via_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
2151 if (err < 0) 2654 if (err < 0)
2152 return err; 2655 return err;
2153 err = vt1708_auto_create_analog_input_ctls(codec, &spec->autocfg); 2656 err = via_auto_create_speaker_ctls(codec);
2154 if (err < 0) 2657 if (err < 0)
2155 return err; 2658 return err;
2156 /* add jack detect on/off control */ 2659 err = via_auto_create_loopback_switch(codec);
2157 err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect); 2660 if (err < 0)
2661 return err;
2662 err = via_auto_create_analog_input_ctls(codec);
2158 if (err < 0) 2663 if (err < 0)
2159 return err; 2664 return err;
2160 2665
2161 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 2666 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2162 2667
2163 if (spec->autocfg.dig_outs) 2668 fill_dig_outs(codec);
2164 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID; 2669 fill_dig_in(codec);
2165 spec->dig_in_pin = VT1708_DIGIN_PIN;
2166 if (spec->autocfg.dig_in_pin)
2167 spec->dig_in_nid = VT1708_DIGIN_NID;
2168 2670
2169 if (spec->kctls.list) 2671 if (spec->kctls.list)
2170 spec->mixers[spec->num_mixers++] = spec->kctls.list; 2672 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2171 2673
2172 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
2173 2674
2174 spec->input_mux = &spec->private_imux[0]; 2675 if (spec->hp_dac_nid && spec->hp_mix_path.depth) {
2676 err = via_hp_build(codec);
2677 if (err < 0)
2678 return err;
2679 }
2175 2680
2176 if (spec->hp_mux) 2681 err = via_smart51_build(codec);
2177 via_hp_build(codec); 2682 if (err < 0)
2683 return err;
2684
2685 /* assign slave outs */
2686 if (spec->slave_dig_outs[0])
2687 codec->slave_dig_outs = spec->slave_dig_outs;
2178 2688
2179 via_smart51_build(spec);
2180 return 1; 2689 return 1;
2181} 2690}
2182 2691
2183/* init callback for auto-configuration model -- overriding the default init */ 2692static void via_auto_init_dig_outs(struct hda_codec *codec)
2184static int via_auto_init(struct hda_codec *codec)
2185{ 2693{
2186 struct via_spec *spec = codec->spec; 2694 struct via_spec *spec = codec->spec;
2695 if (spec->multiout.dig_out_nid)
2696 init_output_pin(codec, spec->autocfg.dig_out_pins[0], PIN_OUT);
2697 if (spec->slave_dig_outs[0])
2698 init_output_pin(codec, spec->autocfg.dig_out_pins[1], PIN_OUT);
2699}
2700
2701static void via_auto_init_dig_in(struct hda_codec *codec)
2702{
2703 struct via_spec *spec = codec->spec;
2704 if (!spec->dig_in_nid)
2705 return;
2706 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2707 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2708}
2709
2710/* initialize the unsolicited events */
2711static void via_auto_init_unsol_event(struct hda_codec *codec)
2712{
2713 struct via_spec *spec = codec->spec;
2714 struct auto_pin_cfg *cfg = &spec->autocfg;
2715 unsigned int ev;
2716 int i;
2717
2718 if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0]))
2719 snd_hda_codec_write(codec, cfg->hp_pins[0], 0,
2720 AC_VERB_SET_UNSOLICITED_ENABLE,
2721 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT);
2722
2723 if (cfg->speaker_pins[0])
2724 ev = VIA_LINE_EVENT;
2725 else
2726 ev = 0;
2727 for (i = 0; i < cfg->line_outs; i++) {
2728 if (cfg->line_out_pins[i] &&
2729 is_jack_detectable(codec, cfg->line_out_pins[i]))
2730 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
2731 AC_VERB_SET_UNSOLICITED_ENABLE,
2732 AC_USRSP_EN | ev | VIA_JACK_EVENT);
2733 }
2734
2735 for (i = 0; i < cfg->num_inputs; i++) {
2736 if (is_jack_detectable(codec, cfg->inputs[i].pin))
2737 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
2738 AC_VERB_SET_UNSOLICITED_ENABLE,
2739 AC_USRSP_EN | VIA_JACK_EVENT);
2740 }
2741}
2742
2743static int via_init(struct hda_codec *codec)
2744{
2745 struct via_spec *spec = codec->spec;
2746 int i;
2747
2748 for (i = 0; i < spec->num_iverbs; i++)
2749 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2187 2750
2188 via_init(codec);
2189 via_auto_init_multi_out(codec); 2751 via_auto_init_multi_out(codec);
2190 via_auto_init_hp_out(codec); 2752 via_auto_init_hp_out(codec);
2753 via_auto_init_speaker_out(codec);
2191 via_auto_init_analog_input(codec); 2754 via_auto_init_analog_input(codec);
2755 via_auto_init_dig_outs(codec);
2756 via_auto_init_dig_in(codec);
2192 2757
2193 if (VT2002P_COMPATIBLE(spec)) { 2758 via_auto_init_unsol_event(codec);
2194 via_hp_bind_automute(codec); 2759
2195 } else { 2760 via_hp_automute(codec);
2196 via_hp_automute(codec);
2197 via_speaker_automute(codec);
2198 }
2199 2761
2200 return 0; 2762 return 0;
2201} 2763}
@@ -2252,437 +2814,36 @@ static int patch_vt1708(struct hda_codec *codec)
2252 if (spec == NULL) 2814 if (spec == NULL)
2253 return -ENOMEM; 2815 return -ENOMEM;
2254 2816
2817 spec->aa_mix_nid = 0x17;
2818
2819 /* Add HP and CD pin config connect bit re-config action */
2820 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2821 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2822
2255 /* automatic parse from the BIOS config */ 2823 /* automatic parse from the BIOS config */
2256 err = vt1708_parse_auto_config(codec); 2824 err = via_parse_auto_config(codec);
2257 if (err < 0) { 2825 if (err < 0) {
2258 via_free(codec); 2826 via_free(codec);
2259 return err; 2827 return err;
2260 } else if (!err) {
2261 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2262 "from BIOS. Using genenic mode...\n");
2263 } 2828 }
2264 2829
2830 /* add jack detect on/off control */
2831 if (!via_clone_control(spec, &vt1708_jack_detect_ctl))
2832 return -ENOMEM;
2265 2833
2266 spec->stream_name_analog = "VT1708 Analog";
2267 spec->stream_analog_playback = &vt1708_pcm_analog_playback;
2268 /* disable 32bit format on VT1708 */ 2834 /* disable 32bit format on VT1708 */
2269 if (codec->vendor_id == 0x11061708) 2835 if (codec->vendor_id == 0x11061708)
2270 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback; 2836 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
2271 spec->stream_analog_capture = &vt1708_pcm_analog_capture;
2272
2273 spec->stream_name_digital = "VT1708 Digital";
2274 spec->stream_digital_playback = &vt1708_pcm_digital_playback;
2275 spec->stream_digital_capture = &vt1708_pcm_digital_capture;
2276 2837
2277 2838 spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs;
2278 if (!spec->adc_nids && spec->input_mux) {
2279 spec->adc_nids = vt1708_adc_nids;
2280 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
2281 get_mux_nids(codec);
2282 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
2283 spec->num_mixers++;
2284 }
2285 2839
2286 codec->patch_ops = via_patch_ops; 2840 codec->patch_ops = via_patch_ops;
2287 2841
2288 codec->patch_ops.init = via_auto_init;
2289#ifdef CONFIG_SND_HDA_POWER_SAVE
2290 spec->loopback.amplist = vt1708_loopbacks;
2291#endif
2292 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); 2842 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2293 return 0; 2843 return 0;
2294} 2844}
2295 2845
2296/* capture mixer elements */ 2846static int patch_vt1709(struct hda_codec *codec)
2297static const struct snd_kcontrol_new vt1709_capture_mixer[] = {
2298 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
2299 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
2300 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
2301 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
2302 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
2303 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
2304 {
2305 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2306 /* The multiple "Capture Source" controls confuse alsamixer
2307 * So call somewhat different..
2308 */
2309 /* .name = "Capture Source", */
2310 .name = "Input Source",
2311 .count = 1,
2312 .info = via_mux_enum_info,
2313 .get = via_mux_enum_get,
2314 .put = via_mux_enum_put,
2315 },
2316 { } /* end */
2317};
2318
2319static const struct hda_verb vt1709_uniwill_init_verbs[] = {
2320 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2321 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2322 { }
2323};
2324
2325/*
2326 * generic initialization of ADC, input mixers and output mixers
2327 */
2328static const struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2329 /*
2330 * Unmute ADC0-2 and set the default input to mic-in
2331 */
2332 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2333 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2334 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2335
2336
2337 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2338 * mixer widget
2339 */
2340 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2341 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2342 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2343 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2344 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2345 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2346
2347 /*
2348 * Set up output selector (0x1a, 0x1b, 0x29)
2349 */
2350 /* set vol=0 to output mixers */
2351 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2352 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2353 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2354
2355 /*
2356 * Unmute PW3 and PW4
2357 */
2358 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2359 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2360
2361 /* Set input of PW4 as MW0 */
2362 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
2363 /* PW9 Output enable */
2364 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2365 { }
2366};
2367
2368static const struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2369 .substreams = 1,
2370 .channels_min = 2,
2371 .channels_max = 10,
2372 .nid = 0x10, /* NID to query formats and rates */
2373 .ops = {
2374 .open = via_playback_pcm_open,
2375 .prepare = via_playback_multi_pcm_prepare,
2376 .cleanup = via_playback_multi_pcm_cleanup,
2377 },
2378};
2379
2380static const struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2381 .substreams = 1,
2382 .channels_min = 2,
2383 .channels_max = 6,
2384 .nid = 0x10, /* NID to query formats and rates */
2385 .ops = {
2386 .open = via_playback_pcm_open,
2387 .prepare = via_playback_multi_pcm_prepare,
2388 .cleanup = via_playback_multi_pcm_cleanup,
2389 },
2390};
2391
2392static const struct hda_pcm_stream vt1709_pcm_analog_capture = {
2393 .substreams = 2,
2394 .channels_min = 2,
2395 .channels_max = 2,
2396 .nid = 0x14, /* NID to query formats and rates */
2397 .ops = {
2398 .prepare = via_capture_pcm_prepare,
2399 .cleanup = via_capture_pcm_cleanup
2400 },
2401};
2402
2403static const struct hda_pcm_stream vt1709_pcm_digital_playback = {
2404 .substreams = 1,
2405 .channels_min = 2,
2406 .channels_max = 2,
2407 /* NID is set in via_build_pcms */
2408 .ops = {
2409 .open = via_dig_playback_pcm_open,
2410 .close = via_dig_playback_pcm_close
2411 },
2412};
2413
2414static const struct hda_pcm_stream vt1709_pcm_digital_capture = {
2415 .substreams = 1,
2416 .channels_min = 2,
2417 .channels_max = 2,
2418};
2419
2420static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2421 const struct auto_pin_cfg *cfg)
2422{
2423 int i;
2424 hda_nid_t nid;
2425
2426 if (cfg->line_outs == 4) /* 10 channels */
2427 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
2428 else if (cfg->line_outs == 3) /* 6 channels */
2429 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
2430
2431 spec->multiout.dac_nids = spec->private_dac_nids;
2432
2433 if (cfg->line_outs == 4) { /* 10 channels */
2434 for (i = 0; i < cfg->line_outs; i++) {
2435 nid = cfg->line_out_pins[i];
2436 if (nid) {
2437 /* config dac list */
2438 switch (i) {
2439 case AUTO_SEQ_FRONT:
2440 /* AOW0 */
2441 spec->private_dac_nids[i] = 0x10;
2442 break;
2443 case AUTO_SEQ_CENLFE:
2444 /* AOW2 */
2445 spec->private_dac_nids[i] = 0x12;
2446 break;
2447 case AUTO_SEQ_SURROUND:
2448 /* AOW3 */
2449 spec->private_dac_nids[i] = 0x11;
2450 break;
2451 case AUTO_SEQ_SIDE:
2452 /* AOW1 */
2453 spec->private_dac_nids[i] = 0x27;
2454 break;
2455 default:
2456 break;
2457 }
2458 }
2459 }
2460 spec->private_dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
2461
2462 } else if (cfg->line_outs == 3) { /* 6 channels */
2463 for (i = 0; i < cfg->line_outs; i++) {
2464 nid = cfg->line_out_pins[i];
2465 if (nid) {
2466 /* config dac list */
2467 switch (i) {
2468 case AUTO_SEQ_FRONT:
2469 /* AOW0 */
2470 spec->private_dac_nids[i] = 0x10;
2471 break;
2472 case AUTO_SEQ_CENLFE:
2473 /* AOW2 */
2474 spec->private_dac_nids[i] = 0x12;
2475 break;
2476 case AUTO_SEQ_SURROUND:
2477 /* AOW1 */
2478 spec->private_dac_nids[i] = 0x11;
2479 break;
2480 default:
2481 break;
2482 }
2483 }
2484 }
2485 }
2486
2487 return 0;
2488}
2489
2490/* add playback controls from the parsed DAC table */
2491static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
2492 const struct auto_pin_cfg *cfg)
2493{
2494 char name[32];
2495 static const char * const chname[4] = {
2496 "Front", "Surround", "C/LFE", "Side"
2497 };
2498 hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
2499 int i, err;
2500
2501 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2502 nid = cfg->line_out_pins[i];
2503
2504 if (!nid)
2505 continue;
2506
2507 nid_vol = nid_vols[i];
2508
2509 if (i == AUTO_SEQ_CENLFE) {
2510 /* Center/LFE */
2511 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2512 "Center Playback Volume",
2513 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2514 HDA_OUTPUT));
2515 if (err < 0)
2516 return err;
2517 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2518 "LFE Playback Volume",
2519 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2520 HDA_OUTPUT));
2521 if (err < 0)
2522 return err;
2523 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2524 "Center Playback Switch",
2525 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2526 HDA_OUTPUT));
2527 if (err < 0)
2528 return err;
2529 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2530 "LFE Playback Switch",
2531 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2532 HDA_OUTPUT));
2533 if (err < 0)
2534 return err;
2535 } else if (i == AUTO_SEQ_FRONT) {
2536 /* ADD control to mixer index 0 */
2537 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2538 "Master Front Playback Volume",
2539 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2540 HDA_INPUT));
2541 if (err < 0)
2542 return err;
2543 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2544 "Master Front Playback Switch",
2545 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2546 HDA_INPUT));
2547 if (err < 0)
2548 return err;
2549
2550 /* add control to PW3 */
2551 sprintf(name, "%s Playback Volume", chname[i]);
2552 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2553 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2554 HDA_OUTPUT));
2555 if (err < 0)
2556 return err;
2557 sprintf(name, "%s Playback Switch", chname[i]);
2558 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2559 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2560 HDA_OUTPUT));
2561 if (err < 0)
2562 return err;
2563 } else if (i == AUTO_SEQ_SURROUND) {
2564 sprintf(name, "%s Playback Volume", chname[i]);
2565 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2566 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2567 HDA_OUTPUT));
2568 if (err < 0)
2569 return err;
2570 sprintf(name, "%s Playback Switch", chname[i]);
2571 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2572 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2573 HDA_OUTPUT));
2574 if (err < 0)
2575 return err;
2576 } else if (i == AUTO_SEQ_SIDE) {
2577 sprintf(name, "%s Playback Volume", chname[i]);
2578 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2579 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2580 HDA_OUTPUT));
2581 if (err < 0)
2582 return err;
2583 sprintf(name, "%s Playback Switch", chname[i]);
2584 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2585 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2586 HDA_OUTPUT));
2587 if (err < 0)
2588 return err;
2589 }
2590 }
2591
2592 return 0;
2593}
2594
2595static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2596{
2597 int err;
2598
2599 if (!pin)
2600 return 0;
2601
2602 if (spec->multiout.num_dacs == 5) /* 10 channels */
2603 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
2604 else if (spec->multiout.num_dacs == 3) /* 6 channels */
2605 spec->multiout.hp_nid = 0;
2606 spec->hp_independent_mode_index = 1;
2607
2608 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2609 "Headphone Playback Volume",
2610 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2611 if (err < 0)
2612 return err;
2613 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2614 "Headphone Playback Switch",
2615 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2616 if (err < 0)
2617 return err;
2618
2619 return 0;
2620}
2621
2622/* create playback/capture controls for input pins */
2623static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec,
2624 const struct auto_pin_cfg *cfg)
2625{
2626 static const hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
2627 return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs,
2628 ARRAY_SIZE(pin_idxs));
2629}
2630
2631static int vt1709_parse_auto_config(struct hda_codec *codec)
2632{
2633 struct via_spec *spec = codec->spec;
2634 int err;
2635
2636 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2637 if (err < 0)
2638 return err;
2639 err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
2640 if (err < 0)
2641 return err;
2642 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2643 return 0; /* can't find valid BIOS pin config */
2644
2645 err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
2646 if (err < 0)
2647 return err;
2648 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2649 if (err < 0)
2650 return err;
2651 err = vt1709_auto_create_analog_input_ctls(codec, &spec->autocfg);
2652 if (err < 0)
2653 return err;
2654
2655 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2656
2657 if (spec->autocfg.dig_outs)
2658 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
2659 spec->dig_in_pin = VT1709_DIGIN_PIN;
2660 if (spec->autocfg.dig_in_pin)
2661 spec->dig_in_nid = VT1709_DIGIN_NID;
2662
2663 if (spec->kctls.list)
2664 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2665
2666 spec->input_mux = &spec->private_imux[0];
2667
2668 if (spec->hp_mux)
2669 via_hp_build(codec);
2670
2671 via_smart51_build(spec);
2672 return 1;
2673}
2674
2675#ifdef CONFIG_SND_HDA_POWER_SAVE
2676static const struct hda_amp_list vt1709_loopbacks[] = {
2677 { 0x18, HDA_INPUT, 1 },
2678 { 0x18, HDA_INPUT, 2 },
2679 { 0x18, HDA_INPUT, 3 },
2680 { 0x18, HDA_INPUT, 4 },
2681 { } /* end */
2682};
2683#endif
2684
2685static int patch_vt1709_10ch(struct hda_codec *codec)
2686{ 2847{
2687 struct via_spec *spec; 2848 struct via_spec *spec;
2688 int err; 2849 int err;
@@ -2692,528 +2853,19 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
2692 if (spec == NULL) 2853 if (spec == NULL)
2693 return -ENOMEM; 2854 return -ENOMEM;
2694 2855
2695 err = vt1709_parse_auto_config(codec); 2856 spec->aa_mix_nid = 0x18;
2696 if (err < 0) {
2697 via_free(codec);
2698 return err;
2699 } else if (!err) {
2700 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
2701 "Using genenic mode...\n");
2702 }
2703
2704 spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
2705 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
2706
2707 spec->stream_name_analog = "VT1709 Analog";
2708 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
2709 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
2710
2711 spec->stream_name_digital = "VT1709 Digital";
2712 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
2713 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
2714
2715
2716 if (!spec->adc_nids && spec->input_mux) {
2717 spec->adc_nids = vt1709_adc_nids;
2718 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
2719 get_mux_nids(codec);
2720 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
2721 spec->num_mixers++;
2722 }
2723
2724 codec->patch_ops = via_patch_ops;
2725
2726 codec->patch_ops.init = via_auto_init;
2727 codec->patch_ops.unsol_event = via_unsol_event;
2728#ifdef CONFIG_SND_HDA_POWER_SAVE
2729 spec->loopback.amplist = vt1709_loopbacks;
2730#endif
2731
2732 return 0;
2733}
2734/*
2735 * generic initialization of ADC, input mixers and output mixers
2736 */
2737static const struct hda_verb vt1709_6ch_volume_init_verbs[] = {
2738 /*
2739 * Unmute ADC0-2 and set the default input to mic-in
2740 */
2741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2743 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2744
2745
2746 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2747 * mixer widget
2748 */
2749 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2750 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2751 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2752 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2753 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2754 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2755
2756 /*
2757 * Set up output selector (0x1a, 0x1b, 0x29)
2758 */
2759 /* set vol=0 to output mixers */
2760 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2761 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2762 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2763
2764 /*
2765 * Unmute PW3 and PW4
2766 */
2767 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2768 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2769
2770 /* Set input of PW4 as MW0 */
2771 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
2772 /* PW9 Output enable */
2773 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2774 { }
2775};
2776
2777static int patch_vt1709_6ch(struct hda_codec *codec)
2778{
2779 struct via_spec *spec;
2780 int err;
2781
2782 /* create a codec specific record */
2783 spec = via_new_spec(codec);
2784 if (spec == NULL)
2785 return -ENOMEM;
2786 2857
2787 err = vt1709_parse_auto_config(codec); 2858 err = via_parse_auto_config(codec);
2788 if (err < 0) { 2859 if (err < 0) {
2789 via_free(codec); 2860 via_free(codec);
2790 return err; 2861 return err;
2791 } else if (!err) {
2792 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
2793 "Using genenic mode...\n");
2794 }
2795
2796 spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
2797 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
2798
2799 spec->stream_name_analog = "VT1709 Analog";
2800 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
2801 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
2802
2803 spec->stream_name_digital = "VT1709 Digital";
2804 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
2805 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
2806
2807
2808 if (!spec->adc_nids && spec->input_mux) {
2809 spec->adc_nids = vt1709_adc_nids;
2810 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
2811 get_mux_nids(codec);
2812 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
2813 spec->num_mixers++;
2814 } 2862 }
2815 2863
2816 codec->patch_ops = via_patch_ops; 2864 codec->patch_ops = via_patch_ops;
2817 2865
2818 codec->patch_ops.init = via_auto_init;
2819 codec->patch_ops.unsol_event = via_unsol_event;
2820#ifdef CONFIG_SND_HDA_POWER_SAVE
2821 spec->loopback.amplist = vt1709_loopbacks;
2822#endif
2823 return 0;
2824}
2825
2826/* capture mixer elements */
2827static const struct snd_kcontrol_new vt1708B_capture_mixer[] = {
2828 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
2829 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
2830 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
2831 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
2832 {
2833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2834 /* The multiple "Capture Source" controls confuse alsamixer
2835 * So call somewhat different..
2836 */
2837 /* .name = "Capture Source", */
2838 .name = "Input Source",
2839 .count = 1,
2840 .info = via_mux_enum_info,
2841 .get = via_mux_enum_get,
2842 .put = via_mux_enum_put,
2843 },
2844 { } /* end */
2845};
2846/*
2847 * generic initialization of ADC, input mixers and output mixers
2848 */
2849static const struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
2850 /*
2851 * Unmute ADC0-1 and set the default input to mic-in
2852 */
2853 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2854 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2855
2856
2857 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2858 * mixer widget
2859 */
2860 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2861 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2862 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2863 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2864 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2865 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2866
2867 /*
2868 * Set up output mixers
2869 */
2870 /* set vol=0 to output mixers */
2871 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2872 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2873 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2874
2875 /* Setup default input to PW4 */
2876 {0x1d, AC_VERB_SET_CONNECT_SEL, 0},
2877 /* PW9 Output enable */
2878 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2879 /* PW10 Input enable */
2880 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2881 { }
2882};
2883
2884static const struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
2885 /*
2886 * Unmute ADC0-1 and set the default input to mic-in
2887 */
2888 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2889 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2890
2891
2892 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2893 * mixer widget
2894 */
2895 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2896 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2897 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2898 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2899 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2901
2902 /*
2903 * Set up output mixers
2904 */
2905 /* set vol=0 to output mixers */
2906 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2907 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2908 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2909
2910 /* Setup default input of PW4 to MW0 */
2911 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
2912 /* PW9 Output enable */
2913 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2914 /* PW10 Input enable */
2915 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2916 { }
2917};
2918
2919static const struct hda_verb vt1708B_uniwill_init_verbs[] = {
2920 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
2921 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2922 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2923 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2924 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2925 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2926 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2927 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2928 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2929 { }
2930};
2931
2932static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
2933 struct hda_codec *codec,
2934 struct snd_pcm_substream *substream)
2935{
2936 int idle = substream->pstr->substream_opened == 1
2937 && substream->ref_count == 0;
2938
2939 analog_low_current_mode(codec, idle);
2940 return 0;
2941}
2942
2943static const struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
2944 .substreams = 2,
2945 .channels_min = 2,
2946 .channels_max = 8,
2947 .nid = 0x10, /* NID to query formats and rates */
2948 .ops = {
2949 .open = via_playback_pcm_open,
2950 .prepare = via_playback_multi_pcm_prepare,
2951 .cleanup = via_playback_multi_pcm_cleanup,
2952 .close = via_pcm_open_close
2953 },
2954};
2955
2956static const struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
2957 .substreams = 2,
2958 .channels_min = 2,
2959 .channels_max = 4,
2960 .nid = 0x10, /* NID to query formats and rates */
2961 .ops = {
2962 .open = via_playback_pcm_open,
2963 .prepare = via_playback_multi_pcm_prepare,
2964 .cleanup = via_playback_multi_pcm_cleanup
2965 },
2966};
2967
2968static const struct hda_pcm_stream vt1708B_pcm_analog_capture = {
2969 .substreams = 2,
2970 .channels_min = 2,
2971 .channels_max = 2,
2972 .nid = 0x13, /* NID to query formats and rates */
2973 .ops = {
2974 .open = via_pcm_open_close,
2975 .prepare = via_capture_pcm_prepare,
2976 .cleanup = via_capture_pcm_cleanup,
2977 .close = via_pcm_open_close
2978 },
2979};
2980
2981static const struct hda_pcm_stream vt1708B_pcm_digital_playback = {
2982 .substreams = 1,
2983 .channels_min = 2,
2984 .channels_max = 2,
2985 /* NID is set in via_build_pcms */
2986 .ops = {
2987 .open = via_dig_playback_pcm_open,
2988 .close = via_dig_playback_pcm_close,
2989 .prepare = via_dig_playback_pcm_prepare,
2990 .cleanup = via_dig_playback_pcm_cleanup
2991 },
2992};
2993
2994static const struct hda_pcm_stream vt1708B_pcm_digital_capture = {
2995 .substreams = 1,
2996 .channels_min = 2,
2997 .channels_max = 2,
2998};
2999
3000/* fill in the dac_nids table from the parsed pin configuration */
3001static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
3002 const struct auto_pin_cfg *cfg)
3003{
3004 int i;
3005 hda_nid_t nid;
3006
3007 spec->multiout.num_dacs = cfg->line_outs;
3008
3009 spec->multiout.dac_nids = spec->private_dac_nids;
3010
3011 for (i = 0; i < 4; i++) {
3012 nid = cfg->line_out_pins[i];
3013 if (nid) {
3014 /* config dac list */
3015 switch (i) {
3016 case AUTO_SEQ_FRONT:
3017 spec->private_dac_nids[i] = 0x10;
3018 break;
3019 case AUTO_SEQ_CENLFE:
3020 spec->private_dac_nids[i] = 0x24;
3021 break;
3022 case AUTO_SEQ_SURROUND:
3023 spec->private_dac_nids[i] = 0x11;
3024 break;
3025 case AUTO_SEQ_SIDE:
3026 spec->private_dac_nids[i] = 0x25;
3027 break;
3028 }
3029 }
3030 }
3031
3032 return 0;
3033}
3034
3035/* add playback controls from the parsed DAC table */
3036static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
3037 const struct auto_pin_cfg *cfg)
3038{
3039 char name[32];
3040 static const char * const chname[4] = {
3041 "Front", "Surround", "C/LFE", "Side"
3042 };
3043 hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
3044 hda_nid_t nid, nid_vol = 0;
3045 int i, err;
3046
3047 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3048 nid = cfg->line_out_pins[i];
3049
3050 if (!nid)
3051 continue;
3052
3053 nid_vol = nid_vols[i];
3054
3055 if (i == AUTO_SEQ_CENLFE) {
3056 /* Center/LFE */
3057 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3058 "Center Playback Volume",
3059 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3060 HDA_OUTPUT));
3061 if (err < 0)
3062 return err;
3063 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3064 "LFE Playback Volume",
3065 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3066 HDA_OUTPUT));
3067 if (err < 0)
3068 return err;
3069 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3070 "Center Playback Switch",
3071 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3072 HDA_OUTPUT));
3073 if (err < 0)
3074 return err;
3075 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3076 "LFE Playback Switch",
3077 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3078 HDA_OUTPUT));
3079 if (err < 0)
3080 return err;
3081 } else if (i == AUTO_SEQ_FRONT) {
3082 /* add control to mixer index 0 */
3083 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3084 "Master Front Playback Volume",
3085 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3086 HDA_INPUT));
3087 if (err < 0)
3088 return err;
3089 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3090 "Master Front Playback Switch",
3091 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3092 HDA_INPUT));
3093 if (err < 0)
3094 return err;
3095
3096 /* add control to PW3 */
3097 sprintf(name, "%s Playback Volume", chname[i]);
3098 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3099 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3100 HDA_OUTPUT));
3101 if (err < 0)
3102 return err;
3103 sprintf(name, "%s Playback Switch", chname[i]);
3104 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3105 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3106 HDA_OUTPUT));
3107 if (err < 0)
3108 return err;
3109 } else {
3110 sprintf(name, "%s Playback Volume", chname[i]);
3111 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3112 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3113 HDA_OUTPUT));
3114 if (err < 0)
3115 return err;
3116 sprintf(name, "%s Playback Switch", chname[i]);
3117 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3118 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3119 HDA_OUTPUT));
3120 if (err < 0)
3121 return err;
3122 }
3123 }
3124
3125 return 0;
3126}
3127
3128static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3129{
3130 int err;
3131
3132 if (!pin)
3133 return 0;
3134
3135 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
3136 spec->hp_independent_mode_index = 1;
3137
3138 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3139 "Headphone Playback Volume",
3140 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3141 if (err < 0)
3142 return err;
3143 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3144 "Headphone Playback Switch",
3145 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3146 if (err < 0)
3147 return err;
3148
3149 create_hp_imux(spec);
3150
3151 return 0; 2866 return 0;
3152} 2867}
3153 2868
3154/* create playback/capture controls for input pins */
3155static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec,
3156 const struct auto_pin_cfg *cfg)
3157{
3158 static const hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
3159 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
3160 ARRAY_SIZE(pin_idxs));
3161}
3162
3163static int vt1708B_parse_auto_config(struct hda_codec *codec)
3164{
3165 struct via_spec *spec = codec->spec;
3166 int err;
3167
3168 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3169 if (err < 0)
3170 return err;
3171 err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
3172 if (err < 0)
3173 return err;
3174 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3175 return 0; /* can't find valid BIOS pin config */
3176
3177 err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
3178 if (err < 0)
3179 return err;
3180 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3181 if (err < 0)
3182 return err;
3183 err = vt1708B_auto_create_analog_input_ctls(codec, &spec->autocfg);
3184 if (err < 0)
3185 return err;
3186
3187 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3188
3189 if (spec->autocfg.dig_outs)
3190 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
3191 spec->dig_in_pin = VT1708B_DIGIN_PIN;
3192 if (spec->autocfg.dig_in_pin)
3193 spec->dig_in_nid = VT1708B_DIGIN_NID;
3194
3195 if (spec->kctls.list)
3196 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3197
3198 spec->input_mux = &spec->private_imux[0];
3199
3200 if (spec->hp_mux)
3201 via_hp_build(codec);
3202
3203 via_smart51_build(spec);
3204 return 1;
3205}
3206
3207#ifdef CONFIG_SND_HDA_POWER_SAVE
3208static const struct hda_amp_list vt1708B_loopbacks[] = {
3209 { 0x16, HDA_INPUT, 1 },
3210 { 0x16, HDA_INPUT, 2 },
3211 { 0x16, HDA_INPUT, 3 },
3212 { 0x16, HDA_INPUT, 4 },
3213 { } /* end */
3214};
3215#endif
3216
3217static void set_widgets_power_state_vt1708B(struct hda_codec *codec) 2869static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3218{ 2870{
3219 struct via_spec *spec = codec->spec; 2871 struct via_spec *spec = codec->spec;
@@ -3295,157 +2947,37 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3295} 2947}
3296 2948
3297static int patch_vt1708S(struct hda_codec *codec); 2949static int patch_vt1708S(struct hda_codec *codec);
3298static int patch_vt1708B_8ch(struct hda_codec *codec) 2950static int patch_vt1708B(struct hda_codec *codec)
3299{ 2951{
3300 struct via_spec *spec; 2952 struct via_spec *spec;
3301 int err; 2953 int err;
3302 2954
3303 if (get_codec_type(codec) == VT1708BCE) 2955 if (get_codec_type(codec) == VT1708BCE)
3304 return patch_vt1708S(codec); 2956 return patch_vt1708S(codec);
3305 /* create a codec specific record */
3306 spec = via_new_spec(codec);
3307 if (spec == NULL)
3308 return -ENOMEM;
3309
3310 /* automatic parse from the BIOS config */
3311 err = vt1708B_parse_auto_config(codec);
3312 if (err < 0) {
3313 via_free(codec);
3314 return err;
3315 } else if (!err) {
3316 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3317 "from BIOS. Using genenic mode...\n");
3318 }
3319
3320 spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
3321 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3322
3323 spec->stream_name_analog = "VT1708B Analog";
3324 spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
3325 spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3326
3327 spec->stream_name_digital = "VT1708B Digital";
3328 spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3329 spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3330
3331 if (!spec->adc_nids && spec->input_mux) {
3332 spec->adc_nids = vt1708B_adc_nids;
3333 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3334 get_mux_nids(codec);
3335 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3336 spec->num_mixers++;
3337 }
3338
3339 codec->patch_ops = via_patch_ops;
3340
3341 codec->patch_ops.init = via_auto_init;
3342 codec->patch_ops.unsol_event = via_unsol_event;
3343#ifdef CONFIG_SND_HDA_POWER_SAVE
3344 spec->loopback.amplist = vt1708B_loopbacks;
3345#endif
3346
3347 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3348
3349 return 0;
3350}
3351
3352static int patch_vt1708B_4ch(struct hda_codec *codec)
3353{
3354 struct via_spec *spec;
3355 int err;
3356 2957
3357 /* create a codec specific record */ 2958 /* create a codec specific record */
3358 spec = via_new_spec(codec); 2959 spec = via_new_spec(codec);
3359 if (spec == NULL) 2960 if (spec == NULL)
3360 return -ENOMEM; 2961 return -ENOMEM;
3361 2962
2963 spec->aa_mix_nid = 0x16;
2964
3362 /* automatic parse from the BIOS config */ 2965 /* automatic parse from the BIOS config */
3363 err = vt1708B_parse_auto_config(codec); 2966 err = via_parse_auto_config(codec);
3364 if (err < 0) { 2967 if (err < 0) {
3365 via_free(codec); 2968 via_free(codec);
3366 return err; 2969 return err;
3367 } else if (!err) {
3368 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3369 "from BIOS. Using genenic mode...\n");
3370 }
3371
3372 spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
3373 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3374
3375 spec->stream_name_analog = "VT1708B Analog";
3376 spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
3377 spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3378
3379 spec->stream_name_digital = "VT1708B Digital";
3380 spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3381 spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3382
3383 if (!spec->adc_nids && spec->input_mux) {
3384 spec->adc_nids = vt1708B_adc_nids;
3385 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3386 get_mux_nids(codec);
3387 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3388 spec->num_mixers++;
3389 } 2970 }
3390 2971
3391 codec->patch_ops = via_patch_ops; 2972 codec->patch_ops = via_patch_ops;
3392 2973
3393 codec->patch_ops.init = via_auto_init;
3394 codec->patch_ops.unsol_event = via_unsol_event;
3395#ifdef CONFIG_SND_HDA_POWER_SAVE
3396 spec->loopback.amplist = vt1708B_loopbacks;
3397#endif
3398
3399 spec->set_widgets_power_state = set_widgets_power_state_vt1708B; 2974 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3400 2975
3401 return 0; 2976 return 0;
3402} 2977}
3403 2978
3404/* Patch for VT1708S */ 2979/* Patch for VT1708S */
3405 2980static const struct hda_verb vt1708S_init_verbs[] = {
3406/* capture mixer elements */
3407static const struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3408 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3409 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3410 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3411 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3412 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
3413 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
3414 HDA_INPUT),
3415 {
3416 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3417 /* The multiple "Capture Source" controls confuse alsamixer
3418 * So call somewhat different..
3419 */
3420 /* .name = "Capture Source", */
3421 .name = "Input Source",
3422 .count = 1,
3423 .info = via_mux_enum_info,
3424 .get = via_mux_enum_get,
3425 .put = via_mux_enum_put,
3426 },
3427 { } /* end */
3428};
3429
3430static const struct hda_verb vt1708S_volume_init_verbs[] = {
3431 /* Unmute ADC0-1 and set the default input to mic-in */
3432 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3433 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3434
3435 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
3436 * analog-loopback mixer widget */
3437 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3438 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3439 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3440 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3441 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3442 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3443
3444 /* Setup default input of PW4 to MW0 */
3445 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3446 /* PW9, PW10 Output enable */
3447 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3448 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3449 /* Enable Mic Boost Volume backdoor */ 2981 /* Enable Mic Boost Volume backdoor */
3450 {0x1, 0xf98, 0x1}, 2982 {0x1, 0xf98, 0x1},
3451 /* don't bybass mixer */ 2983 /* don't bybass mixer */
@@ -3453,277 +2985,6 @@ static const struct hda_verb vt1708S_volume_init_verbs[] = {
3453 { } 2985 { }
3454}; 2986};
3455 2987
3456static const struct hda_verb vt1708S_uniwill_init_verbs[] = {
3457 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3458 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3459 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3460 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3461 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3462 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3463 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3464 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3465 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3466 { }
3467};
3468
3469static const struct hda_verb vt1705_uniwill_init_verbs[] = {
3470 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3471 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3472 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3473 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3474 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3475 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3476 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3477 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3478 { }
3479};
3480
3481static const struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3482 .substreams = 2,
3483 .channels_min = 2,
3484 .channels_max = 8,
3485 .nid = 0x10, /* NID to query formats and rates */
3486 .ops = {
3487 .open = via_playback_pcm_open,
3488 .prepare = via_playback_multi_pcm_prepare,
3489 .cleanup = via_playback_multi_pcm_cleanup,
3490 .close = via_pcm_open_close
3491 },
3492};
3493
3494static const struct hda_pcm_stream vt1705_pcm_analog_playback = {
3495 .substreams = 2,
3496 .channels_min = 2,
3497 .channels_max = 6,
3498 .nid = 0x10, /* NID to query formats and rates */
3499 .ops = {
3500 .open = via_playback_pcm_open,
3501 .prepare = via_playback_multi_pcm_prepare,
3502 .cleanup = via_playback_multi_pcm_cleanup,
3503 .close = via_pcm_open_close
3504 },
3505};
3506
3507static const struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3508 .substreams = 2,
3509 .channels_min = 2,
3510 .channels_max = 2,
3511 .nid = 0x13, /* NID to query formats and rates */
3512 .ops = {
3513 .open = via_pcm_open_close,
3514 .prepare = via_capture_pcm_prepare,
3515 .cleanup = via_capture_pcm_cleanup,
3516 .close = via_pcm_open_close
3517 },
3518};
3519
3520static const struct hda_pcm_stream vt1708S_pcm_digital_playback = {
3521 .substreams = 1,
3522 .channels_min = 2,
3523 .channels_max = 2,
3524 /* NID is set in via_build_pcms */
3525 .ops = {
3526 .open = via_dig_playback_pcm_open,
3527 .close = via_dig_playback_pcm_close,
3528 .prepare = via_dig_playback_pcm_prepare,
3529 .cleanup = via_dig_playback_pcm_cleanup
3530 },
3531};
3532
3533/* fill in the dac_nids table from the parsed pin configuration */
3534static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3535 const struct auto_pin_cfg *cfg)
3536{
3537 int i;
3538 hda_nid_t nid;
3539
3540 spec->multiout.num_dacs = cfg->line_outs;
3541
3542 spec->multiout.dac_nids = spec->private_dac_nids;
3543
3544 for (i = 0; i < 4; i++) {
3545 nid = cfg->line_out_pins[i];
3546 if (nid) {
3547 /* config dac list */
3548 switch (i) {
3549 case AUTO_SEQ_FRONT:
3550 spec->private_dac_nids[i] = 0x10;
3551 break;
3552 case AUTO_SEQ_CENLFE:
3553 if (spec->codec->vendor_id == 0x11064397)
3554 spec->private_dac_nids[i] = 0x25;
3555 else
3556 spec->private_dac_nids[i] = 0x24;
3557 break;
3558 case AUTO_SEQ_SURROUND:
3559 spec->private_dac_nids[i] = 0x11;
3560 break;
3561 case AUTO_SEQ_SIDE:
3562 spec->private_dac_nids[i] = 0x25;
3563 break;
3564 }
3565 }
3566 }
3567
3568 /* for Smart 5.1, line/mic inputs double as output pins */
3569 if (cfg->line_outs == 1) {
3570 spec->multiout.num_dacs = 3;
3571 spec->private_dac_nids[AUTO_SEQ_SURROUND] = 0x11;
3572 if (spec->codec->vendor_id == 0x11064397)
3573 spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x25;
3574 else
3575 spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x24;
3576 }
3577
3578 return 0;
3579}
3580
3581/* add playback controls from the parsed DAC table */
3582static int vt1708S_auto_create_multi_out_ctls(struct hda_codec *codec,
3583 const struct auto_pin_cfg *cfg)
3584{
3585 struct via_spec *spec = codec->spec;
3586 char name[32];
3587 static const char * const chname[4] = {
3588 "Front", "Surround", "C/LFE", "Side"
3589 };
3590 hda_nid_t nid_vols[2][4] = { {0x10, 0x11, 0x24, 0x25},
3591 {0x10, 0x11, 0x25, 0} };
3592 hda_nid_t nid_mutes[2][4] = { {0x1C, 0x18, 0x26, 0x27},
3593 {0x1C, 0x18, 0x27, 0} };
3594 hda_nid_t nid, nid_vol, nid_mute;
3595 int i, err;
3596
3597 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3598 nid = cfg->line_out_pins[i];
3599
3600 /* for Smart 5.1, there are always at least six channels */
3601 if (!nid && i > AUTO_SEQ_CENLFE)
3602 continue;
3603
3604 if (codec->vendor_id == 0x11064397) {
3605 nid_vol = nid_vols[1][i];
3606 nid_mute = nid_mutes[1][i];
3607 } else {
3608 nid_vol = nid_vols[0][i];
3609 nid_mute = nid_mutes[0][i];
3610 }
3611 if (!nid_vol && !nid_mute)
3612 continue;
3613
3614 if (i == AUTO_SEQ_CENLFE) {
3615 /* Center/LFE */
3616 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3617 "Center Playback Volume",
3618 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3619 HDA_OUTPUT));
3620 if (err < 0)
3621 return err;
3622 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3623 "LFE Playback Volume",
3624 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3625 HDA_OUTPUT));
3626 if (err < 0)
3627 return err;
3628 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3629 "Center Playback Switch",
3630 HDA_COMPOSE_AMP_VAL(nid_mute,
3631 1, 0,
3632 HDA_OUTPUT));
3633 if (err < 0)
3634 return err;
3635 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3636 "LFE Playback Switch",
3637 HDA_COMPOSE_AMP_VAL(nid_mute,
3638 2, 0,
3639 HDA_OUTPUT));
3640 if (err < 0)
3641 return err;
3642 } else if (i == AUTO_SEQ_FRONT) {
3643 /* add control to mixer index 0 */
3644 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3645 "Master Front Playback Volume",
3646 HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3647 HDA_INPUT));
3648 if (err < 0)
3649 return err;
3650 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3651 "Master Front Playback Switch",
3652 HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3653 HDA_INPUT));
3654 if (err < 0)
3655 return err;
3656
3657 /* Front */
3658 sprintf(name, "%s Playback Volume", chname[i]);
3659 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3660 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3661 HDA_OUTPUT));
3662 if (err < 0)
3663 return err;
3664 sprintf(name, "%s Playback Switch", chname[i]);
3665 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3666 HDA_COMPOSE_AMP_VAL(nid_mute,
3667 3, 0,
3668 HDA_OUTPUT));
3669 if (err < 0)
3670 return err;
3671 } else {
3672 sprintf(name, "%s Playback Volume", chname[i]);
3673 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3674 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3675 HDA_OUTPUT));
3676 if (err < 0)
3677 return err;
3678 sprintf(name, "%s Playback Switch", chname[i]);
3679 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3680 HDA_COMPOSE_AMP_VAL(nid_mute,
3681 3, 0,
3682 HDA_OUTPUT));
3683 if (err < 0)
3684 return err;
3685 }
3686 }
3687
3688 return 0;
3689}
3690
3691static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3692{
3693 int err;
3694
3695 if (!pin)
3696 return 0;
3697
3698 spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
3699 spec->hp_independent_mode_index = 1;
3700
3701 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3702 "Headphone Playback Volume",
3703 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
3704 if (err < 0)
3705 return err;
3706
3707 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3708 "Headphone Playback Switch",
3709 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3710 if (err < 0)
3711 return err;
3712
3713 create_hp_imux(spec);
3714
3715 return 0;
3716}
3717
3718/* create playback/capture controls for input pins */
3719static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec,
3720 const struct auto_pin_cfg *cfg)
3721{
3722 static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
3723 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
3724 ARRAY_SIZE(pin_idxs));
3725}
3726
3727/* fill out digital output widgets; one for master and one for slave outputs */ 2988/* fill out digital output widgets; one for master and one for slave outputs */
3728static void fill_dig_outs(struct hda_codec *codec) 2989static void fill_dig_outs(struct hda_codec *codec)
3729{ 2990{
@@ -3749,56 +3010,33 @@ static void fill_dig_outs(struct hda_codec *codec)
3749 } 3010 }
3750} 3011}
3751 3012
3752static int vt1708S_parse_auto_config(struct hda_codec *codec) 3013static void fill_dig_in(struct hda_codec *codec)
3753{ 3014{
3754 struct via_spec *spec = codec->spec; 3015 struct via_spec *spec = codec->spec;
3755 int err; 3016 hda_nid_t dig_nid;
3756 3017 int i, err;
3757 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3758 if (err < 0)
3759 return err;
3760 err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
3761 if (err < 0)
3762 return err;
3763 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3764 return 0; /* can't find valid BIOS pin config */
3765
3766 err = vt1708S_auto_create_multi_out_ctls(codec, &spec->autocfg);
3767 if (err < 0)
3768 return err;
3769 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3770 if (err < 0)
3771 return err;
3772 err = vt1708S_auto_create_analog_input_ctls(codec, &spec->autocfg);
3773 if (err < 0)
3774 return err;
3775
3776 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3777
3778 fill_dig_outs(codec);
3779
3780 if (spec->kctls.list)
3781 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3782
3783 spec->input_mux = &spec->private_imux[0];
3784 3018
3785 if (spec->hp_mux) 3019 if (!spec->autocfg.dig_in_pin)
3786 via_hp_build(codec); 3020 return;
3787 3021
3788 via_smart51_build(spec); 3022 dig_nid = codec->start_nid;
3789 return 1; 3023 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
3024 unsigned int wcaps = get_wcaps(codec, dig_nid);
3025 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
3026 continue;
3027 if (!(wcaps & AC_WCAP_DIGITAL))
3028 continue;
3029 if (!(wcaps & AC_WCAP_CONN_LIST))
3030 continue;
3031 err = get_connection_index(codec, dig_nid,
3032 spec->autocfg.dig_in_pin);
3033 if (err >= 0) {
3034 spec->dig_in_nid = dig_nid;
3035 break;
3036 }
3037 }
3790} 3038}
3791 3039
3792#ifdef CONFIG_SND_HDA_POWER_SAVE
3793static const struct hda_amp_list vt1708S_loopbacks[] = {
3794 { 0x16, HDA_INPUT, 1 },
3795 { 0x16, HDA_INPUT, 2 },
3796 { 0x16, HDA_INPUT, 3 },
3797 { 0x16, HDA_INPUT, 4 },
3798 { } /* end */
3799};
3800#endif
3801
3802static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin, 3040static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
3803 int offset, int num_steps, int step_size) 3041 int offset, int num_steps, int step_size)
3804{ 3042{
@@ -3819,62 +3057,21 @@ static int patch_vt1708S(struct hda_codec *codec)
3819 if (spec == NULL) 3057 if (spec == NULL)
3820 return -ENOMEM; 3058 return -ENOMEM;
3821 3059
3060 spec->aa_mix_nid = 0x16;
3061 override_mic_boost(codec, 0x1a, 0, 3, 40);
3062 override_mic_boost(codec, 0x1e, 0, 3, 40);
3063
3822 /* automatic parse from the BIOS config */ 3064 /* automatic parse from the BIOS config */
3823 err = vt1708S_parse_auto_config(codec); 3065 err = via_parse_auto_config(codec);
3824 if (err < 0) { 3066 if (err < 0) {
3825 via_free(codec); 3067 via_free(codec);
3826 return err; 3068 return err;
3827 } else if (!err) {
3828 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3829 "from BIOS. Using genenic mode...\n");
3830 } 3069 }
3831 3070
3832 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; 3071 spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs;
3833 if (codec->vendor_id == 0x11064397)
3834 spec->init_verbs[spec->num_iverbs++] =
3835 vt1705_uniwill_init_verbs;
3836 else
3837 spec->init_verbs[spec->num_iverbs++] =
3838 vt1708S_uniwill_init_verbs;
3839
3840 if (codec->vendor_id == 0x11060440)
3841 spec->stream_name_analog = "VT1818S Analog";
3842 else if (codec->vendor_id == 0x11064397)
3843 spec->stream_name_analog = "VT1705 Analog";
3844 else
3845 spec->stream_name_analog = "VT1708S Analog";
3846 if (codec->vendor_id == 0x11064397)
3847 spec->stream_analog_playback = &vt1705_pcm_analog_playback;
3848 else
3849 spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
3850 spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
3851
3852 if (codec->vendor_id == 0x11060440)
3853 spec->stream_name_digital = "VT1818S Digital";
3854 else if (codec->vendor_id == 0x11064397)
3855 spec->stream_name_digital = "VT1705 Digital";
3856 else
3857 spec->stream_name_digital = "VT1708S Digital";
3858 spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
3859
3860 if (!spec->adc_nids && spec->input_mux) {
3861 spec->adc_nids = vt1708S_adc_nids;
3862 spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
3863 get_mux_nids(codec);
3864 override_mic_boost(codec, 0x1a, 0, 3, 40);
3865 override_mic_boost(codec, 0x1e, 0, 3, 40);
3866 spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
3867 spec->num_mixers++;
3868 }
3869 3072
3870 codec->patch_ops = via_patch_ops; 3073 codec->patch_ops = via_patch_ops;
3871 3074
3872 codec->patch_ops.init = via_auto_init;
3873 codec->patch_ops.unsol_event = via_unsol_event;
3874#ifdef CONFIG_SND_HDA_POWER_SAVE
3875 spec->loopback.amplist = vt1708S_loopbacks;
3876#endif
3877
3878 /* correct names for VT1708BCE */ 3075 /* correct names for VT1708BCE */
3879 if (get_codec_type(codec) == VT1708BCE) { 3076 if (get_codec_type(codec) == VT1708BCE) {
3880 kfree(codec->chip_name); 3077 kfree(codec->chip_name);
@@ -3882,13 +3079,6 @@ static int patch_vt1708S(struct hda_codec *codec)
3882 snprintf(codec->bus->card->mixername, 3079 snprintf(codec->bus->card->mixername,
3883 sizeof(codec->bus->card->mixername), 3080 sizeof(codec->bus->card->mixername),
3884 "%s %s", codec->vendor_name, codec->chip_name); 3081 "%s %s", codec->vendor_name, codec->chip_name);
3885 spec->stream_name_analog = "VT1708BCE Analog";
3886 spec->stream_name_digital = "VT1708BCE Digital";
3887 }
3888 /* correct names for VT1818S */
3889 if (codec->vendor_id == 0x11060440) {
3890 spec->stream_name_analog = "VT1818S Analog";
3891 spec->stream_name_digital = "VT1818S Digital";
3892 } 3082 }
3893 /* correct names for VT1705 */ 3083 /* correct names for VT1705 */
3894 if (codec->vendor_id == 0x11064397) { 3084 if (codec->vendor_id == 0x11064397) {
@@ -3904,55 +3094,7 @@ static int patch_vt1708S(struct hda_codec *codec)
3904 3094
3905/* Patch for VT1702 */ 3095/* Patch for VT1702 */
3906 3096
3907/* capture mixer elements */ 3097static const struct hda_verb vt1702_init_verbs[] = {
3908static const struct snd_kcontrol_new vt1702_capture_mixer[] = {
3909 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
3910 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
3911 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
3912 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
3913 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
3914 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
3915 HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
3916 HDA_INPUT),
3917 {
3918 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3919 /* The multiple "Capture Source" controls confuse alsamixer
3920 * So call somewhat different..
3921 */
3922 /* .name = "Capture Source", */
3923 .name = "Input Source",
3924 .count = 1,
3925 .info = via_mux_enum_info,
3926 .get = via_mux_enum_get,
3927 .put = via_mux_enum_put,
3928 },
3929 { } /* end */
3930};
3931
3932static const struct hda_verb vt1702_volume_init_verbs[] = {
3933 /*
3934 * Unmute ADC0-1 and set the default input to mic-in
3935 */
3936 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3937 {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3938 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3939
3940
3941 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3942 * mixer widget
3943 */
3944 /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
3945 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3946 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3947 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3948 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3949 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3950
3951 /* Setup default input of PW4 to MW0 */
3952 {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
3953 /* PW6 PW7 Output enable */
3954 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3955 {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3956 /* mixer enable */ 3098 /* mixer enable */
3957 {0x1, 0xF88, 0x3}, 3099 {0x1, 0xF88, 0x3},
3958 /* GPIO 0~2 */ 3100 /* GPIO 0~2 */
@@ -3960,202 +3102,6 @@ static const struct hda_verb vt1702_volume_init_verbs[] = {
3960 { } 3102 { }
3961}; 3103};
3962 3104
3963static const struct hda_verb vt1702_uniwill_init_verbs[] = {
3964 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
3965 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3966 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3967 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3968 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3969 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3970 { }
3971};
3972
3973static const struct hda_pcm_stream vt1702_pcm_analog_playback = {
3974 .substreams = 2,
3975 .channels_min = 2,
3976 .channels_max = 2,
3977 .nid = 0x10, /* NID to query formats and rates */
3978 .ops = {
3979 .open = via_playback_pcm_open,
3980 .prepare = via_playback_multi_pcm_prepare,
3981 .cleanup = via_playback_multi_pcm_cleanup,
3982 .close = via_pcm_open_close
3983 },
3984};
3985
3986static const struct hda_pcm_stream vt1702_pcm_analog_capture = {
3987 .substreams = 3,
3988 .channels_min = 2,
3989 .channels_max = 2,
3990 .nid = 0x12, /* NID to query formats and rates */
3991 .ops = {
3992 .open = via_pcm_open_close,
3993 .prepare = via_capture_pcm_prepare,
3994 .cleanup = via_capture_pcm_cleanup,
3995 .close = via_pcm_open_close
3996 },
3997};
3998
3999static const struct hda_pcm_stream vt1702_pcm_digital_playback = {
4000 .substreams = 2,
4001 .channels_min = 2,
4002 .channels_max = 2,
4003 /* NID is set in via_build_pcms */
4004 .ops = {
4005 .open = via_dig_playback_pcm_open,
4006 .close = via_dig_playback_pcm_close,
4007 .prepare = via_dig_playback_pcm_prepare,
4008 .cleanup = via_dig_playback_pcm_cleanup
4009 },
4010};
4011
4012/* fill in the dac_nids table from the parsed pin configuration */
4013static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
4014 const struct auto_pin_cfg *cfg)
4015{
4016 spec->multiout.num_dacs = 1;
4017 spec->multiout.dac_nids = spec->private_dac_nids;
4018
4019 if (cfg->line_out_pins[0]) {
4020 /* config dac list */
4021 spec->private_dac_nids[0] = 0x10;
4022 }
4023
4024 return 0;
4025}
4026
4027/* add playback controls from the parsed DAC table */
4028static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
4029 const struct auto_pin_cfg *cfg)
4030{
4031 int err;
4032
4033 if (!cfg->line_out_pins[0])
4034 return -1;
4035
4036 /* add control to mixer index 0 */
4037 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4038 "Master Front Playback Volume",
4039 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4040 if (err < 0)
4041 return err;
4042 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4043 "Master Front Playback Switch",
4044 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4045 if (err < 0)
4046 return err;
4047
4048 /* Front */
4049 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4050 "Front Playback Volume",
4051 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
4052 if (err < 0)
4053 return err;
4054 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4055 "Front Playback Switch",
4056 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
4057 if (err < 0)
4058 return err;
4059
4060 return 0;
4061}
4062
4063static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4064{
4065 int err, i;
4066 struct hda_input_mux *imux;
4067 static const char * const texts[] = { "ON", "OFF", NULL};
4068 if (!pin)
4069 return 0;
4070 spec->multiout.hp_nid = 0x1D;
4071 spec->hp_independent_mode_index = 0;
4072
4073 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4074 "Headphone Playback Volume",
4075 HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
4076 if (err < 0)
4077 return err;
4078
4079 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4080 "Headphone Playback Switch",
4081 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4082 if (err < 0)
4083 return err;
4084
4085 imux = &spec->private_imux[1];
4086
4087 /* for hp mode select */
4088 for (i = 0; texts[i]; i++)
4089 snd_hda_add_imux_item(imux, texts[i], i, NULL);
4090
4091 spec->hp_mux = &spec->private_imux[1];
4092 return 0;
4093}
4094
4095/* create playback/capture controls for input pins */
4096static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec,
4097 const struct auto_pin_cfg *cfg)
4098{
4099 static const hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff };
4100 return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs,
4101 ARRAY_SIZE(pin_idxs));
4102}
4103
4104static int vt1702_parse_auto_config(struct hda_codec *codec)
4105{
4106 struct via_spec *spec = codec->spec;
4107 int err;
4108
4109 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4110 if (err < 0)
4111 return err;
4112 err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
4113 if (err < 0)
4114 return err;
4115 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4116 return 0; /* can't find valid BIOS pin config */
4117
4118 err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
4119 if (err < 0)
4120 return err;
4121 err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4122 if (err < 0)
4123 return err;
4124 /* limit AA path volume to 0 dB */
4125 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
4126 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4127 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4128 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4129 (1 << AC_AMPCAP_MUTE_SHIFT));
4130 err = vt1702_auto_create_analog_input_ctls(codec, &spec->autocfg);
4131 if (err < 0)
4132 return err;
4133
4134 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4135
4136 fill_dig_outs(codec);
4137
4138 if (spec->kctls.list)
4139 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4140
4141 spec->input_mux = &spec->private_imux[0];
4142
4143 if (spec->hp_mux)
4144 via_hp_build(codec);
4145
4146 return 1;
4147}
4148
4149#ifdef CONFIG_SND_HDA_POWER_SAVE
4150static const struct hda_amp_list vt1702_loopbacks[] = {
4151 { 0x1A, HDA_INPUT, 1 },
4152 { 0x1A, HDA_INPUT, 2 },
4153 { 0x1A, HDA_INPUT, 3 },
4154 { 0x1A, HDA_INPUT, 4 },
4155 { } /* end */
4156};
4157#endif
4158
4159static void set_widgets_power_state_vt1702(struct hda_codec *codec) 3105static void set_widgets_power_state_vt1702(struct hda_codec *codec)
4160{ 3106{
4161 int imux_is_smixer = 3107 int imux_is_smixer =
@@ -4197,385 +3143,41 @@ static int patch_vt1702(struct hda_codec *codec)
4197 if (spec == NULL) 3143 if (spec == NULL)
4198 return -ENOMEM; 3144 return -ENOMEM;
4199 3145
3146 spec->aa_mix_nid = 0x1a;
3147
3148 /* limit AA path volume to 0 dB */
3149 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
3150 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
3151 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3152 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3153 (1 << AC_AMPCAP_MUTE_SHIFT));
3154
4200 /* automatic parse from the BIOS config */ 3155 /* automatic parse from the BIOS config */
4201 err = vt1702_parse_auto_config(codec); 3156 err = via_parse_auto_config(codec);
4202 if (err < 0) { 3157 if (err < 0) {
4203 via_free(codec); 3158 via_free(codec);
4204 return err; 3159 return err;
4205 } else if (!err) {
4206 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4207 "from BIOS. Using genenic mode...\n");
4208 } 3160 }
4209 3161
4210 spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs; 3162 spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs;
4211 spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
4212
4213 spec->stream_name_analog = "VT1702 Analog";
4214 spec->stream_analog_playback = &vt1702_pcm_analog_playback;
4215 spec->stream_analog_capture = &vt1702_pcm_analog_capture;
4216
4217 spec->stream_name_digital = "VT1702 Digital";
4218 spec->stream_digital_playback = &vt1702_pcm_digital_playback;
4219
4220 if (!spec->adc_nids && spec->input_mux) {
4221 spec->adc_nids = vt1702_adc_nids;
4222 spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
4223 get_mux_nids(codec);
4224 spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
4225 spec->num_mixers++;
4226 }
4227 3163
4228 codec->patch_ops = via_patch_ops; 3164 codec->patch_ops = via_patch_ops;
4229 3165
4230 codec->patch_ops.init = via_auto_init;
4231 codec->patch_ops.unsol_event = via_unsol_event;
4232#ifdef CONFIG_SND_HDA_POWER_SAVE
4233 spec->loopback.amplist = vt1702_loopbacks;
4234#endif
4235
4236 spec->set_widgets_power_state = set_widgets_power_state_vt1702; 3166 spec->set_widgets_power_state = set_widgets_power_state_vt1702;
4237 return 0; 3167 return 0;
4238} 3168}
4239 3169
4240/* Patch for VT1718S */ 3170/* Patch for VT1718S */
4241 3171
4242/* capture mixer elements */ 3172static const struct hda_verb vt1718S_init_verbs[] = {
4243static const struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4244 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
4245 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
4246 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
4247 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
4248 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
4249 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
4250 HDA_INPUT),
4251 {
4252 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4253 /* The multiple "Capture Source" controls confuse alsamixer
4254 * So call somewhat different..
4255 */
4256 .name = "Input Source",
4257 .count = 2,
4258 .info = via_mux_enum_info,
4259 .get = via_mux_enum_get,
4260 .put = via_mux_enum_put,
4261 },
4262 { } /* end */
4263};
4264
4265static const struct hda_verb vt1718S_volume_init_verbs[] = {
4266 /*
4267 * Unmute ADC0-1 and set the default input to mic-in
4268 */
4269 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4270 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4271
4272 /* Enable MW0 adjust Gain 5 */ 3173 /* Enable MW0 adjust Gain 5 */
4273 {0x1, 0xfb2, 0x10}, 3174 {0x1, 0xfb2, 0x10},
4274 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4275 * mixer widget
4276 */
4277 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4278 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4279 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4280 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4281 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4282 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
4283
4284 /* Setup default input of Front HP to MW9 */
4285 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4286 /* PW9 PW10 Output enable */
4287 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4288 {0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4289 /* PW11 Input enable */
4290 {0x2f, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_IN_EN},
4291 /* Enable Boost Volume backdoor */ 3175 /* Enable Boost Volume backdoor */
4292 {0x1, 0xf88, 0x8}, 3176 {0x1, 0xf88, 0x8},
4293 /* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */
4294 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4295 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4296 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4297 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4298 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4299 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4300 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4301 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4302 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4303 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4304 /* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */
4305 {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
4306 {0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
4307 /* Unmute MW4's index 0 */
4308 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4309 { }
4310};
4311
4312 3177
4313static const struct hda_verb vt1718S_uniwill_init_verbs[] = {
4314 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
4315 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4316 {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4317 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4318 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4319 {0x27, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4320 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4321 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4322 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4323 { } 3178 { }
4324}; 3179};
4325 3180
4326static const struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4327 .substreams = 2,
4328 .channels_min = 2,
4329 .channels_max = 10,
4330 .nid = 0x8, /* NID to query formats and rates */
4331 .ops = {
4332 .open = via_playback_pcm_open,
4333 .prepare = via_playback_multi_pcm_prepare,
4334 .cleanup = via_playback_multi_pcm_cleanup,
4335 .close = via_pcm_open_close,
4336 },
4337};
4338
4339static const struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4340 .substreams = 2,
4341 .channels_min = 2,
4342 .channels_max = 2,
4343 .nid = 0x10, /* NID to query formats and rates */
4344 .ops = {
4345 .open = via_pcm_open_close,
4346 .prepare = via_capture_pcm_prepare,
4347 .cleanup = via_capture_pcm_cleanup,
4348 .close = via_pcm_open_close,
4349 },
4350};
4351
4352static const struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4353 .substreams = 2,
4354 .channels_min = 2,
4355 .channels_max = 2,
4356 /* NID is set in via_build_pcms */
4357 .ops = {
4358 .open = via_dig_playback_pcm_open,
4359 .close = via_dig_playback_pcm_close,
4360 .prepare = via_dig_playback_pcm_prepare,
4361 .cleanup = via_dig_playback_pcm_cleanup
4362 },
4363};
4364
4365static const struct hda_pcm_stream vt1718S_pcm_digital_capture = {
4366 .substreams = 1,
4367 .channels_min = 2,
4368 .channels_max = 2,
4369};
4370
4371/* fill in the dac_nids table from the parsed pin configuration */
4372static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
4373 const struct auto_pin_cfg *cfg)
4374{
4375 int i;
4376 hda_nid_t nid;
4377
4378 spec->multiout.num_dacs = cfg->line_outs;
4379
4380 spec->multiout.dac_nids = spec->private_dac_nids;
4381
4382 for (i = 0; i < 4; i++) {
4383 nid = cfg->line_out_pins[i];
4384 if (nid) {
4385 /* config dac list */
4386 switch (i) {
4387 case AUTO_SEQ_FRONT:
4388 spec->private_dac_nids[i] = 0x8;
4389 break;
4390 case AUTO_SEQ_CENLFE:
4391 spec->private_dac_nids[i] = 0xa;
4392 break;
4393 case AUTO_SEQ_SURROUND:
4394 spec->private_dac_nids[i] = 0x9;
4395 break;
4396 case AUTO_SEQ_SIDE:
4397 spec->private_dac_nids[i] = 0xb;
4398 break;
4399 }
4400 }
4401 }
4402
4403 return 0;
4404}
4405
4406/* add playback controls from the parsed DAC table */
4407static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
4408 const struct auto_pin_cfg *cfg)
4409{
4410 char name[32];
4411 static const char * const chname[4] = {
4412 "Front", "Surround", "C/LFE", "Side"
4413 };
4414 hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb};
4415 hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27};
4416 hda_nid_t nid, nid_vol, nid_mute = 0;
4417 int i, err;
4418
4419 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
4420 nid = cfg->line_out_pins[i];
4421
4422 if (!nid)
4423 continue;
4424 nid_vol = nid_vols[i];
4425 nid_mute = nid_mutes[i];
4426
4427 if (i == AUTO_SEQ_CENLFE) {
4428 /* Center/LFE */
4429 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4430 "Center Playback Volume",
4431 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
4432 HDA_OUTPUT));
4433 if (err < 0)
4434 return err;
4435 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4436 "LFE Playback Volume",
4437 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
4438 HDA_OUTPUT));
4439 if (err < 0)
4440 return err;
4441 err = via_add_control(
4442 spec, VIA_CTL_WIDGET_MUTE,
4443 "Center Playback Switch",
4444 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
4445 HDA_OUTPUT));
4446 if (err < 0)
4447 return err;
4448 err = via_add_control(
4449 spec, VIA_CTL_WIDGET_MUTE,
4450 "LFE Playback Switch",
4451 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
4452 HDA_OUTPUT));
4453 if (err < 0)
4454 return err;
4455 } else if (i == AUTO_SEQ_FRONT) {
4456 /* Front */
4457 sprintf(name, "%s Playback Volume", chname[i]);
4458 err = via_add_control(
4459 spec, VIA_CTL_WIDGET_VOL, name,
4460 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4461 if (err < 0)
4462 return err;
4463 sprintf(name, "%s Playback Switch", chname[i]);
4464 err = via_add_control(
4465 spec, VIA_CTL_WIDGET_MUTE, name,
4466 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4467 HDA_OUTPUT));
4468 if (err < 0)
4469 return err;
4470 } else {
4471 sprintf(name, "%s Playback Volume", chname[i]);
4472 err = via_add_control(
4473 spec, VIA_CTL_WIDGET_VOL, name,
4474 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4475 if (err < 0)
4476 return err;
4477 sprintf(name, "%s Playback Switch", chname[i]);
4478 err = via_add_control(
4479 spec, VIA_CTL_WIDGET_MUTE, name,
4480 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4481 HDA_OUTPUT));
4482 if (err < 0)
4483 return err;
4484 }
4485 }
4486 return 0;
4487}
4488
4489static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4490{
4491 int err;
4492
4493 if (!pin)
4494 return 0;
4495
4496 spec->multiout.hp_nid = 0xc; /* AOW4 */
4497 spec->hp_independent_mode_index = 1;
4498
4499 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4500 "Headphone Playback Volume",
4501 HDA_COMPOSE_AMP_VAL(0xc, 3, 0, HDA_OUTPUT));
4502 if (err < 0)
4503 return err;
4504
4505 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4506 "Headphone Playback Switch",
4507 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4508 if (err < 0)
4509 return err;
4510
4511 create_hp_imux(spec);
4512 return 0;
4513}
4514
4515/* create playback/capture controls for input pins */
4516static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec,
4517 const struct auto_pin_cfg *cfg)
4518{
4519 static const hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff };
4520 return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
4521 ARRAY_SIZE(pin_idxs));
4522}
4523
4524static int vt1718S_parse_auto_config(struct hda_codec *codec)
4525{
4526 struct via_spec *spec = codec->spec;
4527 int err;
4528
4529 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4530
4531 if (err < 0)
4532 return err;
4533 err = vt1718S_auto_fill_dac_nids(spec, &spec->autocfg);
4534 if (err < 0)
4535 return err;
4536 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4537 return 0; /* can't find valid BIOS pin config */
4538
4539 err = vt1718S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4540 if (err < 0)
4541 return err;
4542 err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4543 if (err < 0)
4544 return err;
4545 err = vt1718S_auto_create_analog_input_ctls(codec, &spec->autocfg);
4546 if (err < 0)
4547 return err;
4548
4549 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4550
4551 fill_dig_outs(codec);
4552
4553 if (spec->autocfg.dig_in_pin && codec->vendor_id == 0x11060428)
4554 spec->dig_in_nid = 0x13;
4555
4556 if (spec->kctls.list)
4557 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4558
4559 spec->input_mux = &spec->private_imux[0];
4560
4561 if (spec->hp_mux)
4562 via_hp_build(codec);
4563
4564 via_smart51_build(spec);
4565
4566 return 1;
4567}
4568
4569#ifdef CONFIG_SND_HDA_POWER_SAVE
4570static const struct hda_amp_list vt1718S_loopbacks[] = {
4571 { 0x21, HDA_INPUT, 1 },
4572 { 0x21, HDA_INPUT, 2 },
4573 { 0x21, HDA_INPUT, 3 },
4574 { 0x21, HDA_INPUT, 4 },
4575 { } /* end */
4576};
4577#endif
4578
4579static void set_widgets_power_state_vt1718S(struct hda_codec *codec) 3181static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
4580{ 3182{
4581 struct via_spec *spec = codec->spec; 3183 struct via_spec *spec = codec->spec;
@@ -4642,6 +3244,41 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
4642 } 3244 }
4643} 3245}
4644 3246
3247/* Add a connection to the primary DAC from AA-mixer for some codecs
3248 * This isn't listed from the raw info, but the chip has a secret connection.
3249 */
3250static int add_secret_dac_path(struct hda_codec *codec)
3251{
3252 struct via_spec *spec = codec->spec;
3253 int i, nums;
3254 hda_nid_t conn[8];
3255 hda_nid_t nid;
3256
3257 if (!spec->aa_mix_nid)
3258 return 0;
3259 nums = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
3260 ARRAY_SIZE(conn) - 1);
3261 for (i = 0; i < nums; i++) {
3262 if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT)
3263 return 0;
3264 }
3265
3266 /* find the primary DAC and add to the connection list */
3267 nid = codec->start_nid;
3268 for (i = 0; i < codec->num_nodes; i++, nid++) {
3269 unsigned int caps = get_wcaps(codec, nid);
3270 if (get_wcaps_type(caps) == AC_WID_AUD_OUT &&
3271 !(caps & AC_WCAP_DIGITAL)) {
3272 conn[nums++] = nid;
3273 return snd_hda_override_conn_list(codec,
3274 spec->aa_mix_nid,
3275 nums, conn);
3276 }
3277 }
3278 return 0;
3279}
3280
3281
4645static int patch_vt1718S(struct hda_codec *codec) 3282static int patch_vt1718S(struct hda_codec *codec)
4646{ 3283{
4647 struct via_spec *spec; 3284 struct via_spec *spec;
@@ -4652,57 +3289,22 @@ static int patch_vt1718S(struct hda_codec *codec)
4652 if (spec == NULL) 3289 if (spec == NULL)
4653 return -ENOMEM; 3290 return -ENOMEM;
4654 3291
3292 spec->aa_mix_nid = 0x21;
3293 override_mic_boost(codec, 0x2b, 0, 3, 40);
3294 override_mic_boost(codec, 0x29, 0, 3, 40);
3295 add_secret_dac_path(codec);
3296
4655 /* automatic parse from the BIOS config */ 3297 /* automatic parse from the BIOS config */
4656 err = vt1718S_parse_auto_config(codec); 3298 err = via_parse_auto_config(codec);
4657 if (err < 0) { 3299 if (err < 0) {
4658 via_free(codec); 3300 via_free(codec);
4659 return err; 3301 return err;
4660 } else if (!err) {
4661 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4662 "from BIOS. Using genenic mode...\n");
4663 } 3302 }
4664 3303
4665 spec->init_verbs[spec->num_iverbs++] = vt1718S_volume_init_verbs; 3304 spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs;
4666 spec->init_verbs[spec->num_iverbs++] = vt1718S_uniwill_init_verbs;
4667
4668 if (codec->vendor_id == 0x11060441)
4669 spec->stream_name_analog = "VT2020 Analog";
4670 else if (codec->vendor_id == 0x11064441)
4671 spec->stream_name_analog = "VT1828S Analog";
4672 else
4673 spec->stream_name_analog = "VT1718S Analog";
4674 spec->stream_analog_playback = &vt1718S_pcm_analog_playback;
4675 spec->stream_analog_capture = &vt1718S_pcm_analog_capture;
4676
4677 if (codec->vendor_id == 0x11060441)
4678 spec->stream_name_digital = "VT2020 Digital";
4679 else if (codec->vendor_id == 0x11064441)
4680 spec->stream_name_digital = "VT1828S Digital";
4681 else
4682 spec->stream_name_digital = "VT1718S Digital";
4683 spec->stream_digital_playback = &vt1718S_pcm_digital_playback;
4684 if (codec->vendor_id == 0x11060428 || codec->vendor_id == 0x11060441)
4685 spec->stream_digital_capture = &vt1718S_pcm_digital_capture;
4686
4687 if (!spec->adc_nids && spec->input_mux) {
4688 spec->adc_nids = vt1718S_adc_nids;
4689 spec->num_adc_nids = ARRAY_SIZE(vt1718S_adc_nids);
4690 get_mux_nids(codec);
4691 override_mic_boost(codec, 0x2b, 0, 3, 40);
4692 override_mic_boost(codec, 0x29, 0, 3, 40);
4693 spec->mixers[spec->num_mixers] = vt1718S_capture_mixer;
4694 spec->num_mixers++;
4695 }
4696 3305
4697 codec->patch_ops = via_patch_ops; 3306 codec->patch_ops = via_patch_ops;
4698 3307
4699 codec->patch_ops.init = via_auto_init;
4700 codec->patch_ops.unsol_event = via_unsol_event;
4701
4702#ifdef CONFIG_SND_HDA_POWER_SAVE
4703 spec->loopback.amplist = vt1718S_loopbacks;
4704#endif
4705
4706 spec->set_widgets_power_state = set_widgets_power_state_vt1718S; 3308 spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
4707 3309
4708 return 0; 3310 return 0;
@@ -4748,26 +3350,6 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
4748 return 1; 3350 return 1;
4749} 3351}
4750 3352
4751/* capture mixer elements */
4752static const struct snd_kcontrol_new vt1716S_capture_mixer[] = {
4753 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
4754 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
4755 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
4756 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
4757 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
4758 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
4759 HDA_INPUT),
4760 {
4761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4762 .name = "Input Source",
4763 .count = 1,
4764 .info = via_mux_enum_info,
4765 .get = via_mux_enum_get,
4766 .put = via_mux_enum_put,
4767 },
4768 { } /* end */
4769};
4770
4771static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = { 3353static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
4772 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT), 3354 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
4773 { 3355 {
@@ -4789,45 +3371,7 @@ static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
4789 { } /* end */ 3371 { } /* end */
4790}; 3372};
4791 3373
4792static const struct hda_verb vt1716S_volume_init_verbs[] = { 3374static const struct hda_verb vt1716S_init_verbs[] = {
4793 /*
4794 * Unmute ADC0-1 and set the default input to mic-in
4795 */
4796 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4798
4799
4800 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4801 * mixer widget
4802 */
4803 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4804 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4805 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4806 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4807 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4808 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4809
4810 /* MUX Indices: Stereo Mixer = 5 */
4811 {0x17, AC_VERB_SET_CONNECT_SEL, 0x5},
4812
4813 /* Setup default input of PW4 to MW0 */
4814 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
4815
4816 /* Setup default input of SW1 as MW0 */
4817 {0x18, AC_VERB_SET_CONNECT_SEL, 0x1},
4818
4819 /* Setup default input of SW4 as AOW0 */
4820 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4821
4822 /* PW9 PW10 Output enable */
4823 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4824 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4825
4826 /* Unmute SW1, PW12 */
4827 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4828 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4829 /* PW12 Output enable */
4830 {0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4831 /* Enable Boost Volume backdoor */ 3375 /* Enable Boost Volume backdoor */
4832 {0x1, 0xf8a, 0x80}, 3376 {0x1, 0xf8a, 0x80},
4833 /* don't bybass mixer */ 3377 /* don't bybass mixer */
@@ -4837,272 +3381,6 @@ static const struct hda_verb vt1716S_volume_init_verbs[] = {
4837 { } 3381 { }
4838}; 3382};
4839 3383
4840
4841static const struct hda_verb vt1716S_uniwill_init_verbs[] = {
4842 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
4843 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4844 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4845 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4846 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4847 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE,
4848 AC_USRSP_EN | VIA_MONO_EVENT | VIA_JACK_EVENT},
4849 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4850 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4851 { }
4852};
4853
4854static const struct hda_pcm_stream vt1716S_pcm_analog_playback = {
4855 .substreams = 2,
4856 .channels_min = 2,
4857 .channels_max = 6,
4858 .nid = 0x10, /* NID to query formats and rates */
4859 .ops = {
4860 .open = via_playback_pcm_open,
4861 .prepare = via_playback_multi_pcm_prepare,
4862 .cleanup = via_playback_multi_pcm_cleanup,
4863 .close = via_pcm_open_close,
4864 },
4865};
4866
4867static const struct hda_pcm_stream vt1716S_pcm_analog_capture = {
4868 .substreams = 2,
4869 .channels_min = 2,
4870 .channels_max = 2,
4871 .nid = 0x13, /* NID to query formats and rates */
4872 .ops = {
4873 .open = via_pcm_open_close,
4874 .prepare = via_capture_pcm_prepare,
4875 .cleanup = via_capture_pcm_cleanup,
4876 .close = via_pcm_open_close,
4877 },
4878};
4879
4880static const struct hda_pcm_stream vt1716S_pcm_digital_playback = {
4881 .substreams = 2,
4882 .channels_min = 2,
4883 .channels_max = 2,
4884 /* NID is set in via_build_pcms */
4885 .ops = {
4886 .open = via_dig_playback_pcm_open,
4887 .close = via_dig_playback_pcm_close,
4888 .prepare = via_dig_playback_pcm_prepare,
4889 .cleanup = via_dig_playback_pcm_cleanup
4890 },
4891};
4892
4893/* fill in the dac_nids table from the parsed pin configuration */
4894static int vt1716S_auto_fill_dac_nids(struct via_spec *spec,
4895 const struct auto_pin_cfg *cfg)
4896{ int i;
4897 hda_nid_t nid;
4898
4899 spec->multiout.num_dacs = cfg->line_outs;
4900
4901 spec->multiout.dac_nids = spec->private_dac_nids;
4902
4903 for (i = 0; i < 3; i++) {
4904 nid = cfg->line_out_pins[i];
4905 if (nid) {
4906 /* config dac list */
4907 switch (i) {
4908 case AUTO_SEQ_FRONT:
4909 spec->private_dac_nids[i] = 0x10;
4910 break;
4911 case AUTO_SEQ_CENLFE:
4912 spec->private_dac_nids[i] = 0x25;
4913 break;
4914 case AUTO_SEQ_SURROUND:
4915 spec->private_dac_nids[i] = 0x11;
4916 break;
4917 }
4918 }
4919 }
4920
4921 return 0;
4922}
4923
4924/* add playback controls from the parsed DAC table */
4925static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec,
4926 const struct auto_pin_cfg *cfg)
4927{
4928 char name[32];
4929 static const char * const chname[3] = {
4930 "Front", "Surround", "C/LFE"
4931 };
4932 hda_nid_t nid_vols[] = {0x10, 0x11, 0x25};
4933 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27};
4934 hda_nid_t nid, nid_vol, nid_mute;
4935 int i, err;
4936
4937 for (i = 0; i <= AUTO_SEQ_CENLFE; i++) {
4938 nid = cfg->line_out_pins[i];
4939
4940 if (!nid)
4941 continue;
4942
4943 nid_vol = nid_vols[i];
4944 nid_mute = nid_mutes[i];
4945
4946 if (i == AUTO_SEQ_CENLFE) {
4947 err = via_add_control(
4948 spec, VIA_CTL_WIDGET_VOL,
4949 "Center Playback Volume",
4950 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
4951 if (err < 0)
4952 return err;
4953 err = via_add_control(
4954 spec, VIA_CTL_WIDGET_VOL,
4955 "LFE Playback Volume",
4956 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
4957 if (err < 0)
4958 return err;
4959 err = via_add_control(
4960 spec, VIA_CTL_WIDGET_MUTE,
4961 "Center Playback Switch",
4962 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
4963 HDA_OUTPUT));
4964 if (err < 0)
4965 return err;
4966 err = via_add_control(
4967 spec, VIA_CTL_WIDGET_MUTE,
4968 "LFE Playback Switch",
4969 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
4970 HDA_OUTPUT));
4971 if (err < 0)
4972 return err;
4973 } else if (i == AUTO_SEQ_FRONT) {
4974
4975 err = via_add_control(
4976 spec, VIA_CTL_WIDGET_VOL,
4977 "Master Front Playback Volume",
4978 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
4979 if (err < 0)
4980 return err;
4981 err = via_add_control(
4982 spec, VIA_CTL_WIDGET_MUTE,
4983 "Master Front Playback Switch",
4984 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
4985 if (err < 0)
4986 return err;
4987
4988 sprintf(name, "%s Playback Volume", chname[i]);
4989 err = via_add_control(
4990 spec, VIA_CTL_WIDGET_VOL, name,
4991 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4992 if (err < 0)
4993 return err;
4994 sprintf(name, "%s Playback Switch", chname[i]);
4995 err = via_add_control(
4996 spec, VIA_CTL_WIDGET_MUTE, name,
4997 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4998 HDA_OUTPUT));
4999 if (err < 0)
5000 return err;
5001 } else {
5002 sprintf(name, "%s Playback Volume", chname[i]);
5003 err = via_add_control(
5004 spec, VIA_CTL_WIDGET_VOL, name,
5005 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5006 if (err < 0)
5007 return err;
5008 sprintf(name, "%s Playback Switch", chname[i]);
5009 err = via_add_control(
5010 spec, VIA_CTL_WIDGET_MUTE, name,
5011 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5012 HDA_OUTPUT));
5013 if (err < 0)
5014 return err;
5015 }
5016 }
5017 return 0;
5018}
5019
5020static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5021{
5022 int err;
5023
5024 if (!pin)
5025 return 0;
5026
5027 spec->multiout.hp_nid = 0x25; /* AOW3 */
5028 spec->hp_independent_mode_index = 1;
5029
5030 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5031 "Headphone Playback Volume",
5032 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5033 if (err < 0)
5034 return err;
5035
5036 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5037 "Headphone Playback Switch",
5038 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5039 if (err < 0)
5040 return err;
5041
5042 create_hp_imux(spec);
5043 return 0;
5044}
5045
5046/* create playback/capture controls for input pins */
5047static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec,
5048 const struct auto_pin_cfg *cfg)
5049{
5050 static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
5051 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
5052 ARRAY_SIZE(pin_idxs));
5053}
5054
5055static int vt1716S_parse_auto_config(struct hda_codec *codec)
5056{
5057 struct via_spec *spec = codec->spec;
5058 int err;
5059
5060 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5061 if (err < 0)
5062 return err;
5063 err = vt1716S_auto_fill_dac_nids(spec, &spec->autocfg);
5064 if (err < 0)
5065 return err;
5066 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5067 return 0; /* can't find valid BIOS pin config */
5068
5069 err = vt1716S_auto_create_multi_out_ctls(spec, &spec->autocfg);
5070 if (err < 0)
5071 return err;
5072 err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5073 if (err < 0)
5074 return err;
5075 err = vt1716S_auto_create_analog_input_ctls(codec, &spec->autocfg);
5076 if (err < 0)
5077 return err;
5078
5079 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5080
5081 fill_dig_outs(codec);
5082
5083 if (spec->kctls.list)
5084 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5085
5086 spec->input_mux = &spec->private_imux[0];
5087
5088 if (spec->hp_mux)
5089 via_hp_build(codec);
5090
5091 via_smart51_build(spec);
5092
5093 return 1;
5094}
5095
5096#ifdef CONFIG_SND_HDA_POWER_SAVE
5097static const struct hda_amp_list vt1716S_loopbacks[] = {
5098 { 0x16, HDA_INPUT, 1 },
5099 { 0x16, HDA_INPUT, 2 },
5100 { 0x16, HDA_INPUT, 3 },
5101 { 0x16, HDA_INPUT, 4 },
5102 { } /* end */
5103};
5104#endif
5105
5106static void set_widgets_power_state_vt1716S(struct hda_codec *codec) 3384static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
5107{ 3385{
5108 struct via_spec *spec = codec->spec; 3386 struct via_spec *spec = codec->spec;
@@ -5206,35 +3484,18 @@ static int patch_vt1716S(struct hda_codec *codec)
5206 if (spec == NULL) 3484 if (spec == NULL)
5207 return -ENOMEM; 3485 return -ENOMEM;
5208 3486
3487 spec->aa_mix_nid = 0x16;
3488 override_mic_boost(codec, 0x1a, 0, 3, 40);
3489 override_mic_boost(codec, 0x1e, 0, 3, 40);
3490
5209 /* automatic parse from the BIOS config */ 3491 /* automatic parse from the BIOS config */
5210 err = vt1716S_parse_auto_config(codec); 3492 err = via_parse_auto_config(codec);
5211 if (err < 0) { 3493 if (err < 0) {
5212 via_free(codec); 3494 via_free(codec);
5213 return err; 3495 return err;
5214 } else if (!err) {
5215 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5216 "from BIOS. Using genenic mode...\n");
5217 } 3496 }
5218 3497
5219 spec->init_verbs[spec->num_iverbs++] = vt1716S_volume_init_verbs; 3498 spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs;
5220 spec->init_verbs[spec->num_iverbs++] = vt1716S_uniwill_init_verbs;
5221
5222 spec->stream_name_analog = "VT1716S Analog";
5223 spec->stream_analog_playback = &vt1716S_pcm_analog_playback;
5224 spec->stream_analog_capture = &vt1716S_pcm_analog_capture;
5225
5226 spec->stream_name_digital = "VT1716S Digital";
5227 spec->stream_digital_playback = &vt1716S_pcm_digital_playback;
5228
5229 if (!spec->adc_nids && spec->input_mux) {
5230 spec->adc_nids = vt1716S_adc_nids;
5231 spec->num_adc_nids = ARRAY_SIZE(vt1716S_adc_nids);
5232 get_mux_nids(codec);
5233 override_mic_boost(codec, 0x1a, 0, 3, 40);
5234 override_mic_boost(codec, 0x1e, 0, 3, 40);
5235 spec->mixers[spec->num_mixers] = vt1716S_capture_mixer;
5236 spec->num_mixers++;
5237 }
5238 3499
5239 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer; 3500 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
5240 spec->num_mixers++; 3501 spec->num_mixers++;
@@ -5243,354 +3504,32 @@ static int patch_vt1716S(struct hda_codec *codec)
5243 3504
5244 codec->patch_ops = via_patch_ops; 3505 codec->patch_ops = via_patch_ops;
5245 3506
5246 codec->patch_ops.init = via_auto_init;
5247 codec->patch_ops.unsol_event = via_unsol_event;
5248
5249#ifdef CONFIG_SND_HDA_POWER_SAVE
5250 spec->loopback.amplist = vt1716S_loopbacks;
5251#endif
5252
5253 spec->set_widgets_power_state = set_widgets_power_state_vt1716S; 3507 spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
5254 return 0; 3508 return 0;
5255} 3509}
5256 3510
5257/* for vt2002P */ 3511/* for vt2002P */
5258 3512
5259/* capture mixer elements */ 3513static const struct hda_verb vt2002P_init_verbs[] = {
5260static const struct snd_kcontrol_new vt2002P_capture_mixer[] = {
5261 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5262 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5263 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5264 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5265 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5266 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
5267 HDA_INPUT),
5268 {
5269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5270 /* The multiple "Capture Source" controls confuse alsamixer
5271 * So call somewhat different..
5272 */
5273 /* .name = "Capture Source", */
5274 .name = "Input Source",
5275 .count = 2,
5276 .info = via_mux_enum_info,
5277 .get = via_mux_enum_get,
5278 .put = via_mux_enum_put,
5279 },
5280 { } /* end */
5281};
5282
5283static const struct hda_verb vt2002P_volume_init_verbs[] = {
5284 /* Class-D speaker related verbs */ 3514 /* Class-D speaker related verbs */
5285 {0x1, 0xfe0, 0x4}, 3515 {0x1, 0xfe0, 0x4},
5286 {0x1, 0xfe9, 0x80}, 3516 {0x1, 0xfe9, 0x80},
5287 {0x1, 0xfe2, 0x22}, 3517 {0x1, 0xfe2, 0x22},
5288 /*
5289 * Unmute ADC0-1 and set the default input to mic-in
5290 */
5291 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5292 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5293
5294
5295 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5296 * mixer widget
5297 */
5298 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5299 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5300 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5301 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5302 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5303 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5304
5305 /* MUX Indices: Mic = 0 */
5306 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5307 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5308
5309 /* PW9 Output enable */
5310 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5311
5312 /* Enable Boost Volume backdoor */ 3518 /* Enable Boost Volume backdoor */
5313 {0x1, 0xfb9, 0x24}, 3519 {0x1, 0xfb9, 0x24},
5314
5315 /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5316 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5317 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5318 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5319 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5320 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5321 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5322 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5323 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5324
5325 /* set MUX0/1/4/8 = 0 (AOW0) */
5326 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5327 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5328 {0x37, AC_VERB_SET_CONNECT_SEL, 0},
5329 {0x3b, AC_VERB_SET_CONNECT_SEL, 0},
5330
5331 /* set PW0 index=0 (MW0) */
5332 {0x24, AC_VERB_SET_CONNECT_SEL, 0},
5333
5334 /* Enable AOW0 to MW9 */ 3520 /* Enable AOW0 to MW9 */
5335 {0x1, 0xfb8, 0x88}, 3521 {0x1, 0xfb8, 0x88},
5336 { } 3522 { }
5337}; 3523};
5338static const struct hda_verb vt1802_volume_init_verbs[] = {
5339 /*
5340 * Unmute ADC0-1 and set the default input to mic-in
5341 */
5342 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5343 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5344
5345
5346 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5347 * mixer widget
5348 */
5349 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5350 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5351 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5352 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5353 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5354 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5355
5356 /* MUX Indices: Mic = 0 */
5357 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5358 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5359
5360 /* PW9 Output enable */
5361 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5362 3524
3525static const struct hda_verb vt1802_init_verbs[] = {
5363 /* Enable Boost Volume backdoor */ 3526 /* Enable Boost Volume backdoor */
5364 {0x1, 0xfb9, 0x24}, 3527 {0x1, 0xfb9, 0x24},
5365
5366 /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5367 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5368 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5369 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5370 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5371 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5373 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5374 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5375
5376 /* set MUX0/1/4/8 = 0 (AOW0) */
5377 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5378 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5379 {0x38, AC_VERB_SET_CONNECT_SEL, 0},
5380 {0x3c, AC_VERB_SET_CONNECT_SEL, 0},
5381
5382 /* set PW0 index=0 (MW0) */
5383 {0x24, AC_VERB_SET_CONNECT_SEL, 0},
5384
5385 /* Enable AOW0 to MW9 */ 3528 /* Enable AOW0 to MW9 */
5386 {0x1, 0xfb8, 0x88}, 3529 {0x1, 0xfb8, 0x88},
5387 { } 3530 { }
5388}; 3531};
5389 3532
5390
5391static const struct hda_verb vt2002P_uniwill_init_verbs[] = {
5392 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5393 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5394 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE,
5395 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5396 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5397 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5398 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5399 { }
5400};
5401static const struct hda_verb vt1802_uniwill_init_verbs[] = {
5402 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5403 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5404 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
5405 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5406 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5407 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5408 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5409 { }
5410};
5411
5412static const struct hda_pcm_stream vt2002P_pcm_analog_playback = {
5413 .substreams = 2,
5414 .channels_min = 2,
5415 .channels_max = 2,
5416 .nid = 0x8, /* NID to query formats and rates */
5417 .ops = {
5418 .open = via_playback_pcm_open,
5419 .prepare = via_playback_multi_pcm_prepare,
5420 .cleanup = via_playback_multi_pcm_cleanup,
5421 .close = via_pcm_open_close,
5422 },
5423};
5424
5425static const struct hda_pcm_stream vt2002P_pcm_analog_capture = {
5426 .substreams = 2,
5427 .channels_min = 2,
5428 .channels_max = 2,
5429 .nid = 0x10, /* NID to query formats and rates */
5430 .ops = {
5431 .open = via_pcm_open_close,
5432 .prepare = via_capture_pcm_prepare,
5433 .cleanup = via_capture_pcm_cleanup,
5434 .close = via_pcm_open_close,
5435 },
5436};
5437
5438static const struct hda_pcm_stream vt2002P_pcm_digital_playback = {
5439 .substreams = 1,
5440 .channels_min = 2,
5441 .channels_max = 2,
5442 /* NID is set in via_build_pcms */
5443 .ops = {
5444 .open = via_dig_playback_pcm_open,
5445 .close = via_dig_playback_pcm_close,
5446 .prepare = via_dig_playback_pcm_prepare,
5447 .cleanup = via_dig_playback_pcm_cleanup
5448 },
5449};
5450
5451/* fill in the dac_nids table from the parsed pin configuration */
5452static int vt2002P_auto_fill_dac_nids(struct via_spec *spec,
5453 const struct auto_pin_cfg *cfg)
5454{
5455 spec->multiout.num_dacs = 1;
5456 spec->multiout.dac_nids = spec->private_dac_nids;
5457 if (cfg->line_out_pins[0])
5458 spec->private_dac_nids[0] = 0x8;
5459 return 0;
5460}
5461
5462/* add playback controls from the parsed DAC table */
5463static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
5464 const struct auto_pin_cfg *cfg)
5465{
5466 int err;
5467 hda_nid_t sw_nid;
5468
5469 if (!cfg->line_out_pins[0])
5470 return -1;
5471
5472 if (spec->codec_type == VT1802)
5473 sw_nid = 0x28;
5474 else
5475 sw_nid = 0x26;
5476
5477 /* Line-Out: PortE */
5478 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5479 "Master Front Playback Volume",
5480 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5481 if (err < 0)
5482 return err;
5483 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5484 "Master Front Playback Switch",
5485 HDA_COMPOSE_AMP_VAL(sw_nid, 3, 0, HDA_OUTPUT));
5486 if (err < 0)
5487 return err;
5488
5489 return 0;
5490}
5491
5492static int vt2002P_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5493{
5494 int err;
5495
5496 if (!pin)
5497 return 0;
5498
5499 spec->multiout.hp_nid = 0x9;
5500 spec->hp_independent_mode_index = 1;
5501
5502 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5503 "Headphone Playback Volume",
5504 HDA_COMPOSE_AMP_VAL(
5505 spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5506 if (err < 0)
5507 return err;
5508
5509 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5510 "Headphone Playback Switch",
5511 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5512 if (err < 0)
5513 return err;
5514
5515 create_hp_imux(spec);
5516 return 0;
5517}
5518
5519/* create playback/capture controls for input pins */
5520static int vt2002P_auto_create_analog_input_ctls(struct hda_codec *codec,
5521 const struct auto_pin_cfg *cfg)
5522{
5523 struct via_spec *spec = codec->spec;
5524 struct hda_input_mux *imux = &spec->private_imux[0];
5525 static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff };
5526 int err;
5527
5528 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
5529 ARRAY_SIZE(pin_idxs));
5530 if (err < 0)
5531 return err;
5532 /* build volume/mute control of loopback */
5533 err = via_new_analog_input(spec, "Stereo Mixer", 0, 3, 0x21);
5534 if (err < 0)
5535 return err;
5536
5537 /* for digital mic select */
5538 snd_hda_add_imux_item(imux, "Digital Mic", 4, NULL);
5539
5540 return 0;
5541}
5542
5543static int vt2002P_parse_auto_config(struct hda_codec *codec)
5544{
5545 struct via_spec *spec = codec->spec;
5546 int err;
5547
5548
5549 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5550 if (err < 0)
5551 return err;
5552
5553 err = vt2002P_auto_fill_dac_nids(spec, &spec->autocfg);
5554 if (err < 0)
5555 return err;
5556
5557 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5558 return 0; /* can't find valid BIOS pin config */
5559
5560 err = vt2002P_auto_create_multi_out_ctls(spec, &spec->autocfg);
5561 if (err < 0)
5562 return err;
5563 err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5564 if (err < 0)
5565 return err;
5566 err = vt2002P_auto_create_analog_input_ctls(codec, &spec->autocfg);
5567 if (err < 0)
5568 return err;
5569
5570 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5571
5572 fill_dig_outs(codec);
5573
5574 if (spec->kctls.list)
5575 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5576
5577 spec->input_mux = &spec->private_imux[0];
5578
5579 if (spec->hp_mux)
5580 via_hp_build(codec);
5581
5582 return 1;
5583}
5584
5585#ifdef CONFIG_SND_HDA_POWER_SAVE
5586static const struct hda_amp_list vt2002P_loopbacks[] = {
5587 { 0x21, HDA_INPUT, 0 },
5588 { 0x21, HDA_INPUT, 1 },
5589 { 0x21, HDA_INPUT, 2 },
5590 { } /* end */
5591};
5592#endif
5593
5594static void set_widgets_power_state_vt2002P(struct hda_codec *codec) 3533static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
5595{ 3534{
5596 struct via_spec *spec = codec->spec; 3535 struct via_spec *spec = codec->spec;
@@ -5713,334 +3652,39 @@ static int patch_vt2002P(struct hda_codec *codec)
5713 if (spec == NULL) 3652 if (spec == NULL)
5714 return -ENOMEM; 3653 return -ENOMEM;
5715 3654
3655 spec->aa_mix_nid = 0x21;
3656 override_mic_boost(codec, 0x2b, 0, 3, 40);
3657 override_mic_boost(codec, 0x29, 0, 3, 40);
3658 add_secret_dac_path(codec);
3659
5716 /* automatic parse from the BIOS config */ 3660 /* automatic parse from the BIOS config */
5717 err = vt2002P_parse_auto_config(codec); 3661 err = via_parse_auto_config(codec);
5718 if (err < 0) { 3662 if (err < 0) {
5719 via_free(codec); 3663 via_free(codec);
5720 return err; 3664 return err;
5721 } else if (!err) {
5722 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5723 "from BIOS. Using genenic mode...\n");
5724 } 3665 }
5725 3666
5726 if (spec->codec_type == VT1802) 3667 if (spec->codec_type == VT1802)
5727 spec->init_verbs[spec->num_iverbs++] = 3668 spec->init_verbs[spec->num_iverbs++] = vt1802_init_verbs;
5728 vt1802_volume_init_verbs;
5729 else 3669 else
5730 spec->init_verbs[spec->num_iverbs++] = 3670 spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
5731 vt2002P_volume_init_verbs;
5732
5733 if (spec->codec_type == VT1802)
5734 spec->init_verbs[spec->num_iverbs++] =
5735 vt1802_uniwill_init_verbs;
5736 else
5737 spec->init_verbs[spec->num_iverbs++] =
5738 vt2002P_uniwill_init_verbs;
5739
5740 if (spec->codec_type == VT1802)
5741 spec->stream_name_analog = "VT1802 Analog";
5742 else
5743 spec->stream_name_analog = "VT2002P Analog";
5744 spec->stream_analog_playback = &vt2002P_pcm_analog_playback;
5745 spec->stream_analog_capture = &vt2002P_pcm_analog_capture;
5746
5747 if (spec->codec_type == VT1802)
5748 spec->stream_name_digital = "VT1802 Digital";
5749 else
5750 spec->stream_name_digital = "VT2002P Digital";
5751 spec->stream_digital_playback = &vt2002P_pcm_digital_playback;
5752
5753 if (!spec->adc_nids && spec->input_mux) {
5754 spec->adc_nids = vt2002P_adc_nids;
5755 spec->num_adc_nids = ARRAY_SIZE(vt2002P_adc_nids);
5756 get_mux_nids(codec);
5757 override_mic_boost(codec, 0x2b, 0, 3, 40);
5758 override_mic_boost(codec, 0x29, 0, 3, 40);
5759 spec->mixers[spec->num_mixers] = vt2002P_capture_mixer;
5760 spec->num_mixers++;
5761 }
5762 3671
5763 codec->patch_ops = via_patch_ops; 3672 codec->patch_ops = via_patch_ops;
5764 3673
5765 codec->patch_ops.init = via_auto_init;
5766 codec->patch_ops.unsol_event = via_unsol_event;
5767
5768#ifdef CONFIG_SND_HDA_POWER_SAVE
5769 spec->loopback.amplist = vt2002P_loopbacks;
5770#endif
5771
5772 spec->set_widgets_power_state = set_widgets_power_state_vt2002P; 3674 spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
5773 return 0; 3675 return 0;
5774} 3676}
5775 3677
5776/* for vt1812 */ 3678/* for vt1812 */
5777 3679
5778/* capture mixer elements */ 3680static const struct hda_verb vt1812_init_verbs[] = {
5779static const struct snd_kcontrol_new vt1812_capture_mixer[] = {
5780 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5781 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5782 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5783 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5784 HDA_CODEC_MUTE("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5785 HDA_CODEC_MUTE("Front Mic Boost Capture Volume", 0x29, 0x0,
5786 HDA_INPUT),
5787 {
5788 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5789 /* The multiple "Capture Source" controls confuse alsamixer
5790 * So call somewhat different..
5791 */
5792 .name = "Input Source",
5793 .count = 2,
5794 .info = via_mux_enum_info,
5795 .get = via_mux_enum_get,
5796 .put = via_mux_enum_put,
5797 },
5798 { } /* end */
5799};
5800
5801static const struct hda_verb vt1812_volume_init_verbs[] = {
5802 /*
5803 * Unmute ADC0-1 and set the default input to mic-in
5804 */
5805 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5806 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5807
5808
5809 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5810 * mixer widget
5811 */
5812 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5813 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5814 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5815 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5816 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5817 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5818
5819 /* MUX Indices: Mic = 0 */
5820 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5821 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5822
5823 /* PW9 Output enable */
5824 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5825
5826 /* Enable Boost Volume backdoor */ 3681 /* Enable Boost Volume backdoor */
5827 {0x1, 0xfb9, 0x24}, 3682 {0x1, 0xfb9, 0x24},
5828
5829 /* MW0/1/4/13/15: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5830 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5831 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5832 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5833 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5834 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5835 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5836 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5837 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5838 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5839 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5840
5841 /* set MUX0/1/4/13/15 = 0 (AOW0) */
5842 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5843 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5844 {0x38, AC_VERB_SET_CONNECT_SEL, 0},
5845 {0x3c, AC_VERB_SET_CONNECT_SEL, 0},
5846 {0x3d, AC_VERB_SET_CONNECT_SEL, 0},
5847
5848 /* Enable AOW0 to MW9 */ 3683 /* Enable AOW0 to MW9 */
5849 {0x1, 0xfb8, 0xa8}, 3684 {0x1, 0xfb8, 0xa8},
5850 { } 3685 { }
5851}; 3686};
5852 3687
5853
5854static const struct hda_verb vt1812_uniwill_init_verbs[] = {
5855 {0x33, AC_VERB_SET_UNSOLICITED_ENABLE,
5856 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5857 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT },
5858 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
5859 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5860 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5861 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5862 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5863 { }
5864};
5865
5866static const struct hda_pcm_stream vt1812_pcm_analog_playback = {
5867 .substreams = 2,
5868 .channels_min = 2,
5869 .channels_max = 2,
5870 .nid = 0x8, /* NID to query formats and rates */
5871 .ops = {
5872 .open = via_playback_pcm_open,
5873 .prepare = via_playback_multi_pcm_prepare,
5874 .cleanup = via_playback_multi_pcm_cleanup,
5875 .close = via_pcm_open_close,
5876 },
5877};
5878
5879static const struct hda_pcm_stream vt1812_pcm_analog_capture = {
5880 .substreams = 2,
5881 .channels_min = 2,
5882 .channels_max = 2,
5883 .nid = 0x10, /* NID to query formats and rates */
5884 .ops = {
5885 .open = via_pcm_open_close,
5886 .prepare = via_capture_pcm_prepare,
5887 .cleanup = via_capture_pcm_cleanup,
5888 .close = via_pcm_open_close,
5889 },
5890};
5891
5892static const struct hda_pcm_stream vt1812_pcm_digital_playback = {
5893 .substreams = 1,
5894 .channels_min = 2,
5895 .channels_max = 2,
5896 /* NID is set in via_build_pcms */
5897 .ops = {
5898 .open = via_dig_playback_pcm_open,
5899 .close = via_dig_playback_pcm_close,
5900 .prepare = via_dig_playback_pcm_prepare,
5901 .cleanup = via_dig_playback_pcm_cleanup
5902 },
5903};
5904/* fill in the dac_nids table from the parsed pin configuration */
5905static int vt1812_auto_fill_dac_nids(struct via_spec *spec,
5906 const struct auto_pin_cfg *cfg)
5907{
5908 spec->multiout.num_dacs = 1;
5909 spec->multiout.dac_nids = spec->private_dac_nids;
5910 if (cfg->line_out_pins[0])
5911 spec->private_dac_nids[0] = 0x8;
5912 return 0;
5913}
5914
5915
5916/* add playback controls from the parsed DAC table */
5917static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
5918 const struct auto_pin_cfg *cfg)
5919{
5920 int err;
5921
5922 if (!cfg->line_out_pins[0])
5923 return -1;
5924
5925 /* Line-Out: PortE */
5926 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5927 "Front Playback Volume",
5928 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5929 if (err < 0)
5930 return err;
5931 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5932 "Front Playback Switch",
5933 HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
5934 if (err < 0)
5935 return err;
5936
5937 return 0;
5938}
5939
5940static int vt1812_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5941{
5942 int err;
5943
5944 if (!pin)
5945 return 0;
5946
5947 spec->multiout.hp_nid = 0x9;
5948 spec->hp_independent_mode_index = 1;
5949
5950
5951 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5952 "Headphone Playback Volume",
5953 HDA_COMPOSE_AMP_VAL(
5954 spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5955 if (err < 0)
5956 return err;
5957
5958 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5959 "Headphone Playback Switch",
5960 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5961 if (err < 0)
5962 return err;
5963
5964 create_hp_imux(spec);
5965 return 0;
5966}
5967
5968/* create playback/capture controls for input pins */
5969static int vt1812_auto_create_analog_input_ctls(struct hda_codec *codec,
5970 const struct auto_pin_cfg *cfg)
5971{
5972 struct via_spec *spec = codec->spec;
5973 struct hda_input_mux *imux = &spec->private_imux[0];
5974 static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff };
5975 int err;
5976
5977 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
5978 ARRAY_SIZE(pin_idxs));
5979 if (err < 0)
5980 return err;
5981
5982 /* build volume/mute control of loopback */
5983 err = via_new_analog_input(spec, "Stereo Mixer", 0, 5, 0x21);
5984 if (err < 0)
5985 return err;
5986
5987 /* for digital mic select */
5988 snd_hda_add_imux_item(imux, "Digital Mic", 6, NULL);
5989
5990 return 0;
5991}
5992
5993static int vt1812_parse_auto_config(struct hda_codec *codec)
5994{
5995 struct via_spec *spec = codec->spec;
5996 int err;
5997
5998
5999 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
6000 if (err < 0)
6001 return err;
6002 fill_dig_outs(codec);
6003 err = vt1812_auto_fill_dac_nids(spec, &spec->autocfg);
6004 if (err < 0)
6005 return err;
6006
6007 if (!spec->autocfg.line_outs && !spec->autocfg.hp_outs)
6008 return 0; /* can't find valid BIOS pin config */
6009
6010 err = vt1812_auto_create_multi_out_ctls(spec, &spec->autocfg);
6011 if (err < 0)
6012 return err;
6013 err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
6014 if (err < 0)
6015 return err;
6016 err = vt1812_auto_create_analog_input_ctls(codec, &spec->autocfg);
6017 if (err < 0)
6018 return err;
6019
6020 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
6021
6022 fill_dig_outs(codec);
6023
6024 if (spec->kctls.list)
6025 spec->mixers[spec->num_mixers++] = spec->kctls.list;
6026
6027 spec->input_mux = &spec->private_imux[0];
6028
6029 if (spec->hp_mux)
6030 via_hp_build(codec);
6031
6032 return 1;
6033}
6034
6035#ifdef CONFIG_SND_HDA_POWER_SAVE
6036static const struct hda_amp_list vt1812_loopbacks[] = {
6037 { 0x21, HDA_INPUT, 0 },
6038 { 0x21, HDA_INPUT, 1 },
6039 { 0x21, HDA_INPUT, 2 },
6040 { } /* end */
6041};
6042#endif
6043
6044static void set_widgets_power_state_vt1812(struct hda_codec *codec) 3688static void set_widgets_power_state_vt1812(struct hda_codec *codec)
6045{ 3689{
6046 struct via_spec *spec = codec->spec; 3690 struct via_spec *spec = codec->spec;
@@ -6144,47 +3788,22 @@ static int patch_vt1812(struct hda_codec *codec)
6144 if (spec == NULL) 3788 if (spec == NULL)
6145 return -ENOMEM; 3789 return -ENOMEM;
6146 3790
3791 spec->aa_mix_nid = 0x21;
3792 override_mic_boost(codec, 0x2b, 0, 3, 40);
3793 override_mic_boost(codec, 0x29, 0, 3, 40);
3794 add_secret_dac_path(codec);
3795
6147 /* automatic parse from the BIOS config */ 3796 /* automatic parse from the BIOS config */
6148 err = vt1812_parse_auto_config(codec); 3797 err = via_parse_auto_config(codec);
6149 if (err < 0) { 3798 if (err < 0) {
6150 via_free(codec); 3799 via_free(codec);
6151 return err; 3800 return err;
6152 } else if (!err) {
6153 printk(KERN_INFO "hda_codec: Cannot set up configuration "
6154 "from BIOS. Using genenic mode...\n");
6155 } 3801 }
6156 3802
6157 3803 spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs;
6158 spec->init_verbs[spec->num_iverbs++] = vt1812_volume_init_verbs;
6159 spec->init_verbs[spec->num_iverbs++] = vt1812_uniwill_init_verbs;
6160
6161 spec->stream_name_analog = "VT1812 Analog";
6162 spec->stream_analog_playback = &vt1812_pcm_analog_playback;
6163 spec->stream_analog_capture = &vt1812_pcm_analog_capture;
6164
6165 spec->stream_name_digital = "VT1812 Digital";
6166 spec->stream_digital_playback = &vt1812_pcm_digital_playback;
6167
6168
6169 if (!spec->adc_nids && spec->input_mux) {
6170 spec->adc_nids = vt1812_adc_nids;
6171 spec->num_adc_nids = ARRAY_SIZE(vt1812_adc_nids);
6172 get_mux_nids(codec);
6173 override_mic_boost(codec, 0x2b, 0, 3, 40);
6174 override_mic_boost(codec, 0x29, 0, 3, 40);
6175 spec->mixers[spec->num_mixers] = vt1812_capture_mixer;
6176 spec->num_mixers++;
6177 }
6178 3804
6179 codec->patch_ops = via_patch_ops; 3805 codec->patch_ops = via_patch_ops;
6180 3806
6181 codec->patch_ops.init = via_auto_init;
6182 codec->patch_ops.unsol_event = via_unsol_event;
6183
6184#ifdef CONFIG_SND_HDA_POWER_SAVE
6185 spec->loopback.amplist = vt1812_loopbacks;
6186#endif
6187
6188 spec->set_widgets_power_state = set_widgets_power_state_vt1812; 3807 spec->set_widgets_power_state = set_widgets_power_state_vt1812;
6189 return 0; 3808 return 0;
6190} 3809}
@@ -6198,37 +3817,37 @@ static const struct hda_codec_preset snd_hda_preset_via[] = {
6198 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708}, 3817 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
6199 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708}, 3818 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
6200 { .id = 0x1106e710, .name = "VT1709 10-Ch", 3819 { .id = 0x1106e710, .name = "VT1709 10-Ch",
6201 .patch = patch_vt1709_10ch}, 3820 .patch = patch_vt1709},
6202 { .id = 0x1106e711, .name = "VT1709 10-Ch", 3821 { .id = 0x1106e711, .name = "VT1709 10-Ch",
6203 .patch = patch_vt1709_10ch}, 3822 .patch = patch_vt1709},
6204 { .id = 0x1106e712, .name = "VT1709 10-Ch", 3823 { .id = 0x1106e712, .name = "VT1709 10-Ch",
6205 .patch = patch_vt1709_10ch}, 3824 .patch = patch_vt1709},
6206 { .id = 0x1106e713, .name = "VT1709 10-Ch", 3825 { .id = 0x1106e713, .name = "VT1709 10-Ch",
6207 .patch = patch_vt1709_10ch}, 3826 .patch = patch_vt1709},
6208 { .id = 0x1106e714, .name = "VT1709 6-Ch", 3827 { .id = 0x1106e714, .name = "VT1709 6-Ch",
6209 .patch = patch_vt1709_6ch}, 3828 .patch = patch_vt1709},
6210 { .id = 0x1106e715, .name = "VT1709 6-Ch", 3829 { .id = 0x1106e715, .name = "VT1709 6-Ch",
6211 .patch = patch_vt1709_6ch}, 3830 .patch = patch_vt1709},
6212 { .id = 0x1106e716, .name = "VT1709 6-Ch", 3831 { .id = 0x1106e716, .name = "VT1709 6-Ch",
6213 .patch = patch_vt1709_6ch}, 3832 .patch = patch_vt1709},
6214 { .id = 0x1106e717, .name = "VT1709 6-Ch", 3833 { .id = 0x1106e717, .name = "VT1709 6-Ch",
6215 .patch = patch_vt1709_6ch}, 3834 .patch = patch_vt1709},
6216 { .id = 0x1106e720, .name = "VT1708B 8-Ch", 3835 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
6217 .patch = patch_vt1708B_8ch}, 3836 .patch = patch_vt1708B},
6218 { .id = 0x1106e721, .name = "VT1708B 8-Ch", 3837 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
6219 .patch = patch_vt1708B_8ch}, 3838 .patch = patch_vt1708B},
6220 { .id = 0x1106e722, .name = "VT1708B 8-Ch", 3839 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
6221 .patch = patch_vt1708B_8ch}, 3840 .patch = patch_vt1708B},
6222 { .id = 0x1106e723, .name = "VT1708B 8-Ch", 3841 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
6223 .patch = patch_vt1708B_8ch}, 3842 .patch = patch_vt1708B},
6224 { .id = 0x1106e724, .name = "VT1708B 4-Ch", 3843 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
6225 .patch = patch_vt1708B_4ch}, 3844 .patch = patch_vt1708B},
6226 { .id = 0x1106e725, .name = "VT1708B 4-Ch", 3845 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
6227 .patch = patch_vt1708B_4ch}, 3846 .patch = patch_vt1708B},
6228 { .id = 0x1106e726, .name = "VT1708B 4-Ch", 3847 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
6229 .patch = patch_vt1708B_4ch}, 3848 .patch = patch_vt1708B},
6230 { .id = 0x1106e727, .name = "VT1708B 4-Ch", 3849 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
6231 .patch = patch_vt1708B_4ch}, 3850 .patch = patch_vt1708B},
6232 { .id = 0x11060397, .name = "VT1708S", 3851 { .id = 0x11060397, .name = "VT1708S",
6233 .patch = patch_vt1708S}, 3852 .patch = patch_vt1708S},
6234 { .id = 0x11061397, .name = "VT1708S", 3853 { .id = 0x11061397, .name = "VT1708S",
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index f4594d76b6e..be06fb3e45a 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2607,7 +2607,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
2607 ice->profi_port = pci_resource_start(pci, 3); 2607 ice->profi_port = pci_resource_start(pci, 3);
2608 2608
2609 if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED, 2609 if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED,
2610 "ICE1712", ice)) { 2610 KBUILD_MODNAME, ice)) {
2611 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 2611 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2612 snd_ice1712_free(ice); 2612 snd_ice1712_free(ice);
2613 return -EIO; 2613 return -EIO;
@@ -2802,7 +2802,7 @@ static void __devexit snd_ice1712_remove(struct pci_dev *pci)
2802} 2802}
2803 2803
2804static struct pci_driver driver = { 2804static struct pci_driver driver = {
2805 .name = "ICE1712", 2805 .name = KBUILD_MODNAME,
2806 .id_table = snd_ice1712_ids, 2806 .id_table = snd_ice1712_ids,
2807 .probe = snd_ice1712_probe, 2807 .probe = snd_ice1712_probe,
2808 .remove = __devexit_p(snd_ice1712_remove), 2808 .remove = __devexit_p(snd_ice1712_remove),
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index c1498fa5545..c2b7f8bc41e 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2509,7 +2509,7 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2509 ice->profi_port = pci_resource_start(pci, 1); 2509 ice->profi_port = pci_resource_start(pci, 1);
2510 2510
2511 if (request_irq(pci->irq, snd_vt1724_interrupt, 2511 if (request_irq(pci->irq, snd_vt1724_interrupt,
2512 IRQF_SHARED, "ICE1724", ice)) { 2512 IRQF_SHARED, KBUILD_MODNAME, ice)) {
2513 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 2513 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2514 snd_vt1724_free(ice); 2514 snd_vt1724_free(ice);
2515 return -EIO; 2515 return -EIO;
@@ -2802,7 +2802,7 @@ static int snd_vt1724_resume(struct pci_dev *pci)
2802#endif 2802#endif
2803 2803
2804static struct pci_driver driver = { 2804static struct pci_driver driver = {
2805 .name = "ICE1724", 2805 .name = KBUILD_MODNAME,
2806 .id_table = snd_vt1724_ids, 2806 .id_table = snd_vt1724_ids,
2807 .probe = snd_vt1724_probe, 2807 .probe = snd_vt1724_probe,
2808 .remove = __devexit_p(snd_vt1724_remove), 2808 .remove = __devexit_p(snd_vt1724_remove),
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 6c896dbfd79..6a5b387b97f 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1884,6 +1884,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1884 }, 1884 },
1885 { 1885 {
1886 .subvendor = 0x1028, 1886 .subvendor = 0x1028,
1887 .subdevice = 0x0189,
1888 .name = "Dell Inspiron 9300",
1889 .type = AC97_TUNE_HP_MUTE_LED
1890 },
1891 {
1892 .subvendor = 0x1028,
1887 .subdevice = 0x0191, 1893 .subdevice = 0x0191,
1888 .name = "Dell Inspiron 8600", 1894 .name = "Dell Inspiron 8600",
1889 .type = AC97_TUNE_HP_ONLY 1895 .type = AC97_TUNE_HP_ONLY
@@ -2647,7 +2653,7 @@ static int intel8x0_resume(struct pci_dev *pci)
2647 pci_set_master(pci); 2653 pci_set_master(pci);
2648 snd_intel8x0_chip_init(chip, 0); 2654 snd_intel8x0_chip_init(chip, 0);
2649 if (request_irq(pci->irq, snd_intel8x0_interrupt, 2655 if (request_irq(pci->irq, snd_intel8x0_interrupt,
2650 IRQF_SHARED, card->shortname, chip)) { 2656 IRQF_SHARED, KBUILD_MODNAME, chip)) {
2651 printk(KERN_ERR "intel8x0: unable to grab IRQ %d, " 2657 printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
2652 "disabling device\n", pci->irq); 2658 "disabling device\n", pci->irq);
2653 snd_card_disconnect(card); 2659 snd_card_disconnect(card);
@@ -3106,7 +3112,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
3106 3112
3107 /* request irq after initializaing int_sta_mask, etc */ 3113 /* request irq after initializaing int_sta_mask, etc */
3108 if (request_irq(pci->irq, snd_intel8x0_interrupt, 3114 if (request_irq(pci->irq, snd_intel8x0_interrupt,
3109 IRQF_SHARED, card->shortname, chip)) { 3115 IRQF_SHARED, KBUILD_MODNAME, chip)) {
3110 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 3116 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
3111 snd_intel8x0_free(chip); 3117 snd_intel8x0_free(chip);
3112 return -EBUSY; 3118 return -EBUSY;
@@ -3266,7 +3272,7 @@ static void __devexit snd_intel8x0_remove(struct pci_dev *pci)
3266} 3272}
3267 3273
3268static struct pci_driver driver = { 3274static struct pci_driver driver = {
3269 .name = "Intel ICH", 3275 .name = KBUILD_MODNAME,
3270 .id_table = snd_intel8x0_ids, 3276 .id_table = snd_intel8x0_ids,
3271 .probe = snd_intel8x0_probe, 3277 .probe = snd_intel8x0_probe,
3272 .remove = __devexit_p(snd_intel8x0_remove), 3278 .remove = __devexit_p(snd_intel8x0_remove),
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index f3353b49c78..7c161645d86 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1047,7 +1047,7 @@ static int intel8x0m_resume(struct pci_dev *pci)
1047 } 1047 }
1048 pci_set_master(pci); 1048 pci_set_master(pci);
1049 if (request_irq(pci->irq, snd_intel8x0m_interrupt, 1049 if (request_irq(pci->irq, snd_intel8x0m_interrupt,
1050 IRQF_SHARED, card->shortname, chip)) { 1050 IRQF_SHARED, KBUILD_MODNAME, chip)) {
1051 printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, " 1051 printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
1052 "disabling device\n", pci->irq); 1052 "disabling device\n", pci->irq);
1053 snd_card_disconnect(card); 1053 snd_card_disconnect(card);
@@ -1174,7 +1174,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1174 1174
1175 port_inited: 1175 port_inited:
1176 if (request_irq(pci->irq, snd_intel8x0m_interrupt, IRQF_SHARED, 1176 if (request_irq(pci->irq, snd_intel8x0m_interrupt, IRQF_SHARED,
1177 card->shortname, chip)) { 1177 KBUILD_MODNAME, chip)) {
1178 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1178 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1179 snd_intel8x0m_free(chip); 1179 snd_intel8x0m_free(chip);
1180 return -EBUSY; 1180 return -EBUSY;
@@ -1325,7 +1325,7 @@ static void __devexit snd_intel8x0m_remove(struct pci_dev *pci)
1325} 1325}
1326 1326
1327static struct pci_driver driver = { 1327static struct pci_driver driver = {
1328 .name = "Intel ICH Modem", 1328 .name = KBUILD_MODNAME,
1329 .id_table = snd_intel8x0m_ids, 1329 .id_table = snd_intel8x0m_ids,
1330 .probe = snd_intel8x0m_probe, 1330 .probe = snd_intel8x0m_probe,
1331 .remove = __devexit_p(snd_intel8x0m_remove), 1331 .remove = __devexit_p(snd_intel8x0m_remove),
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 6d795700be7..fc1d573cf30 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2241,7 +2241,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
2241 2241
2242 err = request_irq(pci->irq, snd_korg1212_interrupt, 2242 err = request_irq(pci->irq, snd_korg1212_interrupt,
2243 IRQF_SHARED, 2243 IRQF_SHARED,
2244 "korg1212", korg1212); 2244 KBUILD_MODNAME, korg1212);
2245 2245
2246 if (err) { 2246 if (err) {
2247 snd_printk(KERN_ERR "korg1212: unable to grab IRQ %d\n", pci->irq); 2247 snd_printk(KERN_ERR "korg1212: unable to grab IRQ %d\n", pci->irq);
@@ -2477,7 +2477,7 @@ static void __devexit snd_korg1212_remove(struct pci_dev *pci)
2477} 2477}
2478 2478
2479static struct pci_driver driver = { 2479static struct pci_driver driver = {
2480 .name = "korg1212", 2480 .name = KBUILD_MODNAME,
2481 .id_table = snd_korg1212_ids, 2481 .id_table = snd_korg1212_ids,
2482 .probe = snd_korg1212_probe, 2482 .probe = snd_korg1212_probe,
2483 .remove = __devexit_p(snd_korg1212_remove), 2483 .remove = __devexit_p(snd_korg1212_remove),
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c
index 34b24286d27..3e92e5b5ec3 100644
--- a/sound/pci/lola/lola.c
+++ b/sound/pci/lola/lola.c
@@ -445,7 +445,7 @@ static void lola_reset_setups(struct lola *chip)
445 lola_setup_all_analog_gains(chip, PLAY, false); /* output, update */ 445 lola_setup_all_analog_gains(chip, PLAY, false); /* output, update */
446} 446}
447 447
448static int lola_parse_tree(struct lola *chip) 448static int __devinit lola_parse_tree(struct lola *chip)
449{ 449{
450 unsigned int val; 450 unsigned int val;
451 int nid, err; 451 int nid, err;
@@ -648,7 +648,7 @@ static int __devinit lola_create(struct snd_card *card, struct pci_dev *pci,
648 goto errout; 648 goto errout;
649 649
650 if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED, 650 if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED,
651 DRVNAME, chip)) { 651 KBUILD_MODNAME, chip)) {
652 printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq); 652 printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
653 err = -EBUSY; 653 err = -EBUSY;
654 goto errout; 654 goto errout;
@@ -771,7 +771,7 @@ MODULE_DEVICE_TABLE(pci, lola_ids);
771 771
772/* pci_driver definition */ 772/* pci_driver definition */
773static struct pci_driver driver = { 773static struct pci_driver driver = {
774 .name = DRVNAME, 774 .name = KBUILD_MODNAME,
775 .id_table = lola_ids, 775 .id_table = lola_ids,
776 .probe = lola_probe, 776 .probe = lola_probe,
777 .remove = __devexit_p(lola_remove), 777 .remove = __devexit_p(lola_remove),
diff --git a/sound/pci/lola/lola.h b/sound/pci/lola/lola.h
index d5708e29b16..f0b100059ef 100644
--- a/sound/pci/lola/lola.h
+++ b/sound/pci/lola/lola.h
@@ -480,7 +480,7 @@ struct lola {
480 480
481/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */ 481/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
482#define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res) ((res >> 2) & 0x1f) 482#define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res) ((res >> 2) & 0x1f)
483#define LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(res) ((res >> 7) & 0x1f) 483#define LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(res) ((res >> 7) & 0x1f)
484 484
485int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb, 485int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
486 unsigned int data, unsigned int extdata); 486 unsigned int data, unsigned int extdata);
diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c
index 5d518f1a712..6b8d6481295 100644
--- a/sound/pci/lola/lola_mixer.c
+++ b/sound/pci/lola/lola_mixer.c
@@ -144,40 +144,61 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
144 chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams; 144 chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
145 chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins; 145 chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
146 146
147 /* mixer matrix can have unused areas between PhysIn and 147 /* mixer matrix may have unused areas between PhysIn and
148 * Play or Record and PhysOut zones 148 * Play or Record and PhysOut zones
149 */ 149 */
150 chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins + 150 chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
151 LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val); 151 LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
152 chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins + 152 chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
153 LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(val); 153 LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);
154 154
155 /* example : MixerMatrix of LoLa881 155 /* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
156 * 0-------8------16-------8------16 156 * +-+ 0-------8------16-------8------16
157 * | | | | | 157 * | | | | | | |
158 * | INPUT | | INPUT | | 158 * |s| | INPUT | | INPUT | |
159 * | -> |unused | -> |unused | 159 * | |->| -> |unused | -> |unused |
160 * | RECORD| | OUTPUT| | 160 * |r| |CAPTURE| | OUTPUT| |
161 * | | | | | 161 * | | | MIX | | MIX | |
162 * 8-------------------------------- 162 * |c| 8--------------------------------
163 * | | | | | 163 * | | | | | | |
164 * | | | | | 164 * | | | | | | |
165 * |unused |unused |unused |unused | 165 * |g| |unused |unused |unused |unused |
166 * | | | | | 166 * | | | | | | |
167 * | | | | | 167 * |a| | | | | |
168 * 16------------------------------- 168 * | | 16-------------------------------
169 * | | | | | 169 * |i| | | | | |
170 * | PLAY | | PLAY | | 170 * | | | PLAYBK| | PLAYBK| |
171 * | -> |unused | -> |unused | 171 * |n|->| -> |unused | -> |unused |
172 * | RECORD| | OUTPUT| | 172 * | | |CAPTURE| | OUTPUT| |
173 * | | | | | 173 * | | | MIX | | MIX | |
174 * 8-------------------------------- 174 * |a| 8--------------------------------
175 * | | | | | 175 * |r| | | | | |
176 * | | | | | 176 * |r| | | | | |
177 * |unused |unused |unused |unused | 177 * |a| |unused |unused |unused |unused |
178 * | | | | | 178 * |y| | | | | |
179 * | | | | | 179 * | | | | | | |
180 * 16------------------------------- 180 * +++ 16--|---------------|------------
181 * +---V---------------V-----------+
182 * | dest_mix_gain_enable array |
183 * +-------------------------------+
184 */
185 /* example : MixerMatrix of LoLa280
186 * +-+ 0-------8-2
187 * | | | | |
188 * |s| | INPUT | | INPUT
189 * |r|->| -> | | ->
190 * |c| |CAPTURE| | <- OUTPUT
191 * | | | MIX | | MIX
192 * |g| 8----------
193 * |a| | | |
194 * |i| | PLAYBK| | PLAYBACK
195 * |n|->| -> | | ->
196 * | | |CAPTURE| | <- OUTPUT
197 * |a| | MIX | | MIX
198 * |r| 8---|----|-
199 * |r| +---V----V-------------------+
200 * |a| | dest_mix_gain_enable array |
201 * |y| +----------------------------+
181 */ 202 */
182 if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT || 203 if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
183 chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) { 204 chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
@@ -192,6 +213,9 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
192 (((1U << chip->mixer.dest_phys_outs) - 1) 213 (((1U << chip->mixer.dest_phys_outs) - 1)
193 << chip->mixer.dest_phys_out_ofs); 214 << chip->mixer.dest_phys_out_ofs);
194 215
216 snd_printdd("Mixer src_mask=%x, dest_mask=%x\n",
217 chip->mixer.src_mask, chip->mixer.dest_mask);
218
195 return 0; 219 return 0;
196} 220}
197 221
@@ -202,12 +226,19 @@ static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
202 226
203 if (!(chip->mixer.src_mask & (1 << id))) 227 if (!(chip->mixer.src_mask & (1 << id)))
204 return -EINVAL; 228 return -EINVAL;
205 writew(gain, &chip->mixer.array->src_gain[id]);
206 oldval = val = readl(&chip->mixer.array->src_gain_enable); 229 oldval = val = readl(&chip->mixer.array->src_gain_enable);
207 if (on) 230 if (on)
208 val |= (1 << id); 231 val |= (1 << id);
209 else 232 else
210 val &= ~(1 << id); 233 val &= ~(1 << id);
234 /* test if values unchanged */
235 if ((val == oldval) &&
236 (gain == readw(&chip->mixer.array->src_gain[id])))
237 return 0;
238
239 snd_printdd("lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
240 id, gain, val);
241 writew(gain, &chip->mixer.array->src_gain[id]);
211 writel(val, &chip->mixer.array->src_gain_enable); 242 writel(val, &chip->mixer.array->src_gain_enable);
212 lola_codec_flush(chip); 243 lola_codec_flush(chip);
213 /* inform micro-controller about the new source gain */ 244 /* inform micro-controller about the new source gain */
@@ -269,6 +300,7 @@ static int lola_mixer_set_mapping_gain(struct lola *chip,
269 src, dest); 300 src, dest);
270} 301}
271 302
303#if 0 /* not used */
272static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id, 304static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
273 unsigned int mask, unsigned short *gains) 305 unsigned int mask, unsigned short *gains)
274{ 306{
@@ -289,6 +321,7 @@ static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
289 return lola_codec_write(chip, chip->mixer.nid, 321 return lola_codec_write(chip, chip->mixer.nid,
290 LOLA_VERB_SET_DESTINATION_GAIN, id, 0); 322 LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
291} 323}
324#endif /* not used */
292 325
293/* 326/*
294 */ 327 */
@@ -376,6 +409,8 @@ static int set_analog_volume(struct lola *chip, int dir,
376 return 0; 409 return 0;
377 if (external_call) 410 if (external_call)
378 lola_codec_flush(chip); 411 lola_codec_flush(chip);
412 snd_printdd("set_analog_volume (dir=%d idx=%d, volume=%d)\n",
413 dir, idx, val);
379 err = lola_codec_write(chip, pin->nid, 414 err = lola_codec_write(chip, pin->nid,
380 LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0); 415 LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
381 if (err < 0) 416 if (err < 0)
@@ -427,23 +462,40 @@ static int init_mixer_values(struct lola *chip)
427{ 462{
428 int i; 463 int i;
429 464
430 /* all src on */ 465 /* all sample rate converters on */
431 lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false); 466 lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
432 467
433 /* clear all matrix */ 468 /* clear all mixer matrix settings */
434 memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array)); 469 memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
435 /* set src gain to 0dB */ 470 /* inform firmware about all updated matrix columns - capture part */
471 for (i = 0; i < chip->mixer.dest_stream_ins; i++)
472 lola_codec_write(chip, chip->mixer.nid,
473 LOLA_VERB_SET_DESTINATION_GAIN,
474 i, 0);
475 /* inform firmware about all updated matrix columns - output part */
476 for (i = 0; i < chip->mixer.dest_phys_outs; i++)
477 lola_codec_write(chip, chip->mixer.nid,
478 LOLA_VERB_SET_DESTINATION_GAIN,
479 chip->mixer.dest_phys_out_ofs + i, 0);
480
481 /* set all digital input source (master) gains to 0dB */
436 for (i = 0; i < chip->mixer.src_phys_ins; i++) 482 for (i = 0; i < chip->mixer.src_phys_ins; i++)
437 lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */ 483 lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
484
485 /* set all digital playback source (master) gains to 0dB */
438 for (i = 0; i < chip->mixer.src_stream_outs; i++) 486 for (i = 0; i < chip->mixer.src_stream_outs; i++)
439 lola_mixer_set_src_gain(chip, 487 lola_mixer_set_src_gain(chip,
440 i + chip->mixer.src_stream_out_ofs, 488 i + chip->mixer.src_stream_out_ofs,
441 336, true); /* 0dB */ 489 336, true); /* 0dB */
442 /* set 1:1 dest gain */ 490 /* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
443 for (i = 0; i < chip->mixer.dest_stream_ins; i++) { 491 for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
444 int src = i % chip->mixer.src_phys_ins; 492 int src = i % chip->mixer.src_phys_ins;
445 lola_mixer_set_mapping_gain(chip, src, i, 336, true); 493 lola_mixer_set_mapping_gain(chip, src, i, 336, true);
446 } 494 }
495 /* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
496 * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
497 * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
498 */
447 for (i = 0; i < chip->mixer.src_stream_outs; i++) { 499 for (i = 0; i < chip->mixer.src_stream_outs; i++) {
448 int src = chip->mixer.src_stream_out_ofs + i; 500 int src = chip->mixer.src_stream_out_ofs + i;
449 int dst = chip->mixer.dest_phys_out_ofs + 501 int dst = chip->mixer.dest_phys_out_ofs +
@@ -693,6 +745,7 @@ static int __devinit create_src_gain_mixer(struct lola *chip,
693 snd_ctl_new1(&lola_src_gain_mixer, chip)); 745 snd_ctl_new1(&lola_src_gain_mixer, chip));
694} 746}
695 747
748#if 0 /* not used */
696/* 749/*
697 * destination gain (matrix-like) mixer 750 * destination gain (matrix-like) mixer
698 */ 751 */
@@ -781,6 +834,7 @@ static int __devinit create_dest_gain_mixer(struct lola *chip,
781 return snd_ctl_add(chip->card, 834 return snd_ctl_add(chip->card,
782 snd_ctl_new1(&lola_dest_gain_mixer, chip)); 835 snd_ctl_new1(&lola_dest_gain_mixer, chip));
783} 836}
837#endif /* not used */
784 838
785/* 839/*
786 */ 840 */
@@ -798,14 +852,16 @@ int __devinit lola_create_mixer(struct lola *chip)
798 if (err < 0) 852 if (err < 0)
799 return err; 853 return err;
800 err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0, 854 err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
801 "Line Source Gain Volume"); 855 "Digital Capture Volume");
802 if (err < 0) 856 if (err < 0)
803 return err; 857 return err;
804 err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs, 858 err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
805 chip->mixer.src_stream_out_ofs, 859 chip->mixer.src_stream_out_ofs,
806 "Stream Source Gain Volume"); 860 "Digital Playback Volume");
807 if (err < 0) 861 if (err < 0)
808 return err; 862 return err;
863#if 0
864/* FIXME: buggy mixer matrix handling */
809 err = create_dest_gain_mixer(chip, 865 err = create_dest_gain_mixer(chip,
810 chip->mixer.src_phys_ins, 0, 866 chip->mixer.src_phys_ins, 0,
811 chip->mixer.dest_stream_ins, 0, 867 chip->mixer.dest_stream_ins, 0,
@@ -834,6 +890,6 @@ int __devinit lola_create_mixer(struct lola *chip)
834 "Stream Playback Volume"); 890 "Stream Playback Volume");
835 if (err < 0) 891 if (err < 0)
836 return err; 892 return err;
837 893#endif /* FIXME */
838 return init_mixer_values(chip); 894 return init_mixer_values(chip);
839} 895}
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 1bd7a540fd4..04ae84b2a10 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -762,7 +762,6 @@ static int lx_set_granularity(struct lx6464es *chip, u32 gran)
762static int __devinit lx_init_dsp(struct lx6464es *chip) 762static int __devinit lx_init_dsp(struct lx6464es *chip)
763{ 763{
764 int err; 764 int err;
765 u8 mac_address[6];
766 int i; 765 int i;
767 766
768 snd_printdd("->lx_init_dsp\n"); 767 snd_printdd("->lx_init_dsp\n");
@@ -787,11 +786,11 @@ static int __devinit lx_init_dsp(struct lx6464es *chip)
787 /** \todo the mac address should be ready by not, but it isn't, 786 /** \todo the mac address should be ready by not, but it isn't,
788 * so we wait for it */ 787 * so we wait for it */
789 for (i = 0; i != 1000; ++i) { 788 for (i = 0; i != 1000; ++i) {
790 err = lx_dsp_get_mac(chip, mac_address); 789 err = lx_dsp_get_mac(chip);
791 if (err) 790 if (err)
792 return err; 791 return err;
793 if (mac_address[0] || mac_address[1] || mac_address[2] || 792 if (chip->mac_address[0] || chip->mac_address[1] || chip->mac_address[2] ||
794 mac_address[3] || mac_address[4] || mac_address[5]) 793 chip->mac_address[3] || chip->mac_address[4] || chip->mac_address[5])
795 goto mac_ready; 794 goto mac_ready;
796 msleep(1); 795 msleep(1);
797 } 796 }
@@ -800,8 +799,8 @@ static int __devinit lx_init_dsp(struct lx6464es *chip)
800mac_ready: 799mac_ready:
801 snd_printd(LXP "mac address ready read after: %dms\n", i); 800 snd_printd(LXP "mac address ready read after: %dms\n", i);
802 snd_printk(LXP "mac address: %02X.%02X.%02X.%02X.%02X.%02X\n", 801 snd_printk(LXP "mac address: %02X.%02X.%02X.%02X.%02X.%02X\n",
803 mac_address[0], mac_address[1], mac_address[2], 802 chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
804 mac_address[3], mac_address[4], mac_address[5]); 803 chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
805 804
806 err = lx_init_get_version_features(chip); 805 err = lx_init_get_version_features(chip);
807 if (err) 806 if (err)
@@ -1031,7 +1030,7 @@ static int __devinit snd_lx6464es_create(struct snd_card *card,
1031 chip->port_dsp_bar = pci_ioremap_bar(pci, 2); 1030 chip->port_dsp_bar = pci_ioremap_bar(pci, 2);
1032 1031
1033 err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED, 1032 err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED,
1034 card_name, chip); 1033 KBUILD_MODNAME, chip);
1035 if (err) { 1034 if (err) {
1036 snd_printk(KERN_ERR LXP "unable to grab IRQ %d\n", pci->irq); 1035 snd_printk(KERN_ERR LXP "unable to grab IRQ %d\n", pci->irq);
1037 goto request_irq_failed; 1036 goto request_irq_failed;
@@ -1108,8 +1107,14 @@ static int __devinit snd_lx6464es_probe(struct pci_dev *pci,
1108 goto out_free; 1107 goto out_free;
1109 } 1108 }
1110 1109
1111 strcpy(card->driver, "lx6464es"); 1110 strcpy(card->driver, "LX6464ES");
1112 strcpy(card->shortname, "Digigram LX6464ES"); 1111 sprintf(card->id, "LX6464ES_%02X%02X%02X",
1112 chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
1113
1114 sprintf(card->shortname, "LX6464ES %02X.%02X.%02X.%02X.%02X.%02X",
1115 chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
1116 chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
1117
1113 sprintf(card->longname, "%s at 0x%lx, 0x%p, irq %i", 1118 sprintf(card->longname, "%s at 0x%lx, 0x%p, irq %i",
1114 card->shortname, chip->port_plx, 1119 card->shortname, chip->port_plx,
1115 chip->port_dsp_bar, chip->irq); 1120 chip->port_dsp_bar, chip->irq);
@@ -1137,7 +1142,7 @@ static void __devexit snd_lx6464es_remove(struct pci_dev *pci)
1137 1142
1138 1143
1139static struct pci_driver driver = { 1144static struct pci_driver driver = {
1140 .name = "Digigram LX6464ES", 1145 .name = KBUILD_MODNAME,
1141 .id_table = snd_lx6464es_ids, 1146 .id_table = snd_lx6464es_ids,
1142 .probe = snd_lx6464es_probe, 1147 .probe = snd_lx6464es_probe,
1143 .remove = __devexit_p(snd_lx6464es_remove), 1148 .remove = __devexit_p(snd_lx6464es_remove),
diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h
index aea621eafbb..e2a124ae27e 100644
--- a/sound/pci/lx6464es/lx6464es.h
+++ b/sound/pci/lx6464es/lx6464es.h
@@ -69,6 +69,8 @@ struct lx6464es {
69 struct pci_dev *pci; 69 struct pci_dev *pci;
70 int irq; 70 int irq;
71 71
72 u8 mac_address[6];
73
72 spinlock_t lock; /* interrupt spinlock */ 74 spinlock_t lock; /* interrupt spinlock */
73 struct mutex setup_mutex; /* mutex used in hw_params, open 75 struct mutex setup_mutex; /* mutex used in hw_params, open
74 * and close */ 76 * and close */
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c
index 617f98b0cba..5c8717e29ee 100644
--- a/sound/pci/lx6464es/lx_core.c
+++ b/sound/pci/lx6464es/lx_core.c
@@ -424,7 +424,7 @@ int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq)
424 return ret; 424 return ret;
425} 425}
426 426
427int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address) 427int lx_dsp_get_mac(struct lx6464es *chip)
428{ 428{
429 u32 macmsb, maclsb; 429 u32 macmsb, maclsb;
430 430
@@ -432,12 +432,12 @@ int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address)
432 maclsb = lx_dsp_reg_read(chip, eReg_ADMACESLSB) & 0x00FFFFFF; 432 maclsb = lx_dsp_reg_read(chip, eReg_ADMACESLSB) & 0x00FFFFFF;
433 433
434 /* todo: endianess handling */ 434 /* todo: endianess handling */
435 mac_address[5] = ((u8 *)(&maclsb))[0]; 435 chip->mac_address[5] = ((u8 *)(&maclsb))[0];
436 mac_address[4] = ((u8 *)(&maclsb))[1]; 436 chip->mac_address[4] = ((u8 *)(&maclsb))[1];
437 mac_address[3] = ((u8 *)(&maclsb))[2]; 437 chip->mac_address[3] = ((u8 *)(&maclsb))[2];
438 mac_address[2] = ((u8 *)(&macmsb))[0]; 438 chip->mac_address[2] = ((u8 *)(&macmsb))[0];
439 mac_address[1] = ((u8 *)(&macmsb))[1]; 439 chip->mac_address[1] = ((u8 *)(&macmsb))[1];
440 mac_address[0] = ((u8 *)(&macmsb))[2]; 440 chip->mac_address[0] = ((u8 *)(&macmsb))[2];
441 441
442 return 0; 442 return 0;
443} 443}
diff --git a/sound/pci/lx6464es/lx_core.h b/sound/pci/lx6464es/lx_core.h
index 6bd9cbbbc68..1dd562980b6 100644
--- a/sound/pci/lx6464es/lx_core.h
+++ b/sound/pci/lx6464es/lx_core.h
@@ -116,7 +116,7 @@ int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version);
116int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq); 116int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq);
117int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran); 117int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran);
118int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data); 118int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data);
119int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address); 119int lx_dsp_get_mac(struct lx6464es *chip);
120 120
121 121
122/* low-level pipe handling */ 122/* low-level pipe handling */
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 3c40d726b46..0378126e627 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -850,11 +850,10 @@ struct snd_m3 {
850 struct input_dev *input_dev; 850 struct input_dev *input_dev;
851 char phys[64]; /* physical device path */ 851 char phys[64]; /* physical device path */
852#else 852#else
853 spinlock_t ac97_lock;
854 struct snd_kcontrol *master_switch; 853 struct snd_kcontrol *master_switch;
855 struct snd_kcontrol *master_volume; 854 struct snd_kcontrol *master_volume;
856 struct tasklet_struct hwvol_tq;
857#endif 855#endif
856 struct work_struct hwvol_work;
858 857
859 unsigned int in_suspend; 858 unsigned int in_suspend;
860 859
@@ -1609,13 +1608,10 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
1609 (without wrap around) in response to volume button presses and then 1608 (without wrap around) in response to volume button presses and then
1610 generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7 1609 generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
1611 of a byte wide register. The meaning of bits 0 and 4 is unknown. */ 1610 of a byte wide register. The meaning of bits 0 and 4 is unknown. */
1612static void snd_m3_update_hw_volume(unsigned long private_data) 1611static void snd_m3_update_hw_volume(struct work_struct *work)
1613{ 1612{
1614 struct snd_m3 *chip = (struct snd_m3 *) private_data; 1613 struct snd_m3 *chip = container_of(work, struct snd_m3, hwvol_work);
1615 int x, val; 1614 int x, val;
1616#ifndef CONFIG_SND_MAESTRO3_INPUT
1617 unsigned long flags;
1618#endif
1619 1615
1620 /* Figure out which volume control button was pushed, 1616 /* Figure out which volume control button was pushed,
1621 based on differences from the default register 1617 based on differences from the default register
@@ -1645,21 +1641,13 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1645 if (!chip->master_switch || !chip->master_volume) 1641 if (!chip->master_switch || !chip->master_volume)
1646 return; 1642 return;
1647 1643
1648 /* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */ 1644 val = snd_ac97_read(chip->ac97, AC97_MASTER);
1649 spin_lock_irqsave(&chip->ac97_lock, flags);
1650
1651 val = chip->ac97->regs[AC97_MASTER_VOL];
1652 switch (x) { 1645 switch (x) {
1653 case 0x88: 1646 case 0x88:
1654 /* The counters have not changed, yet we've received a HV 1647 /* The counters have not changed, yet we've received a HV
1655 interrupt. According to tests run by various people this 1648 interrupt. According to tests run by various people this
1656 happens when pressing the mute button. */ 1649 happens when pressing the mute button. */
1657 val ^= 0x8000; 1650 val ^= 0x8000;
1658 chip->ac97->regs[AC97_MASTER_VOL] = val;
1659 outw(val, chip->iobase + CODEC_DATA);
1660 outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
1661 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1662 &chip->master_switch->id);
1663 break; 1651 break;
1664 case 0xaa: 1652 case 0xaa:
1665 /* counters increased by 1 -> volume up */ 1653 /* counters increased by 1 -> volume up */
@@ -1667,11 +1655,6 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1667 val--; 1655 val--;
1668 if ((val & 0x7f00) > 0) 1656 if ((val & 0x7f00) > 0)
1669 val -= 0x0100; 1657 val -= 0x0100;
1670 chip->ac97->regs[AC97_MASTER_VOL] = val;
1671 outw(val, chip->iobase + CODEC_DATA);
1672 outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
1673 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1674 &chip->master_volume->id);
1675 break; 1658 break;
1676 case 0x66: 1659 case 0x66:
1677 /* counters decreased by 1 -> volume down */ 1660 /* counters decreased by 1 -> volume down */
@@ -1679,14 +1662,11 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1679 val++; 1662 val++;
1680 if ((val & 0x7f00) < 0x1f00) 1663 if ((val & 0x7f00) < 0x1f00)
1681 val += 0x0100; 1664 val += 0x0100;
1682 chip->ac97->regs[AC97_MASTER_VOL] = val;
1683 outw(val, chip->iobase + CODEC_DATA);
1684 outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
1685 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1686 &chip->master_volume->id);
1687 break; 1665 break;
1688 } 1666 }
1689 spin_unlock_irqrestore(&chip->ac97_lock, flags); 1667 if (snd_ac97_update(chip->ac97, AC97_MASTER, val))
1668 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1669 &chip->master_switch->id);
1690#else 1670#else
1691 if (!chip->input_dev) 1671 if (!chip->input_dev)
1692 return; 1672 return;
@@ -1730,11 +1710,7 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
1730 return IRQ_NONE; 1710 return IRQ_NONE;
1731 1711
1732 if (status & HV_INT_PENDING) 1712 if (status & HV_INT_PENDING)
1733#ifdef CONFIG_SND_MAESTRO3_INPUT 1713 schedule_work(&chip->hwvol_work);
1734 snd_m3_update_hw_volume((unsigned long)chip);
1735#else
1736 tasklet_schedule(&chip->hwvol_tq);
1737#endif
1738 1714
1739 /* 1715 /*
1740 * ack an assp int if its running 1716 * ack an assp int if its running
@@ -2000,24 +1976,14 @@ static unsigned short
2000snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 1976snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
2001{ 1977{
2002 struct snd_m3 *chip = ac97->private_data; 1978 struct snd_m3 *chip = ac97->private_data;
2003#ifndef CONFIG_SND_MAESTRO3_INPUT
2004 unsigned long flags;
2005#endif
2006 unsigned short data = 0xffff; 1979 unsigned short data = 0xffff;
2007 1980
2008 if (snd_m3_ac97_wait(chip)) 1981 if (snd_m3_ac97_wait(chip))
2009 goto fail; 1982 goto fail;
2010#ifndef CONFIG_SND_MAESTRO3_INPUT
2011 spin_lock_irqsave(&chip->ac97_lock, flags);
2012#endif
2013 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); 1983 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
2014 if (snd_m3_ac97_wait(chip)) 1984 if (snd_m3_ac97_wait(chip))
2015 goto fail_unlock; 1985 goto fail;
2016 data = snd_m3_inw(chip, CODEC_DATA); 1986 data = snd_m3_inw(chip, CODEC_DATA);
2017fail_unlock:
2018#ifndef CONFIG_SND_MAESTRO3_INPUT
2019 spin_unlock_irqrestore(&chip->ac97_lock, flags);
2020#endif
2021fail: 1987fail:
2022 return data; 1988 return data;
2023} 1989}
@@ -2026,20 +1992,11 @@ static void
2026snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) 1992snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
2027{ 1993{
2028 struct snd_m3 *chip = ac97->private_data; 1994 struct snd_m3 *chip = ac97->private_data;
2029#ifndef CONFIG_SND_MAESTRO3_INPUT
2030 unsigned long flags;
2031#endif
2032 1995
2033 if (snd_m3_ac97_wait(chip)) 1996 if (snd_m3_ac97_wait(chip))
2034 return; 1997 return;
2035#ifndef CONFIG_SND_MAESTRO3_INPUT
2036 spin_lock_irqsave(&chip->ac97_lock, flags);
2037#endif
2038 snd_m3_outw(chip, val, CODEC_DATA); 1998 snd_m3_outw(chip, val, CODEC_DATA);
2039 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND); 1999 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
2040#ifndef CONFIG_SND_MAESTRO3_INPUT
2041 spin_unlock_irqrestore(&chip->ac97_lock, flags);
2042#endif
2043} 2000}
2044 2001
2045 2002
@@ -2458,6 +2415,7 @@ static int snd_m3_free(struct snd_m3 *chip)
2458 struct m3_dma *s; 2415 struct m3_dma *s;
2459 int i; 2416 int i;
2460 2417
2418 cancel_work_sync(&chip->hwvol_work);
2461#ifdef CONFIG_SND_MAESTRO3_INPUT 2419#ifdef CONFIG_SND_MAESTRO3_INPUT
2462 if (chip->input_dev) 2420 if (chip->input_dev)
2463 input_unregister_device(chip->input_dev); 2421 input_unregister_device(chip->input_dev);
@@ -2511,6 +2469,7 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
2511 return 0; 2469 return 0;
2512 2470
2513 chip->in_suspend = 1; 2471 chip->in_suspend = 1;
2472 cancel_work_sync(&chip->hwvol_work);
2514 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2473 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2515 snd_pcm_suspend_all(chip->pcm); 2474 snd_pcm_suspend_all(chip->pcm);
2516 snd_ac97_suspend(chip->ac97); 2475 snd_ac97_suspend(chip->ac97);
@@ -2667,9 +2626,6 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2667 } 2626 }
2668 2627
2669 spin_lock_init(&chip->reg_lock); 2628 spin_lock_init(&chip->reg_lock);
2670#ifndef CONFIG_SND_MAESTRO3_INPUT
2671 spin_lock_init(&chip->ac97_lock);
2672#endif
2673 2629
2674 switch (pci->device) { 2630 switch (pci->device) {
2675 case PCI_DEVICE_ID_ESS_ALLEGRO: 2631 case PCI_DEVICE_ID_ESS_ALLEGRO:
@@ -2683,6 +2639,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2683 chip->card = card; 2639 chip->card = card;
2684 chip->pci = pci; 2640 chip->pci = pci;
2685 chip->irq = -1; 2641 chip->irq = -1;
2642 INIT_WORK(&chip->hwvol_work, snd_m3_update_hw_volume);
2686 2643
2687 chip->external_amp = enable_amp; 2644 chip->external_amp = enable_amp;
2688 if (amp_gpio >= 0 && amp_gpio <= 0x0f) 2645 if (amp_gpio >= 0 && amp_gpio <= 0x0f)
@@ -2752,12 +2709,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2752 2709
2753 snd_m3_hv_init(chip); 2710 snd_m3_hv_init(chip);
2754 2711
2755#ifndef CONFIG_SND_MAESTRO3_INPUT
2756 tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
2757#endif
2758
2759 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, 2712 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
2760 card->driver, chip)) { 2713 KBUILD_MODNAME, chip)) {
2761 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 2714 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2762 snd_m3_free(chip); 2715 snd_m3_free(chip);
2763 return -ENOMEM; 2716 return -ENOMEM;
@@ -2885,7 +2838,7 @@ static void __devexit snd_m3_remove(struct pci_dev *pci)
2885} 2838}
2886 2839
2887static struct pci_driver driver = { 2840static struct pci_driver driver = {
2888 .name = "Maestro3", 2841 .name = KBUILD_MODNAME,
2889 .id_table = snd_m3_ids, 2842 .id_table = snd_m3_ids,
2890 .probe = snd_m3_probe, 2843 .probe = snd_m3_probe,
2891 .remove = __devexit_p(snd_m3_remove), 2844 .remove = __devexit_p(snd_m3_remove),
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 6c3fd4d1c49..dbee59906ae 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1268,7 +1268,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
1268 } 1268 }
1269 1269
1270 if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_SHARED, 1270 if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_SHARED,
1271 CARD_NAME, mgr)) { 1271 KBUILD_MODNAME, mgr)) {
1272 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1272 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1273 snd_mixart_free(mgr); 1273 snd_mixart_free(mgr);
1274 return -EBUSY; 1274 return -EBUSY;
@@ -1381,7 +1381,7 @@ static void __devexit snd_mixart_remove(struct pci_dev *pci)
1381} 1381}
1382 1382
1383static struct pci_driver driver = { 1383static struct pci_driver driver = {
1384 .name = "Digigram miXart", 1384 .name = KBUILD_MODNAME,
1385 .id_table = snd_mixart_ids, 1385 .id_table = snd_mixart_ids,
1386 .probe = snd_mixart_probe, 1386 .probe = snd_mixart_probe,
1387 .remove = __devexit_p(snd_mixart_remove), 1387 .remove = __devexit_p(snd_mixart_remove),
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 5a60492ac7b..83ea7a7d3ee 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -465,7 +465,7 @@ static int snd_nm256_acquire_irq(struct nm256 *chip)
465 mutex_lock(&chip->irq_mutex); 465 mutex_lock(&chip->irq_mutex);
466 if (chip->irq < 0) { 466 if (chip->irq < 0) {
467 if (request_irq(chip->pci->irq, chip->interrupt, IRQF_SHARED, 467 if (request_irq(chip->pci->irq, chip->interrupt, IRQF_SHARED,
468 chip->card->driver, chip)) { 468 KBUILD_MODNAME, chip)) {
469 snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq); 469 snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
470 mutex_unlock(&chip->irq_mutex); 470 mutex_unlock(&chip->irq_mutex);
471 return -EBUSY; 471 return -EBUSY;
@@ -1743,7 +1743,7 @@ static void __devexit snd_nm256_remove(struct pci_dev *pci)
1743 1743
1744 1744
1745static struct pci_driver driver = { 1745static struct pci_driver driver = {
1746 .name = "NeoMagic 256", 1746 .name = KBUILD_MODNAME,
1747 .id_table = snd_nm256_ids, 1747 .id_table = snd_nm256_ids,
1748 .probe = snd_nm256_probe, 1748 .probe = snd_nm256_probe,
1749 .remove = __devexit_p(snd_nm256_remove), 1749 .remove = __devexit_p(snd_nm256_remove),
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index d7e8ddd9a67..218d9854e5c 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -859,7 +859,7 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci,
859} 859}
860 860
861static struct pci_driver oxygen_driver = { 861static struct pci_driver oxygen_driver = {
862 .name = "CMI8788", 862 .name = KBUILD_MODNAME,
863 .id_table = oxygen_ids, 863 .id_table = oxygen_ids,
864 .probe = generic_oxygen_probe, 864 .probe = generic_oxygen_probe,
865 .remove = __devexit_p(oxygen_pci_remove), 865 .remove = __devexit_p(oxygen_pci_remove),
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 70b739816fc..82311fcb86f 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -655,7 +655,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
655 chip->model.init(chip); 655 chip->model.init(chip);
656 656
657 err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED, 657 err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
658 DRIVER, chip); 658 KBUILD_MODNAME, chip);
659 if (err < 0) { 659 if (err < 0) {
660 snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq); 660 snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
661 goto err_card; 661 goto err_card;
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index d5533e34ece..cc0bcd9f335 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -168,12 +168,6 @@ static int oxygen_open(struct snd_pcm_substream *substream,
168 if (err < 0) 168 if (err < 0)
169 return err; 169 return err;
170 } 170 }
171 if (channel == PCM_MULTICH) {
172 err = snd_pcm_hw_constraint_minmax
173 (runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 0, 8192000);
174 if (err < 0)
175 return err;
176 }
177 snd_pcm_set_sync(substream); 171 snd_pcm_set_sync(substream);
178 chip->streams[channel] = substream; 172 chip->streams[channel] = substream;
179 173
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 469010a8b84..773db794b43 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -88,7 +88,7 @@ static int __devinit xonar_probe(struct pci_dev *pci,
88} 88}
89 89
90static struct pci_driver xonar_driver = { 90static struct pci_driver xonar_driver = {
91 .name = "AV200", 91 .name = KBUILD_MODNAME,
92 .id_table = xonar_ids, 92 .id_table = xonar_ids,
93 .probe = xonar_probe, 93 .probe = xonar_probe,
94 .remove = __devexit_p(oxygen_pci_remove), 94 .remove = __devexit_p(oxygen_pci_remove),
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index 54cad38ec30..32d096c98f5 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -327,8 +327,10 @@ static void pcm1796_init(struct oxygen *chip)
327{ 327{
328 struct xonar_pcm179x *data = chip->model_data; 328 struct xonar_pcm179x *data = chip->model_data;
329 329
330 data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE | 330 data->pcm1796_regs[0][18 - PCM1796_REG_BASE] =
331 PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD; 331 PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
332 if (!data->broken_i2c)
333 data->pcm1796_regs[0][18 - PCM1796_REG_BASE] |= PCM1796_MUTE;
332 data->pcm1796_regs[0][19 - PCM1796_REG_BASE] = 334 data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
333 PCM1796_FLT_SHARP | PCM1796_ATS_1; 335 PCM1796_FLT_SHARP | PCM1796_ATS_1;
334 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = 336 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] =
@@ -1123,6 +1125,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1123 chip->model.control_filter = xonar_st_h6_control_filter; 1125 chip->model.control_filter = xonar_st_h6_control_filter;
1124 chip->model.dac_channels_pcm = 8; 1126 chip->model.dac_channels_pcm = 8;
1125 chip->model.dac_channels_mixer = 8; 1127 chip->model.dac_channels_mixer = 8;
1128 chip->model.dac_volume_min = 255;
1126 chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128); 1129 chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
1127 break; 1130 break;
1128 } 1131 }
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 95cfde27d25..046578d26f9 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1501,7 +1501,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci,
1501 mgr->irq = -1; 1501 mgr->irq = -1;
1502 1502
1503 if (request_irq(pci->irq, pcxhr_interrupt, IRQF_SHARED, 1503 if (request_irq(pci->irq, pcxhr_interrupt, IRQF_SHARED,
1504 card_name, mgr)) { 1504 KBUILD_MODNAME, mgr)) {
1505 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1505 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1506 pcxhr_free(mgr); 1506 pcxhr_free(mgr);
1507 return -EBUSY; 1507 return -EBUSY;
@@ -1608,7 +1608,7 @@ static void __devexit pcxhr_remove(struct pci_dev *pci)
1608} 1608}
1609 1609
1610static struct pci_driver driver = { 1610static struct pci_driver driver = {
1611 .name = "Digigram pcxhr", 1611 .name = KBUILD_MODNAME,
1612 .id_table = pcxhr_ids, 1612 .id_table = pcxhr_ids,
1613 .probe = pcxhr_probe, 1613 .probe = pcxhr_probe,
1614 .remove = __devexit_p(pcxhr_remove), 1614 .remove = __devexit_p(pcxhr_remove),
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index ad5202efd7a..e34ae14908b 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1890,7 +1890,7 @@ snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
1890 UNSET_AIE(hwport); 1890 UNSET_AIE(hwport);
1891 1891
1892 if (request_irq(pci->irq, snd_riptide_interrupt, IRQF_SHARED, 1892 if (request_irq(pci->irq, snd_riptide_interrupt, IRQF_SHARED,
1893 "RIPTIDE", chip)) { 1893 KBUILD_MODNAME, chip)) {
1894 snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n", 1894 snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n",
1895 pci->irq); 1895 pci->irq);
1896 snd_riptide_free(chip); 1896 snd_riptide_free(chip);
@@ -2176,7 +2176,7 @@ static void __devexit snd_card_riptide_remove(struct pci_dev *pci)
2176} 2176}
2177 2177
2178static struct pci_driver driver = { 2178static struct pci_driver driver = {
2179 .name = "RIPTIDE", 2179 .name = KBUILD_MODNAME,
2180 .id_table = snd_riptide_ids, 2180 .id_table = snd_riptide_ids,
2181 .probe = snd_card_riptide_probe, 2181 .probe = snd_card_riptide_probe,
2182 .remove = __devexit_p(snd_card_riptide_remove), 2182 .remove = __devexit_p(snd_card_riptide_remove),
@@ -2188,7 +2188,7 @@ static struct pci_driver driver = {
2188 2188
2189#ifdef SUPPORT_JOYSTICK 2189#ifdef SUPPORT_JOYSTICK
2190static struct pci_driver joystick_driver = { 2190static struct pci_driver joystick_driver = {
2191 .name = "Riptide Joystick", 2191 .name = KBUILD_MODNAME "-joystick",
2192 .id_table = snd_riptide_joystick_ids, 2192 .id_table = snd_riptide_joystick_ids,
2193 .probe = snd_riptide_joystick_probe, 2193 .probe = snd_riptide_joystick_probe,
2194 .remove = __devexit_p(snd_riptide_joystick_remove), 2194 .remove = __devexit_p(snd_riptide_joystick_remove),
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 3c04524de37..6be77a264d4 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1355,7 +1355,7 @@ static int __devinit snd_rme32_create(struct rme32 * rme32)
1355 } 1355 }
1356 1356
1357 if (request_irq(pci->irq, snd_rme32_interrupt, IRQF_SHARED, 1357 if (request_irq(pci->irq, snd_rme32_interrupt, IRQF_SHARED,
1358 "RME32", rme32)) { 1358 KBUILD_MODNAME, rme32)) {
1359 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1359 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1360 return -EBUSY; 1360 return -EBUSY;
1361 } 1361 }
@@ -1985,7 +1985,7 @@ static void __devexit snd_rme32_remove(struct pci_dev *pci)
1985} 1985}
1986 1986
1987static struct pci_driver driver = { 1987static struct pci_driver driver = {
1988 .name = "RME Digi32", 1988 .name = KBUILD_MODNAME,
1989 .id_table = snd_rme32_ids, 1989 .id_table = snd_rme32_ids,
1990 .probe = snd_rme32_probe, 1990 .probe = snd_rme32_probe,
1991 .remove = __devexit_p(snd_rme32_remove), 1991 .remove = __devexit_p(snd_rme32_remove),
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 9ff247fc887..409e5b89519 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1561,7 +1561,7 @@ snd_rme96_create(struct rme96 *rme96)
1561 } 1561 }
1562 1562
1563 if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_SHARED, 1563 if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_SHARED,
1564 "RME96", rme96)) { 1564 KBUILD_MODNAME, rme96)) {
1565 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1565 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1566 return -EBUSY; 1566 return -EBUSY;
1567 } 1567 }
@@ -2396,7 +2396,7 @@ static void __devexit snd_rme96_remove(struct pci_dev *pci)
2396} 2396}
2397 2397
2398static struct pci_driver driver = { 2398static struct pci_driver driver = {
2399 .name = "RME Digi96", 2399 .name = KBUILD_MODNAME,
2400 .id_table = snd_rme96_ids, 2400 .id_table = snd_rme96_ids,
2401 .probe = snd_rme96_probe, 2401 .probe = snd_rme96_probe,
2402 .remove = __devexit_p(snd_rme96_remove), 2402 .remove = __devexit_p(snd_rme96_remove),
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 2d8332416c8..1c6d1e1c27c 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -5482,7 +5482,7 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
5482 } 5482 }
5483 5483
5484 if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_SHARED, 5484 if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_SHARED,
5485 "hdsp", hdsp)) { 5485 KBUILD_MODNAME, hdsp)) {
5486 snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq); 5486 snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
5487 return -EBUSY; 5487 return -EBUSY;
5488 } 5488 }
@@ -5637,7 +5637,7 @@ static void __devexit snd_hdsp_remove(struct pci_dev *pci)
5637} 5637}
5638 5638
5639static struct pci_driver driver = { 5639static struct pci_driver driver = {
5640 .name = "RME Hammerfall DSP", 5640 .name = KBUILD_MODNAME,
5641 .id_table = snd_hdsp_ids, 5641 .id_table = snd_hdsp_ids,
5642 .probe = snd_hdsp_probe, 5642 .probe = snd_hdsp_probe,
5643 .remove = __devexit_p(snd_hdsp_remove), 5643 .remove = __devexit_p(snd_hdsp_remove),
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 949691a876d..6edc67ced90 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -521,6 +521,8 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
521#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) 521#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
522 522
523/* revisions >= 230 indicate AES32 card */ 523/* revisions >= 230 indicate AES32 card */
524#define HDSPM_MADI_ANCIENT_REV 204
525#define HDSPM_MADI_OLD_REV 207
524#define HDSPM_MADI_REV 210 526#define HDSPM_MADI_REV 210
525#define HDSPM_RAYDAT_REV 211 527#define HDSPM_RAYDAT_REV 211
526#define HDSPM_AIO_REV 212 528#define HDSPM_AIO_REV 212
@@ -895,11 +897,11 @@ struct hdspm {
895 unsigned char max_channels_in; 897 unsigned char max_channels_in;
896 unsigned char max_channels_out; 898 unsigned char max_channels_out;
897 899
898 char *channel_map_in; 900 signed char *channel_map_in;
899 char *channel_map_out; 901 signed char *channel_map_out;
900 902
901 char *channel_map_in_ss, *channel_map_in_ds, *channel_map_in_qs; 903 signed char *channel_map_in_ss, *channel_map_in_ds, *channel_map_in_qs;
902 char *channel_map_out_ss, *channel_map_out_ds, *channel_map_out_qs; 904 signed char *channel_map_out_ss, *channel_map_out_ds, *channel_map_out_qs;
903 905
904 char **port_names_in; 906 char **port_names_in;
905 char **port_names_out; 907 char **port_names_out;
@@ -1143,7 +1145,7 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
1143 1145
1144 /* if wordclock has synced freq and wordclock is valid */ 1146 /* if wordclock has synced freq and wordclock is valid */
1145 if ((status2 & HDSPM_wcLock) != 0 && 1147 if ((status2 & HDSPM_wcLock) != 0 &&
1146 (status & HDSPM_SelSyncRef0) == 0) { 1148 (status2 & HDSPM_SelSyncRef0) == 0) {
1147 1149
1148 rate_bits = status2 & HDSPM_wcFreqMask; 1150 rate_bits = status2 & HDSPM_wcFreqMask;
1149 1151
@@ -1216,6 +1218,22 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
1216 rate = 0; 1218 rate = 0;
1217 break; 1219 break;
1218 } 1220 }
1221
1222 /* QS and DS rates normally can not be detected
1223 * automatically by the card. Only exception is MADI
1224 * in 96k frame mode.
1225 *
1226 * So if we read SS values (32 .. 48k), check for
1227 * user-provided DS/QS bits in the control register
1228 * and multiply the base frequency accordingly.
1229 */
1230 if (rate <= 48000) {
1231 if (hdspm->control_register & HDSPM_QuadSpeed)
1232 rate *= 4;
1233 else if (hdspm->control_register &
1234 HDSPM_DoubleSpeed)
1235 rate *= 2;
1236 }
1219 } 1237 }
1220 break; 1238 break;
1221 } 1239 }
@@ -1639,12 +1657,14 @@ static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi)
1639 } 1657 }
1640 } 1658 }
1641 hmidi->pending = 0; 1659 hmidi->pending = 0;
1660 spin_unlock_irqrestore(&hmidi->lock, flags);
1642 1661
1662 spin_lock_irqsave(&hmidi->hdspm->lock, flags);
1643 hmidi->hdspm->control_register |= hmidi->ie; 1663 hmidi->hdspm->control_register |= hmidi->ie;
1644 hdspm_write(hmidi->hdspm, HDSPM_controlRegister, 1664 hdspm_write(hmidi->hdspm, HDSPM_controlRegister,
1645 hmidi->hdspm->control_register); 1665 hmidi->hdspm->control_register);
1666 spin_unlock_irqrestore(&hmidi->hdspm->lock, flags);
1646 1667
1647 spin_unlock_irqrestore (&hmidi->lock, flags);
1648 return snd_hdspm_midi_output_write (hmidi); 1668 return snd_hdspm_midi_output_write (hmidi);
1649} 1669}
1650 1670
@@ -3412,6 +3432,91 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
3412 return change; 3432 return change;
3413} 3433}
3414 3434
3435#define HDSPM_MADI_SPEEDMODE(xname, xindex) \
3436{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3437 .name = xname, \
3438 .index = xindex, \
3439 .info = snd_hdspm_info_madi_speedmode, \
3440 .get = snd_hdspm_get_madi_speedmode, \
3441 .put = snd_hdspm_put_madi_speedmode \
3442}
3443
3444static int hdspm_madi_speedmode(struct hdspm *hdspm)
3445{
3446 if (hdspm->control_register & HDSPM_QuadSpeed)
3447 return 2;
3448 if (hdspm->control_register & HDSPM_DoubleSpeed)
3449 return 1;
3450 return 0;
3451}
3452
3453static int hdspm_set_madi_speedmode(struct hdspm *hdspm, int mode)
3454{
3455 hdspm->control_register &= ~(HDSPM_DoubleSpeed | HDSPM_QuadSpeed);
3456 switch (mode) {
3457 case 0:
3458 break;
3459 case 1:
3460 hdspm->control_register |= HDSPM_DoubleSpeed;
3461 break;
3462 case 2:
3463 hdspm->control_register |= HDSPM_QuadSpeed;
3464 break;
3465 }
3466 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
3467
3468 return 0;
3469}
3470
3471static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol,
3472 struct snd_ctl_elem_info *uinfo)
3473{
3474 static char *texts[] = { "Single", "Double", "Quad" };
3475
3476 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3477 uinfo->count = 1;
3478 uinfo->value.enumerated.items = 3;
3479
3480 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3481 uinfo->value.enumerated.item =
3482 uinfo->value.enumerated.items - 1;
3483 strcpy(uinfo->value.enumerated.name,
3484 texts[uinfo->value.enumerated.item]);
3485
3486 return 0;
3487}
3488
3489static int snd_hdspm_get_madi_speedmode(struct snd_kcontrol *kcontrol,
3490 struct snd_ctl_elem_value *ucontrol)
3491{
3492 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3493
3494 spin_lock_irq(&hdspm->lock);
3495 ucontrol->value.enumerated.item[0] = hdspm_madi_speedmode(hdspm);
3496 spin_unlock_irq(&hdspm->lock);
3497 return 0;
3498}
3499
3500static int snd_hdspm_put_madi_speedmode(struct snd_kcontrol *kcontrol,
3501 struct snd_ctl_elem_value *ucontrol)
3502{
3503 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3504 int change;
3505 int val;
3506
3507 if (!snd_hdspm_use_is_exclusive(hdspm))
3508 return -EBUSY;
3509 val = ucontrol->value.integer.value[0];
3510 if (val < 0)
3511 val = 0;
3512 if (val > 2)
3513 val = 2;
3514 spin_lock_irq(&hdspm->lock);
3515 change = val != hdspm_madi_speedmode(hdspm);
3516 hdspm_set_madi_speedmode(hdspm, val);
3517 spin_unlock_irq(&hdspm->lock);
3518 return change;
3519}
3415 3520
3416#define HDSPM_MIXER(xname, xindex) \ 3521#define HDSPM_MIXER(xname, xindex) \
3417{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ 3522{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
@@ -4286,7 +4391,8 @@ static struct snd_kcontrol_new snd_hdspm_controls_madi[] = {
4286 HDSPM_TX_64("TX 64 channels mode", 0), 4391 HDSPM_TX_64("TX 64 channels mode", 0),
4287 HDSPM_C_TMS("Clear Track Marker", 0), 4392 HDSPM_C_TMS("Clear Track Marker", 0),
4288 HDSPM_SAFE_MODE("Safe Mode", 0), 4393 HDSPM_SAFE_MODE("Safe Mode", 0),
4289 HDSPM_INPUT_SELECT("Input Select", 0) 4394 HDSPM_INPUT_SELECT("Input Select", 0),
4395 HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0)
4290}; 4396};
4291 4397
4292 4398
@@ -4299,7 +4405,8 @@ static struct snd_kcontrol_new snd_hdspm_controls_madiface[] = {
4299 HDSPM_SYNC_CHECK("MADI SyncCheck", 0), 4405 HDSPM_SYNC_CHECK("MADI SyncCheck", 0),
4300 HDSPM_TX_64("TX 64 channels mode", 0), 4406 HDSPM_TX_64("TX 64 channels mode", 0),
4301 HDSPM_C_TMS("Clear Track Marker", 0), 4407 HDSPM_C_TMS("Clear Track Marker", 0),
4302 HDSPM_SAFE_MODE("Safe Mode", 0) 4408 HDSPM_SAFE_MODE("Safe Mode", 0),
4409 HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0)
4303}; 4410};
4304 4411
4305static struct snd_kcontrol_new snd_hdspm_controls_aio[] = { 4412static struct snd_kcontrol_new snd_hdspm_controls_aio[] = {
@@ -6377,6 +6484,8 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
6377 6484
6378 switch (hdspm->firmware_rev) { 6485 switch (hdspm->firmware_rev) {
6379 case HDSPM_MADI_REV: 6486 case HDSPM_MADI_REV:
6487 case HDSPM_MADI_OLD_REV:
6488 case HDSPM_MADI_ANCIENT_REV:
6380 hdspm->io_type = MADI; 6489 hdspm->io_type = MADI;
6381 hdspm->card_name = "RME MADI"; 6490 hdspm->card_name = "RME MADI";
6382 hdspm->midiPorts = 3; 6491 hdspm->midiPorts = 3;
@@ -6437,7 +6546,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
6437 hdspm->port + io_extent - 1); 6546 hdspm->port + io_extent - 1);
6438 6547
6439 if (request_irq(pci->irq, snd_hdspm_interrupt, 6548 if (request_irq(pci->irq, snd_hdspm_interrupt,
6440 IRQF_SHARED, "hdspm", hdspm)) { 6549 IRQF_SHARED, KBUILD_MODNAME, hdspm)) {
6441 snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq); 6550 snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
6442 return -EBUSY; 6551 return -EBUSY;
6443 } 6552 }
@@ -6775,7 +6884,7 @@ static void __devexit snd_hdspm_remove(struct pci_dev *pci)
6775} 6884}
6776 6885
6777static struct pci_driver driver = { 6886static struct pci_driver driver = {
6778 .name = "RME Hammerfall DSP MADI", 6887 .name = KBUILD_MODNAME,
6779 .id_table = snd_hdspm_ids, 6888 .id_table = snd_hdspm_ids,
6780 .probe = snd_hdspm_probe, 6889 .probe = snd_hdspm_probe,
6781 .remove = __devexit_p(snd_hdspm_remove), 6890 .remove = __devexit_p(snd_hdspm_remove),
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index c492af5b25f..1c7bc1ef818 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -2479,7 +2479,7 @@ static int __devinit snd_rme9652_create(struct snd_card *card,
2479 } 2479 }
2480 2480
2481 if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_SHARED, 2481 if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_SHARED,
2482 "rme9652", rme9652)) { 2482 KBUILD_MODNAME, rme9652)) {
2483 snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq); 2483 snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
2484 return -EBUSY; 2484 return -EBUSY;
2485 } 2485 }
@@ -2632,7 +2632,7 @@ static void __devexit snd_rme9652_remove(struct pci_dev *pci)
2632} 2632}
2633 2633
2634static struct pci_driver driver = { 2634static struct pci_driver driver = {
2635 .name = "RME Digi9652 (Hammerfall)", 2635 .name = KBUILD_MODNAME,
2636 .id_table = snd_rme9652_ids, 2636 .id_table = snd_rme9652_ids,
2637 .probe = snd_rme9652_probe, 2637 .probe = snd_rme9652_probe,
2638 .remove = __devexit_p(snd_rme9652_remove), 2638 .remove = __devexit_p(snd_rme9652_remove),
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 2b5c7a95ae1..bcf61524a13 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -1235,7 +1235,7 @@ static int sis_resume(struct pci_dev *pci)
1235 } 1235 }
1236 1236
1237 if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED, 1237 if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
1238 card->shortname, sis)) { 1238 KBUILD_MODNAME, sis)) {
1239 printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq); 1239 printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq);
1240 goto error; 1240 goto error;
1241 } 1241 }
@@ -1341,7 +1341,7 @@ static int __devinit sis_chip_create(struct snd_card *card,
1341 goto error_out_cleanup; 1341 goto error_out_cleanup;
1342 1342
1343 if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED, 1343 if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
1344 card->shortname, sis)) { 1344 KBUILD_MODNAME, sis)) {
1345 printk(KERN_ERR "unable to allocate irq %d\n", sis->irq); 1345 printk(KERN_ERR "unable to allocate irq %d\n", sis->irq);
1346 goto error_out_cleanup; 1346 goto error_out_cleanup;
1347 } 1347 }
@@ -1436,7 +1436,7 @@ static void __devexit snd_sis7019_remove(struct pci_dev *pci)
1436} 1436}
1437 1437
1438static struct pci_driver sis7019_driver = { 1438static struct pci_driver sis7019_driver = {
1439 .name = "SiS7019", 1439 .name = KBUILD_MODNAME,
1440 .id_table = snd_sis7019_ids, 1440 .id_table = snd_sis7019_ids,
1441 .probe = snd_sis7019_probe, 1441 .probe = snd_sis7019_probe,
1442 .remove = __devexit_p(snd_sis7019_remove), 1442 .remove = __devexit_p(snd_sis7019_remove),
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 337b9facadf..2571a67b389 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -1294,7 +1294,7 @@ static int __devinit snd_sonicvibes_create(struct snd_card *card,
1294 sonic->game_port = pci_resource_start(pci, 4); 1294 sonic->game_port = pci_resource_start(pci, 4);
1295 1295
1296 if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_SHARED, 1296 if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_SHARED,
1297 "S3 SonicVibes", sonic)) { 1297 KBUILD_MODNAME, sonic)) {
1298 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1298 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1299 snd_sonicvibes_free(sonic); 1299 snd_sonicvibes_free(sonic);
1300 return -EBUSY; 1300 return -EBUSY;
@@ -1530,7 +1530,7 @@ static void __devexit snd_sonic_remove(struct pci_dev *pci)
1530} 1530}
1531 1531
1532static struct pci_driver driver = { 1532static struct pci_driver driver = {
1533 .name = "S3 SonicVibes", 1533 .name = KBUILD_MODNAME,
1534 .id_table = snd_sonic_ids, 1534 .id_table = snd_sonic_ids,
1535 .probe = snd_sonic_probe, 1535 .probe = snd_sonic_probe,
1536 .remove = __devexit_p(snd_sonic_remove), 1536 .remove = __devexit_p(snd_sonic_remove),
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 6d0581841d7..d8a128f6fc0 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -172,7 +172,7 @@ static void __devexit snd_trident_remove(struct pci_dev *pci)
172} 172}
173 173
174static struct pci_driver driver = { 174static struct pci_driver driver = {
175 .name = "Trident4DWaveAudio", 175 .name = KBUILD_MODNAME,
176 .id_table = snd_trident_ids, 176 .id_table = snd_trident_ids,
177 .probe = snd_trident_probe, 177 .probe = snd_trident_probe,
178 .remove = __devexit_p(snd_trident_remove), 178 .remove = __devexit_p(snd_trident_remove),
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 2870a4fdc13..5bd57a7c52d 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -3598,7 +3598,7 @@ int __devinit snd_trident_create(struct snd_card *card,
3598 trident->port = pci_resource_start(pci, 0); 3598 trident->port = pci_resource_start(pci, 0);
3599 3599
3600 if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED, 3600 if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED,
3601 "Trident Audio", trident)) { 3601 KBUILD_MODNAME, trident)) {
3602 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 3602 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
3603 snd_trident_free(trident); 3603 snd_trident_free(trident);
3604 return -EBUSY; 3604 return -EBUSY;
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 8c5f8b5a59f..f03fd620a2a 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2377,7 +2377,7 @@ static int __devinit snd_via82xx_create(struct snd_card *card,
2377 chip_type == TYPE_VIA8233 ? 2377 chip_type == TYPE_VIA8233 ?
2378 snd_via8233_interrupt : snd_via686_interrupt, 2378 snd_via8233_interrupt : snd_via686_interrupt,
2379 IRQF_SHARED, 2379 IRQF_SHARED,
2380 card->driver, chip)) { 2380 KBUILD_MODNAME, chip)) {
2381 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 2381 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2382 snd_via82xx_free(chip); 2382 snd_via82xx_free(chip);
2383 return -EBUSY; 2383 return -EBUSY;
@@ -2611,7 +2611,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
2611} 2611}
2612 2612
2613static struct pci_driver driver = { 2613static struct pci_driver driver = {
2614 .name = "VIA 82xx Audio", 2614 .name = KBUILD_MODNAME,
2615 .id_table = snd_via82xx_ids, 2615 .id_table = snd_via82xx_ids,
2616 .probe = snd_via82xx_probe, 2616 .probe = snd_via82xx_probe,
2617 .remove = __devexit_p(snd_via82xx_remove), 2617 .remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index f7e8bbbe395..a386dd9f673 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1129,7 +1129,7 @@ static int __devinit snd_via82xx_create(struct snd_card *card,
1129 } 1129 }
1130 chip->port = pci_resource_start(pci, 0); 1130 chip->port = pci_resource_start(pci, 0);
1131 if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_SHARED, 1131 if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_SHARED,
1132 card->driver, chip)) { 1132 KBUILD_MODNAME, chip)) {
1133 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1133 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1134 snd_via82xx_free(chip); 1134 snd_via82xx_free(chip);
1135 return -EBUSY; 1135 return -EBUSY;
@@ -1224,7 +1224,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
1224} 1224}
1225 1225
1226static struct pci_driver driver = { 1226static struct pci_driver driver = {
1227 .name = "VIA 82xx Modem", 1227 .name = KBUILD_MODNAME,
1228 .id_table = snd_via82xx_modem_ids, 1228 .id_table = snd_via82xx_modem_ids,
1229 .probe = snd_via82xx_probe, 1229 .probe = snd_via82xx_probe,
1230 .remove = __devexit_p(snd_via82xx_remove), 1230 .remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index 99a9a814be0..5342d5e1366 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -169,7 +169,7 @@ static int __devinit snd_vx222_create(struct snd_card *card, struct pci_dev *pci
169 vx->port[i] = pci_resource_start(pci, i + 1); 169 vx->port[i] = pci_resource_start(pci, i + 1);
170 170
171 if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_SHARED, 171 if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_SHARED,
172 CARD_NAME, chip)) { 172 KBUILD_MODNAME, chip)) {
173 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 173 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
174 snd_vx222_free(chip); 174 snd_vx222_free(chip);
175 return -EBUSY; 175 return -EBUSY;
@@ -290,7 +290,7 @@ static int snd_vx222_resume(struct pci_dev *pci)
290#endif 290#endif
291 291
292static struct pci_driver driver = { 292static struct pci_driver driver = {
293 .name = "Digigram VX222", 293 .name = KBUILD_MODNAME,
294 .id_table = snd_vx222_ids, 294 .id_table = snd_vx222_ids,
295 .probe = snd_vx222_probe, 295 .probe = snd_vx222_probe,
296 .remove = __devexit_p(snd_vx222_remove), 296 .remove = __devexit_p(snd_vx222_remove),
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 80c68211338..511d5765312 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -345,7 +345,7 @@ static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci)
345} 345}
346 346
347static struct pci_driver driver = { 347static struct pci_driver driver = {
348 .name = "Yamaha DS-1 PCI", 348 .name = KBUILD_MODNAME,
349 .id_table = snd_ymfpci_ids, 349 .id_table = snd_ymfpci_ids,
350 .probe = snd_card_ymfpci_probe, 350 .probe = snd_card_ymfpci_probe,
351 .remove = __devexit_p(snd_card_ymfpci_remove), 351 .remove = __devexit_p(snd_card_ymfpci_remove),
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index c94c051ad0c..f3260e658b8 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2380,7 +2380,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
2380 return -EBUSY; 2380 return -EBUSY;
2381 } 2381 }
2382 if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED, 2382 if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED,
2383 "YMFPCI", chip)) { 2383 KBUILD_MODNAME, chip)) {
2384 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 2384 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
2385 snd_ymfpci_free(chip); 2385 snd_ymfpci_free(chip);
2386 return -EBUSY; 2386 return -EBUSY;
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index ce33be0e4e9..66488a7a570 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -223,7 +223,7 @@ static int pdacf_config(struct pcmcia_device *link)
223 if (ret) 223 if (ret)
224 goto failed; 224 goto failed;
225 225
226 ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt); 226 ret = pcmcia_request_irq(link, pdacf_interrupt);
227 if (ret) 227 if (ret)
228 goto failed; 228 goto failed;
229 229
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index d9ef21d8fa7..31777d1ea49 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -229,7 +229,7 @@ static int vxpocket_config(struct pcmcia_device *link)
229 if (ret) 229 if (ret)
230 goto failed; 230 goto failed;
231 231
232 ret = pcmcia_request_exclusive_irq(link, snd_vx_irq_handler); 232 ret = pcmcia_request_irq(link, snd_vx_irq_handler);
233 if (ret) 233 if (ret)
234 goto failed; 234 goto failed;
235 235
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index f8c663dcff0..d68ea532cc7 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -262,14 +262,14 @@ static int v253_hangup(struct tty_struct *tty)
262} 262}
263 263
264/* Line discipline .receive_buf() */ 264/* Line discipline .receive_buf() */
265static unsigned int v253_receive(struct tty_struct *tty, 265static void v253_receive(struct tty_struct *tty,
266 const unsigned char *cp, char *fp, int count) 266 const unsigned char *cp, char *fp, int count)
267{ 267{
268 struct snd_soc_codec *codec = tty->disc_data; 268 struct snd_soc_codec *codec = tty->disc_data;
269 struct cx20442_priv *cx20442; 269 struct cx20442_priv *cx20442;
270 270
271 if (!codec) 271 if (!codec)
272 return count; 272 return;
273 273
274 cx20442 = snd_soc_codec_get_drvdata(codec); 274 cx20442 = snd_soc_codec_get_drvdata(codec);
275 275
@@ -281,8 +281,6 @@ static unsigned int v253_receive(struct tty_struct *tty,
281 codec->hw_write = (hw_write_t)tty->ops->write; 281 codec->hw_write = (hw_write_t)tty->ops->write;
282 codec->card->pop_time = 1; 282 codec->card->pop_time = 1;
283 } 283 }
284
285 return count;
286} 284}
287 285
288/* Line discipline .write_wakeup() */ 286/* Line discipline .write_wakeup() */
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 3c2ee1bb73c..6af23d06870 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -13,7 +13,6 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
16#include <linux/version.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/delay.h> 18#include <linux/delay.h>
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c
index 337a00241a1..4dd051bdf4f 100644
--- a/sound/spi/at73c213.c
+++ b/sound/spi/at73c213.c
@@ -1124,6 +1124,6 @@ static void __exit at73c213_exit(void)
1124} 1124}
1125module_exit(at73c213_exit); 1125module_exit(at73c213_exit);
1126 1126
1127MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); 1127MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
1128MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC"); 1128MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC");
1129MODULE_LICENSE("GPL"); 1129MODULE_LICENSE("GPL");
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index d47beffedb0..1e3ae3327dd 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -227,6 +227,7 @@ static int usb6fire_fw_ezusb_upload(
227 ret = usb6fire_fw_ihex_init(fw, rec); 227 ret = usb6fire_fw_ihex_init(fw, rec);
228 if (ret < 0) { 228 if (ret < 0) {
229 kfree(rec); 229 kfree(rec);
230 release_firmware(fw);
230 snd_printk(KERN_ERR PREFIX "error validating ezusb " 231 snd_printk(KERN_ERR PREFIX "error validating ezusb "
231 "firmware %s.\n", fwname); 232 "firmware %s.\n", fwname);
232 return ret; 233 return ret;
@@ -269,7 +270,6 @@ static int usb6fire_fw_ezusb_upload(
269 data = 0x00; /* resume ezusb cpu */ 270 data = 0x00; /* resume ezusb cpu */
270 ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1); 271 ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1);
271 if (ret < 0) { 272 if (ret < 0) {
272 release_firmware(fw);
273 snd_printk(KERN_ERR PREFIX "unable to upload ezusb " 273 snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
274 "firmware %s: end message.\n", fwname); 274 "firmware %s: end message.\n", fwname);
275 return ret; 275 return ret;
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index b137b25865c..d144cdb2f15 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -395,12 +395,12 @@ static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
395 alsa_rt->hw = pcm_hw; 395 alsa_rt->hw = pcm_hw;
396 396
397 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) { 397 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) {
398 if (rt->rate >= 0) 398 if (rt->rate < ARRAY_SIZE(rates))
399 alsa_rt->hw.rates = rates_alsaid[rt->rate]; 399 alsa_rt->hw.rates = rates_alsaid[rt->rate];
400 alsa_rt->hw.channels_max = OUT_N_CHANNELS; 400 alsa_rt->hw.channels_max = OUT_N_CHANNELS;
401 sub = &rt->playback; 401 sub = &rt->playback;
402 } else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) { 402 } else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) {
403 if (rt->rate >= 0) 403 if (rt->rate < ARRAY_SIZE(rates))
404 alsa_rt->hw.rates = rates_alsaid[rt->rate]; 404 alsa_rt->hw.rates = rates_alsaid[rt->rate];
405 alsa_rt->hw.channels_max = IN_N_CHANNELS; 405 alsa_rt->hw.channels_max = IN_N_CHANNELS;
406 sub = &rt->capture; 406 sub = &rt->capture;
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 220c6167dd8..781d9e61adf 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -433,9 +433,10 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
433 * only at the first time. the successive calls of this function will 433 * only at the first time. the successive calls of this function will
434 * append the pcm interface to the corresponding card. 434 * append the pcm interface to the corresponding card.
435 */ 435 */
436static void *snd_usb_audio_probe(struct usb_device *dev, 436static struct snd_usb_audio *
437 struct usb_interface *intf, 437snd_usb_audio_probe(struct usb_device *dev,
438 const struct usb_device_id *usb_id) 438 struct usb_interface *intf,
439 const struct usb_device_id *usb_id)
439{ 440{
440 const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info; 441 const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
441 int i, err; 442 int i, err;
@@ -540,16 +541,15 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
540 * we need to take care of counter, since disconnection can be called also 541 * we need to take care of counter, since disconnection can be called also
541 * many times as well as usb_audio_probe(). 542 * many times as well as usb_audio_probe().
542 */ 543 */
543static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) 544static void snd_usb_audio_disconnect(struct usb_device *dev,
545 struct snd_usb_audio *chip)
544{ 546{
545 struct snd_usb_audio *chip;
546 struct snd_card *card; 547 struct snd_card *card;
547 struct list_head *p; 548 struct list_head *p;
548 549
549 if (ptr == (void *)-1L) 550 if (chip == (void *)-1L)
550 return; 551 return;
551 552
552 chip = ptr;
553 card = chip->card; 553 card = chip->card;
554 mutex_lock(&register_mutex); 554 mutex_lock(&register_mutex);
555 mutex_lock(&chip->shutdown_mutex); 555 mutex_lock(&chip->shutdown_mutex);
@@ -585,7 +585,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
585static int usb_audio_probe(struct usb_interface *intf, 585static int usb_audio_probe(struct usb_interface *intf,
586 const struct usb_device_id *id) 586 const struct usb_device_id *id)
587{ 587{
588 void *chip; 588 struct snd_usb_audio *chip;
589 chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id); 589 chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
590 if (chip) { 590 if (chip) {
591 usb_set_intfdata(intf, chip); 591 usb_set_intfdata(intf, chip);
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index b0ef9f50189..7c0d21ecd82 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -408,6 +408,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
408 /* doesn't set the sample rate attribute, but supports it */ 408 /* doesn't set the sample rate attribute, but supports it */
409 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; 409 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
410 break; 410 break;
411 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */
412 case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
411 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ 413 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
412 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is 414 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
413 an older model 77d:223) */ 415 an older model 77d:223) */
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index fb5d68fa7ff..67bec761244 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -645,7 +645,7 @@ static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
645 err = snd_pcm_hw_constraint_minmax(substream->runtime, 645 err = snd_pcm_hw_constraint_minmax(substream->runtime,
646 SNDRV_PCM_HW_PARAM_PERIOD_TIME, 646 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
647 1500000 / ua->packets_per_second, 647 1500000 / ua->packets_per_second,
648 8192000); 648 UINT_MAX);
649 if (err < 0) 649 if (err < 0)
650 return err; 650 return err;
651 err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); 651 err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 0b2ae8e1c02..dba0b7f11c5 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -1677,6 +1677,36 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1677 } 1677 }
1678 } 1678 }
1679}, 1679},
1680{
1681 USB_DEVICE(0x0582, 0x011e),
1682 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1683 /* .vendor_name = "BOSS", */
1684 /* .product_name = "BR-800", */
1685 .ifnum = QUIRK_ANY_INTERFACE,
1686 .type = QUIRK_COMPOSITE,
1687 .data = (const struct snd_usb_audio_quirk[]) {
1688 {
1689 .ifnum = 0,
1690 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1691 },
1692 {
1693 .ifnum = 1,
1694 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1695 },
1696 {
1697 .ifnum = 2,
1698 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1699 .data = & (const struct snd_usb_midi_endpoint_info) {
1700 .out_cables = 0x0001,
1701 .in_cables = 0x0001
1702 }
1703 },
1704 {
1705 .ifnum = -1
1706 }
1707 }
1708 }
1709},
1680 1710
1681/* Guillemot devices */ 1711/* Guillemot devices */
1682{ 1712{
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 2e969cbb393..77762c99afb 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -369,6 +369,30 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
369 return 0; 369 return 0;
370} 370}
371 371
372static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev)
373{
374 int err;
375
376 if (dev->actconfig->desc.bConfigurationValue == 1) {
377 snd_printk(KERN_INFO "usb-audio: "
378 "Fast Track Pro switching to config #2\n");
379 /* This function has to be available by the usb core module.
380 * if it is not avialable the boot quirk has to be left out
381 * and the configuration has to be set by udev or hotplug
382 * rules
383 */
384 err = usb_driver_set_configuration(dev, 2);
385 if (err < 0) {
386 snd_printdd("error usb_driver_set_configuration: %d\n",
387 err);
388 return -ENODEV;
389 }
390 } else
391 snd_printk(KERN_INFO "usb-audio: Fast Track Pro config OK\n");
392
393 return 0;
394}
395
372/* 396/*
373 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely 397 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
374 * documented in the device's data sheet. 398 * documented in the device's data sheet.
@@ -403,7 +427,7 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
403static int snd_usb_cm6206_boot_quirk(struct usb_device *dev) 427static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
404{ 428{
405 int err, reg; 429 int err, reg;
406 int val[] = {0x200c, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000}; 430 int val[] = {0x2004, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
407 431
408 for (reg = 0; reg < ARRAY_SIZE(val); reg++) { 432 for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
409 err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]); 433 err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
@@ -471,16 +495,49 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
471/* 495/*
472 * Setup quirks 496 * Setup quirks
473 */ 497 */
474#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ 498#define MAUDIO_SET 0x01 /* parse device_setup */
475#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */ 499#define MAUDIO_SET_COMPATIBLE 0x80 /* use only "win-compatible" interfaces */
476#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */ 500#define MAUDIO_SET_DTS 0x02 /* enable DTS Digital Output */
477#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */ 501#define MAUDIO_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
478#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */ 502#define MAUDIO_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
479#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */ 503#define MAUDIO_SET_DI 0x10 /* enable Digital Input */
480#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */ 504#define MAUDIO_SET_MASK 0x1f /* bit mask for setup value */
481#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */ 505#define MAUDIO_SET_24B_48K_DI 0x19 /* 24bits+48KHz+Digital Input */
482#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */ 506#define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48KHz+No Digital Input */
483#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */ 507#define MAUDIO_SET_16B_48K_DI 0x11 /* 16bits+48KHz+Digital Input */
508#define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48KHz+No Digital Input */
509
510static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,
511 int iface, int altno)
512{
513 /* Reset ALL ifaces to 0 altsetting.
514 * Call it for every possible altsetting of every interface.
515 */
516 usb_set_interface(chip->dev, iface, 0);
517 if (chip->setup & MAUDIO_SET) {
518 if (chip->setup & MAUDIO_SET_COMPATIBLE) {
519 if (iface != 1 && iface != 2)
520 return 1; /* skip all interfaces but 1 and 2 */
521 } else {
522 unsigned int mask;
523 if (iface == 1 || iface == 2)
524 return 1; /* skip interfaces 1 and 2 */
525 if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
526 return 1; /* skip this altsetting */
527 mask = chip->setup & MAUDIO_SET_MASK;
528 if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
529 return 1; /* skip this altsetting */
530 if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
531 return 1; /* skip this altsetting */
532 if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 4)
533 return 1; /* skip this altsetting */
534 }
535 }
536 snd_printdd(KERN_INFO
537 "using altsetting %d for interface %d config %d\n",
538 altno, iface, chip->setup);
539 return 0; /* keep this altsetting */
540}
484 541
485static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, 542static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
486 int iface, 543 int iface,
@@ -491,30 +548,65 @@ static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
491 */ 548 */
492 usb_set_interface(chip->dev, iface, 0); 549 usb_set_interface(chip->dev, iface, 0);
493 550
494 if (chip->setup & AUDIOPHILE_SET) { 551 if (chip->setup & MAUDIO_SET) {
495 if ((chip->setup & AUDIOPHILE_SET_DTS) 552 unsigned int mask;
496 && altno != 6) 553 if ((chip->setup & MAUDIO_SET_DTS) && altno != 6)
497 return 1; /* skip this altsetting */ 554 return 1; /* skip this altsetting */
498 if ((chip->setup & AUDIOPHILE_SET_96K) 555 if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
499 && altno != 1)
500 return 1; /* skip this altsetting */ 556 return 1; /* skip this altsetting */
501 if ((chip->setup & AUDIOPHILE_SET_MASK) == 557 mask = chip->setup & MAUDIO_SET_MASK;
502 AUDIOPHILE_SET_24B_48K_DI && altno != 2) 558 if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
503 return 1; /* skip this altsetting */ 559 return 1; /* skip this altsetting */
504 if ((chip->setup & AUDIOPHILE_SET_MASK) == 560 if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
505 AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
506 return 1; /* skip this altsetting */ 561 return 1; /* skip this altsetting */
507 if ((chip->setup & AUDIOPHILE_SET_MASK) == 562 if (mask == MAUDIO_SET_16B_48K_DI && altno != 4)
508 AUDIOPHILE_SET_16B_48K_DI && altno != 4)
509 return 1; /* skip this altsetting */ 563 return 1; /* skip this altsetting */
510 if ((chip->setup & AUDIOPHILE_SET_MASK) == 564 if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 5)
511 AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
512 return 1; /* skip this altsetting */ 565 return 1; /* skip this altsetting */
513 } 566 }
514 567
515 return 0; /* keep this altsetting */ 568 return 0; /* keep this altsetting */
516} 569}
517 570
571
572static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip,
573 int iface, int altno)
574{
575 /* Reset ALL ifaces to 0 altsetting.
576 * Call it for every possible altsetting of every interface.
577 */
578 usb_set_interface(chip->dev, iface, 0);
579
580 /* possible configuration where both inputs and only one output is
581 *used is not supported by the current setup
582 */
583 if (chip->setup & (MAUDIO_SET | MAUDIO_SET_24B)) {
584 if (chip->setup & MAUDIO_SET_96K) {
585 if (altno != 3 && altno != 6)
586 return 1;
587 } else if (chip->setup & MAUDIO_SET_DI) {
588 if (iface == 4)
589 return 1; /* no analog input */
590 if (altno != 2 && altno != 5)
591 return 1; /* enable only altsets 2 and 5 */
592 } else {
593 if (iface == 5)
594 return 1; /* disable digialt input */
595 if (altno != 2 && altno != 5)
596 return 1; /* enalbe only altsets 2 and 5 */
597 }
598 } else {
599 /* keep only 16-Bit mode */
600 if (altno != 1)
601 return 1;
602 }
603
604 snd_printdd(KERN_INFO
605 "using altsetting %d for interface %d config %d\n",
606 altno, iface, chip->setup);
607 return 0; /* keep this altsetting */
608}
609
518int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, 610int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
519 int iface, 611 int iface,
520 int altno) 612 int altno)
@@ -522,6 +614,12 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
522 /* audiophile usb: skip altsets incompatible with device_setup */ 614 /* audiophile usb: skip altsets incompatible with device_setup */
523 if (chip->usb_id == USB_ID(0x0763, 0x2003)) 615 if (chip->usb_id == USB_ID(0x0763, 0x2003))
524 return audiophile_skip_setting_quirk(chip, iface, altno); 616 return audiophile_skip_setting_quirk(chip, iface, altno);
617 /* quattro usb: skip altsets incompatible with device_setup */
618 if (chip->usb_id == USB_ID(0x0763, 0x2001))
619 return quattro_skip_setting_quirk(chip, iface, altno);
620 /* fasttrackpro usb: skip altsets incompatible with device_setup */
621 if (chip->usb_id == USB_ID(0x0763, 0x2012))
622 return fasttrackpro_skip_setting_quirk(chip, iface, altno);
525 623
526 return 0; 624 return 0;
527} 625}
@@ -560,6 +658,8 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
560 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ 658 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
561 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ 659 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
562 return snd_usb_nativeinstruments_boot_quirk(dev); 660 return snd_usb_nativeinstruments_boot_quirk(dev);
661 case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
662 return snd_usb_fasttrackpro_boot_quirk(dev);
563 } 663 }
564 664
565 return 0; 665 return 0;
@@ -570,15 +670,24 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
570 */ 670 */
571int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp) 671int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
572{ 672{
673 /* it depends on altsetting wether the device is big-endian or not */
573 switch (chip->usb_id) { 674 switch (chip->usb_id) {
574 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */ 675 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
575 if (fp->endpoint & USB_DIR_IN) 676 if (fp->altsetting == 2 || fp->altsetting == 3 ||
677 fp->altsetting == 5 || fp->altsetting == 6)
576 return 1; 678 return 1;
577 break; 679 break;
578 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ 680 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
579 if (chip->setup == 0x00 || 681 if (chip->setup == 0x00 ||
580 fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3) 682 fp->altsetting == 1 || fp->altsetting == 2 ||
683 fp->altsetting == 3)
684 return 1;
685 break;
686 case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro */
687 if (fp->altsetting == 2 || fp->altsetting == 3 ||
688 fp->altsetting == 5 || fp->altsetting == 6)
581 return 1; 689 return 1;
690 break;
582 } 691 }
583 return 0; 692 return 0;
584} 693}