diff options
author | Takashi Iwai <tiwai@suse.de> | 2005-06-13 08:16:38 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2005-06-22 06:28:59 -0400 |
commit | e9edcee061a80181f0d6e7cada07e1898c14718e (patch) | |
tree | b8ce3f0430ef436cbfbe98736f1ef6bc86fd8c94 /sound/pci | |
parent | b636a71d9b9525ee51ca872d461817a5bd5c39fd (diff) |
[ALSA] hda-codec - More fix of ALC880 codec support
Documentation,HDA Codec driver,HDA generic driver,HDA Intel driver
- Fix some invalid configurations, typos in the last patch
- Make init_verbs chainable, so that different configs can share the same
init_verbs
- Reorder and clean up the source codes in patch_realtek.c
- Add the pin default configuration parser, used commonly in cmedia
and realtek patch codes.
- Add 'auto' model to ALC880 for auto-configuration from BIOS
Use this model as default, and 3-stack as fallback
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 103 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.c | 10 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 33 | ||||
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 236 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 1909 |
6 files changed, 1201 insertions, 1092 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index f62d1d5eb7fa..e2cf02387289 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1520,9 +1520,9 @@ int snd_hda_build_pcms(struct hda_bus *bus) | |||
1520 | * | 1520 | * |
1521 | * If no entries are matching, the function returns a negative value. | 1521 | * If no entries are matching, the function returns a negative value. |
1522 | */ | 1522 | */ |
1523 | int snd_hda_check_board_config(struct hda_codec *codec, struct hda_board_config *tbl) | 1523 | int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl) |
1524 | { | 1524 | { |
1525 | struct hda_board_config *c; | 1525 | const struct hda_board_config *c; |
1526 | 1526 | ||
1527 | if (codec->bus->modelname) { | 1527 | if (codec->bus->modelname) { |
1528 | for (c = tbl; c->modelname || c->pci_subvendor; c++) { | 1528 | for (c = tbl; c->modelname || c->pci_subvendor; c++) { |
@@ -1714,6 +1714,105 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o | |||
1714 | return 0; | 1714 | return 0; |
1715 | } | 1715 | } |
1716 | 1716 | ||
1717 | /* | ||
1718 | * Helper for automatic ping configuration | ||
1719 | */ | ||
1720 | /* parse all pin widgets and store the useful pin nids to cfg */ | ||
1721 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg) | ||
1722 | { | ||
1723 | hda_nid_t nid, nid_start; | ||
1724 | int i, j, nodes; | ||
1725 | short seq, sequences[4], assoc_line_out; | ||
1726 | |||
1727 | memset(cfg, 0, sizeof(*cfg)); | ||
1728 | |||
1729 | memset(sequences, 0, sizeof(sequences)); | ||
1730 | assoc_line_out = 0; | ||
1731 | |||
1732 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); | ||
1733 | for (nid = nid_start; nid < nodes + nid_start; nid++) { | ||
1734 | unsigned int wid_caps = snd_hda_param_read(codec, nid, | ||
1735 | AC_PAR_AUDIO_WIDGET_CAP); | ||
1736 | unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
1737 | unsigned int def_conf; | ||
1738 | short assoc, loc; | ||
1739 | |||
1740 | /* read all default configuration for pin complex */ | ||
1741 | if (wid_type != AC_WID_PIN) | ||
1742 | continue; | ||
1743 | def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
1744 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | ||
1745 | continue; | ||
1746 | loc = get_defcfg_location(def_conf); | ||
1747 | switch (get_defcfg_device(def_conf)) { | ||
1748 | case AC_JACK_LINE_OUT: | ||
1749 | case AC_JACK_SPEAKER: | ||
1750 | seq = get_defcfg_sequence(def_conf); | ||
1751 | assoc = get_defcfg_association(def_conf); | ||
1752 | if (! assoc) | ||
1753 | continue; | ||
1754 | if (! assoc_line_out) | ||
1755 | assoc_line_out = assoc; | ||
1756 | else if (assoc_line_out != assoc) | ||
1757 | continue; | ||
1758 | if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) | ||
1759 | continue; | ||
1760 | cfg->line_out_pins[cfg->line_outs] = nid; | ||
1761 | sequences[cfg->line_outs] = seq; | ||
1762 | cfg->line_outs++; | ||
1763 | break; | ||
1764 | case AC_JACK_HP_OUT: | ||
1765 | cfg->hp_pin = nid; | ||
1766 | break; | ||
1767 | case AC_JACK_MIC_IN: | ||
1768 | if (loc == AC_JACK_LOC_FRONT) | ||
1769 | cfg->input_pins[AUTO_PIN_FRONT_MIC] = nid; | ||
1770 | else | ||
1771 | cfg->input_pins[AUTO_PIN_MIC] = nid; | ||
1772 | break; | ||
1773 | case AC_JACK_LINE_IN: | ||
1774 | if (loc == AC_JACK_LOC_FRONT) | ||
1775 | cfg->input_pins[AUTO_PIN_FRONT_LINE] = nid; | ||
1776 | else | ||
1777 | cfg->input_pins[AUTO_PIN_LINE] = nid; | ||
1778 | break; | ||
1779 | case AC_JACK_CD: | ||
1780 | cfg->input_pins[AUTO_PIN_CD] = nid; | ||
1781 | break; | ||
1782 | case AC_JACK_AUX: | ||
1783 | cfg->input_pins[AUTO_PIN_AUX] = nid; | ||
1784 | break; | ||
1785 | case AC_JACK_SPDIF_OUT: | ||
1786 | cfg->dig_out_pin = nid; | ||
1787 | break; | ||
1788 | case AC_JACK_SPDIF_IN: | ||
1789 | cfg->dig_in_pin = nid; | ||
1790 | break; | ||
1791 | } | ||
1792 | } | ||
1793 | |||
1794 | /* sort by sequence */ | ||
1795 | for (i = 0; i < cfg->line_outs; i++) | ||
1796 | for (j = i + 1; j < cfg->line_outs; j++) | ||
1797 | if (sequences[i] > sequences[j]) { | ||
1798 | seq = sequences[i]; | ||
1799 | sequences[i] = sequences[j]; | ||
1800 | sequences[j] = seq; | ||
1801 | nid = cfg->line_out_pins[i]; | ||
1802 | cfg->line_out_pins[i] = cfg->line_out_pins[j]; | ||
1803 | cfg->line_out_pins[j] = nid; | ||
1804 | } | ||
1805 | |||
1806 | /* Swap surround and CLFE: the association order is front/CLFE/surr/back */ | ||
1807 | if (cfg->line_outs >= 3) { | ||
1808 | nid = cfg->line_out_pins[1]; | ||
1809 | cfg->line_out_pins[1] = cfg->line_out_pins[2]; | ||
1810 | cfg->line_out_pins[2] = nid; | ||
1811 | } | ||
1812 | |||
1813 | return 0; | ||
1814 | } | ||
1815 | |||
1717 | #ifdef CONFIG_PM | 1816 | #ifdef CONFIG_PM |
1718 | /* | 1817 | /* |
1719 | * power management | 1818 | * power management |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index bfbeff2e0d0c..2d046abb5911 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -68,8 +68,8 @@ struct hda_gspec { | |||
68 | /* | 68 | /* |
69 | * retrieve the default device type from the default config value | 69 | * retrieve the default device type from the default config value |
70 | */ | 70 | */ |
71 | #define get_defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) | 71 | #define defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) |
72 | #define get_defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) | 72 | #define defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * destructor | 75 | * destructor |
@@ -323,7 +323,7 @@ static struct hda_gnode *parse_output_jack(struct hda_codec *codec, | |||
323 | if (! (node->pin_caps & AC_PINCAP_OUT)) | 323 | if (! (node->pin_caps & AC_PINCAP_OUT)) |
324 | continue; | 324 | continue; |
325 | if (jack_type >= 0) { | 325 | if (jack_type >= 0) { |
326 | if (jack_type != get_defcfg_type(node)) | 326 | if (jack_type != defcfg_type(node)) |
327 | continue; | 327 | continue; |
328 | if (node->wid_caps & AC_WCAP_DIGITAL) | 328 | if (node->wid_caps & AC_WCAP_DIGITAL) |
329 | continue; /* skip SPDIF */ | 329 | continue; /* skip SPDIF */ |
@@ -418,8 +418,8 @@ static int capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *uc | |||
418 | */ | 418 | */ |
419 | static const char *get_input_type(struct hda_gnode *node, unsigned int *pinctl) | 419 | static const char *get_input_type(struct hda_gnode *node, unsigned int *pinctl) |
420 | { | 420 | { |
421 | unsigned int location = get_defcfg_location(node); | 421 | unsigned int location = defcfg_location(node); |
422 | switch (get_defcfg_type(node)) { | 422 | switch (defcfg_type(node)) { |
423 | case AC_JACK_LINE_IN: | 423 | case AC_JACK_LINE_IN: |
424 | if ((location & 0x0f) == AC_JACK_LOC_FRONT) | 424 | if ((location & 0x0f) == AC_JACK_LOC_FRONT) |
425 | return "Front Line"; | 425 | return "Front Line"; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d89849197422..5e0cca36ed57 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1458,7 +1458,7 @@ static struct pci_device_id azx_ids[] = { | |||
1458 | { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ESB2 */ | 1458 | { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ESB2 */ |
1459 | { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ATI SB450 */ | 1459 | { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ATI SB450 */ |
1460 | { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* VIA VT8251/VT8237A */ | 1460 | { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* VIA VT8251/VT8237A */ |
1461 | { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ULI */ | 1461 | { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ALI 5461? */ |
1462 | { 0, } | 1462 | { 0, } |
1463 | }; | 1463 | }; |
1464 | MODULE_DEVICE_TABLE(pci, azx_ids); | 1464 | MODULE_DEVICE_TABLE(pci, azx_ids); |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index b8fbbc4901d9..810cfd2d9bba 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -130,7 +130,7 @@ struct hda_board_config { | |||
130 | unsigned short pci_subdevice; | 130 | unsigned short pci_subdevice; |
131 | }; | 131 | }; |
132 | 132 | ||
133 | int snd_hda_check_board_config(struct hda_codec *codec, struct hda_board_config *tbl); | 133 | int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl); |
134 | int snd_hda_add_new_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew); | 134 | int snd_hda_add_new_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew); |
135 | 135 | ||
136 | /* | 136 | /* |
@@ -158,4 +158,35 @@ struct hda_bus_unsolicited { | |||
158 | struct work_struct work; | 158 | struct work_struct work; |
159 | }; | 159 | }; |
160 | 160 | ||
161 | /* | ||
162 | * Helper for automatic ping configuration | ||
163 | */ | ||
164 | |||
165 | enum { | ||
166 | AUTO_PIN_MIC, | ||
167 | AUTO_PIN_FRONT_MIC, | ||
168 | AUTO_PIN_LINE, | ||
169 | AUTO_PIN_FRONT_LINE, | ||
170 | AUTO_PIN_CD, | ||
171 | AUTO_PIN_AUX, | ||
172 | AUTO_PIN_LAST | ||
173 | }; | ||
174 | |||
175 | struct auto_pin_cfg { | ||
176 | int line_outs; | ||
177 | hda_nid_t line_out_pins[4]; /* sorted in the order of Front/Surr/CLFE/Side */ | ||
178 | hda_nid_t hp_pin; | ||
179 | hda_nid_t input_pins[AUTO_PIN_LAST]; | ||
180 | hda_nid_t dig_out_pin; | ||
181 | hda_nid_t dig_in_pin; | ||
182 | }; | ||
183 | |||
184 | #define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) | ||
185 | #define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) | ||
186 | #define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) | ||
187 | #define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE) | ||
188 | #define get_defcfg_device(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) | ||
189 | |||
190 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg); | ||
191 | |||
161 | #endif /* __SOUND_HDA_LOCAL_H */ | 192 | #endif /* __SOUND_HDA_LOCAL_H */ |
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 087230ca20a5..2d6e3e3d0a38 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -51,6 +51,7 @@ struct cmi_spec { | |||
51 | /* playback */ | 51 | /* playback */ |
52 | struct hda_multi_out multiout; | 52 | struct hda_multi_out multiout; |
53 | hda_nid_t dac_nids[4]; /* NID for each DAC */ | 53 | hda_nid_t dac_nids[4]; /* NID for each DAC */ |
54 | int num_dacs; | ||
54 | 55 | ||
55 | /* capture */ | 56 | /* capture */ |
56 | hda_nid_t *adc_nids; | 57 | hda_nid_t *adc_nids; |
@@ -77,6 +78,19 @@ struct cmi_spec { | |||
77 | struct hda_verb multi_init[9]; /* 2 verbs for each pin + terminator */ | 78 | struct hda_verb multi_init[9]; /* 2 verbs for each pin + terminator */ |
78 | }; | 79 | }; |
79 | 80 | ||
81 | /* amp values */ | ||
82 | #define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) | ||
83 | #define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8)) | ||
84 | #define AMP_OUT_MUTE 0xb080 | ||
85 | #define AMP_OUT_UNMUTE 0xb000 | ||
86 | #define AMP_OUT_ZERO 0xb000 | ||
87 | /* pinctl values */ | ||
88 | #define PIN_IN 0x20 | ||
89 | #define PIN_VREF80 0x24 | ||
90 | #define PIN_VREF50 0x21 | ||
91 | #define PIN_OUT 0x40 | ||
92 | #define PIN_HP 0xc0 | ||
93 | |||
80 | /* | 94 | /* |
81 | * input MUX | 95 | * input MUX |
82 | */ | 96 | */ |
@@ -114,9 +128,9 @@ static int cmi_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucon | |||
114 | /* 3-stack / 2 channel */ | 128 | /* 3-stack / 2 channel */ |
115 | static struct hda_verb cmi9880_ch2_init[] = { | 129 | static struct hda_verb cmi9880_ch2_init[] = { |
116 | /* set line-in PIN for input */ | 130 | /* set line-in PIN for input */ |
117 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | 131 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
118 | /* set mic PIN for input, also enable vref */ | 132 | /* set mic PIN for input, also enable vref */ |
119 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 133 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
120 | /* route front PCM (DAC1) to HP */ | 134 | /* route front PCM (DAC1) to HP */ |
121 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 135 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
122 | {} | 136 | {} |
@@ -125,9 +139,9 @@ static struct hda_verb cmi9880_ch2_init[] = { | |||
125 | /* 3-stack / 6 channel */ | 139 | /* 3-stack / 6 channel */ |
126 | static struct hda_verb cmi9880_ch6_init[] = { | 140 | static struct hda_verb cmi9880_ch6_init[] = { |
127 | /* set line-in PIN for output */ | 141 | /* set line-in PIN for output */ |
128 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 142 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
129 | /* set mic PIN for output */ | 143 | /* set mic PIN for output */ |
130 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 144 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
131 | /* route front PCM (DAC1) to HP */ | 145 | /* route front PCM (DAC1) to HP */ |
132 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 146 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
133 | {} | 147 | {} |
@@ -136,9 +150,9 @@ static struct hda_verb cmi9880_ch6_init[] = { | |||
136 | /* 3-stack+front / 8 channel */ | 150 | /* 3-stack+front / 8 channel */ |
137 | static struct hda_verb cmi9880_ch8_init[] = { | 151 | static struct hda_verb cmi9880_ch8_init[] = { |
138 | /* set line-in PIN for output */ | 152 | /* set line-in PIN for output */ |
139 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 153 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
140 | /* set mic PIN for output */ | 154 | /* set mic PIN for output */ |
141 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 155 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
142 | /* route rear-surround PCM (DAC4) to HP */ | 156 | /* route rear-surround PCM (DAC4) to HP */ |
143 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x03 }, | 157 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x03 }, |
144 | {} | 158 | {} |
@@ -281,27 +295,27 @@ static hda_nid_t cmi9880_adc_nids[2] = { | |||
281 | */ | 295 | */ |
282 | static struct hda_verb cmi9880_basic_init[] = { | 296 | static struct hda_verb cmi9880_basic_init[] = { |
283 | /* port-D for line out (rear panel) */ | 297 | /* port-D for line out (rear panel) */ |
284 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 298 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
285 | /* port-E for HP out (front panel) */ | 299 | /* port-E for HP out (front panel) */ |
286 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 300 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
287 | /* route front PCM to HP */ | 301 | /* route front PCM to HP */ |
288 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 302 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
289 | /* port-A for surround (rear panel) */ | 303 | /* port-A for surround (rear panel) */ |
290 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 304 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
291 | /* port-G for CLFE (rear panel) */ | 305 | /* port-G for CLFE (rear panel) */ |
292 | { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 306 | { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
293 | { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 }, | 307 | { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 }, |
294 | /* port-H for side (rear panel) */ | 308 | /* port-H for side (rear panel) */ |
295 | { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 309 | { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
296 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 }, | 310 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 }, |
297 | /* port-C for line-in (rear panel) */ | 311 | /* port-C for line-in (rear panel) */ |
298 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | 312 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
299 | /* port-B for mic-in (rear panel) with vref */ | 313 | /* port-B for mic-in (rear panel) with vref */ |
300 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 314 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
301 | /* port-F for mic-in (front panel) with vref */ | 315 | /* port-F for mic-in (front panel) with vref */ |
302 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 316 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
303 | /* CD-in */ | 317 | /* CD-in */ |
304 | { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | 318 | { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
305 | /* route front mic to ADC1/2 */ | 319 | /* route front mic to ADC1/2 */ |
306 | { 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 }, | 320 | { 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 }, |
307 | { 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 }, | 321 | { 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 }, |
@@ -310,27 +324,27 @@ static struct hda_verb cmi9880_basic_init[] = { | |||
310 | 324 | ||
311 | static struct hda_verb cmi9880_allout_init[] = { | 325 | static struct hda_verb cmi9880_allout_init[] = { |
312 | /* port-D for line out (rear panel) */ | 326 | /* port-D for line out (rear panel) */ |
313 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 327 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
314 | /* port-E for HP out (front panel) */ | 328 | /* port-E for HP out (front panel) */ |
315 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 329 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
316 | /* route front PCM to HP */ | 330 | /* route front PCM to HP */ |
317 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 331 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
318 | /* port-A for side (rear panel) */ | 332 | /* port-A for side (rear panel) */ |
319 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 333 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
320 | /* port-G for CLFE (rear panel) */ | 334 | /* port-G for CLFE (rear panel) */ |
321 | { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 335 | { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
322 | { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 }, | 336 | { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 }, |
323 | /* port-H for side (rear panel) */ | 337 | /* port-H for side (rear panel) */ |
324 | { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 338 | { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
325 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 }, | 339 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 }, |
326 | /* port-C for surround (rear panel) */ | 340 | /* port-C for surround (rear panel) */ |
327 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 341 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
328 | /* port-B for mic-in (rear panel) with vref */ | 342 | /* port-B for mic-in (rear panel) with vref */ |
329 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 343 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
330 | /* port-F for mic-in (front panel) with vref */ | 344 | /* port-F for mic-in (front panel) with vref */ |
331 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 345 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
332 | /* CD-in */ | 346 | /* CD-in */ |
333 | { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | 347 | { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
334 | /* route front mic to ADC1/2 */ | 348 | /* route front mic to ADC1/2 */ |
335 | { 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 }, | 349 | { 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 }, |
336 | { 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 }, | 350 | { 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 }, |
@@ -365,101 +379,9 @@ static int cmi9880_build_controls(struct hda_codec *codec) | |||
365 | return 0; | 379 | return 0; |
366 | } | 380 | } |
367 | 381 | ||
368 | #define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) | ||
369 | #define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) | ||
370 | #define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE) | ||
371 | |||
372 | /* get all pin default configuration in def_conf */ | ||
373 | static int cmi9880_get_pin_def_config(struct hda_codec *codec) | ||
374 | { | ||
375 | struct cmi_spec *spec = codec->spec; | ||
376 | hda_nid_t nid, nid_start; | ||
377 | int i = 0, nodes; | ||
378 | |||
379 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); | ||
380 | for (nid = nid_start; nid < nodes + nid_start; nid++) { | ||
381 | unsigned int wid_caps = snd_hda_param_read(codec, nid, | ||
382 | AC_PAR_AUDIO_WIDGET_CAP); | ||
383 | unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
384 | /* read all default configuration for pin complex */ | ||
385 | if (wid_type == AC_WID_PIN) { | ||
386 | spec->pin_nid[i] = nid; | ||
387 | spec->def_conf[i] = | ||
388 | snd_hda_codec_read(codec, nid, 0, | ||
389 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
390 | i++; | ||
391 | } | ||
392 | } | ||
393 | spec->pin_def_confs = i; | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | /* get a pin default configuration of nid in def_conf */ | ||
398 | static unsigned int cmi9880_get_def_config(struct hda_codec *codec, hda_nid_t nid) | ||
399 | { | ||
400 | struct cmi_spec *spec = codec->spec; | ||
401 | int i = 0; | ||
402 | |||
403 | while (spec->pin_nid[i] != nid && i < spec->pin_def_confs) | ||
404 | i++; | ||
405 | if (i == spec->pin_def_confs) | ||
406 | return (unsigned int) -1; | ||
407 | else | ||
408 | return spec->def_conf[i]; | ||
409 | } | ||
410 | |||
411 | /* decide what pins to use for multichannel playback */ | ||
412 | static int cmi9880_get_multich_pins(struct hda_codec *codec) | ||
413 | { | ||
414 | struct cmi_spec *spec = codec->spec; | ||
415 | int i, j, pins, seq[4]; | ||
416 | int max_channel = 0; | ||
417 | unsigned int def_conf, sequence; | ||
418 | hda_nid_t nid; | ||
419 | |||
420 | memset(spec->multich_pin, 0, sizeof(spec->multich_pin)); | ||
421 | for (pins = 0, i = 0; i < spec->pin_def_confs && pins < 4; i++) { | ||
422 | def_conf = spec->def_conf[i]; | ||
423 | /* skip pin not connected */ | ||
424 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | ||
425 | continue; | ||
426 | /* get the sequence if association == 1 */ | ||
427 | /* the other pins have association = 0, incorrect in spec 1.0 */ | ||
428 | if (get_defcfg_association(def_conf) == 1) { | ||
429 | sequence = get_defcfg_sequence(def_conf); | ||
430 | seq[pins] = sequence; | ||
431 | spec->multich_pin[pins] = spec->pin_nid[i]; | ||
432 | pins++; // ready for next slot | ||
433 | max_channel += 2; | ||
434 | } | ||
435 | } | ||
436 | /* sort by sequence, data collected here will be for Windows */ | ||
437 | for (i = 0; i < pins; i++) { | ||
438 | for (j = i + 1; j < pins; j++) { | ||
439 | if (seq[j] < seq[i]) { | ||
440 | sequence = seq[j]; | ||
441 | nid = spec->multich_pin[j]; | ||
442 | seq[j] = seq[i]; | ||
443 | spec->multich_pin[j] = spec->multich_pin[i]; | ||
444 | seq[i] = sequence; | ||
445 | spec->multich_pin[i] = nid; | ||
446 | } | ||
447 | } | ||
448 | } | ||
449 | /* the pin assignment is for front, C/LFE, surround and back */ | ||
450 | if (max_channel >= 6) { | ||
451 | hda_nid_t temp; | ||
452 | /* exchange pin of C/LFE and surround */ | ||
453 | temp = spec->multich_pin[1]; | ||
454 | spec->multich_pin[1] = spec->multich_pin[2]; | ||
455 | spec->multich_pin[2] = temp; | ||
456 | } | ||
457 | return max_channel; | ||
458 | } | ||
459 | |||
460 | /* fill in the multi_dac_nids table, which will decide | 382 | /* fill in the multi_dac_nids table, which will decide |
461 | which audio widget to use for each channel */ | 383 | which audio widget to use for each channel */ |
462 | static int cmi9880_fill_multi_dac_nids(struct hda_codec *codec) | 384 | static int cmi9880_fill_multi_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg) |
463 | { | 385 | { |
464 | struct cmi_spec *spec = codec->spec; | 386 | struct cmi_spec *spec = codec->spec; |
465 | hda_nid_t nid; | 387 | hda_nid_t nid; |
@@ -470,32 +392,34 @@ static int cmi9880_fill_multi_dac_nids(struct hda_codec *codec) | |||
470 | memset(spec->dac_nids, 0, sizeof(spec->dac_nids)); | 392 | memset(spec->dac_nids, 0, sizeof(spec->dac_nids)); |
471 | memset(assigned, 0, sizeof(assigned)); | 393 | memset(assigned, 0, sizeof(assigned)); |
472 | /* check the pins we found */ | 394 | /* check the pins we found */ |
473 | for (i = 0; i < spec->multiout.max_channels / 2; i++) { | 395 | for (i = 0; i < cfg->line_outs; i++) { |
474 | nid = spec->multich_pin[i]; | 396 | nid = cfg->line_out_pins[i]; |
475 | /* nid 0x0b~0x0e is hardwired to audio widget 0x3~0x6 */ | 397 | /* nid 0x0b~0x0e is hardwired to audio widget 0x3~0x6 */ |
476 | if (nid <= 0x0e && nid >= 0x0b) { | 398 | if (nid >= 0x0b && nid <= 0x0e) { |
477 | spec->dac_nids[i] = nid - 0x08; | 399 | spec->dac_nids[i] = (nid - 0x0b) + 0x03; |
478 | assigned[nid - 0x0b] = 1; | 400 | assigned[nid - 0x0b] = 1; |
479 | } | 401 | } |
480 | } | 402 | } |
481 | /* left pin can be connect to any audio widget */ | 403 | /* left pin can be connect to any audio widget */ |
482 | for (i = 0; i < spec->multiout.max_channels / 2; i++) { | 404 | for (i = 0; i < cfg->line_outs; i++) { |
483 | if (!assigned[i]) { | 405 | nid = cfg->line_out_pins[i]; |
484 | /* search for an empty channel */ | 406 | if (nid <= 0x0e) |
485 | /* I should also check the pin type */ | 407 | continue; |
486 | for (j = 0; j < ARRAY_SIZE(spec->dac_nids); j++) | 408 | /* search for an empty channel */ |
487 | if (! spec->dac_nids[j]) { | 409 | for (j = 0; j < cfg->line_outs; j++) { |
488 | spec->dac_nids[j] = i + 3; | 410 | if (! assigned[j]) { |
489 | assigned[i] = 1; | 411 | spec->dac_nids[i] = i + 0x03; |
490 | break; | 412 | assigned[j] = 1; |
491 | } | 413 | break; |
414 | } | ||
492 | } | 415 | } |
493 | } | 416 | } |
417 | spec->num_dacs = cfg->line_outs; | ||
494 | return 0; | 418 | return 0; |
495 | } | 419 | } |
496 | 420 | ||
497 | /* create multi_init table, which is used for multichannel initialization */ | 421 | /* create multi_init table, which is used for multichannel initialization */ |
498 | static int cmi9880_fill_multi_init(struct hda_codec *codec) | 422 | static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pin_cfg *cfg) |
499 | { | 423 | { |
500 | struct cmi_spec *spec = codec->spec; | 424 | struct cmi_spec *spec = codec->spec; |
501 | hda_nid_t nid; | 425 | hda_nid_t nid; |
@@ -503,29 +427,26 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec) | |||
503 | 427 | ||
504 | /* clear the table, only one c-media dac assumed here */ | 428 | /* clear the table, only one c-media dac assumed here */ |
505 | memset(spec->multi_init, 0, sizeof(spec->multi_init)); | 429 | memset(spec->multi_init, 0, sizeof(spec->multi_init)); |
506 | for (j = 0, i = 0; i < spec->multiout.max_channels / 2; i++) { | 430 | for (j = 0, i = 0; i < cfg->line_outs; i++) { |
507 | hda_nid_t conn[4]; | 431 | hda_nid_t conn[4]; |
508 | nid = spec->multich_pin[i]; | 432 | nid = cfg->line_out_pins[i]; |
509 | /* set as output */ | 433 | /* set as output */ |
510 | spec->multi_init[j].nid = nid; | 434 | spec->multi_init[j].nid = nid; |
511 | spec->multi_init[j].verb = AC_VERB_SET_PIN_WIDGET_CONTROL; | 435 | spec->multi_init[j].verb = AC_VERB_SET_PIN_WIDGET_CONTROL; |
512 | spec->multi_init[j].param = 0xc0; | 436 | spec->multi_init[j].param = PIN_OUT; |
513 | j++; | 437 | j++; |
514 | /* nid 0x0f,0x10,0x1f,0x20 are needed to set connection */ | 438 | if (nid > 0x0e) { |
515 | switch (nid) { | ||
516 | case 0x0f: | ||
517 | case 0x10: | ||
518 | case 0x1f: | ||
519 | case 0x20: | ||
520 | /* set connection */ | 439 | /* set connection */ |
521 | spec->multi_init[j].nid = nid; | 440 | spec->multi_init[j].nid = nid; |
522 | spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL; | 441 | spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL; |
442 | spec->multi_init[j].param = 0; | ||
523 | /* find the index in connect list */ | 443 | /* find the index in connect list */ |
524 | len = snd_hda_get_connections(codec, nid, conn, 4); | 444 | len = snd_hda_get_connections(codec, nid, conn, 4); |
525 | for (k = 0; k < len; k++) | 445 | for (k = 0; k < len; k++) |
526 | if (conn[k] == spec->dac_nids[i]) | 446 | if (conn[k] == spec->dac_nids[i]) { |
447 | spec->multi_init[j].param = j; | ||
527 | break; | 448 | break; |
528 | spec->multi_init[j].param = k < len ? k : 0; | 449 | } |
529 | j++; | 450 | j++; |
530 | break; | 451 | break; |
531 | } | 452 | } |
@@ -759,6 +680,7 @@ static int patch_cmi9880(struct hda_codec *codec) | |||
759 | 680 | ||
760 | /* copy default DAC NIDs */ | 681 | /* copy default DAC NIDs */ |
761 | memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids)); | 682 | memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids)); |
683 | spec->num_dacs = 4; | ||
762 | 684 | ||
763 | switch (spec->board_config) { | 685 | switch (spec->board_config) { |
764 | case CMI_MINIMAL: | 686 | case CMI_MINIMAL: |
@@ -795,18 +717,16 @@ static int patch_cmi9880(struct hda_codec *codec) | |||
795 | { | 717 | { |
796 | unsigned int port_e, port_f, port_g, port_h; | 718 | unsigned int port_e, port_f, port_g, port_h; |
797 | unsigned int port_spdifi, port_spdifo; | 719 | unsigned int port_spdifi, port_spdifo; |
798 | int max_channels; | 720 | struct auto_pin_cfg cfg; |
721 | |||
799 | /* collect pin default configuration */ | 722 | /* collect pin default configuration */ |
800 | cmi9880_get_pin_def_config(codec); | 723 | port_e = snd_hda_codec_read(codec, 0x0f, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); |
801 | port_e = cmi9880_get_def_config(codec, 0x0f); | 724 | port_f = snd_hda_codec_read(codec, 0x10, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); |
802 | port_f = cmi9880_get_def_config(codec, 0x10); | ||
803 | port_g = cmi9880_get_def_config(codec, 0x1f); | ||
804 | port_h = cmi9880_get_def_config(codec, 0x20); | ||
805 | port_spdifi = cmi9880_get_def_config(codec, 0x13); | ||
806 | port_spdifo = cmi9880_get_def_config(codec, 0x12); | ||
807 | spec->front_panel = 1; | 725 | spec->front_panel = 1; |
808 | if (get_defcfg_connect(port_e) == AC_JACK_PORT_NONE || | 726 | if (get_defcfg_connect(port_e) == AC_JACK_PORT_NONE || |
809 | get_defcfg_connect(port_f) == AC_JACK_PORT_NONE) { | 727 | get_defcfg_connect(port_f) == AC_JACK_PORT_NONE) { |
728 | port_g = snd_hda_codec_read(codec, 0x1f, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
729 | port_h = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
810 | spec->surr_switch = 1; | 730 | spec->surr_switch = 1; |
811 | /* no front panel */ | 731 | /* no front panel */ |
812 | if (get_defcfg_connect(port_g) == AC_JACK_PORT_NONE || | 732 | if (get_defcfg_connect(port_g) == AC_JACK_PORT_NONE || |
@@ -824,24 +744,26 @@ static int patch_cmi9880(struct hda_codec *codec) | |||
824 | spec->multiout.max_channels = cmi9880_channel_modes[0].channels; | 744 | spec->multiout.max_channels = cmi9880_channel_modes[0].channels; |
825 | } else { | 745 | } else { |
826 | spec->input_mux = &cmi9880_basic_mux; | 746 | spec->input_mux = &cmi9880_basic_mux; |
747 | port_spdifi = snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
748 | port_spdifo = snd_hda_codec_read(codec, 0x12, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
827 | if (get_defcfg_connect(port_spdifo) != AC_JACK_PORT_NONE) | 749 | if (get_defcfg_connect(port_spdifo) != AC_JACK_PORT_NONE) |
828 | spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; | 750 | spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; |
829 | if (get_defcfg_connect(port_spdifi) != AC_JACK_PORT_NONE) | 751 | if (get_defcfg_connect(port_spdifi) != AC_JACK_PORT_NONE) |
830 | spec->dig_in_nid = CMI_DIG_IN_NID; | 752 | spec->dig_in_nid = CMI_DIG_IN_NID; |
831 | spec->multiout.max_channels = 8; | 753 | spec->multiout.max_channels = 8; |
832 | } | 754 | } |
833 | max_channels = cmi9880_get_multich_pins(codec); | 755 | snd_hda_parse_pin_def_config(codec, &cfg); |
834 | if (max_channels > 0) { | 756 | if (cfg.line_outs) { |
835 | spec->multiout.max_channels = max_channels; | 757 | spec->multiout.max_channels = cfg.line_outs * 2; |
836 | cmi9880_fill_multi_dac_nids(codec); | 758 | cmi9880_fill_multi_dac_nids(codec, &cfg); |
837 | cmi9880_fill_multi_init(codec); | 759 | cmi9880_fill_multi_init(codec, &cfg); |
838 | } else | 760 | } else |
839 | snd_printd("patch_cmedia: cannot detect association in defcfg\n"); | 761 | snd_printd("patch_cmedia: cannot detect association in defcfg\n"); |
840 | break; | 762 | break; |
841 | } | 763 | } |
842 | } | 764 | } |
843 | 765 | ||
844 | spec->multiout.num_dacs = 4; | 766 | spec->multiout.num_dacs = spec->num_dacs; |
845 | spec->multiout.dac_nids = spec->dac_nids; | 767 | spec->multiout.dac_nids = spec->dac_nids; |
846 | 768 | ||
847 | spec->adc_nids = cmi9880_adc_nids; | 769 | spec->adc_nids = cmi9880_adc_nids; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ce280c006be1..9edd558d6bd3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -39,13 +39,16 @@ enum { | |||
39 | ALC880_5ST_DIG, | 39 | ALC880_5ST_DIG, |
40 | ALC880_W810, | 40 | ALC880_W810, |
41 | ALC880_Z71V, | 41 | ALC880_Z71V, |
42 | ALC880_TEST, | 42 | ALC880_AUTO, |
43 | ALC880_6ST_DIG, | 43 | ALC880_6ST_DIG, |
44 | ALC880_F1734, | 44 | ALC880_F1734, |
45 | ALC880_ASUS, | 45 | ALC880_ASUS, |
46 | ALC880_ASUS_DIG, | 46 | ALC880_ASUS_DIG, |
47 | ALC880_ASUS_W1V, | 47 | ALC880_ASUS_W1V, |
48 | ALC880_UNIWILL_DIG, | 48 | ALC880_UNIWILL_DIG, |
49 | #ifdef CONFIG_SND_DEBUG | ||
50 | ALC880_TEST, | ||
51 | #endif | ||
49 | ALC880_MODEL_LAST /* last tag */ | 52 | ALC880_MODEL_LAST /* last tag */ |
50 | }; | 53 | }; |
51 | 54 | ||
@@ -56,19 +59,28 @@ enum { | |||
56 | ALC260_MODEL_LAST /* last tag */ | 59 | ALC260_MODEL_LAST /* last tag */ |
57 | }; | 60 | }; |
58 | 61 | ||
62 | /* amp values */ | ||
63 | #define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) | ||
64 | #define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8)) | ||
65 | #define AMP_OUT_MUTE 0xb080 | ||
66 | #define AMP_OUT_UNMUTE 0xb000 | ||
67 | #define AMP_OUT_ZERO 0xb000 | ||
68 | /* pinctl values */ | ||
69 | #define PIN_IN 0x20 | ||
70 | #define PIN_VREF80 0x24 | ||
71 | #define PIN_VREF50 0x21 | ||
72 | #define PIN_OUT 0x40 | ||
73 | #define PIN_HP 0xc0 | ||
74 | |||
59 | struct alc_spec { | 75 | struct alc_spec { |
60 | /* codec parameterization */ | 76 | /* codec parameterization */ |
61 | unsigned int front_panel: 1; /* indicates the board has a front panel; | 77 | snd_kcontrol_new_t *mixers[3]; /* mixer arrays */ |
62 | * not referred currently for any purpose, | ||
63 | * though... | ||
64 | */ | ||
65 | |||
66 | snd_kcontrol_new_t *mixers[2]; /* mixer arrays */ | ||
67 | unsigned int num_mixers; | 78 | unsigned int num_mixers; |
68 | 79 | ||
69 | struct hda_verb *init_verbs; /* initialization verbs | 80 | const struct hda_verb *init_verbs[3]; /* initialization verbs |
70 | * don't forget NULL termination! | 81 | * don't forget NULL termination! |
71 | */ | 82 | */ |
83 | unsigned int num_init_verbs; | ||
72 | 84 | ||
73 | char *stream_name_analog; /* analog PCM stream */ | 85 | char *stream_name_analog; /* analog PCM stream */ |
74 | struct hda_pcm_stream *stream_analog_playback; | 86 | struct hda_pcm_stream *stream_analog_playback; |
@@ -101,96 +113,14 @@ struct alc_spec { | |||
101 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ | 113 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ |
102 | 114 | ||
103 | struct semaphore bind_mutex; /* for bound controls */ | 115 | struct semaphore bind_mutex; /* for bound controls */ |
104 | }; | ||
105 | |||
106 | /* DAC/ADC assignment */ | ||
107 | |||
108 | static hda_nid_t alc880_dac_nids[4] = { | ||
109 | /* front, rear, clfe, rear_surr */ | ||
110 | 0x02, 0x05, 0x04, 0x03 | ||
111 | }; | ||
112 | |||
113 | static hda_nid_t alc880_6st_dac_nids[4] = { | ||
114 | /* front, rear, clfe, rear_surr */ | ||
115 | 0x02, 0x03, 0x04, 0x05 | ||
116 | }; | ||
117 | |||
118 | static hda_nid_t alc880_w810_dac_nids[3] = { | ||
119 | /* front, rear/surround, clfe */ | ||
120 | 0x02, 0x03, 0x04 | ||
121 | }; | ||
122 | |||
123 | static hda_nid_t alc880_z71v_dac_nids[1] = { | ||
124 | /* front only? */ | ||
125 | 0x02 | ||
126 | }; | ||
127 | |||
128 | #if 0 | ||
129 | /* The datasheet says the node 0x07 is connected from inputs, | ||
130 | * but it shows zero connection in the real implementation on some devices. | ||
131 | */ | ||
132 | static hda_nid_t alc880_adc_nids[3] = { | ||
133 | /* ADC0-2 */ | ||
134 | 0x07, 0x08, 0x09, | ||
135 | }; | ||
136 | #else | ||
137 | static hda_nid_t alc880_adc_nids[2] = { | ||
138 | /* ADC1-2 */ | ||
139 | 0x08, 0x09, | ||
140 | }; | ||
141 | #endif | ||
142 | |||
143 | #define ALC880_DIGOUT_NID 0x06 | ||
144 | #define ALC880_DIGIN_NID 0x0a | ||
145 | |||
146 | static hda_nid_t alc260_dac_nids[1] = { | ||
147 | /* front */ | ||
148 | 0x02, | ||
149 | }; | ||
150 | |||
151 | static hda_nid_t alc260_adc_nids[1] = { | ||
152 | /* ADC0 */ | ||
153 | 0x04, | ||
154 | }; | ||
155 | |||
156 | static hda_nid_t alc260_hp_adc_nids[1] = { | ||
157 | /* ADC1 */ | ||
158 | 0x05, | ||
159 | }; | ||
160 | 116 | ||
161 | #define ALC260_DIGOUT_NID 0x03 | 117 | /* dynamic controls, init_verbs and input_mux */ |
162 | #define ALC260_DIGIN_NID 0x06 | 118 | struct auto_pin_cfg autocfg; |
163 | 119 | unsigned int num_kctl_alloc, num_kctl_used; | |
164 | static struct hda_input_mux alc880_capture_source = { | 120 | snd_kcontrol_new_t *kctl_alloc; |
165 | .num_items = 4, | 121 | struct hda_input_mux private_imux; |
166 | .items = { | ||
167 | { "Mic", 0x0 }, | ||
168 | { "Front Mic", 0x3 }, | ||
169 | { "Line", 0x2 }, | ||
170 | { "CD", 0x4 }, | ||
171 | }, | ||
172 | }; | 122 | }; |
173 | 123 | ||
174 | //pshou 05/24/05 | ||
175 | static struct hda_input_mux alc880_6stack_capture_source = { | ||
176 | .num_items = 4, | ||
177 | .items = { | ||
178 | { "Mic", 0x0 }, | ||
179 | { "Front Mic", 0x1 }, | ||
180 | { "Line", 0x2 }, | ||
181 | { "CD", 0x4 }, | ||
182 | }, | ||
183 | }; | ||
184 | |||
185 | static struct hda_input_mux alc260_capture_source = { | ||
186 | .num_items = 4, | ||
187 | .items = { | ||
188 | { "Mic", 0x0 }, | ||
189 | { "Front Mic", 0x1 }, | ||
190 | { "Line", 0x2 }, | ||
191 | { "CD", 0x4 }, | ||
192 | }, | ||
193 | }; | ||
194 | 124 | ||
195 | /* | 125 | /* |
196 | * input MUX handling | 126 | * input MUX handling |
@@ -221,6 +151,7 @@ static int alc_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucon | |||
221 | spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]); | 151 | spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]); |
222 | } | 152 | } |
223 | 153 | ||
154 | |||
224 | /* | 155 | /* |
225 | * channel mode setting | 156 | * channel mode setting |
226 | */ | 157 | */ |
@@ -229,133 +160,6 @@ struct alc_channel_mode { | |||
229 | const struct hda_verb *sequence; | 160 | const struct hda_verb *sequence; |
230 | }; | 161 | }; |
231 | 162 | ||
232 | |||
233 | /* | ||
234 | * channel source setting (2/6 channel selection for 3-stack) | ||
235 | */ | ||
236 | |||
237 | /* | ||
238 | * set the path ways for 2 channel output | ||
239 | * need to set the codec line out and mic 1 pin widgets to inputs | ||
240 | */ | ||
241 | static struct hda_verb alc880_threestack_ch2_init[] = { | ||
242 | /* set pin widget 1Ah (line in) for input */ | ||
243 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
244 | /* set pin widget 18h (mic1) for input, for mic also enable the vref */ | ||
245 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
246 | /* mute the output for Line In PW */ | ||
247 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, | ||
248 | /* mute for Mic1 PW */ | ||
249 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, | ||
250 | { } /* end */ | ||
251 | }; | ||
252 | |||
253 | /* | ||
254 | * 6ch mode | ||
255 | * need to set the codec line out and mic 1 pin widgets to outputs | ||
256 | */ | ||
257 | static struct hda_verb alc880_threestack_ch6_init[] = { | ||
258 | /* set pin widget 1Ah (line in) for output */ | ||
259 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
260 | /* set pin widget 18h (mic1) for output */ | ||
261 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
262 | /* unmute the output for Line In PW */ | ||
263 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 }, | ||
264 | /* unmute for Mic1 PW */ | ||
265 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 }, | ||
266 | /* for rear channel output using Line In 1 | ||
267 | * set select widget connection (nid = 0x12) - to summer node | ||
268 | * for rear NID = 0x0f...offset 3 in connection list | ||
269 | */ | ||
270 | { 0x12, AC_VERB_SET_CONNECT_SEL, 0x3 }, | ||
271 | /* for Mic1 - retask for center/lfe */ | ||
272 | /* set select widget connection (nid = 0x10) - to summer node for | ||
273 | * front CLFE NID = 0x0e...offset 2 in connection list | ||
274 | */ | ||
275 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x2 }, | ||
276 | { } /* end */ | ||
277 | }; | ||
278 | |||
279 | static struct alc_channel_mode alc880_threestack_modes[2] = { | ||
280 | { 2, alc880_threestack_ch2_init }, | ||
281 | { 6, alc880_threestack_ch6_init }, | ||
282 | }; | ||
283 | |||
284 | |||
285 | /* | ||
286 | * channel source setting (6/8 channel selection for 5-stack) | ||
287 | */ | ||
288 | |||
289 | /* set the path ways for 6 channel output | ||
290 | * need to set the codec line out and mic 1 pin widgets to inputs | ||
291 | */ | ||
292 | static struct hda_verb alc880_fivestack_ch6_init[] = { | ||
293 | /* set pin widget 1Ah (line in) for input */ | ||
294 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
295 | /* mute the output for Line In PW */ | ||
296 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, | ||
297 | { } /* end */ | ||
298 | }; | ||
299 | |||
300 | /* need to set the codec line out and mic 1 pin widgets to outputs */ | ||
301 | static struct hda_verb alc880_fivestack_ch8_init[] = { | ||
302 | /* set pin widget 1Ah (line in) for output */ | ||
303 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
304 | /* unmute the output for Line In PW */ | ||
305 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 }, | ||
306 | /* output for surround channel output using Line In 1 */ | ||
307 | /* set select widget connection (nid = 0x12) - to summer node | ||
308 | * for surr_rear NID = 0x0d...offset 1 in connection list | ||
309 | */ | ||
310 | { 0x12, AC_VERB_SET_CONNECT_SEL, 0x1 }, | ||
311 | { } /* end */ | ||
312 | }; | ||
313 | |||
314 | static struct alc_channel_mode alc880_fivestack_modes[2] = { | ||
315 | { 6, alc880_fivestack_ch6_init }, | ||
316 | { 8, alc880_fivestack_ch8_init }, | ||
317 | }; | ||
318 | |||
319 | /* | ||
320 | * channel source setting for W810 system | ||
321 | * | ||
322 | * W810 has rear IO for: | ||
323 | * Front (DAC 02) | ||
324 | * Surround (DAC 03) | ||
325 | * Center/LFE (DAC 04) | ||
326 | * Digital out (06) | ||
327 | * | ||
328 | * The system also has a pair of internal speakers, and a headphone jack. | ||
329 | * These are both connected to Line2 on the codec, hence to DAC 02. | ||
330 | * | ||
331 | * There is a variable resistor to control the speaker or headphone | ||
332 | * volume. This is a hardware-only device without a software API. | ||
333 | * | ||
334 | * Plugging headphones in will disable the internal speakers. This is | ||
335 | * implemented in hardware, not via the driver using jack sense. In | ||
336 | * a similar fashion, plugging into the rear socket marked "front" will | ||
337 | * disable both the speakers and headphones. | ||
338 | * | ||
339 | * For input, there's a microphone jack, and an "audio in" jack. | ||
340 | * These may not do anything useful with this driver yet, because I | ||
341 | * haven't setup any initialization verbs for these yet... | ||
342 | */ | ||
343 | |||
344 | static struct alc_channel_mode alc880_w810_modes[1] = { | ||
345 | { 6, NULL } | ||
346 | }; | ||
347 | |||
348 | static struct alc_channel_mode alc880_z71v_modes[1] = { | ||
349 | { 2, NULL } | ||
350 | }; | ||
351 | |||
352 | //pshou 05/19/05 | ||
353 | static struct alc_channel_mode alc880_sixstack_modes[1] = { | ||
354 | { 8, NULL }, | ||
355 | }; | ||
356 | |||
357 | /* | ||
358 | */ | ||
359 | static int alc880_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) | 163 | static int alc880_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) |
360 | { | 164 | { |
361 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 165 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
@@ -478,67 +282,75 @@ static int alc_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u | |||
478 | 282 | ||
479 | #define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir) | 283 | #define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir) |
480 | 284 | ||
285 | |||
481 | /* | 286 | /* |
287 | * ALC880 3-stack model | ||
288 | * | ||
289 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) | ||
290 | * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, F-Mic = 0x1b | ||
291 | * HP = 0x19 | ||
482 | */ | 292 | */ |
483 | 293 | ||
484 | /* 3-stack mode | 294 | static hda_nid_t alc880_dac_nids[4] = { |
485 | * Pin assignment: Front=0x14, Line-In/Rear=0x1a, Mic/CLFE=0x18, F-Mic=0x1b | 295 | /* front, rear, clfe, rear_surr */ |
486 | * HP=0x19 | 296 | 0x02, 0x05, 0x04, 0x03 |
297 | }; | ||
298 | |||
299 | static hda_nid_t alc880_adc_nids[3] = { | ||
300 | /* ADC0-2 */ | ||
301 | 0x07, 0x08, 0x09, | ||
302 | }; | ||
303 | |||
304 | /* The datasheet says the node 0x07 is connected from inputs, | ||
305 | * but it shows zero connection in the real implementation on some devices. | ||
487 | */ | 306 | */ |
488 | static snd_kcontrol_new_t alc880_base_mixer[] = { | 307 | static hda_nid_t alc880_adc_nids_alt[2] = { |
489 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 308 | /* ADC1-2 */ |
490 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 309 | 0x08, 0x09, |
491 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 310 | }; |
492 | ALC_BIND_MUTE("Surround Playback Switch", 0x1a, 2, HDA_INPUT), | 311 | |
493 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 312 | #define ALC880_DIGOUT_NID 0x06 |
494 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 313 | #define ALC880_DIGIN_NID 0x0a |
495 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 314 | |
496 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 315 | static struct hda_input_mux alc880_capture_source = { |
497 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 316 | .num_items = 4, |
498 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 317 | .items = { |
499 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 318 | { "Mic", 0x0 }, |
500 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 319 | { "Front Mic", 0x3 }, |
501 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 320 | { "Line", 0x2 }, |
502 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 321 | { "CD", 0x4 }, |
503 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), | ||
504 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), | ||
505 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
506 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
507 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
508 | ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), | ||
509 | /* We don't use NID 0x07 - see above */ | ||
510 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
511 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
512 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
513 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
514 | { | ||
515 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
516 | /* The multiple "Capture Source" controls confuse alsamixer | ||
517 | * So call somewhat different.. | ||
518 | * FIXME: the controls appear in the "playback" view! | ||
519 | */ | ||
520 | /* .name = "Capture Source", */ | ||
521 | .name = "Input Source", | ||
522 | .count = 2, | ||
523 | .info = alc_mux_enum_info, | ||
524 | .get = alc_mux_enum_get, | ||
525 | .put = alc_mux_enum_put, | ||
526 | }, | ||
527 | { | ||
528 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
529 | .name = "Channel Mode", | ||
530 | .info = alc880_ch_mode_info, | ||
531 | .get = alc880_ch_mode_get, | ||
532 | .put = alc880_ch_mode_put, | ||
533 | }, | 322 | }, |
323 | }; | ||
324 | |||
325 | /* channel source setting (2/6 channel selection for 3-stack) */ | ||
326 | /* 2ch mode */ | ||
327 | static struct hda_verb alc880_threestack_ch2_init[] = { | ||
328 | /* set line-in to input, mute it */ | ||
329 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
330 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
331 | /* set mic-in to input vref 80%, mute it */ | ||
332 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
333 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
534 | { } /* end */ | 334 | { } /* end */ |
535 | }; | 335 | }; |
536 | 336 | ||
537 | /* 5-stack mode | 337 | /* 6ch mode */ |
538 | * Pin assignment: Front=0x14, Rear=0x17, CLFE=0x16 | 338 | static struct hda_verb alc880_threestack_ch6_init[] = { |
539 | * Line-In/Side=0x1a, Mic=0x18, F-Mic=0x1b, HP=0x19 | 339 | /* set line-in to output, unmute it */ |
540 | */ | 340 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
541 | static snd_kcontrol_new_t alc880_five_stack_mixer[] = { | 341 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
342 | /* set mic-in to output, unmute it */ | ||
343 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
344 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
345 | { } /* end */ | ||
346 | }; | ||
347 | |||
348 | static struct alc_channel_mode alc880_threestack_modes[2] = { | ||
349 | { 2, alc880_threestack_ch2_init }, | ||
350 | { 6, alc880_threestack_ch6_init }, | ||
351 | }; | ||
352 | |||
353 | static snd_kcontrol_new_t alc880_three_stack_mixer[] = { | ||
542 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 354 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
543 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 355 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
544 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 356 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
@@ -547,8 +359,6 @@ static snd_kcontrol_new_t alc880_five_stack_mixer[] = { | |||
547 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 359 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
548 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 360 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
549 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 361 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
550 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
551 | ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), | ||
552 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 362 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
553 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 363 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
554 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 364 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
@@ -559,26 +369,7 @@ static snd_kcontrol_new_t alc880_five_stack_mixer[] = { | |||
559 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), | 369 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), |
560 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | 370 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), |
561 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | 371 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), |
562 | /* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), */ | ||
563 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), | 372 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), |
564 | /* We don't use NID 0x07 - see above */ | ||
565 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
566 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
567 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
568 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
569 | { | ||
570 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
571 | /* The multiple "Capture Source" controls confuse alsamixer | ||
572 | * So call somewhat different.. | ||
573 | * FIXME: the controls appear in the "playback" view! | ||
574 | */ | ||
575 | /* .name = "Capture Source", */ | ||
576 | .name = "Input Source", | ||
577 | .count = 2, | ||
578 | .info = alc_mux_enum_info, | ||
579 | .get = alc_mux_enum_get, | ||
580 | .put = alc_mux_enum_put, | ||
581 | }, | ||
582 | { | 373 | { |
583 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 374 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
584 | .name = "Channel Mode", | 375 | .name = "Channel Mode", |
@@ -589,16 +380,8 @@ static snd_kcontrol_new_t alc880_five_stack_mixer[] = { | |||
589 | { } /* end */ | 380 | { } /* end */ |
590 | }; | 381 | }; |
591 | 382 | ||
592 | static snd_kcontrol_new_t alc880_w810_base_mixer[] = { | 383 | /* capture mixer elements */ |
593 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 384 | static snd_kcontrol_new_t alc880_capture_mixer[] = { |
594 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
595 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
596 | HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
597 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
598 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
599 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT), | ||
600 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), | ||
601 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
602 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | 385 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), |
603 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | 386 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), |
604 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), | 387 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), |
@@ -621,21 +404,12 @@ static snd_kcontrol_new_t alc880_w810_base_mixer[] = { | |||
621 | { } /* end */ | 404 | { } /* end */ |
622 | }; | 405 | }; |
623 | 406 | ||
624 | static snd_kcontrol_new_t alc880_z71v_mixer[] = { | 407 | /* capture mixer elements (in case NID 0x07 not available) */ |
625 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 408 | static snd_kcontrol_new_t alc880_capture_alt_mixer[] = { |
626 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 409 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
627 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 410 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
628 | ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), | 411 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), |
629 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 412 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), |
630 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
631 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
632 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
633 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | ||
634 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | ||
635 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), | ||
636 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), | ||
637 | HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), | ||
638 | HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), | ||
639 | { | 413 | { |
640 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 414 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
641 | /* The multiple "Capture Source" controls confuse alsamixer | 415 | /* The multiple "Capture Source" controls confuse alsamixer |
@@ -644,7 +418,7 @@ static snd_kcontrol_new_t alc880_z71v_mixer[] = { | |||
644 | */ | 418 | */ |
645 | /* .name = "Capture Source", */ | 419 | /* .name = "Capture Source", */ |
646 | .name = "Input Source", | 420 | .name = "Input Source", |
647 | .count = 3, | 421 | .count = 2, |
648 | .info = alc_mux_enum_info, | 422 | .info = alc_mux_enum_info, |
649 | .get = alc_mux_enum_get, | 423 | .get = alc_mux_enum_get, |
650 | .put = alc_mux_enum_put, | 424 | .put = alc_mux_enum_put, |
@@ -652,7 +426,74 @@ static snd_kcontrol_new_t alc880_z71v_mixer[] = { | |||
652 | { } /* end */ | 426 | { } /* end */ |
653 | }; | 427 | }; |
654 | 428 | ||
655 | //pshou 05/24/05 | 429 | |
430 | |||
431 | /* | ||
432 | * ALC880 5-stack model | ||
433 | * | ||
434 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), Side = 0x02 (0xd) | ||
435 | * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 | ||
436 | * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 | ||
437 | */ | ||
438 | |||
439 | /* additional mixers to alc880_three_stack_mixer */ | ||
440 | static snd_kcontrol_new_t alc880_five_stack_mixer[] = { | ||
441 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
442 | ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), | ||
443 | { } /* end */ | ||
444 | }; | ||
445 | |||
446 | /* channel source setting (6/8 channel selection for 5-stack) */ | ||
447 | /* 6ch mode */ | ||
448 | static struct hda_verb alc880_fivestack_ch6_init[] = { | ||
449 | /* set line-in to input, mute it */ | ||
450 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
451 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
452 | { } /* end */ | ||
453 | }; | ||
454 | |||
455 | /* 8ch mode */ | ||
456 | static struct hda_verb alc880_fivestack_ch8_init[] = { | ||
457 | /* set line-in to output, unmute it */ | ||
458 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
459 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
460 | { } /* end */ | ||
461 | }; | ||
462 | |||
463 | static struct alc_channel_mode alc880_fivestack_modes[2] = { | ||
464 | { 6, alc880_fivestack_ch6_init }, | ||
465 | { 8, alc880_fivestack_ch8_init }, | ||
466 | }; | ||
467 | |||
468 | |||
469 | /* | ||
470 | * ALC880 6-stack model | ||
471 | * | ||
472 | * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), Side = 0x05 (0x0f) | ||
473 | * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, | ||
474 | * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b | ||
475 | */ | ||
476 | |||
477 | static hda_nid_t alc880_6st_dac_nids[4] = { | ||
478 | /* front, rear, clfe, rear_surr */ | ||
479 | 0x02, 0x03, 0x04, 0x05 | ||
480 | }; | ||
481 | |||
482 | static struct hda_input_mux alc880_6stack_capture_source = { | ||
483 | .num_items = 4, | ||
484 | .items = { | ||
485 | { "Mic", 0x0 }, | ||
486 | { "Front Mic", 0x1 }, | ||
487 | { "Line", 0x2 }, | ||
488 | { "CD", 0x4 }, | ||
489 | }, | ||
490 | }; | ||
491 | |||
492 | /* fixed 8-channels */ | ||
493 | static struct alc_channel_mode alc880_sixstack_modes[1] = { | ||
494 | { 8, NULL }, | ||
495 | }; | ||
496 | |||
656 | static snd_kcontrol_new_t alc880_six_stack_mixer[] = { | 497 | static snd_kcontrol_new_t alc880_six_stack_mixer[] = { |
657 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 498 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
658 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 499 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
@@ -674,25 +515,6 @@ static snd_kcontrol_new_t alc880_six_stack_mixer[] = { | |||
674 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 515 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
675 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | 516 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), |
676 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | 517 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), |
677 | /* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), */ | ||
678 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
679 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | ||
680 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | ||
681 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), | ||
682 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), | ||
683 | { | ||
684 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
685 | /* The multiple "Capture Source" controls confuse alsamixer | ||
686 | * So call somewhat different.. | ||
687 | * FIXME: the controls appear in the "playback" view! | ||
688 | */ | ||
689 | /* .name = "Capture Source", */ | ||
690 | .name = "Input Source", | ||
691 | .count = 2, | ||
692 | .info = alc_mux_enum_info, | ||
693 | .get = alc_mux_enum_get, | ||
694 | .put = alc_mux_enum_put, | ||
695 | }, | ||
696 | { | 518 | { |
697 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 519 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
698 | .name = "Channel Mode", | 520 | .name = "Channel Mode", |
@@ -703,8 +525,101 @@ static snd_kcontrol_new_t alc880_six_stack_mixer[] = { | |||
703 | { } /* end */ | 525 | { } /* end */ |
704 | }; | 526 | }; |
705 | 527 | ||
706 | // 03/08/05 Fujitsu | 528 | |
707 | static snd_kcontrol_new_t alc880_2_jack_mixer[] = { | 529 | /* |
530 | * ALC880 W810 model | ||
531 | * | ||
532 | * W810 has rear IO for: | ||
533 | * Front (DAC 02) | ||
534 | * Surround (DAC 03) | ||
535 | * Center/LFE (DAC 04) | ||
536 | * Digital out (06) | ||
537 | * | ||
538 | * The system also has a pair of internal speakers, and a headphone jack. | ||
539 | * These are both connected to Line2 on the codec, hence to DAC 02. | ||
540 | * | ||
541 | * There is a variable resistor to control the speaker or headphone | ||
542 | * volume. This is a hardware-only device without a software API. | ||
543 | * | ||
544 | * Plugging headphones in will disable the internal speakers. This is | ||
545 | * implemented in hardware, not via the driver using jack sense. In | ||
546 | * a similar fashion, plugging into the rear socket marked "front" will | ||
547 | * disable both the speakers and headphones. | ||
548 | * | ||
549 | * For input, there's a microphone jack, and an "audio in" jack. | ||
550 | * These may not do anything useful with this driver yet, because I | ||
551 | * haven't setup any initialization verbs for these yet... | ||
552 | */ | ||
553 | |||
554 | static hda_nid_t alc880_w810_dac_nids[3] = { | ||
555 | /* front, rear/surround, clfe */ | ||
556 | 0x02, 0x03, 0x04 | ||
557 | }; | ||
558 | |||
559 | /* fixed 6 channels */ | ||
560 | static struct alc_channel_mode alc880_w810_modes[1] = { | ||
561 | { 6, NULL } | ||
562 | }; | ||
563 | |||
564 | /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ | ||
565 | static snd_kcontrol_new_t alc880_w810_base_mixer[] = { | ||
566 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
567 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
568 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
569 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
570 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
571 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
572 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
573 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
574 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
575 | { } /* end */ | ||
576 | }; | ||
577 | |||
578 | |||
579 | /* | ||
580 | * Z710V model | ||
581 | * | ||
582 | * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) | ||
583 | * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), Line = 0x1a | ||
584 | */ | ||
585 | |||
586 | static hda_nid_t alc880_z71v_dac_nids[1] = { | ||
587 | 0x02 | ||
588 | }; | ||
589 | #define ALC880_Z71V_HP_DAC 0x03 | ||
590 | |||
591 | /* fixed 2 channels */ | ||
592 | static struct alc_channel_mode alc880_2_jack_modes[1] = { | ||
593 | { 2, NULL } | ||
594 | }; | ||
595 | |||
596 | static snd_kcontrol_new_t alc880_z71v_mixer[] = { | ||
597 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
598 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
599 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
600 | ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), | ||
601 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
602 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
603 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
604 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
605 | { } /* end */ | ||
606 | }; | ||
607 | |||
608 | |||
609 | /* FIXME! */ | ||
610 | /* | ||
611 | * ALC880 F1734 model | ||
612 | * | ||
613 | * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) | ||
614 | * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 | ||
615 | */ | ||
616 | |||
617 | static hda_nid_t alc880_f1734_dac_nids[1] = { | ||
618 | 0x03 | ||
619 | }; | ||
620 | #define ALC880_F1734_HP_DAC 0x02 | ||
621 | |||
622 | static snd_kcontrol_new_t alc880_f1734_mixer[] = { | ||
708 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 623 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
709 | ALC_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | 624 | ALC_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), |
710 | HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 625 | HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -713,25 +628,22 @@ static snd_kcontrol_new_t alc880_2_jack_mixer[] = { | |||
713 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 628 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
714 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 629 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
715 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 630 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
716 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | ||
717 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | ||
718 | { | ||
719 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
720 | /* The multiple "Capture Source" controls confuse alsamixer | ||
721 | * So call somewhat different.. | ||
722 | * FIXME: the controls appear in the "playback" view! | ||
723 | */ | ||
724 | /* .name = "Capture Source", */ | ||
725 | .name = "Input Source", | ||
726 | .count = 1, | ||
727 | .info = alc_mux_enum_info, | ||
728 | .get = alc_mux_enum_get, | ||
729 | .put = alc_mux_enum_put, | ||
730 | }, | ||
731 | { } /* end */ | 631 | { } /* end */ |
732 | }; | 632 | }; |
733 | 633 | ||
734 | //pshou 04/24/05 | 634 | |
635 | /* FIXME! */ | ||
636 | /* | ||
637 | * ALC880 ASUS model | ||
638 | * | ||
639 | * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) | ||
640 | * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, | ||
641 | * Mic = 0x18, Line = 0x1a | ||
642 | */ | ||
643 | |||
644 | #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ | ||
645 | #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ | ||
646 | |||
735 | static snd_kcontrol_new_t alc880_asus_mixer[] = { | 647 | static snd_kcontrol_new_t alc880_asus_mixer[] = { |
736 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 648 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
737 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 649 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
@@ -747,23 +659,6 @@ static snd_kcontrol_new_t alc880_asus_mixer[] = { | |||
747 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 659 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
748 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 660 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
749 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 661 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
750 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | ||
751 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | ||
752 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), | ||
753 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), | ||
754 | { | ||
755 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
756 | /* The multiple "Capture Source" controls confuse alsamixer | ||
757 | * So call somewhat different.. | ||
758 | * FIXME: the controls appear in the "playback" view! | ||
759 | */ | ||
760 | /* .name = "Capture Source", */ | ||
761 | .name = "Input Source", | ||
762 | .count = 2, | ||
763 | .info = alc_mux_enum_info, | ||
764 | .get = alc_mux_enum_get, | ||
765 | .put = alc_mux_enum_put, | ||
766 | }, | ||
767 | { | 662 | { |
768 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 663 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
769 | .name = "Channel Mode", | 664 | .name = "Channel Mode", |
@@ -774,51 +669,25 @@ static snd_kcontrol_new_t alc880_asus_mixer[] = { | |||
774 | { } /* end */ | 669 | { } /* end */ |
775 | }; | 670 | }; |
776 | 671 | ||
777 | // pshou 05/03/05 | 672 | /* FIXME! */ |
673 | /* | ||
674 | * ALC880 ASUS W1V model | ||
675 | * | ||
676 | * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) | ||
677 | * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, | ||
678 | * Mic = 0x18, Line = 0x1a, Line2 = 0x1b | ||
679 | */ | ||
680 | |||
681 | /* additional mixers to alc880_asus_mixer */ | ||
778 | static snd_kcontrol_new_t alc880_asus_w1v_mixer[] = { | 682 | static snd_kcontrol_new_t alc880_asus_w1v_mixer[] = { |
779 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
780 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
781 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
782 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
783 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
784 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
785 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
786 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
787 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
788 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
789 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
790 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
791 | HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), | 683 | HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), |
792 | HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), | 684 | HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), |
793 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
794 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
795 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | ||
796 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | ||
797 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), | ||
798 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), | ||
799 | { | ||
800 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
801 | /* The multiple "Capture Source" controls confuse alsamixer | ||
802 | * So call somewhat different.. | ||
803 | * FIXME: the controls appear in the "playback" view! | ||
804 | */ | ||
805 | /* .name = "Capture Source", */ | ||
806 | .name = "Input Source", | ||
807 | .count = 2, | ||
808 | .info = alc_mux_enum_info, | ||
809 | .get = alc_mux_enum_get, | ||
810 | .put = alc_mux_enum_put, | ||
811 | }, | ||
812 | { | ||
813 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
814 | .name = "Channel Mode", | ||
815 | .info = alc880_ch_mode_info, | ||
816 | .get = alc880_ch_mode_get, | ||
817 | .put = alc880_ch_mode_put, | ||
818 | }, | ||
819 | { } /* end */ | 685 | { } /* end */ |
820 | }; | 686 | }; |
687 | |||
688 | |||
821 | /* | 689 | /* |
690 | * build control elements | ||
822 | */ | 691 | */ |
823 | static int alc_build_controls(struct hda_codec *codec) | 692 | static int alc_build_controls(struct hda_codec *codec) |
824 | { | 693 | { |
@@ -845,453 +714,297 @@ static int alc_build_controls(struct hda_codec *codec) | |||
845 | return 0; | 714 | return 0; |
846 | } | 715 | } |
847 | 716 | ||
717 | |||
848 | /* | 718 | /* |
849 | * initialize the codec volumes, etc | 719 | * initialize the codec volumes, etc |
850 | */ | 720 | */ |
851 | 721 | ||
852 | #define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) | 722 | /* |
853 | #define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8)) | 723 | * generic initialization of ADC, input mixers and output mixers |
854 | #define AMP_OUT_MUTE 0xb080 | 724 | */ |
855 | #define AMP_OUT_UNMUTE 0xb000 | 725 | static struct hda_verb alc880_volume_init_verbs[] = { |
856 | #define AMP_OUT_ZERO 0xb000 | 726 | /* |
857 | #define PIN_IN 0x20 | 727 | * Unmute ADC0-2 and set the default input to mic-in |
858 | #define PIN_VREF80 0x24 | 728 | */ |
859 | #define PIN_VREF50 0x21 | ||
860 | #define PIN_OUT 0x40 | ||
861 | #define PIN_HP 0xc0 | ||
862 | |||
863 | static struct hda_verb alc880_init_verbs_three_stack[] = { | ||
864 | /* Set pin widgets for output */ | ||
865 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
866 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
867 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
868 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
869 | /* Line In pin widget for input */ | ||
870 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
871 | /* CD pin widget for input */ | ||
872 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
873 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
874 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
875 | /* Mic2 (front panel) pin widget for input and vref at 80% */ | ||
876 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
877 | /* unmute capture amp left and right */ | ||
878 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
879 | /* set connection select to mic in */ | ||
880 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | 729 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, |
881 | /* unmute capture1 amp left and right */ | 730 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
882 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
883 | /* set connection select to mic in */ | ||
884 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | 731 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, |
885 | /* unmute capture2 amp left and right */ | 732 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
886 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
887 | /* set connection select to mic in */ | ||
888 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | 733 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, |
889 | /* set vol=0 front mixer amp */ | 734 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
890 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
891 | /* unmute front-out pin widget amp (no gain on this amp) */ | ||
892 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
893 | /* set vol=0 rear mixer amp */ | ||
894 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
895 | /* mute line-in pin widget amp left and right (no gain on this amp) */ | ||
896 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
897 | /* set vol=0 clfe mixer amp */ | ||
898 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
899 | /* mute mic pin widget amp left and right (no gain on this amp) */ | ||
900 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
901 | |||
902 | /* using rear surround as the path for headphone output */ | ||
903 | /* set vol=0 rear surround mixer amp */ | ||
904 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
905 | /* PASD 3 stack boards use the Mic 2 as the headphone output */ | ||
906 | /* need to program the selector associated with the Mic 2 pin widget to | ||
907 | * surround path (index 0x01) for headphone output */ | ||
908 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
909 | /* unmute pin widget amp left and right (no gain on this amp) */ | ||
910 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
911 | /* need to retask the Mic 2 pin widget to output */ | ||
912 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
913 | 735 | ||
914 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer widget(nid=0x0B) | 736 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
915 | * to support the input path of analog loopback | 737 | * mixer widget |
916 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 738 | * Note: PASD motherboards uses the Line In 2 as the input for front panel |
917 | * mic (mic 2) | 739 | * mic (mic 2) |
918 | */ | 740 | */ |
919 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ | 741 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
920 | /* mute CD */ | ||
921 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
922 | /* unmute Line In */ | ||
923 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
924 | /* mute Mic 1 */ | ||
925 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 742 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
926 | /* mute Line In 2 (for PASD boards Mic 2) */ | 743 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
927 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 744 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
745 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
746 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
928 | 747 | ||
929 | /* Unmute input amps for the line out paths to support the output path of | 748 | /* |
930 | * analog loopback | 749 | * Set up output mixers (0x0c - 0x0f) |
931 | * the mixers on the output path has 2 inputs, one from the DAC and one | ||
932 | * from the mixer | ||
933 | */ | 750 | */ |
934 | /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ | 751 | /* set vol=0 to output mixers */ |
935 | /* Unmute Front out path */ | 752 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
753 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
754 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
755 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
756 | /* set up input amps for analog loopback */ | ||
757 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
936 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 758 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
937 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 759 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
938 | /* Unmute Surround (used as HP) out path */ | ||
939 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 760 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
940 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 761 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
941 | /* Unmute C/LFE out path */ | ||
942 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 762 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
943 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 763 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
944 | /* Unmute rear Surround out path */ | ||
945 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 764 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
946 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 765 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
947 | 766 | ||
948 | { } | 767 | { } |
949 | }; | 768 | }; |
950 | 769 | ||
951 | static struct hda_verb alc880_init_verbs_five_stack[] = { | 770 | /* |
952 | /* Set pin widgets for output */ | 771 | * 3-stack pin configuration: |
772 | * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b | ||
773 | */ | ||
774 | static struct hda_verb alc880_pin_3stack_init_verbs[] = { | ||
775 | /* | ||
776 | * preset connection lists of input pins | ||
777 | * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround | ||
778 | */ | ||
779 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ | ||
780 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
781 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ | ||
782 | |||
783 | /* | ||
784 | * Set pin mode and muting | ||
785 | */ | ||
786 | /* set front pin widgets 0x14 for output */ | ||
953 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 787 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
954 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 788 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
955 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 789 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ |
956 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 790 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
791 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
792 | /* Mic2 (as headphone out) for HP output */ | ||
793 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
794 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
957 | /* Line In pin widget for input */ | 795 | /* Line In pin widget for input */ |
958 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 796 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
797 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
798 | /* Line2 (as front mic) pin widget for input and vref at 80% */ | ||
799 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
800 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
959 | /* CD pin widget for input */ | 801 | /* CD pin widget for input */ |
960 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 802 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
961 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
962 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
963 | /* Mic2 (front panel) pin widget for input and vref at 80% */ | ||
964 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
965 | /* mute capture amp left and right */ | ||
966 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
967 | /* set connection select to mic in */ | ||
968 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
969 | /* mute amp1 left and right */ | ||
970 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
971 | /* set connection select to mic in */ | ||
972 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
973 | /* mute amp left and right */ | ||
974 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
975 | /* set connection select to mic in */ | ||
976 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
977 | /* set vol=0 front mixer amp */ | ||
978 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
979 | /* unmute front-out pin widget amp (no gain on this amp) */ | ||
980 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
981 | /* set vol=0 rear mixer amp */ | ||
982 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
983 | /* unmute rear-out pin widget (no gain on this amp) */ | ||
984 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
985 | /* set vol=0 clfe mixer amp */ | ||
986 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
987 | /* unmute clfe-pin widget amp (no gain on this amp) */ | ||
988 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
989 | 803 | ||
990 | /* using rear surround as the path for headphone output */ | 804 | { } |
991 | /* set vol=0 rear surround mixer amp */ | 805 | }; |
992 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
993 | /* PASD 3 stack boards use the Mic 2 as the headphone output */ | ||
994 | /* need to program the selector associated with the Mic 2 pin widget to | ||
995 | * surround path (index 0x01) for headphone output | ||
996 | */ | ||
997 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
998 | /* mute pin widget amp left and right (no gain on this amp) */ | ||
999 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1000 | /* need to retask the Mic 2 pin widget to output */ | ||
1001 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
1002 | 806 | ||
1003 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer | 807 | /* |
1004 | * widget(nid=0x0B) to support the input path of analog loopback | 808 | * 5-stack pin configuration: |
809 | * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, | ||
810 | * line-in/side = 0x1a, f-mic = 0x1b | ||
811 | */ | ||
812 | static struct hda_verb alc880_pin_5stack_init_verbs[] = { | ||
813 | /* | ||
814 | * preset connection lists of input pins | ||
815 | * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround | ||
1005 | */ | 816 | */ |
1006 | /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */ | 817 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
1007 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/ | 818 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ |
1008 | /* unmute CD */ | ||
1009 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
1010 | /* unmute Line In */ | ||
1011 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
1012 | /* unmute Mic 1 */ | ||
1013 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1014 | /* unmute Line In 2 (for PASD boards Mic 2) */ | ||
1015 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
1016 | 819 | ||
1017 | /* Unmute input amps for the line out paths to support the output path of | 820 | /* |
1018 | * analog loopback | 821 | * Set pin mode and muting |
1019 | * the mixers on the output path has 2 inputs, one from the DAC and | ||
1020 | * one from the mixer | ||
1021 | */ | 822 | */ |
1022 | /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ | 823 | /* set pin widgets 0x14-0x17 for output */ |
1023 | /* Unmute Front out path */ | 824 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1024 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 825 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1025 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 826 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1026 | /* Unmute Surround (used as HP) out path */ | 827 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1027 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 828 | /* unmute pins for output (no gain on this amp) */ |
1028 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 829 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1029 | /* Unmute C/LFE out path */ | 830 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1030 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 831 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1031 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 832 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1032 | /* Unmute rear Surround out path */ | 833 | |
1033 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 834 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ |
1034 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 835 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
836 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
837 | /* Mic2 (as headphone out) for HP output */ | ||
838 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
839 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
840 | /* Line In pin widget for input */ | ||
841 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
842 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
843 | /* Line2 (as front mic) pin widget for input and vref at 80% */ | ||
844 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
845 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
846 | /* CD pin widget for input */ | ||
847 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1035 | 848 | ||
1036 | { } | 849 | { } |
1037 | }; | 850 | }; |
1038 | 851 | ||
1039 | static struct hda_verb alc880_w810_init_verbs[] = { | 852 | /* |
1040 | /* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */ | 853 | * W810 pin configuration: |
1041 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 854 | * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b |
1042 | 855 | */ | |
1043 | /* front channel selector/amp: input 1: capture mix: muted, (no volume selection) */ | 856 | static struct hda_verb alc880_pin_w810_init_verbs[] = { |
1044 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 857 | /* hphone/speaker input selector: front DAC */ |
1045 | 858 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, | |
1046 | /* front channel selector/amp: output 0: unmuted, max volume */ | ||
1047 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1048 | |||
1049 | /* front out pin: muted, (no volume selection) */ | ||
1050 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1051 | 859 | ||
1052 | /* front out pin: NOT headphone enable, out enable, vref disabled */ | ||
1053 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 860 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1054 | 861 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | |
1055 | |||
1056 | /* surround channel selector/amp: input 0: DAC: unmuted, (no volume selection) */ | ||
1057 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1058 | |||
1059 | /* surround channel selector/amp: input 1: capture mix: muted, (no volume selection) */ | ||
1060 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1061 | |||
1062 | /* surround channel selector/amp: output 0: unmuted, max volume */ | ||
1063 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1064 | |||
1065 | /* surround out pin: muted, (no volume selection) */ | ||
1066 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1067 | |||
1068 | /* surround out pin: NOT headphone enable, out enable, vref disabled */ | ||
1069 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 862 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1070 | 863 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | |
1071 | |||
1072 | /* c/lfe channel selector/amp: input 0: DAC: unmuted, (no volume selection) */ | ||
1073 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1074 | |||
1075 | /* c/lfe channel selector/amp: input 1: capture mix: muted, (no volume selection) */ | ||
1076 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1077 | |||
1078 | /* c/lfe channel selector/amp: output 0: unmuted, max volume */ | ||
1079 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1080 | |||
1081 | /* c/lfe out pin: muted, (no volume selection) */ | ||
1082 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1083 | |||
1084 | /* c/lfe out pin: NOT headphone enable, out enable, vref disabled */ | ||
1085 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 864 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
865 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1086 | 866 | ||
1087 | 867 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | |
1088 | /* hphone/speaker input selector: front DAC */ | ||
1089 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
1090 | |||
1091 | /* hphone/speaker out pin: muted, (no volume selection) */ | ||
1092 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 868 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
1093 | 869 | ||
1094 | /* hphone/speaker out pin: NOT headphone enable, out enable, vref disabled */ | ||
1095 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1096 | |||
1097 | |||
1098 | { } | 870 | { } |
1099 | }; | 871 | }; |
1100 | 872 | ||
1101 | static struct hda_verb alc880_z71v_init_verbs[] = { | 873 | /* |
1102 | /* front channel selector/amp: muted, DAC and mix (no vol) */ | 874 | * Z71V pin configuration: |
1103 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 875 | * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) |
1104 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 876 | */ |
1105 | /* front channel selector/amp: output 0: vol=0 */ | 877 | static struct hda_verb alc880_pin_z71v_init_verbs[] = { |
1106 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1107 | /* front out pin: unmuted, (no volume selection) */ | ||
1108 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1109 | /* front out pin: NOT headphone enable, out enable, vref disabled */ | ||
1110 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 878 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1111 | /* headphone channel selector/amp: muted, DAC and mix (no vol) */ | 879 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1112 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1113 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1114 | /* headphone channel selector/amp: output 0: vol=0 */ | ||
1115 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1116 | /* headphone out pin: muted, (no volume selection) */ | ||
1117 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1118 | /* headpohne out pin: headphone enable, out enable, vref disabled */ | ||
1119 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 880 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
881 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1120 | 882 | ||
1121 | /* Line In pin widget for input */ | ||
1122 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1123 | /* CD pin widget for input */ | ||
1124 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1125 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
1126 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 883 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
1127 | /* Mic2 (front panel) pin widget for input and vref at 80% */ | 884 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
1128 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 885 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
1129 | /* unmute amp left and right */ | 886 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
1130 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1131 | /* set connection select to mic in */ | ||
1132 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1133 | /* unmute amp left and right */ | ||
1134 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1135 | /* set connection select to mic in */ | ||
1136 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1137 | /* unmute amp left and right */ | ||
1138 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1139 | /* set connection select to mic in */ | ||
1140 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1141 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer | ||
1142 | * widget(nid=0x0B) to support the input path of analog loopback | ||
1143 | */ | ||
1144 | /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */ | ||
1145 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/ | ||
1146 | /* unmute CD */ | ||
1147 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
1148 | /* unmute Line In */ | ||
1149 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
1150 | /* unmute Mic 1 */ | ||
1151 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1152 | /* unmute Line In 2 (for PASD boards Mic 2) */ | ||
1153 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
1154 | 887 | ||
1155 | { } | 888 | { } |
1156 | }; | 889 | }; |
1157 | 890 | ||
1158 | //pshou 05/24/05 | 891 | /* |
1159 | static struct hda_verb alc880_six_stack_init_verbs[] = { | 892 | * 6-stack pin configuration: |
893 | * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, f-mic = 0x19, | ||
894 | * line = 0x1a, HP = 0x1b | ||
895 | */ | ||
896 | static struct hda_verb alc880_pin_6stack_init_verbs[] = { | ||
897 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
898 | |||
1160 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 899 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
900 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1161 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 901 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
902 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1162 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 903 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
904 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1163 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 905 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
906 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
907 | |||
1164 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 908 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
909 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1165 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 910 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
911 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1166 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 912 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
913 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1167 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 914 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
915 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1168 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 916 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
1169 | 917 | ||
918 | { } | ||
919 | }; | ||
920 | |||
921 | /* FIXME! */ | ||
922 | /* | ||
923 | * F1734 pin configuration: | ||
924 | * HP = 0x14, speaker-out = 0x15, mic = 0x18 | ||
925 | */ | ||
926 | static struct hda_verb alc880_pin_f1734_init_verbs[] = { | ||
1170 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, | 927 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, |
1171 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, | 928 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, |
1172 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, | 929 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, |
1173 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, | 930 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, |
1174 | 931 | ||
1175 | /* unmute amp left and right */ | 932 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
1176 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1177 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
1178 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1179 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 933 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1180 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 934 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1181 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 935 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1182 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1183 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1184 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1185 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1186 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1187 | |||
1188 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer | ||
1189 | * widget(nid=0x0B) to support the input path of analog loopback | ||
1190 | */ | ||
1191 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
1192 | /* unmute Line In */ | ||
1193 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
1194 | /* unmute Mic 1 */ | ||
1195 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1196 | /* unmute Mic 2 */ | ||
1197 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1198 | |||
1199 | /* Unmute Front out path */ | ||
1200 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1201 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1202 | /* Unmute Surround (used as HP) out path */ | ||
1203 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1204 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1205 | /* Unmute C/LFE out path */ | ||
1206 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1207 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mute */ | ||
1208 | /* Unmute rear Surround out path */ | ||
1209 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1210 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1211 | 936 | ||
1212 | { } | 937 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
1213 | }; | 938 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
1214 | |||
1215 | static struct hda_verb alc880_2_jack_init_verbs[] = { | ||
1216 | /* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */ | ||
1217 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1218 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1219 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1220 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 939 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
940 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1221 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 941 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
942 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1222 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 943 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
944 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1223 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 945 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
1224 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1225 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1226 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1227 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1228 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1229 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
1230 | {0x0C, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1231 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1232 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1233 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1234 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1235 | {0x1B, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1236 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1237 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1238 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1239 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
1240 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1241 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
1242 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1243 | 946 | ||
1244 | { } | 947 | { } |
1245 | }; | 948 | }; |
1246 | 949 | ||
1247 | static struct hda_verb alc880_asus_init_verbs[] = { | 950 | /* FIXME! */ |
951 | /* | ||
952 | * ASUS pin configuration: | ||
953 | * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a | ||
954 | */ | ||
955 | static struct hda_verb alc880_pin_asus_init_verbs[] = { | ||
1248 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, | 956 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, |
1249 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, | 957 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, |
1250 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, | 958 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, |
1251 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, | 959 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, |
1252 | 960 | ||
1253 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 961 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
962 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1254 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 963 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
964 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1255 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 965 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
966 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1256 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 967 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1257 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | 968 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1258 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | 969 | |
1259 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | 970 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
971 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
972 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
973 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
974 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
975 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1260 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 976 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
977 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1261 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 978 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
1262 | 979 | ||
1263 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ | 980 | { } |
1264 | /* unmute CD */ | 981 | }; |
1265 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
1266 | /* unmute Line In */ | ||
1267 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
1268 | /* unmute Mic 1 */ | ||
1269 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1270 | /* unmute Line In 2 (for PASD boards Mic 2) */ | ||
1271 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1272 | 982 | ||
1273 | /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ | 983 | /* Enable GPIO mask and set output */ |
1274 | /* Unmute Front out path */ | 984 | static struct hda_verb alc880_gpio1_init_verbs[] = { |
1275 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 985 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, |
1276 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 986 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, |
1277 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 987 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, |
1278 | /* Unmute Surround (used as HP) out path */ | 988 | }; |
1279 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1280 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1281 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1282 | /* Unmute C/LFE out path */ | ||
1283 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1284 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1285 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1286 | 989 | ||
1287 | { } | 990 | /* Enable GPIO mask and set output */ |
991 | static struct hda_verb alc880_gpio2_init_verbs[] = { | ||
992 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, | ||
993 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, | ||
994 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, | ||
1288 | }; | 995 | }; |
1289 | 996 | ||
1290 | 997 | ||
998 | /* | ||
999 | */ | ||
1000 | |||
1291 | static int alc_init(struct hda_codec *codec) | 1001 | static int alc_init(struct hda_codec *codec) |
1292 | { | 1002 | { |
1293 | struct alc_spec *spec = codec->spec; | 1003 | struct alc_spec *spec = codec->spec; |
1294 | snd_hda_sequence_write(codec, spec->init_verbs); | 1004 | unsigned int i; |
1005 | |||
1006 | for (i = 0; i < spec->num_init_verbs; i++) | ||
1007 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | ||
1295 | return 0; | 1008 | return 0; |
1296 | } | 1009 | } |
1297 | 1010 | ||
@@ -1305,9 +1018,8 @@ static int alc_resume(struct hda_codec *codec) | |||
1305 | int i; | 1018 | int i; |
1306 | 1019 | ||
1307 | alc_init(codec); | 1020 | alc_init(codec); |
1308 | for (i = 0; i < spec->num_mixers; i++) { | 1021 | for (i = 0; i < spec->num_mixers; i++) |
1309 | snd_hda_resume_ctls(codec, spec->mixers[i]); | 1022 | snd_hda_resume_ctls(codec, spec->mixers[i]); |
1310 | } | ||
1311 | if (spec->multiout.dig_out_nid) | 1023 | if (spec->multiout.dig_out_nid) |
1312 | snd_hda_resume_spdif_out(codec); | 1024 | snd_hda_resume_spdif_out(codec); |
1313 | if (spec->dig_in_nid) | 1025 | if (spec->dig_in_nid) |
@@ -1399,7 +1111,7 @@ static struct hda_pcm_stream alc880_pcm_analog_playback = { | |||
1399 | .substreams = 1, | 1111 | .substreams = 1, |
1400 | .channels_min = 2, | 1112 | .channels_min = 2, |
1401 | .channels_max = 8, | 1113 | .channels_max = 8, |
1402 | .nid = 0x02, /* NID to query formats and rates */ | 1114 | /* NID is set in alc_build_pcms */ |
1403 | .ops = { | 1115 | .ops = { |
1404 | .open = alc880_playback_pcm_open, | 1116 | .open = alc880_playback_pcm_open, |
1405 | .prepare = alc880_playback_pcm_prepare, | 1117 | .prepare = alc880_playback_pcm_prepare, |
@@ -1411,9 +1123,7 @@ static struct hda_pcm_stream alc880_pcm_analog_capture = { | |||
1411 | .substreams = 2, | 1123 | .substreams = 2, |
1412 | .channels_min = 2, | 1124 | .channels_min = 2, |
1413 | .channels_max = 2, | 1125 | .channels_max = 2, |
1414 | .nid = 0x08, /* NID to query formats and rates | 1126 | /* NID is set in alc_build_pcms */ |
1415 | * (0x07 might be broken on some devices) | ||
1416 | */ | ||
1417 | .ops = { | 1127 | .ops = { |
1418 | .prepare = alc880_capture_pcm_prepare, | 1128 | .prepare = alc880_capture_pcm_prepare, |
1419 | .cleanup = alc880_capture_pcm_cleanup | 1129 | .cleanup = alc880_capture_pcm_cleanup |
@@ -1449,7 +1159,9 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
1449 | 1159 | ||
1450 | info->name = spec->stream_name_analog; | 1160 | info->name = spec->stream_name_analog; |
1451 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); | 1161 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); |
1162 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; | ||
1452 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); | 1163 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); |
1164 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; | ||
1453 | 1165 | ||
1454 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; | 1166 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; |
1455 | for (i = 0; i < spec->num_channel_mode; i++) { | 1167 | for (i = 0; i < spec->num_channel_mode; i++) { |
@@ -1477,7 +1189,18 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
1477 | 1189 | ||
1478 | static void alc_free(struct hda_codec *codec) | 1190 | static void alc_free(struct hda_codec *codec) |
1479 | { | 1191 | { |
1480 | kfree(codec->spec); | 1192 | struct alc_spec *spec = codec->spec; |
1193 | unsigned int i; | ||
1194 | |||
1195 | if (! spec) | ||
1196 | return; | ||
1197 | |||
1198 | if (spec->kctl_alloc) { | ||
1199 | for (i = 0; i < spec->num_kctl_used; i++) | ||
1200 | kfree(spec->kctl_alloc[i].name); | ||
1201 | kfree(spec->kctl_alloc); | ||
1202 | } | ||
1203 | kfree(spec); | ||
1481 | } | 1204 | } |
1482 | 1205 | ||
1483 | /* | 1206 | /* |
@@ -1840,7 +1563,7 @@ static struct hda_board_config alc880_cfg_tbl[] = { | |||
1840 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG }, | 1563 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG }, |
1841 | { .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG }, | 1564 | { .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG }, |
1842 | 1565 | ||
1843 | { .modelname = "asua", .config = ALC880_ASUS }, | 1566 | { .modelname = "asus", .config = ALC880_ASUS }, |
1844 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG }, | 1567 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG }, |
1845 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG }, | 1568 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG }, |
1846 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG }, | 1569 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG }, |
@@ -1869,10 +1592,8 @@ static struct hda_board_config alc880_cfg_tbl[] = { | |||
1869 | * configuration template - to be copied to the spec instance | 1592 | * configuration template - to be copied to the spec instance |
1870 | */ | 1593 | */ |
1871 | struct alc_config_preset { | 1594 | struct alc_config_preset { |
1872 | snd_kcontrol_new_t *mixers; | 1595 | snd_kcontrol_new_t *mixers[4]; |
1873 | unsigned int front_panel: 1; /* optional */ | 1596 | const struct hda_verb *init_verbs[4]; |
1874 | unsigned int gpio_payload; /* optional */ | ||
1875 | struct hda_verb *init_verbs; | ||
1876 | unsigned int num_dacs; | 1597 | unsigned int num_dacs; |
1877 | hda_nid_t *dac_nids; | 1598 | hda_nid_t *dac_nids; |
1878 | hda_nid_t dig_out_nid; /* optional */ | 1599 | hda_nid_t dig_out_nid; /* optional */ |
@@ -1886,174 +1607,134 @@ struct alc_config_preset { | |||
1886 | 1607 | ||
1887 | static struct alc_config_preset alc880_presets[] = { | 1608 | static struct alc_config_preset alc880_presets[] = { |
1888 | [ALC880_3ST] = { | 1609 | [ALC880_3ST] = { |
1889 | .mixers = alc880_base_mixer, | 1610 | .mixers = { alc880_three_stack_mixer }, |
1890 | .init_verbs = alc880_init_verbs_three_stack, | 1611 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, |
1891 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 1612 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
1892 | .front_panel = 1, | ||
1893 | .dac_nids = alc880_dac_nids, | 1613 | .dac_nids = alc880_dac_nids, |
1894 | .hp_nid = 0x03, | ||
1895 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | ||
1896 | .adc_nids = alc880_adc_nids, | ||
1897 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | 1614 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), |
1898 | .channel_mode = alc880_threestack_modes, | 1615 | .channel_mode = alc880_threestack_modes, |
1899 | .input_mux = &alc880_capture_source, | 1616 | .input_mux = &alc880_capture_source, |
1900 | }, | 1617 | }, |
1901 | [ALC880_3ST_DIG] = { | 1618 | [ALC880_3ST_DIG] = { |
1902 | .mixers = alc880_base_mixer, | 1619 | .mixers = { alc880_three_stack_mixer }, |
1903 | .init_verbs = alc880_init_verbs_three_stack, | 1620 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, |
1904 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 1621 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
1905 | .front_panel = 1, | ||
1906 | .dac_nids = alc880_dac_nids, | 1622 | .dac_nids = alc880_dac_nids, |
1907 | .dig_out_nid = ALC880_DIGOUT_NID, | 1623 | .dig_out_nid = ALC880_DIGOUT_NID, |
1908 | .hp_nid = 0x03, | ||
1909 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | ||
1910 | .adc_nids = alc880_adc_nids, | ||
1911 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | 1624 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), |
1912 | .channel_mode = alc880_threestack_modes, | 1625 | .channel_mode = alc880_threestack_modes, |
1913 | .input_mux = &alc880_capture_source, | 1626 | .input_mux = &alc880_capture_source, |
1914 | }, | 1627 | }, |
1915 | [ALC880_5ST] = { | 1628 | [ALC880_5ST] = { |
1916 | .mixers = alc880_five_stack_mixer, | 1629 | .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer}, |
1917 | .init_verbs = alc880_init_verbs_five_stack, | 1630 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, |
1918 | .front_panel = 1, | ||
1919 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 1631 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
1920 | .dac_nids = alc880_dac_nids, | 1632 | .dac_nids = alc880_dac_nids, |
1921 | .hp_nid = 0x03, | ||
1922 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | ||
1923 | .adc_nids = alc880_adc_nids, | ||
1924 | .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), | 1633 | .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), |
1925 | .channel_mode = alc880_fivestack_modes, | 1634 | .channel_mode = alc880_fivestack_modes, |
1926 | .input_mux = &alc880_capture_source, | 1635 | .input_mux = &alc880_capture_source, |
1927 | }, | 1636 | }, |
1928 | [ALC880_5ST_DIG] = { | 1637 | [ALC880_5ST_DIG] = { |
1929 | .mixers = alc880_five_stack_mixer, | 1638 | .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer }, |
1930 | .init_verbs = alc880_init_verbs_five_stack, | 1639 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, |
1931 | .front_panel = 1, | ||
1932 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 1640 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
1933 | .dac_nids = alc880_dac_nids, | 1641 | .dac_nids = alc880_dac_nids, |
1934 | .dig_out_nid = ALC880_DIGOUT_NID, | 1642 | .dig_out_nid = ALC880_DIGOUT_NID, |
1935 | .hp_nid = 0x03, | ||
1936 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | ||
1937 | .adc_nids = alc880_adc_nids, | ||
1938 | .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), | 1643 | .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), |
1939 | .channel_mode = alc880_fivestack_modes, | 1644 | .channel_mode = alc880_fivestack_modes, |
1940 | .input_mux = &alc880_capture_source, | 1645 | .input_mux = &alc880_capture_source, |
1941 | }, | 1646 | }, |
1942 | [ALC880_6ST_DIG] = { | 1647 | [ALC880_6ST_DIG] = { |
1943 | .mixers = alc880_six_stack_mixer, | 1648 | .mixers = { alc880_six_stack_mixer }, |
1944 | .init_verbs = alc880_six_stack_init_verbs, | 1649 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, |
1945 | .front_panel = 1, | ||
1946 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), | 1650 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), |
1947 | .dac_nids = alc880_6st_dac_nids, | 1651 | .dac_nids = alc880_6st_dac_nids, |
1948 | .dig_out_nid = ALC880_DIGOUT_NID, | 1652 | .dig_out_nid = ALC880_DIGOUT_NID, |
1949 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | ||
1950 | .adc_nids = alc880_adc_nids, | ||
1951 | .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), | 1653 | .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), |
1952 | .channel_mode = alc880_sixstack_modes, | 1654 | .channel_mode = alc880_sixstack_modes, |
1953 | .input_mux = &alc880_6stack_capture_source, | 1655 | .input_mux = &alc880_6stack_capture_source, |
1954 | }, | 1656 | }, |
1955 | [ALC880_W810] = { | 1657 | [ALC880_W810] = { |
1956 | .mixers = alc880_w810_base_mixer, | 1658 | .mixers = { alc880_w810_base_mixer }, |
1957 | .init_verbs = alc880_w810_init_verbs, | 1659 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs }, |
1958 | .gpio_payload = 0x2, | ||
1959 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), | 1660 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), |
1960 | .dac_nids = alc880_w810_dac_nids, | 1661 | .dac_nids = alc880_w810_dac_nids, |
1961 | .dig_out_nid = ALC880_DIGOUT_NID, | 1662 | .dig_out_nid = ALC880_DIGOUT_NID, |
1962 | // No dedicated headphone socket - it's shared with built-in speakers. | ||
1963 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | ||
1964 | .adc_nids = alc880_adc_nids, | ||
1965 | .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), | 1663 | .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), |
1966 | .channel_mode = alc880_w810_modes, | 1664 | .channel_mode = alc880_w810_modes, |
1967 | .input_mux = &alc880_capture_source, | 1665 | .input_mux = &alc880_capture_source, |
1968 | }, | 1666 | }, |
1969 | [ALC880_Z71V] = { | 1667 | [ALC880_Z71V] = { |
1970 | .mixers = alc880_z71v_mixer, | 1668 | .mixers = { alc880_z71v_mixer }, |
1971 | .init_verbs = alc880_z71v_init_verbs, | 1669 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs, |
1670 | alc880_gpio2_init_verbs }, | ||
1972 | .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), | 1671 | .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), |
1973 | .dac_nids = alc880_z71v_dac_nids, | 1672 | .dac_nids = alc880_z71v_dac_nids, |
1974 | .dig_out_nid = ALC880_DIGOUT_NID, | 1673 | .dig_out_nid = ALC880_DIGOUT_NID, |
1975 | .hp_nid = 0x03, | 1674 | .hp_nid = 0x03, |
1976 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | 1675 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), |
1977 | .adc_nids = alc880_adc_nids, | 1676 | .channel_mode = alc880_2_jack_modes, |
1978 | .num_channel_mode = ARRAY_SIZE(alc880_z71v_modes), | ||
1979 | .channel_mode = alc880_z71v_modes, | ||
1980 | .input_mux = &alc880_capture_source, | 1677 | .input_mux = &alc880_capture_source, |
1981 | }, | 1678 | }, |
1982 | [ALC880_F1734] = { | 1679 | [ALC880_F1734] = { |
1983 | .mixers = alc880_2_jack_mixer, | 1680 | .mixers = { alc880_f1734_mixer }, |
1984 | .init_verbs = alc880_2_jack_init_verbs, | 1681 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs }, |
1985 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 1682 | .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), |
1986 | .dac_nids = alc880_dac_nids, | 1683 | .dac_nids = alc880_f1734_dac_nids, |
1987 | .hp_nid = 0x03, | 1684 | .hp_nid = 0x02, |
1988 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | 1685 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), |
1989 | .adc_nids = alc880_adc_nids, | 1686 | .channel_mode = alc880_2_jack_modes, |
1990 | .num_channel_mode = ARRAY_SIZE(alc880_z71v_modes), | ||
1991 | .channel_mode = alc880_z71v_modes, | ||
1992 | .input_mux = &alc880_capture_source, | 1687 | .input_mux = &alc880_capture_source, |
1993 | }, | 1688 | }, |
1994 | [ALC880_ASUS] = { | 1689 | [ALC880_ASUS] = { |
1995 | .mixers = alc880_asus_mixer, | 1690 | .mixers = { alc880_asus_mixer }, |
1996 | .init_verbs = alc880_asus_init_verbs, | 1691 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, |
1997 | .gpio_payload = 0x1, | 1692 | alc880_gpio1_init_verbs }, |
1998 | .front_panel = 1, | 1693 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
1999 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), | 1694 | .dac_nids = alc880_asus_dac_nids, |
2000 | .dac_nids = alc880_w810_dac_nids, | 1695 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), |
2001 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | 1696 | .channel_mode = alc880_asus_modes, |
2002 | .adc_nids = alc880_adc_nids, | ||
2003 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
2004 | .channel_mode = alc880_threestack_modes, | ||
2005 | .input_mux = &alc880_capture_source, | 1697 | .input_mux = &alc880_capture_source, |
2006 | }, | 1698 | }, |
2007 | [ALC880_ASUS_DIG] = { | 1699 | [ALC880_ASUS_DIG] = { |
2008 | .mixers = alc880_asus_mixer, | 1700 | .mixers = { alc880_asus_mixer }, |
2009 | .init_verbs = alc880_asus_init_verbs, | 1701 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, |
2010 | .gpio_payload = 0x1, | 1702 | alc880_gpio1_init_verbs }, |
2011 | .front_panel = 1, | 1703 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2012 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), | 1704 | .dac_nids = alc880_asus_dac_nids, |
2013 | .dac_nids = alc880_w810_dac_nids, | ||
2014 | .dig_out_nid = ALC880_DIGOUT_NID, | 1705 | .dig_out_nid = ALC880_DIGOUT_NID, |
2015 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | 1706 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), |
2016 | .adc_nids = alc880_adc_nids, | 1707 | .channel_mode = alc880_asus_modes, |
2017 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
2018 | .channel_mode = alc880_threestack_modes, | ||
2019 | .input_mux = &alc880_capture_source, | 1708 | .input_mux = &alc880_capture_source, |
2020 | }, | 1709 | }, |
2021 | [ALC880_ASUS_W1V] = { | 1710 | [ALC880_ASUS_W1V] = { |
2022 | .mixers = alc880_asus_w1v_mixer, | 1711 | .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, |
2023 | .init_verbs = alc880_asus_init_verbs, | 1712 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, |
2024 | .gpio_payload = 0x1, | 1713 | alc880_gpio1_init_verbs }, |
2025 | .front_panel = 1, | 1714 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2026 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), | 1715 | .dac_nids = alc880_asus_dac_nids, |
2027 | .dac_nids = alc880_w810_dac_nids, | ||
2028 | .dig_out_nid = ALC880_DIGOUT_NID, | 1716 | .dig_out_nid = ALC880_DIGOUT_NID, |
2029 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | 1717 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), |
2030 | .adc_nids = alc880_adc_nids, | 1718 | .channel_mode = alc880_asus_modes, |
2031 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
2032 | .channel_mode = alc880_threestack_modes, | ||
2033 | .input_mux = &alc880_capture_source, | 1719 | .input_mux = &alc880_capture_source, |
2034 | }, | 1720 | }, |
2035 | [ALC880_UNIWILL_DIG] = { | 1721 | [ALC880_UNIWILL_DIG] = { |
2036 | .mixers = alc880_asus_mixer, | 1722 | .mixers = { alc880_asus_mixer }, |
2037 | .init_verbs = alc880_asus_init_verbs, | 1723 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs }, |
2038 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | 1724 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2039 | .dac_nids = alc880_dac_nids, | 1725 | .dac_nids = alc880_asus_dac_nids, |
2040 | .dig_out_nid = ALC880_DIGOUT_NID, | 1726 | .dig_out_nid = ALC880_DIGOUT_NID, |
2041 | .hp_nid = 0x03, | 1727 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), |
2042 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | 1728 | .channel_mode = alc880_asus_modes, |
2043 | .adc_nids = alc880_adc_nids, | ||
2044 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
2045 | .channel_mode = alc880_threestack_modes, | ||
2046 | .input_mux = &alc880_capture_source, | 1729 | .input_mux = &alc880_capture_source, |
2047 | }, | 1730 | }, |
2048 | #ifdef CONFIG_SND_DEBUG | 1731 | #ifdef CONFIG_SND_DEBUG |
2049 | [ALC880_TEST] = { | 1732 | [ALC880_TEST] = { |
2050 | .mixers = alc880_test_mixer, | 1733 | .mixers = { alc880_test_mixer }, |
2051 | .init_verbs = alc880_test_init_verbs, | 1734 | .init_verbs = { alc880_test_init_verbs }, |
2052 | .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), | 1735 | .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), |
2053 | .dac_nids = alc880_test_dac_nids, | 1736 | .dac_nids = alc880_test_dac_nids, |
2054 | .dig_out_nid = ALC880_DIGOUT_NID, | 1737 | .dig_out_nid = ALC880_DIGOUT_NID, |
2055 | .num_adc_nids = ARRAY_SIZE(alc880_adc_nids), | ||
2056 | .adc_nids = alc880_adc_nids, | ||
2057 | .num_channel_mode = ARRAY_SIZE(alc880_test_modes), | 1738 | .num_channel_mode = ARRAY_SIZE(alc880_test_modes), |
2058 | .channel_mode = alc880_test_modes, | 1739 | .channel_mode = alc880_test_modes, |
2059 | .input_mux = &alc880_test_capture_source, | 1740 | .input_mux = &alc880_test_capture_source, |
@@ -2061,11 +1742,333 @@ static struct alc_config_preset alc880_presets[] = { | |||
2061 | #endif | 1742 | #endif |
2062 | }; | 1743 | }; |
2063 | 1744 | ||
1745 | /* | ||
1746 | * Automatic parse of I/O pins from the BIOS configuration | ||
1747 | */ | ||
1748 | |||
1749 | #define NUM_CONTROL_ALLOC 32 | ||
1750 | #define NUM_VERB_ALLOC 32 | ||
1751 | |||
1752 | enum { | ||
1753 | ALC_CTL_WIDGET_VOL, | ||
1754 | ALC_CTL_WIDGET_MUTE, | ||
1755 | ALC_CTL_BIND_MUTE, | ||
1756 | }; | ||
1757 | static snd_kcontrol_new_t alc880_control_templates[] = { | ||
1758 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | ||
1759 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | ||
1760 | ALC_BIND_MUTE(NULL, 0, 0, 0), | ||
1761 | }; | ||
1762 | |||
1763 | /* add dynamic controls */ | ||
1764 | static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val) | ||
1765 | { | ||
1766 | snd_kcontrol_new_t *knew; | ||
1767 | |||
1768 | if (spec->num_kctl_used >= spec->num_kctl_alloc) { | ||
1769 | int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; | ||
1770 | |||
1771 | knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ | ||
1772 | if (! knew) | ||
1773 | return -ENOMEM; | ||
1774 | if (spec->kctl_alloc) { | ||
1775 | memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); | ||
1776 | kfree(spec->kctl_alloc); | ||
1777 | } | ||
1778 | spec->kctl_alloc = knew; | ||
1779 | spec->num_kctl_alloc = num; | ||
1780 | } | ||
1781 | |||
1782 | knew = &spec->kctl_alloc[spec->num_kctl_used]; | ||
1783 | *knew = alc880_control_templates[type]; | ||
1784 | knew->name = snd_kmalloc_strdup(name, GFP_KERNEL); | ||
1785 | if (! knew->name) | ||
1786 | return -ENOMEM; | ||
1787 | knew->private_value = val; | ||
1788 | spec->num_kctl_used++; | ||
1789 | return 0; | ||
1790 | } | ||
1791 | |||
1792 | #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) | ||
1793 | #define alc880_fixed_pin_idx(nid) ((nid) - 0x14) | ||
1794 | #define alc880_is_multi_pin(nid) ((nid) >= 0x18) | ||
1795 | #define alc880_multi_pin_idx(nid) ((nid) - 0x18) | ||
1796 | #define alc880_is_input_pin(nid) ((nid) >= 0x18) | ||
1797 | #define alc880_input_pin_idx(nid) ((nid) - 0x18) | ||
1798 | #define alc880_idx_to_dac(nid) ((nid) + 0x02) | ||
1799 | #define alc880_dac_to_idx(nid) ((nid) - 0x02) | ||
1800 | #define alc880_idx_to_mixer(nid) ((nid) + 0x0c) | ||
1801 | #define alc880_idx_to_selector(nid) ((nid) + 0x10) | ||
1802 | #define ALC880_PIN_CD_NID 0x1c | ||
1803 | |||
1804 | /* fill in the dac_nids table from the parsed pin configuration */ | ||
1805 | static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | ||
1806 | { | ||
1807 | hda_nid_t nid; | ||
1808 | int assigned[4]; | ||
1809 | int i, j; | ||
1810 | |||
1811 | memset(assigned, 0, sizeof(assigned)); | ||
1812 | |||
1813 | /* check the pins hardwired to audio widget */ | ||
1814 | for (i = 0; i < cfg->line_outs; i++) { | ||
1815 | nid = cfg->line_out_pins[i]; | ||
1816 | if (alc880_is_fixed_pin(nid)) { | ||
1817 | int idx = alc880_fixed_pin_idx(nid); | ||
1818 | spec->multiout.dac_nids[i] = alc880_dac_to_idx(idx); | ||
1819 | assigned[idx] = 1; | ||
1820 | } | ||
1821 | } | ||
1822 | /* left pins can be connect to any audio widget */ | ||
1823 | for (i = 0; i < cfg->line_outs; i++) { | ||
1824 | nid = cfg->line_out_pins[i]; | ||
1825 | if (alc880_is_fixed_pin(nid)) | ||
1826 | continue; | ||
1827 | /* search for an empty channel */ | ||
1828 | for (j = 0; j < cfg->line_outs; j++) { | ||
1829 | if (! assigned[j]) { | ||
1830 | spec->multiout.dac_nids[i] = alc880_idx_to_dac(j); | ||
1831 | assigned[j] = 1; | ||
1832 | break; | ||
1833 | } | ||
1834 | } | ||
1835 | } | ||
1836 | spec->multiout.num_dacs = cfg->line_outs; | ||
1837 | return 0; | ||
1838 | } | ||
1839 | |||
1840 | /* add playback controls from the parsed DAC table */ | ||
1841 | static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | ||
1842 | { | ||
1843 | char name[32]; | ||
1844 | static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; | ||
1845 | hda_nid_t nid; | ||
1846 | int i, err; | ||
1847 | |||
1848 | for (i = 0; i < cfg->line_outs; i++) { | ||
1849 | if (! spec->multiout.dac_nids[i]) | ||
1850 | continue; | ||
1851 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); | ||
1852 | if (i == 2) { | ||
1853 | /* Center/LFE */ | ||
1854 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume", | ||
1855 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) | ||
1856 | return err; | ||
1857 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume", | ||
1858 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | ||
1859 | return err; | ||
1860 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", | ||
1861 | HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0) | ||
1862 | return err; | ||
1863 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", | ||
1864 | HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0) | ||
1865 | return err; | ||
1866 | } else { | ||
1867 | sprintf(name, "%s Playback Volume", chname[i]); | ||
1868 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
1869 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | ||
1870 | return err; | ||
1871 | sprintf(name, "%s Playback Switch", chname[i]); | ||
1872 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
1873 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) | ||
1874 | return err; | ||
1875 | } | ||
1876 | } | ||
1877 | |||
1878 | return 0; | ||
1879 | } | ||
1880 | |||
1881 | /* add playback controls for HP output */ | ||
1882 | static int alc880_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) | ||
1883 | { | ||
1884 | hda_nid_t nid; | ||
1885 | int err; | ||
1886 | |||
1887 | if (! pin) | ||
1888 | return 0; | ||
1889 | |||
1890 | if (alc880_is_fixed_pin(pin)) { | ||
1891 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | ||
1892 | if (! spec->multiout.dac_nids[0]) { | ||
1893 | /* use this as the primary output */ | ||
1894 | spec->multiout.dac_nids[0] = nid; | ||
1895 | if (! spec->multiout.num_dacs) | ||
1896 | spec->multiout.num_dacs = 1; | ||
1897 | } else | ||
1898 | /* specify the DAC as the extra HP output */ | ||
1899 | spec->multiout.hp_nid = nid; | ||
1900 | /* control HP volume/switch on the output mixer amp */ | ||
1901 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); | ||
1902 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume", | ||
1903 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | ||
1904 | return err; | ||
1905 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Headphone Playback Switch", | ||
1906 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) | ||
1907 | return err; | ||
1908 | } else if (alc880_is_multi_pin(pin)) { | ||
1909 | /* set manual connection */ | ||
1910 | if (! spec->multiout.dac_nids[0]) { | ||
1911 | /* use this as the primary output */ | ||
1912 | spec->multiout.dac_nids[0] = alc880_idx_to_dac(alc880_multi_pin_idx(pin)); | ||
1913 | if (! spec->multiout.num_dacs) | ||
1914 | spec->multiout.num_dacs = 1; | ||
1915 | } | ||
1916 | /* we have only a switch on HP-out PIN */ | ||
1917 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", | ||
1918 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0) | ||
1919 | return err; | ||
1920 | } | ||
1921 | return 0; | ||
1922 | } | ||
1923 | |||
1924 | /* create input playback/capture controls for the given pin */ | ||
1925 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname) | ||
1926 | { | ||
1927 | char name[32]; | ||
1928 | int err, idx; | ||
1929 | |||
1930 | sprintf(name, "%s Playback Volume", ctlname); | ||
1931 | idx = alc880_input_pin_idx(pin); | ||
1932 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
1933 | HDA_COMPOSE_AMP_VAL(0x0b, 3, idx, HDA_INPUT))) < 0) | ||
1934 | return err; | ||
1935 | sprintf(name, "%s Playback Switch", ctlname); | ||
1936 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
1937 | HDA_COMPOSE_AMP_VAL(0x0b, 3, idx, HDA_INPUT))) < 0) | ||
1938 | return err; | ||
1939 | return 0; | ||
1940 | } | ||
1941 | |||
1942 | /* create playback/capture controls for input pins */ | ||
1943 | static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | ||
1944 | { | ||
1945 | static char *labels[AUTO_PIN_LAST] = { | ||
1946 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux" | ||
1947 | }; | ||
1948 | struct hda_input_mux *imux = &spec->private_imux; | ||
1949 | int i, err; | ||
1950 | |||
1951 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
1952 | if (alc880_is_input_pin(cfg->input_pins[i])) { | ||
1953 | err = new_analog_input(spec, cfg->input_pins[i], labels[i]); | ||
1954 | if (err < 0) | ||
1955 | return err; | ||
1956 | imux->items[imux->num_items].label = labels[i]; | ||
1957 | imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]); | ||
1958 | imux->num_items++; | ||
1959 | } | ||
1960 | } | ||
1961 | return 0; | ||
1962 | } | ||
1963 | |||
1964 | static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, int pin_type, | ||
1965 | int dac_idx) | ||
1966 | { | ||
1967 | /* set as output */ | ||
1968 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | ||
1969 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | ||
1970 | /* need the manual connection? */ | ||
1971 | if (alc880_is_multi_pin(nid)) { | ||
1972 | struct alc_spec *spec = codec->spec; | ||
1973 | int idx = alc880_multi_pin_idx(nid); | ||
1974 | snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, | ||
1975 | AC_VERB_SET_CONNECT_SEL, | ||
1976 | alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); | ||
1977 | } | ||
1978 | } | ||
1979 | |||
1980 | static void alc880_auto_init_multi_out(struct hda_codec *codec) | ||
1981 | { | ||
1982 | struct alc_spec *spec = codec->spec; | ||
1983 | int i; | ||
1984 | |||
1985 | for (i = 0; i < spec->autocfg.line_outs; i++) { | ||
1986 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
1987 | alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); | ||
1988 | } | ||
1989 | } | ||
1990 | |||
1991 | static void alc880_auto_init_hp_out(struct hda_codec *codec) | ||
1992 | { | ||
1993 | struct alc_spec *spec = codec->spec; | ||
1994 | hda_nid_t pin; | ||
1995 | |||
1996 | pin = spec->autocfg.hp_pin; | ||
1997 | if (pin) /* connect to front */ | ||
1998 | alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); | ||
1999 | } | ||
2000 | |||
2001 | static void alc880_auto_init_analog_input(struct hda_codec *codec) | ||
2002 | { | ||
2003 | struct alc_spec *spec = codec->spec; | ||
2004 | int i; | ||
2005 | |||
2006 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
2007 | hda_nid_t nid = spec->autocfg.input_pins[i]; | ||
2008 | if (alc880_is_input_pin(nid)) { | ||
2009 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
2010 | i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); | ||
2011 | if (nid != ALC880_PIN_CD_NID) | ||
2012 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
2013 | AMP_OUT_MUTE); | ||
2014 | } | ||
2015 | } | ||
2016 | } | ||
2017 | |||
2018 | /* parse the BIOS configuration and set up the alc_spec */ | ||
2019 | /* return 1 if successful, 0 if the proper config is not found, or a negative error code */ | ||
2020 | static int alc880_parse_auto_config(struct hda_codec *codec) | ||
2021 | { | ||
2022 | struct alc_spec *spec = codec->spec; | ||
2023 | int err; | ||
2024 | |||
2025 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0) | ||
2026 | return err; | ||
2027 | if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0) | ||
2028 | return err; | ||
2029 | if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin) | ||
2030 | return 0; /* can't find valid BIOS pin config */ | ||
2031 | if ((err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | ||
2032 | (err = alc880_auto_create_hp_ctls(spec, spec->autocfg.hp_pin)) < 0 || | ||
2033 | (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | ||
2034 | return err; | ||
2035 | |||
2036 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | ||
2037 | |||
2038 | if (spec->autocfg.dig_out_pin) | ||
2039 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; | ||
2040 | if (spec->autocfg.dig_in_pin) | ||
2041 | spec->dig_in_nid = ALC880_DIGIN_NID; | ||
2042 | |||
2043 | if (spec->kctl_alloc) | ||
2044 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | ||
2045 | |||
2046 | spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; | ||
2047 | |||
2048 | spec->input_mux = &spec->private_imux; | ||
2049 | |||
2050 | return 1; | ||
2051 | } | ||
2052 | |||
2053 | /* init callback for auto-configuration model -- overriding the default init */ | ||
2054 | static int alc880_auto_init(struct hda_codec *codec) | ||
2055 | { | ||
2056 | alc_init(codec); | ||
2057 | alc880_auto_init_multi_out(codec); | ||
2058 | alc880_auto_init_hp_out(codec); | ||
2059 | alc880_auto_init_analog_input(codec); | ||
2060 | return 0; | ||
2061 | } | ||
2062 | |||
2063 | /* | ||
2064 | * OK, here we have finally the patch for ALC880 | ||
2065 | */ | ||
2066 | |||
2064 | static int patch_alc880(struct hda_codec *codec) | 2067 | static int patch_alc880(struct hda_codec *codec) |
2065 | { | 2068 | { |
2066 | struct alc_spec *spec; | 2069 | struct alc_spec *spec; |
2067 | int board_config; | 2070 | int board_config; |
2068 | const struct alc_config_preset *preset; | 2071 | int i, err; |
2069 | 2072 | ||
2070 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); | 2073 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); |
2071 | if (spec == NULL) | 2074 | if (spec == NULL) |
@@ -2076,30 +2079,52 @@ static int patch_alc880(struct hda_codec *codec) | |||
2076 | 2079 | ||
2077 | board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); | 2080 | board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); |
2078 | if (board_config < 0 || board_config >= ALC880_MODEL_LAST) { | 2081 | if (board_config < 0 || board_config >= ALC880_MODEL_LAST) { |
2079 | snd_printd(KERN_INFO "hda_codec: Unknown model for ALC880\n"); | 2082 | printk(KERN_INFO "hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...\n"); |
2080 | board_config = ALC880_3ST; | 2083 | board_config = ALC880_AUTO; |
2081 | } | 2084 | } |
2082 | preset = &alc880_presets[board_config]; | ||
2083 | |||
2084 | spec->mixers[spec->num_mixers] = preset->mixers; | ||
2085 | snd_assert(spec->mixers[0], kfree(spec);return -EINVAL); | ||
2086 | spec->num_mixers++; | ||
2087 | 2085 | ||
2088 | /* some MBs need GPIO setup */ | 2086 | if (board_config == ALC880_AUTO) { |
2089 | if (preset->gpio_payload) { | 2087 | /* automatic parse from the BIOS config */ |
2090 | /* Enable mask and set output */ | 2088 | err = alc880_parse_auto_config(codec); |
2091 | snd_hda_codec_write(codec, codec->afg, 0, | 2089 | if (err < 0) { |
2092 | AC_VERB_SET_GPIO_MASK, preset->gpio_payload); | 2090 | alc_free(codec); |
2093 | snd_hda_codec_write(codec, codec->afg, 0, | 2091 | return err; |
2094 | AC_VERB_SET_GPIO_DIRECTION, preset->gpio_payload); | 2092 | } else if (! err) { |
2095 | snd_hda_codec_write(codec, codec->afg, 0, | 2093 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 3-stack mode...\n"); |
2096 | AC_VERB_SET_GPIO_DATA, preset->gpio_payload); | 2094 | board_config = ALC880_3ST; |
2095 | } | ||
2097 | } | 2096 | } |
2098 | 2097 | ||
2099 | spec->front_panel = preset->front_panel; | 2098 | if (board_config != ALC880_AUTO) { |
2100 | spec->init_verbs = preset->init_verbs; | 2099 | /* set up from the preset table */ |
2101 | spec->channel_mode = preset->channel_mode; | 2100 | const struct alc_config_preset *preset; |
2102 | spec->num_channel_mode = preset->num_channel_mode; | 2101 | |
2102 | preset = &alc880_presets[board_config]; | ||
2103 | |||
2104 | for (i = 0; preset->mixers[i]; i++) { | ||
2105 | snd_assert(spec->num_mixers < ARRAY_SIZE(spec->mixers), break); | ||
2106 | spec->mixers[spec->num_mixers++] = preset->mixers[i]; | ||
2107 | } | ||
2108 | for (i = 0; preset->init_verbs[i]; i++) { | ||
2109 | snd_assert(spec->num_init_verbs < ARRAY_SIZE(spec->init_verbs), break); | ||
2110 | spec->init_verbs[spec->num_init_verbs++] = preset->init_verbs[i]; | ||
2111 | } | ||
2112 | |||
2113 | spec->channel_mode = preset->channel_mode; | ||
2114 | spec->num_channel_mode = preset->num_channel_mode; | ||
2115 | |||
2116 | spec->multiout.max_channels = spec->channel_mode[0].channels; | ||
2117 | |||
2118 | spec->multiout.num_dacs = preset->num_dacs; | ||
2119 | spec->multiout.dac_nids = preset->dac_nids; | ||
2120 | spec->multiout.dig_out_nid = preset->dig_out_nid; | ||
2121 | spec->multiout.hp_nid = preset->hp_nid; | ||
2122 | |||
2123 | spec->input_mux = preset->input_mux; | ||
2124 | |||
2125 | spec->num_adc_nids = preset->num_adc_nids; | ||
2126 | spec->adc_nids = preset->adc_nids; | ||
2127 | } | ||
2103 | 2128 | ||
2104 | spec->stream_name_analog = "ALC880 Analog"; | 2129 | spec->stream_name_analog = "ALC880 Analog"; |
2105 | spec->stream_analog_playback = &alc880_pcm_analog_playback; | 2130 | spec->stream_analog_playback = &alc880_pcm_analog_playback; |
@@ -2109,26 +2134,64 @@ static int patch_alc880(struct hda_codec *codec) | |||
2109 | spec->stream_digital_playback = &alc880_pcm_digital_playback; | 2134 | spec->stream_digital_playback = &alc880_pcm_digital_playback; |
2110 | spec->stream_digital_capture = &alc880_pcm_digital_capture; | 2135 | spec->stream_digital_capture = &alc880_pcm_digital_capture; |
2111 | 2136 | ||
2112 | spec->multiout.max_channels = spec->channel_mode[0].channels; | 2137 | if (! spec->adc_nids && spec->input_mux) { |
2113 | 2138 | /* check whether NID 0x07 is valid */ | |
2114 | spec->multiout.num_dacs = preset->num_dacs; | 2139 | unsigned int wcap = snd_hda_param_read(codec, alc880_adc_nids[0], |
2115 | spec->multiout.dac_nids = preset->adc_nids; | 2140 | AC_PAR_AUDIO_WIDGET_CAP); |
2116 | spec->multiout.dig_out_nid = preset->dig_out_nid; | 2141 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ |
2117 | spec->multiout.hp_nid = preset->hp_nid; | 2142 | if (wcap != AC_WID_AUD_IN) { |
2118 | 2143 | spec->adc_nids = alc880_adc_nids_alt; | |
2119 | spec->input_mux = preset->input_mux; | 2144 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); |
2120 | spec->num_adc_nids = preset->num_adc_nids; | 2145 | spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer; |
2121 | spec->adc_nids = preset->adc_nids; | 2146 | spec->num_mixers++; |
2147 | } else { | ||
2148 | spec->adc_nids = alc880_adc_nids; | ||
2149 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); | ||
2150 | spec->mixers[spec->num_mixers] = alc880_capture_mixer; | ||
2151 | spec->num_mixers++; | ||
2152 | } | ||
2153 | } | ||
2122 | 2154 | ||
2123 | codec->patch_ops = alc_patch_ops; | 2155 | codec->patch_ops = alc_patch_ops; |
2156 | if (board_config == ALC880_AUTO) | ||
2157 | codec->patch_ops.init = alc880_auto_init; | ||
2124 | 2158 | ||
2125 | return 0; | 2159 | return 0; |
2126 | } | 2160 | } |
2127 | 2161 | ||
2162 | |||
2128 | /* | 2163 | /* |
2129 | * ALC260 support | 2164 | * ALC260 support |
2130 | */ | 2165 | */ |
2131 | 2166 | ||
2167 | static hda_nid_t alc260_dac_nids[1] = { | ||
2168 | /* front */ | ||
2169 | 0x02, | ||
2170 | }; | ||
2171 | |||
2172 | static hda_nid_t alc260_adc_nids[1] = { | ||
2173 | /* ADC0 */ | ||
2174 | 0x04, | ||
2175 | }; | ||
2176 | |||
2177 | static hda_nid_t alc260_hp_adc_nids[1] = { | ||
2178 | /* ADC1 */ | ||
2179 | 0x05, | ||
2180 | }; | ||
2181 | |||
2182 | #define ALC260_DIGOUT_NID 0x03 | ||
2183 | #define ALC260_DIGIN_NID 0x06 | ||
2184 | |||
2185 | static struct hda_input_mux alc260_capture_source = { | ||
2186 | .num_items = 4, | ||
2187 | .items = { | ||
2188 | { "Mic", 0x0 }, | ||
2189 | { "Front Mic", 0x1 }, | ||
2190 | { "Line", 0x2 }, | ||
2191 | { "CD", 0x4 }, | ||
2192 | }, | ||
2193 | }; | ||
2194 | |||
2132 | /* | 2195 | /* |
2133 | * This is just place-holder, so there's something for alc_build_pcms to look | 2196 | * This is just place-holder, so there's something for alc_build_pcms to look |
2134 | * at when it calculates the maximum number of channels. ALC260 has no mixer | 2197 | * at when it calculates the maximum number of channels. ALC260 has no mixer |
@@ -2139,7 +2202,7 @@ static struct alc_channel_mode alc260_modes[1] = { | |||
2139 | { 2, NULL }, | 2202 | { 2, NULL }, |
2140 | }; | 2203 | }; |
2141 | 2204 | ||
2142 | snd_kcontrol_new_t alc260_base_mixer[] = { | 2205 | static snd_kcontrol_new_t alc260_base_mixer[] = { |
2143 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 2206 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
2144 | ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | 2207 | ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), |
2145 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 2208 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
@@ -2168,7 +2231,7 @@ snd_kcontrol_new_t alc260_base_mixer[] = { | |||
2168 | { } /* end */ | 2231 | { } /* end */ |
2169 | }; | 2232 | }; |
2170 | 2233 | ||
2171 | snd_kcontrol_new_t alc260_hp_mixer[] = { | 2234 | static snd_kcontrol_new_t alc260_hp_mixer[] = { |
2172 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 2235 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
2173 | ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | 2236 | ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), |
2174 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 2237 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
@@ -2260,14 +2323,12 @@ static struct hda_pcm_stream alc260_pcm_analog_playback = { | |||
2260 | .substreams = 1, | 2323 | .substreams = 1, |
2261 | .channels_min = 2, | 2324 | .channels_min = 2, |
2262 | .channels_max = 2, | 2325 | .channels_max = 2, |
2263 | .nid = 0x2, | ||
2264 | }; | 2326 | }; |
2265 | 2327 | ||
2266 | static struct hda_pcm_stream alc260_pcm_analog_capture = { | 2328 | static struct hda_pcm_stream alc260_pcm_analog_capture = { |
2267 | .substreams = 1, | 2329 | .substreams = 1, |
2268 | .channels_min = 2, | 2330 | .channels_min = 2, |
2269 | .channels_max = 2, | 2331 | .channels_max = 2, |
2270 | .nid = 0x4, | ||
2271 | }; | 2332 | }; |
2272 | 2333 | ||
2273 | static struct hda_board_config alc260_cfg_tbl[] = { | 2334 | static struct hda_board_config alc260_cfg_tbl[] = { |
@@ -2296,7 +2357,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
2296 | 2357 | ||
2297 | switch (board_config) { | 2358 | switch (board_config) { |
2298 | case ALC260_HP: | 2359 | case ALC260_HP: |
2299 | spec->mixers[spec->num_mixers] = alc260_base_mixer; | 2360 | spec->mixers[spec->num_mixers] = alc260_hp_mixer; |
2300 | spec->num_mixers++; | 2361 | spec->num_mixers++; |
2301 | break; | 2362 | break; |
2302 | default: | 2363 | default: |
@@ -2305,7 +2366,9 @@ static int patch_alc260(struct hda_codec *codec) | |||
2305 | break; | 2366 | break; |
2306 | } | 2367 | } |
2307 | 2368 | ||
2308 | spec->init_verbs = alc260_init_verbs; | 2369 | spec->init_verbs[0] = alc260_init_verbs; |
2370 | spec->num_init_verbs = 1; | ||
2371 | |||
2309 | spec->channel_mode = alc260_modes; | 2372 | spec->channel_mode = alc260_modes; |
2310 | spec->num_channel_mode = ARRAY_SIZE(alc260_modes); | 2373 | spec->num_channel_mode = ARRAY_SIZE(alc260_modes); |
2311 | 2374 | ||
@@ -2320,7 +2383,6 @@ static int patch_alc260(struct hda_codec *codec) | |||
2320 | spec->input_mux = &alc260_capture_source; | 2383 | spec->input_mux = &alc260_capture_source; |
2321 | switch (board_config) { | 2384 | switch (board_config) { |
2322 | case ALC260_HP: | 2385 | case ALC260_HP: |
2323 | spec->stream_analog_capture->nid = 5; | ||
2324 | spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids); | 2386 | spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids); |
2325 | spec->adc_nids = alc260_hp_adc_nids; | 2387 | spec->adc_nids = alc260_hp_adc_nids; |
2326 | break; | 2388 | break; |
@@ -2335,6 +2397,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
2335 | return 0; | 2397 | return 0; |
2336 | } | 2398 | } |
2337 | 2399 | ||
2400 | |||
2338 | /* | 2401 | /* |
2339 | * ALC882 support | 2402 | * ALC882 support |
2340 | * | 2403 | * |
@@ -2463,42 +2526,35 @@ static struct hda_verb alc882_init_verbs[] = { | |||
2463 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 2526 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
2464 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2527 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
2465 | 2528 | ||
2466 | /* Front Pin: to output mode */ | 2529 | /* Front Pin: output 0 (0x0c) */ |
2467 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 2530 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
2468 | /* Front Pin: mute amp left and right (no volume) */ | ||
2469 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2531 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2470 | /* select Front mixer (0x0c, index 0) */ | ||
2471 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | 2532 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, |
2472 | /* Rear Pin */ | 2533 | /* Rear Pin: output 1 (0x0d) */ |
2473 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 2534 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
2474 | /* Rear Pin: mute amp left and right (no volume) */ | ||
2475 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2535 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2476 | /* select Rear mixer (0x0d, index 1) */ | ||
2477 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | 2536 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, |
2478 | /* CLFE Pin */ | 2537 | /* CLFE Pin: output 2 (0x0e) */ |
2479 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 2538 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
2480 | /* CLFE Pin: mute amp left and right (no volume) */ | ||
2481 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2539 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2482 | /* select CLFE mixer (0x0e, index 2) */ | ||
2483 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, | 2540 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, |
2484 | /* Side Pin */ | 2541 | /* Side Pin: output 3 (0x0f) */ |
2485 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 2542 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
2486 | /* Side Pin: mute amp left and right (no volume) */ | ||
2487 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2543 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2488 | /* select Side mixer (0x0f, index 3) */ | ||
2489 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, | 2544 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, |
2490 | /* Headphone Pin */ | 2545 | /* Mic (rear) pin: input vref at 80% */ |
2491 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2492 | /* Headphone Pin: mute amp left and right (no volume) */ | ||
2493 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2494 | /* select Front mixer (0x0c, index 0) */ | ||
2495 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
2496 | /* Mic (rear) pin widget for input and vref at 80% */ | ||
2497 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 2546 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
2498 | /* Front Mic pin widget for input and vref at 80% */ | 2547 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
2548 | /* Front Mic pin: input vref at 80% */ | ||
2499 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 2549 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
2500 | /* Line In pin widget for input */ | 2550 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
2551 | /* Line In pin: input */ | ||
2501 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 2552 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
2553 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2554 | /* Line-2 In: Headphone output (output 0 - 0x0c) */ | ||
2555 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2556 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2557 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
2502 | /* CD pin widget for input */ | 2558 | /* CD pin widget for input */ |
2503 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 2559 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
2504 | 2560 | ||
@@ -2548,8 +2604,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
2548 | 2604 | ||
2549 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; | 2605 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; |
2550 | spec->dig_in_nid = ALC880_DIGIN_NID; | 2606 | spec->dig_in_nid = ALC880_DIGIN_NID; |
2551 | spec->front_panel = 1; | 2607 | spec->init_verbs[0] = alc882_init_verbs; |
2552 | spec->init_verbs = alc882_init_verbs; | 2608 | spec->num_init_verbs = 1; |
2609 | |||
2553 | spec->channel_mode = alc882_ch_modes; | 2610 | spec->channel_mode = alc882_ch_modes; |
2554 | spec->num_channel_mode = ARRAY_SIZE(alc882_ch_modes); | 2611 | spec->num_channel_mode = ARRAY_SIZE(alc882_ch_modes); |
2555 | 2612 | ||