diff options
author | Paul Mackerras <paulus@samba.org> | 2005-11-07 19:14:20 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-11-07 19:14:20 -0500 |
commit | 24bfb00123e82a2e70bd115277d922438813515b (patch) | |
tree | 27328b8a5718e16d64e2d101f4b7ddcad5930aed /sound/pci/hda | |
parent | c6135234550ed89a6fd0e8cb229633967e41d649 (diff) | |
parent | 3f00d3e8fb963968a922d821a9a53b503b687e81 (diff) |
Merge ../linux-2.6
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 52 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 72 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 22 | ||||
-rw-r--r-- | sound/pci/hda/hda_proc.c | 5 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 133 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 274 | ||||
-rw-r--r-- | sound/pci/hda/patch_si3054.c | 2 |
8 files changed, 401 insertions, 161 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 3815403ed095..0dbeeaf6113a 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -518,6 +518,13 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | |||
518 | return -ENODEV; | 518 | return -ENODEV; |
519 | } | 519 | } |
520 | 520 | ||
521 | if (! codec->subsystem_id) { | ||
522 | hda_nid_t nid = codec->afg ? codec->afg : codec->mfg; | ||
523 | codec->subsystem_id = snd_hda_codec_read(codec, nid, 0, | ||
524 | AC_VERB_GET_SUBSYSTEM_ID, | ||
525 | 0); | ||
526 | } | ||
527 | |||
521 | codec->preset = find_codec_preset(codec); | 528 | codec->preset = find_codec_preset(codec); |
522 | if (! *bus->card->mixername) | 529 | if (! *bus->card->mixername) |
523 | snd_hda_get_codec_name(codec, bus->card->mixername, | 530 | snd_hda_get_codec_name(codec, bus->card->mixername, |
@@ -814,6 +821,51 @@ int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t | |||
814 | } | 821 | } |
815 | 822 | ||
816 | /* | 823 | /* |
824 | * bound volume controls | ||
825 | * | ||
826 | * bind multiple volumes (# indices, from 0) | ||
827 | */ | ||
828 | |||
829 | #define AMP_VAL_IDX_SHIFT 19 | ||
830 | #define AMP_VAL_IDX_MASK (0x0f<<19) | ||
831 | |||
832 | int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
833 | { | ||
834 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
835 | unsigned long pval; | ||
836 | int err; | ||
837 | |||
838 | down(&codec->spdif_mutex); /* reuse spdif_mutex */ | ||
839 | pval = kcontrol->private_value; | ||
840 | kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ | ||
841 | err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | ||
842 | kcontrol->private_value = pval; | ||
843 | up(&codec->spdif_mutex); | ||
844 | return err; | ||
845 | } | ||
846 | |||
847 | int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
848 | { | ||
849 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
850 | unsigned long pval; | ||
851 | int i, indices, err = 0, change = 0; | ||
852 | |||
853 | down(&codec->spdif_mutex); /* reuse spdif_mutex */ | ||
854 | pval = kcontrol->private_value; | ||
855 | indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; | ||
856 | for (i = 0; i < indices; i++) { | ||
857 | kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT); | ||
858 | err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
859 | if (err < 0) | ||
860 | break; | ||
861 | change |= err; | ||
862 | } | ||
863 | kcontrol->private_value = pval; | ||
864 | up(&codec->spdif_mutex); | ||
865 | return err < 0 ? err : change; | ||
866 | } | ||
867 | |||
868 | /* | ||
817 | * SPDIF out controls | 869 | * SPDIF out controls |
818 | */ | 870 | */ |
819 | 871 | ||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index bb53bcf76742..1179d6cfa82a 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -79,6 +79,8 @@ enum { | |||
79 | #define AC_VERB_GET_GPIO_MASK 0x0f16 | 79 | #define AC_VERB_GET_GPIO_MASK 0x0f16 |
80 | #define AC_VERB_GET_GPIO_DIRECTION 0x0f17 | 80 | #define AC_VERB_GET_GPIO_DIRECTION 0x0f17 |
81 | #define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c | 81 | #define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c |
82 | /* f20: AFG/MFG */ | ||
83 | #define AC_VERB_GET_SUBSYSTEM_ID 0x0f20 | ||
82 | 84 | ||
83 | /* | 85 | /* |
84 | * SET verbs | 86 | * SET verbs |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 6fe696e53ea6..9d1412a9f2f8 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -47,23 +47,24 @@ | |||
47 | #include "hda_codec.h" | 47 | #include "hda_codec.h" |
48 | 48 | ||
49 | 49 | ||
50 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | 50 | static int index = SNDRV_DEFAULT_IDX1; |
51 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | 51 | static char *id = SNDRV_DEFAULT_STR1; |
52 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | 52 | static char *model; |
53 | static char *model[SNDRV_CARDS]; | 53 | static int position_fix; |
54 | static int position_fix[SNDRV_CARDS]; | ||
55 | 54 | ||
56 | module_param_array(index, int, NULL, 0444); | 55 | module_param(index, int, 0444); |
57 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); | 56 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); |
58 | module_param_array(id, charp, NULL, 0444); | 57 | module_param(id, charp, 0444); |
59 | MODULE_PARM_DESC(id, "ID string for Intel HD audio interface."); | 58 | MODULE_PARM_DESC(id, "ID string for Intel HD audio interface."); |
60 | module_param_array(enable, bool, NULL, 0444); | 59 | module_param(model, charp, 0444); |
61 | MODULE_PARM_DESC(enable, "Enable Intel HD audio interface."); | ||
62 | module_param_array(model, charp, NULL, 0444); | ||
63 | MODULE_PARM_DESC(model, "Use the given board model."); | 60 | MODULE_PARM_DESC(model, "Use the given board model."); |
64 | module_param_array(position_fix, int, NULL, 0444); | 61 | module_param(position_fix, int, 0444); |
65 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); | 62 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); |
66 | 63 | ||
64 | /* just for backward compatibility */ | ||
65 | static int enable; | ||
66 | module_param(enable, bool, 0444); | ||
67 | |||
67 | MODULE_LICENSE("GPL"); | 68 | MODULE_LICENSE("GPL"); |
68 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | 69 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," |
69 | "{Intel, ICH6M}," | 70 | "{Intel, ICH6M}," |
@@ -223,6 +224,9 @@ enum { | |||
223 | #define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42 | 224 | #define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42 |
224 | #define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02 | 225 | #define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02 |
225 | 226 | ||
227 | /* Defines for Nvidia HDA support */ | ||
228 | #define NVIDIA_HDA_TRANSREG_ADDR 0x4e | ||
229 | #define NVIDIA_HDA_ENABLE_COHBITS 0x0f | ||
226 | 230 | ||
227 | /* | 231 | /* |
228 | * Use CORB/RIRB for communication from/to codecs. | 232 | * Use CORB/RIRB for communication from/to codecs. |
@@ -328,6 +332,7 @@ enum { | |||
328 | AZX_DRIVER_VIA, | 332 | AZX_DRIVER_VIA, |
329 | AZX_DRIVER_SIS, | 333 | AZX_DRIVER_SIS, |
330 | AZX_DRIVER_ULI, | 334 | AZX_DRIVER_ULI, |
335 | AZX_DRIVER_NVIDIA, | ||
331 | }; | 336 | }; |
332 | 337 | ||
333 | static char *driver_short_names[] __devinitdata = { | 338 | static char *driver_short_names[] __devinitdata = { |
@@ -335,7 +340,8 @@ static char *driver_short_names[] __devinitdata = { | |||
335 | [AZX_DRIVER_ATI] = "HDA ATI SB", | 340 | [AZX_DRIVER_ATI] = "HDA ATI SB", |
336 | [AZX_DRIVER_VIA] = "HDA VIA VT82xx", | 341 | [AZX_DRIVER_VIA] = "HDA VIA VT82xx", |
337 | [AZX_DRIVER_SIS] = "HDA SIS966", | 342 | [AZX_DRIVER_SIS] = "HDA SIS966", |
338 | [AZX_DRIVER_ULI] = "HDA ULI M5461" | 343 | [AZX_DRIVER_ULI] = "HDA ULI M5461", |
344 | [AZX_DRIVER_NVIDIA] = "HDA NVidia", | ||
339 | }; | 345 | }; |
340 | 346 | ||
341 | /* | 347 | /* |
@@ -710,14 +716,14 @@ static void azx_stream_stop(azx_t *chip, azx_dev_t *azx_dev) | |||
710 | */ | 716 | */ |
711 | static void azx_init_chip(azx_t *chip) | 717 | static void azx_init_chip(azx_t *chip) |
712 | { | 718 | { |
713 | unsigned char tcsel_reg, ati_misc_cntl2; | 719 | unsigned char reg; |
714 | 720 | ||
715 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) | 721 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) |
716 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS | 722 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS |
717 | * Ensuring these bits are 0 clears playback static on some HD Audio codecs | 723 | * Ensuring these bits are 0 clears playback static on some HD Audio codecs |
718 | */ | 724 | */ |
719 | pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &tcsel_reg); | 725 | pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, ®); |
720 | pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, tcsel_reg & 0xf8); | 726 | pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8); |
721 | 727 | ||
722 | /* reset controller */ | 728 | /* reset controller */ |
723 | azx_reset(chip); | 729 | azx_reset(chip); |
@@ -733,13 +739,21 @@ static void azx_init_chip(azx_t *chip) | |||
733 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); | 739 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); |
734 | azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); | 740 | azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); |
735 | 741 | ||
736 | /* For ATI SB450 azalia HD audio, we need to enable snoop */ | 742 | switch (chip->driver_type) { |
737 | if (chip->driver_type == AZX_DRIVER_ATI) { | 743 | case AZX_DRIVER_ATI: |
744 | /* For ATI SB450 azalia HD audio, we need to enable snoop */ | ||
738 | pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, | 745 | pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, |
739 | &ati_misc_cntl2); | 746 | ®); |
740 | pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, | 747 | pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, |
741 | (ati_misc_cntl2 & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP); | 748 | (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP); |
742 | } | 749 | break; |
750 | case AZX_DRIVER_NVIDIA: | ||
751 | /* For NVIDIA HDA, enable snoop */ | ||
752 | pci_read_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, ®); | ||
753 | pci_write_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, | ||
754 | (reg & 0xf0) | NVIDIA_HDA_ENABLE_COHBITS); | ||
755 | break; | ||
756 | } | ||
743 | } | 757 | } |
744 | 758 | ||
745 | 759 | ||
@@ -1264,6 +1278,7 @@ static int __devinit azx_pcm_create(azx_t *chip) | |||
1264 | err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); | 1278 | err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); |
1265 | if (err < 0) | 1279 | if (err < 0) |
1266 | return err; | 1280 | return err; |
1281 | chip->pcm[pcm_dev]->dev_class = SNDRV_PCM_CLASS_MODEM; | ||
1267 | pcm_dev++; | 1282 | pcm_dev++; |
1268 | } | 1283 | } |
1269 | } | 1284 | } |
@@ -1530,32 +1545,24 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, | |||
1530 | 1545 | ||
1531 | static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | 1546 | static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) |
1532 | { | 1547 | { |
1533 | static int dev; | ||
1534 | snd_card_t *card; | 1548 | snd_card_t *card; |
1535 | azx_t *chip; | 1549 | azx_t *chip; |
1536 | int err = 0; | 1550 | int err = 0; |
1537 | 1551 | ||
1538 | if (dev >= SNDRV_CARDS) | 1552 | card = snd_card_new(index, id, THIS_MODULE, 0); |
1539 | return -ENODEV; | ||
1540 | if (! enable[dev]) { | ||
1541 | dev++; | ||
1542 | return -ENOENT; | ||
1543 | } | ||
1544 | |||
1545 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | ||
1546 | if (NULL == card) { | 1553 | if (NULL == card) { |
1547 | snd_printk(KERN_ERR SFX "Error creating card!\n"); | 1554 | snd_printk(KERN_ERR SFX "Error creating card!\n"); |
1548 | return -ENOMEM; | 1555 | return -ENOMEM; |
1549 | } | 1556 | } |
1550 | 1557 | ||
1551 | if ((err = azx_create(card, pci, position_fix[dev], pci_id->driver_data, | 1558 | if ((err = azx_create(card, pci, position_fix, pci_id->driver_data, |
1552 | &chip)) < 0) { | 1559 | &chip)) < 0) { |
1553 | snd_card_free(card); | 1560 | snd_card_free(card); |
1554 | return err; | 1561 | return err; |
1555 | } | 1562 | } |
1556 | 1563 | ||
1557 | /* create codec instances */ | 1564 | /* create codec instances */ |
1558 | if ((err = azx_codec_create(chip, model[dev])) < 0) { | 1565 | if ((err = azx_codec_create(chip, model)) < 0) { |
1559 | snd_card_free(card); | 1566 | snd_card_free(card); |
1560 | return err; | 1567 | return err; |
1561 | } | 1568 | } |
@@ -1581,7 +1588,6 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id * | |||
1581 | } | 1588 | } |
1582 | 1589 | ||
1583 | pci_set_drvdata(pci, card); | 1590 | pci_set_drvdata(pci, card); |
1584 | dev++; | ||
1585 | 1591 | ||
1586 | return err; | 1592 | return err; |
1587 | } | 1593 | } |
@@ -1601,6 +1607,8 @@ static struct pci_device_id azx_ids[] = { | |||
1601 | { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ | 1607 | { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ |
1602 | { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ | 1608 | { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ |
1603 | { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ | 1609 | { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ |
1610 | { 0x10de, 0x026c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 026c */ | ||
1611 | { 0x10de, 0x0371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 0371 */ | ||
1604 | { 0, } | 1612 | { 0, } |
1605 | }; | 1613 | }; |
1606 | MODULE_DEVICE_TABLE(pci, azx_ids); | 1614 | MODULE_DEVICE_TABLE(pci, azx_ids); |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 810cfd2d9bba..f51a56f813c8 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -27,28 +27,36 @@ | |||
27 | * for mixer controls | 27 | * for mixer controls |
28 | */ | 28 | */ |
29 | #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) | 29 | #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) |
30 | /* mono volume with index (index=0,1,...) (channel=1,2) */ | ||
30 | #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ | 31 | #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ |
31 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 32 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
32 | .info = snd_hda_mixer_amp_volume_info, \ | 33 | .info = snd_hda_mixer_amp_volume_info, \ |
33 | .get = snd_hda_mixer_amp_volume_get, \ | 34 | .get = snd_hda_mixer_amp_volume_get, \ |
34 | .put = snd_hda_mixer_amp_volume_put, \ | 35 | .put = snd_hda_mixer_amp_volume_put, \ |
35 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } | 36 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } |
37 | /* stereo volume with index */ | ||
36 | #define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \ | 38 | #define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \ |
37 | HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) | 39 | HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) |
40 | /* mono volume */ | ||
38 | #define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \ | 41 | #define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \ |
39 | HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction) | 42 | HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction) |
43 | /* stereo volume */ | ||
40 | #define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \ | 44 | #define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \ |
41 | HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction) | 45 | HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction) |
46 | /* mono mute switch with index (index=0,1,...) (channel=1,2) */ | ||
42 | #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ | 47 | #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ |
43 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 48 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
44 | .info = snd_hda_mixer_amp_switch_info, \ | 49 | .info = snd_hda_mixer_amp_switch_info, \ |
45 | .get = snd_hda_mixer_amp_switch_get, \ | 50 | .get = snd_hda_mixer_amp_switch_get, \ |
46 | .put = snd_hda_mixer_amp_switch_put, \ | 51 | .put = snd_hda_mixer_amp_switch_put, \ |
47 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } | 52 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } |
53 | /* stereo mute switch with index */ | ||
48 | #define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \ | 54 | #define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \ |
49 | HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) | 55 | HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) |
56 | /* mono mute switch */ | ||
50 | #define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \ | 57 | #define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \ |
51 | HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction) | 58 | HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction) |
59 | /* stereo mute switch */ | ||
52 | #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ | 60 | #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ |
53 | HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) | 61 | HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) |
54 | 62 | ||
@@ -59,6 +67,20 @@ int snd_hda_mixer_amp_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t | |||
59 | int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | 67 | int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); |
60 | int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | 68 | int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); |
61 | 69 | ||
70 | /* mono switch binding multiple inputs */ | ||
71 | #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ | ||
72 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
73 | .info = snd_hda_mixer_amp_switch_info, \ | ||
74 | .get = snd_hda_mixer_bind_switch_get, \ | ||
75 | .put = snd_hda_mixer_bind_switch_put, \ | ||
76 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } | ||
77 | |||
78 | /* stereo switch binding multiple inputs */ | ||
79 | #define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) | ||
80 | |||
81 | int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | ||
82 | int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | ||
83 | |||
62 | int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); | 84 | int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); |
63 | int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); | 85 | int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); |
64 | 86 | ||
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 08f6a6efc5e6..39ddf1cd9019 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -281,6 +281,11 @@ static void print_codec_info(snd_info_entry_t *entry, snd_info_buffer_t *buffer) | |||
281 | print_pcm_caps(buffer, codec, nid); | 281 | print_pcm_caps(buffer, codec, nid); |
282 | } | 282 | } |
283 | 283 | ||
284 | if (wid_caps & AC_WCAP_POWER) | ||
285 | snd_iprintf(buffer, " Power: 0x%x\n", | ||
286 | snd_hda_codec_read(codec, nid, 0, | ||
287 | AC_VERB_GET_POWER_STATE, 0)); | ||
288 | |||
284 | if (wid_caps & AC_WCAP_CONN_LIST) { | 289 | if (wid_caps & AC_WCAP_CONN_LIST) { |
285 | int c, curr = -1; | 290 | int c, curr = -1; |
286 | if (conn_len > 1 && wid_type != AC_WID_AUD_MIX) | 291 | if (conn_len > 1 && wid_type != AC_WID_AUD_MIX) |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index da6874d3988c..d7d636decef8 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -28,15 +28,38 @@ | |||
28 | #include "hda_local.h" | 28 | #include "hda_local.h" |
29 | 29 | ||
30 | struct ad198x_spec { | 30 | struct ad198x_spec { |
31 | struct semaphore amp_mutex; /* PCM volume/mute control mutex */ | 31 | snd_kcontrol_new_t *mixers[5]; |
32 | struct hda_multi_out multiout; /* playback */ | 32 | int num_mixers; |
33 | hda_nid_t adc_nid; | 33 | |
34 | const struct hda_verb *init_verbs[3]; /* initialization verbs | ||
35 | * don't forget NULL termination! | ||
36 | */ | ||
37 | unsigned int num_init_verbs; | ||
38 | |||
39 | /* playback */ | ||
40 | struct hda_multi_out multiout; /* playback set-up | ||
41 | * max_channels, dacs must be set | ||
42 | * dig_out_nid and hp_nid are optional | ||
43 | */ | ||
44 | |||
45 | /* capture */ | ||
46 | unsigned int num_adc_nids; | ||
47 | hda_nid_t *adc_nids; | ||
48 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | ||
49 | |||
50 | /* capture source */ | ||
34 | const struct hda_input_mux *input_mux; | 51 | const struct hda_input_mux *input_mux; |
35 | unsigned int cur_mux; /* capture source */ | 52 | unsigned int cur_mux[3]; |
53 | |||
54 | /* channel model */ | ||
55 | const struct alc_channel_mode *channel_mode; | ||
56 | int num_channel_mode; | ||
57 | |||
58 | /* PCM information */ | ||
59 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ | ||
60 | |||
61 | struct semaphore amp_mutex; /* PCM volume/mute control mutex */ | ||
36 | unsigned int spdif_route; | 62 | unsigned int spdif_route; |
37 | snd_kcontrol_new_t *mixers; | ||
38 | const struct hda_verb *init_verbs; | ||
39 | struct hda_pcm pcm_rec[2]; /* PCM information */ | ||
40 | }; | 63 | }; |
41 | 64 | ||
42 | /* | 65 | /* |
@@ -54,8 +77,9 @@ static int ad198x_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u | |||
54 | { | 77 | { |
55 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 78 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
56 | struct ad198x_spec *spec = codec->spec; | 79 | struct ad198x_spec *spec = codec->spec; |
80 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
57 | 81 | ||
58 | ucontrol->value.enumerated.item[0] = spec->cur_mux; | 82 | ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; |
59 | return 0; | 83 | return 0; |
60 | } | 84 | } |
61 | 85 | ||
@@ -63,9 +87,10 @@ static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u | |||
63 | { | 87 | { |
64 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 88 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
65 | struct ad198x_spec *spec = codec->spec; | 89 | struct ad198x_spec *spec = codec->spec; |
90 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
66 | 91 | ||
67 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | 92 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, |
68 | spec->adc_nid, &spec->cur_mux); | 93 | spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]); |
69 | } | 94 | } |
70 | 95 | ||
71 | /* | 96 | /* |
@@ -74,22 +99,34 @@ static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u | |||
74 | static int ad198x_init(struct hda_codec *codec) | 99 | static int ad198x_init(struct hda_codec *codec) |
75 | { | 100 | { |
76 | struct ad198x_spec *spec = codec->spec; | 101 | struct ad198x_spec *spec = codec->spec; |
77 | snd_hda_sequence_write(codec, spec->init_verbs); | 102 | int i; |
103 | |||
104 | for (i = 0; i < spec->num_init_verbs; i++) | ||
105 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | ||
78 | return 0; | 106 | return 0; |
79 | } | 107 | } |
80 | 108 | ||
81 | static int ad198x_build_controls(struct hda_codec *codec) | 109 | static int ad198x_build_controls(struct hda_codec *codec) |
82 | { | 110 | { |
83 | struct ad198x_spec *spec = codec->spec; | 111 | struct ad198x_spec *spec = codec->spec; |
112 | unsigned int i; | ||
84 | int err; | 113 | int err; |
85 | 114 | ||
86 | err = snd_hda_add_new_ctls(codec, spec->mixers); | 115 | for (i = 0; i < spec->num_mixers; i++) { |
87 | if (err < 0) | 116 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
88 | return err; | 117 | if (err < 0) |
89 | if (spec->multiout.dig_out_nid) | 118 | return err; |
119 | } | ||
120 | if (spec->multiout.dig_out_nid) { | ||
90 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); | 121 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); |
91 | if (err < 0) | 122 | if (err < 0) |
92 | return err; | 123 | return err; |
124 | } | ||
125 | if (spec->dig_in_nid) { | ||
126 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | ||
127 | if (err < 0) | ||
128 | return err; | ||
129 | } | ||
93 | return 0; | 130 | return 0; |
94 | } | 131 | } |
95 | 132 | ||
@@ -152,7 +189,8 @@ static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
152 | snd_pcm_substream_t *substream) | 189 | snd_pcm_substream_t *substream) |
153 | { | 190 | { |
154 | struct ad198x_spec *spec = codec->spec; | 191 | struct ad198x_spec *spec = codec->spec; |
155 | snd_hda_codec_setup_stream(codec, spec->adc_nid, stream_tag, 0, format); | 192 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], |
193 | stream_tag, 0, format); | ||
156 | return 0; | 194 | return 0; |
157 | } | 195 | } |
158 | 196 | ||
@@ -161,7 +199,8 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
161 | snd_pcm_substream_t *substream) | 199 | snd_pcm_substream_t *substream) |
162 | { | 200 | { |
163 | struct ad198x_spec *spec = codec->spec; | 201 | struct ad198x_spec *spec = codec->spec; |
164 | snd_hda_codec_setup_stream(codec, spec->adc_nid, 0, 0, 0); | 202 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], |
203 | 0, 0, 0); | ||
165 | return 0; | 204 | return 0; |
166 | } | 205 | } |
167 | 206 | ||
@@ -171,7 +210,7 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
171 | static struct hda_pcm_stream ad198x_pcm_analog_playback = { | 210 | static struct hda_pcm_stream ad198x_pcm_analog_playback = { |
172 | .substreams = 1, | 211 | .substreams = 1, |
173 | .channels_min = 2, | 212 | .channels_min = 2, |
174 | .channels_max = 6, | 213 | .channels_max = 6, /* changed later */ |
175 | .nid = 0, /* fill later */ | 214 | .nid = 0, /* fill later */ |
176 | .ops = { | 215 | .ops = { |
177 | .open = ad198x_playback_pcm_open, | 216 | .open = ad198x_playback_pcm_open, |
@@ -181,7 +220,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_playback = { | |||
181 | }; | 220 | }; |
182 | 221 | ||
183 | static struct hda_pcm_stream ad198x_pcm_analog_capture = { | 222 | static struct hda_pcm_stream ad198x_pcm_analog_capture = { |
184 | .substreams = 2, | 223 | .substreams = 1, |
185 | .channels_min = 2, | 224 | .channels_min = 2, |
186 | .channels_max = 2, | 225 | .channels_max = 2, |
187 | .nid = 0, /* fill later */ | 226 | .nid = 0, /* fill later */ |
@@ -202,6 +241,13 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { | |||
202 | }, | 241 | }, |
203 | }; | 242 | }; |
204 | 243 | ||
244 | static struct hda_pcm_stream ad198x_pcm_digital_capture = { | ||
245 | .substreams = 1, | ||
246 | .channels_min = 2, | ||
247 | .channels_max = 2, | ||
248 | /* NID is set in alc_build_pcms */ | ||
249 | }; | ||
250 | |||
205 | static int ad198x_build_pcms(struct hda_codec *codec) | 251 | static int ad198x_build_pcms(struct hda_codec *codec) |
206 | { | 252 | { |
207 | struct ad198x_spec *spec = codec->spec; | 253 | struct ad198x_spec *spec = codec->spec; |
@@ -215,7 +261,8 @@ static int ad198x_build_pcms(struct hda_codec *codec) | |||
215 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels; | 261 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels; |
216 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; | 262 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; |
217 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture; | 263 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture; |
218 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nid; | 264 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids; |
265 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; | ||
219 | 266 | ||
220 | if (spec->multiout.dig_out_nid) { | 267 | if (spec->multiout.dig_out_nid) { |
221 | info++; | 268 | info++; |
@@ -223,6 +270,10 @@ static int ad198x_build_pcms(struct hda_codec *codec) | |||
223 | info->name = "AD198x Digital"; | 270 | info->name = "AD198x Digital"; |
224 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; | 271 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; |
225 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; | 272 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; |
273 | if (spec->dig_in_nid) { | ||
274 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture; | ||
275 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; | ||
276 | } | ||
226 | } | 277 | } |
227 | 278 | ||
228 | return 0; | 279 | return 0; |
@@ -237,10 +288,15 @@ static void ad198x_free(struct hda_codec *codec) | |||
237 | static int ad198x_resume(struct hda_codec *codec) | 288 | static int ad198x_resume(struct hda_codec *codec) |
238 | { | 289 | { |
239 | struct ad198x_spec *spec = codec->spec; | 290 | struct ad198x_spec *spec = codec->spec; |
291 | int i; | ||
240 | 292 | ||
241 | ad198x_init(codec); | 293 | ad198x_init(codec); |
242 | snd_hda_resume_ctls(codec, spec->mixers); | 294 | for (i = 0; i < spec->num_mixers; i++) |
243 | snd_hda_resume_spdif_out(codec); | 295 | snd_hda_resume_ctls(codec, spec->mixers[i]); |
296 | if (spec->multiout.dig_out_nid) | ||
297 | snd_hda_resume_spdif_out(codec); | ||
298 | if (spec->dig_in_nid) | ||
299 | snd_hda_resume_spdif_in(codec); | ||
244 | return 0; | 300 | return 0; |
245 | } | 301 | } |
246 | #endif | 302 | #endif |
@@ -269,6 +325,7 @@ static struct hda_codec_ops ad198x_patch_ops = { | |||
269 | static hda_nid_t ad1986a_dac_nids[3] = { | 325 | static hda_nid_t ad1986a_dac_nids[3] = { |
270 | AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC | 326 | AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC |
271 | }; | 327 | }; |
328 | static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; | ||
272 | 329 | ||
273 | static struct hda_input_mux ad1986a_capture_source = { | 330 | static struct hda_input_mux ad1986a_capture_source = { |
274 | .num_items = 7, | 331 | .num_items = 7, |
@@ -476,10 +533,13 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
476 | spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids); | 533 | spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids); |
477 | spec->multiout.dac_nids = ad1986a_dac_nids; | 534 | spec->multiout.dac_nids = ad1986a_dac_nids; |
478 | spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; | 535 | spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; |
479 | spec->adc_nid = AD1986A_ADC; | 536 | spec->num_adc_nids = 1; |
537 | spec->adc_nids = ad1986a_adc_nids; | ||
480 | spec->input_mux = &ad1986a_capture_source; | 538 | spec->input_mux = &ad1986a_capture_source; |
481 | spec->mixers = ad1986a_mixers; | 539 | spec->num_mixers = 1; |
482 | spec->init_verbs = ad1986a_init_verbs; | 540 | spec->mixers[0] = ad1986a_mixers; |
541 | spec->num_init_verbs = 1; | ||
542 | spec->init_verbs[0] = ad1986a_init_verbs; | ||
483 | 543 | ||
484 | codec->patch_ops = ad198x_patch_ops; | 544 | codec->patch_ops = ad198x_patch_ops; |
485 | 545 | ||
@@ -495,6 +555,7 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
495 | #define AD1983_ADC 0x04 | 555 | #define AD1983_ADC 0x04 |
496 | 556 | ||
497 | static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; | 557 | static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; |
558 | static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; | ||
498 | 559 | ||
499 | static struct hda_input_mux ad1983_capture_source = { | 560 | static struct hda_input_mux ad1983_capture_source = { |
500 | .num_items = 4, | 561 | .num_items = 4, |
@@ -619,6 +680,7 @@ static struct hda_verb ad1983_init_verbs[] = { | |||
619 | { } /* end */ | 680 | { } /* end */ |
620 | }; | 681 | }; |
621 | 682 | ||
683 | |||
622 | static int patch_ad1983(struct hda_codec *codec) | 684 | static int patch_ad1983(struct hda_codec *codec) |
623 | { | 685 | { |
624 | struct ad198x_spec *spec; | 686 | struct ad198x_spec *spec; |
@@ -634,10 +696,13 @@ static int patch_ad1983(struct hda_codec *codec) | |||
634 | spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids); | 696 | spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids); |
635 | spec->multiout.dac_nids = ad1983_dac_nids; | 697 | spec->multiout.dac_nids = ad1983_dac_nids; |
636 | spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; | 698 | spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; |
637 | spec->adc_nid = AD1983_ADC; | 699 | spec->num_adc_nids = 1; |
700 | spec->adc_nids = ad1983_adc_nids; | ||
638 | spec->input_mux = &ad1983_capture_source; | 701 | spec->input_mux = &ad1983_capture_source; |
639 | spec->mixers = ad1983_mixers; | 702 | spec->num_mixers = 1; |
640 | spec->init_verbs = ad1983_init_verbs; | 703 | spec->mixers[0] = ad1983_mixers; |
704 | spec->num_init_verbs = 1; | ||
705 | spec->init_verbs[0] = ad1983_init_verbs; | ||
641 | spec->spdif_route = 0; | 706 | spec->spdif_route = 0; |
642 | 707 | ||
643 | codec->patch_ops = ad198x_patch_ops; | 708 | codec->patch_ops = ad198x_patch_ops; |
@@ -655,6 +720,7 @@ static int patch_ad1983(struct hda_codec *codec) | |||
655 | #define AD1981_ADC 0x04 | 720 | #define AD1981_ADC 0x04 |
656 | 721 | ||
657 | static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; | 722 | static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; |
723 | static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; | ||
658 | 724 | ||
659 | /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ | 725 | /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ |
660 | static struct hda_input_mux ad1981_capture_source = { | 726 | static struct hda_input_mux ad1981_capture_source = { |
@@ -775,10 +841,13 @@ static int patch_ad1981(struct hda_codec *codec) | |||
775 | spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids); | 841 | spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids); |
776 | spec->multiout.dac_nids = ad1981_dac_nids; | 842 | spec->multiout.dac_nids = ad1981_dac_nids; |
777 | spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; | 843 | spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; |
778 | spec->adc_nid = AD1981_ADC; | 844 | spec->num_adc_nids = 1; |
845 | spec->adc_nids = ad1981_adc_nids; | ||
779 | spec->input_mux = &ad1981_capture_source; | 846 | spec->input_mux = &ad1981_capture_source; |
780 | spec->mixers = ad1981_mixers; | 847 | spec->num_mixers = 1; |
781 | spec->init_verbs = ad1981_init_verbs; | 848 | spec->mixers[0] = ad1981_mixers; |
849 | spec->num_init_verbs = 1; | ||
850 | spec->init_verbs[0] = ad1981_init_verbs; | ||
782 | spec->spdif_route = 0; | 851 | spec->spdif_route = 0; |
783 | 852 | ||
784 | codec->patch_ops = ad198x_patch_ops; | 853 | codec->patch_ops = ad198x_patch_ops; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7327deb6df9f..cffb83fdcff7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -57,6 +57,7 @@ enum { | |||
57 | enum { | 57 | enum { |
58 | ALC260_BASIC, | 58 | ALC260_BASIC, |
59 | ALC260_HP, | 59 | ALC260_HP, |
60 | ALC260_FUJITSU_S702x, | ||
60 | ALC260_MODEL_LAST /* last tag */ | 61 | ALC260_MODEL_LAST /* last tag */ |
61 | }; | 62 | }; |
62 | 63 | ||
@@ -72,6 +73,7 @@ enum { | |||
72 | #define PIN_VREF50 0x21 | 73 | #define PIN_VREF50 0x21 |
73 | #define PIN_OUT 0x40 | 74 | #define PIN_OUT 0x40 |
74 | #define PIN_HP 0xc0 | 75 | #define PIN_HP 0xc0 |
76 | #define PIN_HP_AMP 0x80 | ||
75 | 77 | ||
76 | struct alc_spec { | 78 | struct alc_spec { |
77 | /* codec parameterization */ | 79 | /* codec parameterization */ |
@@ -113,8 +115,6 @@ struct alc_spec { | |||
113 | /* PCM information */ | 115 | /* PCM information */ |
114 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ | 116 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ |
115 | 117 | ||
116 | struct semaphore bind_mutex; /* for bound controls */ | ||
117 | |||
118 | /* dynamic controls, init_verbs and input_mux */ | 118 | /* dynamic controls, init_verbs and input_mux */ |
119 | struct auto_pin_cfg autocfg; | 119 | struct auto_pin_cfg autocfg; |
120 | unsigned int num_kctl_alloc, num_kctl_used; | 120 | unsigned int num_kctl_alloc, num_kctl_used; |
@@ -218,72 +218,53 @@ static int alc880_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *uc | |||
218 | 218 | ||
219 | 219 | ||
220 | /* | 220 | /* |
221 | * bound volume controls | 221 | * Control of pin widget settings via the mixer. Only boolean settings are |
222 | * | 222 | * supported, so VrefEn can't be controlled using these functions as they |
223 | * bind multiple volumes (# indices, from 0) | 223 | * stand. |
224 | */ | 224 | */ |
225 | 225 | static int alc_pinctl_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) | |
226 | #define AMP_VAL_IDX_SHIFT 19 | ||
227 | #define AMP_VAL_IDX_MASK (0x0f<<19) | ||
228 | |||
229 | static int alc_bind_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) | ||
230 | { | 226 | { |
231 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 227 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
232 | struct alc_spec *spec = codec->spec; | 228 | uinfo->count = 1; |
233 | unsigned long pval; | 229 | uinfo->value.integer.min = 0; |
234 | 230 | uinfo->value.integer.max = 1; | |
235 | down(&spec->bind_mutex); | ||
236 | pval = kcontrol->private_value; | ||
237 | kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ | ||
238 | snd_hda_mixer_amp_switch_info(kcontrol, uinfo); | ||
239 | kcontrol->private_value = pval; | ||
240 | up(&spec->bind_mutex); | ||
241 | return 0; | 231 | return 0; |
242 | } | 232 | } |
243 | 233 | ||
244 | static int alc_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | 234 | static int alc_pinctl_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) |
245 | { | 235 | { |
246 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 236 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
247 | struct alc_spec *spec = codec->spec; | 237 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
248 | unsigned long pval; | 238 | long mask = (kcontrol->private_value >> 16) & 0xff; |
249 | 239 | long *valp = ucontrol->value.integer.value; | |
250 | down(&spec->bind_mutex); | 240 | |
251 | pval = kcontrol->private_value; | 241 | *valp = 0; |
252 | kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ | 242 | if (snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00) & mask) |
253 | snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | 243 | *valp = 1; |
254 | kcontrol->private_value = pval; | ||
255 | up(&spec->bind_mutex); | ||
256 | return 0; | 244 | return 0; |
257 | } | 245 | } |
258 | 246 | ||
259 | static int alc_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | 247 | static int alc_pinctl_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) |
260 | { | 248 | { |
261 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 249 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
262 | struct alc_spec *spec = codec->spec; | 250 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
263 | unsigned long pval; | 251 | long mask = (kcontrol->private_value >> 16) & 0xff; |
264 | int i, indices, change = 0; | 252 | long *valp = ucontrol->value.integer.value; |
265 | 253 | unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); | |
266 | down(&spec->bind_mutex); | 254 | int change = ((pinctl & mask)!=0) != *valp; |
267 | pval = kcontrol->private_value; | 255 | |
268 | indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; | 256 | if (change) |
269 | for (i = 0; i < indices; i++) { | 257 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, |
270 | kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT); | 258 | *valp?(pinctl|mask):(pinctl&~mask)); |
271 | change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
272 | } | ||
273 | kcontrol->private_value = pval; | ||
274 | up(&spec->bind_mutex); | ||
275 | return change; | 259 | return change; |
276 | } | 260 | } |
277 | 261 | ||
278 | #define ALC_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ | 262 | #define ALC_PINCTL_SWITCH(xname, nid, mask) \ |
279 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | 263 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ |
280 | .info = alc_bind_switch_info, \ | 264 | .info = alc_pinctl_switch_info, \ |
281 | .get = alc_bind_switch_get, \ | 265 | .get = alc_pinctl_switch_get, \ |
282 | .put = alc_bind_switch_put, \ | 266 | .put = alc_pinctl_switch_put, \ |
283 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } | 267 | .private_value = (nid) | (mask<<16) } |
284 | |||
285 | #define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir) | ||
286 | |||
287 | 268 | ||
288 | /* | 269 | /* |
289 | * ALC880 3-stack model | 270 | * ALC880 3-stack model |
@@ -354,13 +335,13 @@ static struct alc_channel_mode alc880_threestack_modes[2] = { | |||
354 | 335 | ||
355 | static snd_kcontrol_new_t alc880_three_stack_mixer[] = { | 336 | static snd_kcontrol_new_t alc880_three_stack_mixer[] = { |
356 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 337 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
357 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 338 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
358 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 339 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
359 | ALC_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), | 340 | HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), |
360 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 341 | 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), | 342 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
362 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 343 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
363 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 344 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
364 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 345 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
365 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 346 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
366 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 347 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
@@ -441,7 +422,7 @@ static snd_kcontrol_new_t alc880_capture_alt_mixer[] = { | |||
441 | /* additional mixers to alc880_three_stack_mixer */ | 422 | /* additional mixers to alc880_three_stack_mixer */ |
442 | static snd_kcontrol_new_t alc880_five_stack_mixer[] = { | 423 | static snd_kcontrol_new_t alc880_five_stack_mixer[] = { |
443 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 424 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
444 | ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), | 425 | HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), |
445 | { } /* end */ | 426 | { } /* end */ |
446 | }; | 427 | }; |
447 | 428 | ||
@@ -498,15 +479,15 @@ static struct alc_channel_mode alc880_sixstack_modes[1] = { | |||
498 | 479 | ||
499 | static snd_kcontrol_new_t alc880_six_stack_mixer[] = { | 480 | static snd_kcontrol_new_t alc880_six_stack_mixer[] = { |
500 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 481 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
501 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 482 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
502 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 483 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
503 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | 484 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
504 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 485 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
505 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 486 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
506 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 487 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
507 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 488 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
508 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 489 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
509 | ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | 490 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), |
510 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 491 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
511 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 492 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
512 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 493 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
@@ -566,13 +547,13 @@ static struct alc_channel_mode alc880_w810_modes[1] = { | |||
566 | /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ | 547 | /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ |
567 | static snd_kcontrol_new_t alc880_w810_base_mixer[] = { | 548 | static snd_kcontrol_new_t alc880_w810_base_mixer[] = { |
568 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 549 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
569 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 550 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
570 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 551 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
571 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | 552 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
572 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 553 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
573 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 554 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
574 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 555 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
575 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 556 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
576 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 557 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
577 | { } /* end */ | 558 | { } /* end */ |
578 | }; | 559 | }; |
@@ -597,9 +578,9 @@ static struct alc_channel_mode alc880_2_jack_modes[1] = { | |||
597 | 578 | ||
598 | static snd_kcontrol_new_t alc880_z71v_mixer[] = { | 579 | static snd_kcontrol_new_t alc880_z71v_mixer[] = { |
599 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 580 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
600 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 581 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
601 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 582 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
602 | ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), | 583 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), |
603 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 584 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
604 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 585 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
605 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 586 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -623,9 +604,9 @@ static hda_nid_t alc880_f1734_dac_nids[1] = { | |||
623 | 604 | ||
624 | static snd_kcontrol_new_t alc880_f1734_mixer[] = { | 605 | static snd_kcontrol_new_t alc880_f1734_mixer[] = { |
625 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 606 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
626 | ALC_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | 607 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), |
627 | HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 608 | HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
628 | ALC_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT), | 609 | HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT), |
629 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 610 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
630 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 611 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
631 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 612 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -648,13 +629,13 @@ static snd_kcontrol_new_t alc880_f1734_mixer[] = { | |||
648 | 629 | ||
649 | static snd_kcontrol_new_t alc880_asus_mixer[] = { | 630 | static snd_kcontrol_new_t alc880_asus_mixer[] = { |
650 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 631 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
651 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 632 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
652 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 633 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
653 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | 634 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
654 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 635 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
655 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 636 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
656 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 637 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
657 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 638 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
658 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 639 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
659 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 640 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
660 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 641 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
@@ -1383,10 +1364,10 @@ static snd_kcontrol_new_t alc880_test_mixer[] = { | |||
1383 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 1364 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
1384 | HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), | 1365 | HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), |
1385 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 1366 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
1386 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 1367 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
1387 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | 1368 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
1388 | ALC_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), | 1369 | HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), |
1389 | ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | 1370 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), |
1390 | PIN_CTL_TEST("Front Pin Mode", 0x14), | 1371 | PIN_CTL_TEST("Front Pin Mode", 0x14), |
1391 | PIN_CTL_TEST("Surround Pin Mode", 0x15), | 1372 | PIN_CTL_TEST("Surround Pin Mode", 0x15), |
1392 | PIN_CTL_TEST("CLFE Pin Mode", 0x16), | 1373 | PIN_CTL_TEST("CLFE Pin Mode", 0x16), |
@@ -1769,7 +1750,7 @@ enum { | |||
1769 | static snd_kcontrol_new_t alc880_control_templates[] = { | 1750 | static snd_kcontrol_new_t alc880_control_templates[] = { |
1770 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | 1751 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), |
1771 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | 1752 | HDA_CODEC_MUTE(NULL, 0, 0, 0), |
1772 | ALC_BIND_MUTE(NULL, 0, 0, 0), | 1753 | HDA_BIND_MUTE(NULL, 0, 0, 0), |
1773 | }; | 1754 | }; |
1774 | 1755 | ||
1775 | /* add dynamic controls */ | 1756 | /* add dynamic controls */ |
@@ -2087,7 +2068,6 @@ static int patch_alc880(struct hda_codec *codec) | |||
2087 | if (spec == NULL) | 2068 | if (spec == NULL) |
2088 | return -ENOMEM; | 2069 | return -ENOMEM; |
2089 | 2070 | ||
2090 | init_MUTEX(&spec->bind_mutex); | ||
2091 | codec->spec = spec; | 2071 | codec->spec = spec; |
2092 | 2072 | ||
2093 | board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); | 2073 | board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); |
@@ -2205,6 +2185,17 @@ static struct hda_input_mux alc260_capture_source = { | |||
2205 | }, | 2185 | }, |
2206 | }; | 2186 | }; |
2207 | 2187 | ||
2188 | /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack | ||
2189 | * and the internal CD lines. | ||
2190 | */ | ||
2191 | static struct hda_input_mux alc260_fujitsu_capture_source = { | ||
2192 | .num_items = 2, | ||
2193 | .items = { | ||
2194 | { "Mic/Line", 0x0 }, | ||
2195 | { "CD", 0x4 }, | ||
2196 | }, | ||
2197 | }; | ||
2198 | |||
2208 | /* | 2199 | /* |
2209 | * This is just place-holder, so there's something for alc_build_pcms to look | 2200 | * This is just place-holder, so there's something for alc_build_pcms to look |
2210 | * at when it calculates the maximum number of channels. ALC260 has no mixer | 2201 | * at when it calculates the maximum number of channels. ALC260 has no mixer |
@@ -2217,7 +2208,7 @@ static struct alc_channel_mode alc260_modes[1] = { | |||
2217 | 2208 | ||
2218 | static snd_kcontrol_new_t alc260_base_mixer[] = { | 2209 | static snd_kcontrol_new_t alc260_base_mixer[] = { |
2219 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 2210 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
2220 | ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | 2211 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), |
2221 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 2212 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
2222 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | 2213 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), |
2223 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | 2214 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), |
@@ -2229,9 +2220,9 @@ static snd_kcontrol_new_t alc260_base_mixer[] = { | |||
2229 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT), | 2220 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT), |
2230 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT), | 2221 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT), |
2231 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), | 2222 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), |
2232 | ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), | 2223 | HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), |
2233 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | 2224 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), |
2234 | ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | 2225 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), |
2235 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), | 2226 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), |
2236 | HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), | 2227 | HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), |
2237 | { | 2228 | { |
@@ -2246,7 +2237,7 @@ static snd_kcontrol_new_t alc260_base_mixer[] = { | |||
2246 | 2237 | ||
2247 | static snd_kcontrol_new_t alc260_hp_mixer[] = { | 2238 | static snd_kcontrol_new_t alc260_hp_mixer[] = { |
2248 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 2239 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
2249 | ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | 2240 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), |
2250 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 2241 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
2251 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | 2242 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), |
2252 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | 2243 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), |
@@ -2256,9 +2247,9 @@ static snd_kcontrol_new_t alc260_hp_mixer[] = { | |||
2256 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), | 2247 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), |
2257 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), | 2248 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), |
2258 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), | 2249 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), |
2259 | ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), | 2250 | HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), |
2260 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | 2251 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), |
2261 | ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | 2252 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), |
2262 | HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT), | 2253 | HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT), |
2263 | HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT), | 2254 | HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT), |
2264 | { | 2255 | { |
@@ -2271,6 +2262,30 @@ static snd_kcontrol_new_t alc260_hp_mixer[] = { | |||
2271 | { } /* end */ | 2262 | { } /* end */ |
2272 | }; | 2263 | }; |
2273 | 2264 | ||
2265 | static snd_kcontrol_new_t alc260_fujitsu_mixer[] = { | ||
2266 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
2267 | HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), | ||
2268 | ALC_PINCTL_SWITCH("Headphone Amp Switch", 0x14, PIN_HP_AMP), | ||
2269 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
2270 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
2271 | HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
2272 | HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
2273 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | ||
2274 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | ||
2275 | HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
2276 | HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT), | ||
2277 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), | ||
2278 | HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), | ||
2279 | { | ||
2280 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2281 | .name = "Capture Source", | ||
2282 | .info = alc_mux_enum_info, | ||
2283 | .get = alc_mux_enum_get, | ||
2284 | .put = alc_mux_enum_put, | ||
2285 | }, | ||
2286 | { } /* end */ | ||
2287 | }; | ||
2288 | |||
2274 | static struct hda_verb alc260_init_verbs[] = { | 2289 | static struct hda_verb alc260_init_verbs[] = { |
2275 | /* Line In pin widget for input */ | 2290 | /* Line In pin widget for input */ |
2276 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 2291 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
@@ -2332,6 +2347,60 @@ static struct hda_verb alc260_init_verbs[] = { | |||
2332 | { } | 2347 | { } |
2333 | }; | 2348 | }; |
2334 | 2349 | ||
2350 | /* Initialisation sequence for ALC260 as configured in Fujitsu S702x | ||
2351 | * laptops. | ||
2352 | */ | ||
2353 | static struct hda_verb alc260_fujitsu_init_verbs[] = { | ||
2354 | /* Disable all GPIOs */ | ||
2355 | {0x01, AC_VERB_SET_GPIO_MASK, 0}, | ||
2356 | /* Internal speaker is connected to headphone pin */ | ||
2357 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2358 | /* Headphone/Line-out jack connects to Line1 pin; make it an output */ | ||
2359 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2360 | /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ | ||
2361 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
2362 | /* Ensure all other unused pins are disabled and muted. | ||
2363 | * Note: trying to set widget 0x15 to anything blocks all audio | ||
2364 | * output for some reason, so just leave that at the default. | ||
2365 | */ | ||
2366 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2367 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2368 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2369 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2370 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2371 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2372 | /* Disable digital (SPDIF) pins */ | ||
2373 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
2374 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
2375 | |||
2376 | /* Start with mixer outputs muted */ | ||
2377 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2378 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2379 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2380 | |||
2381 | /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ | ||
2382 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2383 | /* Unmute Line1 pin widget amp left and right (no equiv mixer ctrl) */ | ||
2384 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2385 | /* Unmute pin widget used for Line-in (no equiv mixer ctrl) */ | ||
2386 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2387 | |||
2388 | /* Mute capture amp left and right */ | ||
2389 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2390 | /* Set ADC connection select to line in (on mic1 pin) */ | ||
2391 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
2392 | |||
2393 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
2394 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
2395 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
2396 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
2397 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
2398 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
2399 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
2400 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
2401 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
2402 | }; | ||
2403 | |||
2335 | static struct hda_pcm_stream alc260_pcm_analog_playback = { | 2404 | static struct hda_pcm_stream alc260_pcm_analog_playback = { |
2336 | .substreams = 1, | 2405 | .substreams = 1, |
2337 | .channels_min = 2, | 2406 | .channels_min = 2, |
@@ -2347,6 +2416,8 @@ static struct hda_pcm_stream alc260_pcm_analog_capture = { | |||
2347 | static struct hda_board_config alc260_cfg_tbl[] = { | 2416 | static struct hda_board_config alc260_cfg_tbl[] = { |
2348 | { .modelname = "hp", .config = ALC260_HP }, | 2417 | { .modelname = "hp", .config = ALC260_HP }, |
2349 | { .pci_subvendor = 0x103c, .config = ALC260_HP }, | 2418 | { .pci_subvendor = 0x103c, .config = ALC260_HP }, |
2419 | { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702x }, | ||
2420 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702x }, | ||
2350 | {} | 2421 | {} |
2351 | }; | 2422 | }; |
2352 | 2423 | ||
@@ -2359,7 +2430,6 @@ static int patch_alc260(struct hda_codec *codec) | |||
2359 | if (spec == NULL) | 2430 | if (spec == NULL) |
2360 | return -ENOMEM; | 2431 | return -ENOMEM; |
2361 | 2432 | ||
2362 | init_MUTEX(&spec->bind_mutex); | ||
2363 | codec->spec = spec; | 2433 | codec->spec = spec; |
2364 | 2434 | ||
2365 | board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); | 2435 | board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); |
@@ -2373,14 +2443,23 @@ static int patch_alc260(struct hda_codec *codec) | |||
2373 | spec->mixers[spec->num_mixers] = alc260_hp_mixer; | 2443 | spec->mixers[spec->num_mixers] = alc260_hp_mixer; |
2374 | spec->num_mixers++; | 2444 | spec->num_mixers++; |
2375 | break; | 2445 | break; |
2446 | case ALC260_FUJITSU_S702x: | ||
2447 | spec->mixers[spec->num_mixers] = alc260_fujitsu_mixer; | ||
2448 | spec->num_mixers++; | ||
2449 | break; | ||
2376 | default: | 2450 | default: |
2377 | spec->mixers[spec->num_mixers] = alc260_base_mixer; | 2451 | spec->mixers[spec->num_mixers] = alc260_base_mixer; |
2378 | spec->num_mixers++; | 2452 | spec->num_mixers++; |
2379 | break; | 2453 | break; |
2380 | } | 2454 | } |
2381 | 2455 | ||
2382 | spec->init_verbs[0] = alc260_init_verbs; | 2456 | if (board_config != ALC260_FUJITSU_S702x) { |
2383 | spec->num_init_verbs = 1; | 2457 | spec->init_verbs[0] = alc260_init_verbs; |
2458 | spec->num_init_verbs = 1; | ||
2459 | } else { | ||
2460 | spec->init_verbs[0] = alc260_fujitsu_init_verbs; | ||
2461 | spec->num_init_verbs = 1; | ||
2462 | } | ||
2384 | 2463 | ||
2385 | spec->channel_mode = alc260_modes; | 2464 | spec->channel_mode = alc260_modes; |
2386 | spec->num_channel_mode = ARRAY_SIZE(alc260_modes); | 2465 | spec->num_channel_mode = ARRAY_SIZE(alc260_modes); |
@@ -2393,7 +2472,11 @@ static int patch_alc260(struct hda_codec *codec) | |||
2393 | spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids); | 2472 | spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids); |
2394 | spec->multiout.dac_nids = alc260_dac_nids; | 2473 | spec->multiout.dac_nids = alc260_dac_nids; |
2395 | 2474 | ||
2396 | spec->input_mux = &alc260_capture_source; | 2475 | if (board_config != ALC260_FUJITSU_S702x) { |
2476 | spec->input_mux = &alc260_capture_source; | ||
2477 | } else { | ||
2478 | spec->input_mux = &alc260_fujitsu_capture_source; | ||
2479 | } | ||
2397 | switch (board_config) { | 2480 | switch (board_config) { |
2398 | case ALC260_HP: | 2481 | case ALC260_HP: |
2399 | spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids); | 2482 | spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids); |
@@ -2483,15 +2566,15 @@ static int alc882_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u | |||
2483 | */ | 2566 | */ |
2484 | static snd_kcontrol_new_t alc882_base_mixer[] = { | 2567 | static snd_kcontrol_new_t alc882_base_mixer[] = { |
2485 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 2568 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2486 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2569 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
2487 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 2570 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
2488 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | 2571 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
2489 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 2572 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
2490 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 2573 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
2491 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 2574 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
2492 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 2575 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
2493 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 2576 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
2494 | ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | 2577 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), |
2495 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 2578 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
2496 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 2579 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
2497 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 2580 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
@@ -2609,7 +2692,6 @@ static int patch_alc882(struct hda_codec *codec) | |||
2609 | if (spec == NULL) | 2692 | if (spec == NULL) |
2610 | return -ENOMEM; | 2693 | return -ENOMEM; |
2611 | 2694 | ||
2612 | init_MUTEX(&spec->bind_mutex); | ||
2613 | codec->spec = spec; | 2695 | codec->spec = spec; |
2614 | 2696 | ||
2615 | spec->mixers[spec->num_mixers] = alc882_base_mixer; | 2697 | spec->mixers[spec->num_mixers] = alc882_base_mixer; |
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index d014b7bb70df..9c7fe0b3200a 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * HD audio interface patch for Silicon Labs 3054/5 modem codec | 4 | * HD audio interface patch for Silicon Labs 3054/5 modem codec |
5 | * | 5 | * |
6 | * Copyright (c) 2005 Sasha Khapyorsky <sashak@smlink.com> | 6 | * Copyright (c) 2005 Sasha Khapyorsky <sashak@alsa-project.org> |
7 | * Takashi Iwai <tiwai@suse.de> | 7 | * Takashi Iwai <tiwai@suse.de> |
8 | * | 8 | * |
9 | * | 9 | * |