aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2012-04-08 15:48:52 -0400
committerJiri Kosina <jkosina@suse.cz>2012-04-08 15:48:52 -0400
commite75d660672ddd11704b7f0fdb8ff21968587b266 (patch)
treeccb9c107744c10b553c0373e450bee3971d16c00 /sound/pci
parent61282f37927143e45b03153f3e7b48d6b702147a (diff)
parent0034102808e0dbbf3a2394b82b1bb40b5778de9e (diff)
Merge branch 'master' into for-next
Merge with latest Linus' tree, as I have incoming patches that fix code that is newer than current HEAD of for-next. Conflicts: drivers/net/ethernet/realtek/r8169.c
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/asihpi/hpi_internal.h2
-rw-r--r--sound/pci/asihpi/hpios.c2
-rw-r--r--sound/pci/asihpi/hpios.h1
-rw-r--r--sound/pci/au88x0/au88x0.h13
-rw-r--r--sound/pci/au88x0/au88x0_core.c20
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c127
-rw-r--r--sound/pci/aw2/aw2-saa7146.c1
-rw-r--r--sound/pci/azt3328.c3
-rw-r--r--sound/pci/ctxfi/ctvmem.c2
-rw-r--r--sound/pci/es1968.c15
-rw-r--r--sound/pci/fm801.c20
-rw-r--r--sound/pci/hda/alc260_quirks.c968
-rw-r--r--sound/pci/hda/alc880_quirks.c1707
-rw-r--r--sound/pci/hda/alc882_quirks.c866
-rw-r--r--sound/pci/hda/alc_quirks.c480
-rw-r--r--sound/pci/hda/hda_codec.c204
-rw-r--r--sound/pci/hda/hda_codec.h4
-rw-r--r--sound/pci/hda/hda_eld.c4
-rw-r--r--sound/pci/hda/hda_intel.c52
-rw-r--r--sound/pci/hda/hda_jack.c16
-rw-r--r--sound/pci/hda/hda_jack.h13
-rw-r--r--sound/pci/hda/hda_local.h30
-rw-r--r--sound/pci/hda/patch_analog.c72
-rw-r--r--sound/pci/hda/patch_ca0132.c33
-rw-r--r--sound/pci/hda/patch_cirrus.c4
-rw-r--r--sound/pci/hda/patch_conexant.c146
-rw-r--r--sound/pci/hda/patch_hdmi.c2
-rw-r--r--sound/pci/hda/patch_realtek.c1895
-rw-r--r--sound/pci/hda/patch_sigmatel.c205
-rw-r--r--sound/pci/hda/patch_via.c51
-rw-r--r--sound/pci/ice1712/ice1724.c23
-rw-r--r--sound/pci/intel8x0.c6
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c25
-rw-r--r--sound/pci/rme9652/hdspm.c1
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c9
35 files changed, 2075 insertions, 4947 deletions
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index 4cc315daeda0..8c63200cf339 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -42,7 +42,7 @@ On error *pLockedMemHandle marked invalid, non-zero returned.
42If this function succeeds, then HpiOs_LockedMem_GetVirtAddr() and 42If this function succeeds, then HpiOs_LockedMem_GetVirtAddr() and
43HpiOs_LockedMem_GetPyhsAddr() will always succed on the returned handle. 43HpiOs_LockedMem_GetPyhsAddr() will always succed on the returned handle.
44*/ 44*/
45u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle, 45int hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle,
46 /**< memory handle */ 46 /**< memory handle */
47 u32 size, /**< Size in bytes to allocate */ 47 u32 size, /**< Size in bytes to allocate */
48 struct pci_dev *p_os_reference 48 struct pci_dev *p_os_reference
diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c
index 2d7d1c2e1d0d..87f4385fe8c7 100644
--- a/sound/pci/asihpi/hpios.c
+++ b/sound/pci/asihpi/hpios.c
@@ -43,7 +43,7 @@ void hpios_delay_micro_seconds(u32 num_micro_sec)
43 43
44On error, return -ENOMEM, and *pMemArea.size = 0 44On error, return -ENOMEM, and *pMemArea.size = 0
45*/ 45*/
46u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size, 46int hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
47 struct pci_dev *pdev) 47 struct pci_dev *pdev)
48{ 48{
49 /*?? any benefit in using managed dmam_alloc_coherent? */ 49 /*?? any benefit in using managed dmam_alloc_coherent? */
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h
index c5cef113c209..d3fbd0d76c37 100644
--- a/sound/pci/asihpi/hpios.h
+++ b/sound/pci/asihpi/hpios.h
@@ -30,7 +30,6 @@ HPI Operating System Specific macros for Linux Kernel driver
30#define HPI_BUILD_KERNEL_MODE 30#define HPI_BUILD_KERNEL_MODE
31 31
32#include <linux/io.h> 32#include <linux/io.h>
33#include <asm/system.h>
34#include <linux/ioctl.h> 33#include <linux/ioctl.h>
35#include <linux/kernel.h> 34#include <linux/kernel.h>
36#include <linux/string.h> 35#include <linux/string.h>
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index bb938153a964..466a5c8e8354 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -26,7 +26,7 @@
26#include <sound/mpu401.h> 26#include <sound/mpu401.h>
27#include <sound/hwdep.h> 27#include <sound/hwdep.h>
28#include <sound/ac97_codec.h> 28#include <sound/ac97_codec.h>
29 29#include <sound/tlv.h>
30#endif 30#endif
31 31
32#ifndef CHIP_AU8820 32#ifndef CHIP_AU8820
@@ -107,6 +107,14 @@
107#define NR_WTPB 0x20 /* WT channels per each bank. */ 107#define NR_WTPB 0x20 /* WT channels per each bank. */
108#define NR_PCM 0x10 108#define NR_PCM 0x10
109 109
110struct pcm_vol {
111 struct snd_kcontrol *kctl;
112 int active;
113 int dma;
114 int mixin[4];
115 int vol[4];
116};
117
110/* Structs */ 118/* Structs */
111typedef struct { 119typedef struct {
112 //int this_08; /* Still unknown */ 120 //int this_08; /* Still unknown */
@@ -168,6 +176,7 @@ struct snd_vortex {
168 /* Xtalk canceler */ 176 /* Xtalk canceler */
169 int xt_mode; /* 1: speakers, 0:headphones. */ 177 int xt_mode; /* 1: speakers, 0:headphones. */
170#endif 178#endif
179 struct pcm_vol pcm_vol[NR_PCM];
171 180
172 int isquad; /* cache of extended ID codec flag. */ 181 int isquad; /* cache of extended ID codec flag. */
173 182
@@ -239,7 +248,7 @@ static int vortex_alsafmt_aspfmt(int alsafmt);
239/* Connection stuff. */ 248/* Connection stuff. */
240static void vortex_connect_default(vortex_t * vortex, int en); 249static void vortex_connect_default(vortex_t * vortex, int en);
241static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, 250static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
242 int dir, int type); 251 int dir, int type, int subdev);
243static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, 252static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
244 int restype); 253 int restype);
245#ifndef CHIP_AU8810 254#ifndef CHIP_AU8810
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 6933a27a5d76..525f881f0409 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2050,8 +2050,6 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
2050} 2050}
2051 2051
2052/* Default Connections */ 2052/* Default Connections */
2053static int
2054vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type);
2055 2053
2056static void vortex_connect_default(vortex_t * vortex, int en) 2054static void vortex_connect_default(vortex_t * vortex, int en)
2057{ 2055{
@@ -2111,15 +2109,13 @@ static void vortex_connect_default(vortex_t * vortex, int en)
2111 Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0. 2109 Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.
2112*/ 2110*/
2113static int 2111static int
2114vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) 2112vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
2113 int type, int subdev)
2115{ 2114{
2116 stream_t *stream; 2115 stream_t *stream;
2117 int i, en; 2116 int i, en;
2117 struct pcm_vol *p;
2118 2118
2119 if ((nr_ch == 3)
2120 || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
2121 return -EBUSY;
2122
2123 if (dma >= 0) { 2119 if (dma >= 0) {
2124 en = 0; 2120 en = 0;
2125 vortex_adb_checkinout(vortex, 2121 vortex_adb_checkinout(vortex,
@@ -2250,6 +2246,14 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
2250 MIX_DEFIGAIN); 2246 MIX_DEFIGAIN);
2251#endif 2247#endif
2252 } 2248 }
2249 if (stream->type == VORTEX_PCM_ADB && en) {
2250 p = &vortex->pcm_vol[subdev];
2251 p->dma = dma;
2252 for (i = 0; i < nr_ch; i++)
2253 p->mixin[i] = mix[i];
2254 for (i = 0; i < ch_top; i++)
2255 p->vol[i] = 0;
2256 }
2253 } 2257 }
2254#ifndef CHIP_AU8820 2258#ifndef CHIP_AU8820
2255 else { 2259 else {
@@ -2473,7 +2477,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id)
2473 hwread(vortex->mmio, VORTEX_IRQ_STAT); 2477 hwread(vortex->mmio, VORTEX_IRQ_STAT);
2474 handled = 1; 2478 handled = 1;
2475 } 2479 }
2476 if (source & IRQ_MIDI) { 2480 if ((source & IRQ_MIDI) && vortex->rmidi) {
2477 snd_mpu401_uart_interrupt(vortex->irq, 2481 snd_mpu401_uart_interrupt(vortex->irq,
2478 vortex->rmidi->private_data); 2482 vortex->rmidi->private_data);
2479 handled = 1; 2483 handled = 1;
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 0ef2f9712208..e59f120742a4 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -122,6 +122,18 @@ static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
122 .mask = 0, 122 .mask = 0,
123}; 123};
124#endif 124#endif
125
126static void vortex_notify_pcm_vol_change(struct snd_card *card,
127 struct snd_kcontrol *kctl, int activate)
128{
129 if (activate)
130 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
131 else
132 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
133 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
134 SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id));
135}
136
125/* open callback */ 137/* open callback */
126static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) 138static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
127{ 139{
@@ -230,12 +242,14 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
230 if (stream != NULL) 242 if (stream != NULL)
231 vortex_adb_allocroute(chip, stream->dma, 243 vortex_adb_allocroute(chip, stream->dma,
232 stream->nr_ch, stream->dir, 244 stream->nr_ch, stream->dir,
233 stream->type); 245 stream->type,
246 substream->number);
234 /* Alloc routes. */ 247 /* Alloc routes. */
235 dma = 248 dma =
236 vortex_adb_allocroute(chip, -1, 249 vortex_adb_allocroute(chip, -1,
237 params_channels(hw_params), 250 params_channels(hw_params),
238 substream->stream, type); 251 substream->stream, type,
252 substream->number);
239 if (dma < 0) { 253 if (dma < 0) {
240 spin_unlock_irq(&chip->lock); 254 spin_unlock_irq(&chip->lock);
241 return dma; 255 return dma;
@@ -246,6 +260,11 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
246 vortex_adbdma_setbuffers(chip, dma, 260 vortex_adbdma_setbuffers(chip, dma,
247 params_period_bytes(hw_params), 261 params_period_bytes(hw_params),
248 params_periods(hw_params)); 262 params_periods(hw_params));
263 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
264 chip->pcm_vol[substream->number].active = 1;
265 vortex_notify_pcm_vol_change(chip->card,
266 chip->pcm_vol[substream->number].kctl, 1);
267 }
249 } 268 }
250#ifndef CHIP_AU8810 269#ifndef CHIP_AU8810
251 else { 270 else {
@@ -275,10 +294,18 @@ static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
275 spin_lock_irq(&chip->lock); 294 spin_lock_irq(&chip->lock);
276 // Delete audio routes. 295 // Delete audio routes.
277 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { 296 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
278 if (stream != NULL) 297 if (stream != NULL) {
298 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
299 chip->pcm_vol[substream->number].active = 0;
300 vortex_notify_pcm_vol_change(chip->card,
301 chip->pcm_vol[substream->number].kctl,
302 0);
303 }
279 vortex_adb_allocroute(chip, stream->dma, 304 vortex_adb_allocroute(chip, stream->dma,
280 stream->nr_ch, stream->dir, 305 stream->nr_ch, stream->dir,
281 stream->type); 306 stream->type,
307 substream->number);
308 }
282 } 309 }
283#ifndef CHIP_AU8810 310#ifndef CHIP_AU8810
284 else { 311 else {
@@ -506,6 +533,83 @@ static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = {
506 }, 533 },
507}; 534};
508 535
536/* subdevice PCM Volume control */
537
538static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol,
539 struct snd_ctl_elem_info *uinfo)
540{
541 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
542 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
543 uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
544 uinfo->value.integer.min = -128;
545 uinfo->value.integer.max = 32;
546 return 0;
547}
548
549static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol,
550 struct snd_ctl_elem_value *ucontrol)
551{
552 int i;
553 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
554 int subdev = kcontrol->id.subdevice;
555 struct pcm_vol *p = &vortex->pcm_vol[subdev];
556 int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
557 for (i = 0; i < max_chn; i++)
558 ucontrol->value.integer.value[i] = p->vol[i];
559 return 0;
560}
561
562static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
564{
565 int i;
566 int changed = 0;
567 int mixin;
568 unsigned char vol;
569 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
570 int subdev = kcontrol->id.subdevice;
571 struct pcm_vol *p = &vortex->pcm_vol[subdev];
572 int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
573 for (i = 0; i < max_chn; i++) {
574 if (p->vol[i] != ucontrol->value.integer.value[i]) {
575 p->vol[i] = ucontrol->value.integer.value[i];
576 if (p->active) {
577 switch (vortex->dma_adb[p->dma].nr_ch) {
578 case 1:
579 mixin = p->mixin[0];
580 break;
581 case 2:
582 default:
583 mixin = p->mixin[(i < 2) ? i : (i - 2)];
584 break;
585 case 4:
586 mixin = p->mixin[i];
587 break;
588 };
589 vol = p->vol[i];
590 vortex_mix_setinputvolumebyte(vortex,
591 vortex->mixplayb[i], mixin, vol);
592 }
593 changed = 1;
594 }
595 }
596 return changed;
597}
598
599static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
600
601static struct snd_kcontrol_new snd_vortex_pcm_vol __devinitdata = {
602 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
603 .name = "PCM Playback Volume",
604 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
605 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
606 SNDRV_CTL_ELEM_ACCESS_INACTIVE,
607 .info = snd_vortex_pcm_vol_info,
608 .get = snd_vortex_pcm_vol_get,
609 .put = snd_vortex_pcm_vol_put,
610 .tlv = { .p = vortex_pcm_vol_db_scale },
611};
612
509/* create a pcm device */ 613/* create a pcm device */
510static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) 614static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
511{ 615{
@@ -555,5 +659,20 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
555 return err; 659 return err;
556 } 660 }
557 } 661 }
662 if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) {
663 for (i = 0; i < NR_PCM; i++) {
664 chip->pcm_vol[i].active = 0;
665 chip->pcm_vol[i].dma = -1;
666 kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip);
667 if (!kctl)
668 return -ENOMEM;
669 chip->pcm_vol[i].kctl = kctl;
670 kctl->id.device = 0;
671 kctl->id.subdevice = i;
672 err = snd_ctl_add(chip->card, kctl);
673 if (err < 0)
674 return err;
675 }
676 }
558 return 0; 677 return 0;
559} 678}
diff --git a/sound/pci/aw2/aw2-saa7146.c b/sound/pci/aw2/aw2-saa7146.c
index 8afd8b5d1ac7..4439636971eb 100644
--- a/sound/pci/aw2/aw2-saa7146.c
+++ b/sound/pci/aw2/aw2-saa7146.c
@@ -27,7 +27,6 @@
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <asm/system.h>
31#include <asm/io.h> 30#include <asm/io.h>
32#include <sound/core.h> 31#include <sound/core.h>
33#include <sound/initval.h> 32#include <sound/initval.h>
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 95ffa6a9db6e..496f14c1a731 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2684,10 +2684,9 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2684 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); 2684 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2685 if (err < 0) 2685 if (err < 0)
2686 goto out_err; 2686 goto out_err;
2687 opl3->private_data = chip;
2687 } 2688 }
2688 2689
2689 opl3->private_data = chip;
2690
2691 sprintf(card->longname, "%s at 0x%lx, irq %i", 2690 sprintf(card->longname, "%s at 0x%lx, irq %i",
2692 card->shortname, chip->ctrl_io, chip->irq); 2691 card->shortname, chip->ctrl_io, chip->irq);
2693 2692
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index b78f3fc3c33c..6109490b83e8 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -36,7 +36,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
36 36
37 size = CT_PAGE_ALIGN(size); 37 size = CT_PAGE_ALIGN(size);
38 if (size > vm->size) { 38 if (size > vm->size) {
39 printk(KERN_ERR "ctxfi: Fail! No sufficient device virtural " 39 printk(KERN_ERR "ctxfi: Fail! No sufficient device virtual "
40 "memory space available!\n"); 40 "memory space available!\n");
41 return NULL; 41 return NULL;
42 } 42 }
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index cb557c603a80..a8faae1c85e4 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -142,6 +142,7 @@ static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
142#ifdef SUPPORT_JOYSTICK 142#ifdef SUPPORT_JOYSTICK
143static bool joystick[SNDRV_CARDS]; 143static bool joystick[SNDRV_CARDS];
144#endif 144#endif
145static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
145 146
146module_param_array(index, int, NULL, 0444); 147module_param_array(index, int, NULL, 0444);
147MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); 148MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
@@ -165,6 +166,9 @@ MODULE_PARM_DESC(enable_mpu, "Enable MPU401. (0 = off, 1 = on, 2 = auto)");
165module_param_array(joystick, bool, NULL, 0444); 166module_param_array(joystick, bool, NULL, 0444);
166MODULE_PARM_DESC(joystick, "Enable joystick."); 167MODULE_PARM_DESC(joystick, "Enable joystick.");
167#endif 168#endif
169module_param_array(radio_nr, int, NULL, 0444);
170MODULE_PARM_DESC(radio_nr, "Radio device numbers");
171
168 172
169 173
170#define NR_APUS 64 174#define NR_APUS 64
@@ -558,6 +562,7 @@ struct es1968 {
558 struct work_struct hwvol_work; 562 struct work_struct hwvol_work;
559 563
560#ifdef CONFIG_SND_ES1968_RADIO 564#ifdef CONFIG_SND_ES1968_RADIO
565 struct v4l2_device v4l2_dev;
561 struct snd_tea575x tea; 566 struct snd_tea575x tea;
562#endif 567#endif
563}; 568};
@@ -2613,6 +2618,7 @@ static int snd_es1968_free(struct es1968 *chip)
2613 2618
2614#ifdef CONFIG_SND_ES1968_RADIO 2619#ifdef CONFIG_SND_ES1968_RADIO
2615 snd_tea575x_exit(&chip->tea); 2620 snd_tea575x_exit(&chip->tea);
2621 v4l2_device_unregister(&chip->v4l2_dev);
2616#endif 2622#endif
2617 2623
2618 if (chip->irq >= 0) 2624 if (chip->irq >= 0)
@@ -2655,6 +2661,7 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2655 int capt_streams, 2661 int capt_streams,
2656 int chip_type, 2662 int chip_type,
2657 int do_pm, 2663 int do_pm,
2664 int radio_nr,
2658 struct es1968 **chip_ret) 2665 struct es1968 **chip_ret)
2659{ 2666{
2660 static struct snd_device_ops ops = { 2667 static struct snd_device_ops ops = {
@@ -2751,7 +2758,14 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2751 snd_card_set_dev(card, &pci->dev); 2758 snd_card_set_dev(card, &pci->dev);
2752 2759
2753#ifdef CONFIG_SND_ES1968_RADIO 2760#ifdef CONFIG_SND_ES1968_RADIO
2761 err = v4l2_device_register(&pci->dev, &chip->v4l2_dev);
2762 if (err < 0) {
2763 snd_es1968_free(chip);
2764 return err;
2765 }
2766 chip->tea.v4l2_dev = &chip->v4l2_dev;
2754 chip->tea.private_data = chip; 2767 chip->tea.private_data = chip;
2768 chip->tea.radio_nr = radio_nr;
2755 chip->tea.ops = &snd_es1968_tea_ops; 2769 chip->tea.ops = &snd_es1968_tea_ops;
2756 strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); 2770 strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card));
2757 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); 2771 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
@@ -2797,6 +2811,7 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci,
2797 pcm_substreams_c[dev], 2811 pcm_substreams_c[dev],
2798 pci_id->driver_data, 2812 pci_id->driver_data,
2799 use_pm[dev], 2813 use_pm[dev],
2814 radio_nr[dev],
2800 &chip)) < 0) { 2815 &chip)) < 0) {
2801 snd_card_free(card); 2816 snd_card_free(card);
2802 return err; 2817 return err;
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 9597ef1eccca..a416ea8af3e9 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -58,6 +58,7 @@ static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card
58 * High 16-bits are video (radio) device number + 1 58 * High 16-bits are video (radio) device number + 1
59 */ 59 */
60static int tea575x_tuner[SNDRV_CARDS]; 60static int tea575x_tuner[SNDRV_CARDS];
61static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
61 62
62module_param_array(index, int, NULL, 0444); 63module_param_array(index, int, NULL, 0444);
63MODULE_PARM_DESC(index, "Index value for the FM801 soundcard."); 64MODULE_PARM_DESC(index, "Index value for the FM801 soundcard.");
@@ -67,6 +68,9 @@ module_param_array(enable, bool, NULL, 0444);
67MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); 68MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
68module_param_array(tea575x_tuner, int, NULL, 0444); 69module_param_array(tea575x_tuner, int, NULL, 0444);
69MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only)."); 70MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only).");
71module_param_array(radio_nr, int, NULL, 0444);
72MODULE_PARM_DESC(radio_nr, "Radio device numbers");
73
70 74
71#define TUNER_DISABLED (1<<3) 75#define TUNER_DISABLED (1<<3)
72#define TUNER_ONLY (1<<4) 76#define TUNER_ONLY (1<<4)
@@ -197,6 +201,7 @@ struct fm801 {
197 struct snd_info_entry *proc_entry; 201 struct snd_info_entry *proc_entry;
198 202
199#ifdef CONFIG_SND_FM801_TEA575X_BOOL 203#ifdef CONFIG_SND_FM801_TEA575X_BOOL
204 struct v4l2_device v4l2_dev;
200 struct snd_tea575x tea; 205 struct snd_tea575x tea;
201#endif 206#endif
202 207
@@ -1154,8 +1159,10 @@ static int snd_fm801_free(struct fm801 *chip)
1154 1159
1155 __end_hw: 1160 __end_hw:
1156#ifdef CONFIG_SND_FM801_TEA575X_BOOL 1161#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1157 if (!(chip->tea575x_tuner & TUNER_DISABLED)) 1162 if (!(chip->tea575x_tuner & TUNER_DISABLED)) {
1158 snd_tea575x_exit(&chip->tea); 1163 snd_tea575x_exit(&chip->tea);
1164 v4l2_device_unregister(&chip->v4l2_dev);
1165 }
1159#endif 1166#endif
1160 if (chip->irq >= 0) 1167 if (chip->irq >= 0)
1161 free_irq(chip->irq, chip); 1168 free_irq(chip->irq, chip);
@@ -1175,6 +1182,7 @@ static int snd_fm801_dev_free(struct snd_device *device)
1175static int __devinit snd_fm801_create(struct snd_card *card, 1182static int __devinit snd_fm801_create(struct snd_card *card,
1176 struct pci_dev * pci, 1183 struct pci_dev * pci,
1177 int tea575x_tuner, 1184 int tea575x_tuner,
1185 int radio_nr,
1178 struct fm801 ** rchip) 1186 struct fm801 ** rchip)
1179{ 1187{
1180 struct fm801 *chip; 1188 struct fm801 *chip;
@@ -1234,6 +1242,13 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1234 snd_card_set_dev(card, &pci->dev); 1242 snd_card_set_dev(card, &pci->dev);
1235 1243
1236#ifdef CONFIG_SND_FM801_TEA575X_BOOL 1244#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1245 err = v4l2_device_register(&pci->dev, &chip->v4l2_dev);
1246 if (err < 0) {
1247 snd_fm801_free(chip);
1248 return err;
1249 }
1250 chip->tea.v4l2_dev = &chip->v4l2_dev;
1251 chip->tea.radio_nr = radio_nr;
1237 chip->tea.private_data = chip; 1252 chip->tea.private_data = chip;
1238 chip->tea.ops = &snd_fm801_tea_ops; 1253 chip->tea.ops = &snd_fm801_tea_ops;
1239 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); 1254 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
@@ -1241,6 +1256,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1241 (tea575x_tuner & TUNER_TYPE_MASK) < 4) { 1256 (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
1242 if (snd_tea575x_init(&chip->tea)) { 1257 if (snd_tea575x_init(&chip->tea)) {
1243 snd_printk(KERN_ERR "TEA575x radio not found\n"); 1258 snd_printk(KERN_ERR "TEA575x radio not found\n");
1259 snd_fm801_free(chip);
1244 return -ENODEV; 1260 return -ENODEV;
1245 } 1261 }
1246 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) { 1262 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) {
@@ -1287,7 +1303,7 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
1287 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); 1303 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
1288 if (err < 0) 1304 if (err < 0)
1289 return err; 1305 return err;
1290 if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], &chip)) < 0) { 1306 if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], radio_nr[dev], &chip)) < 0) {
1291 snd_card_free(card); 1307 snd_card_free(card);
1292 return err; 1308 return err;
1293 } 1309 }
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c
deleted file mode 100644
index 3b5170b9700f..000000000000
--- a/sound/pci/hda/alc260_quirks.c
+++ /dev/null
@@ -1,968 +0,0 @@
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_FUJITSU_S702X,
11 ALC260_ACER,
12 ALC260_WILL,
13 ALC260_REPLACER_672V,
14 ALC260_FAVORIT100,
15#ifdef CONFIG_SND_DEBUG
16 ALC260_TEST,
17#endif
18 ALC260_MODEL_LAST /* last tag */
19};
20
21static const hda_nid_t alc260_dac_nids[1] = {
22 /* front */
23 0x02,
24};
25
26static const hda_nid_t alc260_adc_nids[1] = {
27 /* ADC0 */
28 0x04,
29};
30
31static const hda_nid_t alc260_adc_nids_alt[1] = {
32 /* ADC1 */
33 0x05,
34};
35
36/* NIDs used when simultaneous access to both ADCs makes sense. Note that
37 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
38 */
39static const hda_nid_t alc260_dual_adc_nids[2] = {
40 /* ADC0, ADC1 */
41 0x04, 0x05
42};
43
44#define ALC260_DIGOUT_NID 0x03
45#define ALC260_DIGIN_NID 0x06
46
47static const struct hda_input_mux alc260_capture_source = {
48 .num_items = 4,
49 .items = {
50 { "Mic", 0x0 },
51 { "Front Mic", 0x1 },
52 { "Line", 0x2 },
53 { "CD", 0x4 },
54 },
55};
56
57/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
58 * headphone jack and the internal CD lines since these are the only pins at
59 * which audio can appear. For flexibility, also allow the option of
60 * recording the mixer output on the second ADC (ADC0 doesn't have a
61 * connection to the mixer output).
62 */
63static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
64 {
65 .num_items = 3,
66 .items = {
67 { "Mic/Line", 0x0 },
68 { "CD", 0x4 },
69 { "Headphone", 0x2 },
70 },
71 },
72 {
73 .num_items = 4,
74 .items = {
75 { "Mic/Line", 0x0 },
76 { "CD", 0x4 },
77 { "Headphone", 0x2 },
78 { "Mixer", 0x5 },
79 },
80 },
81
82};
83
84/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
85 * the Fujitsu S702x, but jacks are marked differently.
86 */
87static const struct hda_input_mux alc260_acer_capture_sources[2] = {
88 {
89 .num_items = 4,
90 .items = {
91 { "Mic", 0x0 },
92 { "Line", 0x2 },
93 { "CD", 0x4 },
94 { "Headphone", 0x5 },
95 },
96 },
97 {
98 .num_items = 5,
99 .items = {
100 { "Mic", 0x0 },
101 { "Line", 0x2 },
102 { "CD", 0x4 },
103 { "Headphone", 0x6 },
104 { "Mixer", 0x5 },
105 },
106 },
107};
108
109/* Maxdata Favorit 100XS */
110static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
111 {
112 .num_items = 2,
113 .items = {
114 { "Line/Mic", 0x0 },
115 { "CD", 0x4 },
116 },
117 },
118 {
119 .num_items = 3,
120 .items = {
121 { "Line/Mic", 0x0 },
122 { "CD", 0x4 },
123 { "Mixer", 0x5 },
124 },
125 },
126};
127
128/*
129 * This is just place-holder, so there's something for alc_build_pcms to look
130 * at when it calculates the maximum number of channels. ALC260 has no mixer
131 * element which allows changing the channel mode, so the verb list is
132 * never used.
133 */
134static const struct hda_channel_mode alc260_modes[1] = {
135 { 2, NULL },
136};
137
138
139/* Mixer combinations
140 *
141 * basic: base_output + input + pc_beep + capture
142 * fujitsu: fujitsu + capture
143 * acer: acer + capture
144 */
145
146static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
147 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
148 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
149 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
150 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
151 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
152 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
153 { } /* end */
154};
155
156static const struct snd_kcontrol_new alc260_input_mixer[] = {
157 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
158 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
159 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
160 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
161 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
162 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
163 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
164 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
165 { } /* end */
166};
167
168/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
169 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
170 */
171static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
172 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
173 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
174 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
175 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
176 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
177 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
178 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
179 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
180 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
181 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
182 { } /* end */
183};
184
185/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
186 * versions of the ALC260 don't act on requests to enable mic bias from NID
187 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
188 * datasheet doesn't mention this restriction. At this stage it's not clear
189 * whether this behaviour is intentional or is a hardware bug in chip
190 * revisions available in early 2006. Therefore for now allow the
191 * "Headphone Jack Mode" control to span all choices, but if it turns out
192 * that the lack of mic bias for this NID is intentional we could change the
193 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
194 *
195 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
196 * don't appear to make the mic bias available from the "line" jack, even
197 * though the NID used for this jack (0x14) can supply it. The theory is
198 * that perhaps Acer have included blocking capacitors between the ALC260
199 * and the output jack. If this turns out to be the case for all such
200 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
201 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
202 *
203 * The C20x Tablet series have a mono internal speaker which is controlled
204 * via the chip's Mono sum widget and pin complex, so include the necessary
205 * controls for such models. On models without a "mono speaker" the control
206 * won't do anything.
207 */
208static const struct snd_kcontrol_new alc260_acer_mixer[] = {
209 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
210 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
211 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
212 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
213 HDA_OUTPUT),
214 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
215 HDA_INPUT),
216 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
217 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
219 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
220 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
221 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
222 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
223 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
224 { } /* end */
225};
226
227/* Maxdata Favorit 100XS: one output and one input (0x12) jack
228 */
229static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
230 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
231 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
232 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
233 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
234 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
235 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
236 { } /* end */
237};
238
239/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
240 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
241 */
242static const struct snd_kcontrol_new alc260_will_mixer[] = {
243 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
244 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
245 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
246 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
247 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
248 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
249 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
250 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
251 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
252 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
253 { } /* end */
254};
255
256/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
257 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
258 */
259static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
260 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
261 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
262 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
263 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
264 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
265 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
266 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
267 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
268 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
269 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
270 { } /* end */
271};
272
273/*
274 * initialization verbs
275 */
276static const struct hda_verb alc260_init_verbs[] = {
277 /* Line In pin widget for input */
278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
279 /* CD pin widget for input */
280 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
281 /* Mic1 (rear panel) pin widget for input and vref at 80% */
282 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
283 /* Mic2 (front panel) pin widget for input and vref at 80% */
284 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
285 /* LINE-2 is used for line-out in rear */
286 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
287 /* select line-out */
288 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
289 /* LINE-OUT pin */
290 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
291 /* enable HP */
292 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
293 /* enable Mono */
294 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
295 /* mute capture amp left and right */
296 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
297 /* set connection select to line in (default select for this ADC) */
298 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
299 /* mute capture amp left and right */
300 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
301 /* set connection select to line in (default select for this ADC) */
302 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
303 /* set vol=0 Line-Out mixer amp left and right */
304 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
305 /* unmute pin widget amp left and right (no gain on this amp) */
306 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
307 /* set vol=0 HP mixer amp left and right */
308 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
309 /* unmute pin widget amp left and right (no gain on this amp) */
310 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
311 /* set vol=0 Mono mixer amp left and right */
312 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
313 /* unmute pin widget amp left and right (no gain on this amp) */
314 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
315 /* unmute LINE-2 out pin */
316 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
317 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
318 * Line In 2 = 0x03
319 */
320 /* mute analog inputs */
321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
322 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
325 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
326 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
327 /* mute Front out path */
328 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
329 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
330 /* mute Headphone out path */
331 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
332 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
333 /* mute Mono out path */
334 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
335 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
336 { }
337};
338
339/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
340 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
341 * audio = 0x16, internal speaker = 0x10.
342 */
343static const struct hda_verb alc260_fujitsu_init_verbs[] = {
344 /* Disable all GPIOs */
345 {0x01, AC_VERB_SET_GPIO_MASK, 0},
346 /* Internal speaker is connected to headphone pin */
347 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
348 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
350 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
351 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
352 /* Ensure all other unused pins are disabled and muted. */
353 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
354 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
355 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
356 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
357 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
358 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
359 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
360 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
361
362 /* Disable digital (SPDIF) pins */
363 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
364 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
365
366 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
367 * when acting as an output.
368 */
369 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
370
371 /* Start with output sum widgets muted and their output gains at min */
372 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
373 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
374 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
375 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
377 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
378 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
379 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
380 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
381
382 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
383 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
384 /* Unmute Line1 pin widget output buffer since it starts as an output.
385 * If the pin mode is changed by the user the pin mode control will
386 * take care of enabling the pin's input/output buffers as needed.
387 * Therefore there's no need to enable the input buffer at this
388 * stage.
389 */
390 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
391 /* Unmute input buffer of pin widget used for Line-in (no equiv
392 * mixer ctrl)
393 */
394 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
395
396 /* Mute capture amp left and right */
397 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
398 /* Set ADC connection select to match default mixer setting - line
399 * in (on mic1 pin)
400 */
401 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
402
403 /* Do the same for the second ADC: mute capture input amp and
404 * set ADC connection to line in (on mic1 pin)
405 */
406 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
407 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
408
409 /* Mute all inputs to mixer widget (even unconnected ones) */
410 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
411 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
413 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
414 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
415 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
416 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
418
419 { }
420};
421
422/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
423 * similar laptops (adapted from Fujitsu init verbs).
424 */
425static const struct hda_verb alc260_acer_init_verbs[] = {
426 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
427 * the headphone jack. Turn this on and rely on the standard mute
428 * methods whenever the user wants to turn these outputs off.
429 */
430 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
431 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
432 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
433 /* Internal speaker/Headphone jack is connected to Line-out pin */
434 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
435 /* Internal microphone/Mic jack is connected to Mic1 pin */
436 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
437 /* Line In jack is connected to Line1 pin */
438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
439 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
440 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
441 /* Ensure all other unused pins are disabled and muted. */
442 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
443 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
444 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
445 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
448 /* Disable digital (SPDIF) pins */
449 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
450 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
451
452 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
453 * bus when acting as outputs.
454 */
455 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
456 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
457
458 /* Start with output sum widgets muted and their output gains at min */
459 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
460 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
461 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
462 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
464 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
465 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
466 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
467 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
468
469 /* Unmute Line-out pin widget amp left and right
470 * (no equiv mixer ctrl)
471 */
472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
473 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
474 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
475 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
476 * inputs. If the pin mode is changed by the user the pin mode control
477 * will take care of enabling the pin's input/output buffers as needed.
478 * Therefore there's no need to enable the input buffer at this
479 * stage.
480 */
481 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
482 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
483
484 /* Mute capture amp left and right */
485 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
486 /* Set ADC connection select to match default mixer setting - mic
487 * (on mic1 pin)
488 */
489 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
490
491 /* Do similar with the second ADC: mute capture input amp and
492 * set ADC connection to mic to match ALSA's default state.
493 */
494 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
495 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
496
497 /* Mute all inputs to mixer widget (even unconnected ones) */
498 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
505 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
506
507 { }
508};
509
510/* Initialisation sequence for Maxdata Favorit 100XS
511 * (adapted from Acer init verbs).
512 */
513static const struct hda_verb alc260_favorit100_init_verbs[] = {
514 /* GPIO 0 enables the output jack.
515 * Turn this on and rely on the standard mute
516 * methods whenever the user wants to turn these outputs off.
517 */
518 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
519 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
520 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
521 /* Line/Mic input jack is connected to Mic1 pin */
522 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
523 /* Ensure all other unused pins are disabled and muted. */
524 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
525 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
526 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
527 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
528 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
529 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
530 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
532 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
533 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
534 /* Disable digital (SPDIF) pins */
535 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
536 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
537
538 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
539 * bus when acting as outputs.
540 */
541 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
542 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
543
544 /* Start with output sum widgets muted and their output gains at min */
545 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
546 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
547 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
548 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
549 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
550 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
551 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
552 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
553 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
554
555 /* Unmute Line-out pin widget amp left and right
556 * (no equiv mixer ctrl)
557 */
558 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
559 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
560 * inputs. If the pin mode is changed by the user the pin mode control
561 * will take care of enabling the pin's input/output buffers as needed.
562 * Therefore there's no need to enable the input buffer at this
563 * stage.
564 */
565 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
566
567 /* Mute capture amp left and right */
568 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
569 /* Set ADC connection select to match default mixer setting - mic
570 * (on mic1 pin)
571 */
572 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
573
574 /* Do similar with the second ADC: mute capture input amp and
575 * set ADC connection to mic to match ALSA's default state.
576 */
577 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
578 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
579
580 /* Mute all inputs to mixer widget (even unconnected ones) */
581 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
582 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
583 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
584 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
585 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
586 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
587 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
589
590 { }
591};
592
593static const struct hda_verb alc260_will_verbs[] = {
594 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
595 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
596 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
597 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
598 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
599 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
600 {}
601};
602
603static const struct hda_verb alc260_replacer_672v_verbs[] = {
604 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
605 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
606 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
607
608 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
609 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
610 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
611
612 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
613 {}
614};
615
616/* toggle speaker-output according to the hp-jack state */
617static void alc260_replacer_672v_automute(struct hda_codec *codec)
618{
619 unsigned int present;
620
621 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
622 present = snd_hda_jack_detect(codec, 0x0f);
623 if (present) {
624 snd_hda_codec_write_cache(codec, 0x01, 0,
625 AC_VERB_SET_GPIO_DATA, 1);
626 snd_hda_codec_write_cache(codec, 0x0f, 0,
627 AC_VERB_SET_PIN_WIDGET_CONTROL,
628 PIN_HP);
629 } else {
630 snd_hda_codec_write_cache(codec, 0x01, 0,
631 AC_VERB_SET_GPIO_DATA, 0);
632 snd_hda_codec_write_cache(codec, 0x0f, 0,
633 AC_VERB_SET_PIN_WIDGET_CONTROL,
634 PIN_OUT);
635 }
636}
637
638static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
639 unsigned int res)
640{
641 if ((res >> 26) == ALC_HP_EVENT)
642 alc260_replacer_672v_automute(codec);
643}
644
645static const struct hda_verb alc260_hp_dc7600_verbs[] = {
646 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
647 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
648 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
649 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
650 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
651 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
652 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
653 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
654 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
655 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
656 {}
657};
658
659/* Test configuration for debugging, modelled after the ALC880 test
660 * configuration.
661 */
662#ifdef CONFIG_SND_DEBUG
663static const hda_nid_t alc260_test_dac_nids[1] = {
664 0x02,
665};
666static const hda_nid_t alc260_test_adc_nids[2] = {
667 0x04, 0x05,
668};
669/* For testing the ALC260, each input MUX needs its own definition since
670 * the signal assignments are different. This assumes that the first ADC
671 * is NID 0x04.
672 */
673static const struct hda_input_mux alc260_test_capture_sources[2] = {
674 {
675 .num_items = 7,
676 .items = {
677 { "MIC1 pin", 0x0 },
678 { "MIC2 pin", 0x1 },
679 { "LINE1 pin", 0x2 },
680 { "LINE2 pin", 0x3 },
681 { "CD pin", 0x4 },
682 { "LINE-OUT pin", 0x5 },
683 { "HP-OUT pin", 0x6 },
684 },
685 },
686 {
687 .num_items = 8,
688 .items = {
689 { "MIC1 pin", 0x0 },
690 { "MIC2 pin", 0x1 },
691 { "LINE1 pin", 0x2 },
692 { "LINE2 pin", 0x3 },
693 { "CD pin", 0x4 },
694 { "Mixer", 0x5 },
695 { "LINE-OUT pin", 0x6 },
696 { "HP-OUT pin", 0x7 },
697 },
698 },
699};
700static const struct snd_kcontrol_new alc260_test_mixer[] = {
701 /* Output driver widgets */
702 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
703 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
704 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
705 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
706 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
707 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
708
709 /* Modes for retasking pin widgets
710 * Note: the ALC260 doesn't seem to act on requests to enable mic
711 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
712 * mention this restriction. At this stage it's not clear whether
713 * this behaviour is intentional or is a hardware bug in chip
714 * revisions available at least up until early 2006. Therefore for
715 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
716 * choices, but if it turns out that the lack of mic bias for these
717 * NIDs is intentional we could change their modes from
718 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
719 */
720 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
721 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
722 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
723 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
724 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
725 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
726
727 /* Loopback mixer controls */
728 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
729 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
730 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
731 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
732 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
733 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
734 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
735 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
736 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
737 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
738 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
739 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
740 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
741 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
742
743 /* Controls for GPIO pins, assuming they are configured as outputs */
744 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
745 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
746 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
747 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
748
749 /* Switches to allow the digital IO pins to be enabled. The datasheet
750 * is ambigious as to which NID is which; testing on laptops which
751 * make this output available should provide clarification.
752 */
753 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
754 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
755
756 /* A switch allowing EAPD to be enabled. Some laptops seem to use
757 * this output to turn on an external amplifier.
758 */
759 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
760 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
761
762 { } /* end */
763};
764static const struct hda_verb alc260_test_init_verbs[] = {
765 /* Enable all GPIOs as outputs with an initial value of 0 */
766 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
767 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
768 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
769
770 /* Enable retasking pins as output, initially without power amp */
771 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
772 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
773 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
774 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
775 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
776 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
777
778 /* Disable digital (SPDIF) pins initially, but users can enable
779 * them via a mixer switch. In the case of SPDIF-out, this initverb
780 * payload also sets the generation to 0, output to be in "consumer"
781 * PCM format, copyright asserted, no pre-emphasis and no validity
782 * control.
783 */
784 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
785 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
786
787 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
788 * OUT1 sum bus when acting as an output.
789 */
790 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
791 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
792 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
793 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
794
795 /* Start with output sum widgets muted and their output gains at min */
796 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
797 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
798 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
799 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
800 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
801 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
802 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
803 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
804 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
805
806 /* Unmute retasking pin widget output buffers since the default
807 * state appears to be output. As the pin mode is changed by the
808 * user the pin mode control will take care of enabling the pin's
809 * input/output buffers as needed.
810 */
811 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
814 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
815 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
816 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
817 /* Also unmute the mono-out pin widget */
818 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
819
820 /* Mute capture amp left and right */
821 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
822 /* Set ADC connection select to match default mixer setting (mic1
823 * pin)
824 */
825 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
826
827 /* Do the same for the second ADC: mute capture input amp and
828 * set ADC connection to mic1 pin
829 */
830 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
831 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
832
833 /* Mute all inputs to mixer widget (even unconnected ones) */
834 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
835 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
836 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
837 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
838 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
839 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
840 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
841 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
842
843 { }
844};
845#endif
846
847/*
848 * ALC260 configurations
849 */
850static const char * const alc260_models[ALC260_MODEL_LAST] = {
851 [ALC260_BASIC] = "basic",
852 [ALC260_FUJITSU_S702X] = "fujitsu",
853 [ALC260_ACER] = "acer",
854 [ALC260_WILL] = "will",
855 [ALC260_REPLACER_672V] = "replacer",
856 [ALC260_FAVORIT100] = "favorit100",
857#ifdef CONFIG_SND_DEBUG
858 [ALC260_TEST] = "test",
859#endif
860 [ALC260_AUTO] = "auto",
861};
862
863static const struct snd_pci_quirk alc260_cfg_tbl[] = {
864 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
865 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
866 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
867 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
868 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
869 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
870 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
871 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
872 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
873 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
874 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
875 {}
876};
877
878static const struct alc_config_preset alc260_presets[] = {
879 [ALC260_BASIC] = {
880 .mixers = { alc260_base_output_mixer,
881 alc260_input_mixer },
882 .init_verbs = { alc260_init_verbs },
883 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
884 .dac_nids = alc260_dac_nids,
885 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
886 .adc_nids = alc260_dual_adc_nids,
887 .num_channel_mode = ARRAY_SIZE(alc260_modes),
888 .channel_mode = alc260_modes,
889 .input_mux = &alc260_capture_source,
890 },
891 [ALC260_FUJITSU_S702X] = {
892 .mixers = { alc260_fujitsu_mixer },
893 .init_verbs = { alc260_fujitsu_init_verbs },
894 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
895 .dac_nids = alc260_dac_nids,
896 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
897 .adc_nids = alc260_dual_adc_nids,
898 .num_channel_mode = ARRAY_SIZE(alc260_modes),
899 .channel_mode = alc260_modes,
900 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
901 .input_mux = alc260_fujitsu_capture_sources,
902 },
903 [ALC260_ACER] = {
904 .mixers = { alc260_acer_mixer },
905 .init_verbs = { alc260_acer_init_verbs },
906 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
907 .dac_nids = alc260_dac_nids,
908 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
909 .adc_nids = alc260_dual_adc_nids,
910 .num_channel_mode = ARRAY_SIZE(alc260_modes),
911 .channel_mode = alc260_modes,
912 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
913 .input_mux = alc260_acer_capture_sources,
914 },
915 [ALC260_FAVORIT100] = {
916 .mixers = { alc260_favorit100_mixer },
917 .init_verbs = { alc260_favorit100_init_verbs },
918 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
919 .dac_nids = alc260_dac_nids,
920 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
921 .adc_nids = alc260_dual_adc_nids,
922 .num_channel_mode = ARRAY_SIZE(alc260_modes),
923 .channel_mode = alc260_modes,
924 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
925 .input_mux = alc260_favorit100_capture_sources,
926 },
927 [ALC260_WILL] = {
928 .mixers = { alc260_will_mixer },
929 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
930 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
931 .dac_nids = alc260_dac_nids,
932 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
933 .adc_nids = alc260_adc_nids,
934 .dig_out_nid = ALC260_DIGOUT_NID,
935 .num_channel_mode = ARRAY_SIZE(alc260_modes),
936 .channel_mode = alc260_modes,
937 .input_mux = &alc260_capture_source,
938 },
939 [ALC260_REPLACER_672V] = {
940 .mixers = { alc260_replacer_672v_mixer },
941 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
942 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
943 .dac_nids = alc260_dac_nids,
944 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
945 .adc_nids = alc260_adc_nids,
946 .dig_out_nid = ALC260_DIGOUT_NID,
947 .num_channel_mode = ARRAY_SIZE(alc260_modes),
948 .channel_mode = alc260_modes,
949 .input_mux = &alc260_capture_source,
950 .unsol_event = alc260_replacer_672v_unsol_event,
951 .init_hook = alc260_replacer_672v_automute,
952 },
953#ifdef CONFIG_SND_DEBUG
954 [ALC260_TEST] = {
955 .mixers = { alc260_test_mixer },
956 .init_verbs = { alc260_test_init_verbs },
957 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
958 .dac_nids = alc260_test_dac_nids,
959 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
960 .adc_nids = alc260_test_adc_nids,
961 .num_channel_mode = ARRAY_SIZE(alc260_modes),
962 .channel_mode = alc260_modes,
963 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
964 .input_mux = alc260_test_capture_sources,
965 },
966#endif
967};
968
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c
deleted file mode 100644
index 501501ef36a9..000000000000
--- a/sound/pci/hda/alc880_quirks.c
+++ /dev/null
@@ -1,1707 +0,0 @@
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#ifdef CONFIG_SND_DEBUG
30 ALC880_TEST,
31#endif
32 ALC880_MODEL_LAST /* last tag */
33};
34
35/*
36 * ALC880 3-stack model
37 *
38 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
39 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
40 * F-Mic = 0x1b, HP = 0x19
41 */
42
43static const hda_nid_t alc880_dac_nids[4] = {
44 /* front, rear, clfe, rear_surr */
45 0x02, 0x05, 0x04, 0x03
46};
47
48static const hda_nid_t alc880_adc_nids[3] = {
49 /* ADC0-2 */
50 0x07, 0x08, 0x09,
51};
52
53/* The datasheet says the node 0x07 is connected from inputs,
54 * but it shows zero connection in the real implementation on some devices.
55 * Note: this is a 915GAV bug, fixed on 915GLV
56 */
57static const hda_nid_t alc880_adc_nids_alt[2] = {
58 /* ADC1-2 */
59 0x08, 0x09,
60};
61
62#define ALC880_DIGOUT_NID 0x06
63#define ALC880_DIGIN_NID 0x0a
64#define ALC880_PIN_CD_NID 0x1c
65
66static const struct hda_input_mux alc880_capture_source = {
67 .num_items = 4,
68 .items = {
69 { "Mic", 0x0 },
70 { "Front Mic", 0x3 },
71 { "Line", 0x2 },
72 { "CD", 0x4 },
73 },
74};
75
76/* channel source setting (2/6 channel selection for 3-stack) */
77/* 2ch mode */
78static const struct hda_verb alc880_threestack_ch2_init[] = {
79 /* set line-in to input, mute it */
80 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
81 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
82 /* set mic-in to input vref 80%, mute it */
83 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
84 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
85 { } /* end */
86};
87
88/* 6ch mode */
89static const struct hda_verb alc880_threestack_ch6_init[] = {
90 /* set line-in to output, unmute it */
91 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
92 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
93 /* set mic-in to output, unmute it */
94 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
95 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
96 { } /* end */
97};
98
99static const struct hda_channel_mode alc880_threestack_modes[2] = {
100 { 2, alc880_threestack_ch2_init },
101 { 6, alc880_threestack_ch6_init },
102};
103
104static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
105 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
106 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
107 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
108 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
109 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
110 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
111 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
112 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
113 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
114 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
115 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
116 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
119 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
120 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
121 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
122 {
123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
124 .name = "Channel Mode",
125 .info = alc_ch_mode_info,
126 .get = alc_ch_mode_get,
127 .put = alc_ch_mode_put,
128 },
129 { } /* end */
130};
131
132/*
133 * ALC880 5-stack model
134 *
135 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
136 * Side = 0x02 (0xd)
137 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
138 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
139 */
140
141/* additional mixers to alc880_three_stack_mixer */
142static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
143 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
144 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
145 { } /* end */
146};
147
148/* channel source setting (6/8 channel selection for 5-stack) */
149/* 6ch mode */
150static const struct hda_verb alc880_fivestack_ch6_init[] = {
151 /* set line-in to input, mute it */
152 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
153 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
154 { } /* end */
155};
156
157/* 8ch mode */
158static const struct hda_verb alc880_fivestack_ch8_init[] = {
159 /* set line-in to output, unmute it */
160 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
161 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
162 { } /* end */
163};
164
165static const struct hda_channel_mode alc880_fivestack_modes[2] = {
166 { 6, alc880_fivestack_ch6_init },
167 { 8, alc880_fivestack_ch8_init },
168};
169
170
171/*
172 * ALC880 6-stack model
173 *
174 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
175 * Side = 0x05 (0x0f)
176 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
177 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
178 */
179
180static const hda_nid_t alc880_6st_dac_nids[4] = {
181 /* front, rear, clfe, rear_surr */
182 0x02, 0x03, 0x04, 0x05
183};
184
185static const struct hda_input_mux alc880_6stack_capture_source = {
186 .num_items = 4,
187 .items = {
188 { "Mic", 0x0 },
189 { "Front Mic", 0x1 },
190 { "Line", 0x2 },
191 { "CD", 0x4 },
192 },
193};
194
195/* fixed 8-channels */
196static const struct hda_channel_mode alc880_sixstack_modes[1] = {
197 { 8, NULL },
198};
199
200static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
201 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
202 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
204 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
205 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
206 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
207 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
208 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
209 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
210 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
211 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
212 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
213 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
214 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
215 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
216 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
217 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
218 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
219 {
220 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
221 .name = "Channel Mode",
222 .info = alc_ch_mode_info,
223 .get = alc_ch_mode_get,
224 .put = alc_ch_mode_put,
225 },
226 { } /* end */
227};
228
229
230/*
231 * ALC880 W810 model
232 *
233 * W810 has rear IO for:
234 * Front (DAC 02)
235 * Surround (DAC 03)
236 * Center/LFE (DAC 04)
237 * Digital out (06)
238 *
239 * The system also has a pair of internal speakers, and a headphone jack.
240 * These are both connected to Line2 on the codec, hence to DAC 02.
241 *
242 * There is a variable resistor to control the speaker or headphone
243 * volume. This is a hardware-only device without a software API.
244 *
245 * Plugging headphones in will disable the internal speakers. This is
246 * implemented in hardware, not via the driver using jack sense. In
247 * a similar fashion, plugging into the rear socket marked "front" will
248 * disable both the speakers and headphones.
249 *
250 * For input, there's a microphone jack, and an "audio in" jack.
251 * These may not do anything useful with this driver yet, because I
252 * haven't setup any initialization verbs for these yet...
253 */
254
255static const hda_nid_t alc880_w810_dac_nids[3] = {
256 /* front, rear/surround, clfe */
257 0x02, 0x03, 0x04
258};
259
260/* fixed 6 channels */
261static const struct hda_channel_mode alc880_w810_modes[1] = {
262 { 6, NULL }
263};
264
265/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
266static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
270 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
271 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
272 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
273 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
274 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
276 { } /* end */
277};
278
279
280/*
281 * Z710V model
282 *
283 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
284 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
285 * Line = 0x1a
286 */
287
288static const hda_nid_t alc880_z71v_dac_nids[1] = {
289 0x02
290};
291#define ALC880_Z71V_HP_DAC 0x03
292
293/* fixed 2 channels */
294static const struct hda_channel_mode alc880_2_jack_modes[1] = {
295 { 2, NULL }
296};
297
298static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
299 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
300 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
301 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
302 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
303 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
304 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
307 { } /* end */
308};
309
310
311/*
312 * ALC880 F1734 model
313 *
314 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
315 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
316 */
317
318static const hda_nid_t alc880_f1734_dac_nids[1] = {
319 0x03
320};
321#define ALC880_F1734_HP_DAC 0x02
322
323static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
324 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
325 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
327 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
328 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
329 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
330 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
331 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
332 { } /* end */
333};
334
335static const struct hda_input_mux alc880_f1734_capture_source = {
336 .num_items = 2,
337 .items = {
338 { "Mic", 0x1 },
339 { "CD", 0x4 },
340 },
341};
342
343
344/*
345 * ALC880 ASUS model
346 *
347 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
348 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
349 * Mic = 0x18, Line = 0x1a
350 */
351
352#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
353#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
354
355static const struct snd_kcontrol_new alc880_asus_mixer[] = {
356 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
357 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
358 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
359 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
360 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
361 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
362 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
363 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
364 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
365 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
366 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
367 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
369 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
370 {
371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
372 .name = "Channel Mode",
373 .info = alc_ch_mode_info,
374 .get = alc_ch_mode_get,
375 .put = alc_ch_mode_put,
376 },
377 { } /* end */
378};
379
380/*
381 * ALC880 ASUS W1V model
382 *
383 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
384 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
385 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
386 */
387
388/* additional mixers to alc880_asus_mixer */
389static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
390 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
391 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
392 { } /* end */
393};
394
395/* TCL S700 */
396static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
398 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
400 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
401 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
404 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
405 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
406 { } /* end */
407};
408
409/* Uniwill */
410static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
411 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
412 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
413 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
414 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
415 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
416 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
417 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
418 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 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_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
425 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
426 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
427 {
428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
429 .name = "Channel Mode",
430 .info = alc_ch_mode_info,
431 .get = alc_ch_mode_get,
432 .put = alc_ch_mode_put,
433 },
434 { } /* end */
435};
436
437static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
438 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
439 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
440 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
441 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
442 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
443 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
444 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
445 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
446 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
447 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
448 { } /* end */
449};
450
451static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
452 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
453 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
454 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
455 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
457 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
458 { } /* end */
459};
460
461/*
462 * initialize the codec volumes, etc
463 */
464
465/*
466 * generic initialization of ADC, input mixers and output mixers
467 */
468static const struct hda_verb alc880_volume_init_verbs[] = {
469 /*
470 * Unmute ADC0-2 and set the default input to mic-in
471 */
472 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
474 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
475 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
476 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
477 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
478
479 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
480 * mixer widget
481 * Note: PASD motherboards uses the Line In 2 as the input for front
482 * panel mic (mic 2)
483 */
484 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
485 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
486 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
492
493 /*
494 * Set up output mixers (0x0c - 0x0f)
495 */
496 /* set vol=0 to output mixers */
497 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
498 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
499 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
501 /* set up input amps for analog loopback */
502 /* Amp Indices: DAC = 0, mixer = 1 */
503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
504 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
509 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
511
512 { }
513};
514
515/*
516 * 3-stack pin configuration:
517 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
518 */
519static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
520 /*
521 * preset connection lists of input pins
522 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
523 */
524 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
525 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
526 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
527
528 /*
529 * Set pin mode and muting
530 */
531 /* set front pin widgets 0x14 for output */
532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
534 /* Mic1 (rear panel) pin widget for input and vref at 80% */
535 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
536 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
537 /* Mic2 (as headphone out) for HP output */
538 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
539 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
540 /* Line In pin widget for input */
541 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
542 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
543 /* Line2 (as front mic) pin widget for input and vref at 80% */
544 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
545 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
546 /* CD pin widget for input */
547 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
548
549 { }
550};
551
552/*
553 * 5-stack pin configuration:
554 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
555 * line-in/side = 0x1a, f-mic = 0x1b
556 */
557static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
558 /*
559 * preset connection lists of input pins
560 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
561 */
562 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
563 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
564
565 /*
566 * Set pin mode and muting
567 */
568 /* set pin widgets 0x14-0x17 for output */
569 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
571 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
572 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
573 /* unmute pins for output (no gain on this amp) */
574 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
576 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
577 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
578
579 /* Mic1 (rear panel) pin widget for input and vref at 80% */
580 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
581 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
582 /* Mic2 (as headphone out) for HP output */
583 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
584 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
585 /* Line In pin widget for input */
586 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
587 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
588 /* Line2 (as front mic) pin widget for input and vref at 80% */
589 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
590 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
591 /* CD pin widget for input */
592 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
593
594 { }
595};
596
597/*
598 * W810 pin configuration:
599 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
600 */
601static const struct hda_verb alc880_pin_w810_init_verbs[] = {
602 /* hphone/speaker input selector: front DAC */
603 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
604
605 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
606 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
607 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
608 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
609 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
610 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
611
612 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
613 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
614
615 { }
616};
617
618/*
619 * Z71V pin configuration:
620 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
621 */
622static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
623 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
624 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
627
628 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
629 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
630 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
631 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
632
633 { }
634};
635
636/*
637 * 6-stack pin configuration:
638 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
639 * f-mic = 0x19, line = 0x1a, HP = 0x1b
640 */
641static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
642 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
643
644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
645 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
646 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
648 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
649 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
650 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
651 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
652
653 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
654 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
655 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
656 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
657 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
658 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
659 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
660 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
661 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
662
663 { }
664};
665
666/*
667 * Uniwill pin configuration:
668 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
669 * line = 0x1a
670 */
671static const struct hda_verb alc880_uniwill_init_verbs[] = {
672 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
673
674 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
675 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
676 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
678 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
679 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
680 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
681 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
682 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
684 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
685 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
686 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
687 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
688
689 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
691 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
692 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
695 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
696 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
697 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
698
699 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
700 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
701
702 { }
703};
704
705/*
706* Uniwill P53
707* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
708 */
709static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
710 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
711
712 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
713 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
714 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
715 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
716 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
717 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
720 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
721 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
722 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
723 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
724
725 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
726 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
727 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
728 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
729 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
730 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
731
732 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
733 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_DCVOL_EVENT},
734
735 { }
736};
737
738static const struct hda_verb alc880_beep_init_verbs[] = {
739 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
740 { }
741};
742
743static void alc880_uniwill_setup(struct hda_codec *codec)
744{
745 struct alc_spec *spec = codec->spec;
746
747 spec->autocfg.hp_pins[0] = 0x14;
748 spec->autocfg.speaker_pins[0] = 0x15;
749 spec->autocfg.speaker_pins[0] = 0x16;
750 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
751}
752
753static void alc880_uniwill_init_hook(struct hda_codec *codec)
754{
755 alc_hp_automute(codec);
756 alc88x_simple_mic_automute(codec);
757}
758
759static void alc880_uniwill_unsol_event(struct hda_codec *codec,
760 unsigned int res)
761{
762 /* Looks like the unsol event is incompatible with the standard
763 * definition. 4bit tag is placed at 28 bit!
764 */
765 res >>= 28;
766 switch (res) {
767 case ALC_MIC_EVENT:
768 alc88x_simple_mic_automute(codec);
769 break;
770 default:
771 alc_exec_unsol_event(codec, res);
772 break;
773 }
774}
775
776static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
777{
778 alc_exec_unsol_event(codec, res >> 28);
779}
780
781static void alc880_uniwill_p53_setup(struct hda_codec *codec)
782{
783 struct alc_spec *spec = codec->spec;
784
785 spec->autocfg.hp_pins[0] = 0x14;
786 spec->autocfg.speaker_pins[0] = 0x15;
787 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
788}
789
790static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
791{
792 unsigned int present;
793
794 present = snd_hda_codec_read(codec, 0x21, 0,
795 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
796 present &= HDA_AMP_VOLMASK;
797 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
798 HDA_AMP_VOLMASK, present);
799 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
800 HDA_AMP_VOLMASK, present);
801}
802
803static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
804 unsigned int res)
805{
806 /* Looks like the unsol event is incompatible with the standard
807 * definition. 4bit tag is placed at 28 bit!
808 */
809 res >>= 28;
810 if (res == ALC_DCVOL_EVENT)
811 alc880_uniwill_p53_dcvol_automute(codec);
812 else
813 alc_exec_unsol_event(codec, res);
814}
815
816/*
817 * F1734 pin configuration:
818 * HP = 0x14, speaker-out = 0x15, mic = 0x18
819 */
820static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
821 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
822 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
823 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
824 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
825 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
826
827 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
828 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
829 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
830 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
831
832 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
833 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
834 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
835 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
836 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
837 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
838 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
839 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
840 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
841
842 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
843 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_DCVOL_EVENT},
844
845 { }
846};
847
848/*
849 * ASUS pin configuration:
850 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
851 */
852static const struct hda_verb alc880_pin_asus_init_verbs[] = {
853 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
854 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
855 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
856 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
857
858 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
859 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
860 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
861 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
862 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
863 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
864 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
865 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
866
867 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
868 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
869 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
871 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
872 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
873 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
874 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
875 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
876
877 { }
878};
879
880/* Enable GPIO mask and set output */
881#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
882#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
883#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
884
885/* Clevo m520g init */
886static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
887 /* headphone output */
888 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
889 /* line-out */
890 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
891 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
892 /* Line-in */
893 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
894 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
895 /* CD */
896 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
897 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
898 /* Mic1 (rear panel) */
899 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
900 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
901 /* Mic2 (front panel) */
902 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
903 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
904 /* headphone */
905 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
906 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
907 /* change to EAPD mode */
908 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
909 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
910
911 { }
912};
913
914static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
915 /* change to EAPD mode */
916 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
917 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
918
919 /* Headphone output */
920 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
921 /* Front output*/
922 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
923 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
924
925 /* Line In pin widget for input */
926 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
927 /* CD pin widget for input */
928 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
929 /* Mic1 (rear panel) pin widget for input and vref at 80% */
930 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
931
932 /* change to EAPD mode */
933 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
934 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
935
936 { }
937};
938
939/*
940 * LG m1 express dual
941 *
942 * Pin assignment:
943 * Rear Line-In/Out (blue): 0x14
944 * Build-in Mic-In: 0x15
945 * Speaker-out: 0x17
946 * HP-Out (green): 0x1b
947 * Mic-In/Out (red): 0x19
948 * SPDIF-Out: 0x1e
949 */
950
951/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
952static const hda_nid_t alc880_lg_dac_nids[3] = {
953 0x05, 0x02, 0x03
954};
955
956/* seems analog CD is not working */
957static const struct hda_input_mux alc880_lg_capture_source = {
958 .num_items = 3,
959 .items = {
960 { "Mic", 0x1 },
961 { "Line", 0x5 },
962 { "Internal Mic", 0x6 },
963 },
964};
965
966/* 2,4,6 channel modes */
967static const struct hda_verb alc880_lg_ch2_init[] = {
968 /* set line-in and mic-in to input */
969 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
970 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
971 { }
972};
973
974static const struct hda_verb alc880_lg_ch4_init[] = {
975 /* set line-in to out and mic-in to input */
976 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
977 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
978 { }
979};
980
981static const struct hda_verb alc880_lg_ch6_init[] = {
982 /* set line-in and mic-in to output */
983 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
984 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
985 { }
986};
987
988static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
989 { 2, alc880_lg_ch2_init },
990 { 4, alc880_lg_ch4_init },
991 { 6, alc880_lg_ch6_init },
992};
993
994static const struct snd_kcontrol_new alc880_lg_mixer[] = {
995 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
996 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
997 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
998 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
999 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1000 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1001 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1002 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1003 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1004 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1005 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1006 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1007 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1008 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1009 {
1010 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1011 .name = "Channel Mode",
1012 .info = alc_ch_mode_info,
1013 .get = alc_ch_mode_get,
1014 .put = alc_ch_mode_put,
1015 },
1016 { } /* end */
1017};
1018
1019static const struct hda_verb alc880_lg_init_verbs[] = {
1020 /* set capture source to mic-in */
1021 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1022 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1023 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1024 /* mute all amp mixer inputs */
1025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1026 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1027 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1028 /* line-in to input */
1029 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1030 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1031 /* built-in mic */
1032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1033 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1034 /* speaker-out */
1035 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1036 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1037 /* mic-in to input */
1038 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1039 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1040 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1041 /* HP-out */
1042 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1043 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1044 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1045 /* jack sense */
1046 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1047 { }
1048};
1049
1050/* toggle speaker-output according to the hp-jack state */
1051static void alc880_lg_setup(struct hda_codec *codec)
1052{
1053 struct alc_spec *spec = codec->spec;
1054
1055 spec->autocfg.hp_pins[0] = 0x1b;
1056 spec->autocfg.speaker_pins[0] = 0x17;
1057 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
1058}
1059
1060#ifdef CONFIG_SND_HDA_POWER_SAVE
1061static const struct hda_amp_list alc880_lg_loopbacks[] = {
1062 { 0x0b, HDA_INPUT, 1 },
1063 { 0x0b, HDA_INPUT, 6 },
1064 { 0x0b, HDA_INPUT, 7 },
1065 { } /* end */
1066};
1067#endif
1068
1069/*
1070 * Test configuration for debugging
1071 *
1072 * Almost all inputs/outputs are enabled. I/O pins can be configured via
1073 * enum controls.
1074 */
1075#ifdef CONFIG_SND_DEBUG
1076static const hda_nid_t alc880_test_dac_nids[4] = {
1077 0x02, 0x03, 0x04, 0x05
1078};
1079
1080static const struct hda_input_mux alc880_test_capture_source = {
1081 .num_items = 7,
1082 .items = {
1083 { "In-1", 0x0 },
1084 { "In-2", 0x1 },
1085 { "In-3", 0x2 },
1086 { "In-4", 0x3 },
1087 { "CD", 0x4 },
1088 { "Front", 0x5 },
1089 { "Surround", 0x6 },
1090 },
1091};
1092
1093static const struct hda_channel_mode alc880_test_modes[4] = {
1094 { 2, NULL },
1095 { 4, NULL },
1096 { 6, NULL },
1097 { 8, NULL },
1098};
1099
1100static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
1101 struct snd_ctl_elem_info *uinfo)
1102{
1103 static const char * const texts[] = {
1104 "N/A", "Line Out", "HP Out",
1105 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1106 };
1107 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1108 uinfo->count = 1;
1109 uinfo->value.enumerated.items = 8;
1110 if (uinfo->value.enumerated.item >= 8)
1111 uinfo->value.enumerated.item = 7;
1112 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1113 return 0;
1114}
1115
1116static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
1117 struct snd_ctl_elem_value *ucontrol)
1118{
1119 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1120 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1121 unsigned int pin_ctl, item = 0;
1122
1123 pin_ctl = snd_hda_codec_read(codec, nid, 0,
1124 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1125 if (pin_ctl & AC_PINCTL_OUT_EN) {
1126 if (pin_ctl & AC_PINCTL_HP_EN)
1127 item = 2;
1128 else
1129 item = 1;
1130 } else if (pin_ctl & AC_PINCTL_IN_EN) {
1131 switch (pin_ctl & AC_PINCTL_VREFEN) {
1132 case AC_PINCTL_VREF_HIZ: item = 3; break;
1133 case AC_PINCTL_VREF_50: item = 4; break;
1134 case AC_PINCTL_VREF_GRD: item = 5; break;
1135 case AC_PINCTL_VREF_80: item = 6; break;
1136 case AC_PINCTL_VREF_100: item = 7; break;
1137 }
1138 }
1139 ucontrol->value.enumerated.item[0] = item;
1140 return 0;
1141}
1142
1143static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
1144 struct snd_ctl_elem_value *ucontrol)
1145{
1146 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1147 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1148 static const unsigned int ctls[] = {
1149 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1150 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1151 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1152 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1153 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1154 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1155 };
1156 unsigned int old_ctl, new_ctl;
1157
1158 old_ctl = snd_hda_codec_read(codec, nid, 0,
1159 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1160 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1161 if (old_ctl != new_ctl) {
1162 int val;
1163 snd_hda_codec_write_cache(codec, nid, 0,
1164 AC_VERB_SET_PIN_WIDGET_CONTROL,
1165 new_ctl);
1166 val = ucontrol->value.enumerated.item[0] >= 3 ?
1167 HDA_AMP_MUTE : 0;
1168 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1169 HDA_AMP_MUTE, val);
1170 return 1;
1171 }
1172 return 0;
1173}
1174
1175static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
1176 struct snd_ctl_elem_info *uinfo)
1177{
1178 static const char * const texts[] = {
1179 "Front", "Surround", "CLFE", "Side"
1180 };
1181 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1182 uinfo->count = 1;
1183 uinfo->value.enumerated.items = 4;
1184 if (uinfo->value.enumerated.item >= 4)
1185 uinfo->value.enumerated.item = 3;
1186 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1187 return 0;
1188}
1189
1190static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
1191 struct snd_ctl_elem_value *ucontrol)
1192{
1193 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1194 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1195 unsigned int sel;
1196
1197 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1198 ucontrol->value.enumerated.item[0] = sel & 3;
1199 return 0;
1200}
1201
1202static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
1203 struct snd_ctl_elem_value *ucontrol)
1204{
1205 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1206 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1207 unsigned int sel;
1208
1209 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1210 if (ucontrol->value.enumerated.item[0] != sel) {
1211 sel = ucontrol->value.enumerated.item[0] & 3;
1212 snd_hda_codec_write_cache(codec, nid, 0,
1213 AC_VERB_SET_CONNECT_SEL, sel);
1214 return 1;
1215 }
1216 return 0;
1217}
1218
1219#define PIN_CTL_TEST(xname,nid) { \
1220 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1221 .name = xname, \
1222 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1223 .info = alc_test_pin_ctl_info, \
1224 .get = alc_test_pin_ctl_get, \
1225 .put = alc_test_pin_ctl_put, \
1226 .private_value = nid \
1227 }
1228
1229#define PIN_SRC_TEST(xname,nid) { \
1230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1231 .name = xname, \
1232 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1233 .info = alc_test_pin_src_info, \
1234 .get = alc_test_pin_src_get, \
1235 .put = alc_test_pin_src_put, \
1236 .private_value = nid \
1237 }
1238
1239static const struct snd_kcontrol_new alc880_test_mixer[] = {
1240 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1241 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1242 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1243 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1245 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1246 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
1247 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1248 PIN_CTL_TEST("Front Pin Mode", 0x14),
1249 PIN_CTL_TEST("Surround Pin Mode", 0x15),
1250 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1251 PIN_CTL_TEST("Side Pin Mode", 0x17),
1252 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1253 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1254 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1255 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1256 PIN_SRC_TEST("In-1 Pin Source", 0x18),
1257 PIN_SRC_TEST("In-2 Pin Source", 0x19),
1258 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1259 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1260 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1261 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1262 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1263 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1264 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1265 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1266 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1267 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1268 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1269 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1270 {
1271 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1272 .name = "Channel Mode",
1273 .info = alc_ch_mode_info,
1274 .get = alc_ch_mode_get,
1275 .put = alc_ch_mode_put,
1276 },
1277 { } /* end */
1278};
1279
1280static const struct hda_verb alc880_test_init_verbs[] = {
1281 /* Unmute inputs of 0x0c - 0x0f */
1282 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1283 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1284 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1285 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1286 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1287 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1288 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1289 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1290 /* Vol output for 0x0c-0x0f */
1291 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1292 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1294 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1295 /* Set output pins 0x14-0x17 */
1296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1297 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1298 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1299 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1300 /* Unmute output pins 0x14-0x17 */
1301 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1302 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1303 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1304 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1305 /* Set input pins 0x18-0x1c */
1306 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1307 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1308 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1309 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1310 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1311 /* Mute input pins 0x18-0x1b */
1312 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1313 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1314 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1315 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1316 /* ADC set up */
1317 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1318 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1320 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1321 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1322 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1323 /* Analog input/passthru */
1324 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1325 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1326 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1327 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1328 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1329 { }
1330};
1331#endif
1332
1333/*
1334 */
1335
1336static const char * const alc880_models[ALC880_MODEL_LAST] = {
1337 [ALC880_3ST] = "3stack",
1338 [ALC880_TCL_S700] = "tcl",
1339 [ALC880_3ST_DIG] = "3stack-digout",
1340 [ALC880_CLEVO] = "clevo",
1341 [ALC880_5ST] = "5stack",
1342 [ALC880_5ST_DIG] = "5stack-digout",
1343 [ALC880_W810] = "w810",
1344 [ALC880_Z71V] = "z71v",
1345 [ALC880_6ST] = "6stack",
1346 [ALC880_6ST_DIG] = "6stack-digout",
1347 [ALC880_ASUS] = "asus",
1348 [ALC880_ASUS_W1V] = "asus-w1v",
1349 [ALC880_ASUS_DIG] = "asus-dig",
1350 [ALC880_ASUS_DIG2] = "asus-dig2",
1351 [ALC880_UNIWILL_DIG] = "uniwill",
1352 [ALC880_UNIWILL_P53] = "uniwill-p53",
1353 [ALC880_FUJITSU] = "fujitsu",
1354 [ALC880_F1734] = "F1734",
1355 [ALC880_LG] = "lg",
1356#ifdef CONFIG_SND_DEBUG
1357 [ALC880_TEST] = "test",
1358#endif
1359 [ALC880_AUTO] = "auto",
1360};
1361
1362static const struct snd_pci_quirk alc880_cfg_tbl[] = {
1363 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
1364 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
1365 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
1366 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
1367 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
1368 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
1369 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
1370 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
1371 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
1372 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
1373 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
1374 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
1375 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
1376 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
1377 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
1378 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
1379 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
1380 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
1381 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
1382 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
1383 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
1384 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
1385 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
1386 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
1387 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
1388 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
1389 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
1390 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
1391 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
1392 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
1393 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
1394 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
1395 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
1396 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
1397 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
1398 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
1399 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
1400 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
1401 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
1402 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
1403 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
1404 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
1405 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
1406 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
1407 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
1408 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1409 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
1410 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
1411 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
1412 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
1413 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
1414 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
1415 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
1416 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
1417 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
1418 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
1419 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
1420 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
1421 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
1422 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
1423 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
1424 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
1425 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
1426 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
1427 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
1428 /* default Intel */
1429 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
1430 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
1431 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1432 {}
1433};
1434
1435/*
1436 * ALC880 codec presets
1437 */
1438static const struct alc_config_preset alc880_presets[] = {
1439 [ALC880_3ST] = {
1440 .mixers = { alc880_three_stack_mixer },
1441 .init_verbs = { alc880_volume_init_verbs,
1442 alc880_pin_3stack_init_verbs },
1443 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1444 .dac_nids = alc880_dac_nids,
1445 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1446 .channel_mode = alc880_threestack_modes,
1447 .need_dac_fix = 1,
1448 .input_mux = &alc880_capture_source,
1449 },
1450 [ALC880_3ST_DIG] = {
1451 .mixers = { alc880_three_stack_mixer },
1452 .init_verbs = { alc880_volume_init_verbs,
1453 alc880_pin_3stack_init_verbs },
1454 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1455 .dac_nids = alc880_dac_nids,
1456 .dig_out_nid = ALC880_DIGOUT_NID,
1457 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1458 .channel_mode = alc880_threestack_modes,
1459 .need_dac_fix = 1,
1460 .input_mux = &alc880_capture_source,
1461 },
1462 [ALC880_TCL_S700] = {
1463 .mixers = { alc880_tcl_s700_mixer },
1464 .init_verbs = { alc880_volume_init_verbs,
1465 alc880_pin_tcl_S700_init_verbs,
1466 alc880_gpio2_init_verbs },
1467 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1468 .dac_nids = alc880_dac_nids,
1469 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
1470 .num_adc_nids = 1, /* single ADC */
1471 .hp_nid = 0x03,
1472 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1473 .channel_mode = alc880_2_jack_modes,
1474 .input_mux = &alc880_capture_source,
1475 },
1476 [ALC880_5ST] = {
1477 .mixers = { alc880_three_stack_mixer,
1478 alc880_five_stack_mixer},
1479 .init_verbs = { alc880_volume_init_verbs,
1480 alc880_pin_5stack_init_verbs },
1481 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1482 .dac_nids = alc880_dac_nids,
1483 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1484 .channel_mode = alc880_fivestack_modes,
1485 .input_mux = &alc880_capture_source,
1486 },
1487 [ALC880_5ST_DIG] = {
1488 .mixers = { alc880_three_stack_mixer,
1489 alc880_five_stack_mixer },
1490 .init_verbs = { alc880_volume_init_verbs,
1491 alc880_pin_5stack_init_verbs },
1492 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1493 .dac_nids = alc880_dac_nids,
1494 .dig_out_nid = ALC880_DIGOUT_NID,
1495 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1496 .channel_mode = alc880_fivestack_modes,
1497 .input_mux = &alc880_capture_source,
1498 },
1499 [ALC880_6ST] = {
1500 .mixers = { alc880_six_stack_mixer },
1501 .init_verbs = { alc880_volume_init_verbs,
1502 alc880_pin_6stack_init_verbs },
1503 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1504 .dac_nids = alc880_6st_dac_nids,
1505 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1506 .channel_mode = alc880_sixstack_modes,
1507 .input_mux = &alc880_6stack_capture_source,
1508 },
1509 [ALC880_6ST_DIG] = {
1510 .mixers = { alc880_six_stack_mixer },
1511 .init_verbs = { alc880_volume_init_verbs,
1512 alc880_pin_6stack_init_verbs },
1513 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1514 .dac_nids = alc880_6st_dac_nids,
1515 .dig_out_nid = ALC880_DIGOUT_NID,
1516 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1517 .channel_mode = alc880_sixstack_modes,
1518 .input_mux = &alc880_6stack_capture_source,
1519 },
1520 [ALC880_W810] = {
1521 .mixers = { alc880_w810_base_mixer },
1522 .init_verbs = { alc880_volume_init_verbs,
1523 alc880_pin_w810_init_verbs,
1524 alc880_gpio2_init_verbs },
1525 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
1526 .dac_nids = alc880_w810_dac_nids,
1527 .dig_out_nid = ALC880_DIGOUT_NID,
1528 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1529 .channel_mode = alc880_w810_modes,
1530 .input_mux = &alc880_capture_source,
1531 },
1532 [ALC880_Z71V] = {
1533 .mixers = { alc880_z71v_mixer },
1534 .init_verbs = { alc880_volume_init_verbs,
1535 alc880_pin_z71v_init_verbs },
1536 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
1537 .dac_nids = alc880_z71v_dac_nids,
1538 .dig_out_nid = ALC880_DIGOUT_NID,
1539 .hp_nid = 0x03,
1540 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1541 .channel_mode = alc880_2_jack_modes,
1542 .input_mux = &alc880_capture_source,
1543 },
1544 [ALC880_F1734] = {
1545 .mixers = { alc880_f1734_mixer },
1546 .init_verbs = { alc880_volume_init_verbs,
1547 alc880_pin_f1734_init_verbs },
1548 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
1549 .dac_nids = alc880_f1734_dac_nids,
1550 .hp_nid = 0x02,
1551 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1552 .channel_mode = alc880_2_jack_modes,
1553 .input_mux = &alc880_f1734_capture_source,
1554 .unsol_event = alc880_uniwill_p53_unsol_event,
1555 .setup = alc880_uniwill_p53_setup,
1556 .init_hook = alc_hp_automute,
1557 },
1558 [ALC880_ASUS] = {
1559 .mixers = { alc880_asus_mixer },
1560 .init_verbs = { alc880_volume_init_verbs,
1561 alc880_pin_asus_init_verbs,
1562 alc880_gpio1_init_verbs },
1563 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1564 .dac_nids = alc880_asus_dac_nids,
1565 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1566 .channel_mode = alc880_asus_modes,
1567 .need_dac_fix = 1,
1568 .input_mux = &alc880_capture_source,
1569 },
1570 [ALC880_ASUS_DIG] = {
1571 .mixers = { alc880_asus_mixer },
1572 .init_verbs = { alc880_volume_init_verbs,
1573 alc880_pin_asus_init_verbs,
1574 alc880_gpio1_init_verbs },
1575 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1576 .dac_nids = alc880_asus_dac_nids,
1577 .dig_out_nid = ALC880_DIGOUT_NID,
1578 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1579 .channel_mode = alc880_asus_modes,
1580 .need_dac_fix = 1,
1581 .input_mux = &alc880_capture_source,
1582 },
1583 [ALC880_ASUS_DIG2] = {
1584 .mixers = { alc880_asus_mixer },
1585 .init_verbs = { alc880_volume_init_verbs,
1586 alc880_pin_asus_init_verbs,
1587 alc880_gpio2_init_verbs }, /* use GPIO2 */
1588 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1589 .dac_nids = alc880_asus_dac_nids,
1590 .dig_out_nid = ALC880_DIGOUT_NID,
1591 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1592 .channel_mode = alc880_asus_modes,
1593 .need_dac_fix = 1,
1594 .input_mux = &alc880_capture_source,
1595 },
1596 [ALC880_ASUS_W1V] = {
1597 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
1598 .init_verbs = { alc880_volume_init_verbs,
1599 alc880_pin_asus_init_verbs,
1600 alc880_gpio1_init_verbs },
1601 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1602 .dac_nids = alc880_asus_dac_nids,
1603 .dig_out_nid = ALC880_DIGOUT_NID,
1604 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1605 .channel_mode = alc880_asus_modes,
1606 .need_dac_fix = 1,
1607 .input_mux = &alc880_capture_source,
1608 },
1609 [ALC880_UNIWILL_DIG] = {
1610 .mixers = { alc880_asus_mixer },
1611 .init_verbs = { alc880_volume_init_verbs,
1612 alc880_pin_asus_init_verbs },
1613 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1614 .dac_nids = alc880_asus_dac_nids,
1615 .dig_out_nid = ALC880_DIGOUT_NID,
1616 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1617 .channel_mode = alc880_asus_modes,
1618 .need_dac_fix = 1,
1619 .input_mux = &alc880_capture_source,
1620 },
1621 [ALC880_UNIWILL] = {
1622 .mixers = { alc880_uniwill_mixer },
1623 .init_verbs = { alc880_volume_init_verbs,
1624 alc880_uniwill_init_verbs },
1625 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1626 .dac_nids = alc880_asus_dac_nids,
1627 .dig_out_nid = ALC880_DIGOUT_NID,
1628 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1629 .channel_mode = alc880_threestack_modes,
1630 .need_dac_fix = 1,
1631 .input_mux = &alc880_capture_source,
1632 .unsol_event = alc880_uniwill_unsol_event,
1633 .setup = alc880_uniwill_setup,
1634 .init_hook = alc880_uniwill_init_hook,
1635 },
1636 [ALC880_UNIWILL_P53] = {
1637 .mixers = { alc880_uniwill_p53_mixer },
1638 .init_verbs = { alc880_volume_init_verbs,
1639 alc880_uniwill_p53_init_verbs },
1640 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1641 .dac_nids = alc880_asus_dac_nids,
1642 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1643 .channel_mode = alc880_threestack_modes,
1644 .input_mux = &alc880_capture_source,
1645 .unsol_event = alc880_uniwill_p53_unsol_event,
1646 .setup = alc880_uniwill_p53_setup,
1647 .init_hook = alc_hp_automute,
1648 },
1649 [ALC880_FUJITSU] = {
1650 .mixers = { alc880_fujitsu_mixer },
1651 .init_verbs = { alc880_volume_init_verbs,
1652 alc880_uniwill_p53_init_verbs,
1653 alc880_beep_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_2_jack_modes),
1658 .channel_mode = alc880_2_jack_modes,
1659 .input_mux = &alc880_capture_source,
1660 .unsol_event = alc880_uniwill_p53_unsol_event,
1661 .setup = alc880_uniwill_p53_setup,
1662 .init_hook = alc_hp_automute,
1663 },
1664 [ALC880_CLEVO] = {
1665 .mixers = { alc880_three_stack_mixer },
1666 .init_verbs = { alc880_volume_init_verbs,
1667 alc880_pin_clevo_init_verbs },
1668 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1669 .dac_nids = alc880_dac_nids,
1670 .hp_nid = 0x03,
1671 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1672 .channel_mode = alc880_threestack_modes,
1673 .need_dac_fix = 1,
1674 .input_mux = &alc880_capture_source,
1675 },
1676 [ALC880_LG] = {
1677 .mixers = { alc880_lg_mixer },
1678 .init_verbs = { alc880_volume_init_verbs,
1679 alc880_lg_init_verbs },
1680 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
1681 .dac_nids = alc880_lg_dac_nids,
1682 .dig_out_nid = ALC880_DIGOUT_NID,
1683 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
1684 .channel_mode = alc880_lg_ch_modes,
1685 .need_dac_fix = 1,
1686 .input_mux = &alc880_lg_capture_source,
1687 .unsol_event = alc880_unsol_event,
1688 .setup = alc880_lg_setup,
1689 .init_hook = alc_hp_automute,
1690#ifdef CONFIG_SND_HDA_POWER_SAVE
1691 .loopbacks = alc880_lg_loopbacks,
1692#endif
1693 },
1694#ifdef CONFIG_SND_DEBUG
1695 [ALC880_TEST] = {
1696 .mixers = { alc880_test_mixer },
1697 .init_verbs = { alc880_test_init_verbs },
1698 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
1699 .dac_nids = alc880_test_dac_nids,
1700 .dig_out_nid = ALC880_DIGOUT_NID,
1701 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
1702 .channel_mode = alc880_test_modes,
1703 .input_mux = &alc880_test_capture_source,
1704 },
1705#endif
1706};
1707
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c
deleted file mode 100644
index bb364a53f546..000000000000
--- a/sound/pci/hda/alc882_quirks.c
+++ /dev/null
@@ -1,866 +0,0 @@
1/*
2 * ALC882/ALC883/ALC888/ALC889 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC882 models */
7enum {
8 ALC882_AUTO,
9 ALC885_MBA21,
10 ALC885_MBP3,
11 ALC885_MB5,
12 ALC885_MACMINI3,
13 ALC885_IMAC91,
14 ALC889A_MB31,
15 ALC882_MODEL_LAST,
16};
17
18#define ALC882_DIGOUT_NID 0x06
19#define ALC882_DIGIN_NID 0x0a
20#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
21#define ALC883_DIGIN_NID ALC882_DIGIN_NID
22#define ALC1200_DIGOUT_NID 0x10
23
24
25static const struct hda_channel_mode alc882_ch_modes[1] = {
26 { 8, NULL }
27};
28
29/* DACs */
30static const hda_nid_t alc882_dac_nids[4] = {
31 /* front, rear, clfe, rear_surr */
32 0x02, 0x03, 0x04, 0x05
33};
34#define alc883_dac_nids alc882_dac_nids
35
36/* ADCs */
37#define alc882_adc_nids alc880_adc_nids
38#define alc882_adc_nids_alt alc880_adc_nids_alt
39#define alc883_adc_nids alc882_adc_nids_alt
40
41static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
42#define alc883_capsrc_nids alc882_capsrc_nids_alt
43
44/* input MUX */
45/* FIXME: should be a matrix-type input source selection */
46
47static const struct hda_input_mux alc882_capture_source = {
48 .num_items = 4,
49 .items = {
50 { "Mic", 0x0 },
51 { "Front Mic", 0x1 },
52 { "Line", 0x2 },
53 { "CD", 0x4 },
54 },
55};
56
57#define alc883_capture_source alc882_capture_source
58
59static const struct hda_input_mux mb5_capture_source = {
60 .num_items = 3,
61 .items = {
62 { "Mic", 0x1 },
63 { "Line", 0x7 },
64 { "CD", 0x4 },
65 },
66};
67
68static const struct hda_input_mux macmini3_capture_source = {
69 .num_items = 2,
70 .items = {
71 { "Line", 0x2 },
72 { "CD", 0x4 },
73 },
74};
75
76static const struct hda_input_mux alc883_3stack_6ch_intel = {
77 .num_items = 4,
78 .items = {
79 { "Mic", 0x1 },
80 { "Front Mic", 0x0 },
81 { "Line", 0x2 },
82 { "CD", 0x4 },
83 },
84};
85
86static const struct hda_input_mux alc889A_mb31_capture_source = {
87 .num_items = 2,
88 .items = {
89 { "Mic", 0x0 },
90 /* Front Mic (0x01) unused */
91 { "Line", 0x2 },
92 /* Line 2 (0x03) unused */
93 /* CD (0x04) unused? */
94 },
95};
96
97static const struct hda_input_mux alc889A_imac91_capture_source = {
98 .num_items = 2,
99 .items = {
100 { "Mic", 0x01 },
101 { "Line", 0x2 }, /* Not sure! */
102 },
103};
104
105/* Macbook Air 2,1 */
106
107static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
108 { 2, NULL },
109};
110
111/*
112 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
113 */
114
115/*
116 * 2ch mode
117 */
118static const struct hda_verb alc885_mbp_ch2_init[] = {
119 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
120 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
121 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
122 { } /* end */
123};
124
125/*
126 * 4ch mode
127 */
128static const struct hda_verb alc885_mbp_ch4_init[] = {
129 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
130 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
131 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
132 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
133 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
134 { } /* end */
135};
136
137static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
138 { 2, alc885_mbp_ch2_init },
139 { 4, alc885_mbp_ch4_init },
140};
141
142/*
143 * 2ch
144 * Speakers/Woofer/HP = Front
145 * LineIn = Input
146 */
147static const struct hda_verb alc885_mb5_ch2_init[] = {
148 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
149 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
150 { } /* end */
151};
152
153/*
154 * 6ch mode
155 * Speakers/HP = Front
156 * Woofer = LFE
157 * LineIn = Surround
158 */
159static const struct hda_verb alc885_mb5_ch6_init[] = {
160 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
161 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
162 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
163 { } /* end */
164};
165
166static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
167 { 2, alc885_mb5_ch2_init },
168 { 6, alc885_mb5_ch6_init },
169};
170
171#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
172
173/* Macbook Air 2,1 same control for HP and internal Speaker */
174
175static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
176 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
177 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
178 { }
179};
180
181
182static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
183 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
184 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
185 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
186 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
187 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
188 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
189 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
191 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
192 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
194 { } /* end */
195};
196
197static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
198 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
199 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
200 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
201 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
202 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
203 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
204 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
205 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
206 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
207 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
208 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
209 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
210 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
212 { } /* end */
213};
214
215static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
216 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
217 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
218 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
219 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
220 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
221 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
222 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
223 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
224 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
225 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
226 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
227 { } /* end */
228};
229
230static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
231 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
232 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
233 { } /* end */
234};
235
236
237static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
238 {
239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
240 .name = "Channel Mode",
241 .info = alc_ch_mode_info,
242 .get = alc_ch_mode_get,
243 .put = alc_ch_mode_put,
244 },
245 { } /* end */
246};
247
248static const struct hda_verb alc882_base_init_verbs[] = {
249 /* Front mixer: unmute input/output amp left and right (volume = 0) */
250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
252 /* Rear mixer */
253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
255 /* CLFE mixer */
256 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
257 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
258 /* Side mixer */
259 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
260 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
261
262 /* Front Pin: output 0 (0x0c) */
263 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
264 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
265 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
266 /* Rear Pin: output 1 (0x0d) */
267 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
268 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
269 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
270 /* CLFE Pin: output 2 (0x0e) */
271 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
272 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
273 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
274 /* Side Pin: output 3 (0x0f) */
275 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
276 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
277 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
278 /* Mic (rear) pin: input vref at 80% */
279 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
280 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
281 /* Front Mic pin: input vref at 80% */
282 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
283 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
284 /* Line In pin: input */
285 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
286 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
287 /* Line-2 In: Headphone output (output 0 - 0x0c) */
288 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
289 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
290 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
291 /* CD pin widget for input */
292 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
293
294 /* FIXME: use matrix-type input source selection */
295 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
296 /* Input mixer2 */
297 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
298 /* Input mixer3 */
299 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
300 /* ADC2: mute amp left and right */
301 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
302 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
303 /* ADC3: mute amp left and right */
304 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
305 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
306
307 { }
308};
309
310#define alc883_init_verbs alc882_base_init_verbs
311
312/* Macbook 5,1 */
313static const struct hda_verb alc885_mb5_init_verbs[] = {
314 /* DACs */
315 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
316 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
317 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
318 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
319 /* Front mixer */
320 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
321 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
322 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
323 /* Surround mixer */
324 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
325 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
326 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
327 /* LFE mixer */
328 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
329 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
330 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
331 /* HP mixer */
332 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
333 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
334 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
335 /* Front Pin (0x0c) */
336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
338 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
339 /* LFE Pin (0x0e) */
340 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
341 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
342 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
343 /* HP Pin (0x0f) */
344 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
345 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
346 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
347 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
348 /* Front Mic pin: input vref at 80% */
349 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
350 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
351 /* Line In pin */
352 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
353 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
354
355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
358 { }
359};
360
361/* Macmini 3,1 */
362static const struct hda_verb alc885_macmini3_init_verbs[] = {
363 /* DACs */
364 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
365 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
366 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
367 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
368 /* Front mixer */
369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
372 /* Surround mixer */
373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
375 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
376 /* LFE mixer */
377 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
378 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
380 /* HP mixer */
381 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
382 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
383 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
384 /* Front Pin (0x0c) */
385 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
386 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
387 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
388 /* LFE Pin (0x0e) */
389 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
390 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
391 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
392 /* HP Pin (0x0f) */
393 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
394 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
395 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
396 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
397 /* Line In pin */
398 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
399 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
400
401 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
405 { }
406};
407
408
409static const struct hda_verb alc885_mba21_init_verbs[] = {
410 /*Internal and HP Speaker Mixer*/
411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
414 /*Internal Speaker Pin (0x0c)*/
415 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
416 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
417 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
418 /* HP Pin: output 0 (0x0e) */
419 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
420 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
421 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
422 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
423 /* Line in (is hp when jack connected)*/
424 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
425 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
426
427 { }
428 };
429
430
431/* Macbook Pro rev3 */
432static const struct hda_verb alc885_mbp3_init_verbs[] = {
433 /* Front mixer: unmute input/output amp left and right (volume = 0) */
434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
436 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
437 /* Rear mixer */
438 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
439 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
440 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
441 /* HP mixer */
442 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
445 /* Front Pin: output 0 (0x0c) */
446 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
447 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
448 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
449 /* HP Pin: output 0 (0x0e) */
450 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
451 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
452 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
453 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
454 /* Mic (rear) pin: input vref at 80% */
455 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
457 /* Front Mic pin: input vref at 80% */
458 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
459 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
460 /* Line In pin: use output 1 when in LineOut mode */
461 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
462 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
463 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
464
465 /* FIXME: use matrix-type input source selection */
466 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
467 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
468 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
469 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
471 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
472 /* Input mixer2 */
473 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
477 /* Input mixer3 */
478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
482 /* ADC1: mute amp left and right */
483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
484 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
485 /* ADC2: mute amp left and right */
486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
487 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
488 /* ADC3: mute amp left and right */
489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
490 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
491
492 { }
493};
494
495/* iMac 9,1 */
496static const struct hda_verb alc885_imac91_init_verbs[] = {
497 /* Internal Speaker Pin (0x0c) */
498 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
499 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
500 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
501 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
502 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
503 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
504 /* HP Pin: Rear */
505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
506 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
507 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
508 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
509 /* Line in Rear */
510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
511 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
512 /* Front Mic pin: input vref at 80% */
513 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
514 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
515 /* Rear mixer */
516 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
517 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
519 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
521 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
522 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
523 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
525 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
526 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
527 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
528 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
531 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
532 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
533 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
538 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
539 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
540 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
541 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
542 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
543 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
544 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
545 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
546 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
547 { }
548};
549
550/* Toggle speaker-output according to the hp-jack state */
551static void alc885_imac24_setup(struct hda_codec *codec)
552{
553 struct alc_spec *spec = codec->spec;
554
555 spec->autocfg.hp_pins[0] = 0x14;
556 spec->autocfg.speaker_pins[0] = 0x18;
557 spec->autocfg.speaker_pins[1] = 0x1a;
558 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
559}
560
561#define alc885_mb5_setup alc885_imac24_setup
562#define alc885_macmini3_setup alc885_imac24_setup
563
564/* Macbook Air 2,1 */
565static void alc885_mba21_setup(struct hda_codec *codec)
566{
567 struct alc_spec *spec = codec->spec;
568
569 spec->autocfg.hp_pins[0] = 0x14;
570 spec->autocfg.speaker_pins[0] = 0x18;
571 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
572}
573
574
575
576static void alc885_mbp3_setup(struct hda_codec *codec)
577{
578 struct alc_spec *spec = codec->spec;
579
580 spec->autocfg.hp_pins[0] = 0x15;
581 spec->autocfg.speaker_pins[0] = 0x14;
582 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
583}
584
585static void alc885_imac91_setup(struct hda_codec *codec)
586{
587 struct alc_spec *spec = codec->spec;
588
589 spec->autocfg.hp_pins[0] = 0x14;
590 spec->autocfg.speaker_pins[0] = 0x18;
591 spec->autocfg.speaker_pins[1] = 0x1a;
592 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
593}
594
595/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
596static const struct hda_verb alc889A_mb31_ch2_init[] = {
597 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
598 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
599 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
601 { } /* end */
602};
603
604/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
605static const struct hda_verb alc889A_mb31_ch4_init[] = {
606 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
607 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
608 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
609 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
610 { } /* end */
611};
612
613/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
614static const struct hda_verb alc889A_mb31_ch5_init[] = {
615 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
616 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
617 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
618 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
619 { } /* end */
620};
621
622/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
623static const struct hda_verb alc889A_mb31_ch6_init[] = {
624 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
625 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
626 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
627 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
628 { } /* end */
629};
630
631static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
632 { 2, alc889A_mb31_ch2_init },
633 { 4, alc889A_mb31_ch4_init },
634 { 5, alc889A_mb31_ch5_init },
635 { 6, alc889A_mb31_ch6_init },
636};
637
638static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
639 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
640 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
641 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
642 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
643 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
644 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
645 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
646 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
647 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
648 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
649 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
650 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
651 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
653 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
654 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
655 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
656 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
657 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
658 { } /* end */
659};
660
661static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
662 /* Output mixers */
663 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
664 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
665 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
666 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
667 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
668 HDA_OUTPUT),
669 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
670 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
671 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
672 /* Output switches */
673 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
674 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
675 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
676 /* Boost mixers */
677 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
678 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
679 /* Input mixers */
680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
682 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
683 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
684 { } /* end */
685};
686
687static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
688 {
689 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
690 .name = "Channel Mode",
691 .info = alc_ch_mode_info,
692 .get = alc_ch_mode_get,
693 .put = alc_ch_mode_put,
694 },
695 { } /* end */
696};
697
698static const struct hda_verb alc889A_mb31_verbs[] = {
699 /* Init rear pin (used as headphone output) */
700 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
701 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
702 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
703 /* Init line pin (used as output in 4ch and 6ch mode) */
704 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
705 /* Init line 2 pin (used as headphone out by default) */
706 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
707 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
708 { } /* end */
709};
710
711/* Mute speakers according to the headphone jack state */
712static void alc889A_mb31_automute(struct hda_codec *codec)
713{
714 unsigned int present;
715
716 /* Mute only in 2ch or 4ch mode */
717 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
718 == 0x00) {
719 present = snd_hda_jack_detect(codec, 0x15);
720 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
721 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
722 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
723 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
724 }
725}
726
727static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
728{
729 if ((res >> 26) == ALC_HP_EVENT)
730 alc889A_mb31_automute(codec);
731}
732
733static void alc882_unsol_event(struct hda_codec *codec, unsigned int res)
734{
735 alc_exec_unsol_event(codec, res >> 26);
736}
737
738/*
739 * configuration and preset
740 */
741static const char * const alc882_models[ALC882_MODEL_LAST] = {
742 [ALC885_MB5] = "mb5",
743 [ALC885_MACMINI3] = "macmini3",
744 [ALC885_MBA21] = "mba21",
745 [ALC885_MBP3] = "mbp3",
746 [ALC885_IMAC91] = "imac91",
747 [ALC889A_MB31] = "mb31",
748 [ALC882_AUTO] = "auto",
749};
750
751/* codec SSID table for Intel Mac */
752static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
753 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
754 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
755 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
756 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
757 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
758 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
759 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
760 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
761 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
762 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
763 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
764 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
765 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
766 * so apparently no perfect solution yet
767 */
768 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
769 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
770 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
771 {} /* terminator */
772};
773
774static const struct alc_config_preset alc882_presets[] = {
775 [ALC885_MBA21] = {
776 .mixers = { alc885_mba21_mixer },
777 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
778 .num_dacs = 2,
779 .dac_nids = alc882_dac_nids,
780 .channel_mode = alc885_mba21_ch_modes,
781 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
782 .input_mux = &alc882_capture_source,
783 .unsol_event = alc882_unsol_event,
784 .setup = alc885_mba21_setup,
785 .init_hook = alc_hp_automute,
786 },
787 [ALC885_MBP3] = {
788 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
789 .init_verbs = { alc885_mbp3_init_verbs,
790 alc880_gpio1_init_verbs },
791 .num_dacs = 2,
792 .dac_nids = alc882_dac_nids,
793 .hp_nid = 0x04,
794 .channel_mode = alc885_mbp_4ch_modes,
795 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
796 .input_mux = &alc882_capture_source,
797 .dig_out_nid = ALC882_DIGOUT_NID,
798 .dig_in_nid = ALC882_DIGIN_NID,
799 .unsol_event = alc882_unsol_event,
800 .setup = alc885_mbp3_setup,
801 .init_hook = alc_hp_automute,
802 },
803 [ALC885_MB5] = {
804 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
805 .init_verbs = { alc885_mb5_init_verbs,
806 alc880_gpio1_init_verbs },
807 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
808 .dac_nids = alc882_dac_nids,
809 .channel_mode = alc885_mb5_6ch_modes,
810 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
811 .input_mux = &mb5_capture_source,
812 .dig_out_nid = ALC882_DIGOUT_NID,
813 .dig_in_nid = ALC882_DIGIN_NID,
814 .unsol_event = alc882_unsol_event,
815 .setup = alc885_mb5_setup,
816 .init_hook = alc_hp_automute,
817 },
818 [ALC885_MACMINI3] = {
819 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
820 .init_verbs = { alc885_macmini3_init_verbs,
821 alc880_gpio1_init_verbs },
822 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
823 .dac_nids = alc882_dac_nids,
824 .channel_mode = alc885_macmini3_6ch_modes,
825 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
826 .input_mux = &macmini3_capture_source,
827 .dig_out_nid = ALC882_DIGOUT_NID,
828 .dig_in_nid = ALC882_DIGIN_NID,
829 .unsol_event = alc882_unsol_event,
830 .setup = alc885_macmini3_setup,
831 .init_hook = alc_hp_automute,
832 },
833 [ALC885_IMAC91] = {
834 .mixers = {alc885_imac91_mixer},
835 .init_verbs = { alc885_imac91_init_verbs,
836 alc880_gpio1_init_verbs },
837 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
838 .dac_nids = alc882_dac_nids,
839 .channel_mode = alc885_mba21_ch_modes,
840 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
841 .input_mux = &alc889A_imac91_capture_source,
842 .dig_out_nid = ALC882_DIGOUT_NID,
843 .dig_in_nid = ALC882_DIGIN_NID,
844 .unsol_event = alc882_unsol_event,
845 .setup = alc885_imac91_setup,
846 .init_hook = alc_hp_automute,
847 },
848 [ALC889A_MB31] = {
849 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
850 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
851 alc880_gpio1_init_verbs },
852 .adc_nids = alc883_adc_nids,
853 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
854 .capsrc_nids = alc883_capsrc_nids,
855 .dac_nids = alc883_dac_nids,
856 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
857 .channel_mode = alc889A_mb31_6ch_modes,
858 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
859 .input_mux = &alc889A_mb31_capture_source,
860 .dig_out_nid = ALC883_DIGOUT_NID,
861 .unsol_event = alc889A_mb31_unsol_event,
862 .init_hook = alc889A_mb31_automute,
863 },
864};
865
866
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c
deleted file mode 100644
index a18952ed4311..000000000000
--- a/sound/pci/hda/alc_quirks.c
+++ /dev/null
@@ -1,480 +0,0 @@
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
456static void alc_simple_setup_automute(struct alc_spec *spec, int mode)
457{
458 int lo_pin = spec->autocfg.line_out_pins[0];
459
460 if (lo_pin == spec->autocfg.speaker_pins[0] ||
461 lo_pin == spec->autocfg.hp_pins[0])
462 lo_pin = 0;
463 spec->automute_mode = mode;
464 spec->detect_hp = !!spec->autocfg.hp_pins[0];
465 spec->detect_lo = !!lo_pin;
466 spec->automute_lo = spec->automute_lo_possible = !!lo_pin;
467 spec->automute_speaker = spec->automute_speaker_possible = !!spec->autocfg.speaker_pins[0];
468}
469
470/* auto-toggle front mic */
471static void alc88x_simple_mic_automute(struct hda_codec *codec)
472{
473 unsigned int present;
474 unsigned char bits;
475
476 present = snd_hda_jack_detect(codec, 0x18);
477 bits = present ? HDA_AMP_MUTE : 0;
478 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
479}
480
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index c2c65f63bf06..7a8fcc4c15f8 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -19,6 +19,7 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/mm.h>
22#include <linux/init.h> 23#include <linux/init.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
@@ -1759,7 +1760,11 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
1759 parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT; 1760 parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT;
1760 parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT; 1761 parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT;
1761 parm |= index << AC_AMP_SET_INDEX_SHIFT; 1762 parm |= index << AC_AMP_SET_INDEX_SHIFT;
1762 parm |= val; 1763 if ((val & HDA_AMP_MUTE) && !(info->amp_caps & AC_AMPCAP_MUTE) &&
1764 (info->amp_caps & AC_AMPCAP_MIN_MUTE))
1765 ; /* set the zero value as a fake mute */
1766 else
1767 parm |= val;
1763 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); 1768 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);
1764 info->vol[ch] = val; 1769 info->vol[ch] = val;
1765} 1770}
@@ -2026,7 +2031,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2026 val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); 2031 val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
2027 val1 += ofs; 2032 val1 += ofs;
2028 val1 = ((int)val1) * ((int)val2); 2033 val1 = ((int)val1) * ((int)val2);
2029 if (min_mute) 2034 if (min_mute || (caps & AC_AMPCAP_MIN_MUTE))
2030 val2 |= TLV_DB_SCALE_MUTE; 2035 val2 |= TLV_DB_SCALE_MUTE;
2031 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) 2036 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
2032 return -EFAULT; 2037 return -EFAULT;
@@ -2300,7 +2305,7 @@ typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
2300 2305
2301/* apply the function to all matching slave ctls in the mixer list */ 2306/* apply the function to all matching slave ctls in the mixer list */
2302static int map_slaves(struct hda_codec *codec, const char * const *slaves, 2307static int map_slaves(struct hda_codec *codec, const char * const *slaves,
2303 map_slave_func_t func, void *data) 2308 const char *suffix, map_slave_func_t func, void *data)
2304{ 2309{
2305 struct hda_nid_item *items; 2310 struct hda_nid_item *items;
2306 const char * const *s; 2311 const char * const *s;
@@ -2313,7 +2318,14 @@ static int map_slaves(struct hda_codec *codec, const char * const *slaves,
2313 sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) 2318 sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
2314 continue; 2319 continue;
2315 for (s = slaves; *s; s++) { 2320 for (s = slaves; *s; s++) {
2316 if (!strcmp(sctl->id.name, *s)) { 2321 char tmpname[sizeof(sctl->id.name)];
2322 const char *name = *s;
2323 if (suffix) {
2324 snprintf(tmpname, sizeof(tmpname), "%s %s",
2325 name, suffix);
2326 name = tmpname;
2327 }
2328 if (!strcmp(sctl->id.name, name)) {
2317 err = func(data, sctl); 2329 err = func(data, sctl);
2318 if (err) 2330 if (err)
2319 return err; 2331 return err;
@@ -2329,12 +2341,65 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
2329 return 1; 2341 return 1;
2330} 2342}
2331 2343
2344/* guess the value corresponding to 0dB */
2345static int get_kctl_0dB_offset(struct snd_kcontrol *kctl)
2346{
2347 int _tlv[4];
2348 const int *tlv = NULL;
2349 int val = -1;
2350
2351 if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
2352 /* FIXME: set_fs() hack for obtaining user-space TLV data */
2353 mm_segment_t fs = get_fs();
2354 set_fs(get_ds());
2355 if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), _tlv))
2356 tlv = _tlv;
2357 set_fs(fs);
2358 } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
2359 tlv = kctl->tlv.p;
2360 if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE)
2361 val = -tlv[2] / tlv[3];
2362 return val;
2363}
2364
2365/* call kctl->put with the given value(s) */
2366static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
2367{
2368 struct snd_ctl_elem_value *ucontrol;
2369 ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL);
2370 if (!ucontrol)
2371 return -ENOMEM;
2372 ucontrol->value.integer.value[0] = val;
2373 ucontrol->value.integer.value[1] = val;
2374 kctl->put(kctl, ucontrol);
2375 kfree(ucontrol);
2376 return 0;
2377}
2378
2379/* initialize the slave volume with 0dB */
2380static int init_slave_0dB(void *data, struct snd_kcontrol *slave)
2381{
2382 int offset = get_kctl_0dB_offset(slave);
2383 if (offset > 0)
2384 put_kctl_with_value(slave, offset);
2385 return 0;
2386}
2387
2388/* unmute the slave */
2389static int init_slave_unmute(void *data, struct snd_kcontrol *slave)
2390{
2391 return put_kctl_with_value(slave, 1);
2392}
2393
2332/** 2394/**
2333 * snd_hda_add_vmaster - create a virtual master control and add slaves 2395 * snd_hda_add_vmaster - create a virtual master control and add slaves
2334 * @codec: HD-audio codec 2396 * @codec: HD-audio codec
2335 * @name: vmaster control name 2397 * @name: vmaster control name
2336 * @tlv: TLV data (optional) 2398 * @tlv: TLV data (optional)
2337 * @slaves: slave control names (optional) 2399 * @slaves: slave control names (optional)
2400 * @suffix: suffix string to each slave name (optional)
2401 * @init_slave_vol: initialize slaves to unmute/0dB
2402 * @ctl_ret: store the vmaster kcontrol in return
2338 * 2403 *
2339 * Create a virtual master control with the given name. The TLV data 2404 * Create a virtual master control with the given name. The TLV data
2340 * must be either NULL or a valid data. 2405 * must be either NULL or a valid data.
@@ -2345,13 +2410,18 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
2345 * 2410 *
2346 * This function returns zero if successful or a negative error code. 2411 * This function returns zero if successful or a negative error code.
2347 */ 2412 */
2348int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 2413int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2349 unsigned int *tlv, const char * const *slaves) 2414 unsigned int *tlv, const char * const *slaves,
2415 const char *suffix, bool init_slave_vol,
2416 struct snd_kcontrol **ctl_ret)
2350{ 2417{
2351 struct snd_kcontrol *kctl; 2418 struct snd_kcontrol *kctl;
2352 int err; 2419 int err;
2353 2420
2354 err = map_slaves(codec, slaves, check_slave_present, NULL); 2421 if (ctl_ret)
2422 *ctl_ret = NULL;
2423
2424 err = map_slaves(codec, slaves, suffix, check_slave_present, NULL);
2355 if (err != 1) { 2425 if (err != 1) {
2356 snd_printdd("No slave found for %s\n", name); 2426 snd_printdd("No slave found for %s\n", name);
2357 return 0; 2427 return 0;
@@ -2363,13 +2433,119 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2363 if (err < 0) 2433 if (err < 0)
2364 return err; 2434 return err;
2365 2435
2366 err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, 2436 err = map_slaves(codec, slaves, suffix,
2367 kctl); 2437 (map_slave_func_t)snd_ctl_add_slave, kctl);
2368 if (err < 0) 2438 if (err < 0)
2369 return err; 2439 return err;
2440
2441 /* init with master mute & zero volume */
2442 put_kctl_with_value(kctl, 0);
2443 if (init_slave_vol)
2444 map_slaves(codec, slaves, suffix,
2445 tlv ? init_slave_0dB : init_slave_unmute, kctl);
2446
2447 if (ctl_ret)
2448 *ctl_ret = kctl;
2449 return 0;
2450}
2451EXPORT_SYMBOL_HDA(__snd_hda_add_vmaster);
2452
2453/*
2454 * mute-LED control using vmaster
2455 */
2456static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol,
2457 struct snd_ctl_elem_info *uinfo)
2458{
2459 static const char * const texts[] = {
2460 "Off", "On", "Follow Master"
2461 };
2462 unsigned int index;
2463
2464 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2465 uinfo->count = 1;
2466 uinfo->value.enumerated.items = 3;
2467 index = uinfo->value.enumerated.item;
2468 if (index >= 3)
2469 index = 2;
2470 strcpy(uinfo->value.enumerated.name, texts[index]);
2471 return 0;
2472}
2473
2474static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol,
2475 struct snd_ctl_elem_value *ucontrol)
2476{
2477 struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
2478 ucontrol->value.enumerated.item[0] = hook->mute_mode;
2370 return 0; 2479 return 0;
2371} 2480}
2372EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); 2481
2482static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol,
2483 struct snd_ctl_elem_value *ucontrol)
2484{
2485 struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
2486 unsigned int old_mode = hook->mute_mode;
2487
2488 hook->mute_mode = ucontrol->value.enumerated.item[0];
2489 if (hook->mute_mode > HDA_VMUTE_FOLLOW_MASTER)
2490 hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
2491 if (old_mode == hook->mute_mode)
2492 return 0;
2493 snd_hda_sync_vmaster_hook(hook);
2494 return 1;
2495}
2496
2497static struct snd_kcontrol_new vmaster_mute_mode = {
2498 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2499 .name = "Mute-LED Mode",
2500 .info = vmaster_mute_mode_info,
2501 .get = vmaster_mute_mode_get,
2502 .put = vmaster_mute_mode_put,
2503};
2504
2505/*
2506 * Add a mute-LED hook with the given vmaster switch kctl
2507 * "Mute-LED Mode" control is automatically created and associated with
2508 * the given hook.
2509 */
2510int snd_hda_add_vmaster_hook(struct hda_codec *codec,
2511 struct hda_vmaster_mute_hook *hook,
2512 bool expose_enum_ctl)
2513{
2514 struct snd_kcontrol *kctl;
2515
2516 if (!hook->hook || !hook->sw_kctl)
2517 return 0;
2518 snd_ctl_add_vmaster_hook(hook->sw_kctl, hook->hook, codec);
2519 hook->codec = codec;
2520 hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
2521 if (!expose_enum_ctl)
2522 return 0;
2523 kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
2524 if (!kctl)
2525 return -ENOMEM;
2526 return snd_hda_ctl_add(codec, 0, kctl);
2527}
2528EXPORT_SYMBOL_HDA(snd_hda_add_vmaster_hook);
2529
2530/*
2531 * Call the hook with the current value for synchronization
2532 * Should be called in init callback
2533 */
2534void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook)
2535{
2536 if (!hook->hook || !hook->codec)
2537 return;
2538 switch (hook->mute_mode) {
2539 case HDA_VMUTE_FOLLOW_MASTER:
2540 snd_ctl_sync_vmaster_hook(hook->sw_kctl);
2541 break;
2542 default:
2543 hook->hook(hook->codec, hook->mute_mode);
2544 break;
2545 }
2546}
2547EXPORT_SYMBOL_HDA(snd_hda_sync_vmaster_hook);
2548
2373 2549
2374/** 2550/**
2375 * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch 2551 * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch
@@ -5114,7 +5290,7 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
5114 const char *pfx = "", *sfx = ""; 5290 const char *pfx = "", *sfx = "";
5115 5291
5116 /* handle as a speaker if it's a fixed line-out */ 5292 /* handle as a speaker if it's a fixed line-out */
5117 if (!strcmp(name, "Line-Out") && attr == INPUT_PIN_ATTR_INT) 5293 if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT)
5118 name = "Speaker"; 5294 name = "Speaker";
5119 /* check the location */ 5295 /* check the location */
5120 switch (attr) { 5296 switch (attr) {
@@ -5173,7 +5349,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
5173 5349
5174 switch (get_defcfg_device(def_conf)) { 5350 switch (get_defcfg_device(def_conf)) {
5175 case AC_JACK_LINE_OUT: 5351 case AC_JACK_LINE_OUT:
5176 return fill_audio_out_name(codec, nid, cfg, "Line-Out", 5352 return fill_audio_out_name(codec, nid, cfg, "Line Out",
5177 label, maxlen, indexp); 5353 label, maxlen, indexp);
5178 case AC_JACK_SPEAKER: 5354 case AC_JACK_SPEAKER:
5179 return fill_audio_out_name(codec, nid, cfg, "Speaker", 5355 return fill_audio_out_name(codec, nid, cfg, "Speaker",
@@ -5268,6 +5444,10 @@ int snd_hda_suspend(struct hda_bus *bus)
5268 list_for_each_entry(codec, &bus->codec_list, list) { 5444 list_for_each_entry(codec, &bus->codec_list, list) {
5269 if (hda_codec_is_power_on(codec)) 5445 if (hda_codec_is_power_on(codec))
5270 hda_call_codec_suspend(codec); 5446 hda_call_codec_suspend(codec);
5447 else /* forcibly change the power to D3 even if not used */
5448 hda_set_power_state(codec,
5449 codec->afg ? codec->afg : codec->mfg,
5450 AC_PWRST_D3);
5271 if (codec->patch_ops.post_suspend) 5451 if (codec->patch_ops.post_suspend)
5272 codec->patch_ops.post_suspend(codec); 5452 codec->patch_ops.post_suspend(codec);
5273 } 5453 }
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index e9f71dc0d464..9a9f372e1be4 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -298,6 +298,9 @@ enum {
298#define AC_AMPCAP_MUTE (1<<31) /* mute capable */ 298#define AC_AMPCAP_MUTE (1<<31) /* mute capable */
299#define AC_AMPCAP_MUTE_SHIFT 31 299#define AC_AMPCAP_MUTE_SHIFT 31
300 300
301/* driver-specific amp-caps: using bits 24-30 */
302#define AC_AMPCAP_MIN_MUTE (1 << 30) /* min-volume = mute */
303
301/* Connection list */ 304/* Connection list */
302#define AC_CLIST_LENGTH (0x7f<<0) 305#define AC_CLIST_LENGTH (0x7f<<0)
303#define AC_CLIST_LONG (1<<7) 306#define AC_CLIST_LONG (1<<7)
@@ -852,6 +855,7 @@ struct hda_codec {
852 unsigned int pins_shutup:1; /* pins are shut up */ 855 unsigned int pins_shutup:1; /* pins are shut up */
853 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ 856 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
854 unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ 857 unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
858 unsigned int no_jack_detect:1; /* Machine has no jack-detection */
855#ifdef CONFIG_SND_HDA_POWER_SAVE 859#ifdef CONFIG_SND_HDA_POWER_SAVE
856 unsigned int power_on :1; /* current (global) power-state */ 860 unsigned int power_on :1; /* current (global) power-state */
857 unsigned int power_transition :1; /* power-state in transition */ 861 unsigned int power_transition :1; /* power-state in transition */
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index c1da422e085a..b58b4b1687fa 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -385,8 +385,8 @@ error:
385static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen) 385static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen)
386{ 386{
387 static unsigned int alsa_rates[] = { 387 static unsigned int alsa_rates[] = {
388 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, 388 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
389 96000, 176400, 192000, 384000 389 88200, 96000, 176400, 192000, 384000
390 }; 390 };
391 int i, j; 391 int i, j;
392 392
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 95dfb6874941..c19e71a94e1b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -84,7 +84,7 @@ module_param_array(model, charp, NULL, 0444);
84MODULE_PARM_DESC(model, "Use the given board model."); 84MODULE_PARM_DESC(model, "Use the given board model.");
85module_param_array(position_fix, int, NULL, 0444); 85module_param_array(position_fix, int, NULL, 0444);
86MODULE_PARM_DESC(position_fix, "DMA pointer read method." 86MODULE_PARM_DESC(position_fix, "DMA pointer read method."
87 "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO)."); 87 "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");
88module_param_array(bdl_pos_adj, int, NULL, 0644); 88module_param_array(bdl_pos_adj, int, NULL, 0644);
89MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 89MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
90module_param_array(probe_mask, int, NULL, 0444); 90module_param_array(probe_mask, int, NULL, 0444);
@@ -94,7 +94,7 @@ MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
94module_param(single_cmd, bool, 0444); 94module_param(single_cmd, bool, 0444);
95MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " 95MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
96 "(for debugging only)."); 96 "(for debugging only).");
97module_param(enable_msi, int, 0444); 97module_param(enable_msi, bint, 0444);
98MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); 98MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
99#ifdef CONFIG_SND_HDA_PATCH_LOADER 99#ifdef CONFIG_SND_HDA_PATCH_LOADER
100module_param_array(patch, charp, NULL, 0444); 100module_param_array(patch, charp, NULL, 0444);
@@ -121,8 +121,8 @@ module_param(power_save_controller, bool, 0644);
121MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); 121MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
122#endif 122#endif
123 123
124static bool align_buffer_size = 1; 124static int align_buffer_size = -1;
125module_param(align_buffer_size, bool, 0644); 125module_param(align_buffer_size, bint, 0644);
126MODULE_PARM_DESC(align_buffer_size, 126MODULE_PARM_DESC(align_buffer_size,
127 "Force buffer and period sizes to be multiple of 128 bytes."); 127 "Force buffer and period sizes to be multiple of 128 bytes.");
128 128
@@ -148,6 +148,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
148 "{Intel, PCH}," 148 "{Intel, PCH},"
149 "{Intel, CPT}," 149 "{Intel, CPT},"
150 "{Intel, PPT}," 150 "{Intel, PPT},"
151 "{Intel, LPT},"
151 "{Intel, PBG}," 152 "{Intel, PBG},"
152 "{Intel, SCH}," 153 "{Intel, SCH},"
153 "{ATI, SB450}," 154 "{ATI, SB450},"
@@ -329,6 +330,7 @@ enum {
329 POS_FIX_LPIB, 330 POS_FIX_LPIB,
330 POS_FIX_POSBUF, 331 POS_FIX_POSBUF,
331 POS_FIX_VIACOMBO, 332 POS_FIX_VIACOMBO,
333 POS_FIX_COMBO,
332}; 334};
333 335
334/* Defines for ATI HD Audio support in SB450 south bridge */ 336/* Defines for ATI HD Audio support in SB450 south bridge */
@@ -515,6 +517,7 @@ enum {
515#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ 517#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
516#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ 518#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */
517#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ 519#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */
520#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
518 521
519/* quirks for ATI SB / AMD Hudson */ 522/* quirks for ATI SB / AMD Hudson */
520#define AZX_DCAPS_PRESET_ATI_SB \ 523#define AZX_DCAPS_PRESET_ATI_SB \
@@ -527,7 +530,8 @@ enum {
527 530
528/* quirks for Nvidia */ 531/* quirks for Nvidia */
529#define AZX_DCAPS_PRESET_NVIDIA \ 532#define AZX_DCAPS_PRESET_NVIDIA \
530 (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI) 533 (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\
534 AZX_DCAPS_ALIGN_BUFSIZE)
531 535
532static char *driver_short_names[] __devinitdata = { 536static char *driver_short_names[] __devinitdata = {
533 [AZX_DRIVER_ICH] = "HDA Intel", 537 [AZX_DRIVER_ICH] = "HDA Intel",
@@ -2347,17 +2351,6 @@ static void azx_power_notify(struct hda_bus *bus)
2347 * power management 2351 * power management
2348 */ 2352 */
2349 2353
2350static int snd_hda_codecs_inuse(struct hda_bus *bus)
2351{
2352 struct hda_codec *codec;
2353
2354 list_for_each_entry(codec, &bus->codec_list, list) {
2355 if (snd_hda_codec_needs_resume(codec))
2356 return 1;
2357 }
2358 return 0;
2359}
2360
2361static int azx_suspend(struct pci_dev *pci, pm_message_t state) 2354static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2362{ 2355{
2363 struct snd_card *card = pci_get_drvdata(pci); 2356 struct snd_card *card = pci_get_drvdata(pci);
@@ -2404,8 +2397,7 @@ static int azx_resume(struct pci_dev *pci)
2404 return -EIO; 2397 return -EIO;
2405 azx_init_pci(chip); 2398 azx_init_pci(chip);
2406 2399
2407 if (snd_hda_codecs_inuse(chip->bus)) 2400 azx_init_chip(chip, 1);
2408 azx_init_chip(chip, 1);
2409 2401
2410 snd_hda_resume(chip->bus); 2402 snd_hda_resume(chip->bus);
2411 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2403 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -2517,6 +2509,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
2517 case POS_FIX_LPIB: 2509 case POS_FIX_LPIB:
2518 case POS_FIX_POSBUF: 2510 case POS_FIX_POSBUF:
2519 case POS_FIX_VIACOMBO: 2511 case POS_FIX_VIACOMBO:
2512 case POS_FIX_COMBO:
2520 return fix; 2513 return fix;
2521 } 2514 }
2522 2515
@@ -2696,6 +2689,12 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2696 2689
2697 chip->position_fix[0] = chip->position_fix[1] = 2690 chip->position_fix[0] = chip->position_fix[1] =
2698 check_position_fix(chip, position_fix[dev]); 2691 check_position_fix(chip, position_fix[dev]);
2692 /* combo mode uses LPIB for playback */
2693 if (chip->position_fix[0] == POS_FIX_COMBO) {
2694 chip->position_fix[0] = POS_FIX_LPIB;
2695 chip->position_fix[1] = POS_FIX_AUTO;
2696 }
2697
2699 check_probe_mask(chip, dev); 2698 check_probe_mask(chip, dev);
2700 2699
2701 chip->single_cmd = single_cmd; 2700 chip->single_cmd = single_cmd;
@@ -2774,9 +2773,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2774 } 2773 }
2775 2774
2776 /* disable buffer size rounding to 128-byte multiples if supported */ 2775 /* disable buffer size rounding to 128-byte multiples if supported */
2777 chip->align_buffer_size = align_buffer_size; 2776 if (align_buffer_size >= 0)
2778 if (chip->driver_caps & AZX_DCAPS_BUFSIZE) 2777 chip->align_buffer_size = !!align_buffer_size;
2779 chip->align_buffer_size = 0; 2778 else {
2779 if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
2780 chip->align_buffer_size = 0;
2781 else if (chip->driver_caps & AZX_DCAPS_ALIGN_BUFSIZE)
2782 chip->align_buffer_size = 1;
2783 else
2784 chip->align_buffer_size = 1;
2785 }
2780 2786
2781 /* allow 64bit DMA address if supported by H/W */ 2787 /* allow 64bit DMA address if supported by H/W */
2782 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) 2788 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
@@ -2992,6 +2998,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2992 { PCI_DEVICE(0x8086, 0x1e20), 2998 { PCI_DEVICE(0x8086, 0x1e20),
2993 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 2999 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
2994 AZX_DCAPS_BUFSIZE}, 3000 AZX_DCAPS_BUFSIZE},
3001 /* Lynx Point */
3002 { PCI_DEVICE(0x8086, 0x8c20),
3003 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3004 AZX_DCAPS_BUFSIZE},
2995 /* SCH */ 3005 /* SCH */
2996 { PCI_DEVICE(0x8086, 0x811b), 3006 { PCI_DEVICE(0x8086, 0x811b),
2997 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | 3007 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 9d819c4b4923..d68948499fbc 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -19,6 +19,22 @@
19#include "hda_local.h" 19#include "hda_local.h"
20#include "hda_jack.h" 20#include "hda_jack.h"
21 21
22bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
23{
24 if (codec->no_jack_detect)
25 return false;
26 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
27 return false;
28 if (!codec->ignore_misc_bit &&
29 (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
30 AC_DEFCFG_MISC_NO_PRESENCE))
31 return false;
32 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
33 return false;
34 return true;
35}
36EXPORT_SYMBOL_HDA(is_jack_detectable);
37
22/* execute pin sense measurement */ 38/* execute pin sense measurement */
23static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) 39static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
24{ 40{
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index f8f97c71c9c1..c66655cf413a 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -62,18 +62,7 @@ int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
62u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 62u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
63int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 63int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
64 64
65static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) 65bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
66{
67 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
68 return false;
69 if (!codec->ignore_misc_bit &&
70 (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
71 AC_DEFCFG_MISC_NO_PRESENCE))
72 return false;
73 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
74 return false;
75 return true;
76}
77 66
78int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 67int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
79 const char *name, int idx); 68 const char *name, int idx);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index aca8d3193b95..0ec9248165bc 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -139,10 +139,36 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
139 unsigned int *tlv); 139 unsigned int *tlv);
140struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, 140struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
141 const char *name); 141 const char *name);
142int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 142int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
143 unsigned int *tlv, const char * const *slaves); 143 unsigned int *tlv, const char * const *slaves,
144 const char *suffix, bool init_slave_vol,
145 struct snd_kcontrol **ctl_ret);
146#define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \
147 __snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL)
144int snd_hda_codec_reset(struct hda_codec *codec); 148int snd_hda_codec_reset(struct hda_codec *codec);
145 149
150enum {
151 HDA_VMUTE_OFF,
152 HDA_VMUTE_ON,
153 HDA_VMUTE_FOLLOW_MASTER,
154};
155
156struct hda_vmaster_mute_hook {
157 /* below two fields must be filled by the caller of
158 * snd_hda_add_vmaster_hook() beforehand
159 */
160 struct snd_kcontrol *sw_kctl;
161 void (*hook)(void *, int);
162 /* below are initialized automatically */
163 unsigned int mute_mode; /* HDA_VMUTE_XXX */
164 struct hda_codec *codec;
165};
166
167int snd_hda_add_vmaster_hook(struct hda_codec *codec,
168 struct hda_vmaster_mute_hook *hook,
169 bool expose_enum_ctl);
170void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
171
146/* amp value bits */ 172/* amp value bits */
147#define HDA_AMP_MUTE 0x80 173#define HDA_AMP_MUTE 0x80
148#define HDA_AMP_UNMUTE 0x00 174#define HDA_AMP_UNMUTE 0x00
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 9cb14b42dfff..7143393927da 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -82,6 +82,7 @@ struct ad198x_spec {
82 unsigned int inv_jack_detect: 1;/* inverted jack-detection */ 82 unsigned int inv_jack_detect: 1;/* inverted jack-detection */
83 unsigned int inv_eapd: 1; /* inverted EAPD implementation */ 83 unsigned int inv_eapd: 1; /* inverted EAPD implementation */
84 unsigned int analog_beep: 1; /* analog beep input present */ 84 unsigned int analog_beep: 1; /* analog beep input present */
85 unsigned int avoid_init_slave_vol:1;
85 86
86#ifdef CONFIG_SND_HDA_POWER_SAVE 87#ifdef CONFIG_SND_HDA_POWER_SAVE
87 struct hda_loopback_check loopback; 88 struct hda_loopback_check loopback;
@@ -137,51 +138,17 @@ static int ad198x_init(struct hda_codec *codec)
137 return 0; 138 return 0;
138} 139}
139 140
140static const char * const ad_slave_vols[] = { 141static const char * const ad_slave_pfxs[] = {
141 "Front Playback Volume", 142 "Front", "Surround", "Center", "LFE", "Side",
142 "Surround Playback Volume", 143 "Headphone", "Mono", "Speaker", "IEC958",
143 "Center Playback Volume",
144 "LFE Playback Volume",
145 "Side Playback Volume",
146 "Headphone Playback Volume",
147 "Mono Playback Volume",
148 "Speaker Playback Volume",
149 "IEC958 Playback Volume",
150 NULL 144 NULL
151}; 145};
152 146
153static const char * const ad_slave_sws[] = { 147static const char * const ad1988_6stack_fp_slave_pfxs[] = {
154 "Front Playback Switch", 148 "Front", "Surround", "Center", "LFE", "Side", "IEC958",
155 "Surround Playback Switch",
156 "Center Playback Switch",
157 "LFE Playback Switch",
158 "Side Playback Switch",
159 "Headphone Playback Switch",
160 "Mono Playback Switch",
161 "Speaker Playback Switch",
162 "IEC958 Playback Switch",
163 NULL 149 NULL
164}; 150};
165 151
166static const char * const ad1988_6stack_fp_slave_vols[] = {
167 "Front Playback Volume",
168 "Surround Playback Volume",
169 "Center Playback Volume",
170 "LFE Playback Volume",
171 "Side Playback Volume",
172 "IEC958 Playback Volume",
173 NULL
174};
175
176static const char * const ad1988_6stack_fp_slave_sws[] = {
177 "Front Playback Switch",
178 "Surround Playback Switch",
179 "Center Playback Switch",
180 "LFE Playback Switch",
181 "Side Playback Switch",
182 "IEC958 Playback Switch",
183 NULL
184};
185static void ad198x_free_kctls(struct hda_codec *codec); 152static void ad198x_free_kctls(struct hda_codec *codec);
186 153
187#ifdef CONFIG_SND_HDA_INPUT_BEEP 154#ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -257,10 +224,12 @@ static int ad198x_build_controls(struct hda_codec *codec)
257 unsigned int vmaster_tlv[4]; 224 unsigned int vmaster_tlv[4];
258 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 225 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
259 HDA_OUTPUT, vmaster_tlv); 226 HDA_OUTPUT, vmaster_tlv);
260 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 227 err = __snd_hda_add_vmaster(codec, "Master Playback Volume",
261 vmaster_tlv, 228 vmaster_tlv,
262 (spec->slave_vols ? 229 (spec->slave_vols ?
263 spec->slave_vols : ad_slave_vols)); 230 spec->slave_vols : ad_slave_pfxs),
231 "Playback Volume",
232 !spec->avoid_init_slave_vol, NULL);
264 if (err < 0) 233 if (err < 0)
265 return err; 234 return err;
266 } 235 }
@@ -268,7 +237,8 @@ static int ad198x_build_controls(struct hda_codec *codec)
268 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 237 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
269 NULL, 238 NULL,
270 (spec->slave_sws ? 239 (spec->slave_sws ?
271 spec->slave_sws : ad_slave_sws)); 240 spec->slave_sws : ad_slave_pfxs),
241 "Playback Switch");
272 if (err < 0) 242 if (err < 0)
273 return err; 243 return err;
274 } 244 }
@@ -3385,8 +3355,8 @@ static int patch_ad1988(struct hda_codec *codec)
3385 3355
3386 if (spec->autocfg.hp_pins[0]) { 3356 if (spec->autocfg.hp_pins[0]) {
3387 spec->mixers[spec->num_mixers++] = ad1988_hp_mixers; 3357 spec->mixers[spec->num_mixers++] = ad1988_hp_mixers;
3388 spec->slave_vols = ad1988_6stack_fp_slave_vols; 3358 spec->slave_vols = ad1988_6stack_fp_slave_pfxs;
3389 spec->slave_sws = ad1988_6stack_fp_slave_sws; 3359 spec->slave_sws = ad1988_6stack_fp_slave_pfxs;
3390 spec->alt_dac_nid = ad1988_alt_dac_nid; 3360 spec->alt_dac_nid = ad1988_alt_dac_nid;
3391 spec->stream_analog_alt_playback = 3361 spec->stream_analog_alt_playback =
3392 &ad198x_pcm_analog_alt_playback; 3362 &ad198x_pcm_analog_alt_playback;
@@ -3594,16 +3564,8 @@ static const struct hda_amp_list ad1884_loopbacks[] = {
3594#endif 3564#endif
3595 3565
3596static const char * const ad1884_slave_vols[] = { 3566static const char * const ad1884_slave_vols[] = {
3597 "PCM Playback Volume", 3567 "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
3598 "Mic Playback Volume", 3568 "Internal Mic", "Docking Mic", /* "Beep", */ "IEC958",
3599 "Mono Playback Volume",
3600 "Front Mic Playback Volume",
3601 "Mic Playback Volume",
3602 "CD Playback Volume",
3603 "Internal Mic Playback Volume",
3604 "Docking Mic Playback Volume",
3605 /* "Beep Playback Volume", */
3606 "IEC958 Playback Volume",
3607 NULL 3569 NULL
3608}; 3570};
3609 3571
@@ -3644,6 +3606,8 @@ static int patch_ad1884(struct hda_codec *codec)
3644 spec->vmaster_nid = 0x04; 3606 spec->vmaster_nid = 0x04;
3645 /* we need to cover all playback volumes */ 3607 /* we need to cover all playback volumes */
3646 spec->slave_vols = ad1884_slave_vols; 3608 spec->slave_vols = ad1884_slave_vols;
3609 /* slaves may contain input volumes, so we can't raise to 0dB blindly */
3610 spec->avoid_init_slave_vol = 1;
3647 3611
3648 codec->patch_ops = ad198x_patch_ops; 3612 codec->patch_ops = ad198x_patch_ops;
3649 3613
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 35abe3c62908..21d91d580da8 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -728,18 +728,19 @@ static int ca0132_hp_switch_put(struct snd_kcontrol *kcontrol,
728 728
729 err = chipio_read(codec, REG_CODEC_MUTE, &data); 729 err = chipio_read(codec, REG_CODEC_MUTE, &data);
730 if (err < 0) 730 if (err < 0)
731 return err; 731 goto exit;
732 732
733 /* *valp 0 is mute, 1 is unmute */ 733 /* *valp 0 is mute, 1 is unmute */
734 data = (data & 0x7f) | (*valp ? 0 : 0x80); 734 data = (data & 0x7f) | (*valp ? 0 : 0x80);
735 chipio_write(codec, REG_CODEC_MUTE, data); 735 err = chipio_write(codec, REG_CODEC_MUTE, data);
736 if (err < 0) 736 if (err < 0)
737 return err; 737 goto exit;
738 738
739 spec->curr_hp_switch = *valp; 739 spec->curr_hp_switch = *valp;
740 740
741 exit:
741 snd_hda_power_down(codec); 742 snd_hda_power_down(codec);
742 return 1; 743 return err < 0 ? err : 1;
743} 744}
744 745
745static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol, 746static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol,
@@ -770,18 +771,19 @@ static int ca0132_speaker_switch_put(struct snd_kcontrol *kcontrol,
770 771
771 err = chipio_read(codec, REG_CODEC_MUTE, &data); 772 err = chipio_read(codec, REG_CODEC_MUTE, &data);
772 if (err < 0) 773 if (err < 0)
773 return err; 774 goto exit;
774 775
775 /* *valp 0 is mute, 1 is unmute */ 776 /* *valp 0 is mute, 1 is unmute */
776 data = (data & 0xef) | (*valp ? 0 : 0x10); 777 data = (data & 0xef) | (*valp ? 0 : 0x10);
777 chipio_write(codec, REG_CODEC_MUTE, data); 778 err = chipio_write(codec, REG_CODEC_MUTE, data);
778 if (err < 0) 779 if (err < 0)
779 return err; 780 goto exit;
780 781
781 spec->curr_speaker_switch = *valp; 782 spec->curr_speaker_switch = *valp;
782 783
784 exit:
783 snd_hda_power_down(codec); 785 snd_hda_power_down(codec);
784 return 1; 786 return err < 0 ? err : 1;
785} 787}
786 788
787static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol, 789static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol,
@@ -819,25 +821,26 @@ static int ca0132_hp_volume_put(struct snd_kcontrol *kcontrol,
819 821
820 err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data); 822 err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data);
821 if (err < 0) 823 if (err < 0)
822 return err; 824 goto exit;
823 825
824 val = 31 - left_vol; 826 val = 31 - left_vol;
825 data = (data & 0xe0) | val; 827 data = (data & 0xe0) | val;
826 chipio_write(codec, REG_CODEC_HP_VOL_L, data); 828 err = chipio_write(codec, REG_CODEC_HP_VOL_L, data);
827 if (err < 0) 829 if (err < 0)
828 return err; 830 goto exit;
829 831
830 val = 31 - right_vol; 832 val = 31 - right_vol;
831 data = (data & 0xe0) | val; 833 data = (data & 0xe0) | val;
832 chipio_write(codec, REG_CODEC_HP_VOL_R, data); 834 err = chipio_write(codec, REG_CODEC_HP_VOL_R, data);
833 if (err < 0) 835 if (err < 0)
834 return err; 836 goto exit;
835 837
836 spec->curr_hp_volume[0] = left_vol; 838 spec->curr_hp_volume[0] = left_vol;
837 spec->curr_hp_volume[1] = right_vol; 839 spec->curr_hp_volume[1] = right_vol;
838 840
841 exit:
839 snd_hda_power_down(codec); 842 snd_hda_power_down(codec);
840 return 1; 843 return err < 0 ? err : 1;
841} 844}
842 845
843static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid) 846static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid)
@@ -936,6 +939,8 @@ static int ca0132_build_controls(struct hda_codec *codec)
936 if (err < 0) 939 if (err < 0)
937 return err; 940 return err;
938 err = add_in_volume(codec, spec->dig_in, "IEC958"); 941 err = add_in_volume(codec, spec->dig_in, "IEC958");
942 if (err < 0)
943 return err;
939 } 944 }
940 return 0; 945 return 0;
941} 946}
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index bc5a993d1146..c83ccdba1e5a 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -609,7 +609,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
609 "Front Speaker", "Surround Speaker", "Bass Speaker" 609 "Front Speaker", "Surround Speaker", "Bass Speaker"
610 }; 610 };
611 static const char * const line_outs[] = { 611 static const char * const line_outs[] = {
612 "Front Line-Out", "Surround Line-Out", "Bass Line-Out" 612 "Front Line Out", "Surround Line Out", "Bass Line Out"
613 }; 613 };
614 614
615 fix_volume_caps(codec, dac); 615 fix_volume_caps(codec, dac);
@@ -635,7 +635,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
635 if (num_ctls > 1) 635 if (num_ctls > 1)
636 name = line_outs[idx]; 636 name = line_outs[idx];
637 else 637 else
638 name = "Line-Out"; 638 name = "Line Out";
639 break; 639 break;
640 } 640 }
641 641
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 51e3ed4527c3..8c6523bbc797 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -70,6 +70,8 @@ struct conexant_spec {
70 const struct snd_kcontrol_new *mixers[5]; 70 const struct snd_kcontrol_new *mixers[5];
71 int num_mixers; 71 int num_mixers;
72 hda_nid_t vmaster_nid; 72 hda_nid_t vmaster_nid;
73 struct hda_vmaster_mute_hook vmaster_mute;
74 bool vmaster_mute_led;
73 75
74 const struct hda_verb *init_verbs[5]; /* initialization verbs 76 const struct hda_verb *init_verbs[5]; /* initialization verbs
75 * don't forget NULL 77 * don't forget NULL
@@ -465,21 +467,8 @@ static const struct snd_kcontrol_new cxt_beep_mixer[] = {
465}; 467};
466#endif 468#endif
467 469
468static const char * const slave_vols[] = { 470static const char * const slave_pfxs[] = {
469 "Headphone Playback Volume", 471 "Headphone", "Speaker", "Front", "Surround", "CLFE",
470 "Speaker Playback Volume",
471 "Front Playback Volume",
472 "Surround Playback Volume",
473 "CLFE Playback Volume",
474 NULL
475};
476
477static const char * const slave_sws[] = {
478 "Headphone Playback Switch",
479 "Speaker Playback Switch",
480 "Front Playback Switch",
481 "Surround Playback Switch",
482 "CLFE Playback Switch",
483 NULL 472 NULL
484}; 473};
485 474
@@ -519,14 +508,17 @@ static int conexant_build_controls(struct hda_codec *codec)
519 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 508 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
520 HDA_OUTPUT, vmaster_tlv); 509 HDA_OUTPUT, vmaster_tlv);
521 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 510 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
522 vmaster_tlv, slave_vols); 511 vmaster_tlv, slave_pfxs,
512 "Playback Volume");
523 if (err < 0) 513 if (err < 0)
524 return err; 514 return err;
525 } 515 }
526 if (spec->vmaster_nid && 516 if (spec->vmaster_nid &&
527 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 517 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
528 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 518 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
529 NULL, slave_sws); 519 NULL, slave_pfxs,
520 "Playback Switch", true,
521 &spec->vmaster_mute.sw_kctl);
530 if (err < 0) 522 if (err < 0)
531 return err; 523 return err;
532 } 524 }
@@ -3034,7 +3026,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3034 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), 3026 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
3035 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), 3027 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
3036 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), 3028 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
3037 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
3038 SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO), 3029 SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
3039 {} 3030 {}
3040}; 3031};
@@ -3482,7 +3473,7 @@ static int cx_automute_mode_info(struct snd_kcontrol *kcontrol,
3482 "Disabled", "Enabled" 3473 "Disabled", "Enabled"
3483 }; 3474 };
3484 static const char * const texts3[] = { 3475 static const char * const texts3[] = {
3485 "Disabled", "Speaker Only", "Line-Out+Speaker" 3476 "Disabled", "Speaker Only", "Line Out+Speaker"
3486 }; 3477 };
3487 const char * const *texts; 3478 const char * const *texts;
3488 3479
@@ -3943,6 +3934,63 @@ static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
3943 snd_hda_jack_detect_enable(codec, pins[i], action); 3934 snd_hda_jack_detect_enable(codec, pins[i], action);
3944} 3935}
3945 3936
3937static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
3938{
3939 int i;
3940 for (i = 0; i < nums; i++)
3941 if (list[i] == nid)
3942 return true;
3943 return false;
3944}
3945
3946/* is the given NID found in any of autocfg items? */
3947static bool found_in_autocfg(struct auto_pin_cfg *cfg, hda_nid_t nid)
3948{
3949 int i;
3950
3951 if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3952 found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3953 found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs) ||
3954 found_in_nid_list(nid, cfg->dig_out_pins, cfg->dig_outs))
3955 return true;
3956 for (i = 0; i < cfg->num_inputs; i++)
3957 if (cfg->inputs[i].pin == nid)
3958 return true;
3959 if (cfg->dig_in_pin == nid)
3960 return true;
3961 return false;
3962}
3963
3964/* clear unsol-event tags on unused pins; Conexant codecs seem to leave
3965 * invalid unsol tags by some reason
3966 */
3967static void clear_unsol_on_unused_pins(struct hda_codec *codec)
3968{
3969 struct conexant_spec *spec = codec->spec;
3970 struct auto_pin_cfg *cfg = &spec->autocfg;
3971 int i;
3972
3973 for (i = 0; i < codec->init_pins.used; i++) {
3974 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
3975 if (!found_in_autocfg(cfg, pin->nid))
3976 snd_hda_codec_write(codec, pin->nid, 0,
3977 AC_VERB_SET_UNSOLICITED_ENABLE, 0);
3978 }
3979}
3980
3981/* turn on/off EAPD according to Master switch */
3982static void cx_auto_vmaster_hook(void *private_data, int enabled)
3983{
3984 struct hda_codec *codec = private_data;
3985 struct conexant_spec *spec = codec->spec;
3986
3987 if (enabled && spec->pin_eapd_ctrls) {
3988 cx_auto_update_speakers(codec);
3989 return;
3990 }
3991 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled);
3992}
3993
3946static void cx_auto_init_output(struct hda_codec *codec) 3994static void cx_auto_init_output(struct hda_codec *codec)
3947{ 3995{
3948 struct conexant_spec *spec = codec->spec; 3996 struct conexant_spec *spec = codec->spec;
@@ -3983,6 +4031,7 @@ static void cx_auto_init_output(struct hda_codec *codec)
3983 /* turn on all EAPDs if no individual EAPD control is available */ 4031 /* turn on all EAPDs if no individual EAPD control is available */
3984 if (!spec->pin_eapd_ctrls) 4032 if (!spec->pin_eapd_ctrls)
3985 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); 4033 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4034 clear_unsol_on_unused_pins(codec);
3986} 4035}
3987 4036
3988static void cx_auto_init_input(struct hda_codec *codec) 4037static void cx_auto_init_input(struct hda_codec *codec)
@@ -4046,11 +4095,13 @@ static void cx_auto_init_digital(struct hda_codec *codec)
4046 4095
4047static int cx_auto_init(struct hda_codec *codec) 4096static int cx_auto_init(struct hda_codec *codec)
4048{ 4097{
4098 struct conexant_spec *spec = codec->spec;
4049 /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/ 4099 /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/
4050 cx_auto_init_output(codec); 4100 cx_auto_init_output(codec);
4051 cx_auto_init_input(codec); 4101 cx_auto_init_input(codec);
4052 cx_auto_init_digital(codec); 4102 cx_auto_init_digital(codec);
4053 snd_hda_jack_report_sync(codec); 4103 snd_hda_jack_report_sync(codec);
4104 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
4054 return 0; 4105 return 0;
4055} 4106}
4056 4107
@@ -4079,7 +4130,8 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
4079 err = snd_hda_ctl_add(codec, nid, kctl); 4130 err = snd_hda_ctl_add(codec, nid, kctl);
4080 if (err < 0) 4131 if (err < 0)
4081 return err; 4132 return err;
4082 if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE)) 4133 if (!(query_amp_caps(codec, nid, hda_dir) &
4134 (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)))
4083 break; 4135 break;
4084 } 4136 }
4085 return 0; 4137 return 0;
@@ -4295,6 +4347,13 @@ static int cx_auto_build_controls(struct hda_codec *codec)
4295 err = snd_hda_jack_add_kctls(codec, &spec->autocfg); 4347 err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
4296 if (err < 0) 4348 if (err < 0)
4297 return err; 4349 return err;
4350 if (spec->vmaster_mute.sw_kctl) {
4351 spec->vmaster_mute.hook = cx_auto_vmaster_hook;
4352 err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute,
4353 spec->vmaster_mute_led);
4354 if (err < 0)
4355 return err;
4356 }
4298 return 0; 4357 return 0;
4299} 4358}
4300 4359
@@ -4319,7 +4378,6 @@ static int cx_auto_search_adcs(struct hda_codec *codec)
4319 return 0; 4378 return 0;
4320} 4379}
4321 4380
4322
4323static const struct hda_codec_ops cx_auto_patch_ops = { 4381static const struct hda_codec_ops cx_auto_patch_ops = {
4324 .build_controls = cx_auto_build_controls, 4382 .build_controls = cx_auto_build_controls,
4325 .build_pcms = conexant_build_pcms, 4383 .build_pcms = conexant_build_pcms,
@@ -4367,6 +4425,7 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
4367 { 0x16, 0x042140ff }, /* HP (seq# overridden) */ 4425 { 0x16, 0x042140ff }, /* HP (seq# overridden) */
4368 { 0x17, 0x21a11000 }, /* dock-mic */ 4426 { 0x17, 0x21a11000 }, /* dock-mic */
4369 { 0x19, 0x2121103f }, /* dock-HP */ 4427 { 0x19, 0x2121103f }, /* dock-HP */
4428 { 0x1c, 0x21440100 }, /* dock SPDIF out */
4370 {} 4429 {}
4371}; 4430};
4372 4431
@@ -4379,6 +4438,22 @@ static const struct snd_pci_quirk cxt_fixups[] = {
4379 {} 4438 {}
4380}; 4439};
4381 4440
4441/* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
4442 * can be created (bko#42825)
4443 */
4444static void add_cx5051_fake_mutes(struct hda_codec *codec)
4445{
4446 static hda_nid_t out_nids[] = {
4447 0x10, 0x11, 0
4448 };
4449 hda_nid_t *p;
4450
4451 for (p = out_nids; *p; p++)
4452 snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT,
4453 AC_AMPCAP_MIN_MUTE |
4454 query_amp_caps(codec, *p, HDA_OUTPUT));
4455}
4456
4382static int patch_conexant_auto(struct hda_codec *codec) 4457static int patch_conexant_auto(struct hda_codec *codec)
4383{ 4458{
4384 struct conexant_spec *spec; 4459 struct conexant_spec *spec;
@@ -4397,10 +4472,25 @@ static int patch_conexant_auto(struct hda_codec *codec)
4397 case 0x14f15045: 4472 case 0x14f15045:
4398 spec->single_adc_amp = 1; 4473 spec->single_adc_amp = 1;
4399 break; 4474 break;
4475 case 0x14f15051:
4476 add_cx5051_fake_mutes(codec);
4477 break;
4400 } 4478 }
4401 4479
4402 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); 4480 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
4403 4481
4482 /* Show mute-led control only on HP laptops
4483 * This is a sort of white-list: on HP laptops, EAPD corresponds
4484 * only to the mute-LED without actualy amp function. Meanwhile,
4485 * others may use EAPD really as an amp switch, so it might be
4486 * not good to expose it blindly.
4487 */
4488 switch (codec->subsystem_id >> 16) {
4489 case 0x103c:
4490 spec->vmaster_mute_led = 1;
4491 break;
4492 }
4493
4404 err = cx_auto_search_adcs(codec); 4494 err = cx_auto_search_adcs(codec);
4405 if (err < 0) 4495 if (err < 0)
4406 return err; 4496 return err;
@@ -4414,6 +4504,18 @@ static int patch_conexant_auto(struct hda_codec *codec)
4414 codec->patch_ops = cx_auto_patch_ops; 4504 codec->patch_ops = cx_auto_patch_ops;
4415 if (spec->beep_amp) 4505 if (spec->beep_amp)
4416 snd_hda_attach_beep_device(codec, spec->beep_amp); 4506 snd_hda_attach_beep_device(codec, spec->beep_amp);
4507
4508 /* Some laptops with Conexant chips show stalls in S3 resume,
4509 * which falls into the single-cmd mode.
4510 * Better to make reset, then.
4511 */
4512 if (!codec->bus->sync_write) {
4513 snd_printd("hda_codec: "
4514 "Enable sync_write for stable communication\n");
4515 codec->bus->sync_write = 1;
4516 codec->bus->allow_bus_reset = 1;
4517 }
4518
4417 return 0; 4519 return 0;
4418} 4520}
4419 4521
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 1168ebd3fb5c..540cd13f7f15 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1912,6 +1912,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
1912{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, 1912{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1913{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, 1913{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi },
1914{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, 1914{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi },
1915{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi },
1915{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, 1916{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi },
1916{} /* terminator */ 1917{} /* terminator */
1917}; 1918};
@@ -1958,6 +1959,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862803");
1958MODULE_ALIAS("snd-hda-codec-id:80862804"); 1959MODULE_ALIAS("snd-hda-codec-id:80862804");
1959MODULE_ALIAS("snd-hda-codec-id:80862805"); 1960MODULE_ALIAS("snd-hda-codec-id:80862805");
1960MODULE_ALIAS("snd-hda-codec-id:80862806"); 1961MODULE_ALIAS("snd-hda-codec-id:80862806");
1962MODULE_ALIAS("snd-hda-codec-id:80862880");
1961MODULE_ALIAS("snd-hda-codec-id:808629fb"); 1963MODULE_ALIAS("snd-hda-codec-id:808629fb");
1962 1964
1963MODULE_LICENSE("GPL"); 1965MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index f6316507d764..8c463a4f79b4 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -80,6 +80,8 @@ enum {
80 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ 80 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
81}; 81};
82 82
83#define MAX_VOL_NIDS 0x40
84
83struct alc_spec { 85struct alc_spec {
84 /* codec parameterization */ 86 /* codec parameterization */
85 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 87 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -118,8 +120,8 @@ struct alc_spec {
118 const hda_nid_t *capsrc_nids; 120 const hda_nid_t *capsrc_nids;
119 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 121 hda_nid_t dig_in_nid; /* digital-in NID; optional */
120 hda_nid_t mixer_nid; /* analog-mixer NID */ 122 hda_nid_t mixer_nid; /* analog-mixer NID */
121 DECLARE_BITMAP(vol_ctls, 0x20 << 1); 123 DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1);
122 DECLARE_BITMAP(sw_ctls, 0x20 << 1); 124 DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1);
123 125
124 /* capture setup for dynamic dual-adc switch */ 126 /* capture setup for dynamic dual-adc switch */
125 hda_nid_t cur_adc; 127 hda_nid_t cur_adc;
@@ -196,8 +198,11 @@ struct alc_spec {
196 198
197 /* for virtual master */ 199 /* for virtual master */
198 hda_nid_t vmaster_nid; 200 hda_nid_t vmaster_nid;
201 struct hda_vmaster_mute_hook vmaster_mute;
199#ifdef CONFIG_SND_HDA_POWER_SAVE 202#ifdef CONFIG_SND_HDA_POWER_SAVE
200 struct hda_loopback_check loopback; 203 struct hda_loopback_check loopback;
204 int num_loopbacks;
205 struct hda_amp_list loopback_list[8];
201#endif 206#endif
202 207
203 /* for PLL fix */ 208 /* for PLL fix */
@@ -218,8 +223,6 @@ struct alc_spec {
218 struct snd_array bind_ctls; 223 struct snd_array bind_ctls;
219}; 224};
220 225
221#define ALC_MODEL_AUTO 0 /* common for all chips */
222
223static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, 226static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
224 int dir, unsigned int bits) 227 int dir, unsigned int bits)
225{ 228{
@@ -298,6 +301,9 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
298 int i, type, num_conns; 301 int i, type, num_conns;
299 hda_nid_t nid; 302 hda_nid_t nid;
300 303
304 if (!spec->input_mux)
305 return 0;
306
301 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 307 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
302 imux = &spec->input_mux[mux_idx]; 308 imux = &spec->input_mux[mux_idx];
303 if (!imux->num_items && mux_idx > 0) 309 if (!imux->num_items && mux_idx > 0)
@@ -649,15 +655,51 @@ static void alc_exec_unsol_event(struct hda_codec *codec, int action)
649 snd_hda_jack_report_sync(codec); 655 snd_hda_jack_report_sync(codec);
650} 656}
651 657
658/* update the master volume per volume-knob's unsol event */
659static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
660{
661 unsigned int val;
662 struct snd_kcontrol *kctl;
663 struct snd_ctl_elem_value *uctl;
664
665 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
666 if (!kctl)
667 return;
668 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
669 if (!uctl)
670 return;
671 val = snd_hda_codec_read(codec, nid, 0,
672 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
673 val &= HDA_AMP_VOLMASK;
674 uctl->value.integer.value[0] = val;
675 uctl->value.integer.value[1] = val;
676 kctl->put(kctl, uctl);
677 kfree(uctl);
678}
679
652/* unsolicited event for HP jack sensing */ 680/* unsolicited event for HP jack sensing */
653static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 681static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
654{ 682{
683 int action;
684
655 if (codec->vendor_id == 0x10ec0880) 685 if (codec->vendor_id == 0x10ec0880)
656 res >>= 28; 686 res >>= 28;
657 else 687 else
658 res >>= 26; 688 res >>= 26;
659 res = snd_hda_jack_get_action(codec, res); 689 action = snd_hda_jack_get_action(codec, res);
660 alc_exec_unsol_event(codec, res); 690 if (action == ALC_DCVOL_EVENT) {
691 /* Execute the dc-vol event here as it requires the NID
692 * but we don't pass NID to alc_exec_unsol_event().
693 * Once when we convert all static quirks to the auto-parser,
694 * this can be integerated into there.
695 */
696 struct hda_jack_tbl *jack;
697 jack = snd_hda_jack_tbl_get_from_tag(codec, res);
698 if (jack)
699 alc_update_knob_master(codec, jack->nid);
700 return;
701 }
702 alc_exec_unsol_event(codec, action);
661} 703}
662 704
663/* call init functions of standard auto-mute helpers */ 705/* call init functions of standard auto-mute helpers */
@@ -800,7 +842,7 @@ static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
800 "Disabled", "Enabled" 842 "Disabled", "Enabled"
801 }; 843 };
802 static const char * const texts3[] = { 844 static const char * const texts3[] = {
803 "Disabled", "Speaker Only", "Line-Out+Speaker" 845 "Disabled", "Speaker Only", "Line Out+Speaker"
804 }; 846 };
805 const char * const *texts; 847 const char * const *texts;
806 848
@@ -1031,45 +1073,6 @@ static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
1031 return true; 1073 return true;
1032} 1074}
1033 1075
1034/* rebuild imux for matching with the given auto-mic pins (if not yet) */
1035static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
1036{
1037 struct alc_spec *spec = codec->spec;
1038 struct hda_input_mux *imux;
1039 static char * const texts[3] = {
1040 "Mic", "Internal Mic", "Dock Mic"
1041 };
1042 int i;
1043
1044 if (!spec->auto_mic)
1045 return false;
1046 imux = &spec->private_imux[0];
1047 if (spec->input_mux == imux)
1048 return true;
1049 spec->imux_pins[0] = spec->ext_mic_pin;
1050 spec->imux_pins[1] = spec->int_mic_pin;
1051 spec->imux_pins[2] = spec->dock_mic_pin;
1052 for (i = 0; i < 3; i++) {
1053 strcpy(imux->items[i].label, texts[i]);
1054 if (spec->imux_pins[i]) {
1055 hda_nid_t pin = spec->imux_pins[i];
1056 int c;
1057 for (c = 0; c < spec->num_adc_nids; c++) {
1058 hda_nid_t cap = get_capsrc(spec, c);
1059 int idx = get_connection_index(codec, cap, pin);
1060 if (idx >= 0) {
1061 imux->items[i].index = idx;
1062 break;
1063 }
1064 }
1065 imux->num_items = i + 1;
1066 }
1067 }
1068 spec->num_mux_defs = 1;
1069 spec->input_mux = imux;
1070 return true;
1071}
1072
1073/* check whether all auto-mic pins are valid; setup indices if OK */ 1076/* check whether all auto-mic pins are valid; setup indices if OK */
1074static bool alc_auto_mic_check_imux(struct hda_codec *codec) 1077static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1075{ 1078{
@@ -1439,6 +1442,7 @@ enum {
1439 ALC_FIXUP_ACT_PRE_PROBE, 1442 ALC_FIXUP_ACT_PRE_PROBE,
1440 ALC_FIXUP_ACT_PROBE, 1443 ALC_FIXUP_ACT_PROBE,
1441 ALC_FIXUP_ACT_INIT, 1444 ALC_FIXUP_ACT_INIT,
1445 ALC_FIXUP_ACT_BUILD,
1442}; 1446};
1443 1447
1444static void alc_apply_fixup(struct hda_codec *codec, int action) 1448static void alc_apply_fixup(struct hda_codec *codec, int action)
@@ -1518,6 +1522,13 @@ static void alc_pick_fixup(struct hda_codec *codec,
1518 int id = -1; 1522 int id = -1;
1519 const char *name = NULL; 1523 const char *name = NULL;
1520 1524
1525 /* when model=nofixup is given, don't pick up any fixups */
1526 if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
1527 spec->fixup_list = NULL;
1528 spec->fixup_id = -1;
1529 return;
1530 }
1531
1521 if (codec->modelname && models) { 1532 if (codec->modelname && models) {
1522 while (models->name) { 1533 while (models->name) {
1523 if (!strcmp(codec->modelname, models->name)) { 1534 if (!strcmp(codec->modelname, models->name)) {
@@ -1845,32 +1856,10 @@ DEFINE_CAPMIX_NOSRC(3);
1845/* 1856/*
1846 * slave controls for virtual master 1857 * slave controls for virtual master
1847 */ 1858 */
1848static const char * const alc_slave_vols[] = { 1859static const char * const alc_slave_pfxs[] = {
1849 "Front Playback Volume", 1860 "Front", "Surround", "Center", "LFE", "Side",
1850 "Surround Playback Volume", 1861 "Headphone", "Speaker", "Mono", "Line Out",
1851 "Center Playback Volume", 1862 "CLFE", "Bass Speaker", "PCM",
1852 "LFE Playback Volume",
1853 "Side Playback Volume",
1854 "Headphone Playback Volume",
1855 "Speaker Playback Volume",
1856 "Mono Playback Volume",
1857 "Line-Out Playback Volume",
1858 "PCM Playback Volume",
1859 NULL,
1860};
1861
1862static const char * const alc_slave_sws[] = {
1863 "Front Playback Switch",
1864 "Surround Playback Switch",
1865 "Center Playback Switch",
1866 "LFE Playback Switch",
1867 "Side Playback Switch",
1868 "Headphone Playback Switch",
1869 "Speaker Playback Switch",
1870 "Mono Playback Switch",
1871 "IEC958 Playback Switch",
1872 "Line-Out Playback Switch",
1873 "PCM Playback Switch",
1874 NULL, 1863 NULL,
1875}; 1864};
1876 1865
@@ -1961,14 +1950,17 @@ static int __alc_build_controls(struct hda_codec *codec)
1961 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 1950 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1962 HDA_OUTPUT, vmaster_tlv); 1951 HDA_OUTPUT, vmaster_tlv);
1963 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1952 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1964 vmaster_tlv, alc_slave_vols); 1953 vmaster_tlv, alc_slave_pfxs,
1954 "Playback Volume");
1965 if (err < 0) 1955 if (err < 0)
1966 return err; 1956 return err;
1967 } 1957 }
1968 if (!spec->no_analog && 1958 if (!spec->no_analog &&
1969 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 1959 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1970 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 1960 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
1971 NULL, alc_slave_sws); 1961 NULL, alc_slave_pfxs,
1962 "Playback Switch",
1963 true, &spec->vmaster_mute.sw_kctl);
1972 if (err < 0) 1964 if (err < 0)
1973 return err; 1965 return err;
1974 } 1966 }
@@ -2053,7 +2045,11 @@ static int alc_build_controls(struct hda_codec *codec)
2053 int err = __alc_build_controls(codec); 2045 int err = __alc_build_controls(codec);
2054 if (err < 0) 2046 if (err < 0)
2055 return err; 2047 return err;
2056 return snd_hda_jack_add_kctls(codec, &spec->autocfg); 2048 err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
2049 if (err < 0)
2050 return err;
2051 alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD);
2052 return 0;
2057} 2053}
2058 2054
2059 2055
@@ -2062,21 +2058,23 @@ static int alc_build_controls(struct hda_codec *codec)
2062 */ 2058 */
2063 2059
2064static void alc_init_special_input_src(struct hda_codec *codec); 2060static void alc_init_special_input_src(struct hda_codec *codec);
2061static void alc_auto_init_std(struct hda_codec *codec);
2065 2062
2066static int alc_init(struct hda_codec *codec) 2063static int alc_init(struct hda_codec *codec)
2067{ 2064{
2068 struct alc_spec *spec = codec->spec; 2065 struct alc_spec *spec = codec->spec;
2069 unsigned int i; 2066 unsigned int i;
2070 2067
2068 if (spec->init_hook)
2069 spec->init_hook(codec);
2070
2071 alc_fix_pll(codec); 2071 alc_fix_pll(codec);
2072 alc_auto_init_amp(codec, spec->init_amp); 2072 alc_auto_init_amp(codec, spec->init_amp);
2073 2073
2074 for (i = 0; i < spec->num_init_verbs; i++) 2074 for (i = 0; i < spec->num_init_verbs; i++)
2075 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2075 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2076 alc_init_special_input_src(codec); 2076 alc_init_special_input_src(codec);
2077 2077 alc_auto_init_std(codec);
2078 if (spec->init_hook)
2079 spec->init_hook(codec);
2080 2078
2081 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); 2079 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
2082 2080
@@ -2318,7 +2316,7 @@ static int alc_build_pcms(struct hda_codec *codec)
2318 "%s Analog", codec->chip_name); 2316 "%s Analog", codec->chip_name);
2319 info->name = spec->stream_name_analog; 2317 info->name = spec->stream_name_analog;
2320 2318
2321 if (spec->multiout.dac_nids > 0) { 2319 if (spec->multiout.num_dacs > 0) {
2322 p = spec->stream_analog_playback; 2320 p = spec->stream_analog_playback;
2323 if (!p) 2321 if (!p)
2324 p = &alc_pcm_analog_playback; 2322 p = &alc_pcm_analog_playback;
@@ -2665,6 +2663,25 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
2665 return channel_name[ch]; 2663 return channel_name[ch];
2666} 2664}
2667 2665
2666#ifdef CONFIG_SND_HDA_POWER_SAVE
2667/* add the powersave loopback-list entry */
2668static void add_loopback_list(struct alc_spec *spec, hda_nid_t mix, int idx)
2669{
2670 struct hda_amp_list *list;
2671
2672 if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
2673 return;
2674 list = spec->loopback_list + spec->num_loopbacks;
2675 list->nid = mix;
2676 list->dir = HDA_INPUT;
2677 list->idx = idx;
2678 spec->num_loopbacks++;
2679 spec->loopback.amplist = spec->loopback_list;
2680}
2681#else
2682#define add_loopback_list(spec, mix, idx) /* NOP */
2683#endif
2684
2668/* create input playback/capture controls for the given pin */ 2685/* create input playback/capture controls for the given pin */
2669static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 2686static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
2670 const char *ctlname, int ctlidx, 2687 const char *ctlname, int ctlidx,
@@ -2680,6 +2697,7 @@ static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
2680 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 2697 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
2681 if (err < 0) 2698 if (err < 0)
2682 return err; 2699 return err;
2700 add_loopback_list(spec, mix_nid, idx);
2683 return 0; 2701 return 0;
2684} 2702}
2685 2703
@@ -2699,9 +2717,6 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec)
2699 int max_nums = ARRAY_SIZE(spec->private_adc_nids); 2717 int max_nums = ARRAY_SIZE(spec->private_adc_nids);
2700 int i, nums = 0; 2718 int i, nums = 0;
2701 2719
2702 if (spec->shared_mic_hp)
2703 max_nums = 1; /* no multi streams with the shared HP/mic */
2704
2705 nid = codec->start_nid; 2720 nid = codec->start_nid;
2706 for (i = 0; i < codec->num_nodes; i++, nid++) { 2721 for (i = 0; i < codec->num_nodes; i++, nid++) {
2707 hda_nid_t src; 2722 hda_nid_t src;
@@ -2944,10 +2959,27 @@ static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
2944 return 0; 2959 return 0;
2945} 2960}
2946 2961
2962static bool alc_is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
2963{
2964 struct alc_spec *spec = codec->spec;
2965 int i;
2966 if (found_in_nid_list(nid, spec->multiout.dac_nids,
2967 ARRAY_SIZE(spec->private_dac_nids)) ||
2968 found_in_nid_list(nid, spec->multiout.hp_out_nid,
2969 ARRAY_SIZE(spec->multiout.hp_out_nid)) ||
2970 found_in_nid_list(nid, spec->multiout.extra_out_nid,
2971 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2972 return true;
2973 for (i = 0; i < spec->multi_ios; i++) {
2974 if (spec->multi_io[i].dac == nid)
2975 return true;
2976 }
2977 return false;
2978}
2979
2947/* look for an empty DAC slot */ 2980/* look for an empty DAC slot */
2948static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 2981static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
2949{ 2982{
2950 struct alc_spec *spec = codec->spec;
2951 hda_nid_t srcs[5]; 2983 hda_nid_t srcs[5];
2952 int i, num; 2984 int i, num;
2953 2985
@@ -2957,16 +2989,8 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
2957 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); 2989 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
2958 if (!nid) 2990 if (!nid)
2959 continue; 2991 continue;
2960 if (found_in_nid_list(nid, spec->multiout.dac_nids, 2992 if (!alc_is_dac_already_used(codec, nid))
2961 ARRAY_SIZE(spec->private_dac_nids))) 2993 return nid;
2962 continue;
2963 if (found_in_nid_list(nid, spec->multiout.hp_out_nid,
2964 ARRAY_SIZE(spec->multiout.hp_out_nid)))
2965 continue;
2966 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
2967 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2968 continue;
2969 return nid;
2970 } 2994 }
2971 return 0; 2995 return 0;
2972} 2996}
@@ -2978,6 +3002,8 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
2978 hda_nid_t srcs[5]; 3002 hda_nid_t srcs[5];
2979 int i, num; 3003 int i, num;
2980 3004
3005 if (!pin || !dac)
3006 return false;
2981 pin = alc_go_down_to_selector(codec, pin); 3007 pin = alc_go_down_to_selector(codec, pin);
2982 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 3008 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
2983 for (i = 0; i < num; i++) { 3009 for (i = 0; i < num; i++) {
@@ -2990,83 +3016,260 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
2990 3016
2991static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) 3017static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
2992{ 3018{
3019 struct alc_spec *spec = codec->spec;
2993 hda_nid_t sel = alc_go_down_to_selector(codec, pin); 3020 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
2994 if (snd_hda_get_conn_list(codec, sel, NULL) == 1) 3021 hda_nid_t nid, nid_found, srcs[5];
3022 int i, num = snd_hda_get_connections(codec, sel, srcs,
3023 ARRAY_SIZE(srcs));
3024 if (num == 1)
2995 return alc_auto_look_for_dac(codec, pin); 3025 return alc_auto_look_for_dac(codec, pin);
2996 return 0; 3026 nid_found = 0;
3027 for (i = 0; i < num; i++) {
3028 if (srcs[i] == spec->mixer_nid)
3029 continue;
3030 nid = alc_auto_mix_to_dac(codec, srcs[i]);
3031 if (nid && !alc_is_dac_already_used(codec, nid)) {
3032 if (nid_found)
3033 return 0;
3034 nid_found = nid;
3035 }
3036 }
3037 return nid_found;
2997} 3038}
2998 3039
2999/* return 0 if no possible DAC is found, 1 if one or more found */ 3040/* mark up volume and mute control NIDs: used during badness parsing and
3000static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, 3041 * at creating actual controls
3001 const hda_nid_t *pins, hda_nid_t *dacs) 3042 */
3043static inline unsigned int get_ctl_pos(unsigned int data)
3002{ 3044{
3003 int i; 3045 hda_nid_t nid = get_amp_nid_(data);
3046 unsigned int dir;
3047 if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
3048 return 0;
3049 dir = get_amp_direction_(data);
3050 return (nid << 1) | dir;
3051}
3004 3052
3005 if (num_outs && !dacs[0]) { 3053#define is_ctl_used(bits, data) \
3006 dacs[0] = alc_auto_look_for_dac(codec, pins[0]); 3054 test_bit(get_ctl_pos(data), bits)
3007 if (!dacs[0]) 3055#define mark_ctl_usage(bits, data) \
3008 return 0; 3056 set_bit(get_ctl_pos(data), bits)
3009 }
3010 3057
3011 for (i = 1; i < num_outs; i++) 3058static void clear_vol_marks(struct hda_codec *codec)
3012 dacs[i] = get_dac_if_single(codec, pins[i]); 3059{
3013 for (i = 1; i < num_outs; i++) { 3060 struct alc_spec *spec = codec->spec;
3061 memset(spec->vol_ctls, 0, sizeof(spec->vol_ctls));
3062 memset(spec->sw_ctls, 0, sizeof(spec->sw_ctls));
3063}
3064
3065/* badness definition */
3066enum {
3067 /* No primary DAC is found for the main output */
3068 BAD_NO_PRIMARY_DAC = 0x10000,
3069 /* No DAC is found for the extra output */
3070 BAD_NO_DAC = 0x4000,
3071 /* No possible multi-ios */
3072 BAD_MULTI_IO = 0x103,
3073 /* No individual DAC for extra output */
3074 BAD_NO_EXTRA_DAC = 0x102,
3075 /* No individual DAC for extra surrounds */
3076 BAD_NO_EXTRA_SURR_DAC = 0x101,
3077 /* Primary DAC shared with main surrounds */
3078 BAD_SHARED_SURROUND = 0x100,
3079 /* Primary DAC shared with main CLFE */
3080 BAD_SHARED_CLFE = 0x10,
3081 /* Primary DAC shared with extra surrounds */
3082 BAD_SHARED_EXTRA_SURROUND = 0x10,
3083 /* Volume widget is shared */
3084 BAD_SHARED_VOL = 0x10,
3085};
3086
3087static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
3088 hda_nid_t pin, hda_nid_t dac);
3089static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
3090 hda_nid_t pin, hda_nid_t dac);
3091
3092static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin,
3093 hda_nid_t dac)
3094{
3095 struct alc_spec *spec = codec->spec;
3096 hda_nid_t nid;
3097 unsigned int val;
3098 int badness = 0;
3099
3100 nid = alc_look_for_out_vol_nid(codec, pin, dac);
3101 if (nid) {
3102 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3103 if (is_ctl_used(spec->vol_ctls, nid))
3104 badness += BAD_SHARED_VOL;
3105 else
3106 mark_ctl_usage(spec->vol_ctls, val);
3107 } else
3108 badness += BAD_SHARED_VOL;
3109 nid = alc_look_for_out_mute_nid(codec, pin, dac);
3110 if (nid) {
3111 unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid));
3112 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT)
3113 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3114 else
3115 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT);
3116 if (is_ctl_used(spec->sw_ctls, val))
3117 badness += BAD_SHARED_VOL;
3118 else
3119 mark_ctl_usage(spec->sw_ctls, val);
3120 } else
3121 badness += BAD_SHARED_VOL;
3122 return badness;
3123}
3124
3125struct badness_table {
3126 int no_primary_dac; /* no primary DAC */
3127 int no_dac; /* no secondary DACs */
3128 int shared_primary; /* primary DAC is shared with main output */
3129 int shared_surr; /* secondary DAC shared with main or primary */
3130 int shared_clfe; /* third DAC shared with main or primary */
3131 int shared_surr_main; /* secondary DAC sahred with main/DAC0 */
3132};
3133
3134static struct badness_table main_out_badness = {
3135 .no_primary_dac = BAD_NO_PRIMARY_DAC,
3136 .no_dac = BAD_NO_DAC,
3137 .shared_primary = BAD_NO_PRIMARY_DAC,
3138 .shared_surr = BAD_SHARED_SURROUND,
3139 .shared_clfe = BAD_SHARED_CLFE,
3140 .shared_surr_main = BAD_SHARED_SURROUND,
3141};
3142
3143static struct badness_table extra_out_badness = {
3144 .no_primary_dac = BAD_NO_DAC,
3145 .no_dac = BAD_NO_DAC,
3146 .shared_primary = BAD_NO_EXTRA_DAC,
3147 .shared_surr = BAD_SHARED_EXTRA_SURROUND,
3148 .shared_clfe = BAD_SHARED_EXTRA_SURROUND,
3149 .shared_surr_main = BAD_NO_EXTRA_SURR_DAC,
3150};
3151
3152/* try to assign DACs to pins and return the resultant badness */
3153static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs,
3154 const hda_nid_t *pins, hda_nid_t *dacs,
3155 const struct badness_table *bad)
3156{
3157 struct alc_spec *spec = codec->spec;
3158 struct auto_pin_cfg *cfg = &spec->autocfg;
3159 int i, j;
3160 int badness = 0;
3161 hda_nid_t dac;
3162
3163 if (!num_outs)
3164 return 0;
3165
3166 for (i = 0; i < num_outs; i++) {
3167 hda_nid_t pin = pins[i];
3014 if (!dacs[i]) 3168 if (!dacs[i])
3015 dacs[i] = alc_auto_look_for_dac(codec, pins[i]); 3169 dacs[i] = alc_auto_look_for_dac(codec, pin);
3170 if (!dacs[i] && !i) {
3171 for (j = 1; j < num_outs; j++) {
3172 if (alc_auto_is_dac_reachable(codec, pin, dacs[j])) {
3173 dacs[0] = dacs[j];
3174 dacs[j] = 0;
3175 break;
3176 }
3177 }
3178 }
3179 dac = dacs[i];
3180 if (!dac) {
3181 if (alc_auto_is_dac_reachable(codec, pin, dacs[0]))
3182 dac = dacs[0];
3183 else if (cfg->line_outs > i &&
3184 alc_auto_is_dac_reachable(codec, pin,
3185 spec->private_dac_nids[i]))
3186 dac = spec->private_dac_nids[i];
3187 if (dac) {
3188 if (!i)
3189 badness += bad->shared_primary;
3190 else if (i == 1)
3191 badness += bad->shared_surr;
3192 else
3193 badness += bad->shared_clfe;
3194 } else if (alc_auto_is_dac_reachable(codec, pin,
3195 spec->private_dac_nids[0])) {
3196 dac = spec->private_dac_nids[0];
3197 badness += bad->shared_surr_main;
3198 } else if (!i)
3199 badness += bad->no_primary_dac;
3200 else
3201 badness += bad->no_dac;
3202 }
3203 if (dac)
3204 badness += eval_shared_vol_badness(codec, pin, dac);
3016 } 3205 }
3017 return 1; 3206
3207 return badness;
3018} 3208}
3019 3209
3020static int alc_auto_fill_multi_ios(struct hda_codec *codec, 3210static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3021 unsigned int location, int offset); 3211 hda_nid_t reference_pin,
3022static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, 3212 bool hardwired, int offset);
3023 hda_nid_t pin, hda_nid_t dac); 3213
3214static bool alc_map_singles(struct hda_codec *codec, int outs,
3215 const hda_nid_t *pins, hda_nid_t *dacs)
3216{
3217 int i;
3218 bool found = false;
3219 for (i = 0; i < outs; i++) {
3220 if (dacs[i])
3221 continue;
3222 dacs[i] = get_dac_if_single(codec, pins[i]);
3223 if (dacs[i])
3224 found = true;
3225 }
3226 return found;
3227}
3024 3228
3025/* fill in the dac_nids table from the parsed pin configuration */ 3229/* fill in the dac_nids table from the parsed pin configuration */
3026static int alc_auto_fill_dac_nids(struct hda_codec *codec) 3230static int fill_and_eval_dacs(struct hda_codec *codec,
3231 bool fill_hardwired,
3232 bool fill_mio_first)
3027{ 3233{
3028 struct alc_spec *spec = codec->spec; 3234 struct alc_spec *spec = codec->spec;
3029 struct auto_pin_cfg *cfg = &spec->autocfg; 3235 struct auto_pin_cfg *cfg = &spec->autocfg;
3030 unsigned int location, defcfg; 3236 int i, err, badness;
3031 int num_pins;
3032 bool redone = false;
3033 int i;
3034 3237
3035 again:
3036 /* set num_dacs once to full for alc_auto_look_for_dac() */ 3238 /* set num_dacs once to full for alc_auto_look_for_dac() */
3037 spec->multiout.num_dacs = cfg->line_outs; 3239 spec->multiout.num_dacs = cfg->line_outs;
3038 spec->multiout.hp_out_nid[0] = 0;
3039 spec->multiout.extra_out_nid[0] = 0;
3040 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
3041 spec->multiout.dac_nids = spec->private_dac_nids; 3240 spec->multiout.dac_nids = spec->private_dac_nids;
3241 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
3242 memset(spec->multiout.hp_out_nid, 0, sizeof(spec->multiout.hp_out_nid));
3243 memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid));
3042 spec->multi_ios = 0; 3244 spec->multi_ios = 0;
3245 clear_vol_marks(codec);
3246 badness = 0;
3043 3247
3044 /* fill hard-wired DACs first */ 3248 /* fill hard-wired DACs first */
3045 if (!redone) { 3249 if (fill_hardwired) {
3046 for (i = 0; i < cfg->line_outs; i++) 3250 bool mapped;
3047 spec->private_dac_nids[i] = 3251 do {
3048 get_dac_if_single(codec, cfg->line_out_pins[i]); 3252 mapped = alc_map_singles(codec, cfg->line_outs,
3049 if (cfg->hp_outs) 3253 cfg->line_out_pins,
3050 spec->multiout.hp_out_nid[0] = 3254 spec->private_dac_nids);
3051 get_dac_if_single(codec, cfg->hp_pins[0]); 3255 mapped |= alc_map_singles(codec, cfg->hp_outs,
3052 if (cfg->speaker_outs) 3256 cfg->hp_pins,
3053 spec->multiout.extra_out_nid[0] = 3257 spec->multiout.hp_out_nid);
3054 get_dac_if_single(codec, cfg->speaker_pins[0]); 3258 mapped |= alc_map_singles(codec, cfg->speaker_outs,
3259 cfg->speaker_pins,
3260 spec->multiout.extra_out_nid);
3261 if (fill_mio_first && cfg->line_outs == 1 &&
3262 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3263 err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], true, 0);
3264 if (!err)
3265 mapped = true;
3266 }
3267 } while (mapped);
3055 } 3268 }
3056 3269
3057 for (i = 0; i < cfg->line_outs; i++) { 3270 badness += alc_auto_fill_dacs(codec, cfg->line_outs, cfg->line_out_pins,
3058 hda_nid_t pin = cfg->line_out_pins[i]; 3271 spec->private_dac_nids,
3059 if (spec->private_dac_nids[i]) 3272 &main_out_badness);
3060 continue;
3061 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
3062 if (!spec->private_dac_nids[i] && !redone) {
3063 /* if we can't find primary DACs, re-probe without
3064 * checking the hard-wired DACs
3065 */
3066 redone = true;
3067 goto again;
3068 }
3069 }
3070 3273
3071 /* re-count num_dacs and squash invalid entries */ 3274 /* re-count num_dacs and squash invalid entries */
3072 spec->multiout.num_dacs = 0; 3275 spec->multiout.num_dacs = 0;
@@ -3081,30 +3284,144 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3081 } 3284 }
3082 } 3285 }
3083 3286
3084 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 3287 if (fill_mio_first &&
3288 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3085 /* try to fill multi-io first */ 3289 /* try to fill multi-io first */
3086 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); 3290 err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
3087 location = get_defcfg_location(defcfg); 3291 if (err < 0)
3088 3292 return err;
3089 num_pins = alc_auto_fill_multi_ios(codec, location, 0); 3293 /* we don't count badness at this stage yet */
3090 if (num_pins > 0) {
3091 spec->multi_ios = num_pins;
3092 spec->ext_channel_count = 2;
3093 spec->multiout.num_dacs = num_pins + 1;
3094 }
3095 } 3294 }
3096 3295
3097 if (cfg->line_out_type != AUTO_PIN_HP_OUT) 3296 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
3098 alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, 3297 err = alc_auto_fill_dacs(codec, cfg->hp_outs, cfg->hp_pins,
3099 spec->multiout.hp_out_nid); 3298 spec->multiout.hp_out_nid,
3299 &extra_out_badness);
3300 if (err < 0)
3301 return err;
3302 badness += err;
3303 }
3100 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 3304 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3101 int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, 3305 err = alc_auto_fill_dacs(codec, cfg->speaker_outs,
3102 cfg->speaker_pins, 3306 cfg->speaker_pins,
3103 spec->multiout.extra_out_nid); 3307 spec->multiout.extra_out_nid,
3104 /* if no speaker volume is assigned, try again as the primary 3308 &extra_out_badness);
3105 * output 3309 if (err < 0)
3106 */ 3310 return err;
3107 if (!err && cfg->speaker_outs > 0 && 3311 badness += err;
3312 }
3313 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3314 err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
3315 if (err < 0)
3316 return err;
3317 badness += err;
3318 }
3319 if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
3320 /* try multi-ios with HP + inputs */
3321 int offset = 0;
3322 if (cfg->line_outs >= 3)
3323 offset = 1;
3324 err = alc_auto_fill_multi_ios(codec, cfg->hp_pins[0], false,
3325 offset);
3326 if (err < 0)
3327 return err;
3328 badness += err;
3329 }
3330
3331 if (spec->multi_ios == 2) {
3332 for (i = 0; i < 2; i++)
3333 spec->private_dac_nids[spec->multiout.num_dacs++] =
3334 spec->multi_io[i].dac;
3335 spec->ext_channel_count = 2;
3336 } else if (spec->multi_ios) {
3337 spec->multi_ios = 0;
3338 badness += BAD_MULTI_IO;
3339 }
3340
3341 return badness;
3342}
3343
3344#define DEBUG_BADNESS
3345
3346#ifdef DEBUG_BADNESS
3347#define debug_badness snd_printdd
3348#else
3349#define debug_badness(...)
3350#endif
3351
3352static void debug_show_configs(struct alc_spec *spec, struct auto_pin_cfg *cfg)
3353{
3354 debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3355 cfg->line_out_pins[0], cfg->line_out_pins[1],
3356 cfg->line_out_pins[2], cfg->line_out_pins[2],
3357 spec->multiout.dac_nids[0],
3358 spec->multiout.dac_nids[1],
3359 spec->multiout.dac_nids[2],
3360 spec->multiout.dac_nids[3]);
3361 if (spec->multi_ios > 0)
3362 debug_badness("multi_ios(%d) = %x/%x : %x/%x\n",
3363 spec->multi_ios,
3364 spec->multi_io[0].pin, spec->multi_io[1].pin,
3365 spec->multi_io[0].dac, spec->multi_io[1].dac);
3366 debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3367 cfg->hp_pins[0], cfg->hp_pins[1],
3368 cfg->hp_pins[2], cfg->hp_pins[2],
3369 spec->multiout.hp_out_nid[0],
3370 spec->multiout.hp_out_nid[1],
3371 spec->multiout.hp_out_nid[2],
3372 spec->multiout.hp_out_nid[3]);
3373 debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3374 cfg->speaker_pins[0], cfg->speaker_pins[1],
3375 cfg->speaker_pins[2], cfg->speaker_pins[3],
3376 spec->multiout.extra_out_nid[0],
3377 spec->multiout.extra_out_nid[1],
3378 spec->multiout.extra_out_nid[2],
3379 spec->multiout.extra_out_nid[3]);
3380}
3381
3382static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3383{
3384 struct alc_spec *spec = codec->spec;
3385 struct auto_pin_cfg *cfg = &spec->autocfg;
3386 struct auto_pin_cfg *best_cfg;
3387 int best_badness = INT_MAX;
3388 int badness;
3389 bool fill_hardwired = true, fill_mio_first = true;
3390 bool best_wired = true, best_mio = true;
3391 bool hp_spk_swapped = false;
3392
3393 best_cfg = kmalloc(sizeof(*best_cfg), GFP_KERNEL);
3394 if (!best_cfg)
3395 return -ENOMEM;
3396 *best_cfg = *cfg;
3397
3398 for (;;) {
3399 badness = fill_and_eval_dacs(codec, fill_hardwired,
3400 fill_mio_first);
3401 if (badness < 0)
3402 return badness;
3403 debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n",
3404 cfg->line_out_type, fill_hardwired, fill_mio_first,
3405 badness);
3406 debug_show_configs(spec, cfg);
3407 if (badness < best_badness) {
3408 best_badness = badness;
3409 *best_cfg = *cfg;
3410 best_wired = fill_hardwired;
3411 best_mio = fill_mio_first;
3412 }
3413 if (!badness)
3414 break;
3415 fill_mio_first = !fill_mio_first;
3416 if (!fill_mio_first)
3417 continue;
3418 fill_hardwired = !fill_hardwired;
3419 if (!fill_hardwired)
3420 continue;
3421 if (hp_spk_swapped)
3422 break;
3423 hp_spk_swapped = true;
3424 if (cfg->speaker_outs > 0 &&
3108 cfg->line_out_type == AUTO_PIN_HP_OUT) { 3425 cfg->line_out_type == AUTO_PIN_HP_OUT) {
3109 cfg->hp_outs = cfg->line_outs; 3426 cfg->hp_outs = cfg->line_outs;
3110 memcpy(cfg->hp_pins, cfg->line_out_pins, 3427 memcpy(cfg->hp_pins, cfg->line_out_pins,
@@ -3115,45 +3432,45 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3115 cfg->speaker_outs = 0; 3432 cfg->speaker_outs = 0;
3116 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); 3433 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
3117 cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; 3434 cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
3118 redone = false; 3435 fill_hardwired = true;
3119 goto again; 3436 continue;
3120 } 3437 }
3438 if (cfg->hp_outs > 0 &&
3439 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
3440 cfg->speaker_outs = cfg->line_outs;
3441 memcpy(cfg->speaker_pins, cfg->line_out_pins,
3442 sizeof(cfg->speaker_pins));
3443 cfg->line_outs = cfg->hp_outs;
3444 memcpy(cfg->line_out_pins, cfg->hp_pins,
3445 sizeof(cfg->hp_pins));
3446 cfg->hp_outs = 0;
3447 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
3448 cfg->line_out_type = AUTO_PIN_HP_OUT;
3449 fill_hardwired = true;
3450 continue;
3451 }
3452 break;
3121 } 3453 }
3122 3454
3123 if (!spec->multi_ios && 3455 if (badness) {
3124 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && 3456 *cfg = *best_cfg;
3125 cfg->hp_outs) { 3457 fill_and_eval_dacs(codec, best_wired, best_mio);
3126 /* try multi-ios with HP + inputs */
3127 defcfg = snd_hda_codec_get_pincfg(codec, cfg->hp_pins[0]);
3128 location = get_defcfg_location(defcfg);
3129
3130 num_pins = alc_auto_fill_multi_ios(codec, location, 1);
3131 if (num_pins > 0) {
3132 spec->multi_ios = num_pins;
3133 spec->ext_channel_count = 2;
3134 spec->multiout.num_dacs = num_pins + 1;
3135 }
3136 } 3458 }
3459 debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n",
3460 cfg->line_out_type, best_wired, best_mio);
3461 debug_show_configs(spec, cfg);
3137 3462
3138 if (cfg->line_out_pins[0]) 3463 if (cfg->line_out_pins[0])
3139 spec->vmaster_nid = 3464 spec->vmaster_nid =
3140 alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], 3465 alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
3141 spec->multiout.dac_nids[0]); 3466 spec->multiout.dac_nids[0]);
3142 return 0;
3143}
3144 3467
3145static inline unsigned int get_ctl_pos(unsigned int data) 3468 /* clear the bitmap flags for creating controls */
3146{ 3469 clear_vol_marks(codec);
3147 hda_nid_t nid = get_amp_nid_(data); 3470 kfree(best_cfg);
3148 unsigned int dir = get_amp_direction_(data); 3471 return 0;
3149 return (nid << 1) | dir;
3150} 3472}
3151 3473
3152#define is_ctl_used(bits, data) \
3153 test_bit(get_ctl_pos(data), bits)
3154#define mark_ctl_usage(bits, data) \
3155 set_bit(get_ctl_pos(data), bits)
3156
3157static int alc_auto_add_vol_ctl(struct hda_codec *codec, 3474static int alc_auto_add_vol_ctl(struct hda_codec *codec,
3158 const char *pfx, int cidx, 3475 const char *pfx, int cidx,
3159 hda_nid_t nid, unsigned int chs) 3476 hda_nid_t nid, unsigned int chs)
@@ -3265,14 +3582,17 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
3265 dac = spec->multiout.dac_nids[i]; 3582 dac = spec->multiout.dac_nids[i];
3266 if (!dac) 3583 if (!dac)
3267 continue; 3584 continue;
3268 if (i >= cfg->line_outs) 3585 if (i >= cfg->line_outs) {
3269 pin = spec->multi_io[i - 1].pin; 3586 pin = spec->multi_io[i - 1].pin;
3270 else 3587 index = 0;
3588 name = channel_name[i];
3589 } else {
3271 pin = cfg->line_out_pins[i]; 3590 pin = cfg->line_out_pins[i];
3591 name = alc_get_line_out_pfx(spec, i, true, &index);
3592 }
3272 3593
3273 sw = alc_look_for_out_mute_nid(codec, pin, dac); 3594 sw = alc_look_for_out_mute_nid(codec, pin, dac);
3274 vol = alc_look_for_out_vol_nid(codec, pin, dac); 3595 vol = alc_look_for_out_vol_nid(codec, pin, dac);
3275 name = alc_get_line_out_pfx(spec, i, true, &index);
3276 if (!name || !strcmp(name, "CLFE")) { 3596 if (!name || !strcmp(name, "CLFE")) {
3277 /* Center/LFE */ 3597 /* Center/LFE */
3278 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1); 3598 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
@@ -3369,41 +3689,31 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
3369 return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); 3689 return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0);
3370 } 3690 }
3371 3691
3372 if (dacs[num_pins - 1]) {
3373 /* OK, we have a multi-output system with individual volumes */
3374 for (i = 0; i < num_pins; i++) {
3375 if (num_pins >= 3) {
3376 snprintf(name, sizeof(name), "%s %s",
3377 pfx, channel_name[i]);
3378 err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
3379 name, 0);
3380 } else {
3381 err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
3382 pfx, i);
3383 }
3384 if (err < 0)
3385 return err;
3386 }
3387 return 0;
3388 }
3389
3390 /* Let's create a bind-controls */
3391 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_sw);
3392 if (!ctl)
3393 return -ENOMEM;
3394 n = 0;
3395 for (i = 0; i < num_pins; i++) { 3692 for (i = 0; i < num_pins; i++) {
3396 if (get_wcaps(codec, pins[i]) & AC_WCAP_OUT_AMP) 3693 hda_nid_t dac;
3397 ctl->values[n++] = 3694 if (dacs[num_pins - 1])
3398 HDA_COMPOSE_AMP_VAL(pins[i], 3, 0, HDA_OUTPUT); 3695 dac = dacs[i]; /* with individual volumes */
3399 } 3696 else
3400 if (n) { 3697 dac = 0;
3401 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 3698 if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) {
3402 err = add_control(spec, ALC_CTL_BIND_SW, name, 0, (long)ctl); 3699 err = alc_auto_create_extra_out(codec, pins[i], dac,
3700 "Bass Speaker", 0);
3701 } else if (num_pins >= 3) {
3702 snprintf(name, sizeof(name), "%s %s",
3703 pfx, channel_name[i]);
3704 err = alc_auto_create_extra_out(codec, pins[i], dac,
3705 name, 0);
3706 } else {
3707 err = alc_auto_create_extra_out(codec, pins[i], dac,
3708 pfx, i);
3709 }
3403 if (err < 0) 3710 if (err < 0)
3404 return err; 3711 return err;
3405 } 3712 }
3713 if (dacs[num_pins - 1])
3714 return 0;
3406 3715
3716 /* Let's create a bind-controls for volumes */
3407 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol); 3717 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol);
3408 if (!ctl) 3718 if (!ctl)
3409 return -ENOMEM; 3719 return -ENOMEM;
@@ -3539,58 +3849,111 @@ static void alc_auto_init_extra_out(struct hda_codec *codec)
3539 } 3849 }
3540} 3850}
3541 3851
3852/* check whether the given pin can be a multi-io pin */
3853static bool can_be_multiio_pin(struct hda_codec *codec,
3854 unsigned int location, hda_nid_t nid)
3855{
3856 unsigned int defcfg, caps;
3857
3858 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3859 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3860 return false;
3861 if (location && get_defcfg_location(defcfg) != location)
3862 return false;
3863 caps = snd_hda_query_pin_caps(codec, nid);
3864 if (!(caps & AC_PINCAP_OUT))
3865 return false;
3866 return true;
3867}
3868
3542/* 3869/*
3543 * multi-io helper 3870 * multi-io helper
3871 *
3872 * When hardwired is set, try to fill ony hardwired pins, and returns
3873 * zero if any pins are filled, non-zero if nothing found.
3874 * When hardwired is off, try to fill possible input pins, and returns
3875 * the badness value.
3544 */ 3876 */
3545static int alc_auto_fill_multi_ios(struct hda_codec *codec, 3877static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3546 unsigned int location, 3878 hda_nid_t reference_pin,
3547 int offset) 3879 bool hardwired, int offset)
3548{ 3880{
3549 struct alc_spec *spec = codec->spec; 3881 struct alc_spec *spec = codec->spec;
3550 struct auto_pin_cfg *cfg = &spec->autocfg; 3882 struct auto_pin_cfg *cfg = &spec->autocfg;
3551 hda_nid_t prime_dac = spec->private_dac_nids[0]; 3883 int type, i, j, dacs, num_pins, old_pins;
3552 int type, i, dacs, num_pins = 0; 3884 unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin);
3885 unsigned int location = get_defcfg_location(defcfg);
3886 int badness = 0;
3887
3888 old_pins = spec->multi_ios;
3889 if (old_pins >= 2)
3890 goto end_fill;
3891
3892 num_pins = 0;
3893 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3894 for (i = 0; i < cfg->num_inputs; i++) {
3895 if (cfg->inputs[i].type != type)
3896 continue;
3897 if (can_be_multiio_pin(codec, location,
3898 cfg->inputs[i].pin))
3899 num_pins++;
3900 }
3901 }
3902 if (num_pins < 2)
3903 goto end_fill;
3553 3904
3554 dacs = spec->multiout.num_dacs; 3905 dacs = spec->multiout.num_dacs;
3555 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { 3906 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3556 for (i = 0; i < cfg->num_inputs; i++) { 3907 for (i = 0; i < cfg->num_inputs; i++) {
3557 hda_nid_t nid = cfg->inputs[i].pin; 3908 hda_nid_t nid = cfg->inputs[i].pin;
3558 hda_nid_t dac = 0; 3909 hda_nid_t dac = 0;
3559 unsigned int defcfg, caps; 3910
3560 if (cfg->inputs[i].type != type) 3911 if (cfg->inputs[i].type != type)
3561 continue; 3912 continue;
3562 defcfg = snd_hda_codec_get_pincfg(codec, nid); 3913 if (!can_be_multiio_pin(codec, location, nid))
3563 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3564 continue;
3565 if (location && get_defcfg_location(defcfg) != location)
3566 continue; 3914 continue;
3567 caps = snd_hda_query_pin_caps(codec, nid); 3915 for (j = 0; j < spec->multi_ios; j++) {
3568 if (!(caps & AC_PINCAP_OUT)) 3916 if (nid == spec->multi_io[j].pin)
3917 break;
3918 }
3919 if (j < spec->multi_ios)
3569 continue; 3920 continue;
3570 if (offset && offset + num_pins < dacs) { 3921
3571 dac = spec->private_dac_nids[offset + num_pins]; 3922 if (offset && offset + spec->multi_ios < dacs) {
3923 dac = spec->private_dac_nids[offset + spec->multi_ios];
3572 if (!alc_auto_is_dac_reachable(codec, nid, dac)) 3924 if (!alc_auto_is_dac_reachable(codec, nid, dac))
3573 dac = 0; 3925 dac = 0;
3574 } 3926 }
3575 if (!dac) 3927 if (hardwired)
3928 dac = get_dac_if_single(codec, nid);
3929 else if (!dac)
3576 dac = alc_auto_look_for_dac(codec, nid); 3930 dac = alc_auto_look_for_dac(codec, nid);
3577 if (!dac) 3931 if (!dac) {
3932 badness++;
3578 continue; 3933 continue;
3579 spec->multi_io[num_pins].pin = nid; 3934 }
3580 spec->multi_io[num_pins].dac = dac; 3935 spec->multi_io[spec->multi_ios].pin = nid;
3581 num_pins++; 3936 spec->multi_io[spec->multi_ios].dac = dac;
3582 spec->private_dac_nids[spec->multiout.num_dacs++] = dac; 3937 spec->multi_ios++;
3938 if (spec->multi_ios >= 2)
3939 break;
3583 } 3940 }
3584 } 3941 }
3585 spec->multiout.num_dacs = dacs; 3942 end_fill:
3586 if (num_pins < 2) { 3943 if (badness)
3587 /* clear up again */ 3944 badness = BAD_MULTI_IO;
3588 memset(spec->private_dac_nids + dacs, 0, 3945 if (old_pins == spec->multi_ios) {
3589 sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - dacs)); 3946 if (hardwired)
3590 spec->private_dac_nids[0] = prime_dac; 3947 return 1; /* nothing found */
3591 return 0; 3948 else
3949 return badness; /* no badness if nothing found */
3950 }
3951 if (!hardwired && spec->multi_ios < 2) {
3952 spec->multi_ios = old_pins;
3953 return badness;
3592 } 3954 }
3593 return num_pins; 3955
3956 return 0;
3594} 3957}
3595 3958
3596static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol, 3959static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
@@ -3710,6 +4073,7 @@ static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
3710 if (spec->dyn_adc_switch) 4073 if (spec->dyn_adc_switch)
3711 return; 4074 return;
3712 4075
4076 again:
3713 nums = 0; 4077 nums = 0;
3714 for (n = 0; n < spec->num_adc_nids; n++) { 4078 for (n = 0; n < spec->num_adc_nids; n++) {
3715 hda_nid_t cap = spec->private_capsrc_nids[n]; 4079 hda_nid_t cap = spec->private_capsrc_nids[n];
@@ -3730,6 +4094,11 @@ static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
3730 if (!nums) { 4094 if (!nums) {
3731 /* check whether ADC-switch is possible */ 4095 /* check whether ADC-switch is possible */
3732 if (!alc_check_dyn_adc_switch(codec)) { 4096 if (!alc_check_dyn_adc_switch(codec)) {
4097 if (spec->shared_mic_hp) {
4098 spec->shared_mic_hp = 0;
4099 spec->private_imux[0].num_items = 1;
4100 goto again;
4101 }
3733 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" 4102 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
3734 " using fallback 0x%x\n", 4103 " using fallback 0x%x\n",
3735 codec->chip_name, spec->private_adc_nids[0]); 4104 codec->chip_name, spec->private_adc_nids[0]);
@@ -3747,7 +4116,7 @@ static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
3747 4116
3748 if (spec->auto_mic) 4117 if (spec->auto_mic)
3749 alc_auto_mic_check_imux(codec); /* check auto-mic setups */ 4118 alc_auto_mic_check_imux(codec); /* check auto-mic setups */
3750 else if (spec->input_mux->num_items == 1) 4119 else if (spec->input_mux->num_items == 1 || spec->shared_mic_hp)
3751 spec->num_adc_nids = 1; /* reduce to a single ADC */ 4120 spec->num_adc_nids = 1; /* reduce to a single ADC */
3752} 4121}
3753 4122
@@ -3788,7 +4157,7 @@ static void alc_auto_init_input_src(struct hda_codec *codec)
3788 else 4157 else
3789 nums = spec->num_adc_nids; 4158 nums = spec->num_adc_nids;
3790 for (c = 0; c < nums; c++) 4159 for (c = 0; c < nums; c++)
3791 alc_mux_select(codec, 0, spec->cur_mux[c], true); 4160 alc_mux_select(codec, c, spec->cur_mux[c], true);
3792} 4161}
3793 4162
3794/* add mic boosts if needed */ 4163/* add mic boosts if needed */
@@ -3945,6 +4314,7 @@ static const struct snd_pci_quirk beep_white_list[] = {
3945 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), 4314 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
3946 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), 4315 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
3947 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), 4316 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
4317 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
3948 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 4318 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
3949 {} 4319 {}
3950}; 4320};
@@ -4044,6 +4414,9 @@ static int alc_parse_auto_config(struct hda_codec *codec,
4044 if (spec->kctls.list) 4414 if (spec->kctls.list)
4045 add_mixer(spec, spec->kctls.list); 4415 add_mixer(spec, spec->kctls.list);
4046 4416
4417 if (!spec->no_analog && !spec->cap_mixer)
4418 set_capture_mixer(codec);
4419
4047 return 1; 4420 return 1;
4048} 4421}
4049 4422
@@ -4054,26 +4427,47 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4054 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); 4427 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
4055} 4428}
4056 4429
4057#ifdef CONFIG_SND_HDA_POWER_SAVE
4058static const struct hda_amp_list alc880_loopbacks[] = {
4059 { 0x0b, HDA_INPUT, 0 },
4060 { 0x0b, HDA_INPUT, 1 },
4061 { 0x0b, HDA_INPUT, 2 },
4062 { 0x0b, HDA_INPUT, 3 },
4063 { 0x0b, HDA_INPUT, 4 },
4064 { } /* end */
4065};
4066#endif
4067
4068/* 4430/*
4069 * ALC880 fix-ups 4431 * ALC880 fix-ups
4070 */ 4432 */
4071enum { 4433enum {
4434 ALC880_FIXUP_GPIO1,
4072 ALC880_FIXUP_GPIO2, 4435 ALC880_FIXUP_GPIO2,
4073 ALC880_FIXUP_MEDION_RIM, 4436 ALC880_FIXUP_MEDION_RIM,
4437 ALC880_FIXUP_LG,
4438 ALC880_FIXUP_W810,
4439 ALC880_FIXUP_EAPD_COEF,
4440 ALC880_FIXUP_TCL_S700,
4441 ALC880_FIXUP_VOL_KNOB,
4442 ALC880_FIXUP_FUJITSU,
4443 ALC880_FIXUP_F1734,
4444 ALC880_FIXUP_UNIWILL,
4445 ALC880_FIXUP_UNIWILL_DIG,
4446 ALC880_FIXUP_Z71V,
4447 ALC880_FIXUP_3ST_BASE,
4448 ALC880_FIXUP_3ST,
4449 ALC880_FIXUP_3ST_DIG,
4450 ALC880_FIXUP_5ST_BASE,
4451 ALC880_FIXUP_5ST,
4452 ALC880_FIXUP_5ST_DIG,
4453 ALC880_FIXUP_6ST_BASE,
4454 ALC880_FIXUP_6ST,
4455 ALC880_FIXUP_6ST_DIG,
4074}; 4456};
4075 4457
4458/* enable the volume-knob widget support on NID 0x21 */
4459static void alc880_fixup_vol_knob(struct hda_codec *codec,
4460 const struct alc_fixup *fix, int action)
4461{
4462 if (action == ALC_FIXUP_ACT_PROBE)
4463 snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT);
4464}
4465
4076static const struct alc_fixup alc880_fixups[] = { 4466static const struct alc_fixup alc880_fixups[] = {
4467 [ALC880_FIXUP_GPIO1] = {
4468 .type = ALC_FIXUP_VERBS,
4469 .v.verbs = alc_gpio1_init_verbs,
4470 },
4077 [ALC880_FIXUP_GPIO2] = { 4471 [ALC880_FIXUP_GPIO2] = {
4078 .type = ALC_FIXUP_VERBS, 4472 .type = ALC_FIXUP_VERBS,
4079 .v.verbs = alc_gpio2_init_verbs, 4473 .v.verbs = alc_gpio2_init_verbs,
@@ -4088,40 +4482,323 @@ static const struct alc_fixup alc880_fixups[] = {
4088 .chained = true, 4482 .chained = true,
4089 .chain_id = ALC880_FIXUP_GPIO2, 4483 .chain_id = ALC880_FIXUP_GPIO2,
4090 }, 4484 },
4485 [ALC880_FIXUP_LG] = {
4486 .type = ALC_FIXUP_PINS,
4487 .v.pins = (const struct alc_pincfg[]) {
4488 /* disable bogus unused pins */
4489 { 0x16, 0x411111f0 },
4490 { 0x18, 0x411111f0 },
4491 { 0x1a, 0x411111f0 },
4492 { }
4493 }
4494 },
4495 [ALC880_FIXUP_W810] = {
4496 .type = ALC_FIXUP_PINS,
4497 .v.pins = (const struct alc_pincfg[]) {
4498 /* disable bogus unused pins */
4499 { 0x17, 0x411111f0 },
4500 { }
4501 },
4502 .chained = true,
4503 .chain_id = ALC880_FIXUP_GPIO2,
4504 },
4505 [ALC880_FIXUP_EAPD_COEF] = {
4506 .type = ALC_FIXUP_VERBS,
4507 .v.verbs = (const struct hda_verb[]) {
4508 /* change to EAPD mode */
4509 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4510 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
4511 {}
4512 },
4513 },
4514 [ALC880_FIXUP_TCL_S700] = {
4515 .type = ALC_FIXUP_VERBS,
4516 .v.verbs = (const struct hda_verb[]) {
4517 /* change to EAPD mode */
4518 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4519 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
4520 {}
4521 },
4522 .chained = true,
4523 .chain_id = ALC880_FIXUP_GPIO2,
4524 },
4525 [ALC880_FIXUP_VOL_KNOB] = {
4526 .type = ALC_FIXUP_FUNC,
4527 .v.func = alc880_fixup_vol_knob,
4528 },
4529 [ALC880_FIXUP_FUJITSU] = {
4530 /* override all pins as BIOS on old Amilo is broken */
4531 .type = ALC_FIXUP_PINS,
4532 .v.pins = (const struct alc_pincfg[]) {
4533 { 0x14, 0x0121411f }, /* HP */
4534 { 0x15, 0x99030120 }, /* speaker */
4535 { 0x16, 0x99030130 }, /* bass speaker */
4536 { 0x17, 0x411111f0 }, /* N/A */
4537 { 0x18, 0x411111f0 }, /* N/A */
4538 { 0x19, 0x01a19950 }, /* mic-in */
4539 { 0x1a, 0x411111f0 }, /* N/A */
4540 { 0x1b, 0x411111f0 }, /* N/A */
4541 { 0x1c, 0x411111f0 }, /* N/A */
4542 { 0x1d, 0x411111f0 }, /* N/A */
4543 { 0x1e, 0x01454140 }, /* SPDIF out */
4544 { }
4545 },
4546 .chained = true,
4547 .chain_id = ALC880_FIXUP_VOL_KNOB,
4548 },
4549 [ALC880_FIXUP_F1734] = {
4550 /* almost compatible with FUJITSU, but no bass and SPDIF */
4551 .type = ALC_FIXUP_PINS,
4552 .v.pins = (const struct alc_pincfg[]) {
4553 { 0x14, 0x0121411f }, /* HP */
4554 { 0x15, 0x99030120 }, /* speaker */
4555 { 0x16, 0x411111f0 }, /* N/A */
4556 { 0x17, 0x411111f0 }, /* N/A */
4557 { 0x18, 0x411111f0 }, /* N/A */
4558 { 0x19, 0x01a19950 }, /* mic-in */
4559 { 0x1a, 0x411111f0 }, /* N/A */
4560 { 0x1b, 0x411111f0 }, /* N/A */
4561 { 0x1c, 0x411111f0 }, /* N/A */
4562 { 0x1d, 0x411111f0 }, /* N/A */
4563 { 0x1e, 0x411111f0 }, /* N/A */
4564 { }
4565 },
4566 .chained = true,
4567 .chain_id = ALC880_FIXUP_VOL_KNOB,
4568 },
4569 [ALC880_FIXUP_UNIWILL] = {
4570 /* need to fix HP and speaker pins to be parsed correctly */
4571 .type = ALC_FIXUP_PINS,
4572 .v.pins = (const struct alc_pincfg[]) {
4573 { 0x14, 0x0121411f }, /* HP */
4574 { 0x15, 0x99030120 }, /* speaker */
4575 { 0x16, 0x99030130 }, /* bass speaker */
4576 { }
4577 },
4578 },
4579 [ALC880_FIXUP_UNIWILL_DIG] = {
4580 .type = ALC_FIXUP_PINS,
4581 .v.pins = (const struct alc_pincfg[]) {
4582 /* disable bogus unused pins */
4583 { 0x17, 0x411111f0 },
4584 { 0x19, 0x411111f0 },
4585 { 0x1b, 0x411111f0 },
4586 { 0x1f, 0x411111f0 },
4587 { }
4588 }
4589 },
4590 [ALC880_FIXUP_Z71V] = {
4591 .type = ALC_FIXUP_PINS,
4592 .v.pins = (const struct alc_pincfg[]) {
4593 /* set up the whole pins as BIOS is utterly broken */
4594 { 0x14, 0x99030120 }, /* speaker */
4595 { 0x15, 0x0121411f }, /* HP */
4596 { 0x16, 0x411111f0 }, /* N/A */
4597 { 0x17, 0x411111f0 }, /* N/A */
4598 { 0x18, 0x01a19950 }, /* mic-in */
4599 { 0x19, 0x411111f0 }, /* N/A */
4600 { 0x1a, 0x01813031 }, /* line-in */
4601 { 0x1b, 0x411111f0 }, /* N/A */
4602 { 0x1c, 0x411111f0 }, /* N/A */
4603 { 0x1d, 0x411111f0 }, /* N/A */
4604 { 0x1e, 0x0144111e }, /* SPDIF */
4605 { }
4606 }
4607 },
4608 [ALC880_FIXUP_3ST_BASE] = {
4609 .type = ALC_FIXUP_PINS,
4610 .v.pins = (const struct alc_pincfg[]) {
4611 { 0x14, 0x01014010 }, /* line-out */
4612 { 0x15, 0x411111f0 }, /* N/A */
4613 { 0x16, 0x411111f0 }, /* N/A */
4614 { 0x17, 0x411111f0 }, /* N/A */
4615 { 0x18, 0x01a19c30 }, /* mic-in */
4616 { 0x19, 0x0121411f }, /* HP */
4617 { 0x1a, 0x01813031 }, /* line-in */
4618 { 0x1b, 0x02a19c40 }, /* front-mic */
4619 { 0x1c, 0x411111f0 }, /* N/A */
4620 { 0x1d, 0x411111f0 }, /* N/A */
4621 /* 0x1e is filled in below */
4622 { 0x1f, 0x411111f0 }, /* N/A */
4623 { }
4624 }
4625 },
4626 [ALC880_FIXUP_3ST] = {
4627 .type = ALC_FIXUP_PINS,
4628 .v.pins = (const struct alc_pincfg[]) {
4629 { 0x1e, 0x411111f0 }, /* N/A */
4630 { }
4631 },
4632 .chained = true,
4633 .chain_id = ALC880_FIXUP_3ST_BASE,
4634 },
4635 [ALC880_FIXUP_3ST_DIG] = {
4636 .type = ALC_FIXUP_PINS,
4637 .v.pins = (const struct alc_pincfg[]) {
4638 { 0x1e, 0x0144111e }, /* SPDIF */
4639 { }
4640 },
4641 .chained = true,
4642 .chain_id = ALC880_FIXUP_3ST_BASE,
4643 },
4644 [ALC880_FIXUP_5ST_BASE] = {
4645 .type = ALC_FIXUP_PINS,
4646 .v.pins = (const struct alc_pincfg[]) {
4647 { 0x14, 0x01014010 }, /* front */
4648 { 0x15, 0x411111f0 }, /* N/A */
4649 { 0x16, 0x01011411 }, /* CLFE */
4650 { 0x17, 0x01016412 }, /* surr */
4651 { 0x18, 0x01a19c30 }, /* mic-in */
4652 { 0x19, 0x0121411f }, /* HP */
4653 { 0x1a, 0x01813031 }, /* line-in */
4654 { 0x1b, 0x02a19c40 }, /* front-mic */
4655 { 0x1c, 0x411111f0 }, /* N/A */
4656 { 0x1d, 0x411111f0 }, /* N/A */
4657 /* 0x1e is filled in below */
4658 { 0x1f, 0x411111f0 }, /* N/A */
4659 { }
4660 }
4661 },
4662 [ALC880_FIXUP_5ST] = {
4663 .type = ALC_FIXUP_PINS,
4664 .v.pins = (const struct alc_pincfg[]) {
4665 { 0x1e, 0x411111f0 }, /* N/A */
4666 { }
4667 },
4668 .chained = true,
4669 .chain_id = ALC880_FIXUP_5ST_BASE,
4670 },
4671 [ALC880_FIXUP_5ST_DIG] = {
4672 .type = ALC_FIXUP_PINS,
4673 .v.pins = (const struct alc_pincfg[]) {
4674 { 0x1e, 0x0144111e }, /* SPDIF */
4675 { }
4676 },
4677 .chained = true,
4678 .chain_id = ALC880_FIXUP_5ST_BASE,
4679 },
4680 [ALC880_FIXUP_6ST_BASE] = {
4681 .type = ALC_FIXUP_PINS,
4682 .v.pins = (const struct alc_pincfg[]) {
4683 { 0x14, 0x01014010 }, /* front */
4684 { 0x15, 0x01016412 }, /* surr */
4685 { 0x16, 0x01011411 }, /* CLFE */
4686 { 0x17, 0x01012414 }, /* side */
4687 { 0x18, 0x01a19c30 }, /* mic-in */
4688 { 0x19, 0x02a19c40 }, /* front-mic */
4689 { 0x1a, 0x01813031 }, /* line-in */
4690 { 0x1b, 0x0121411f }, /* HP */
4691 { 0x1c, 0x411111f0 }, /* N/A */
4692 { 0x1d, 0x411111f0 }, /* N/A */
4693 /* 0x1e is filled in below */
4694 { 0x1f, 0x411111f0 }, /* N/A */
4695 { }
4696 }
4697 },
4698 [ALC880_FIXUP_6ST] = {
4699 .type = ALC_FIXUP_PINS,
4700 .v.pins = (const struct alc_pincfg[]) {
4701 { 0x1e, 0x411111f0 }, /* N/A */
4702 { }
4703 },
4704 .chained = true,
4705 .chain_id = ALC880_FIXUP_6ST_BASE,
4706 },
4707 [ALC880_FIXUP_6ST_DIG] = {
4708 .type = ALC_FIXUP_PINS,
4709 .v.pins = (const struct alc_pincfg[]) {
4710 { 0x1e, 0x0144111e }, /* SPDIF */
4711 { }
4712 },
4713 .chained = true,
4714 .chain_id = ALC880_FIXUP_6ST_BASE,
4715 },
4091}; 4716};
4092 4717
4093static const struct snd_pci_quirk alc880_fixup_tbl[] = { 4718static const struct snd_pci_quirk alc880_fixup_tbl[] = {
4719 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
4720 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
4721 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
4722 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
4723 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
4724 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
4725 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
4726 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
4727 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
4728 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
4094 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), 4729 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
4730 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734),
4731 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
4732 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
4733 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
4734 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
4735 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
4736 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
4737 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
4738
4739 /* Below is the copied entries from alc880_quirks.c.
4740 * It's not quite sure whether BIOS sets the correct pin-config table
4741 * on these machines, thus they are kept to be compatible with
4742 * the old static quirks. Once when it's confirmed to work without
4743 * these overrides, it'd be better to remove.
4744 */
4745 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
4746 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
4747 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
4748 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
4749 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
4750 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
4751 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
4752 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
4753 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
4754 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
4755 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
4756 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
4757 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
4758 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
4759 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
4760 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
4761 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
4762 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
4763 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
4764 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
4765 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
4766 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
4767 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
4768 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4769 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4770 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4771 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4772 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4773 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4774 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4775 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4776 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4777 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4778 /* default Intel */
4779 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
4780 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
4781 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
4095 {} 4782 {}
4096}; 4783};
4097 4784
4785static const struct alc_model_fixup alc880_fixup_models[] = {
4786 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
4787 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
4788 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
4789 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
4790 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
4791 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
4792 {}
4793};
4098 4794
4099/*
4100 * board setups
4101 */
4102#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4103#define alc_board_config \
4104 snd_hda_check_board_config
4105#define alc_board_codec_sid_config \
4106 snd_hda_check_board_codec_sid_config
4107#include "alc_quirks.c"
4108#else
4109#define alc_board_config(codec, nums, models, tbl) -1
4110#define alc_board_codec_sid_config(codec, nums, models, tbl) -1
4111#define setup_preset(codec, x) /* NOP */
4112#endif
4113 4795
4114/* 4796/*
4115 * OK, here we have finally the patch for ALC880 4797 * OK, here we have finally the patch for ALC880
4116 */ 4798 */
4117#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4118#include "alc880_quirks.c"
4119#endif
4120
4121static int patch_alc880(struct hda_codec *codec) 4799static int patch_alc880(struct hda_codec *codec)
4122{ 4800{
4123 struct alc_spec *spec; 4801 struct alc_spec *spec;
4124 int board_config;
4125 int err; 4802 int err;
4126 4803
4127 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4804 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -4133,47 +4810,14 @@ static int patch_alc880(struct hda_codec *codec)
4133 spec->mixer_nid = 0x0b; 4810 spec->mixer_nid = 0x0b;
4134 spec->need_dac_fix = 1; 4811 spec->need_dac_fix = 1;
4135 4812
4136 board_config = alc_board_config(codec, ALC880_MODEL_LAST, 4813 alc_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
4137 alc880_models, alc880_cfg_tbl); 4814 alc880_fixups);
4138 if (board_config < 0) { 4815 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4139 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4140 codec->chip_name);
4141 board_config = ALC_MODEL_AUTO;
4142 }
4143
4144 if (board_config == ALC_MODEL_AUTO) {
4145 alc_pick_fixup(codec, NULL, alc880_fixup_tbl, alc880_fixups);
4146 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4147 }
4148
4149 if (board_config == ALC_MODEL_AUTO) {
4150 /* automatic parse from the BIOS config */
4151 err = alc880_parse_auto_config(codec);
4152 if (err < 0)
4153 goto error;
4154#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4155 else if (!err) {
4156 printk(KERN_INFO
4157 "hda_codec: Cannot set up configuration "
4158 "from BIOS. Using 3-stack mode...\n");
4159 board_config = ALC880_3ST;
4160 }
4161#endif
4162 }
4163
4164 if (board_config != ALC_MODEL_AUTO) {
4165 spec->vmaster_nid = 0x0c;
4166 setup_preset(codec, &alc880_presets[board_config]);
4167 }
4168
4169 if (!spec->no_analog && !spec->adc_nids) {
4170 alc_auto_fill_adc_caps(codec);
4171 alc_rebuild_imux_for_auto_mic(codec);
4172 alc_remove_invalid_adc_nids(codec);
4173 }
4174 4816
4175 if (!spec->no_analog && !spec->cap_mixer) 4817 /* automatic parse from the BIOS config */
4176 set_capture_mixer(codec); 4818 err = alc880_parse_auto_config(codec);
4819 if (err < 0)
4820 goto error;
4177 4821
4178 if (!spec->no_analog) { 4822 if (!spec->no_analog) {
4179 err = snd_hda_attach_beep_device(codec, 0x1); 4823 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4182,17 +4826,9 @@ static int patch_alc880(struct hda_codec *codec)
4182 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4826 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4183 } 4827 }
4184 4828
4185 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4186
4187 codec->patch_ops = alc_patch_ops; 4829 codec->patch_ops = alc_patch_ops;
4188 if (board_config == ALC_MODEL_AUTO) 4830
4189 spec->init_hook = alc_auto_init_std; 4831 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4190 else
4191 codec->patch_ops.build_controls = __alc_build_controls;
4192#ifdef CONFIG_SND_HDA_POWER_SAVE
4193 if (!spec->loopback.amplist)
4194 spec->loopback.amplist = alc880_loopbacks;
4195#endif
4196 4832
4197 return 0; 4833 return 0;
4198 4834
@@ -4212,49 +4848,115 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
4212 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); 4848 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
4213} 4849}
4214 4850
4215#ifdef CONFIG_SND_HDA_POWER_SAVE
4216static const struct hda_amp_list alc260_loopbacks[] = {
4217 { 0x07, HDA_INPUT, 0 },
4218 { 0x07, HDA_INPUT, 1 },
4219 { 0x07, HDA_INPUT, 2 },
4220 { 0x07, HDA_INPUT, 3 },
4221 { 0x07, HDA_INPUT, 4 },
4222 { } /* end */
4223};
4224#endif
4225
4226/* 4851/*
4227 * Pin config fixes 4852 * Pin config fixes
4228 */ 4853 */
4229enum { 4854enum {
4230 PINFIX_HP_DC5750, 4855 ALC260_FIXUP_HP_DC5750,
4856 ALC260_FIXUP_HP_PIN_0F,
4857 ALC260_FIXUP_COEF,
4858 ALC260_FIXUP_GPIO1,
4859 ALC260_FIXUP_GPIO1_TOGGLE,
4860 ALC260_FIXUP_REPLACER,
4861 ALC260_FIXUP_HP_B1900,
4231}; 4862};
4232 4863
4864static void alc260_gpio1_automute(struct hda_codec *codec)
4865{
4866 struct alc_spec *spec = codec->spec;
4867 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4868 spec->hp_jack_present);
4869}
4870
4871static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
4872 const struct alc_fixup *fix, int action)
4873{
4874 struct alc_spec *spec = codec->spec;
4875 if (action == ALC_FIXUP_ACT_PROBE) {
4876 /* although the machine has only one output pin, we need to
4877 * toggle GPIO1 according to the jack state
4878 */
4879 spec->automute_hook = alc260_gpio1_automute;
4880 spec->detect_hp = 1;
4881 spec->automute_speaker = 1;
4882 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
4883 snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
4884 spec->unsol_event = alc_sku_unsol_event;
4885 add_verb(codec->spec, alc_gpio1_init_verbs);
4886 }
4887}
4888
4233static const struct alc_fixup alc260_fixups[] = { 4889static const struct alc_fixup alc260_fixups[] = {
4234 [PINFIX_HP_DC5750] = { 4890 [ALC260_FIXUP_HP_DC5750] = {
4235 .type = ALC_FIXUP_PINS, 4891 .type = ALC_FIXUP_PINS,
4236 .v.pins = (const struct alc_pincfg[]) { 4892 .v.pins = (const struct alc_pincfg[]) {
4237 { 0x11, 0x90130110 }, /* speaker */ 4893 { 0x11, 0x90130110 }, /* speaker */
4238 { } 4894 { }
4239 } 4895 }
4240 }, 4896 },
4897 [ALC260_FIXUP_HP_PIN_0F] = {
4898 .type = ALC_FIXUP_PINS,
4899 .v.pins = (const struct alc_pincfg[]) {
4900 { 0x0f, 0x01214000 }, /* HP */
4901 { }
4902 }
4903 },
4904 [ALC260_FIXUP_COEF] = {
4905 .type = ALC_FIXUP_VERBS,
4906 .v.verbs = (const struct hda_verb[]) {
4907 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4908 { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 },
4909 { }
4910 },
4911 .chained = true,
4912 .chain_id = ALC260_FIXUP_HP_PIN_0F,
4913 },
4914 [ALC260_FIXUP_GPIO1] = {
4915 .type = ALC_FIXUP_VERBS,
4916 .v.verbs = alc_gpio1_init_verbs,
4917 },
4918 [ALC260_FIXUP_GPIO1_TOGGLE] = {
4919 .type = ALC_FIXUP_FUNC,
4920 .v.func = alc260_fixup_gpio1_toggle,
4921 .chained = true,
4922 .chain_id = ALC260_FIXUP_HP_PIN_0F,
4923 },
4924 [ALC260_FIXUP_REPLACER] = {
4925 .type = ALC_FIXUP_VERBS,
4926 .v.verbs = (const struct hda_verb[]) {
4927 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4928 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
4929 { }
4930 },
4931 .chained = true,
4932 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
4933 },
4934 [ALC260_FIXUP_HP_B1900] = {
4935 .type = ALC_FIXUP_FUNC,
4936 .v.func = alc260_fixup_gpio1_toggle,
4937 .chained = true,
4938 .chain_id = ALC260_FIXUP_COEF,
4939 }
4241}; 4940};
4242 4941
4243static const struct snd_pci_quirk alc260_fixup_tbl[] = { 4942static const struct snd_pci_quirk alc260_fixup_tbl[] = {
4244 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), 4943 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
4944 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
4945 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
4946 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
4947 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
4948 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
4949 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
4950 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
4245 {} 4951 {}
4246}; 4952};
4247 4953
4248/* 4954/*
4249 */ 4955 */
4250#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4251#include "alc260_quirks.c"
4252#endif
4253
4254static int patch_alc260(struct hda_codec *codec) 4956static int patch_alc260(struct hda_codec *codec)
4255{ 4957{
4256 struct alc_spec *spec; 4958 struct alc_spec *spec;
4257 int err, board_config; 4959 int err;
4258 4960
4259 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4961 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4260 if (spec == NULL) 4962 if (spec == NULL)
@@ -4264,47 +4966,13 @@ static int patch_alc260(struct hda_codec *codec)
4264 4966
4265 spec->mixer_nid = 0x07; 4967 spec->mixer_nid = 0x07;
4266 4968
4267 board_config = alc_board_config(codec, ALC260_MODEL_LAST, 4969 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
4268 alc260_models, alc260_cfg_tbl); 4970 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4269 if (board_config < 0) {
4270 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4271 codec->chip_name);
4272 board_config = ALC_MODEL_AUTO;
4273 }
4274
4275 if (board_config == ALC_MODEL_AUTO) {
4276 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
4277 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4278 }
4279
4280 if (board_config == ALC_MODEL_AUTO) {
4281 /* automatic parse from the BIOS config */
4282 err = alc260_parse_auto_config(codec);
4283 if (err < 0)
4284 goto error;
4285#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4286 else if (!err) {
4287 printk(KERN_INFO
4288 "hda_codec: Cannot set up configuration "
4289 "from BIOS. Using base mode...\n");
4290 board_config = ALC260_BASIC;
4291 }
4292#endif
4293 }
4294
4295 if (board_config != ALC_MODEL_AUTO) {
4296 setup_preset(codec, &alc260_presets[board_config]);
4297 spec->vmaster_nid = 0x08;
4298 }
4299
4300 if (!spec->no_analog && !spec->adc_nids) {
4301 alc_auto_fill_adc_caps(codec);
4302 alc_rebuild_imux_for_auto_mic(codec);
4303 alc_remove_invalid_adc_nids(codec);
4304 }
4305 4971
4306 if (!spec->no_analog && !spec->cap_mixer) 4972 /* automatic parse from the BIOS config */
4307 set_capture_mixer(codec); 4973 err = alc260_parse_auto_config(codec);
4974 if (err < 0)
4975 goto error;
4308 4976
4309 if (!spec->no_analog) { 4977 if (!spec->no_analog) {
4310 err = snd_hda_attach_beep_device(codec, 0x1); 4978 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4313,18 +4981,10 @@ static int patch_alc260(struct hda_codec *codec)
4313 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 4981 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
4314 } 4982 }
4315 4983
4316 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4317
4318 codec->patch_ops = alc_patch_ops; 4984 codec->patch_ops = alc_patch_ops;
4319 if (board_config == ALC_MODEL_AUTO)
4320 spec->init_hook = alc_auto_init_std;
4321 else
4322 codec->patch_ops.build_controls = __alc_build_controls;
4323 spec->shutup = alc_eapd_shutup; 4985 spec->shutup = alc_eapd_shutup;
4324#ifdef CONFIG_SND_HDA_POWER_SAVE 4986
4325 if (!spec->loopback.amplist) 4987 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4326 spec->loopback.amplist = alc260_loopbacks;
4327#endif
4328 4988
4329 return 0; 4989 return 0;
4330 4990
@@ -4345,9 +5005,6 @@ static int patch_alc260(struct hda_codec *codec)
4345 * In addition, an independent DAC for the multi-playback (not used in this 5005 * In addition, an independent DAC for the multi-playback (not used in this
4346 * driver yet). 5006 * driver yet).
4347 */ 5007 */
4348#ifdef CONFIG_SND_HDA_POWER_SAVE
4349#define alc882_loopbacks alc880_loopbacks
4350#endif
4351 5008
4352/* 5009/*
4353 * Pin config fixes 5010 * Pin config fixes
@@ -4358,11 +5015,14 @@ enum {
4358 ALC882_FIXUP_PB_M5210, 5015 ALC882_FIXUP_PB_M5210,
4359 ALC882_FIXUP_ACER_ASPIRE_7736, 5016 ALC882_FIXUP_ACER_ASPIRE_7736,
4360 ALC882_FIXUP_ASUS_W90V, 5017 ALC882_FIXUP_ASUS_W90V,
5018 ALC889_FIXUP_CD,
4361 ALC889_FIXUP_VAIO_TT, 5019 ALC889_FIXUP_VAIO_TT,
4362 ALC888_FIXUP_EEE1601, 5020 ALC888_FIXUP_EEE1601,
4363 ALC882_FIXUP_EAPD, 5021 ALC882_FIXUP_EAPD,
4364 ALC883_FIXUP_EAPD, 5022 ALC883_FIXUP_EAPD,
4365 ALC883_FIXUP_ACER_EAPD, 5023 ALC883_FIXUP_ACER_EAPD,
5024 ALC882_FIXUP_GPIO1,
5025 ALC882_FIXUP_GPIO2,
4366 ALC882_FIXUP_GPIO3, 5026 ALC882_FIXUP_GPIO3,
4367 ALC889_FIXUP_COEF, 5027 ALC889_FIXUP_COEF,
4368 ALC882_FIXUP_ASUS_W2JC, 5028 ALC882_FIXUP_ASUS_W2JC,
@@ -4370,6 +5030,9 @@ enum {
4370 ALC882_FIXUP_ACER_ASPIRE_8930G, 5030 ALC882_FIXUP_ACER_ASPIRE_8930G,
4371 ALC882_FIXUP_ASPIRE_8930G_VERBS, 5031 ALC882_FIXUP_ASPIRE_8930G_VERBS,
4372 ALC885_FIXUP_MACPRO_GPIO, 5032 ALC885_FIXUP_MACPRO_GPIO,
5033 ALC889_FIXUP_DAC_ROUTE,
5034 ALC889_FIXUP_MBP_VREF,
5035 ALC889_FIXUP_IMAC91_VREF,
4373}; 5036};
4374 5037
4375static void alc889_fixup_coef(struct hda_codec *codec, 5038static void alc889_fixup_coef(struct hda_codec *codec,
@@ -4423,6 +5086,76 @@ static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
4423 alc882_gpio_mute(codec, 1, 0); 5086 alc882_gpio_mute(codec, 1, 0);
4424} 5087}
4425 5088
5089/* Fix the connection of some pins for ALC889:
5090 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
5091 * work correctly (bko#42740)
5092 */
5093static void alc889_fixup_dac_route(struct hda_codec *codec,
5094 const struct alc_fixup *fix, int action)
5095{
5096 if (action == ALC_FIXUP_ACT_PRE_PROBE) {
5097 /* fake the connections during parsing the tree */
5098 hda_nid_t conn1[2] = { 0x0c, 0x0d };
5099 hda_nid_t conn2[2] = { 0x0e, 0x0f };
5100 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
5101 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
5102 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
5103 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
5104 } else if (action == ALC_FIXUP_ACT_PROBE) {
5105 /* restore the connections */
5106 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
5107 snd_hda_override_conn_list(codec, 0x14, 5, conn);
5108 snd_hda_override_conn_list(codec, 0x15, 5, conn);
5109 snd_hda_override_conn_list(codec, 0x18, 5, conn);
5110 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
5111 }
5112}
5113
5114/* Set VREF on HP pin */
5115static void alc889_fixup_mbp_vref(struct hda_codec *codec,
5116 const struct alc_fixup *fix, int action)
5117{
5118 struct alc_spec *spec = codec->spec;
5119 static hda_nid_t nids[2] = { 0x14, 0x15 };
5120 int i;
5121
5122 if (action != ALC_FIXUP_ACT_INIT)
5123 return;
5124 for (i = 0; i < ARRAY_SIZE(nids); i++) {
5125 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
5126 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
5127 continue;
5128 val = snd_hda_codec_read(codec, nids[i], 0,
5129 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5130 val |= AC_PINCTL_VREF_80;
5131 snd_hda_codec_write(codec, nids[i], 0,
5132 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
5133 spec->keep_vref_in_automute = 1;
5134 break;
5135 }
5136}
5137
5138/* Set VREF on speaker pins on imac91 */
5139static void alc889_fixup_imac91_vref(struct hda_codec *codec,
5140 const struct alc_fixup *fix, int action)
5141{
5142 struct alc_spec *spec = codec->spec;
5143 static hda_nid_t nids[2] = { 0x18, 0x1a };
5144 int i;
5145
5146 if (action != ALC_FIXUP_ACT_INIT)
5147 return;
5148 for (i = 0; i < ARRAY_SIZE(nids); i++) {
5149 unsigned int val;
5150 val = snd_hda_codec_read(codec, nids[i], 0,
5151 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5152 val |= AC_PINCTL_VREF_50;
5153 snd_hda_codec_write(codec, nids[i], 0,
5154 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
5155 }
5156 spec->keep_vref_in_automute = 1;
5157}
5158
4426static const struct alc_fixup alc882_fixups[] = { 5159static const struct alc_fixup alc882_fixups[] = {
4427 [ALC882_FIXUP_ABIT_AW9D_MAX] = { 5160 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
4428 .type = ALC_FIXUP_PINS, 5161 .type = ALC_FIXUP_PINS,
@@ -4459,6 +5192,13 @@ static const struct alc_fixup alc882_fixups[] = {
4459 { } 5192 { }
4460 } 5193 }
4461 }, 5194 },
5195 [ALC889_FIXUP_CD] = {
5196 .type = ALC_FIXUP_PINS,
5197 .v.pins = (const struct alc_pincfg[]) {
5198 { 0x1c, 0x993301f0 }, /* CD */
5199 { }
5200 }
5201 },
4462 [ALC889_FIXUP_VAIO_TT] = { 5202 [ALC889_FIXUP_VAIO_TT] = {
4463 .type = ALC_FIXUP_PINS, 5203 .type = ALC_FIXUP_PINS,
4464 .v.pins = (const struct alc_pincfg[]) { 5204 .v.pins = (const struct alc_pincfg[]) {
@@ -4501,6 +5241,14 @@ static const struct alc_fixup alc882_fixups[] = {
4501 { } 5241 { }
4502 } 5242 }
4503 }, 5243 },
5244 [ALC882_FIXUP_GPIO1] = {
5245 .type = ALC_FIXUP_VERBS,
5246 .v.verbs = alc_gpio1_init_verbs,
5247 },
5248 [ALC882_FIXUP_GPIO2] = {
5249 .type = ALC_FIXUP_VERBS,
5250 .v.verbs = alc_gpio2_init_verbs,
5251 },
4504 [ALC882_FIXUP_GPIO3] = { 5252 [ALC882_FIXUP_GPIO3] = {
4505 .type = ALC_FIXUP_VERBS, 5253 .type = ALC_FIXUP_VERBS,
4506 .v.verbs = alc_gpio3_init_verbs, 5254 .v.verbs = alc_gpio3_init_verbs,
@@ -4570,6 +5318,22 @@ static const struct alc_fixup alc882_fixups[] = {
4570 .type = ALC_FIXUP_FUNC, 5318 .type = ALC_FIXUP_FUNC,
4571 .v.func = alc885_fixup_macpro_gpio, 5319 .v.func = alc885_fixup_macpro_gpio,
4572 }, 5320 },
5321 [ALC889_FIXUP_DAC_ROUTE] = {
5322 .type = ALC_FIXUP_FUNC,
5323 .v.func = alc889_fixup_dac_route,
5324 },
5325 [ALC889_FIXUP_MBP_VREF] = {
5326 .type = ALC_FIXUP_FUNC,
5327 .v.func = alc889_fixup_mbp_vref,
5328 .chained = true,
5329 .chain_id = ALC882_FIXUP_GPIO1,
5330 },
5331 [ALC889_FIXUP_IMAC91_VREF] = {
5332 .type = ALC_FIXUP_FUNC,
5333 .v.func = alc889_fixup_imac91_vref,
5334 .chained = true,
5335 .chain_id = ALC882_FIXUP_GPIO1,
5336 },
4573}; 5337};
4574 5338
4575static const struct snd_pci_quirk alc882_fixup_tbl[] = { 5339static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -4594,6 +5358,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
4594 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 5358 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
4595 ALC882_FIXUP_ACER_ASPIRE_4930G), 5359 ALC882_FIXUP_ACER_ASPIRE_4930G),
4596 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), 5360 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
5361 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
4597 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), 5362 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
4598 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), 5363 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
4599 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), 5364 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
@@ -4602,14 +5367,30 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
4602 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), 5367 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
4603 5368
4604 /* All Apple entries are in codec SSIDs */ 5369 /* All Apple entries are in codec SSIDs */
5370 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
5371 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
5372 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
4605 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), 5373 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO),
4606 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), 5374 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
4607 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), 5375 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
5376 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
5377 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
4608 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), 5378 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
5379 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF),
5380 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF),
5381 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
5382 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
4609 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), 5383 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
5384 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
5385 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
5386 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
5387 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
5388 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
5389 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
4610 5390
4611 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), 5391 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
4612 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), 5392 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
5393 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3", ALC889_FIXUP_CD),
4613 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), 5394 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
4614 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), 5395 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
4615 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), 5396 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
@@ -4631,14 +5412,10 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
4631 5412
4632/* 5413/*
4633 */ 5414 */
4634#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4635#include "alc882_quirks.c"
4636#endif
4637
4638static int patch_alc882(struct hda_codec *codec) 5415static int patch_alc882(struct hda_codec *codec)
4639{ 5416{
4640 struct alc_spec *spec; 5417 struct alc_spec *spec;
4641 int err, board_config; 5418 int err;
4642 5419
4643 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5420 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4644 if (spec == NULL) 5421 if (spec == NULL)
@@ -4662,45 +5439,15 @@ static int patch_alc882(struct hda_codec *codec)
4662 if (err < 0) 5439 if (err < 0)
4663 goto error; 5440 goto error;
4664 5441
4665 board_config = alc_board_config(codec, ALC882_MODEL_LAST, 5442 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
4666 alc882_models, NULL); 5443 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4667 if (board_config < 0)
4668 board_config = alc_board_codec_sid_config(codec,
4669 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
4670
4671 if (board_config < 0) {
4672 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4673 codec->chip_name);
4674 board_config = ALC_MODEL_AUTO;
4675 }
4676
4677 if (board_config == ALC_MODEL_AUTO) {
4678 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
4679 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4680 }
4681 5444
4682 alc_auto_parse_customize_define(codec); 5445 alc_auto_parse_customize_define(codec);
4683 5446
4684 if (board_config == ALC_MODEL_AUTO) { 5447 /* automatic parse from the BIOS config */
4685 /* automatic parse from the BIOS config */ 5448 err = alc882_parse_auto_config(codec);
4686 err = alc882_parse_auto_config(codec); 5449 if (err < 0)
4687 if (err < 0) 5450 goto error;
4688 goto error;
4689 }
4690
4691 if (board_config != ALC_MODEL_AUTO) {
4692 setup_preset(codec, &alc882_presets[board_config]);
4693 spec->vmaster_nid = 0x0c;
4694 }
4695
4696 if (!spec->no_analog && !spec->adc_nids) {
4697 alc_auto_fill_adc_caps(codec);
4698 alc_rebuild_imux_for_auto_mic(codec);
4699 alc_remove_invalid_adc_nids(codec);
4700 }
4701
4702 if (!spec->no_analog && !spec->cap_mixer)
4703 set_capture_mixer(codec);
4704 5451
4705 if (!spec->no_analog && has_cdefine_beep(codec)) { 5452 if (!spec->no_analog && has_cdefine_beep(codec)) {
4706 err = snd_hda_attach_beep_device(codec, 0x1); 5453 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4709,18 +5456,9 @@ static int patch_alc882(struct hda_codec *codec)
4709 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5456 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4710 } 5457 }
4711 5458
4712 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4713
4714 codec->patch_ops = alc_patch_ops; 5459 codec->patch_ops = alc_patch_ops;
4715 if (board_config == ALC_MODEL_AUTO)
4716 spec->init_hook = alc_auto_init_std;
4717 else
4718 codec->patch_ops.build_controls = __alc_build_controls;
4719 5460
4720#ifdef CONFIG_SND_HDA_POWER_SAVE 5461 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4721 if (!spec->loopback.amplist)
4722 spec->loopback.amplist = alc882_loopbacks;
4723#endif
4724 5462
4725 return 0; 5463 return 0;
4726 5464
@@ -4816,10 +5554,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
4816}; 5554};
4817 5555
4818 5556
4819#ifdef CONFIG_SND_HDA_POWER_SAVE
4820#define alc262_loopbacks alc880_loopbacks
4821#endif
4822
4823/* 5557/*
4824 */ 5558 */
4825static int patch_alc262(struct hda_codec *codec) 5559static int patch_alc262(struct hda_codec *codec)
@@ -4859,15 +5593,6 @@ static int patch_alc262(struct hda_codec *codec)
4859 if (err < 0) 5593 if (err < 0)
4860 goto error; 5594 goto error;
4861 5595
4862 if (!spec->no_analog && !spec->adc_nids) {
4863 alc_auto_fill_adc_caps(codec);
4864 alc_rebuild_imux_for_auto_mic(codec);
4865 alc_remove_invalid_adc_nids(codec);
4866 }
4867
4868 if (!spec->no_analog && !spec->cap_mixer)
4869 set_capture_mixer(codec);
4870
4871 if (!spec->no_analog && has_cdefine_beep(codec)) { 5596 if (!spec->no_analog && has_cdefine_beep(codec)) {
4872 err = snd_hda_attach_beep_device(codec, 0x1); 5597 err = snd_hda_attach_beep_device(codec, 0x1);
4873 if (err < 0) 5598 if (err < 0)
@@ -4875,16 +5600,10 @@ static int patch_alc262(struct hda_codec *codec)
4875 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5600 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4876 } 5601 }
4877 5602
4878 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4879
4880 codec->patch_ops = alc_patch_ops; 5603 codec->patch_ops = alc_patch_ops;
4881 spec->init_hook = alc_auto_init_std;
4882 spec->shutup = alc_eapd_shutup; 5604 spec->shutup = alc_eapd_shutup;
4883 5605
4884#ifdef CONFIG_SND_HDA_POWER_SAVE 5606 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4885 if (!spec->loopback.amplist)
4886 spec->loopback.amplist = alc262_loopbacks;
4887#endif
4888 5607
4889 return 0; 5608 return 0;
4890 5609
@@ -4978,17 +5697,7 @@ static int patch_alc268(struct hda_codec *codec)
4978 (0 << AC_AMPCAP_MUTE_SHIFT)); 5697 (0 << AC_AMPCAP_MUTE_SHIFT));
4979 } 5698 }
4980 5699
4981 if (!spec->no_analog && !spec->adc_nids) {
4982 alc_auto_fill_adc_caps(codec);
4983 alc_rebuild_imux_for_auto_mic(codec);
4984 alc_remove_invalid_adc_nids(codec);
4985 }
4986
4987 if (!spec->no_analog && !spec->cap_mixer)
4988 set_capture_mixer(codec);
4989
4990 codec->patch_ops = alc_patch_ops; 5700 codec->patch_ops = alc_patch_ops;
4991 spec->init_hook = alc_auto_init_std;
4992 spec->shutup = alc_eapd_shutup; 5701 spec->shutup = alc_eapd_shutup;
4993 5702
4994 return 0; 5703 return 0;
@@ -5001,10 +5710,6 @@ static int patch_alc268(struct hda_codec *codec)
5001/* 5710/*
5002 * ALC269 5711 * ALC269
5003 */ 5712 */
5004#ifdef CONFIG_SND_HDA_POWER_SAVE
5005#define alc269_loopbacks alc880_loopbacks
5006#endif
5007
5008static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 5713static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
5009 .substreams = 1, 5714 .substreams = 1,
5010 .channels_min = 2, 5715 .channels_min = 2,
@@ -5026,35 +5731,6 @@ static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
5026 /* NID is set in alc_build_pcms */ 5731 /* NID is set in alc_build_pcms */
5027}; 5732};
5028 5733
5029#ifdef CONFIG_SND_HDA_POWER_SAVE
5030static int alc269_mic2_for_mute_led(struct hda_codec *codec)
5031{
5032 switch (codec->subsystem_id) {
5033 case 0x103c1586:
5034 return 1;
5035 }
5036 return 0;
5037}
5038
5039static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
5040{
5041 /* update mute-LED according to the speaker mute state */
5042 if (nid == 0x01 || nid == 0x14) {
5043 int pinval;
5044 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
5045 HDA_AMP_MUTE)
5046 pinval = 0x24;
5047 else
5048 pinval = 0x20;
5049 /* mic2 vref pin is used for mute LED control */
5050 snd_hda_codec_update_cache(codec, 0x19, 0,
5051 AC_VERB_SET_PIN_WIDGET_CONTROL,
5052 pinval);
5053 }
5054 return alc_check_power_status(codec, nid);
5055}
5056#endif /* CONFIG_SND_HDA_POWER_SAVE */
5057
5058/* different alc269-variants */ 5734/* different alc269-variants */
5059enum { 5735enum {
5060 ALC269_TYPE_ALC269VA, 5736 ALC269_TYPE_ALC269VA,
@@ -5205,6 +5881,31 @@ static void alc269_fixup_quanta_mute(struct hda_codec *codec,
5205 spec->automute_hook = alc269_quanta_automute; 5881 spec->automute_hook = alc269_quanta_automute;
5206} 5882}
5207 5883
5884/* update mute-LED according to the speaker mute state via mic2 VREF pin */
5885static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled)
5886{
5887 struct hda_codec *codec = private_data;
5888 unsigned int pinval = enabled ? 0x20 : 0x24;
5889 snd_hda_codec_update_cache(codec, 0x19, 0,
5890 AC_VERB_SET_PIN_WIDGET_CONTROL,
5891 pinval);
5892}
5893
5894static void alc269_fixup_mic2_mute(struct hda_codec *codec,
5895 const struct alc_fixup *fix, int action)
5896{
5897 struct alc_spec *spec = codec->spec;
5898 switch (action) {
5899 case ALC_FIXUP_ACT_BUILD:
5900 spec->vmaster_mute.hook = alc269_fixup_mic2_mute_hook;
5901 snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
5902 /* fallthru */
5903 case ALC_FIXUP_ACT_INIT:
5904 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
5905 break;
5906 }
5907}
5908
5208enum { 5909enum {
5209 ALC269_FIXUP_SONY_VAIO, 5910 ALC269_FIXUP_SONY_VAIO,
5210 ALC275_FIXUP_SONY_VAIO_GPIO2, 5911 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -5222,6 +5923,7 @@ enum {
5222 ALC269_FIXUP_DMIC, 5923 ALC269_FIXUP_DMIC,
5223 ALC269VB_FIXUP_AMIC, 5924 ALC269VB_FIXUP_AMIC,
5224 ALC269VB_FIXUP_DMIC, 5925 ALC269VB_FIXUP_DMIC,
5926 ALC269_FIXUP_MIC2_MUTE_LED,
5225}; 5927};
5226 5928
5227static const struct alc_fixup alc269_fixups[] = { 5929static const struct alc_fixup alc269_fixups[] = {
@@ -5342,9 +6044,14 @@ static const struct alc_fixup alc269_fixups[] = {
5342 { } 6044 { }
5343 }, 6045 },
5344 }, 6046 },
6047 [ALC269_FIXUP_MIC2_MUTE_LED] = {
6048 .type = ALC_FIXUP_FUNC,
6049 .v.func = alc269_fixup_mic2_mute,
6050 },
5345}; 6051};
5346 6052
5347static const struct snd_pci_quirk alc269_fixup_tbl[] = { 6053static const struct snd_pci_quirk alc269_fixup_tbl[] = {
6054 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
5348 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 6055 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
5349 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 6056 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5350 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 6057 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
@@ -5367,7 +6074,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5367 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), 6074 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
5368 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 6075 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
5369 6076
5370#if 1 6077#if 0
5371 /* Below is a quirk table taken from the old code. 6078 /* Below is a quirk table taken from the old code.
5372 * Basically the device should work as is without the fixup table. 6079 * Basically the device should work as is without the fixup table.
5373 * If BIOS doesn't give a proper info, enable the corresponding 6080 * If BIOS doesn't give a proper info, enable the corresponding
@@ -5425,10 +6132,14 @@ static const struct alc_model_fixup alc269_fixup_models[] = {
5425}; 6132};
5426 6133
5427 6134
5428static int alc269_fill_coef(struct hda_codec *codec) 6135static void alc269_fill_coef(struct hda_codec *codec)
5429{ 6136{
6137 struct alc_spec *spec = codec->spec;
5430 int val; 6138 int val;
5431 6139
6140 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
6141 return;
6142
5432 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { 6143 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
5433 alc_write_coef_idx(codec, 0xf, 0x960b); 6144 alc_write_coef_idx(codec, 0xf, 0x960b);
5434 alc_write_coef_idx(codec, 0xe, 0x8817); 6145 alc_write_coef_idx(codec, 0xe, 0x8817);
@@ -5463,8 +6174,6 @@ static int alc269_fill_coef(struct hda_codec *codec)
5463 6174
5464 val = alc_read_coef_idx(codec, 0x4); /* HP */ 6175 val = alc_read_coef_idx(codec, 0x4); /* HP */
5465 alc_write_coef_idx(codec, 0x4, val | (1<<11)); 6176 alc_write_coef_idx(codec, 0x4, val | (1<<11));
5466
5467 return 0;
5468} 6177}
5469 6178
5470/* 6179/*
@@ -5508,6 +6217,7 @@ static int patch_alc269(struct hda_codec *codec)
5508 } 6217 }
5509 if (err < 0) 6218 if (err < 0)
5510 goto error; 6219 goto error;
6220 spec->init_hook = alc269_fill_coef;
5511 alc269_fill_coef(codec); 6221 alc269_fill_coef(codec);
5512 } 6222 }
5513 6223
@@ -5520,15 +6230,6 @@ static int patch_alc269(struct hda_codec *codec)
5520 if (err < 0) 6230 if (err < 0)
5521 goto error; 6231 goto error;
5522 6232
5523 if (!spec->no_analog && !spec->adc_nids) {
5524 alc_auto_fill_adc_caps(codec);
5525 alc_rebuild_imux_for_auto_mic(codec);
5526 alc_remove_invalid_adc_nids(codec);
5527 }
5528
5529 if (!spec->no_analog && !spec->cap_mixer)
5530 set_capture_mixer(codec);
5531
5532 if (!spec->no_analog && has_cdefine_beep(codec)) { 6233 if (!spec->no_analog && has_cdefine_beep(codec)) {
5533 err = snd_hda_attach_beep_device(codec, 0x1); 6234 err = snd_hda_attach_beep_device(codec, 0x1);
5534 if (err < 0) 6235 if (err < 0)
@@ -5536,21 +6237,13 @@ static int patch_alc269(struct hda_codec *codec)
5536 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 6237 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
5537 } 6238 }
5538 6239
5539 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5540
5541 codec->patch_ops = alc_patch_ops; 6240 codec->patch_ops = alc_patch_ops;
5542#ifdef CONFIG_PM 6241#ifdef CONFIG_PM
5543 codec->patch_ops.resume = alc269_resume; 6242 codec->patch_ops.resume = alc269_resume;
5544#endif 6243#endif
5545 spec->init_hook = alc_auto_init_std;
5546 spec->shutup = alc269_shutup; 6244 spec->shutup = alc269_shutup;
5547 6245
5548#ifdef CONFIG_SND_HDA_POWER_SAVE 6246 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5549 if (!spec->loopback.amplist)
5550 spec->loopback.amplist = alc269_loopbacks;
5551 if (alc269_mic2_for_mute_led(codec))
5552 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
5553#endif
5554 6247
5555 return 0; 6248 return 0;
5556 6249
@@ -5570,21 +6263,12 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
5570 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); 6263 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
5571} 6264}
5572 6265
5573#ifdef CONFIG_SND_HDA_POWER_SAVE
5574static const struct hda_amp_list alc861_loopbacks[] = {
5575 { 0x15, HDA_INPUT, 0 },
5576 { 0x15, HDA_INPUT, 1 },
5577 { 0x15, HDA_INPUT, 2 },
5578 { 0x15, HDA_INPUT, 3 },
5579 { } /* end */
5580};
5581#endif
5582
5583
5584/* Pin config fixes */ 6266/* Pin config fixes */
5585enum { 6267enum {
5586 PINFIX_FSC_AMILO_PI1505, 6268 ALC861_FIXUP_FSC_AMILO_PI1505,
5587 PINFIX_ASUS_A6RP, 6269 ALC861_FIXUP_AMP_VREF_0F,
6270 ALC861_FIXUP_NO_JACK_DETECT,
6271 ALC861_FIXUP_ASUS_A6RP,
5588}; 6272};
5589 6273
5590/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ 6274/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
@@ -5606,8 +6290,16 @@ static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
5606 spec->keep_vref_in_automute = 1; 6290 spec->keep_vref_in_automute = 1;
5607} 6291}
5608 6292
6293/* suppress the jack-detection */
6294static void alc_fixup_no_jack_detect(struct hda_codec *codec,
6295 const struct alc_fixup *fix, int action)
6296{
6297 if (action == ALC_FIXUP_ACT_PRE_PROBE)
6298 codec->no_jack_detect = 1;
6299}
6300
5609static const struct alc_fixup alc861_fixups[] = { 6301static const struct alc_fixup alc861_fixups[] = {
5610 [PINFIX_FSC_AMILO_PI1505] = { 6302 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
5611 .type = ALC_FIXUP_PINS, 6303 .type = ALC_FIXUP_PINS,
5612 .v.pins = (const struct alc_pincfg[]) { 6304 .v.pins = (const struct alc_pincfg[]) {
5613 { 0x0b, 0x0221101f }, /* HP */ 6305 { 0x0b, 0x0221101f }, /* HP */
@@ -5615,16 +6307,29 @@ static const struct alc_fixup alc861_fixups[] = {
5615 { } 6307 { }
5616 } 6308 }
5617 }, 6309 },
5618 [PINFIX_ASUS_A6RP] = { 6310 [ALC861_FIXUP_AMP_VREF_0F] = {
5619 .type = ALC_FIXUP_FUNC, 6311 .type = ALC_FIXUP_FUNC,
5620 .v.func = alc861_fixup_asus_amp_vref_0f, 6312 .v.func = alc861_fixup_asus_amp_vref_0f,
5621 }, 6313 },
6314 [ALC861_FIXUP_NO_JACK_DETECT] = {
6315 .type = ALC_FIXUP_FUNC,
6316 .v.func = alc_fixup_no_jack_detect,
6317 },
6318 [ALC861_FIXUP_ASUS_A6RP] = {
6319 .type = ALC_FIXUP_FUNC,
6320 .v.func = alc861_fixup_asus_amp_vref_0f,
6321 .chained = true,
6322 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
6323 }
5622}; 6324};
5623 6325
5624static const struct snd_pci_quirk alc861_fixup_tbl[] = { 6326static const struct snd_pci_quirk alc861_fixup_tbl[] = {
5625 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP), 6327 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
5626 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), 6328 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
5627 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 6329 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
6330 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
6331 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
6332 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
5628 {} 6333 {}
5629}; 6334};
5630 6335
@@ -5651,15 +6356,6 @@ static int patch_alc861(struct hda_codec *codec)
5651 if (err < 0) 6356 if (err < 0)
5652 goto error; 6357 goto error;
5653 6358
5654 if (!spec->no_analog && !spec->adc_nids) {
5655 alc_auto_fill_adc_caps(codec);
5656 alc_rebuild_imux_for_auto_mic(codec);
5657 alc_remove_invalid_adc_nids(codec);
5658 }
5659
5660 if (!spec->no_analog && !spec->cap_mixer)
5661 set_capture_mixer(codec);
5662
5663 if (!spec->no_analog) { 6359 if (!spec->no_analog) {
5664 err = snd_hda_attach_beep_device(codec, 0x23); 6360 err = snd_hda_attach_beep_device(codec, 0x23);
5665 if (err < 0) 6361 if (err < 0)
@@ -5667,16 +6363,13 @@ static int patch_alc861(struct hda_codec *codec)
5667 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 6363 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
5668 } 6364 }
5669 6365
5670 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5671
5672 codec->patch_ops = alc_patch_ops; 6366 codec->patch_ops = alc_patch_ops;
5673 spec->init_hook = alc_auto_init_std;
5674#ifdef CONFIG_SND_HDA_POWER_SAVE 6367#ifdef CONFIG_SND_HDA_POWER_SAVE
5675 spec->power_hook = alc_power_eapd; 6368 spec->power_hook = alc_power_eapd;
5676 if (!spec->loopback.amplist)
5677 spec->loopback.amplist = alc861_loopbacks;
5678#endif 6369#endif
5679 6370
6371 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6372
5680 return 0; 6373 return 0;
5681 6374
5682 error: 6375 error:
@@ -5691,10 +6384,6 @@ static int patch_alc861(struct hda_codec *codec)
5691 * 6384 *
5692 * In addition, an independent DAC 6385 * In addition, an independent DAC
5693 */ 6386 */
5694#ifdef CONFIG_SND_HDA_POWER_SAVE
5695#define alc861vd_loopbacks alc880_loopbacks
5696#endif
5697
5698static int alc861vd_parse_auto_config(struct hda_codec *codec) 6387static int alc861vd_parse_auto_config(struct hda_codec *codec)
5699{ 6388{
5700 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 6389 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
@@ -5775,15 +6464,6 @@ static int patch_alc861vd(struct hda_codec *codec)
5775 add_verb(spec, alc660vd_eapd_verbs); 6464 add_verb(spec, alc660vd_eapd_verbs);
5776 } 6465 }
5777 6466
5778 if (!spec->no_analog && !spec->adc_nids) {
5779 alc_auto_fill_adc_caps(codec);
5780 alc_rebuild_imux_for_auto_mic(codec);
5781 alc_remove_invalid_adc_nids(codec);
5782 }
5783
5784 if (!spec->no_analog && !spec->cap_mixer)
5785 set_capture_mixer(codec);
5786
5787 if (!spec->no_analog) { 6467 if (!spec->no_analog) {
5788 err = snd_hda_attach_beep_device(codec, 0x23); 6468 err = snd_hda_attach_beep_device(codec, 0x23);
5789 if (err < 0) 6469 if (err < 0)
@@ -5791,16 +6471,11 @@ static int patch_alc861vd(struct hda_codec *codec)
5791 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 6471 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5792 } 6472 }
5793 6473
5794 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5795
5796 codec->patch_ops = alc_patch_ops; 6474 codec->patch_ops = alc_patch_ops;
5797 6475
5798 spec->init_hook = alc_auto_init_std;
5799 spec->shutup = alc_eapd_shutup; 6476 spec->shutup = alc_eapd_shutup;
5800#ifdef CONFIG_SND_HDA_POWER_SAVE 6477
5801 if (!spec->loopback.amplist) 6478 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5802 spec->loopback.amplist = alc861vd_loopbacks;
5803#endif
5804 6479
5805 return 0; 6480 return 0;
5806 6481
@@ -5820,9 +6495,6 @@ static int patch_alc861vd(struct hda_codec *codec)
5820 * In addition, an independent DAC for the multi-playback (not used in this 6495 * In addition, an independent DAC for the multi-playback (not used in this
5821 * driver yet). 6496 * driver yet).
5822 */ 6497 */
5823#ifdef CONFIG_SND_HDA_POWER_SAVE
5824#define alc662_loopbacks alc880_loopbacks
5825#endif
5826 6498
5827/* 6499/*
5828 * BIOS auto configuration 6500 * BIOS auto configuration
@@ -5872,6 +6544,7 @@ enum {
5872 ALC662_FIXUP_ASUS_MODE6, 6544 ALC662_FIXUP_ASUS_MODE6,
5873 ALC662_FIXUP_ASUS_MODE7, 6545 ALC662_FIXUP_ASUS_MODE7,
5874 ALC662_FIXUP_ASUS_MODE8, 6546 ALC662_FIXUP_ASUS_MODE8,
6547 ALC662_FIXUP_NO_JACK_DETECT,
5875}; 6548};
5876 6549
5877static const struct alc_fixup alc662_fixups[] = { 6550static const struct alc_fixup alc662_fixups[] = {
@@ -6017,6 +6690,10 @@ static const struct alc_fixup alc662_fixups[] = {
6017 .chained = true, 6690 .chained = true,
6018 .chain_id = ALC662_FIXUP_SKU_IGNORE 6691 .chain_id = ALC662_FIXUP_SKU_IGNORE
6019 }, 6692 },
6693 [ALC662_FIXUP_NO_JACK_DETECT] = {
6694 .type = ALC_FIXUP_FUNC,
6695 .v.func = alc_fixup_no_jack_detect,
6696 },
6020}; 6697};
6021 6698
6022static const struct snd_pci_quirk alc662_fixup_tbl[] = { 6699static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -6025,6 +6702,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
6025 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 6702 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
6026 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 6703 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
6027 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 6704 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
6705 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
6028 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), 6706 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
6029 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 6707 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
6030 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 6708 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
@@ -6146,15 +6824,6 @@ static int patch_alc662(struct hda_codec *codec)
6146 if (err < 0) 6824 if (err < 0)
6147 goto error; 6825 goto error;
6148 6826
6149 if (!spec->no_analog && !spec->adc_nids) {
6150 alc_auto_fill_adc_caps(codec);
6151 alc_rebuild_imux_for_auto_mic(codec);
6152 alc_remove_invalid_adc_nids(codec);
6153 }
6154
6155 if (!spec->no_analog && !spec->cap_mixer)
6156 set_capture_mixer(codec);
6157
6158 if (!spec->no_analog && has_cdefine_beep(codec)) { 6827 if (!spec->no_analog && has_cdefine_beep(codec)) {
6159 err = snd_hda_attach_beep_device(codec, 0x1); 6828 err = snd_hda_attach_beep_device(codec, 0x1);
6160 if (err < 0) 6829 if (err < 0)
@@ -6174,16 +6843,10 @@ static int patch_alc662(struct hda_codec *codec)
6174 } 6843 }
6175 } 6844 }
6176 6845
6177 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6178
6179 codec->patch_ops = alc_patch_ops; 6846 codec->patch_ops = alc_patch_ops;
6180 spec->init_hook = alc_auto_init_std;
6181 spec->shutup = alc_eapd_shutup; 6847 spec->shutup = alc_eapd_shutup;
6182 6848
6183#ifdef CONFIG_SND_HDA_POWER_SAVE 6849 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6184 if (!spec->loopback.amplist)
6185 spec->loopback.amplist = alc662_loopbacks;
6186#endif
6187 6850
6188 return 0; 6851 return 0;
6189 6852
@@ -6223,11 +6886,7 @@ static int patch_alc680(struct hda_codec *codec)
6223 return err; 6886 return err;
6224 } 6887 }
6225 6888
6226 if (!spec->no_analog && !spec->cap_mixer)
6227 set_capture_mixer(codec);
6228
6229 codec->patch_ops = alc_patch_ops; 6889 codec->patch_ops = alc_patch_ops;
6230 spec->init_hook = alc_auto_init_std;
6231 6890
6232 return 0; 6891 return 0;
6233} 6892}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 948f0be2f4f3..33a9946b492c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -99,6 +99,7 @@ enum {
99 STAC_DELL_VOSTRO_3500, 99 STAC_DELL_VOSTRO_3500,
100 STAC_92HD83XXX_HP_cNB11_INTQUAD, 100 STAC_92HD83XXX_HP_cNB11_INTQUAD,
101 STAC_HP_DV7_4000, 101 STAC_HP_DV7_4000,
102 STAC_HP_ZEPHYR,
102 STAC_92HD83XXX_MODELS 103 STAC_92HD83XXX_MODELS
103}; 104};
104 105
@@ -309,6 +310,8 @@ struct sigmatel_spec {
309 unsigned long auto_capvols[MAX_ADCS_NUM]; 310 unsigned long auto_capvols[MAX_ADCS_NUM];
310 unsigned auto_dmic_cnt; 311 unsigned auto_dmic_cnt;
311 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; 312 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM];
313
314 struct hda_vmaster_mute_hook vmaster_mute;
312}; 315};
313 316
314static const hda_nid_t stac9200_adc_nids[1] = { 317static const hda_nid_t stac9200_adc_nids[1] = {
@@ -662,7 +665,6 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
662 return 0; 665 return 0;
663} 666}
664 667
665#ifdef CONFIG_SND_HDA_POWER_SAVE
666static int stac_vrefout_set(struct hda_codec *codec, 668static int stac_vrefout_set(struct hda_codec *codec,
667 hda_nid_t nid, unsigned int new_vref) 669 hda_nid_t nid, unsigned int new_vref)
668{ 670{
@@ -686,7 +688,6 @@ static int stac_vrefout_set(struct hda_codec *codec,
686 688
687 return 1; 689 return 1;
688} 690}
689#endif
690 691
691static unsigned int stac92xx_vref_set(struct hda_codec *codec, 692static unsigned int stac92xx_vref_set(struct hda_codec *codec,
692 hda_nid_t nid, unsigned int new_vref) 693 hda_nid_t nid, unsigned int new_vref)
@@ -894,6 +895,13 @@ static const struct hda_verb stac92hd83xxx_core_init[] = {
894 {} 895 {}
895}; 896};
896 897
898static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
899 { 0x22, 0x785, 0x43 },
900 { 0x22, 0x782, 0xe0 },
901 { 0x22, 0x795, 0x00 },
902 {}
903};
904
897static const struct hda_verb stac92hd71bxx_core_init[] = { 905static const struct hda_verb stac92hd71bxx_core_init[] = {
898 /* set master volume and direct control */ 906 /* set master volume and direct control */
899 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 907 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -999,8 +1007,8 @@ static const struct hda_verb stac9205_core_init[] = {
999 } 1007 }
1000 1008
1001static const struct snd_kcontrol_new stac9200_mixer[] = { 1009static const struct snd_kcontrol_new stac9200_mixer[] = {
1002 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT), 1010 HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xb, 0, HDA_OUTPUT),
1003 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), 1011 HDA_CODEC_MUTE("PCM Playback Switch", 0xb, 0, HDA_OUTPUT),
1004 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), 1012 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
1005 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), 1013 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
1006 { } /* end */ 1014 { } /* end */
@@ -1027,8 +1035,8 @@ static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
1027}; 1035};
1028 1036
1029static const struct snd_kcontrol_new stac925x_mixer[] = { 1037static const struct snd_kcontrol_new stac925x_mixer[] = {
1030 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT), 1038 HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xe, 0, HDA_OUTPUT),
1031 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), 1039 HDA_CODEC_MUTE("PCM Playback Switch", 0x0e, 0, HDA_OUTPUT),
1032 { } /* end */ 1040 { } /* end */
1033}; 1041};
1034 1042
@@ -1060,34 +1068,25 @@ static struct snd_kcontrol_new stac_smux_mixer = {
1060 .put = stac92xx_smux_enum_put, 1068 .put = stac92xx_smux_enum_put,
1061}; 1069};
1062 1070
1063static const char * const slave_vols[] = { 1071static const char * const slave_pfxs[] = {
1064 "Front Playback Volume", 1072 "Front", "Surround", "Center", "LFE", "Side",
1065 "Surround Playback Volume", 1073 "Headphone", "Speaker", "IEC958",
1066 "Center Playback Volume",
1067 "LFE Playback Volume",
1068 "Side Playback Volume",
1069 "Headphone Playback Volume",
1070 "Speaker Playback Volume",
1071 NULL 1074 NULL
1072}; 1075};
1073 1076
1074static const char * const slave_sws[] = { 1077static void stac92xx_update_led_status(struct hda_codec *codec, int enabled);
1075 "Front Playback Switch", 1078
1076 "Surround Playback Switch", 1079static void stac92xx_vmaster_hook(void *private_data, int val)
1077 "Center Playback Switch", 1080{
1078 "LFE Playback Switch", 1081 stac92xx_update_led_status(private_data, val);
1079 "Side Playback Switch", 1082}
1080 "Headphone Playback Switch",
1081 "Speaker Playback Switch",
1082 "IEC958 Playback Switch",
1083 NULL
1084};
1085 1083
1086static void stac92xx_free_kctls(struct hda_codec *codec); 1084static void stac92xx_free_kctls(struct hda_codec *codec);
1087 1085
1088static int stac92xx_build_controls(struct hda_codec *codec) 1086static int stac92xx_build_controls(struct hda_codec *codec)
1089{ 1087{
1090 struct sigmatel_spec *spec = codec->spec; 1088 struct sigmatel_spec *spec = codec->spec;
1089 unsigned int vmaster_tlv[4];
1091 int err; 1090 int err;
1092 int i; 1091 int i;
1093 1092
@@ -1144,22 +1143,28 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1144 } 1143 }
1145 1144
1146 /* if we have no master control, let's create it */ 1145 /* if we have no master control, let's create it */
1147 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 1146 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1148 unsigned int vmaster_tlv[4]; 1147 HDA_OUTPUT, vmaster_tlv);
1149 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], 1148 /* correct volume offset */
1150 HDA_OUTPUT, vmaster_tlv); 1149 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
1151 /* correct volume offset */ 1150 /* minimum value is actually mute */
1152 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; 1151 vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
1153 /* minimum value is actually mute */ 1152 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1154 vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; 1153 vmaster_tlv, slave_pfxs,
1155 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1154 "Playback Volume");
1156 vmaster_tlv, slave_vols); 1155 if (err < 0)
1157 if (err < 0) 1156 return err;
1158 return err; 1157
1159 } 1158 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
1160 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 1159 NULL, slave_pfxs,
1161 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 1160 "Playback Switch", true,
1162 NULL, slave_sws); 1161 &spec->vmaster_mute.sw_kctl);
1162 if (err < 0)
1163 return err;
1164
1165 if (spec->gpio_led) {
1166 spec->vmaster_mute.hook = stac92xx_vmaster_hook;
1167 err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
1163 if (err < 0) 1168 if (err < 0)
1164 return err; 1169 return err;
1165 } 1170 }
@@ -1636,6 +1641,12 @@ static const unsigned int hp_dv7_4000_pin_configs[10] = {
1636 0x40f000f0, 0x40f000f0, 1641 0x40f000f0, 0x40f000f0,
1637}; 1642};
1638 1643
1644static const unsigned int hp_zephyr_pin_configs[10] = {
1645 0x01813050, 0x0421201f, 0x04a1205e, 0x96130310,
1646 0x96130310, 0x0101401f, 0x1111611f, 0xd5a30130,
1647 0, 0,
1648};
1649
1639static const unsigned int hp_cNB11_intquad_pin_configs[10] = { 1650static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
1640 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110, 1651 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
1641 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130, 1652 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
@@ -1649,6 +1660,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1649 [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, 1660 [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs,
1650 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, 1661 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
1651 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, 1662 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
1663 [STAC_HP_ZEPHYR] = hp_zephyr_pin_configs,
1652}; 1664};
1653 1665
1654static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { 1666static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
@@ -1659,6 +1671,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1659 [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", 1671 [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500",
1660 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", 1672 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
1661 [STAC_HP_DV7_4000] = "hp-dv7-4000", 1673 [STAC_HP_DV7_4000] = "hp-dv7-4000",
1674 [STAC_HP_ZEPHYR] = "hp-zephyr",
1662}; 1675};
1663 1676
1664static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { 1677static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -1711,6 +1724,14 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1711 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 1724 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1712 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593, 1725 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
1713 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 1726 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1727 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
1728 "HP", STAC_HP_ZEPHYR),
1729 {} /* terminator */
1730};
1731
1732static const struct snd_pci_quirk stac92hd83xxx_codec_id_cfg_tbl[] = {
1733 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
1734 "HP", STAC_HP_ZEPHYR),
1714 {} /* terminator */ 1735 {} /* terminator */
1715}; 1736};
1716 1737
@@ -4410,8 +4431,7 @@ static int stac92xx_init(struct hda_codec *codec)
4410 snd_hda_jack_report_sync(codec); 4431 snd_hda_jack_report_sync(codec);
4411 4432
4412 /* sync mute LED */ 4433 /* sync mute LED */
4413 if (spec->gpio_led) 4434 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
4414 hda_call_check_power_status(codec, 0x01);
4415 if (spec->dac_list) 4435 if (spec->dac_list)
4416 stac92xx_power_down(codec); 4436 stac92xx_power_down(codec);
4417 return 0; 4437 return 0;
@@ -4629,7 +4649,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec)
4629 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; 4649 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
4630 if (no_hp_sensing(spec, i)) 4650 if (no_hp_sensing(spec, i))
4631 continue; 4651 continue;
4632 if (presence) 4652 if (1 /*presence*/)
4633 stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); 4653 stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
4634#if 0 /* FIXME */ 4654#if 0 /* FIXME */
4635/* Resetting the pinctl like below may lead to (a sort of) regressions 4655/* Resetting the pinctl like below may lead to (a sort of) regressions
@@ -4989,7 +5009,6 @@ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
4989 return 0; 5009 return 0;
4990} 5010}
4991 5011
4992#ifdef CONFIG_SND_HDA_POWER_SAVE
4993static int stac92xx_pre_resume(struct hda_codec *codec) 5012static int stac92xx_pre_resume(struct hda_codec *codec)
4994{ 5013{
4995 struct sigmatel_spec *spec = codec->spec; 5014 struct sigmatel_spec *spec = codec->spec;
@@ -5024,83 +5043,41 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
5024 afg_power_state); 5043 afg_power_state);
5025 snd_hda_codec_set_power_to_all(codec, fg, power_state, true); 5044 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
5026} 5045}
5046#else
5047#define stac92xx_suspend NULL
5048#define stac92xx_resume NULL
5049#define stac92xx_pre_resume NULL
5050#define stac92xx_set_power_state NULL
5051#endif /* CONFIG_PM */
5027 5052
5028/* 5053/* update mute-LED accoring to the master switch */
5029 * For this feature CONFIG_SND_HDA_POWER_SAVE is needed 5054static void stac92xx_update_led_status(struct hda_codec *codec, int enabled)
5030 * as mute LED state is updated in check_power_status hook
5031 */
5032static int stac92xx_update_led_status(struct hda_codec *codec)
5033{ 5055{
5034 struct sigmatel_spec *spec = codec->spec; 5056 struct sigmatel_spec *spec = codec->spec;
5035 int i, num_ext_dacs, muted = 1; 5057 int muted = !enabled;
5036 unsigned int muted_lvl, notmtd_lvl;
5037 hda_nid_t nid;
5038 5058
5039 if (!spec->gpio_led) 5059 if (!spec->gpio_led)
5040 return 0; 5060 return;
5061
5062 /* LED state is inverted on these systems */
5063 if (spec->gpio_led_polarity)
5064 muted = !muted;
5041 5065
5042 for (i = 0; i < spec->multiout.num_dacs; i++) {
5043 nid = spec->multiout.dac_nids[i];
5044 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
5045 HDA_AMP_MUTE)) {
5046 muted = 0; /* something heard */
5047 break;
5048 }
5049 }
5050 if (muted && spec->multiout.hp_nid)
5051 if (!(snd_hda_codec_amp_read(codec,
5052 spec->multiout.hp_nid, 0, HDA_OUTPUT, 0) &
5053 HDA_AMP_MUTE)) {
5054 muted = 0; /* HP is not muted */
5055 }
5056 num_ext_dacs = ARRAY_SIZE(spec->multiout.extra_out_nid);
5057 for (i = 0; muted && i < num_ext_dacs; i++) {
5058 nid = spec->multiout.extra_out_nid[i];
5059 if (nid == 0)
5060 break;
5061 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
5062 HDA_AMP_MUTE)) {
5063 muted = 0; /* extra output is not muted */
5064 }
5065 }
5066 /*polarity defines *not* muted state level*/ 5066 /*polarity defines *not* muted state level*/
5067 if (!spec->vref_mute_led_nid) { 5067 if (!spec->vref_mute_led_nid) {
5068 if (muted) 5068 if (muted)
5069 spec->gpio_data &= ~spec->gpio_led; /* orange */ 5069 spec->gpio_data &= ~spec->gpio_led; /* orange */
5070 else 5070 else
5071 spec->gpio_data |= spec->gpio_led; /* white */ 5071 spec->gpio_data |= spec->gpio_led; /* white */
5072
5073 if (!spec->gpio_led_polarity) {
5074 /* LED state is inverted on these systems */
5075 spec->gpio_data ^= spec->gpio_led;
5076 }
5077 stac_gpio_set(codec, spec->gpio_mask, 5072 stac_gpio_set(codec, spec->gpio_mask,
5078 spec->gpio_dir, spec->gpio_data); 5073 spec->gpio_dir, spec->gpio_data);
5079 } else { 5074 } else {
5080 notmtd_lvl = spec->gpio_led_polarity ? 5075 spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
5081 AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_GRD;
5082 muted_lvl = spec->gpio_led_polarity ?
5083 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
5084 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5085 stac_vrefout_set(codec, spec->vref_mute_led_nid, 5076 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5086 spec->vref_led); 5077 spec->vref_led);
5087 } 5078 }
5088 return 0;
5089} 5079}
5090 5080
5091/*
5092 * use power check for controlling mute led of HP notebooks
5093 */
5094static int stac92xx_check_power_status(struct hda_codec *codec,
5095 hda_nid_t nid)
5096{
5097 stac92xx_update_led_status(codec);
5098
5099 return 0;
5100}
5101#endif /* CONFIG_SND_HDA_POWER_SAVE */
5102#endif /* CONFIG_PM */
5103
5104static const struct hda_codec_ops stac92xx_patch_ops = { 5081static const struct hda_codec_ops stac92xx_patch_ops = {
5105 .build_controls = stac92xx_build_controls, 5082 .build_controls = stac92xx_build_controls,
5106 .build_pcms = stac92xx_build_pcms, 5083 .build_pcms = stac92xx_build_pcms,
@@ -5580,6 +5557,12 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5580 STAC_92HD83XXX_MODELS, 5557 STAC_92HD83XXX_MODELS,
5581 stac92hd83xxx_models, 5558 stac92hd83xxx_models,
5582 stac92hd83xxx_cfg_tbl); 5559 stac92hd83xxx_cfg_tbl);
5560 /* check codec subsystem id if not found */
5561 if (spec->board_config < 0)
5562 spec->board_config =
5563 snd_hda_check_board_codec_sid_config(codec,
5564 STAC_92HD83XXX_MODELS, stac92hd83xxx_models,
5565 stac92hd83xxx_codec_id_cfg_tbl);
5583again: 5566again:
5584 if (spec->board_config < 0) 5567 if (spec->board_config < 0)
5585 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5568 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
@@ -5590,12 +5573,17 @@ again:
5590 5573
5591 codec->patch_ops = stac92xx_patch_ops; 5574 codec->patch_ops = stac92xx_patch_ops;
5592 5575
5576 switch (spec->board_config) {
5577 case STAC_HP_ZEPHYR:
5578 spec->init = stac92hd83xxx_hp_zephyr_init;
5579 break;
5580 }
5581
5593 if (find_mute_led_cfg(codec, -1/*no default cfg*/)) 5582 if (find_mute_led_cfg(codec, -1/*no default cfg*/))
5594 snd_printd("mute LED gpio %d polarity %d\n", 5583 snd_printd("mute LED gpio %d polarity %d\n",
5595 spec->gpio_led, 5584 spec->gpio_led,
5596 spec->gpio_led_polarity); 5585 spec->gpio_led_polarity);
5597 5586
5598#ifdef CONFIG_SND_HDA_POWER_SAVE
5599 if (spec->gpio_led) { 5587 if (spec->gpio_led) {
5600 if (!spec->vref_mute_led_nid) { 5588 if (!spec->vref_mute_led_nid) {
5601 spec->gpio_mask |= spec->gpio_led; 5589 spec->gpio_mask |= spec->gpio_led;
@@ -5605,11 +5593,10 @@ again:
5605 codec->patch_ops.set_power_state = 5593 codec->patch_ops.set_power_state =
5606 stac92xx_set_power_state; 5594 stac92xx_set_power_state;
5607 } 5595 }
5596#ifdef CONFIG_PM
5608 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5597 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5609 codec->patch_ops.check_power_status = 5598#endif
5610 stac92xx_check_power_status;
5611 } 5599 }
5612#endif
5613 5600
5614 err = stac92xx_parse_auto_config(codec); 5601 err = stac92xx_parse_auto_config(codec);
5615 if (!err) { 5602 if (!err) {
@@ -5906,7 +5893,6 @@ again:
5906 spec->gpio_led, 5893 spec->gpio_led,
5907 spec->gpio_led_polarity); 5894 spec->gpio_led_polarity);
5908 5895
5909#ifdef CONFIG_SND_HDA_POWER_SAVE
5910 if (spec->gpio_led) { 5896 if (spec->gpio_led) {
5911 if (!spec->vref_mute_led_nid) { 5897 if (!spec->vref_mute_led_nid) {
5912 spec->gpio_mask |= spec->gpio_led; 5898 spec->gpio_mask |= spec->gpio_led;
@@ -5916,11 +5902,10 @@ again:
5916 codec->patch_ops.set_power_state = 5902 codec->patch_ops.set_power_state =
5917 stac92xx_set_power_state; 5903 stac92xx_set_power_state;
5918 } 5904 }
5905#ifdef CONFIG_PM
5919 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5906 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5920 codec->patch_ops.check_power_status = 5907#endif
5921 stac92xx_check_power_status;
5922 } 5908 }
5923#endif
5924 5909
5925 spec->multiout.dac_nids = spec->dac_nids; 5910 spec->multiout.dac_nids = spec->dac_nids;
5926 5911
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 284e311040fe..06214fdc9486 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -550,7 +550,10 @@ static void via_auto_init_output(struct hda_codec *codec,
550 pin = path->path[path->depth - 1]; 550 pin = path->path[path->depth - 1];
551 551
552 init_output_pin(codec, pin, pin_type); 552 init_output_pin(codec, pin, pin_type);
553 caps = query_amp_caps(codec, pin, HDA_OUTPUT); 553 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
554 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
555 else
556 caps = 0;
554 if (caps & AC_AMPCAP_MUTE) { 557 if (caps & AC_AMPCAP_MUTE) {
555 unsigned int val; 558 unsigned int val;
556 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; 559 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
@@ -645,6 +648,10 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
645 648
646 /* init ADCs */ 649 /* init ADCs */
647 for (i = 0; i < spec->num_adc_nids; i++) { 650 for (i = 0; i < spec->num_adc_nids; i++) {
651 hda_nid_t nid = spec->adc_nids[i];
652 if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP) ||
653 !(query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE))
654 continue;
648 snd_hda_codec_write(codec, spec->adc_nids[i], 0, 655 snd_hda_codec_write(codec, spec->adc_nids[i], 0,
649 AC_VERB_SET_AMP_GAIN_MUTE, 656 AC_VERB_SET_AMP_GAIN_MUTE,
650 AMP_IN_UNMUTE(0)); 657 AMP_IN_UNMUTE(0));
@@ -666,6 +673,9 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
666 /* init input-src */ 673 /* init input-src */
667 for (i = 0; i < spec->num_adc_nids; i++) { 674 for (i = 0; i < spec->num_adc_nids; i++) {
668 int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx; 675 int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx;
676 /* secondary ADCs must have the unique MUX */
677 if (i > 0 && !spec->mux_nids[i])
678 break;
669 if (spec->mux_nids[adc_idx]) { 679 if (spec->mux_nids[adc_idx]) {
670 int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx; 680 int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx;
671 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, 681 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
@@ -1442,25 +1452,9 @@ static const struct hda_pcm_stream via_pcm_digital_capture = {
1442/* 1452/*
1443 * slave controls for virtual master 1453 * slave controls for virtual master
1444 */ 1454 */
1445static const char * const via_slave_vols[] = { 1455static const char * const via_slave_pfxs[] = {
1446 "Front Playback Volume", 1456 "Front", "Surround", "Center", "LFE", "Side",
1447 "Surround Playback Volume", 1457 "Headphone", "Speaker",
1448 "Center Playback Volume",
1449 "LFE Playback Volume",
1450 "Side Playback Volume",
1451 "Headphone Playback Volume",
1452 "Speaker Playback Volume",
1453 NULL,
1454};
1455
1456static const char * const via_slave_sws[] = {
1457 "Front Playback Switch",
1458 "Surround Playback Switch",
1459 "Center Playback Switch",
1460 "LFE Playback Switch",
1461 "Side Playback Switch",
1462 "Headphone Playback Switch",
1463 "Speaker Playback Switch",
1464 NULL, 1458 NULL,
1465}; 1459};
1466 1460
@@ -1505,13 +1499,15 @@ static int via_build_controls(struct hda_codec *codec)
1505 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], 1499 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1506 HDA_OUTPUT, vmaster_tlv); 1500 HDA_OUTPUT, vmaster_tlv);
1507 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1501 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1508 vmaster_tlv, via_slave_vols); 1502 vmaster_tlv, via_slave_pfxs,
1503 "Playback Volume");
1509 if (err < 0) 1504 if (err < 0)
1510 return err; 1505 return err;
1511 } 1506 }
1512 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 1507 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1513 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 1508 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1514 NULL, via_slave_sws); 1509 NULL, via_slave_pfxs,
1510 "Playback Switch");
1515 if (err < 0) 1511 if (err < 0)
1516 return err; 1512 return err;
1517 } 1513 }
@@ -1519,6 +1515,8 @@ static int via_build_controls(struct hda_codec *codec)
1519 /* assign Capture Source enums to NID */ 1515 /* assign Capture Source enums to NID */
1520 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 1516 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1521 for (i = 0; kctl && i < kctl->count; i++) { 1517 for (i = 0; kctl && i < kctl->count; i++) {
1518 if (!spec->mux_nids[i])
1519 continue;
1522 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]); 1520 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1523 if (err < 0) 1521 if (err < 0)
1524 return err; 1522 return err;
@@ -2485,6 +2483,8 @@ static int create_mic_boost_ctls(struct hda_codec *codec)
2485{ 2483{
2486 struct via_spec *spec = codec->spec; 2484 struct via_spec *spec = codec->spec;
2487 const struct auto_pin_cfg *cfg = &spec->autocfg; 2485 const struct auto_pin_cfg *cfg = &spec->autocfg;
2486 const char *prev_label = NULL;
2487 int type_idx = 0;
2488 int i, err; 2488 int i, err;
2489 2489
2490 for (i = 0; i < cfg->num_inputs; i++) { 2490 for (i = 0; i < cfg->num_inputs; i++) {
@@ -2499,8 +2499,13 @@ static int create_mic_boost_ctls(struct hda_codec *codec)
2499 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS)) 2499 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS))
2500 continue; 2500 continue;
2501 label = hda_get_autocfg_input_label(codec, cfg, i); 2501 label = hda_get_autocfg_input_label(codec, cfg, i);
2502 if (prev_label && !strcmp(label, prev_label))
2503 type_idx++;
2504 else
2505 type_idx = 0;
2506 prev_label = label;
2502 snprintf(name, sizeof(name), "%s Boost Volume", label); 2507 snprintf(name, sizeof(name), "%s Boost Volume", label);
2503 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2508 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
2504 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT)); 2509 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT));
2505 if (err < 0) 2510 if (err < 0)
2506 return err; 2511 return err;
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 92362973764d..812d10e43ae0 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -1013,6 +1013,25 @@ static int set_rate_constraints(struct snd_ice1712 *ice,
1013 ice->hw_rates); 1013 ice->hw_rates);
1014} 1014}
1015 1015
1016/* if the card has the internal rate locked (is_pro_locked), limit runtime
1017 hw rates to the current internal rate only.
1018*/
1019static void constrain_rate_if_locked(struct snd_pcm_substream *substream)
1020{
1021 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
1022 struct snd_pcm_runtime *runtime = substream->runtime;
1023 unsigned int rate;
1024 if (is_pro_rate_locked(ice)) {
1025 rate = ice->get_rate(ice);
1026 if (rate >= runtime->hw.rate_min
1027 && rate <= runtime->hw.rate_max) {
1028 runtime->hw.rate_min = rate;
1029 runtime->hw.rate_max = rate;
1030 }
1031 }
1032}
1033
1034
1016/* multi-channel playback needs alignment 8x32bit regardless of the channels 1035/* multi-channel playback needs alignment 8x32bit regardless of the channels
1017 * actually used 1036 * actually used
1018 */ 1037 */
@@ -1046,6 +1065,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
1046 VT1724_BUFFER_ALIGN); 1065 VT1724_BUFFER_ALIGN);
1047 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1066 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1048 VT1724_BUFFER_ALIGN); 1067 VT1724_BUFFER_ALIGN);
1068 constrain_rate_if_locked(substream);
1049 if (ice->pro_open) 1069 if (ice->pro_open)
1050 ice->pro_open(ice, substream); 1070 ice->pro_open(ice, substream);
1051 return 0; 1071 return 0;
@@ -1066,6 +1086,7 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)
1066 VT1724_BUFFER_ALIGN); 1086 VT1724_BUFFER_ALIGN);
1067 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1087 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1068 VT1724_BUFFER_ALIGN); 1088 VT1724_BUFFER_ALIGN);
1089 constrain_rate_if_locked(substream);
1069 if (ice->pro_open) 1090 if (ice->pro_open)
1070 ice->pro_open(ice, substream); 1091 ice->pro_open(ice, substream);
1071 return 0; 1092 return 0;
@@ -1215,6 +1236,7 @@ static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream)
1215 VT1724_BUFFER_ALIGN); 1236 VT1724_BUFFER_ALIGN);
1216 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1237 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1217 VT1724_BUFFER_ALIGN); 1238 VT1724_BUFFER_ALIGN);
1239 constrain_rate_if_locked(substream);
1218 if (ice->spdif.ops.open) 1240 if (ice->spdif.ops.open)
1219 ice->spdif.ops.open(ice, substream); 1241 ice->spdif.ops.open(ice, substream);
1220 return 0; 1242 return 0;
@@ -1251,6 +1273,7 @@ static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream)
1251 VT1724_BUFFER_ALIGN); 1273 VT1724_BUFFER_ALIGN);
1252 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1274 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1253 VT1724_BUFFER_ALIGN); 1275 VT1724_BUFFER_ALIGN);
1276 constrain_rate_if_locked(substream);
1254 if (ice->spdif.ops.open) 1277 if (ice->spdif.ops.open)
1255 ice->spdif.ops.open(ice, substream); 1278 ice->spdif.ops.open(ice, substream);
1256 return 0; 1279 return 0;
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 9f3b01bb72c8..e0a4263baa20 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2102,6 +2102,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
2102 }, 2102 },
2103 { 2103 {
2104 .subvendor = 0x161f, 2104 .subvendor = 0x161f,
2105 .subdevice = 0x202f,
2106 .name = "Gateway M520",
2107 .type = AC97_TUNE_INV_EAPD
2108 },
2109 {
2110 .subvendor = 0x161f,
2105 .subdevice = 0x203a, 2111 .subdevice = 0x203a,
2106 .name = "Gateway 4525GZ", /* AD1981B */ 2112 .name = "Gateway 4525GZ", /* AD1981B */
2107 .type = AC97_TUNE_INV_EAPD 2113 .type = AC97_TUNE_INV_EAPD
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 26c7e8bcb229..c0dbb52d45be 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -618,9 +618,12 @@ static int ac97_volume_get(struct snd_kcontrol *ctl,
618 mutex_lock(&chip->mutex); 618 mutex_lock(&chip->mutex);
619 reg = oxygen_read_ac97(chip, codec, index); 619 reg = oxygen_read_ac97(chip, codec, index);
620 mutex_unlock(&chip->mutex); 620 mutex_unlock(&chip->mutex);
621 value->value.integer.value[0] = 31 - (reg & 0x1f); 621 if (!stereo) {
622 if (stereo) 622 value->value.integer.value[0] = 31 - (reg & 0x1f);
623 value->value.integer.value[1] = 31 - ((reg >> 8) & 0x1f); 623 } else {
624 value->value.integer.value[0] = 31 - ((reg >> 8) & 0x1f);
625 value->value.integer.value[1] = 31 - (reg & 0x1f);
626 }
624 return 0; 627 return 0;
625} 628}
626 629
@@ -636,14 +639,14 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
636 639
637 mutex_lock(&chip->mutex); 640 mutex_lock(&chip->mutex);
638 oldreg = oxygen_read_ac97(chip, codec, index); 641 oldreg = oxygen_read_ac97(chip, codec, index);
639 newreg = oldreg; 642 if (!stereo) {
640 newreg = (newreg & ~0x1f) | 643 newreg = oldreg & ~0x1f;
641 (31 - (value->value.integer.value[0] & 0x1f)); 644 newreg |= 31 - (value->value.integer.value[0] & 0x1f);
642 if (stereo) 645 } else {
643 newreg = (newreg & ~0x1f00) | 646 newreg = oldreg & ~0x1f1f;
644 ((31 - (value->value.integer.value[1] & 0x1f)) << 8); 647 newreg |= (31 - (value->value.integer.value[0] & 0x1f)) << 8;
645 else 648 newreg |= 31 - (value->value.integer.value[1] & 0x1f);
646 newreg = (newreg & ~0x1f00) | ((newreg & 0x1f) << 8); 649 }
647 change = newreg != oldreg; 650 change = newreg != oldreg;
648 if (change) 651 if (change)
649 oxygen_write_ac97(chip, codec, index, newreg); 652 oxygen_write_ac97(chip, codec, index, newreg);
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index cc9f6c83d661..bc030a2088da 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -6333,6 +6333,7 @@ static int __devinit snd_hdspm_create_hwdep(struct snd_card *card,
6333 6333
6334 hw->ops.open = snd_hdspm_hwdep_dummy_op; 6334 hw->ops.open = snd_hdspm_hwdep_dummy_op;
6335 hw->ops.ioctl = snd_hdspm_hwdep_ioctl; 6335 hw->ops.ioctl = snd_hdspm_hwdep_ioctl;
6336 hw->ops.ioctl_compat = snd_hdspm_hwdep_ioctl;
6336 hw->ops.release = snd_hdspm_hwdep_dummy_op; 6337 hw->ops.release = snd_hdspm_hwdep_dummy_op;
6337 6338
6338 return 0; 6339 return 0;
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 12a9a2b03387..a8159b81e9c4 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2317,6 +2317,10 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)
2317 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++) 2317 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)
2318 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]); 2318 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);
2319 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE); 2319 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
2320 pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY,
2321 &chip->saved_dsxg_legacy);
2322 pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY,
2323 &chip->saved_dsxg_elegacy);
2320 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); 2324 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
2321 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); 2325 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
2322 snd_ymfpci_disable_dsp(chip); 2326 snd_ymfpci_disable_dsp(chip);
@@ -2351,6 +2355,11 @@ int snd_ymfpci_resume(struct pci_dev *pci)
2351 2355
2352 snd_ac97_resume(chip->ac97); 2356 snd_ac97_resume(chip->ac97);
2353 2357
2358 pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY,
2359 chip->saved_dsxg_legacy);
2360 pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY,
2361 chip->saved_dsxg_elegacy);
2362
2354 /* start hw again */ 2363 /* start hw again */
2355 if (chip->start_count > 0) { 2364 if (chip->start_count > 0) {
2356 spin_lock_irq(&chip->reg_lock); 2365 spin_lock_irq(&chip->reg_lock);