Blame view
sound/pci/hda/patch_realtek.c
167 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 |
/* * Universal Interface for Intel High Definition Audio Codec * |
1d045db96 ALSA: hda - Split... |
4 |
* HD audio interface patch for Realtek ALC codecs |
1da177e4c Linux-2.6.12-rc2 |
5 |
* |
df694daa3 [ALSA] hda-codec ... |
6 7 |
* Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> * PeiSen Hou <pshou@realtek.com.tw> |
1da177e4c Linux-2.6.12-rc2 |
8 |
* Takashi Iwai <tiwai@suse.de> |
7cf51e483 [ALSA] hda: ALC26... |
9 |
* Jonathan Woithe <jwoithe@physics.adelaide.edu.au> |
1da177e4c Linux-2.6.12-rc2 |
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
* * This driver is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This driver is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
1da177e4c Linux-2.6.12-rc2 |
25 26 27 28 |
#include <linux/init.h> #include <linux/delay.h> #include <linux/slab.h> #include <linux/pci.h> |
da155d5b4 sound: Add module... |
29 |
#include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
30 |
#include <sound/core.h> |
9ad0e4965 ALSA: hda - Add i... |
31 |
#include <sound/jack.h> |
1da177e4c Linux-2.6.12-rc2 |
32 33 |
#include "hda_codec.h" #include "hda_local.h" |
680cd5365 ALSA: hda: Add di... |
34 |
#include "hda_beep.h" |
1835a0f9a ALSA: hda - Cache... |
35 |
#include "hda_jack.h" |
1da177e4c Linux-2.6.12-rc2 |
36 |
|
1d045db96 ALSA: hda - Split... |
37 38 39 40 41 |
/* unsol event tags */ #define ALC_FRONT_EVENT 0x01 #define ALC_DCVOL_EVENT 0x02 #define ALC_HP_EVENT 0x04 #define ALC_MIC_EVENT 0x08 |
d4a86d819 ALSA: hda - Add m... |
42 |
|
df694daa3 [ALSA] hda-codec ... |
43 44 |
/* for GPIO Poll */ #define GPIO_MASK 0x03 |
4a79ba34c ALSA: hda - Add a... |
45 46 47 48 49 50 51 52 |
/* extra amp-initialization sequence types */ enum { ALC_INIT_NONE, ALC_INIT_DEFAULT, ALC_INIT_GPIO1, ALC_INIT_GPIO2, ALC_INIT_GPIO3, }; |
da00c2449 ALSA: hda - Add p... |
53 54 55 56 57 58 59 60 61 62 |
struct alc_customize_define { unsigned int sku_cfg; unsigned char port_connectivity; unsigned char check_sum; unsigned char customization; unsigned char external_amp; unsigned int enable_pcbeep:1; unsigned int platform_type:1; unsigned int swap:1; unsigned int override:1; |
906229174 ALSA: HDA: Enable... |
63 |
unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ |
da00c2449 ALSA: hda - Add p... |
64 |
}; |
b5bfbc670 ALSA: hda - Reorg... |
65 |
struct alc_fixup; |
ce764ab22 ALSA: hda - Add c... |
66 67 68 69 70 |
struct alc_multi_io { hda_nid_t pin; /* multi-io widget pin NID */ hda_nid_t dac; /* DAC to be connected */ unsigned int ctl_in; /* cached input-pin control value */ }; |
d922b51da ALSA: hda - Conso... |
71 |
enum { |
3b8510ce9 ALSA: hda - Add c... |
72 73 74 |
ALC_AUTOMUTE_PIN, /* change the pin control */ ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */ ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ |
d922b51da ALSA: hda - Conso... |
75 |
}; |
1da177e4c Linux-2.6.12-rc2 |
76 77 |
struct alc_spec { /* codec parameterization */ |
a9111321f ALSA: hda - Const... |
78 |
const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ |
1da177e4c Linux-2.6.12-rc2 |
79 |
unsigned int num_mixers; |
a9111321f ALSA: hda - Const... |
80 |
const struct snd_kcontrol_new *cap_mixer; /* capture mixer */ |
45bdd1c1b ALSA: hda - Creat... |
81 |
unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ |
1da177e4c Linux-2.6.12-rc2 |
82 |
|
2d9c64829 ALSA: hda - Fix o... |
83 |
const struct hda_verb *init_verbs[10]; /* initialization verbs |
9c7f852e8 [ALSA] Fix/add su... |
84 85 |
* don't forget NULL * termination! |
e9edcee06 [ALSA] hda-codec ... |
86 87 |
*/ unsigned int num_init_verbs; |
1da177e4c Linux-2.6.12-rc2 |
88 |
|
aa563af76 ALSA: hda - Incre... |
89 |
char stream_name_analog[32]; /* analog PCM stream */ |
a9111321f ALSA: hda - Const... |
90 91 92 93 |
const struct hda_pcm_stream *stream_analog_playback; const struct hda_pcm_stream *stream_analog_capture; const struct hda_pcm_stream *stream_analog_alt_playback; const struct hda_pcm_stream *stream_analog_alt_capture; |
1da177e4c Linux-2.6.12-rc2 |
94 |
|
aa563af76 ALSA: hda - Incre... |
95 |
char stream_name_digital[32]; /* digital PCM stream */ |
a9111321f ALSA: hda - Const... |
96 97 |
const struct hda_pcm_stream *stream_digital_playback; const struct hda_pcm_stream *stream_digital_capture; |
1da177e4c Linux-2.6.12-rc2 |
98 99 |
/* playback */ |
16ded5253 [ALSA] hda-codec ... |
100 101 102 103 |
struct hda_multi_out multiout; /* playback set-up * max_channels, dacs must be set * dig_out_nid and hp_nid are optional */ |
6330079fc [ALSA] hda-codec ... |
104 |
hda_nid_t alt_dac_nid; |
6a05ac4af ALSA: hda - Suppo... |
105 |
hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ |
8c441982f ALSA: hda - Assig... |
106 |
int dig_out_type; |
1da177e4c Linux-2.6.12-rc2 |
107 108 109 |
/* capture */ unsigned int num_adc_nids; |
4c6d72d13 ALSA: hda - Const... |
110 111 |
const hda_nid_t *adc_nids; const hda_nid_t *capsrc_nids; |
16ded5253 [ALSA] hda-codec ... |
112 |
hda_nid_t dig_in_nid; /* digital-in NID; optional */ |
1f0f4b803 ALSA: hda - Reduc... |
113 |
hda_nid_t mixer_nid; /* analog-mixer NID */ |
527e4d73a ALSA: hda/realtek... |
114 115 |
DECLARE_BITMAP(vol_ctls, 0x20 << 1); DECLARE_BITMAP(sw_ctls, 0x20 << 1); |
1da177e4c Linux-2.6.12-rc2 |
116 |
|
840b64c08 ALSA: hda - Add s... |
117 |
/* capture setup for dynamic dual-adc switch */ |
840b64c08 ALSA: hda - Add s... |
118 119 120 |
hda_nid_t cur_adc; unsigned int cur_adc_stream_tag; unsigned int cur_adc_format; |
1da177e4c Linux-2.6.12-rc2 |
121 |
/* capture source */ |
a1e8d2da0 [ALSA] HDA/Realte... |
122 |
unsigned int num_mux_defs; |
1da177e4c Linux-2.6.12-rc2 |
123 124 |
const struct hda_input_mux *input_mux; unsigned int cur_mux[3]; |
21268961d ALSA: hda - More ... |
125 126 127 |
hda_nid_t ext_mic_pin; hda_nid_t dock_mic_pin; hda_nid_t int_mic_pin; |
1da177e4c Linux-2.6.12-rc2 |
128 129 |
/* channel model */ |
d2a6d7dc7 [ALSA] hda-codec ... |
130 |
const struct hda_channel_mode *channel_mode; |
1da177e4c Linux-2.6.12-rc2 |
131 |
int num_channel_mode; |
4e195a7b7 [ALSA] Fix noisy ... |
132 |
int need_dac_fix; |
3b315d70b ALSA: hda - Acer ... |
133 134 |
int const_channel_count; int ext_channel_count; |
1da177e4c Linux-2.6.12-rc2 |
135 136 |
/* PCM information */ |
4c5186ed6 [ALSA] hda: add P... |
137 |
struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ |
41e41f1f3 [ALSA] Fix the an... |
138 |
|
e9edcee06 [ALSA] hda-codec ... |
139 140 |
/* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; |
da00c2449 ALSA: hda - Add p... |
141 |
struct alc_customize_define cdefine; |
603c40199 ALSA: hda - Use g... |
142 |
struct snd_array kctls; |
61b9b9b10 ALSA: hda - Consi... |
143 |
struct hda_input_mux private_imux[3]; |
41923e441 [ALSA] hda-codec ... |
144 |
hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; |
4953550a6 ALSA: hda - Merge... |
145 146 |
hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; |
21268961d ALSA: hda - More ... |
147 148 149 |
hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */ |
834be88d1 [ALSA] hda-codec ... |
150 |
|
ae6b813a4 [ALSA] hda-codec ... |
151 152 153 |
/* hooks */ void (*init_hook)(struct hda_codec *codec); void (*unsol_event)(struct hda_codec *codec, unsigned int res); |
f5de24b06 ALSA: HDA: add po... |
154 |
#ifdef CONFIG_SND_HDA_POWER_SAVE |
c97259df3 ALSA: hda: Refact... |
155 |
void (*power_hook)(struct hda_codec *codec); |
f5de24b06 ALSA: HDA: add po... |
156 |
#endif |
1c716153a ALSA: hda - Intro... |
157 |
void (*shutup)(struct hda_codec *codec); |
245199116 ALSA: hda - Repla... |
158 |
void (*automute_hook)(struct hda_codec *codec); |
ae6b813a4 [ALSA] hda-codec ... |
159 |
|
834be88d1 [ALSA] hda-codec ... |
160 |
/* for pin sensing */ |
42cf0d015 ALSA: HDA: Refact... |
161 |
unsigned int hp_jack_present:1; |
e6a5e1b70 ALSA: hda - Add s... |
162 |
unsigned int line_jack_present:1; |
e9427969f ALSA: hda - Conso... |
163 |
unsigned int master_mute:1; |
6c8194922 ALSA: hda - Add a... |
164 |
unsigned int auto_mic:1; |
21268961d ALSA: hda - More ... |
165 |
unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */ |
42cf0d015 ALSA: HDA: Refact... |
166 167 168 169 170 171 |
unsigned int automute_speaker:1; /* automute speaker outputs */ unsigned int automute_lo:1; /* automute LO outputs */ unsigned int detect_hp:1; /* Headphone detection enabled */ unsigned int detect_lo:1; /* Line-out detection enabled */ unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ unsigned int automute_lo_possible:1; /* there are line outs and HP */ |
cb53c626e [ALSA] hda-intel ... |
172 |
|
e64f14f4e ALSA: hda - Allow... |
173 174 |
/* other flags */ unsigned int no_analog :1; /* digital I/O only */ |
21268961d ALSA: hda - More ... |
175 |
unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ |
584c0c4c3 ALSA: hda - Initi... |
176 |
unsigned int single_input_src:1; |
d6cc9fabd ALSA: hda - Parse... |
177 |
unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ |
53c334add ALSA: hda - Rewri... |
178 |
unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ |
24de183ed ALSA: hda/realtek... |
179 |
unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ |
3a93897ea ALSA: hda - Manag... |
180 |
unsigned int use_jack_tbl:1; /* 1 for model=auto */ |
d922b51da ALSA: hda - Conso... |
181 182 183 |
/* auto-mute control */ int automute_mode; |
3b8510ce9 ALSA: hda - Add c... |
184 |
hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS]; |
d922b51da ALSA: hda - Conso... |
185 |
|
4a79ba34c ALSA: hda - Add a... |
186 |
int init_amp; |
d433a6783 ALSA: hda - Optim... |
187 |
int codec_variant; /* flag for other variants */ |
e64f14f4e ALSA: hda - Allow... |
188 |
|
2134ea4f3 [ALSA] hda-codec ... |
189 190 |
/* for virtual master */ hda_nid_t vmaster_nid; |
cb53c626e [ALSA] hda-intel ... |
191 192 193 |
#ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_loopback_check loopback; #endif |
2c3bf9abb [ALSA] hda - Fix ... |
194 195 196 197 |
/* for PLL fix */ hda_nid_t pll_nid; unsigned int pll_coef_idx, pll_coef_bit; |
1bb7e43e2 ALSA: hda/realtek... |
198 |
unsigned int coef0; |
b5bfbc670 ALSA: hda - Reorg... |
199 200 201 202 203 |
/* fix-up list */ int fixup_id; const struct alc_fixup *fixup_list; const char *fixup_name; |
ce764ab22 ALSA: hda - Add c... |
204 205 206 207 |
/* multi-io */ int multi_ios; struct alc_multi_io multi_io[4]; |
23c09b009 ALSA: hda - Suppo... |
208 209 210 |
/* bind volumes */ struct snd_array bind_ctls; |
df694daa3 [ALSA] hda-codec ... |
211 |
}; |
1d045db96 ALSA: hda - Split... |
212 |
#define ALC_MODEL_AUTO 0 /* common for all chips */ |
1da177e4c Linux-2.6.12-rc2 |
213 |
|
44c024005 ALSA: hda - Fix a... |
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, unsigned int bits) { if (!nid) return false; if (get_wcaps(codec, nid) & (1 << (dir + 1))) if (query_amp_caps(codec, nid, dir) & bits) return true; return false; } #define nid_has_mute(codec, nid, dir) \ check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE) #define nid_has_volume(codec, nid, dir) \ check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS) |
1da177e4c Linux-2.6.12-rc2 |
229 230 231 |
/* * input MUX handling */ |
9c7f852e8 [ALSA] Fix/add su... |
232 233 |
static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1da177e4c Linux-2.6.12-rc2 |
234 235 236 |
{ struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; |
a1e8d2da0 [ALSA] HDA/Realte... |
237 238 239 |
unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); if (mux_idx >= spec->num_mux_defs) mux_idx = 0; |
5311114d4 ALSA: hda - Fix i... |
240 241 |
if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) mux_idx = 0; |
a1e8d2da0 [ALSA] HDA/Realte... |
242 |
return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); |
1da177e4c Linux-2.6.12-rc2 |
243 |
} |
9c7f852e8 [ALSA] Fix/add su... |
244 245 |
static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
1da177e4c Linux-2.6.12-rc2 |
246 247 248 249 250 251 252 253 |
{ struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; return 0; } |
21268961d ALSA: hda - More ... |
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) { struct alc_spec *spec = codec->spec; hda_nid_t new_adc = spec->adc_nids[spec->dyn_adc_idx[cur]]; if (spec->cur_adc && spec->cur_adc != new_adc) { /* stream is running, let's swap the current ADC */ __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); spec->cur_adc = new_adc; snd_hda_codec_setup_stream(codec, new_adc, spec->cur_adc_stream_tag, 0, spec->cur_adc_format); return true; } return false; } |
61071594f ALSA: hda/realtek... |
270 271 272 273 274 |
static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) { return spec->capsrc_nids ? spec->capsrc_nids[idx] : spec->adc_nids[idx]; } |
24de183ed ALSA: hda/realtek... |
275 |
static void call_update_outputs(struct hda_codec *codec); |
21268961d ALSA: hda - More ... |
276 277 278 |
/* select the given imux item; either unmute exclusively or select the route */ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, unsigned int idx, bool force) |
1da177e4c Linux-2.6.12-rc2 |
279 |
{ |
1da177e4c Linux-2.6.12-rc2 |
280 |
struct alc_spec *spec = codec->spec; |
cd896c331 ALSA: hda - Allow... |
281 |
const struct hda_input_mux *imux; |
cd896c331 ALSA: hda - Allow... |
282 |
unsigned int mux_idx; |
dccc1810f ALSA: hda - Mute ... |
283 |
int i, type, num_conns; |
21268961d ALSA: hda - More ... |
284 |
hda_nid_t nid; |
1da177e4c Linux-2.6.12-rc2 |
285 |
|
cd896c331 ALSA: hda - Allow... |
286 287 |
mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; imux = &spec->input_mux[mux_idx]; |
5311114d4 ALSA: hda - Fix i... |
288 289 |
if (!imux->num_items && mux_idx > 0) imux = &spec->input_mux[0]; |
cce4aa378 ALSA: hda/realtek... |
290 291 |
if (!imux->num_items) return 0; |
cd896c331 ALSA: hda - Allow... |
292 |
|
21268961d ALSA: hda - More ... |
293 294 295 296 297 |
if (idx >= imux->num_items) idx = imux->num_items - 1; if (spec->cur_mux[adc_idx] == idx && !force) return 0; spec->cur_mux[adc_idx] = idx; |
24de183ed ALSA: hda/realtek... |
298 299 300 301 302 303 304 305 306 307 308 309 |
/* for shared I/O, change the pin-control accordingly */ if (spec->shared_mic_hp) { /* NOTE: this assumes that there are only two inputs, the * first is the real internal mic and the second is HP jack. */ snd_hda_codec_write(codec, spec->autocfg.inputs[1].pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->cur_mux[adc_idx] ? PIN_VREF80 : PIN_HP); spec->automute_speaker = !spec->cur_mux[adc_idx]; call_update_outputs(codec); } |
21268961d ALSA: hda - More ... |
310 311 312 313 |
if (spec->dyn_adc_switch) { alc_dyn_adc_pcm_resetup(codec, idx); adc_idx = spec->dyn_adc_idx[idx]; } |
61071594f ALSA: hda/realtek... |
314 |
nid = get_capsrc(spec, adc_idx); |
21268961d ALSA: hda - More ... |
315 316 |
/* no selection? */ |
dccc1810f ALSA: hda - Mute ... |
317 318 |
num_conns = snd_hda_get_conn_list(codec, nid, NULL); if (num_conns <= 1) |
21268961d ALSA: hda - More ... |
319 |
return 1; |
a22d543a9 ALSA: hda - Intro... |
320 |
type = get_wcaps_type(get_wcaps(codec, nid)); |
0169b6b33 ALSA: hda - Fix c... |
321 |
if (type == AC_WID_AUD_MIX) { |
54cbc9abe ALSA: hda - Unify... |
322 |
/* Matrix-mixer style (e.g. ALC882) */ |
dccc1810f ALSA: hda - Mute ... |
323 324 325 326 |
int active = imux->items[idx].index; for (i = 0; i < num_conns; i++) { unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE; snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i, |
54cbc9abe ALSA: hda - Unify... |
327 328 |
HDA_AMP_MUTE, v); } |
54cbc9abe ALSA: hda - Unify... |
329 330 |
} else { /* MUX style (e.g. ALC880) */ |
21268961d ALSA: hda - More ... |
331 332 333 |
snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, imux->items[idx].index); |
54cbc9abe ALSA: hda - Unify... |
334 |
} |
21268961d ALSA: hda - More ... |
335 336 337 338 339 340 341 342 343 344 |
return 1; } static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); return alc_mux_select(codec, adc_idx, ucontrol->value.enumerated.item[0], false); |
54cbc9abe ALSA: hda - Unify... |
345 |
} |
e9edcee06 [ALSA] hda-codec ... |
346 |
|
1da177e4c Linux-2.6.12-rc2 |
347 |
/* |
23f0c048b ALSA: hda - Clean... |
348 349 350 351 352 353 |
* set up the input pin config (depending on the given auto-pin type) */ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, int auto_pin_type) { unsigned int val = PIN_IN; |
86e2959a1 ALSA: hda - Remov... |
354 |
if (auto_pin_type == AUTO_PIN_MIC) { |
23f0c048b ALSA: hda - Clean... |
355 |
unsigned int pincap; |
954a29c88 ALSA: hda - Prefe... |
356 357 358 |
unsigned int oldval; oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
1327a32b8 ALSA: hda - Cache... |
359 |
pincap = snd_hda_query_pin_caps(codec, nid); |
23f0c048b ALSA: hda - Clean... |
360 |
pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; |
954a29c88 ALSA: hda - Prefe... |
361 362 |
/* if the default pin setup is vref50, we give it priority */ if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) |
23f0c048b ALSA: hda - Clean... |
363 |
val = PIN_VREF80; |
461c6c3a0 ALSA: hda - Add m... |
364 365 366 367 368 369 |
else if (pincap & AC_PINCAP_VREF_50) val = PIN_VREF50; else if (pincap & AC_PINCAP_VREF_100) val = PIN_VREF100; else if (pincap & AC_PINCAP_VREF_GRD) val = PIN_VREFGRD; |
23f0c048b ALSA: hda - Clean... |
370 371 372 373 374 |
} snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); } /* |
1d045db96 ALSA: hda - Split... |
375 376 377 |
* Append the given mixer and verb elements for the later use * The mixer array is referred in build_controls(), and init_verbs are * called in init(). |
d88897eae ALSA: hda - Use m... |
378 |
*/ |
a9111321f ALSA: hda - Const... |
379 |
static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) |
d88897eae ALSA: hda - Use m... |
380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
{ if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) return; spec->mixers[spec->num_mixers++] = mix; } static void add_verb(struct alc_spec *spec, const struct hda_verb *verb) { if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs))) return; spec->init_verbs[spec->num_init_verbs++] = verb; } /* |
1d045db96 ALSA: hda - Split... |
394 |
* GPIO setup tables, used in initialization |
df694daa3 [ALSA] hda-codec ... |
395 |
*/ |
bc9f98a98 [ALSA] hda-codec ... |
396 |
/* Enable GPIO mask and set output */ |
a9111321f ALSA: hda - Const... |
397 |
static const struct hda_verb alc_gpio1_init_verbs[] = { |
bc9f98a98 [ALSA] hda-codec ... |
398 399 400 401 402 |
{0x01, AC_VERB_SET_GPIO_MASK, 0x01}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, { } }; |
a9111321f ALSA: hda - Const... |
403 |
static const struct hda_verb alc_gpio2_init_verbs[] = { |
bc9f98a98 [ALSA] hda-codec ... |
404 405 406 407 408 |
{0x01, AC_VERB_SET_GPIO_MASK, 0x02}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, { } }; |
a9111321f ALSA: hda - Const... |
409 |
static const struct hda_verb alc_gpio3_init_verbs[] = { |
bdd148a30 [ALSA] hda-codec ... |
410 411 412 413 414 |
{0x01, AC_VERB_SET_GPIO_MASK, 0x03}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, { } }; |
2c3bf9abb [ALSA] hda - Fix ... |
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
/* * Fix hardware PLL issue * On some codecs, the analog PLL gating control must be off while * the default value is 1. */ static void alc_fix_pll(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; unsigned int val; if (!spec->pll_nid) return; snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, spec->pll_coef_idx); val = snd_hda_codec_read(codec, spec->pll_nid, 0, AC_VERB_GET_PROC_COEF, 0); snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, spec->pll_coef_idx); snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, val & ~(1 << spec->pll_coef_bit)); } static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, unsigned int coef_idx, unsigned int coef_bit) { struct alc_spec *spec = codec->spec; spec->pll_nid = nid; spec->pll_coef_idx = coef_idx; spec->pll_coef_bit = coef_bit; alc_fix_pll(codec); } |
1d045db96 ALSA: hda - Split... |
446 |
/* |
1d045db96 ALSA: hda - Split... |
447 448 449 450 451 |
* Jack detections for HP auto-mute and mic-switch */ /* check each pin in the given array; returns true if any of them is plugged */ static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) |
c9b58006b [ALSA] hda-codec ... |
452 |
{ |
e6a5e1b70 ALSA: hda - Add s... |
453 |
int i, present = 0; |
c9b58006b [ALSA] hda-codec ... |
454 |
|
e6a5e1b70 ALSA: hda - Add s... |
455 456 |
for (i = 0; i < num_pins; i++) { hda_nid_t nid = pins[i]; |
bb35febd1 ALSA: hda - Suppo... |
457 458 |
if (!nid) break; |
e6a5e1b70 ALSA: hda - Add s... |
459 |
present |= snd_hda_jack_detect(codec, nid); |
bb35febd1 ALSA: hda - Suppo... |
460 |
} |
e6a5e1b70 ALSA: hda - Add s... |
461 462 |
return present; } |
bb35febd1 ALSA: hda - Suppo... |
463 |
|
1d045db96 ALSA: hda - Split... |
464 |
/* standard HP/line-out auto-mute helper */ |
e6a5e1b70 ALSA: hda - Add s... |
465 |
static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, |
e9427969f ALSA: hda - Conso... |
466 |
bool mute, bool hp_out) |
e6a5e1b70 ALSA: hda - Add s... |
467 468 469 |
{ struct alc_spec *spec = codec->spec; unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0; |
e9427969f ALSA: hda - Conso... |
470 |
unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT); |
e6a5e1b70 ALSA: hda - Add s... |
471 472 473 474 |
int i; for (i = 0; i < num_pins; i++) { hda_nid_t nid = pins[i]; |
a9fd4f3fc ALSA: hda - Clean... |
475 476 |
if (!nid) break; |
3b8510ce9 ALSA: hda - Add c... |
477 478 |
switch (spec->automute_mode) { case ALC_AUTOMUTE_PIN: |
bb35febd1 ALSA: hda - Suppo... |
479 |
snd_hda_codec_write(codec, nid, 0, |
e6a5e1b70 ALSA: hda - Add s... |
480 481 |
AC_VERB_SET_PIN_WIDGET_CONTROL, pin_bits); |
3b8510ce9 ALSA: hda - Add c... |
482 483 |
break; case ALC_AUTOMUTE_AMP: |
bb35febd1 ALSA: hda - Suppo... |
484 |
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, |
e6a5e1b70 ALSA: hda - Add s... |
485 |
HDA_AMP_MUTE, mute_bits); |
3b8510ce9 ALSA: hda - Add c... |
486 487 488 489 490 491 |
break; case ALC_AUTOMUTE_MIXER: nid = spec->automute_mixer_nid[i]; if (!nid) break; snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, |
e6a5e1b70 ALSA: hda - Add s... |
492 |
HDA_AMP_MUTE, mute_bits); |
3b8510ce9 ALSA: hda - Add c... |
493 |
snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1, |
e6a5e1b70 ALSA: hda - Add s... |
494 |
HDA_AMP_MUTE, mute_bits); |
3b8510ce9 ALSA: hda - Add c... |
495 |
break; |
bb35febd1 ALSA: hda - Suppo... |
496 |
} |
a9fd4f3fc ALSA: hda - Clean... |
497 |
} |
c9b58006b [ALSA] hda-codec ... |
498 |
} |
42cf0d015 ALSA: HDA: Refact... |
499 500 |
/* Toggle outputs muting */ static void update_outputs(struct hda_codec *codec) |
e6a5e1b70 ALSA: hda - Add s... |
501 502 |
{ struct alc_spec *spec = codec->spec; |
1a1455de1 ALSA: hda - Add s... |
503 |
int on; |
e6a5e1b70 ALSA: hda - Add s... |
504 |
|
c0a20263d ALSA: hda - Fix i... |
505 506 507 508 |
/* Control HP pins/amps depending on master_mute state; * in general, HP pins/amps control should be enabled in all cases, * but currently set only for master_mute, just to be safe */ |
24de183ed ALSA: hda/realtek... |
509 510 |
if (!spec->shared_mic_hp) /* don't change HP-pin when shared with mic */ do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), |
c0a20263d ALSA: hda - Fix i... |
511 |
spec->autocfg.hp_pins, spec->master_mute, true); |
42cf0d015 ALSA: HDA: Refact... |
512 |
if (!spec->automute_speaker) |
1a1455de1 ALSA: hda - Add s... |
513 514 |
on = 0; else |
42cf0d015 ALSA: HDA: Refact... |
515 |
on = spec->hp_jack_present | spec->line_jack_present; |
1a1455de1 ALSA: hda - Add s... |
516 |
on |= spec->master_mute; |
e6a5e1b70 ALSA: hda - Add s... |
517 |
do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), |
1a1455de1 ALSA: hda - Add s... |
518 |
spec->autocfg.speaker_pins, on, false); |
e6a5e1b70 ALSA: hda - Add s... |
519 520 |
/* toggle line-out mutes if needed, too */ |
1a1455de1 ALSA: hda - Add s... |
521 522 523 |
/* if LO is a copy of either HP or Speaker, don't need to handle it */ if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) |
e6a5e1b70 ALSA: hda - Add s... |
524 |
return; |
42cf0d015 ALSA: HDA: Refact... |
525 |
if (!spec->automute_lo) |
1a1455de1 ALSA: hda - Add s... |
526 527 |
on = 0; else |
42cf0d015 ALSA: HDA: Refact... |
528 |
on = spec->hp_jack_present; |
1a1455de1 ALSA: hda - Add s... |
529 |
on |= spec->master_mute; |
e6a5e1b70 ALSA: hda - Add s... |
530 |
do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), |
1a1455de1 ALSA: hda - Add s... |
531 |
spec->autocfg.line_out_pins, on, false); |
e6a5e1b70 ALSA: hda - Add s... |
532 |
} |
42cf0d015 ALSA: HDA: Refact... |
533 |
static void call_update_outputs(struct hda_codec *codec) |
245199116 ALSA: hda - Repla... |
534 535 536 537 538 |
{ struct alc_spec *spec = codec->spec; if (spec->automute_hook) spec->automute_hook(codec); else |
42cf0d015 ALSA: HDA: Refact... |
539 |
update_outputs(codec); |
245199116 ALSA: hda - Repla... |
540 |
} |
1d045db96 ALSA: hda - Split... |
541 |
/* standard HP-automute helper */ |
e6a5e1b70 ALSA: hda - Add s... |
542 543 544 |
static void alc_hp_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; |
42cf0d015 ALSA: HDA: Refact... |
545 |
spec->hp_jack_present = |
e6a5e1b70 ALSA: hda - Add s... |
546 547 |
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), spec->autocfg.hp_pins); |
42cf0d015 ALSA: HDA: Refact... |
548 |
if (!spec->detect_hp || (!spec->automute_speaker && !spec->automute_lo)) |
3c715a988 ALSA: hda - Updat... |
549 |
return; |
42cf0d015 ALSA: HDA: Refact... |
550 |
call_update_outputs(codec); |
e6a5e1b70 ALSA: hda - Add s... |
551 |
} |
1d045db96 ALSA: hda - Split... |
552 |
/* standard line-out-automute helper */ |
e6a5e1b70 ALSA: hda - Add s... |
553 554 555 |
static void alc_line_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; |
e0d32e335 ALSA: hda/realtek... |
556 557 558 |
/* check LO jack only when it's different from HP */ if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0]) return; |
e6a5e1b70 ALSA: hda - Add s... |
559 560 561 |
spec->line_jack_present = detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), spec->autocfg.line_out_pins); |
42cf0d015 ALSA: HDA: Refact... |
562 |
if (!spec->automute_speaker || !spec->detect_lo) |
3c715a988 ALSA: hda - Updat... |
563 |
return; |
42cf0d015 ALSA: HDA: Refact... |
564 |
call_update_outputs(codec); |
e6a5e1b70 ALSA: hda - Add s... |
565 |
} |
8d087c760 ALSA: hda - Creat... |
566 567 |
#define get_connection_index(codec, mux, nid) \ snd_hda_get_conn_index(codec, mux, nid, 0) |
6c8194922 ALSA: hda - Add a... |
568 |
|
1d045db96 ALSA: hda - Split... |
569 |
/* standard mic auto-switch helper */ |
7fb0d78fb ALSA: hda - Add a... |
570 571 572 |
static void alc_mic_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; |
21268961d ALSA: hda - More ... |
573 |
hda_nid_t *pins = spec->imux_pins; |
6c8194922 ALSA: hda - Add a... |
574 |
|
21268961d ALSA: hda - More ... |
575 |
if (!spec->auto_mic || !spec->auto_mic_valid_imux) |
6c8194922 ALSA: hda - Add a... |
576 577 578 |
return; if (snd_BUG_ON(!spec->adc_nids)) return; |
21268961d ALSA: hda - More ... |
579 |
if (snd_BUG_ON(spec->int_mic_idx < 0 || spec->ext_mic_idx < 0)) |
840b64c08 ALSA: hda - Add s... |
580 |
return; |
6c8194922 ALSA: hda - Add a... |
581 |
|
21268961d ALSA: hda - More ... |
582 583 584 585 586 587 588 |
if (snd_hda_jack_detect(codec, pins[spec->ext_mic_idx])) alc_mux_select(codec, 0, spec->ext_mic_idx, false); else if (spec->dock_mic_idx >= 0 && snd_hda_jack_detect(codec, pins[spec->dock_mic_idx])) alc_mux_select(codec, 0, spec->dock_mic_idx, false); else alc_mux_select(codec, 0, spec->int_mic_idx, false); |
7fb0d78fb ALSA: hda - Add a... |
589 |
} |
c9b58006b [ALSA] hda-codec ... |
590 591 592 |
/* unsolicited event for HP jack sensing */ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) { |
3a93897ea ALSA: hda - Manag... |
593 |
struct alc_spec *spec = codec->spec; |
c9b58006b [ALSA] hda-codec ... |
594 595 596 597 |
if (codec->vendor_id == 0x10ec0880) res >>= 28; else res >>= 26; |
3a93897ea ALSA: hda - Manag... |
598 599 |
if (spec->use_jack_tbl) res = snd_hda_jack_get_action(codec, res); |
a9fd4f3fc ALSA: hda - Clean... |
600 |
switch (res) { |
1d045db96 ALSA: hda - Split... |
601 |
case ALC_HP_EVENT: |
d922b51da ALSA: hda - Conso... |
602 |
alc_hp_automute(codec); |
a9fd4f3fc ALSA: hda - Clean... |
603 |
break; |
1d045db96 ALSA: hda - Split... |
604 |
case ALC_FRONT_EVENT: |
e6a5e1b70 ALSA: hda - Add s... |
605 606 |
alc_line_automute(codec); break; |
1d045db96 ALSA: hda - Split... |
607 |
case ALC_MIC_EVENT: |
7fb0d78fb ALSA: hda - Add a... |
608 |
alc_mic_automute(codec); |
a9fd4f3fc ALSA: hda - Clean... |
609 610 |
break; } |
01a61e12b ALSA: hda - Creat... |
611 |
snd_hda_jack_report_sync(codec); |
7fb0d78fb ALSA: hda - Add a... |
612 |
} |
1d045db96 ALSA: hda - Split... |
613 |
/* call init functions of standard auto-mute helpers */ |
7fb0d78fb ALSA: hda - Add a... |
614 615 |
static void alc_inithook(struct hda_codec *codec) { |
d922b51da ALSA: hda - Conso... |
616 |
alc_hp_automute(codec); |
e6a5e1b70 ALSA: hda - Add s... |
617 |
alc_line_automute(codec); |
7fb0d78fb ALSA: hda - Add a... |
618 |
alc_mic_automute(codec); |
c9b58006b [ALSA] hda-codec ... |
619 |
} |
f9423e7a9 [ALSA] hda - Fix ... |
620 621 622 623 624 625 626 627 |
/* additional initialization for ALC888 variants */ static void alc888_coef_init(struct hda_codec *codec) { unsigned int tmp; snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); |
37db623ae ALSA: hda - Fix c... |
628 |
if ((tmp & 0xf0) == 0x20) |
f9423e7a9 [ALSA] hda - Fix ... |
629 630 631 632 633 634 635 636 |
/* alc888S-VC */ snd_hda_codec_read(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0x830); else /* alc888-VB */ snd_hda_codec_read(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0x3030); } |
1d045db96 ALSA: hda - Split... |
637 |
/* additional initialization for ALC889 variants */ |
87a8c3702 ALSA: hda - Add b... |
638 639 640 641 642 643 644 645 646 |
static void alc889_coef_init(struct hda_codec *codec) { unsigned int tmp; snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); } |
3fb4a508b ALSA: hda - Turn ... |
647 648 649 650 651 652 653 654 655 |
/* turn on/off EAPD control (only if available) */ static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) { if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) return; if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, on ? 2 : 0); } |
691f1fccf ALSA: hda - Refac... |
656 657 658 659 |
/* turn on/off EAPD controls of the codec */ static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) { /* We currently only handle front, HP */ |
39fa84e94 ALSA: hda - Simpl... |
660 661 662 663 664 665 |
static hda_nid_t pins[] = { 0x0f, 0x10, 0x14, 0x15, 0 }; hda_nid_t *p; for (p = pins; *p; p++) set_eapd(codec, *p, on); |
691f1fccf ALSA: hda - Refac... |
666 |
} |
1c716153a ALSA: hda - Intro... |
667 668 669 670 671 672 673 674 |
/* generic shutup callback; * just turning off EPAD and a little pause for avoiding pop-noise */ static void alc_eapd_shutup(struct hda_codec *codec) { alc_auto_setup_eapd(codec, false); msleep(200); } |
1d045db96 ALSA: hda - Split... |
675 |
/* generic EAPD initialization */ |
4a79ba34c ALSA: hda - Add a... |
676 |
static void alc_auto_init_amp(struct hda_codec *codec, int type) |
bc9f98a98 [ALSA] hda-codec ... |
677 |
{ |
4a79ba34c ALSA: hda - Add a... |
678 |
unsigned int tmp; |
bc9f98a98 [ALSA] hda-codec ... |
679 |
|
39fa84e94 ALSA: hda - Simpl... |
680 |
alc_auto_setup_eapd(codec, true); |
4a79ba34c ALSA: hda - Add a... |
681 682 |
switch (type) { case ALC_INIT_GPIO1: |
bc9f98a98 [ALSA] hda-codec ... |
683 684 |
snd_hda_sequence_write(codec, alc_gpio1_init_verbs); break; |
4a79ba34c ALSA: hda - Add a... |
685 |
case ALC_INIT_GPIO2: |
bc9f98a98 [ALSA] hda-codec ... |
686 687 |
snd_hda_sequence_write(codec, alc_gpio2_init_verbs); break; |
4a79ba34c ALSA: hda - Add a... |
688 |
case ALC_INIT_GPIO3: |
bdd148a30 [ALSA] hda-codec ... |
689 690 |
snd_hda_sequence_write(codec, alc_gpio3_init_verbs); break; |
4a79ba34c ALSA: hda - Add a... |
691 |
case ALC_INIT_DEFAULT: |
c9b58006b [ALSA] hda-codec ... |
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 |
switch (codec->vendor_id) { case 0x10ec0260: snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); tmp = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PROC_COEF, 0); snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x2010); break; case 0x10ec0262: case 0x10ec0880: case 0x10ec0882: case 0x10ec0883: case 0x10ec0885: |
4a5a4c56b ALSA: hda - Add m... |
709 |
case 0x10ec0887: |
20b67dddc ALSA: hda - Fix S... |
710 |
/*case 0x10ec0889:*/ /* this causes an SPDIF problem */ |
87a8c3702 ALSA: hda - Add b... |
711 |
alc889_coef_init(codec); |
c9b58006b [ALSA] hda-codec ... |
712 |
break; |
f9423e7a9 [ALSA] hda - Fix ... |
713 |
case 0x10ec0888: |
4a79ba34c ALSA: hda - Add a... |
714 |
alc888_coef_init(codec); |
f9423e7a9 [ALSA] hda - Fix ... |
715 |
break; |
0aea778ef ALSA: hda - Remov... |
716 |
#if 0 /* XXX: This may cause the silent output on speaker on some machines */ |
c9b58006b [ALSA] hda-codec ... |
717 718 719 720 721 722 723 |
case 0x10ec0267: case 0x10ec0268: snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); snd_hda_codec_write(codec, 0x20, 0, |
ea1fb29ac ALSA: hda - fix s... |
724 |
AC_VERB_SET_COEF_INDEX, 7); |
c9b58006b [ALSA] hda-codec ... |
725 726 727 728 |
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp | 0x3000); break; |
0aea778ef ALSA: hda - Remov... |
729 |
#endif /* XXX */ |
bc9f98a98 [ALSA] hda-codec ... |
730 |
} |
4a79ba34c ALSA: hda - Add a... |
731 732 733 |
break; } } |
1d045db96 ALSA: hda - Split... |
734 735 736 |
/* * Auto-Mute mode mixer enum support */ |
1a1455de1 ALSA: hda - Add s... |
737 738 739 |
static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { |
ae8a60a59 ALSA: hda - Add A... |
740 741 742 743 744 745 |
struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; static const char * const texts2[] = { "Disabled", "Enabled" }; static const char * const texts3[] = { |
1a1455de1 ALSA: hda - Add s... |
746 747 |
"Disabled", "Speaker Only", "Line-Out+Speaker" }; |
ae8a60a59 ALSA: hda - Add A... |
748 |
const char * const *texts; |
1a1455de1 ALSA: hda - Add s... |
749 750 751 |
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; |
42cf0d015 ALSA: HDA: Refact... |
752 |
if (spec->automute_speaker_possible && spec->automute_lo_possible) { |
ae8a60a59 ALSA: hda - Add A... |
753 754 755 756 757 758 759 760 |
uinfo->value.enumerated.items = 3; texts = texts3; } else { uinfo->value.enumerated.items = 2; texts = texts2; } if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; |
1a1455de1 ALSA: hda - Add s... |
761 762 763 764 765 766 767 768 769 770 |
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); return 0; } static int alc_automute_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; |
42cf0d015 ALSA: HDA: Refact... |
771 772 773 774 775 |
unsigned int val = 0; if (spec->automute_speaker) val++; if (spec->automute_lo) val++; |
1a1455de1 ALSA: hda - Add s... |
776 777 778 779 780 781 782 783 784 785 786 787 |
ucontrol->value.enumerated.item[0] = val; return 0; } static int alc_automute_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; switch (ucontrol->value.enumerated.item[0]) { case 0: |
42cf0d015 ALSA: HDA: Refact... |
788 |
if (!spec->automute_speaker && !spec->automute_lo) |
1a1455de1 ALSA: hda - Add s... |
789 |
return 0; |
42cf0d015 ALSA: HDA: Refact... |
790 791 |
spec->automute_speaker = 0; spec->automute_lo = 0; |
1a1455de1 ALSA: hda - Add s... |
792 793 |
break; case 1: |
42cf0d015 ALSA: HDA: Refact... |
794 795 796 797 798 799 800 801 802 803 804 |
if (spec->automute_speaker_possible) { if (!spec->automute_lo && spec->automute_speaker) return 0; spec->automute_speaker = 1; spec->automute_lo = 0; } else if (spec->automute_lo_possible) { if (spec->automute_lo) return 0; spec->automute_lo = 1; } else return -EINVAL; |
1a1455de1 ALSA: hda - Add s... |
805 806 |
break; case 2: |
42cf0d015 ALSA: HDA: Refact... |
807 |
if (!spec->automute_lo_possible || !spec->automute_speaker_possible) |
ae8a60a59 ALSA: hda - Add A... |
808 |
return -EINVAL; |
42cf0d015 ALSA: HDA: Refact... |
809 |
if (spec->automute_speaker && spec->automute_lo) |
1a1455de1 ALSA: hda - Add s... |
810 |
return 0; |
42cf0d015 ALSA: HDA: Refact... |
811 812 |
spec->automute_speaker = 1; spec->automute_lo = 1; |
1a1455de1 ALSA: hda - Add s... |
813 814 815 816 |
break; default: return -EINVAL; } |
42cf0d015 ALSA: HDA: Refact... |
817 |
call_update_outputs(codec); |
1a1455de1 ALSA: hda - Add s... |
818 819 |
return 1; } |
a9111321f ALSA: hda - Const... |
820 |
static const struct snd_kcontrol_new alc_automute_mode_enum = { |
1a1455de1 ALSA: hda - Add s... |
821 822 823 824 825 826 |
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Auto-Mute Mode", .info = alc_automute_mode_info, .get = alc_automute_mode_get, .put = alc_automute_mode_put, }; |
1d045db96 ALSA: hda - Split... |
827 828 829 830 831 |
static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec) { snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); return snd_array_new(&spec->kctls); } |
1a1455de1 ALSA: hda - Add s... |
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 |
static int alc_add_automute_mode_enum(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct snd_kcontrol_new *knew; knew = alc_kcontrol_new(spec); if (!knew) return -ENOMEM; *knew = alc_automute_mode_enum; knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL); if (!knew->name) return -ENOMEM; return 0; } |
1d045db96 ALSA: hda - Split... |
847 848 849 850 |
/* * Check the availability of HP/line-out auto-mute; * Set up appropriately if really supported */ |
42cf0d015 ALSA: HDA: Refact... |
851 |
static void alc_init_automute(struct hda_codec *codec) |
4a79ba34c ALSA: hda - Add a... |
852 853 |
{ struct alc_spec *spec = codec->spec; |
bb35febd1 ALSA: hda - Suppo... |
854 |
struct auto_pin_cfg *cfg = &spec->autocfg; |
1daf5f46c ALSA: hda - More ... |
855 |
int present = 0; |
bb35febd1 ALSA: hda - Suppo... |
856 |
int i; |
4a79ba34c ALSA: hda - Add a... |
857 |
|
1daf5f46c ALSA: hda - More ... |
858 859 860 861 862 863 864 865 |
if (cfg->hp_pins[0]) present++; if (cfg->line_out_pins[0]) present++; if (cfg->speaker_pins[0]) present++; if (present < 2) /* need two different output types */ return; |
4a79ba34c ALSA: hda - Add a... |
866 |
|
c48a8fb0d ALSA: hda - Fix d... |
867 868 |
if (!cfg->speaker_pins[0] && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { |
bb35febd1 ALSA: hda - Suppo... |
869 870 871 872 |
memcpy(cfg->speaker_pins, cfg->line_out_pins, sizeof(cfg->speaker_pins)); cfg->speaker_outs = cfg->line_outs; } |
c48a8fb0d ALSA: hda - Fix d... |
873 874 |
if (!cfg->hp_pins[0] && cfg->line_out_type == AUTO_PIN_HP_OUT) { |
bb35febd1 ALSA: hda - Suppo... |
875 876 877 |
memcpy(cfg->hp_pins, cfg->line_out_pins, sizeof(cfg->hp_pins)); cfg->hp_outs = cfg->line_outs; |
4a79ba34c ALSA: hda - Add a... |
878 |
} |
42cf0d015 ALSA: HDA: Refact... |
879 |
spec->automute_mode = ALC_AUTOMUTE_PIN; |
bb35febd1 ALSA: hda - Suppo... |
880 |
for (i = 0; i < cfg->hp_outs; i++) { |
1a1455de1 ALSA: hda - Add s... |
881 |
hda_nid_t nid = cfg->hp_pins[i]; |
06dec2282 ALSA: hda - Use i... |
882 |
if (!is_jack_detectable(codec, nid)) |
1a1455de1 ALSA: hda - Add s... |
883 |
continue; |
bb35febd1 ALSA: hda - Suppo... |
884 885 |
snd_printdd("realtek: Enable HP auto-muting on NID 0x%x ", |
1a1455de1 ALSA: hda - Add s... |
886 |
nid); |
1835a0f9a ALSA: hda - Cache... |
887 |
snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT); |
42cf0d015 ALSA: HDA: Refact... |
888 889 890 891 892 893 894 895 896 897 898 899 |
spec->detect_hp = 1; } if (cfg->line_out_type == AUTO_PIN_LINE_OUT && cfg->line_outs) { if (cfg->speaker_outs) for (i = 0; i < cfg->line_outs; i++) { hda_nid_t nid = cfg->line_out_pins[i]; if (!is_jack_detectable(codec, nid)) continue; snd_printdd("realtek: Enable Line-Out " "auto-muting on NID 0x%x ", nid); |
1835a0f9a ALSA: hda - Cache... |
900 901 |
snd_hda_jack_detect_enable(codec, nid, ALC_FRONT_EVENT); |
42cf0d015 ALSA: HDA: Refact... |
902 |
spec->detect_lo = 1; |
1a1455de1 ALSA: hda - Add s... |
903 |
} |
42cf0d015 ALSA: HDA: Refact... |
904 |
spec->automute_lo_possible = spec->detect_hp; |
ae8a60a59 ALSA: hda - Add A... |
905 |
} |
42cf0d015 ALSA: HDA: Refact... |
906 907 908 909 910 911 912 |
spec->automute_speaker_possible = cfg->speaker_outs && (spec->detect_hp || spec->detect_lo); spec->automute_lo = spec->automute_lo_possible; spec->automute_speaker = spec->automute_speaker_possible; if (spec->automute_speaker_possible || spec->automute_lo_possible) { |
1a1455de1 ALSA: hda - Add s... |
913 914 |
/* create a control for automute mode */ alc_add_automute_mode_enum(codec); |
ae8a60a59 ALSA: hda - Add A... |
915 |
spec->unsol_event = alc_sku_unsol_event; |
1a1455de1 ALSA: hda - Add s... |
916 |
} |
4a79ba34c ALSA: hda - Add a... |
917 |
} |
1d045db96 ALSA: hda - Split... |
918 |
/* return the position of NID in the list, or -1 if not found */ |
21268961d ALSA: hda - More ... |
919 920 921 922 923 924 925 926 |
static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) { int i; for (i = 0; i < nums; i++) if (list[i] == nid) return i; return -1; } |
1d045db96 ALSA: hda - Split... |
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 |
/* check whether dynamic ADC-switching is available */ static bool alc_check_dyn_adc_switch(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct hda_input_mux *imux = &spec->private_imux[0]; int i, n, idx; hda_nid_t cap, pin; if (imux != spec->input_mux) /* no dynamic imux? */ return false; for (n = 0; n < spec->num_adc_nids; n++) { cap = spec->private_capsrc_nids[n]; for (i = 0; i < imux->num_items; i++) { pin = spec->imux_pins[i]; if (!pin) return false; if (get_connection_index(codec, cap, pin) < 0) break; } if (i >= imux->num_items) |
268ff6fbe ALSA: hda - Fix a... |
948 |
return true; /* no ADC-switch is needed */ |
1d045db96 ALSA: hda - Split... |
949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 |
} for (i = 0; i < imux->num_items; i++) { pin = spec->imux_pins[i]; for (n = 0; n < spec->num_adc_nids; n++) { cap = spec->private_capsrc_nids[n]; idx = get_connection_index(codec, cap, pin); if (idx >= 0) { imux->items[i].index = idx; spec->dyn_adc_idx[i] = n; break; } } } snd_printdd("realtek: enabling ADC switching "); spec->dyn_adc_switch = 1; return true; } |
21268961d ALSA: hda - More ... |
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 |
/* rebuild imux for matching with the given auto-mic pins (if not yet) */ static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct hda_input_mux *imux; static char * const texts[3] = { "Mic", "Internal Mic", "Dock Mic" }; int i; if (!spec->auto_mic) return false; imux = &spec->private_imux[0]; if (spec->input_mux == imux) return true; spec->imux_pins[0] = spec->ext_mic_pin; spec->imux_pins[1] = spec->int_mic_pin; spec->imux_pins[2] = spec->dock_mic_pin; for (i = 0; i < 3; i++) { strcpy(imux->items[i].label, texts[i]); |
6759dc323 ALSA: hda/realtek... |
990 991 992 993 |
if (spec->imux_pins[i]) { hda_nid_t pin = spec->imux_pins[i]; int c; for (c = 0; c < spec->num_adc_nids; c++) { |
61071594f ALSA: hda/realtek... |
994 |
hda_nid_t cap = get_capsrc(spec, c); |
6759dc323 ALSA: hda/realtek... |
995 996 997 998 999 1000 |
int idx = get_connection_index(codec, cap, pin); if (idx >= 0) { imux->items[i].index = idx; break; } } |
21268961d ALSA: hda - More ... |
1001 |
imux->num_items = i + 1; |
6759dc323 ALSA: hda/realtek... |
1002 |
} |
21268961d ALSA: hda - More ... |
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 |
} spec->num_mux_defs = 1; spec->input_mux = imux; return true; } /* check whether all auto-mic pins are valid; setup indices if OK */ static bool alc_auto_mic_check_imux(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; const struct hda_input_mux *imux; if (!spec->auto_mic) return false; if (spec->auto_mic_valid_imux) return true; /* already checked */ /* fill up imux indices */ if (!alc_check_dyn_adc_switch(codec)) { spec->auto_mic = 0; return false; } imux = spec->input_mux; spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin, spec->imux_pins, imux->num_items); spec->int_mic_idx = find_idx_in_nid_list(spec->int_mic_pin, spec->imux_pins, imux->num_items); spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin, spec->imux_pins, imux->num_items); if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) { spec->auto_mic = 0; return false; /* no corresponding imux */ } |
1835a0f9a ALSA: hda - Cache... |
1037 |
snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT); |
21268961d ALSA: hda - More ... |
1038 |
if (spec->dock_mic_pin) |
1835a0f9a ALSA: hda - Cache... |
1039 1040 |
snd_hda_jack_detect_enable(codec, spec->dock_mic_pin, ALC_MIC_EVENT); |
21268961d ALSA: hda - More ... |
1041 1042 1043 1044 1045 |
spec->auto_mic_valid_imux = 1; spec->auto_mic = 1; return true; } |
1d045db96 ALSA: hda - Split... |
1046 1047 1048 1049 |
/* * Check the availability of auto-mic switch; * Set up if really supported */ |
6c8194922 ALSA: hda - Add a... |
1050 1051 1052 1053 |
static void alc_init_auto_mic(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; |
8ed99d976 ALSA: hda - Add d... |
1054 |
hda_nid_t fixed, ext, dock; |
6c8194922 ALSA: hda - Add a... |
1055 |
int i; |
24de183ed ALSA: hda/realtek... |
1056 1057 |
if (spec->shared_mic_hp) return; /* no auto-mic for the shared I/O */ |
21268961d ALSA: hda - More ... |
1058 |
spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1; |
8ed99d976 ALSA: hda - Add d... |
1059 |
fixed = ext = dock = 0; |
66ceeb6bc ALSA: hda - Use n... |
1060 1061 |
for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t nid = cfg->inputs[i].pin; |
6c8194922 ALSA: hda - Add a... |
1062 |
unsigned int defcfg; |
6c8194922 ALSA: hda - Add a... |
1063 |
defcfg = snd_hda_codec_get_pincfg(codec, nid); |
99ae28bea ALSA: hda - Make ... |
1064 1065 |
switch (snd_hda_get_input_pin_attr(defcfg)) { case INPUT_PIN_ATTR_INT: |
6c8194922 ALSA: hda - Add a... |
1066 1067 |
if (fixed) return; /* already occupied */ |
8ed99d976 ALSA: hda - Add d... |
1068 1069 |
if (cfg->inputs[i].type != AUTO_PIN_MIC) return; /* invalid type */ |
6c8194922 ALSA: hda - Add a... |
1070 1071 |
fixed = nid; break; |
99ae28bea ALSA: hda - Make ... |
1072 1073 |
case INPUT_PIN_ATTR_UNUSED: return; /* invalid entry */ |
8ed99d976 ALSA: hda - Add d... |
1074 1075 1076 1077 1078 1079 1080 |
case INPUT_PIN_ATTR_DOCK: if (dock) return; /* already occupied */ if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) return; /* invalid type */ dock = nid; break; |
99ae28bea ALSA: hda - Make ... |
1081 |
default: |
6c8194922 ALSA: hda - Add a... |
1082 1083 |
if (ext) return; /* already occupied */ |
8ed99d976 ALSA: hda - Add d... |
1084 1085 |
if (cfg->inputs[i].type != AUTO_PIN_MIC) return; /* invalid type */ |
6c8194922 ALSA: hda - Add a... |
1086 1087 |
ext = nid; break; |
6c8194922 ALSA: hda - Add a... |
1088 1089 |
} } |
8ed99d976 ALSA: hda - Add d... |
1090 1091 1092 1093 |
if (!ext && dock) { ext = dock; dock = 0; } |
eaa9b3a74 ALSA: hda - Fix c... |
1094 1095 |
if (!ext || !fixed) return; |
e35d9d6a1 ALSA: hda - Check... |
1096 |
if (!is_jack_detectable(codec, ext)) |
6c8194922 ALSA: hda - Add a... |
1097 |
return; /* no unsol support */ |
8ed99d976 ALSA: hda - Add d... |
1098 1099 |
if (dock && !is_jack_detectable(codec, dock)) return; /* no unsol support */ |
21268961d ALSA: hda - More ... |
1100 1101 1102 1103 1104 1105 1106 1107 1108 |
/* check imux indices */ spec->ext_mic_pin = ext; spec->int_mic_pin = fixed; spec->dock_mic_pin = dock; spec->auto_mic = 1; if (!alc_auto_mic_check_imux(codec)) return; |
8ed99d976 ALSA: hda - Add d... |
1109 1110 1111 |
snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x ", ext, fixed, dock); |
6c8194922 ALSA: hda - Add a... |
1112 1113 |
spec->unsol_event = alc_sku_unsol_event; } |
1d045db96 ALSA: hda - Split... |
1114 1115 1116 |
/* check the availabilities of auto-mute and auto-mic switches */ static void alc_auto_check_switches(struct hda_codec *codec) { |
42cf0d015 ALSA: HDA: Refact... |
1117 |
alc_init_automute(codec); |
1d045db96 ALSA: hda - Split... |
1118 1119 1120 1121 1122 1123 |
alc_init_auto_mic(codec); } /* * Realtek SSID verification */ |
906229174 ALSA: HDA: Enable... |
1124 1125 1126 1127 |
/* Could be any non-zero and even value. When used as fixup, tells * the driver to ignore any present sku defines. */ #define ALC_FIXUP_SKU_IGNORE (2) |
da00c2449 ALSA: hda - Add p... |
1128 1129 1130 |
static int alc_auto_parse_customize_define(struct hda_codec *codec) { unsigned int ass, tmp, i; |
7fb562232 ALSA: hda - Fix u... |
1131 |
unsigned nid = 0; |
da00c2449 ALSA: hda - Add p... |
1132 |
struct alc_spec *spec = codec->spec; |
b6cbe517b ALSA: hda - Assum... |
1133 |
spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ |
906229174 ALSA: HDA: Enable... |
1134 1135 1136 1137 1138 1139 |
if (spec->cdefine.fixup) { ass = spec->cdefine.sku_cfg; if (ass == ALC_FIXUP_SKU_IGNORE) return -1; goto do_sku; } |
da00c2449 ALSA: hda - Add p... |
1140 |
ass = codec->subsystem_id & 0xffff; |
b6cbe517b ALSA: hda - Assum... |
1141 |
if (ass != codec->bus->pci->subsystem_device && (ass & 1)) |
da00c2449 ALSA: hda - Add p... |
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 |
goto do_sku; nid = 0x1d; if (codec->vendor_id == 0x10ec0260) nid = 0x17; ass = snd_hda_codec_get_pincfg(codec, nid); if (!(ass & 1)) { printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x ", codec->chip_name, ass); return -1; } /* check sum */ tmp = 0; for (i = 1; i < 16; i++) { if ((ass >> i) & 1) tmp++; } if (((ass >> 16) & 0xf) != tmp) return -1; spec->cdefine.port_connectivity = ass >> 30; spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; spec->cdefine.check_sum = (ass >> 16) & 0xf; spec->cdefine.customization = ass >> 8; do_sku: spec->cdefine.sku_cfg = ass; spec->cdefine.external_amp = (ass & 0x38) >> 3; spec->cdefine.platform_type = (ass & 0x4) >> 2; spec->cdefine.swap = (ass & 0x2) >> 1; spec->cdefine.override = ass & 0x1; snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x ", nid, spec->cdefine.sku_cfg); snd_printd("SKU: port_connectivity=0x%x ", spec->cdefine.port_connectivity); snd_printd("SKU: enable_pcbeep=0x%x ", spec->cdefine.enable_pcbeep); snd_printd("SKU: check_sum=0x%08x ", spec->cdefine.check_sum); snd_printd("SKU: customization=0x%08x ", spec->cdefine.customization); snd_printd("SKU: external_amp=0x%x ", spec->cdefine.external_amp); snd_printd("SKU: platform_type=0x%x ", spec->cdefine.platform_type); snd_printd("SKU: swap=0x%x ", spec->cdefine.swap); snd_printd("SKU: override=0x%x ", spec->cdefine.override); return 0; } |
1d045db96 ALSA: hda - Split... |
1199 |
/* return true if the given NID is found in the list */ |
3af9ee6b8 ALSA: hda - Check... |
1200 1201 |
static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) { |
21268961d ALSA: hda - More ... |
1202 |
return find_idx_in_nid_list(nid, list, nums) >= 0; |
3af9ee6b8 ALSA: hda - Check... |
1203 |
} |
4a79ba34c ALSA: hda - Add a... |
1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 |
/* check subsystem ID and set up device-specific initialization; * return 1 if initialized, 0 if invalid SSID */ /* 32-bit subsystem ID for BIOS loading in HD Audio codec. * 31 ~ 16 : Manufacture ID * 15 ~ 8 : SKU ID * 7 ~ 0 : Assembly ID * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 */ static int alc_subsystem_id(struct hda_codec *codec, hda_nid_t porta, hda_nid_t porte, |
6227cdced ALSA: hda - Add A... |
1215 |
hda_nid_t portd, hda_nid_t porti) |
4a79ba34c ALSA: hda - Add a... |
1216 1217 1218 1219 |
{ unsigned int ass, tmp, i; unsigned nid; struct alc_spec *spec = codec->spec; |
906229174 ALSA: HDA: Enable... |
1220 1221 1222 1223 1224 1225 |
if (spec->cdefine.fixup) { ass = spec->cdefine.sku_cfg; if (ass == ALC_FIXUP_SKU_IGNORE) return 0; goto do_sku; } |
4a79ba34c ALSA: hda - Add a... |
1226 1227 1228 1229 1230 1231 |
ass = codec->subsystem_id & 0xffff; if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) goto do_sku; /* invalid SSID, check the special NID pin defcfg instead */ /* |
def319f9e ALSA: HDA - Corre... |
1232 |
* 31~30 : port connectivity |
4a79ba34c ALSA: hda - Add a... |
1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 |
* 29~21 : reserve * 20 : PCBEEP input * 19~16 : Check sum (15:1) * 15~1 : Custom * 0 : override */ nid = 0x1d; if (codec->vendor_id == 0x10ec0260) nid = 0x17; ass = snd_hda_codec_get_pincfg(codec, nid); snd_printd("realtek: No valid SSID, " "checking pincfg 0x%08x for NID 0x%x ", |
cb6605c1e ALSA: hda - Fix a... |
1246 |
ass, nid); |
6227cdced ALSA: hda - Add A... |
1247 |
if (!(ass & 1)) |
4a79ba34c ALSA: hda - Add a... |
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 |
return 0; if ((ass >> 30) != 1) /* no physical connection */ return 0; /* check sum */ tmp = 0; for (i = 1; i < 16; i++) { if ((ass >> i) & 1) tmp++; } if (((ass >> 16) & 0xf) != tmp) return 0; do_sku: snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x ", ass & 0xffff, codec->vendor_id); /* * 0 : override * 1 : Swap Jack * 2 : 0 --> Desktop, 1 --> Laptop * 3~5 : External Amplifier control * 7~6 : Reserved */ tmp = (ass & 0x38) >> 3; /* external Amp control */ switch (tmp) { case 1: spec->init_amp = ALC_INIT_GPIO1; break; case 3: spec->init_amp = ALC_INIT_GPIO2; break; case 7: spec->init_amp = ALC_INIT_GPIO3; break; case 5: |
5a8cfb4e8 ALSA: hda - Use A... |
1283 |
default: |
4a79ba34c ALSA: hda - Add a... |
1284 |
spec->init_amp = ALC_INIT_DEFAULT; |
bc9f98a98 [ALSA] hda-codec ... |
1285 1286 |
break; } |
ea1fb29ac ALSA: hda - fix s... |
1287 |
|
8c427226e [ALSA] hda-codec ... |
1288 |
/* is laptop or Desktop and enable the function "Mute internal speaker |
c9b58006b [ALSA] hda-codec ... |
1289 1290 |
* when the external headphone out jack is plugged" */ |
8c427226e [ALSA] hda-codec ... |
1291 |
if (!(ass & 0x8000)) |
4a79ba34c ALSA: hda - Add a... |
1292 |
return 1; |
c9b58006b [ALSA] hda-codec ... |
1293 1294 1295 1296 1297 1298 1299 |
/* * 10~8 : Jack location * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered * 14~13: Resvered * 15 : 1 --> enable the function "Mute internal speaker * when the external headphone out jack is plugged" */ |
5fe6e0151 ALSA: hda/realtek... |
1300 1301 1302 |
if (!spec->autocfg.hp_pins[0] && !(spec->autocfg.line_out_pins[0] && spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)) { |
01d4825df ALSA: hda - Don't... |
1303 |
hda_nid_t nid; |
c9b58006b [ALSA] hda-codec ... |
1304 1305 |
tmp = (ass >> 11) & 0x3; /* HP to chassis */ if (tmp == 0) |
01d4825df ALSA: hda - Don't... |
1306 |
nid = porta; |
c9b58006b [ALSA] hda-codec ... |
1307 |
else if (tmp == 1) |
01d4825df ALSA: hda - Don't... |
1308 |
nid = porte; |
c9b58006b [ALSA] hda-codec ... |
1309 |
else if (tmp == 2) |
01d4825df ALSA: hda - Don't... |
1310 |
nid = portd; |
6227cdced ALSA: hda - Add A... |
1311 1312 |
else if (tmp == 3) nid = porti; |
c9b58006b [ALSA] hda-codec ... |
1313 |
else |
4a79ba34c ALSA: hda - Add a... |
1314 |
return 1; |
3af9ee6b8 ALSA: hda - Check... |
1315 1316 1317 |
if (found_in_nid_list(nid, spec->autocfg.line_out_pins, spec->autocfg.line_outs)) return 1; |
01d4825df ALSA: hda - Don't... |
1318 |
spec->autocfg.hp_pins[0] = nid; |
c9b58006b [ALSA] hda-codec ... |
1319 |
} |
4a79ba34c ALSA: hda - Add a... |
1320 1321 |
return 1; } |
ea1fb29ac ALSA: hda - fix s... |
1322 |
|
3e6179b84 ALSA: hda - Merge... |
1323 1324 1325 |
/* Check the validity of ALC subsystem-id * ports contains an array of 4 pin NIDs for port-A, E, D and I */ static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) |
4a79ba34c ALSA: hda - Add a... |
1326 |
{ |
3e6179b84 ALSA: hda - Merge... |
1327 |
if (!alc_subsystem_id(codec, ports[0], ports[1], ports[2], ports[3])) { |
4a79ba34c ALSA: hda - Add a... |
1328 1329 1330 1331 1332 |
struct alc_spec *spec = codec->spec; snd_printd("realtek: " "Enable default setup for auto mode as fallback "); spec->init_amp = ALC_INIT_DEFAULT; |
4a79ba34c ALSA: hda - Add a... |
1333 |
} |
21268961d ALSA: hda - More ... |
1334 |
} |
1a1455de1 ALSA: hda - Add s... |
1335 |
|
41e41f1f3 [ALSA] Fix the an... |
1336 |
/* |
f8f25ba35 ALSA: hda - Add a... |
1337 |
* Fix-up pin default configurations and add default verbs |
f95474ec0 [ALSA] hda-codec ... |
1338 1339 1340 1341 1342 1343 |
*/ struct alc_pincfg { hda_nid_t nid; u32 val; }; |
e1eb5f100 ALSA: hda: Add mo... |
1344 1345 1346 1347 |
struct alc_model_fixup { const int id; const char *name; }; |
f8f25ba35 ALSA: hda - Add a... |
1348 |
struct alc_fixup { |
b5bfbc670 ALSA: hda - Reorg... |
1349 |
int type; |
361fe6e90 ALSA: hda - Rearr... |
1350 1351 |
bool chained; int chain_id; |
b5bfbc670 ALSA: hda - Reorg... |
1352 1353 1354 1355 1356 1357 1358 1359 |
union { unsigned int sku; const struct alc_pincfg *pins; const struct hda_verb *verbs; void (*func)(struct hda_codec *codec, const struct alc_fixup *fix, int action); } v; |
f8f25ba35 ALSA: hda - Add a... |
1360 |
}; |
b5bfbc670 ALSA: hda - Reorg... |
1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 |
enum { ALC_FIXUP_INVALID, ALC_FIXUP_SKU, ALC_FIXUP_PINS, ALC_FIXUP_VERBS, ALC_FIXUP_FUNC, }; enum { ALC_FIXUP_ACT_PRE_PROBE, ALC_FIXUP_ACT_PROBE, |
587011202 ALSA: hda - Add f... |
1372 |
ALC_FIXUP_ACT_INIT, |
b5bfbc670 ALSA: hda - Reorg... |
1373 1374 1375 |
}; static void alc_apply_fixup(struct hda_codec *codec, int action) |
f95474ec0 [ALSA] hda-codec ... |
1376 |
{ |
b5bfbc670 ALSA: hda - Reorg... |
1377 1378 |
struct alc_spec *spec = codec->spec; int id = spec->fixup_id; |
aa1d0c526 ALSA: hda - Fix "... |
1379 |
#ifdef CONFIG_SND_DEBUG_VERBOSE |
b5bfbc670 ALSA: hda - Reorg... |
1380 |
const char *modelname = spec->fixup_name; |
aa1d0c526 ALSA: hda - Fix "... |
1381 |
#endif |
b5bfbc670 ALSA: hda - Reorg... |
1382 |
int depth = 0; |
f95474ec0 [ALSA] hda-codec ... |
1383 |
|
b5bfbc670 ALSA: hda - Reorg... |
1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 |
if (!spec->fixup_list) return; while (id >= 0) { const struct alc_fixup *fix = spec->fixup_list + id; const struct alc_pincfg *cfg; switch (fix->type) { case ALC_FIXUP_SKU: if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) |
e53de8f00 ALSA: hda/realtek... |
1394 |
break; |
b5bfbc670 ALSA: hda - Reorg... |
1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 |
snd_printdd(KERN_INFO "hda_codec: %s: " "Apply sku override for %s ", codec->chip_name, modelname); spec->cdefine.sku_cfg = fix->v.sku; spec->cdefine.fixup = 1; break; case ALC_FIXUP_PINS: cfg = fix->v.pins; if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg) break; snd_printdd(KERN_INFO "hda_codec: %s: " "Apply pincfg for %s ", codec->chip_name, modelname); for (; cfg->nid; cfg++) snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); break; case ALC_FIXUP_VERBS: if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs) break; snd_printdd(KERN_INFO "hda_codec: %s: " "Apply fix-verbs for %s ", codec->chip_name, modelname); add_verb(codec->spec, fix->v.verbs); break; case ALC_FIXUP_FUNC: if (!fix->v.func) break; snd_printdd(KERN_INFO "hda_codec: %s: " "Apply fix-func for %s ", codec->chip_name, modelname); fix->v.func(codec, fix, action); break; default: snd_printk(KERN_ERR "hda_codec: %s: " "Invalid fixup type %d ", codec->chip_name, fix->type); break; } |
24af2b1cc ALSA: hda - Fix R... |
1439 |
if (!fix->chained) |
b5bfbc670 ALSA: hda - Reorg... |
1440 1441 1442 |
break; if (++depth > 10) break; |
24af2b1cc ALSA: hda - Fix R... |
1443 |
id = fix->chain_id; |
9d57883f0 ALSA: hda - Add a... |
1444 |
} |
f95474ec0 [ALSA] hda-codec ... |
1445 |
} |
e1eb5f100 ALSA: hda: Add mo... |
1446 |
static void alc_pick_fixup(struct hda_codec *codec, |
b5bfbc670 ALSA: hda - Reorg... |
1447 1448 1449 |
const struct alc_model_fixup *models, const struct snd_pci_quirk *quirk, const struct alc_fixup *fixlist) |
e1eb5f100 ALSA: hda: Add mo... |
1450 |
{ |
b5bfbc670 ALSA: hda - Reorg... |
1451 |
struct alc_spec *spec = codec->spec; |
596830ee1 ALSA: hda/realtek... |
1452 |
const struct snd_pci_quirk *q; |
b5bfbc670 ALSA: hda - Reorg... |
1453 1454 |
int id = -1; const char *name = NULL; |
e1eb5f100 ALSA: hda: Add mo... |
1455 |
|
e1eb5f100 ALSA: hda: Add mo... |
1456 1457 1458 |
if (codec->modelname && models) { while (models->name) { if (!strcmp(codec->modelname, models->name)) { |
b5bfbc670 ALSA: hda - Reorg... |
1459 1460 |
id = models->id; name = models->name; |
e1eb5f100 ALSA: hda: Add mo... |
1461 1462 1463 1464 |
break; } models++; } |
b5bfbc670 ALSA: hda - Reorg... |
1465 1466 |
} if (id < 0) { |
596830ee1 ALSA: hda/realtek... |
1467 1468 1469 |
q = snd_pci_quirk_lookup(codec->bus->pci, quirk); if (q) { id = q->value; |
b5bfbc670 ALSA: hda - Reorg... |
1470 |
#ifdef CONFIG_SND_DEBUG_VERBOSE |
596830ee1 ALSA: hda/realtek... |
1471 |
name = q->name; |
b5bfbc670 ALSA: hda - Reorg... |
1472 1473 1474 |
#endif } } |
596830ee1 ALSA: hda/realtek... |
1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 |
if (id < 0) { for (q = quirk; q->subvendor; q++) { unsigned int vendorid = q->subdevice | (q->subvendor << 16); if (vendorid == codec->subsystem_id) { id = q->value; #ifdef CONFIG_SND_DEBUG_VERBOSE name = q->name; #endif break; } } } |
b5bfbc670 ALSA: hda - Reorg... |
1488 1489 1490 1491 1492 |
spec->fixup_id = id; if (id >= 0) { spec->fixup_list = fixlist; spec->fixup_name = name; |
e1eb5f100 ALSA: hda: Add mo... |
1493 |
} |
f95474ec0 [ALSA] hda-codec ... |
1494 |
} |
1d045db96 ALSA: hda - Split... |
1495 1496 1497 |
/* * COEF access helper functions */ |
274693f37 ALSA: hda - Add A... |
1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 |
static int alc_read_coef_idx(struct hda_codec *codec, unsigned int coef_idx) { unsigned int val; snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, coef_idx); val = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); return val; } |
977ddd6b2 ALSA: hda - Set u... |
1508 1509 1510 1511 1512 1513 1514 1515 |
static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, unsigned int coef_val) { snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, coef_idx); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, coef_val); } |
1bb7e43e2 ALSA: hda/realtek... |
1516 1517 1518 1519 1520 1521 1522 1523 |
/* a special bypass for COEF 0; read the cached value at the second time */ static unsigned int alc_get_coef0(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; if (!spec->coef0) spec->coef0 = alc_read_coef_idx(codec, 0); return spec->coef0; } |
1d045db96 ALSA: hda - Split... |
1524 1525 1526 |
/* * Digital I/O handling */ |
757899ace ALSA: hda - Share... |
1527 1528 1529 1530 1531 |
/* set right pin controls for digital I/O */ static void alc_auto_init_digital(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int i; |
1f0f4b803 ALSA: hda - Reduc... |
1532 |
hda_nid_t pin, dac; |
757899ace ALSA: hda - Share... |
1533 1534 1535 |
for (i = 0; i < spec->autocfg.dig_outs; i++) { pin = spec->autocfg.dig_out_pins[i]; |
1f0f4b803 ALSA: hda - Reduc... |
1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 |
if (!pin) continue; snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); if (!i) dac = spec->multiout.dig_out_nid; else dac = spec->slave_dig_outs[i - 1]; if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP)) continue; snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); |
757899ace ALSA: hda - Share... |
1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 |
} pin = spec->autocfg.dig_in_pin; if (pin) snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN); } /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ static void alc_auto_parse_digital(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; |
51e4152a9 ALSA: hda/realtek... |
1561 |
int i, err, nums; |
757899ace ALSA: hda - Share... |
1562 1563 1564 |
hda_nid_t dig_nid; /* support multiple SPDIFs; the secondary is set up as a slave */ |
51e4152a9 ALSA: hda/realtek... |
1565 |
nums = 0; |
757899ace ALSA: hda - Share... |
1566 |
for (i = 0; i < spec->autocfg.dig_outs; i++) { |
a926757f0 ALSA: hda - Fix w... |
1567 |
hda_nid_t conn[4]; |
757899ace ALSA: hda - Share... |
1568 1569 |
err = snd_hda_get_connections(codec, spec->autocfg.dig_out_pins[i], |
a926757f0 ALSA: hda - Fix w... |
1570 |
conn, ARRAY_SIZE(conn)); |
51e4152a9 ALSA: hda/realtek... |
1571 |
if (err <= 0) |
757899ace ALSA: hda - Share... |
1572 |
continue; |
a926757f0 ALSA: hda - Fix w... |
1573 |
dig_nid = conn[0]; /* assume the first element is audio-out */ |
51e4152a9 ALSA: hda/realtek... |
1574 |
if (!nums) { |
757899ace ALSA: hda - Share... |
1575 1576 1577 1578 |
spec->multiout.dig_out_nid = dig_nid; spec->dig_out_type = spec->autocfg.dig_out_type[0]; } else { spec->multiout.slave_dig_outs = spec->slave_dig_outs; |
51e4152a9 ALSA: hda/realtek... |
1579 |
if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1) |
757899ace ALSA: hda - Share... |
1580 |
break; |
51e4152a9 ALSA: hda/realtek... |
1581 |
spec->slave_dig_outs[nums - 1] = dig_nid; |
757899ace ALSA: hda - Share... |
1582 |
} |
51e4152a9 ALSA: hda/realtek... |
1583 |
nums++; |
757899ace ALSA: hda - Share... |
1584 1585 1586 |
} if (spec->autocfg.dig_in_pin) { |
01fdf1801 ALSA: hda - Fix a... |
1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 |
dig_nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, dig_nid++) { unsigned int wcaps = get_wcaps(codec, dig_nid); if (get_wcaps_type(wcaps) != AC_WID_AUD_IN) continue; if (!(wcaps & AC_WCAP_DIGITAL)) continue; if (!(wcaps & AC_WCAP_CONN_LIST)) continue; err = get_connection_index(codec, dig_nid, spec->autocfg.dig_in_pin); if (err >= 0) { spec->dig_in_nid = dig_nid; break; } } |
757899ace ALSA: hda - Share... |
1603 1604 |
} } |
f95474ec0 [ALSA] hda-codec ... |
1605 |
/* |
1d045db96 ALSA: hda - Split... |
1606 |
* capture mixer elements |
ef8ef5fb1 ALSA: hda: Added ... |
1607 |
*/ |
f9e336f65 ALSA: hda - Unify... |
1608 1609 1610 1611 1612 |
static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; |
d6cc9fabd ALSA: hda - Parse... |
1613 |
unsigned long val; |
f9e336f65 ALSA: hda - Unify... |
1614 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
1615 |
|
5a9e02e94 ALSA: hda - creat... |
1616 |
mutex_lock(&codec->control_mutex); |
d6cc9fabd ALSA: hda - Parse... |
1617 1618 1619 1620 1621 |
if (spec->vol_in_capsrc) val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT); else val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT); kcontrol->private_value = val; |
f9e336f65 ALSA: hda - Unify... |
1622 |
err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); |
5a9e02e94 ALSA: hda - creat... |
1623 |
mutex_unlock(&codec->control_mutex); |
f9e336f65 ALSA: hda - Unify... |
1624 1625 1626 1627 1628 1629 1630 1631 |
return err; } static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *tlv) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; |
d6cc9fabd ALSA: hda - Parse... |
1632 |
unsigned long val; |
f9e336f65 ALSA: hda - Unify... |
1633 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
1634 |
|
5a9e02e94 ALSA: hda - creat... |
1635 |
mutex_lock(&codec->control_mutex); |
d6cc9fabd ALSA: hda - Parse... |
1636 1637 1638 1639 1640 |
if (spec->vol_in_capsrc) val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT); else val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT); kcontrol->private_value = val; |
f9e336f65 ALSA: hda - Unify... |
1641 |
err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); |
5a9e02e94 ALSA: hda - creat... |
1642 |
mutex_unlock(&codec->control_mutex); |
f9e336f65 ALSA: hda - Unify... |
1643 1644 1645 1646 1647 1648 1649 1650 |
return err; } typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol, |
9c7a083d9 ALSA: hda - Chang... |
1651 |
getput_call_t func, bool check_adc_switch) |
f9e336f65 ALSA: hda - Unify... |
1652 1653 1654 |
{ struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; |
21268961d ALSA: hda - More ... |
1655 |
int i, err = 0; |
f9e336f65 ALSA: hda - Unify... |
1656 |
|
5a9e02e94 ALSA: hda - creat... |
1657 |
mutex_lock(&codec->control_mutex); |
21268961d ALSA: hda - More ... |
1658 |
if (check_adc_switch && spec->dyn_adc_switch) { |
9c7a083d9 ALSA: hda - Chang... |
1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 |
for (i = 0; i < spec->num_adc_nids; i++) { kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 3, 0, HDA_INPUT); err = func(kcontrol, ucontrol); if (err < 0) goto error; } } else { i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
d6cc9fabd ALSA: hda - Parse... |
1669 1670 1671 1672 1673 1674 |
if (spec->vol_in_capsrc) kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i], 3, 0, HDA_OUTPUT); else kcontrol->private_value = |
21268961d ALSA: hda - More ... |
1675 1676 |
HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 3, 0, HDA_INPUT); |
9c7a083d9 ALSA: hda - Chang... |
1677 1678 1679 |
err = func(kcontrol, ucontrol); } error: |
5a9e02e94 ALSA: hda - creat... |
1680 |
mutex_unlock(&codec->control_mutex); |
f9e336f65 ALSA: hda - Unify... |
1681 1682 1683 1684 1685 1686 1687 |
return err; } static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { return alc_cap_getput_caller(kcontrol, ucontrol, |
9c7a083d9 ALSA: hda - Chang... |
1688 |
snd_hda_mixer_amp_volume_get, false); |
f9e336f65 ALSA: hda - Unify... |
1689 1690 1691 1692 1693 1694 |
} static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { return alc_cap_getput_caller(kcontrol, ucontrol, |
9c7a083d9 ALSA: hda - Chang... |
1695 |
snd_hda_mixer_amp_volume_put, true); |
f9e336f65 ALSA: hda - Unify... |
1696 1697 1698 1699 1700 1701 1702 1703 1704 |
} /* capture mixer elements */ #define alc_cap_sw_info snd_ctl_boolean_stereo_info static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { return alc_cap_getput_caller(kcontrol, ucontrol, |
9c7a083d9 ALSA: hda - Chang... |
1705 |
snd_hda_mixer_amp_switch_get, false); |
f9e336f65 ALSA: hda - Unify... |
1706 1707 1708 1709 1710 1711 |
} static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { return alc_cap_getput_caller(kcontrol, ucontrol, |
9c7a083d9 ALSA: hda - Chang... |
1712 |
snd_hda_mixer_amp_switch_put, true); |
f9e336f65 ALSA: hda - Unify... |
1713 |
} |
a23b688f4 ALSA: hda - Don't... |
1714 |
#define _DEFINE_CAPMIX(num) \ |
f9e336f65 ALSA: hda - Unify... |
1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 |
{ \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = "Capture Switch", \ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ .count = num, \ .info = alc_cap_sw_info, \ .get = alc_cap_sw_get, \ .put = alc_cap_sw_put, \ }, \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = "Capture Volume", \ .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ .count = num, \ .info = alc_cap_vol_info, \ .get = alc_cap_vol_get, \ .put = alc_cap_vol_put, \ .tlv = { .c = alc_cap_vol_tlv }, \ |
a23b688f4 ALSA: hda - Don't... |
1735 1736 1737 |
} #define _DEFINE_CAPSRC(num) \ |
3c3e9892a ALSA: hda - Re-ad... |
1738 1739 1740 1741 1742 1743 1744 1745 |
{ \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ /* .name = "Capture Source", */ \ .name = "Input Source", \ .count = num, \ .info = alc_mux_enum_info, \ .get = alc_mux_enum_get, \ .put = alc_mux_enum_put, \ |
a23b688f4 ALSA: hda - Don't... |
1746 1747 1748 |
} #define DEFINE_CAPMIX(num) \ |
a9111321f ALSA: hda - Const... |
1749 |
static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ |
a23b688f4 ALSA: hda - Don't... |
1750 1751 1752 1753 1754 1755 |
_DEFINE_CAPMIX(num), \ _DEFINE_CAPSRC(num), \ { } /* end */ \ } #define DEFINE_CAPMIX_NOSRC(num) \ |
a9111321f ALSA: hda - Const... |
1756 |
static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ |
a23b688f4 ALSA: hda - Don't... |
1757 1758 |
_DEFINE_CAPMIX(num), \ { } /* end */ \ |
f9e336f65 ALSA: hda - Unify... |
1759 1760 1761 1762 1763 1764 |
} /* up to three ADCs */ DEFINE_CAPMIX(1); DEFINE_CAPMIX(2); DEFINE_CAPMIX(3); |
a23b688f4 ALSA: hda - Don't... |
1765 1766 1767 |
DEFINE_CAPMIX_NOSRC(1); DEFINE_CAPMIX_NOSRC(2); DEFINE_CAPMIX_NOSRC(3); |
e9edcee06 [ALSA] hda-codec ... |
1768 1769 |
/* |
1d045db96 ALSA: hda - Split... |
1770 |
* virtual master controls |
e9edcee06 [ALSA] hda-codec ... |
1771 |
*/ |
e9edcee06 [ALSA] hda-codec ... |
1772 |
/* |
1d045db96 ALSA: hda - Split... |
1773 |
* slave controls for virtual master |
e9edcee06 [ALSA] hda-codec ... |
1774 |
*/ |
1d045db96 ALSA: hda - Split... |
1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 |
static const char * const alc_slave_vols[] = { "Front Playback Volume", "Surround Playback Volume", "Center Playback Volume", "LFE Playback Volume", "Side Playback Volume", "Headphone Playback Volume", "Speaker Playback Volume", "Mono Playback Volume", "Line-Out Playback Volume", |
3fe45aeaf ALSA: hda - Add "... |
1785 |
"PCM Playback Volume", |
1d045db96 ALSA: hda - Split... |
1786 |
NULL, |
e9edcee06 [ALSA] hda-codec ... |
1787 |
}; |
1d045db96 ALSA: hda - Split... |
1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 |
static const char * const alc_slave_sws[] = { "Front Playback Switch", "Surround Playback Switch", "Center Playback Switch", "LFE Playback Switch", "Side Playback Switch", "Headphone Playback Switch", "Speaker Playback Switch", "Mono Playback Switch", "IEC958 Playback Switch", "Line-Out Playback Switch", |
3fe45aeaf ALSA: hda - Add "... |
1799 |
"PCM Playback Switch", |
1d045db96 ALSA: hda - Split... |
1800 |
NULL, |
16ded5253 [ALSA] hda-codec ... |
1801 |
}; |
e9edcee06 [ALSA] hda-codec ... |
1802 |
/* |
1d045db96 ALSA: hda - Split... |
1803 |
* build control elements |
e9edcee06 [ALSA] hda-codec ... |
1804 |
*/ |
1d045db96 ALSA: hda - Split... |
1805 |
#define NID_MAPPING (-1) |
e9edcee06 [ALSA] hda-codec ... |
1806 |
|
1d045db96 ALSA: hda - Split... |
1807 1808 1809 1810 1811 1812 |
#define SUBDEV_SPEAKER_ (0 << 6) #define SUBDEV_HP_ (1 << 6) #define SUBDEV_LINE_ (2 << 6) #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) |
e9edcee06 [ALSA] hda-codec ... |
1813 |
|
1d045db96 ALSA: hda - Split... |
1814 |
static void alc_free_kctls(struct hda_codec *codec); |
e9edcee06 [ALSA] hda-codec ... |
1815 |
|
1d045db96 ALSA: hda - Split... |
1816 1817 1818 1819 1820 |
#ifdef CONFIG_SND_HDA_INPUT_BEEP /* additional beep mixers; the actual parameters are overwritten at build */ static const struct snd_kcontrol_new alc_beep_mixer[] = { HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), |
16ded5253 [ALSA] hda-codec ... |
1821 1822 |
{ } /* end */ }; |
1d045db96 ALSA: hda - Split... |
1823 |
#endif |
16ded5253 [ALSA] hda-codec ... |
1824 |
|
1d045db96 ALSA: hda - Split... |
1825 1826 1827 1828 1829 1830 1831 1832 |
static int alc_build_controls(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct snd_kcontrol *kctl = NULL; const struct snd_kcontrol_new *knew; int i, j, err; unsigned int u; hda_nid_t nid; |
1da177e4c Linux-2.6.12-rc2 |
1833 1834 1835 1836 1837 1838 |
for (i = 0; i < spec->num_mixers; i++) { err = snd_hda_add_new_ctls(codec, spec->mixers[i]); if (err < 0) return err; } |
f9e336f65 ALSA: hda - Unify... |
1839 1840 1841 1842 1843 |
if (spec->cap_mixer) { err = snd_hda_add_new_ctls(codec, spec->cap_mixer); if (err < 0) return err; } |
1da177e4c Linux-2.6.12-rc2 |
1844 |
if (spec->multiout.dig_out_nid) { |
9c7f852e8 [ALSA] Fix/add su... |
1845 |
err = snd_hda_create_spdif_out_ctls(codec, |
74b654c95 ALSA: hda: Virtua... |
1846 |
spec->multiout.dig_out_nid, |
9c7f852e8 [ALSA] Fix/add su... |
1847 |
spec->multiout.dig_out_nid); |
1da177e4c Linux-2.6.12-rc2 |
1848 1849 |
if (err < 0) return err; |
e64f14f4e ALSA: hda - Allow... |
1850 1851 1852 1853 1854 1855 1856 |
if (!spec->no_analog) { err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); if (err < 0) return err; spec->multiout.share_spdif = 1; } |
1da177e4c Linux-2.6.12-rc2 |
1857 1858 1859 1860 1861 1862 |
} if (spec->dig_in_nid) { err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); if (err < 0) return err; } |
2134ea4f3 [ALSA] hda-codec ... |
1863 |
|
67d634c07 ALSA: hda - Fix b... |
1864 |
#ifdef CONFIG_SND_HDA_INPUT_BEEP |
45bdd1c1b ALSA: hda - Creat... |
1865 1866 |
/* create beep controls if needed */ if (spec->beep_amp) { |
a9111321f ALSA: hda - Const... |
1867 |
const struct snd_kcontrol_new *knew; |
45bdd1c1b ALSA: hda - Creat... |
1868 1869 1870 1871 1872 1873 |
for (knew = alc_beep_mixer; knew->name; knew++) { struct snd_kcontrol *kctl; kctl = snd_ctl_new1(knew, codec); if (!kctl) return -ENOMEM; kctl->private_value = spec->beep_amp; |
5e26dfd06 ALSA: hda - simpl... |
1874 |
err = snd_hda_ctl_add(codec, 0, kctl); |
45bdd1c1b ALSA: hda - Creat... |
1875 1876 1877 1878 |
if (err < 0) return err; } } |
67d634c07 ALSA: hda - Fix b... |
1879 |
#endif |
45bdd1c1b ALSA: hda - Creat... |
1880 |
|
2134ea4f3 [ALSA] hda-codec ... |
1881 |
/* if we have no master control, let's create it */ |
e64f14f4e ALSA: hda - Allow... |
1882 1883 |
if (!spec->no_analog && !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { |
1c82ed1bc [ALSA] Keep priva... |
1884 |
unsigned int vmaster_tlv[4]; |
2134ea4f3 [ALSA] hda-codec ... |
1885 |
snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, |
1c82ed1bc [ALSA] Keep priva... |
1886 |
HDA_OUTPUT, vmaster_tlv); |
2134ea4f3 [ALSA] hda-codec ... |
1887 |
err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
1c82ed1bc [ALSA] Keep priva... |
1888 |
vmaster_tlv, alc_slave_vols); |
2134ea4f3 [ALSA] hda-codec ... |
1889 1890 1891 |
if (err < 0) return err; } |
e64f14f4e ALSA: hda - Allow... |
1892 1893 |
if (!spec->no_analog && !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { |
2134ea4f3 [ALSA] hda-codec ... |
1894 1895 1896 1897 1898 |
err = snd_hda_add_vmaster(codec, "Master Playback Switch", NULL, alc_slave_sws); if (err < 0) return err; } |
5b0cb1d85 ALSA: hda - add m... |
1899 |
/* assign Capture Source enums to NID */ |
fbe618f21 ALSA: hda - Don't... |
1900 1901 1902 1903 1904 |
if (spec->capsrc_nids || spec->adc_nids) { kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { |
61071594f ALSA: hda/realtek... |
1905 1906 |
err = snd_hda_add_nid(codec, kctl, i, get_capsrc(spec, i)); |
fbe618f21 ALSA: hda - Don't... |
1907 1908 1909 |
if (err < 0) return err; } |
5b0cb1d85 ALSA: hda - add m... |
1910 |
} |
60a6a8425 ALSA: hda - Fix O... |
1911 |
if (spec->cap_mixer && spec->adc_nids) { |
5b0cb1d85 ALSA: hda - add m... |
1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 |
const char *kname = kctl ? kctl->id.name : NULL; for (knew = spec->cap_mixer; knew->name; knew++) { if (kname && strcmp(knew->name, kname) == 0) continue; kctl = snd_hda_find_mixer_ctl(codec, knew->name); for (i = 0; kctl && i < kctl->count; i++) { err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]); if (err < 0) return err; } } } /* other nid->control mapping */ for (i = 0; i < spec->num_mixers; i++) { for (knew = spec->mixers[i]; knew->name; knew++) { if (knew->iface != NID_MAPPING) continue; kctl = snd_hda_find_mixer_ctl(codec, knew->name); if (kctl == NULL) continue; u = knew->subdevice; for (j = 0; j < 4; j++, u >>= 8) { nid = u & 0x3f; if (nid == 0) continue; switch (u & 0xc0) { case SUBDEV_SPEAKER_: nid = spec->autocfg.speaker_pins[nid]; break; case SUBDEV_LINE_: nid = spec->autocfg.line_out_pins[nid]; break; case SUBDEV_HP_: nid = spec->autocfg.hp_pins[nid]; break; default: continue; } err = snd_hda_add_nid(codec, kctl, 0, nid); if (err < 0) return err; } u = knew->private_value; for (j = 0; j < 4; j++, u >>= 8) { nid = u & 0xff; if (nid == 0) continue; err = snd_hda_add_nid(codec, kctl, 0, nid); if (err < 0) return err; } } } |
bae84e70d ALSA: hda - Fix a... |
1967 1968 |
alc_free_kctls(codec); /* no longer needed */ |
01a61e12b ALSA: hda - Creat... |
1969 1970 1971 |
err = snd_hda_jack_add_kctls(codec, &spec->autocfg); if (err < 0) return err; |
1da177e4c Linux-2.6.12-rc2 |
1972 1973 |
return 0; } |
e9edcee06 [ALSA] hda-codec ... |
1974 |
|
1da177e4c Linux-2.6.12-rc2 |
1975 |
/* |
1d045db96 ALSA: hda - Split... |
1976 |
* Common callbacks |
e9edcee06 [ALSA] hda-codec ... |
1977 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
1978 |
|
1d045db96 ALSA: hda - Split... |
1979 |
static void alc_init_special_input_src(struct hda_codec *codec); |
1da177e4c Linux-2.6.12-rc2 |
1980 |
|
1d045db96 ALSA: hda - Split... |
1981 1982 1983 1984 |
static int alc_init(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; unsigned int i; |
1da177e4c Linux-2.6.12-rc2 |
1985 |
|
1d045db96 ALSA: hda - Split... |
1986 1987 |
alc_fix_pll(codec); alc_auto_init_amp(codec, spec->init_amp); |
1da177e4c Linux-2.6.12-rc2 |
1988 |
|
1d045db96 ALSA: hda - Split... |
1989 1990 1991 |
for (i = 0; i < spec->num_init_verbs; i++) snd_hda_sequence_write(codec, spec->init_verbs[i]); alc_init_special_input_src(codec); |
dfc0ff62a [ALSA] Add ASUS Z... |
1992 |
|
1d045db96 ALSA: hda - Split... |
1993 1994 |
if (spec->init_hook) spec->init_hook(codec); |
16ded5253 [ALSA] hda-codec ... |
1995 |
|
1d045db96 ALSA: hda - Split... |
1996 |
alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); |
16ded5253 [ALSA] hda-codec ... |
1997 |
|
01a61e12b ALSA: hda - Creat... |
1998 |
snd_hda_jack_report_sync(codec); |
1d045db96 ALSA: hda - Split... |
1999 2000 2001 |
hda_call_check_power_status(codec, 0x01); return 0; } |
ea1fb29ac ALSA: hda - fix s... |
2002 |
|
1d045db96 ALSA: hda - Split... |
2003 2004 2005 |
static void alc_unsol_event(struct hda_codec *codec, unsigned int res) { struct alc_spec *spec = codec->spec; |
e9edcee06 [ALSA] hda-codec ... |
2006 |
|
1d045db96 ALSA: hda - Split... |
2007 2008 2009 |
if (spec->unsol_event) spec->unsol_event(codec, res); } |
ccc656ce5 [ALSA] hda-codec ... |
2010 |
|
1d045db96 ALSA: hda - Split... |
2011 2012 2013 2014 2015 2016 2017 |
#ifdef CONFIG_SND_HDA_POWER_SAVE static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) { struct alc_spec *spec = codec->spec; return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); } #endif |
ccc656ce5 [ALSA] hda-codec ... |
2018 2019 |
/* |
1d045db96 ALSA: hda - Split... |
2020 |
* Analog playback callbacks |
ccc656ce5 [ALSA] hda-codec ... |
2021 |
*/ |
1d045db96 ALSA: hda - Split... |
2022 2023 2024 |
static int alc_playback_pcm_open(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream) |
458a4fabf [ALSA] hda-codec ... |
2025 |
{ |
1d045db96 ALSA: hda - Split... |
2026 2027 2028 |
struct alc_spec *spec = codec->spec; return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, hinfo); |
458a4fabf [ALSA] hda-codec ... |
2029 |
} |
1d045db96 ALSA: hda - Split... |
2030 2031 2032 2033 2034 |
static int alc_playback_pcm_prepare(struct hda_pcm_stream *hinfo, struct hda_codec *codec, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream) |
458a4fabf [ALSA] hda-codec ... |
2035 |
{ |
a9fd4f3fc ALSA: hda - Clean... |
2036 |
struct alc_spec *spec = codec->spec; |
1d045db96 ALSA: hda - Split... |
2037 2038 |
return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream); |
4f5d17062 ALSA: hda - Clean... |
2039 |
} |
1d045db96 ALSA: hda - Split... |
2040 2041 2042 |
static int alc_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream) |
4f5d17062 ALSA: hda - Clean... |
2043 |
{ |
1d045db96 ALSA: hda - Split... |
2044 2045 |
struct alc_spec *spec = codec->spec; return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); |
ccc656ce5 [ALSA] hda-codec ... |
2046 |
} |
1d045db96 ALSA: hda - Split... |
2047 2048 2049 2050 2051 2052 |
/* * Digital out */ static int alc_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream) |
ccc656ce5 [ALSA] hda-codec ... |
2053 |
{ |
1d045db96 ALSA: hda - Split... |
2054 2055 |
struct alc_spec *spec = codec->spec; return snd_hda_multi_out_dig_open(codec, &spec->multiout); |
ccc656ce5 [ALSA] hda-codec ... |
2056 |
} |
1d045db96 ALSA: hda - Split... |
2057 2058 2059 2060 2061 |
static int alc_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, struct hda_codec *codec, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream) |
ccc656ce5 [ALSA] hda-codec ... |
2062 |
{ |
a9fd4f3fc ALSA: hda - Clean... |
2063 |
struct alc_spec *spec = codec->spec; |
1d045db96 ALSA: hda - Split... |
2064 2065 |
return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, format, substream); |
ccc656ce5 [ALSA] hda-codec ... |
2066 |
} |
1d045db96 ALSA: hda - Split... |
2067 2068 2069 |
static int alc_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream) |
ccc656ce5 [ALSA] hda-codec ... |
2070 |
{ |
1d045db96 ALSA: hda - Split... |
2071 2072 |
struct alc_spec *spec = codec->spec; return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); |
ccc656ce5 [ALSA] hda-codec ... |
2073 |
} |
47fd830ac [ALSA] hda-codec ... |
2074 |
|
1d045db96 ALSA: hda - Split... |
2075 2076 2077 |
static int alc_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream) |
ccc656ce5 [ALSA] hda-codec ... |
2078 |
{ |
1d045db96 ALSA: hda - Split... |
2079 2080 |
struct alc_spec *spec = codec->spec; return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
ccc656ce5 [ALSA] hda-codec ... |
2081 |
} |
e9edcee06 [ALSA] hda-codec ... |
2082 |
/* |
1d045db96 ALSA: hda - Split... |
2083 |
* Analog capture |
e9edcee06 [ALSA] hda-codec ... |
2084 |
*/ |
1d045db96 ALSA: hda - Split... |
2085 2086 2087 2088 2089 2090 2091 |
static int alc_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, struct hda_codec *codec, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream) { struct alc_spec *spec = codec->spec; |
1da177e4c Linux-2.6.12-rc2 |
2092 |
|
6330079fc [ALSA] hda-codec ... |
2093 |
snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], |
1da177e4c Linux-2.6.12-rc2 |
2094 2095 2096 |
stream_tag, 0, format); return 0; } |
c2d986b0d ALSA: hda - Clean... |
2097 |
static int alc_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, |
1da177e4c Linux-2.6.12-rc2 |
2098 |
struct hda_codec *codec, |
c8b6bf9b5 [ALSA] Remove xxx... |
2099 |
struct snd_pcm_substream *substream) |
1da177e4c Linux-2.6.12-rc2 |
2100 2101 |
{ struct alc_spec *spec = codec->spec; |
888afa154 [ALSA] hda-codec ... |
2102 2103 |
snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number + 1]); |
1da177e4c Linux-2.6.12-rc2 |
2104 2105 |
return 0; } |
840b64c08 ALSA: hda - Add s... |
2106 |
/* analog capture with dynamic dual-adc changes */ |
21268961d ALSA: hda - More ... |
2107 |
static int dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo, |
840b64c08 ALSA: hda - Add s... |
2108 2109 2110 2111 2112 2113 |
struct hda_codec *codec, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream) { struct alc_spec *spec = codec->spec; |
21268961d ALSA: hda - More ... |
2114 |
spec->cur_adc = spec->adc_nids[spec->dyn_adc_idx[spec->cur_mux[0]]]; |
840b64c08 ALSA: hda - Add s... |
2115 2116 2117 2118 2119 |
spec->cur_adc_stream_tag = stream_tag; spec->cur_adc_format = format; snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); return 0; } |
21268961d ALSA: hda - More ... |
2120 |
static int dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, |
840b64c08 ALSA: hda - Add s... |
2121 2122 2123 2124 2125 2126 2127 2128 |
struct hda_codec *codec, struct snd_pcm_substream *substream) { struct alc_spec *spec = codec->spec; snd_hda_codec_cleanup_stream(codec, spec->cur_adc); spec->cur_adc = 0; return 0; } |
21268961d ALSA: hda - More ... |
2129 |
static const struct hda_pcm_stream dyn_adc_pcm_analog_capture = { |
840b64c08 ALSA: hda - Add s... |
2130 2131 2132 2133 2134 |
.substreams = 1, .channels_min = 2, .channels_max = 2, .nid = 0, /* fill later */ .ops = { |
21268961d ALSA: hda - More ... |
2135 2136 |
.prepare = dyn_adc_capture_pcm_prepare, .cleanup = dyn_adc_capture_pcm_cleanup |
840b64c08 ALSA: hda - Add s... |
2137 2138 |
}, }; |
1da177e4c Linux-2.6.12-rc2 |
2139 2140 2141 |
/* */ |
c2d986b0d ALSA: hda - Clean... |
2142 |
static const struct hda_pcm_stream alc_pcm_analog_playback = { |
1da177e4c Linux-2.6.12-rc2 |
2143 2144 2145 |
.substreams = 1, .channels_min = 2, .channels_max = 8, |
e9edcee06 [ALSA] hda-codec ... |
2146 |
/* NID is set in alc_build_pcms */ |
1da177e4c Linux-2.6.12-rc2 |
2147 |
.ops = { |
c2d986b0d ALSA: hda - Clean... |
2148 2149 2150 |
.open = alc_playback_pcm_open, .prepare = alc_playback_pcm_prepare, .cleanup = alc_playback_pcm_cleanup |
1da177e4c Linux-2.6.12-rc2 |
2151 2152 |
}, }; |
c2d986b0d ALSA: hda - Clean... |
2153 |
static const struct hda_pcm_stream alc_pcm_analog_capture = { |
6330079fc [ALSA] hda-codec ... |
2154 2155 2156 2157 2158 |
.substreams = 1, .channels_min = 2, .channels_max = 2, /* NID is set in alc_build_pcms */ }; |
c2d986b0d ALSA: hda - Clean... |
2159 |
static const struct hda_pcm_stream alc_pcm_analog_alt_playback = { |
6330079fc [ALSA] hda-codec ... |
2160 2161 2162 2163 2164 |
.substreams = 1, .channels_min = 2, .channels_max = 2, /* NID is set in alc_build_pcms */ }; |
c2d986b0d ALSA: hda - Clean... |
2165 |
static const struct hda_pcm_stream alc_pcm_analog_alt_capture = { |
6330079fc [ALSA] hda-codec ... |
2166 |
.substreams = 2, /* can be overridden */ |
1da177e4c Linux-2.6.12-rc2 |
2167 2168 |
.channels_min = 2, .channels_max = 2, |
e9edcee06 [ALSA] hda-codec ... |
2169 |
/* NID is set in alc_build_pcms */ |
1da177e4c Linux-2.6.12-rc2 |
2170 |
.ops = { |
c2d986b0d ALSA: hda - Clean... |
2171 2172 |
.prepare = alc_alt_capture_pcm_prepare, .cleanup = alc_alt_capture_pcm_cleanup |
1da177e4c Linux-2.6.12-rc2 |
2173 2174 |
}, }; |
c2d986b0d ALSA: hda - Clean... |
2175 |
static const struct hda_pcm_stream alc_pcm_digital_playback = { |
1da177e4c Linux-2.6.12-rc2 |
2176 2177 2178 2179 2180 |
.substreams = 1, .channels_min = 2, .channels_max = 2, /* NID is set in alc_build_pcms */ .ops = { |
c2d986b0d ALSA: hda - Clean... |
2181 2182 2183 2184 |
.open = alc_dig_playback_pcm_open, .close = alc_dig_playback_pcm_close, .prepare = alc_dig_playback_pcm_prepare, .cleanup = alc_dig_playback_pcm_cleanup |
1da177e4c Linux-2.6.12-rc2 |
2185 2186 |
}, }; |
c2d986b0d ALSA: hda - Clean... |
2187 |
static const struct hda_pcm_stream alc_pcm_digital_capture = { |
1da177e4c Linux-2.6.12-rc2 |
2188 2189 2190 2191 2192 |
.substreams = 1, .channels_min = 2, .channels_max = 2, /* NID is set in alc_build_pcms */ }; |
4c5186ed6 [ALSA] hda: add P... |
2193 |
/* Used by alc_build_pcms to flag that a PCM has no playback stream */ |
a9111321f ALSA: hda - Const... |
2194 |
static const struct hda_pcm_stream alc_pcm_null_stream = { |
4c5186ed6 [ALSA] hda: add P... |
2195 2196 2197 2198 |
.substreams = 0, .channels_min = 0, .channels_max = 0, }; |
1da177e4c Linux-2.6.12-rc2 |
2199 2200 2201 2202 |
static int alc_build_pcms(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct hda_pcm *info = spec->pcm_rec; |
c2d986b0d ALSA: hda - Clean... |
2203 |
const struct hda_pcm_stream *p; |
1fa175736 ALSA: hda/realtek... |
2204 |
bool have_multi_adcs; |
1da177e4c Linux-2.6.12-rc2 |
2205 2206 2207 2208 |
int i; codec->num_pcms = 1; codec->pcm_info = info; |
e64f14f4e ALSA: hda - Allow... |
2209 2210 |
if (spec->no_analog) goto skip_analog; |
812a2cca2 ALSA: hda - Split... |
2211 2212 |
snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), "%s Analog", codec->chip_name); |
1da177e4c Linux-2.6.12-rc2 |
2213 |
info->name = spec->stream_name_analog; |
274693f37 ALSA: hda - Add A... |
2214 |
|
c2d986b0d ALSA: hda - Clean... |
2215 2216 2217 2218 2219 |
if (spec->multiout.dac_nids > 0) { p = spec->stream_analog_playback; if (!p) p = &alc_pcm_analog_playback; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; |
4a471b7dd [ALSA] hda-codec ... |
2220 2221 |
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; } |
c2d986b0d ALSA: hda - Clean... |
2222 2223 |
if (spec->adc_nids) { p = spec->stream_analog_capture; |
21268961d ALSA: hda - More ... |
2224 2225 2226 2227 2228 2229 |
if (!p) { if (spec->dyn_adc_switch) p = &dyn_adc_pcm_analog_capture; else p = &alc_pcm_analog_capture; } |
c2d986b0d ALSA: hda - Clean... |
2230 |
info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; |
4a471b7dd [ALSA] hda-codec ... |
2231 2232 2233 2234 2235 2236 2237 2238 2239 |
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; } if (spec->channel_mode) { info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; for (i = 0; i < spec->num_channel_mode; i++) { if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; } |
1da177e4c Linux-2.6.12-rc2 |
2240 2241 |
} } |
e64f14f4e ALSA: hda - Allow... |
2242 |
skip_analog: |
e08a007d1 [ALSA] hda-codec ... |
2243 |
/* SPDIF for stream index #1 */ |
1da177e4c Linux-2.6.12-rc2 |
2244 |
if (spec->multiout.dig_out_nid || spec->dig_in_nid) { |
812a2cca2 ALSA: hda - Split... |
2245 2246 2247 |
snprintf(spec->stream_name_digital, sizeof(spec->stream_name_digital), "%s Digital", codec->chip_name); |
e08a007d1 [ALSA] hda-codec ... |
2248 |
codec->num_pcms = 2; |
b25c9da19 ALSA: enable conc... |
2249 |
codec->slave_dig_outs = spec->multiout.slave_dig_outs; |
c06134d73 [ALSA] hda-codec ... |
2250 |
info = spec->pcm_rec + 1; |
1da177e4c Linux-2.6.12-rc2 |
2251 |
info->name = spec->stream_name_digital; |
8c441982f ALSA: hda - Assig... |
2252 2253 2254 2255 |
if (spec->dig_out_type) info->pcm_type = spec->dig_out_type; else info->pcm_type = HDA_PCM_TYPE_SPDIF; |
c2d986b0d ALSA: hda - Clean... |
2256 2257 2258 2259 2260 |
if (spec->multiout.dig_out_nid) { p = spec->stream_digital_playback; if (!p) p = &alc_pcm_digital_playback; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; |
1da177e4c Linux-2.6.12-rc2 |
2261 2262 |
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; } |
c2d986b0d ALSA: hda - Clean... |
2263 2264 2265 2266 2267 |
if (spec->dig_in_nid) { p = spec->stream_digital_capture; if (!p) p = &alc_pcm_digital_capture; info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; |
1da177e4c Linux-2.6.12-rc2 |
2268 2269 |
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; } |
963f803fb ALSA: hda - Don't... |
2270 2271 |
/* FIXME: do we need this for all Realtek codec models? */ codec->spdif_status_reset = 1; |
1da177e4c Linux-2.6.12-rc2 |
2272 |
} |
e64f14f4e ALSA: hda - Allow... |
2273 2274 |
if (spec->no_analog) return 0; |
e08a007d1 [ALSA] hda-codec ... |
2275 2276 2277 |
/* If the use of more than one ADC is requested for the current * model, configure a second analog capture-only PCM. */ |
1fa175736 ALSA: hda/realtek... |
2278 2279 2280 |
have_multi_adcs = (spec->num_adc_nids > 1) && !spec->dyn_adc_switch && !spec->auto_mic && (!spec->input_mux || spec->input_mux->num_items > 1); |
e08a007d1 [ALSA] hda-codec ... |
2281 |
/* Additional Analaog capture for index #2 */ |
1fa175736 ALSA: hda/realtek... |
2282 |
if (spec->alt_dac_nid || have_multi_adcs) { |
e08a007d1 [ALSA] hda-codec ... |
2283 |
codec->num_pcms = 3; |
c06134d73 [ALSA] hda-codec ... |
2284 |
info = spec->pcm_rec + 2; |
e08a007d1 [ALSA] hda-codec ... |
2285 |
info->name = spec->stream_name_analog; |
6330079fc [ALSA] hda-codec ... |
2286 |
if (spec->alt_dac_nid) { |
c2d986b0d ALSA: hda - Clean... |
2287 2288 2289 2290 |
p = spec->stream_analog_alt_playback; if (!p) p = &alc_pcm_analog_alt_playback; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; |
6330079fc [ALSA] hda-codec ... |
2291 2292 2293 2294 2295 2296 2297 |
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->alt_dac_nid; } else { info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_stream; info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; } |
1fa175736 ALSA: hda/realtek... |
2298 |
if (have_multi_adcs) { |
c2d986b0d ALSA: hda - Clean... |
2299 2300 2301 2302 |
p = spec->stream_analog_alt_capture; if (!p) p = &alc_pcm_analog_alt_capture; info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; |
6330079fc [ALSA] hda-codec ... |
2303 2304 2305 2306 2307 2308 2309 2310 |
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1]; info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids - 1; } else { info->stream[SNDRV_PCM_STREAM_CAPTURE] = alc_pcm_null_stream; info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; |
e08a007d1 [ALSA] hda-codec ... |
2311 2312 |
} } |
1da177e4c Linux-2.6.12-rc2 |
2313 2314 |
return 0; } |
a4e09aa3c ALSA: hda - Fix c... |
2315 2316 |
static inline void alc_shutup(struct hda_codec *codec) { |
1c716153a ALSA: hda - Intro... |
2317 2318 2319 2320 |
struct alc_spec *spec = codec->spec; if (spec && spec->shutup) spec->shutup(codec); |
a4e09aa3c ALSA: hda - Fix c... |
2321 2322 |
snd_hda_shutup_pins(codec); } |
603c40199 ALSA: hda - Use g... |
2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 |
static void alc_free_kctls(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; if (spec->kctls.list) { struct snd_kcontrol_new *kctl = spec->kctls.list; int i; for (i = 0; i < spec->kctls.used; i++) kfree(kctl[i].name); } snd_array_free(&spec->kctls); } |
23c09b009 ALSA: hda - Suppo... |
2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 |
static void alc_free_bind_ctls(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; if (spec->bind_ctls.list) { struct hda_bind_ctls **ctl = spec->bind_ctls.list; int i; for (i = 0; i < spec->bind_ctls.used; i++) kfree(ctl[i]); } snd_array_free(&spec->bind_ctls); } |
1da177e4c Linux-2.6.12-rc2 |
2346 2347 |
static void alc_free(struct hda_codec *codec) { |
e9edcee06 [ALSA] hda-codec ... |
2348 |
struct alc_spec *spec = codec->spec; |
e9edcee06 [ALSA] hda-codec ... |
2349 |
|
f12ab1e07 [ALSA] hda-codec ... |
2350 |
if (!spec) |
e9edcee06 [ALSA] hda-codec ... |
2351 |
return; |
a4e09aa3c ALSA: hda - Fix c... |
2352 |
alc_shutup(codec); |
603c40199 ALSA: hda - Use g... |
2353 |
alc_free_kctls(codec); |
23c09b009 ALSA: hda - Suppo... |
2354 |
alc_free_bind_ctls(codec); |
e9edcee06 [ALSA] hda-codec ... |
2355 |
kfree(spec); |
680cd5365 ALSA: hda: Add di... |
2356 |
snd_hda_detach_beep_device(codec); |
1da177e4c Linux-2.6.12-rc2 |
2357 |
} |
f5de24b06 ALSA: HDA: add po... |
2358 |
#ifdef CONFIG_SND_HDA_POWER_SAVE |
c97259df3 ALSA: hda: Refact... |
2359 2360 |
static void alc_power_eapd(struct hda_codec *codec) { |
691f1fccf ALSA: hda - Refac... |
2361 |
alc_auto_setup_eapd(codec, false); |
c97259df3 ALSA: hda: Refact... |
2362 |
} |
f5de24b06 ALSA: HDA: add po... |
2363 2364 2365 |
static int alc_suspend(struct hda_codec *codec, pm_message_t state) { struct alc_spec *spec = codec->spec; |
a4e09aa3c ALSA: hda - Fix c... |
2366 |
alc_shutup(codec); |
f5de24b06 ALSA: HDA: add po... |
2367 |
if (spec && spec->power_hook) |
c97259df3 ALSA: hda: Refact... |
2368 |
spec->power_hook(codec); |
f5de24b06 ALSA: HDA: add po... |
2369 2370 2371 |
return 0; } #endif |
2a43952a9 ALSA: hda - Make ... |
2372 |
#ifdef CONFIG_PM |
e044c39ae ALSA: hda - Resto... |
2373 2374 |
static int alc_resume(struct hda_codec *codec) { |
1c716153a ALSA: hda - Intro... |
2375 |
msleep(150); /* to avoid pop noise */ |
e044c39ae ALSA: hda - Resto... |
2376 2377 2378 |
codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); |
9e5341b92 ALSA: hda - Intro... |
2379 |
hda_call_check_power_status(codec, 0x01); |
e044c39ae ALSA: hda - Resto... |
2380 2381 |
return 0; } |
e044c39ae ALSA: hda - Resto... |
2382 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
2383 2384 |
/* */ |
a9111321f ALSA: hda - Const... |
2385 |
static const struct hda_codec_ops alc_patch_ops = { |
1da177e4c Linux-2.6.12-rc2 |
2386 2387 2388 2389 |
.build_controls = alc_build_controls, .build_pcms = alc_build_pcms, .init = alc_init, .free = alc_free, |
ae6b813a4 [ALSA] hda-codec ... |
2390 |
.unsol_event = alc_unsol_event, |
2a43952a9 ALSA: hda - Make ... |
2391 |
#ifdef CONFIG_PM |
e044c39ae ALSA: hda - Resto... |
2392 2393 |
.resume = alc_resume, #endif |
cb53c626e [ALSA] hda-intel ... |
2394 |
#ifdef CONFIG_SND_HDA_POWER_SAVE |
f5de24b06 ALSA: HDA: add po... |
2395 |
.suspend = alc_suspend, |
cb53c626e [ALSA] hda-intel ... |
2396 2397 |
.check_power_status = alc_check_power_status, #endif |
c97259df3 ALSA: hda: Refact... |
2398 |
.reboot_notify = alc_shutup, |
1da177e4c Linux-2.6.12-rc2 |
2399 |
}; |
c027ddcd0 ALSA: hda - Add a... |
2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 |
/* replace the codec chip_name with the given string */ static int alc_codec_rename(struct hda_codec *codec, const char *name) { kfree(codec->chip_name); codec->chip_name = kstrdup(name, GFP_KERNEL); if (!codec->chip_name) { alc_free(codec); return -ENOMEM; } return 0; } |
2fa522bed [ALSA] Add test m... |
2411 |
/* |
e16fb6d14 ALSA: hda/realtek... |
2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 |
* Rename codecs appropriately from COEF value */ struct alc_codec_rename_table { unsigned int vendor_id; unsigned short coef_mask; unsigned short coef_bits; const char *name; }; static struct alc_codec_rename_table rename_tbl[] = { { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" }, { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" }, { 0x10ec0269, 0xffff, 0xa023, "ALC259" }, { 0x10ec0269, 0xffff, 0x6023, "ALC281X" }, { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" }, { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" }, { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" }, { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" }, { 0x10ec0899, 0x2000, 0x2000, "ALC899" }, { 0x10ec0892, 0xffff, 0x8020, "ALC661" }, { 0x10ec0892, 0xffff, 0x8011, "ALC661" }, { 0x10ec0892, 0xffff, 0x4011, "ALC656" }, { } /* terminator */ }; static int alc_codec_rename_from_preset(struct hda_codec *codec) { const struct alc_codec_rename_table *p; |
e16fb6d14 ALSA: hda/realtek... |
2442 2443 2444 2445 |
for (p = rename_tbl; p->vendor_id; p++) { if (p->vendor_id != codec->vendor_id) continue; |
1bb7e43e2 ALSA: hda/realtek... |
2446 |
if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) |
e16fb6d14 ALSA: hda/realtek... |
2447 2448 2449 2450 2451 2452 |
return alc_codec_rename(codec, p->name); } return 0; } /* |
1d045db96 ALSA: hda - Split... |
2453 |
* Automatic parse of I/O pins from the BIOS configuration |
2fa522bed [ALSA] Add test m... |
2454 |
*/ |
2fa522bed [ALSA] Add test m... |
2455 |
|
1d045db96 ALSA: hda - Split... |
2456 2457 2458 2459 |
enum { ALC_CTL_WIDGET_VOL, ALC_CTL_WIDGET_MUTE, ALC_CTL_BIND_MUTE, |
23c09b009 ALSA: hda - Suppo... |
2460 2461 |
ALC_CTL_BIND_VOL, ALC_CTL_BIND_SW, |
2fa522bed [ALSA] Add test m... |
2462 |
}; |
1d045db96 ALSA: hda - Split... |
2463 2464 2465 2466 |
static const struct snd_kcontrol_new alc_control_templates[] = { HDA_CODEC_VOLUME(NULL, 0, 0, 0), HDA_CODEC_MUTE(NULL, 0, 0, 0), HDA_BIND_MUTE(NULL, 0, 0, 0), |
23c09b009 ALSA: hda - Suppo... |
2467 2468 |
HDA_BIND_VOL(NULL, 0), HDA_BIND_SW(NULL, 0), |
2fa522bed [ALSA] Add test m... |
2469 |
}; |
1d045db96 ALSA: hda - Split... |
2470 2471 2472 |
/* add dynamic controls */ static int add_control(struct alc_spec *spec, int type, const char *name, int cidx, unsigned long val) |
e9edcee06 [ALSA] hda-codec ... |
2473 |
{ |
c8b6bf9b5 [ALSA] Remove xxx... |
2474 |
struct snd_kcontrol_new *knew; |
e9edcee06 [ALSA] hda-codec ... |
2475 |
|
ce764ab22 ALSA: hda - Add c... |
2476 |
knew = alc_kcontrol_new(spec); |
603c40199 ALSA: hda - Use g... |
2477 2478 |
if (!knew) return -ENOMEM; |
1d045db96 ALSA: hda - Split... |
2479 |
*knew = alc_control_templates[type]; |
543537bd9 [PATCH] create a ... |
2480 |
knew->name = kstrdup(name, GFP_KERNEL); |
f12ab1e07 [ALSA] hda-codec ... |
2481 |
if (!knew->name) |
e9edcee06 [ALSA] hda-codec ... |
2482 |
return -ENOMEM; |
66ceeb6bc ALSA: hda - Use n... |
2483 |
knew->index = cidx; |
4d02d1b63 ALSA: hda - proc ... |
2484 |
if (get_amp_nid_(val)) |
5e26dfd06 ALSA: hda - simpl... |
2485 |
knew->subdevice = HDA_SUBDEV_AMP_FLAG; |
e9edcee06 [ALSA] hda-codec ... |
2486 |
knew->private_value = val; |
e9edcee06 [ALSA] hda-codec ... |
2487 2488 |
return 0; } |
0afe5f891 ALSA: hda - Clean... |
2489 2490 |
static int add_control_with_pfx(struct alc_spec *spec, int type, const char *pfx, const char *dir, |
66ceeb6bc ALSA: hda - Use n... |
2491 |
const char *sfx, int cidx, unsigned long val) |
0afe5f891 ALSA: hda - Clean... |
2492 2493 2494 |
{ char name[32]; snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); |
66ceeb6bc ALSA: hda - Use n... |
2495 |
return add_control(spec, type, name, cidx, val); |
0afe5f891 ALSA: hda - Clean... |
2496 |
} |
66ceeb6bc ALSA: hda - Use n... |
2497 2498 2499 2500 2501 2502 2503 2504 |
#define add_pb_vol_ctrl(spec, type, pfx, val) \ add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val) #define add_pb_sw_ctrl(spec, type, pfx, val) \ add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val) #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \ add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val) #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) |
0afe5f891 ALSA: hda - Clean... |
2505 |
|
23c09b009 ALSA: hda - Suppo... |
2506 2507 2508 |
static const char * const channel_name[4] = { "Front", "Surround", "CLFE", "Side" }; |
6843ca16f ALSA: hda - Clean... |
2509 2510 |
static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, bool can_be_master, int *index) |
bcb2f0f51 ALSA: hda - Add s... |
2511 |
{ |
ce764ab22 ALSA: hda - Add c... |
2512 |
struct auto_pin_cfg *cfg = &spec->autocfg; |
6843ca16f ALSA: hda - Clean... |
2513 |
*index = 0; |
ce764ab22 ALSA: hda - Add c... |
2514 2515 |
if (cfg->line_outs == 1 && !spec->multi_ios && !cfg->hp_outs && !cfg->speaker_outs && can_be_master) |
bcb2f0f51 ALSA: hda - Add s... |
2516 2517 2518 2519 |
return "Master"; switch (cfg->line_out_type) { case AUTO_PIN_SPEAKER_OUT: |
ebbeb3d6a ALSA: HDA: Fix vo... |
2520 2521 |
if (cfg->line_outs == 1) return "Speaker"; |
fbabc2461 ALSA: hda/realtek... |
2522 2523 |
if (cfg->line_outs == 2) return ch ? "Bass Speaker" : "Speaker"; |
ebbeb3d6a ALSA: HDA: Fix vo... |
2524 |
break; |
bcb2f0f51 ALSA: hda - Add s... |
2525 |
case AUTO_PIN_HP_OUT: |
6843ca16f ALSA: hda - Clean... |
2526 2527 2528 2529 |
/* for multi-io case, only the primary out */ if (ch && spec->multi_ios) break; *index = ch; |
bcb2f0f51 ALSA: hda - Add s... |
2530 2531 |
return "Headphone"; default: |
ce764ab22 ALSA: hda - Add c... |
2532 |
if (cfg->line_outs == 1 && !spec->multi_ios) |
bcb2f0f51 ALSA: hda - Add s... |
2533 2534 2535 |
return "PCM"; break; } |
23c09b009 ALSA: hda - Suppo... |
2536 2537 2538 2539 |
if (snd_BUG_ON(ch >= ARRAY_SIZE(channel_name))) return "PCM"; return channel_name[ch]; |
bcb2f0f51 ALSA: hda - Add s... |
2540 |
} |
e9edcee06 [ALSA] hda-codec ... |
2541 |
/* create input playback/capture controls for the given pin */ |
f12ab1e07 [ALSA] hda-codec ... |
2542 |
static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, |
66ceeb6bc ALSA: hda - Use n... |
2543 |
const char *ctlname, int ctlidx, |
df694daa3 [ALSA] hda-codec ... |
2544 |
int idx, hda_nid_t mix_nid) |
e9edcee06 [ALSA] hda-codec ... |
2545 |
{ |
df694daa3 [ALSA] hda-codec ... |
2546 |
int err; |
e9edcee06 [ALSA] hda-codec ... |
2547 |
|
66ceeb6bc ALSA: hda - Use n... |
2548 |
err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx, |
f12ab1e07 [ALSA] hda-codec ... |
2549 2550 |
HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); if (err < 0) |
e9edcee06 [ALSA] hda-codec ... |
2551 |
return err; |
66ceeb6bc ALSA: hda - Use n... |
2552 |
err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx, |
f12ab1e07 [ALSA] hda-codec ... |
2553 2554 |
HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); if (err < 0) |
e9edcee06 [ALSA] hda-codec ... |
2555 2556 2557 |
return err; return 0; } |
05f5f4770 ALSA: hda - Gener... |
2558 2559 2560 2561 2562 |
static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid) { unsigned int pincap = snd_hda_query_pin_caps(codec, nid); return (pincap & AC_PINCAP_IN) != 0; } |
1d045db96 ALSA: hda - Split... |
2563 |
/* Parse the codec tree and retrieve ADCs and corresponding capsrc MUXs */ |
d6cc9fabd ALSA: hda - Parse... |
2564 |
static int alc_auto_fill_adc_caps(struct hda_codec *codec) |
b78217096 ALSA: hda - Parse... |
2565 |
{ |
d6cc9fabd ALSA: hda - Parse... |
2566 |
struct alc_spec *spec = codec->spec; |
b78217096 ALSA: hda - Parse... |
2567 |
hda_nid_t nid; |
d6cc9fabd ALSA: hda - Parse... |
2568 2569 2570 |
hda_nid_t *adc_nids = spec->private_adc_nids; hda_nid_t *cap_nids = spec->private_capsrc_nids; int max_nums = ARRAY_SIZE(spec->private_adc_nids); |
b78217096 ALSA: hda - Parse... |
2571 |
int i, nums = 0; |
24de183ed ALSA: hda/realtek... |
2572 2573 |
if (spec->shared_mic_hp) max_nums = 1; /* no multi streams with the shared HP/mic */ |
b78217096 ALSA: hda - Parse... |
2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 |
nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) { hda_nid_t src; const hda_nid_t *list; unsigned int caps = get_wcaps(codec, nid); int type = get_wcaps_type(caps); if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL)) continue; adc_nids[nums] = nid; cap_nids[nums] = nid; src = nid; for (;;) { int n; type = get_wcaps_type(get_wcaps(codec, src)); if (type == AC_WID_PIN) break; if (type == AC_WID_AUD_SEL) { cap_nids[nums] = src; break; } n = snd_hda_get_conn_list(codec, src, &list); if (n > 1) { cap_nids[nums] = src; break; } else if (n != 1) break; src = *list; } if (++nums >= max_nums) break; } |
d6cc9fabd ALSA: hda - Parse... |
2606 |
spec->adc_nids = spec->private_adc_nids; |
21268961d ALSA: hda - More ... |
2607 |
spec->capsrc_nids = spec->private_capsrc_nids; |
d6cc9fabd ALSA: hda - Parse... |
2608 |
spec->num_adc_nids = nums; |
b78217096 ALSA: hda - Parse... |
2609 2610 |
return nums; } |
e9edcee06 [ALSA] hda-codec ... |
2611 |
/* create playback/capture controls for input pins */ |
b78217096 ALSA: hda - Parse... |
2612 |
static int alc_auto_create_input_ctls(struct hda_codec *codec) |
e9edcee06 [ALSA] hda-codec ... |
2613 |
{ |
05f5f4770 ALSA: hda - Gener... |
2614 |
struct alc_spec *spec = codec->spec; |
b78217096 ALSA: hda - Parse... |
2615 2616 |
const struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t mixer = spec->mixer_nid; |
61b9b9b10 ALSA: hda - Consi... |
2617 |
struct hda_input_mux *imux = &spec->private_imux[0]; |
b78217096 ALSA: hda - Parse... |
2618 |
int num_adcs; |
b78217096 ALSA: hda - Parse... |
2619 |
int i, c, err, idx, type_idx = 0; |
5322bf279 ALSA: HDA: Fix vo... |
2620 |
const char *prev_label = NULL; |
e9edcee06 [ALSA] hda-codec ... |
2621 |
|
d6cc9fabd ALSA: hda - Parse... |
2622 |
num_adcs = alc_auto_fill_adc_caps(codec); |
b78217096 ALSA: hda - Parse... |
2623 2624 |
if (num_adcs < 0) return 0; |
66ceeb6bc ALSA: hda - Use n... |
2625 |
for (i = 0; i < cfg->num_inputs; i++) { |
05f5f4770 ALSA: hda - Gener... |
2626 |
hda_nid_t pin; |
10a20af7c ALSA: hda - Impro... |
2627 |
const char *label; |
05f5f4770 ALSA: hda - Gener... |
2628 |
|
66ceeb6bc ALSA: hda - Use n... |
2629 |
pin = cfg->inputs[i].pin; |
05f5f4770 ALSA: hda - Gener... |
2630 2631 |
if (!alc_is_input_pin(codec, pin)) continue; |
5322bf279 ALSA: HDA: Fix vo... |
2632 |
label = hda_get_autocfg_input_label(codec, cfg, i); |
24de183ed ALSA: hda/realtek... |
2633 2634 |
if (spec->shared_mic_hp && !strcmp(label, "Misc")) label = "Headphone Mic"; |
5322bf279 ALSA: HDA: Fix vo... |
2635 |
if (prev_label && !strcmp(label, prev_label)) |
66ceeb6bc ALSA: hda - Use n... |
2636 2637 2638 |
type_idx++; else type_idx = 0; |
5322bf279 ALSA: HDA: Fix vo... |
2639 |
prev_label = label; |
05f5f4770 ALSA: hda - Gener... |
2640 2641 2642 2643 |
if (mixer) { idx = get_connection_index(codec, mixer, pin); if (idx >= 0) { err = new_analog_input(spec, pin, |
10a20af7c ALSA: hda - Impro... |
2644 2645 |
label, type_idx, idx, mixer); |
05f5f4770 ALSA: hda - Gener... |
2646 2647 2648 2649 |
if (err < 0) return err; } } |
b78217096 ALSA: hda - Parse... |
2650 |
for (c = 0; c < num_adcs; c++) { |
61071594f ALSA: hda/realtek... |
2651 |
hda_nid_t cap = get_capsrc(spec, c); |
d6cc9fabd ALSA: hda - Parse... |
2652 |
idx = get_connection_index(codec, cap, pin); |
b78217096 ALSA: hda - Parse... |
2653 |
if (idx >= 0) { |
21268961d ALSA: hda - More ... |
2654 |
spec->imux_pins[imux->num_items] = pin; |
b78217096 ALSA: hda - Parse... |
2655 2656 2657 2658 |
snd_hda_add_imux_item(imux, label, idx, NULL); break; } } |
e9edcee06 [ALSA] hda-codec ... |
2659 |
} |
21268961d ALSA: hda - More ... |
2660 2661 2662 |
spec->num_mux_defs = 1; spec->input_mux = imux; |
e9edcee06 [ALSA] hda-codec ... |
2663 2664 |
return 0; } |
24de183ed ALSA: hda/realtek... |
2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 |
/* create a shared input with the headphone out */ static int alc_auto_create_shared_input(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; unsigned int defcfg; hda_nid_t nid; /* only one internal input pin? */ if (cfg->num_inputs != 1) return 0; defcfg = snd_hda_codec_get_pincfg(codec, cfg->inputs[0].pin); if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) return 0; if (cfg->hp_outs == 1 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) nid = cfg->hp_pins[0]; /* OK, we have a single HP-out */ else if (cfg->line_outs == 1 && cfg->line_out_type == AUTO_PIN_HP_OUT) nid = cfg->line_out_pins[0]; /* OK, we have a single line-out */ else return 0; /* both not available */ if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IN)) return 0; /* no input */ cfg->inputs[1].pin = nid; cfg->inputs[1].type = AUTO_PIN_MIC; cfg->num_inputs = 2; spec->shared_mic_hp = 1; snd_printdd("realtek: Enable shared I/O jack on NID 0x%x ", nid); return 0; } |
f6c7e5461 [ALSA] hda-codec ... |
2698 2699 2700 2701 2702 2703 |
static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, unsigned int pin_type) { snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); /* unmute pin */ |
44c024005 ALSA: hda - Fix a... |
2704 2705 |
if (nid_has_mute(codec, nid, HDA_OUTPUT)) snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
d260cdf65 [ALSA] hda-codec ... |
2706 |
AMP_OUT_UNMUTE); |
f6c7e5461 [ALSA] hda-codec ... |
2707 |
} |
baba8ee9d [ALSA] hda-codec ... |
2708 2709 2710 2711 2712 2713 2714 |
static int get_pin_type(int line_out_type) { if (line_out_type == AUTO_PIN_HP_OUT) return PIN_HP; else return PIN_OUT; } |
0a7f53209 ALSA: hda - Unify... |
2715 |
static void alc_auto_init_analog_input(struct hda_codec *codec) |
e9edcee06 [ALSA] hda-codec ... |
2716 2717 |
{ struct alc_spec *spec = codec->spec; |
66ceeb6bc ALSA: hda - Use n... |
2718 |
struct auto_pin_cfg *cfg = &spec->autocfg; |
e9edcee06 [ALSA] hda-codec ... |
2719 |
int i; |
66ceeb6bc ALSA: hda - Use n... |
2720 2721 |
for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t nid = cfg->inputs[i].pin; |
05f5f4770 ALSA: hda - Gener... |
2722 |
if (alc_is_input_pin(codec, nid)) { |
30ea098fc ALSA: hda - Fix i... |
2723 |
alc_set_input_pin(codec, nid, cfg->inputs[i].type); |
1f0f4b803 ALSA: hda - Reduc... |
2724 |
if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) |
f12ab1e07 [ALSA] hda-codec ... |
2725 2726 |
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
e9edcee06 [ALSA] hda-codec ... |
2727 2728 2729 |
AMP_OUT_MUTE); } } |
1f0f4b803 ALSA: hda - Reduc... |
2730 2731 2732 2733 2734 2735 2736 2737 2738 |
/* mute all loopback inputs */ if (spec->mixer_nid) { int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL); for (i = 0; i < nums; i++) snd_hda_codec_write(codec, spec->mixer_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(i)); } |
e9edcee06 [ALSA] hda-codec ... |
2739 |
} |
1d045db96 ALSA: hda - Split... |
2740 2741 |
/* convert from MIX nid to DAC */ static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid) |
e9edcee06 [ALSA] hda-codec ... |
2742 |
{ |
1d045db96 ALSA: hda - Split... |
2743 2744 |
hda_nid_t list[5]; int i, num; |
4a79ba34c ALSA: hda - Add a... |
2745 |
|
afcd55150 ALSA: hda - Merge... |
2746 2747 |
if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_AUD_OUT) return nid; |
1d045db96 ALSA: hda - Split... |
2748 2749 2750 2751 2752 2753 |
num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list)); for (i = 0; i < num; i++) { if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT) return list[i]; } return 0; |
e9edcee06 [ALSA] hda-codec ... |
2754 |
} |
1d045db96 ALSA: hda - Split... |
2755 2756 |
/* go down to the selector widget before the mixer */ static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin) |
e9edcee06 [ALSA] hda-codec ... |
2757 |
{ |
1d045db96 ALSA: hda - Split... |
2758 2759 2760 2761 2762 2763 2764 |
hda_nid_t srcs[5]; int num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); if (num != 1 || get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL) return pin; return srcs[0]; |
e9edcee06 [ALSA] hda-codec ... |
2765 |
} |
1d045db96 ALSA: hda - Split... |
2766 2767 2768 |
/* get MIX nid connected to the given pin targeted to DAC */ static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) |
748cce431 ALSA: hda - Fix i... |
2769 |
{ |
1d045db96 ALSA: hda - Split... |
2770 2771 2772 2773 2774 2775 2776 2777 |
hda_nid_t mix[5]; int i, num; pin = alc_go_down_to_selector(codec, pin); num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); for (i = 0; i < num; i++) { if (alc_auto_mix_to_dac(codec, mix[i]) == dac) return mix[i]; |
748cce431 ALSA: hda - Fix i... |
2778 |
} |
1d045db96 ALSA: hda - Split... |
2779 |
return 0; |
748cce431 ALSA: hda - Fix i... |
2780 |
} |
1d045db96 ALSA: hda - Split... |
2781 2782 2783 |
/* select the connection from pin to DAC if needed */ static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) |
eaa9b3a74 ALSA: hda - Fix c... |
2784 |
{ |
1d045db96 ALSA: hda - Split... |
2785 2786 |
hda_nid_t mix[5]; int i, num; |
eaa9b3a74 ALSA: hda - Fix c... |
2787 |
|
1d045db96 ALSA: hda - Split... |
2788 2789 2790 |
pin = alc_go_down_to_selector(codec, pin); num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); if (num < 2) |
8ed99d976 ALSA: hda - Add d... |
2791 |
return 0; |
1d045db96 ALSA: hda - Split... |
2792 2793 2794 2795 2796 2797 |
for (i = 0; i < num; i++) { if (alc_auto_mix_to_dac(codec, mix[i]) == dac) { snd_hda_codec_update_cache(codec, pin, 0, AC_VERB_SET_CONNECT_SEL, i); return 0; } |
840b64c08 ALSA: hda - Add s... |
2798 |
} |
1d045db96 ALSA: hda - Split... |
2799 |
return 0; |
840b64c08 ALSA: hda - Add s... |
2800 |
} |
1d045db96 ALSA: hda - Split... |
2801 2802 |
/* look for an empty DAC slot */ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) |
584c0c4c3 ALSA: hda - Initi... |
2803 2804 |
{ struct alc_spec *spec = codec->spec; |
1d045db96 ALSA: hda - Split... |
2805 2806 |
hda_nid_t srcs[5]; int i, num; |
21268961d ALSA: hda - More ... |
2807 |
|
1d045db96 ALSA: hda - Split... |
2808 2809 2810 2811 2812 2813 2814 |
pin = alc_go_down_to_selector(codec, pin); num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); for (i = 0; i < num; i++) { hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); if (!nid) continue; if (found_in_nid_list(nid, spec->multiout.dac_nids, |
0a34b42b6 ALSA: hda/realtek... |
2815 |
ARRAY_SIZE(spec->private_dac_nids))) |
1d045db96 ALSA: hda - Split... |
2816 |
continue; |
c267468e9 ALSA: hda - Prefe... |
2817 2818 2819 |
if (found_in_nid_list(nid, spec->multiout.hp_out_nid, ARRAY_SIZE(spec->multiout.hp_out_nid))) continue; |
1d045db96 ALSA: hda - Split... |
2820 2821 2822 2823 2824 2825 |
if (found_in_nid_list(nid, spec->multiout.extra_out_nid, ARRAY_SIZE(spec->multiout.extra_out_nid))) continue; return nid; } return 0; |
584c0c4c3 ALSA: hda - Initi... |
2826 |
} |
07b18f69a ALSA: hda/realtek... |
2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 |
/* check whether the DAC is reachable from the pin */ static bool alc_auto_is_dac_reachable(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) { hda_nid_t srcs[5]; int i, num; pin = alc_go_down_to_selector(codec, pin); num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); for (i = 0; i < num; i++) { hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); if (nid == dac) return true; } return false; } |
1d045db96 ALSA: hda - Split... |
2843 |
static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) |
f9e336f65 ALSA: hda - Unify... |
2844 |
{ |
1d045db96 ALSA: hda - Split... |
2845 2846 2847 2848 |
hda_nid_t sel = alc_go_down_to_selector(codec, pin); if (snd_hda_get_conn_list(codec, sel, NULL) == 1) return alc_auto_look_for_dac(codec, pin); return 0; |
f9e336f65 ALSA: hda - Unify... |
2849 |
} |
0a34b42b6 ALSA: hda/realtek... |
2850 |
/* return 0 if no possible DAC is found, 1 if one or more found */ |
c267468e9 ALSA: hda - Prefe... |
2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 |
static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, const hda_nid_t *pins, hda_nid_t *dacs) { int i; if (num_outs && !dacs[0]) { dacs[0] = alc_auto_look_for_dac(codec, pins[0]); if (!dacs[0]) return 0; } for (i = 1; i < num_outs; i++) dacs[i] = get_dac_if_single(codec, pins[i]); for (i = 1; i < num_outs; i++) { if (!dacs[i]) dacs[i] = alc_auto_look_for_dac(codec, pins[i]); } |
0a34b42b6 ALSA: hda/realtek... |
2868 |
return 1; |
c267468e9 ALSA: hda - Prefe... |
2869 2870 2871 |
} static int alc_auto_fill_multi_ios(struct hda_codec *codec, |
07b18f69a ALSA: hda/realtek... |
2872 |
unsigned int location, int offset); |
fde48a1f8 ALSA: HDA: Realte... |
2873 2874 |
static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac); |
c267468e9 ALSA: hda - Prefe... |
2875 |
|
1d045db96 ALSA: hda - Split... |
2876 2877 |
/* fill in the dac_nids table from the parsed pin configuration */ static int alc_auto_fill_dac_nids(struct hda_codec *codec) |
21268961d ALSA: hda - More ... |
2878 2879 |
{ struct alc_spec *spec = codec->spec; |
0a34b42b6 ALSA: hda/realtek... |
2880 |
struct auto_pin_cfg *cfg = &spec->autocfg; |
07b18f69a ALSA: hda/realtek... |
2881 2882 |
unsigned int location, defcfg; int num_pins; |
1d045db96 ALSA: hda - Split... |
2883 2884 |
bool redone = false; int i; |
21268961d ALSA: hda - More ... |
2885 |
|
1d045db96 ALSA: hda - Split... |
2886 |
again: |
8f398ae72 ALSA: hda - Fix D... |
2887 2888 |
/* set num_dacs once to full for alc_auto_look_for_dac() */ spec->multiout.num_dacs = cfg->line_outs; |
e23832ac1 ALSA: hda - Suppo... |
2889 |
spec->multiout.hp_out_nid[0] = 0; |
1d045db96 ALSA: hda - Split... |
2890 2891 2892 |
spec->multiout.extra_out_nid[0] = 0; memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); spec->multiout.dac_nids = spec->private_dac_nids; |
0a34b42b6 ALSA: hda/realtek... |
2893 |
spec->multi_ios = 0; |
21268961d ALSA: hda - More ... |
2894 |
|
1d045db96 ALSA: hda - Split... |
2895 2896 2897 2898 2899 2900 |
/* fill hard-wired DACs first */ if (!redone) { for (i = 0; i < cfg->line_outs; i++) spec->private_dac_nids[i] = get_dac_if_single(codec, cfg->line_out_pins[i]); if (cfg->hp_outs) |
e23832ac1 ALSA: hda - Suppo... |
2901 |
spec->multiout.hp_out_nid[0] = |
1d045db96 ALSA: hda - Split... |
2902 2903 2904 2905 |
get_dac_if_single(codec, cfg->hp_pins[0]); if (cfg->speaker_outs) spec->multiout.extra_out_nid[0] = get_dac_if_single(codec, cfg->speaker_pins[0]); |
21268961d ALSA: hda - More ... |
2906 |
} |
1d045db96 ALSA: hda - Split... |
2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 |
for (i = 0; i < cfg->line_outs; i++) { hda_nid_t pin = cfg->line_out_pins[i]; if (spec->private_dac_nids[i]) continue; spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin); if (!spec->private_dac_nids[i] && !redone) { /* if we can't find primary DACs, re-probe without * checking the hard-wired DACs */ redone = true; goto again; |
21268961d ALSA: hda - More ... |
2918 2919 |
} } |
8f398ae72 ALSA: hda - Fix D... |
2920 2921 |
/* re-count num_dacs and squash invalid entries */ spec->multiout.num_dacs = 0; |
1d045db96 ALSA: hda - Split... |
2922 2923 2924 |
for (i = 0; i < cfg->line_outs; i++) { if (spec->private_dac_nids[i]) spec->multiout.num_dacs++; |
0a34b42b6 ALSA: hda/realtek... |
2925 |
else { |
1d045db96 ALSA: hda - Split... |
2926 2927 2928 |
memmove(spec->private_dac_nids + i, spec->private_dac_nids + i + 1, sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); |
0a34b42b6 ALSA: hda/realtek... |
2929 2930 |
spec->private_dac_nids[cfg->line_outs - 1] = 0; } |
1d045db96 ALSA: hda - Split... |
2931 |
} |
c267468e9 ALSA: hda - Prefe... |
2932 2933 |
if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { /* try to fill multi-io first */ |
c267468e9 ALSA: hda - Prefe... |
2934 2935 |
defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); location = get_defcfg_location(defcfg); |
21268961d ALSA: hda - More ... |
2936 |
|
07b18f69a ALSA: hda/realtek... |
2937 |
num_pins = alc_auto_fill_multi_ios(codec, location, 0); |
c267468e9 ALSA: hda - Prefe... |
2938 2939 2940 2941 2942 2943 |
if (num_pins > 0) { spec->multi_ios = num_pins; spec->ext_channel_count = 2; spec->multiout.num_dacs = num_pins + 1; } } |
23c09b009 ALSA: hda - Suppo... |
2944 |
|
716eef032 ALSA: hda/realtek... |
2945 2946 |
if (cfg->line_out_type != AUTO_PIN_HP_OUT) alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, |
c267468e9 ALSA: hda - Prefe... |
2947 |
spec->multiout.hp_out_nid); |
0a34b42b6 ALSA: hda/realtek... |
2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 |
if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, spec->multiout.extra_out_nid); /* if no speaker volume is assigned, try again as the primary * output */ if (!err && cfg->speaker_outs > 0 && cfg->line_out_type == AUTO_PIN_HP_OUT) { cfg->hp_outs = cfg->line_outs; memcpy(cfg->hp_pins, cfg->line_out_pins, sizeof(cfg->hp_pins)); cfg->line_outs = cfg->speaker_outs; memcpy(cfg->line_out_pins, cfg->speaker_pins, sizeof(cfg->speaker_pins)); cfg->speaker_outs = 0; memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; redone = false; goto again; } } |
23c09b009 ALSA: hda - Suppo... |
2970 |
|
07b18f69a ALSA: hda/realtek... |
2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 |
if (!spec->multi_ios && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs) { /* try multi-ios with HP + inputs */ defcfg = snd_hda_codec_get_pincfg(codec, cfg->hp_pins[0]); location = get_defcfg_location(defcfg); num_pins = alc_auto_fill_multi_ios(codec, location, 1); if (num_pins > 0) { spec->multi_ios = num_pins; spec->ext_channel_count = 2; spec->multiout.num_dacs = num_pins + 1; } } |
fde48a1f8 ALSA: HDA: Realte... |
2985 2986 2987 2988 |
if (cfg->line_out_pins[0]) spec->vmaster_nid = alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], spec->multiout.dac_nids[0]); |
23c09b009 ALSA: hda - Suppo... |
2989 2990 |
return 0; } |
527e4d73a ALSA: hda/realtek... |
2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 |
static inline unsigned int get_ctl_pos(unsigned int data) { hda_nid_t nid = get_amp_nid_(data); unsigned int dir = get_amp_direction_(data); return (nid << 1) | dir; } #define is_ctl_used(bits, data) \ test_bit(get_ctl_pos(data), bits) #define mark_ctl_usage(bits, data) \ set_bit(get_ctl_pos(data), bits) |
1d045db96 ALSA: hda - Split... |
3002 3003 3004 |
static int alc_auto_add_vol_ctl(struct hda_codec *codec, const char *pfx, int cidx, hda_nid_t nid, unsigned int chs) |
6694635d3 ALSA: hda - Fix A... |
3005 |
{ |
527e4d73a ALSA: hda/realtek... |
3006 3007 |
struct alc_spec *spec = codec->spec; unsigned int val; |
afcd55150 ALSA: hda - Merge... |
3008 3009 |
if (!nid) return 0; |
527e4d73a ALSA: hda/realtek... |
3010 3011 3012 3013 |
val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT); if (is_ctl_used(spec->vol_ctls, val) && chs != 2) /* exclude LFE */ return 0; mark_ctl_usage(spec->vol_ctls, val); |
1d045db96 ALSA: hda - Split... |
3014 |
return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx, |
527e4d73a ALSA: hda/realtek... |
3015 |
val); |
1d045db96 ALSA: hda - Split... |
3016 |
} |
6694635d3 ALSA: hda - Fix A... |
3017 |
|
e29d37781 ALSA: hda/realtek... |
3018 3019 3020 3021 3022 3023 3024 3025 3026 |
static int alc_auto_add_stereo_vol(struct hda_codec *codec, const char *pfx, int cidx, hda_nid_t nid) { int chs = 1; if (get_wcaps(codec, nid) & AC_WCAP_STEREO) chs = 3; return alc_auto_add_vol_ctl(codec, pfx, cidx, nid, chs); } |
21268961d ALSA: hda - More ... |
3027 |
|
1d045db96 ALSA: hda - Split... |
3028 3029 3030 3031 3032 3033 3034 |
/* create a mute-switch for the given mixer widget; * if it has multiple sources (e.g. DAC and loopback), create a bind-mute */ static int alc_auto_add_sw_ctl(struct hda_codec *codec, const char *pfx, int cidx, hda_nid_t nid, unsigned int chs) { |
527e4d73a ALSA: hda/realtek... |
3035 |
struct alc_spec *spec = codec->spec; |
afcd55150 ALSA: hda - Merge... |
3036 |
int wid_type; |
1d045db96 ALSA: hda - Split... |
3037 3038 |
int type; unsigned long val; |
afcd55150 ALSA: hda - Merge... |
3039 3040 3041 3042 3043 3044 3045 |
if (!nid) return 0; wid_type = get_wcaps_type(get_wcaps(codec, nid)); if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) { type = ALC_CTL_WIDGET_MUTE; val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT); } else if (snd_hda_get_conn_list(codec, nid, NULL) == 1) { |
1d045db96 ALSA: hda - Split... |
3046 3047 3048 3049 3050 |
type = ALC_CTL_WIDGET_MUTE; val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT); } else { type = ALC_CTL_BIND_MUTE; val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT); |
6694635d3 ALSA: hda - Fix A... |
3051 |
} |
527e4d73a ALSA: hda/realtek... |
3052 3053 3054 |
if (is_ctl_used(spec->sw_ctls, val) && chs != 2) /* exclude LFE */ return 0; mark_ctl_usage(spec->sw_ctls, val); |
1d045db96 ALSA: hda - Split... |
3055 |
return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); |
6694635d3 ALSA: hda - Fix A... |
3056 |
} |
e29d37781 ALSA: hda/realtek... |
3057 3058 3059 3060 3061 3062 3063 3064 |
static int alc_auto_add_stereo_sw(struct hda_codec *codec, const char *pfx, int cidx, hda_nid_t nid) { int chs = 1; if (get_wcaps(codec, nid) & AC_WCAP_STEREO) chs = 3; return alc_auto_add_sw_ctl(codec, pfx, cidx, nid, chs); } |
dc1eae256 ALSA: hda - Add a... |
3065 |
|
afcd55150 ALSA: hda - Merge... |
3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 |
static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) { hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac); if (nid_has_mute(codec, pin, HDA_OUTPUT)) return pin; else if (mix && nid_has_mute(codec, mix, HDA_INPUT)) return mix; else if (nid_has_mute(codec, dac, HDA_OUTPUT)) return dac; return 0; } static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) { hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac); if (nid_has_volume(codec, dac, HDA_OUTPUT)) return dac; else if (nid_has_volume(codec, mix, HDA_OUTPUT)) return mix; else if (nid_has_volume(codec, pin, HDA_OUTPUT)) return pin; return 0; } |
1d045db96 ALSA: hda - Split... |
3091 3092 3093 |
/* add playback controls from the parsed DAC table */ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) |
dc1eae256 ALSA: hda - Add a... |
3094 3095 |
{ struct alc_spec *spec = codec->spec; |
1d045db96 ALSA: hda - Split... |
3096 |
int i, err, noutputs; |
1f0f4b803 ALSA: hda - Reduc... |
3097 |
|
1d045db96 ALSA: hda - Split... |
3098 3099 3100 |
noutputs = cfg->line_outs; if (spec->multi_ios > 0) noutputs += spec->multi_ios; |
1da177e4c Linux-2.6.12-rc2 |
3101 |
|
1d045db96 ALSA: hda - Split... |
3102 3103 3104 |
for (i = 0; i < noutputs; i++) { const char *name; int index; |
afcd55150 ALSA: hda - Merge... |
3105 3106 3107 3108 3109 |
hda_nid_t dac, pin; hda_nid_t sw, vol; dac = spec->multiout.dac_nids[i]; if (!dac) |
1d045db96 ALSA: hda - Split... |
3110 3111 3112 3113 3114 |
continue; if (i >= cfg->line_outs) pin = spec->multi_io[i - 1].pin; else pin = cfg->line_out_pins[i]; |
afcd55150 ALSA: hda - Merge... |
3115 3116 3117 |
sw = alc_look_for_out_mute_nid(codec, pin, dac); vol = alc_look_for_out_vol_nid(codec, pin, dac); |
1d045db96 ALSA: hda - Split... |
3118 |
name = alc_get_line_out_pfx(spec, i, true, &index); |
9c4e84d3b ALSA: hda - Fix C... |
3119 |
if (!name || !strcmp(name, "CLFE")) { |
1d045db96 ALSA: hda - Split... |
3120 |
/* Center/LFE */ |
afcd55150 ALSA: hda - Merge... |
3121 |
err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1); |
1d045db96 ALSA: hda - Split... |
3122 3123 |
if (err < 0) return err; |
afcd55150 ALSA: hda - Merge... |
3124 |
err = alc_auto_add_vol_ctl(codec, "LFE", 0, vol, 2); |
1d045db96 ALSA: hda - Split... |
3125 3126 |
if (err < 0) return err; |
afcd55150 ALSA: hda - Merge... |
3127 |
err = alc_auto_add_sw_ctl(codec, "Center", 0, sw, 1); |
1d045db96 ALSA: hda - Split... |
3128 3129 |
if (err < 0) return err; |
afcd55150 ALSA: hda - Merge... |
3130 |
err = alc_auto_add_sw_ctl(codec, "LFE", 0, sw, 2); |
1d045db96 ALSA: hda - Split... |
3131 3132 3133 |
if (err < 0) return err; } else { |
afcd55150 ALSA: hda - Merge... |
3134 |
err = alc_auto_add_stereo_vol(codec, name, index, vol); |
1d045db96 ALSA: hda - Split... |
3135 3136 |
if (err < 0) return err; |
afcd55150 ALSA: hda - Merge... |
3137 |
err = alc_auto_add_stereo_sw(codec, name, index, sw); |
1d045db96 ALSA: hda - Split... |
3138 3139 |
if (err < 0) return err; |
e9edcee06 [ALSA] hda-codec ... |
3140 |
} |
1da177e4c Linux-2.6.12-rc2 |
3141 |
} |
1d045db96 ALSA: hda - Split... |
3142 3143 |
return 0; } |
1da177e4c Linux-2.6.12-rc2 |
3144 |
|
1d045db96 ALSA: hda - Split... |
3145 |
static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, |
766ddee68 ALSA: hda/realtek... |
3146 3147 |
hda_nid_t dac, const char *pfx, int cidx) |
1d045db96 ALSA: hda - Split... |
3148 3149 |
{ struct alc_spec *spec = codec->spec; |
afcd55150 ALSA: hda - Merge... |
3150 |
hda_nid_t sw, vol; |
1d045db96 ALSA: hda - Split... |
3151 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
3152 |
|
1d045db96 ALSA: hda - Split... |
3153 |
if (!dac) { |
527e4d73a ALSA: hda/realtek... |
3154 |
unsigned int val; |
1d045db96 ALSA: hda - Split... |
3155 3156 3157 3158 |
/* the corresponding DAC is already occupied */ if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) return 0; /* no way */ /* create a switch only */ |
527e4d73a ALSA: hda/realtek... |
3159 3160 3161 3162 |
val = HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT); if (is_ctl_used(spec->sw_ctls, val)) return 0; /* already created */ mark_ctl_usage(spec->sw_ctls, val); |
766ddee68 ALSA: hda/realtek... |
3163 |
return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val); |
e9edcee06 [ALSA] hda-codec ... |
3164 |
} |
1da177e4c Linux-2.6.12-rc2 |
3165 |
|
afcd55150 ALSA: hda - Merge... |
3166 3167 |
sw = alc_look_for_out_mute_nid(codec, pin, dac); vol = alc_look_for_out_vol_nid(codec, pin, dac); |
766ddee68 ALSA: hda/realtek... |
3168 |
err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); |
1d045db96 ALSA: hda - Split... |
3169 3170 |
if (err < 0) return err; |
766ddee68 ALSA: hda/realtek... |
3171 |
err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); |
1d045db96 ALSA: hda - Split... |
3172 3173 |
if (err < 0) return err; |
1da177e4c Linux-2.6.12-rc2 |
3174 3175 |
return 0; } |
23c09b009 ALSA: hda - Suppo... |
3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 |
static struct hda_bind_ctls *new_bind_ctl(struct hda_codec *codec, unsigned int nums, struct hda_ctl_ops *ops) { struct alc_spec *spec = codec->spec; struct hda_bind_ctls **ctlp, *ctl; snd_array_init(&spec->bind_ctls, sizeof(ctl), 8); ctlp = snd_array_new(&spec->bind_ctls); if (!ctlp) return NULL; ctl = kzalloc(sizeof(*ctl) + sizeof(long) * (nums + 1), GFP_KERNEL); *ctlp = ctl; if (ctl) ctl->ops = ops; return ctl; } /* add playback controls for speaker and HP outputs */ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, const hda_nid_t *pins, const hda_nid_t *dacs, const char *pfx) { struct alc_spec *spec = codec->spec; struct hda_bind_ctls *ctl; char name[32]; int i, n, err; if (!num_pins || !pins[0]) return 0; |
527e4d73a ALSA: hda/realtek... |
3206 3207 3208 3209 |
if (num_pins == 1) { hda_nid_t dac = *dacs; if (!dac) dac = spec->multiout.dac_nids[0]; |
766ddee68 ALSA: hda/realtek... |
3210 |
return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); |
527e4d73a ALSA: hda/realtek... |
3211 |
} |
23c09b009 ALSA: hda - Suppo... |
3212 3213 3214 3215 |
if (dacs[num_pins - 1]) { /* OK, we have a multi-output system with individual volumes */ for (i = 0; i < num_pins; i++) { |
766ddee68 ALSA: hda/realtek... |
3216 3217 3218 3219 3220 3221 3222 3223 3224 |
if (num_pins >= 3) { snprintf(name, sizeof(name), "%s %s", pfx, channel_name[i]); err = alc_auto_create_extra_out(codec, pins[i], dacs[i], name, 0); } else { err = alc_auto_create_extra_out(codec, pins[i], dacs[i], pfx, i); } |
23c09b009 ALSA: hda - Suppo... |
3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 |
if (err < 0) return err; } return 0; } /* Let's create a bind-controls */ ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_sw); if (!ctl) return -ENOMEM; n = 0; for (i = 0; i < num_pins; i++) { if (get_wcaps(codec, pins[i]) & AC_WCAP_OUT_AMP) ctl->values[n++] = HDA_COMPOSE_AMP_VAL(pins[i], 3, 0, HDA_OUTPUT); } if (n) { snprintf(name, sizeof(name), "%s Playback Switch", pfx); err = add_control(spec, ALC_CTL_BIND_SW, name, 0, (long)ctl); if (err < 0) return err; } ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol); if (!ctl) return -ENOMEM; n = 0; for (i = 0; i < num_pins; i++) { hda_nid_t vol; if (!pins[i] || !dacs[i]) continue; vol = alc_look_for_out_vol_nid(codec, pins[i], dacs[i]); if (vol) ctl->values[n++] = HDA_COMPOSE_AMP_VAL(vol, 3, 0, HDA_OUTPUT); } if (n) { snprintf(name, sizeof(name), "%s Playback Volume", pfx); err = add_control(spec, ALC_CTL_BIND_VOL, name, 0, (long)ctl); if (err < 0) return err; } return 0; } |
1d045db96 ALSA: hda - Split... |
3269 |
static int alc_auto_create_hp_out(struct hda_codec *codec) |
bec15c3a5 [ALSA] hda-codec ... |
3270 |
{ |
1d045db96 ALSA: hda - Split... |
3271 |
struct alc_spec *spec = codec->spec; |
e23832ac1 ALSA: hda - Suppo... |
3272 3273 3274 3275 |
return alc_auto_create_extra_outs(codec, spec->autocfg.hp_outs, spec->autocfg.hp_pins, spec->multiout.hp_out_nid, "Headphone"); |
bec15c3a5 [ALSA] hda-codec ... |
3276 |
} |
1d045db96 ALSA: hda - Split... |
3277 |
static int alc_auto_create_speaker_out(struct hda_codec *codec) |
bec15c3a5 [ALSA] hda-codec ... |
3278 |
{ |
bec15c3a5 [ALSA] hda-codec ... |
3279 |
struct alc_spec *spec = codec->spec; |
23c09b009 ALSA: hda - Suppo... |
3280 3281 3282 3283 |
return alc_auto_create_extra_outs(codec, spec->autocfg.speaker_outs, spec->autocfg.speaker_pins, spec->multiout.extra_out_nid, "Speaker"); |
bec15c3a5 [ALSA] hda-codec ... |
3284 |
} |
1d045db96 ALSA: hda - Split... |
3285 |
static void alc_auto_set_output_and_unmute(struct hda_codec *codec, |
afcd55150 ALSA: hda - Merge... |
3286 |
hda_nid_t pin, int pin_type, |
1d045db96 ALSA: hda - Split... |
3287 |
hda_nid_t dac) |
bec15c3a5 [ALSA] hda-codec ... |
3288 |
{ |
1d045db96 ALSA: hda - Split... |
3289 |
int i, num; |
afcd55150 ALSA: hda - Merge... |
3290 |
hda_nid_t nid, mix = 0; |
1d045db96 ALSA: hda - Split... |
3291 |
hda_nid_t srcs[HDA_MAX_CONNECTIONS]; |
bec15c3a5 [ALSA] hda-codec ... |
3292 |
|
afcd55150 ALSA: hda - Merge... |
3293 3294 |
alc_set_pin_output(codec, pin, pin_type); nid = alc_go_down_to_selector(codec, pin); |
1d045db96 ALSA: hda - Split... |
3295 3296 3297 3298 3299 3300 3301 3302 3303 |
num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); for (i = 0; i < num; i++) { if (alc_auto_mix_to_dac(codec, srcs[i]) != dac) continue; mix = srcs[i]; break; } if (!mix) return; |
bec15c3a5 [ALSA] hda-codec ... |
3304 |
|
1d045db96 ALSA: hda - Split... |
3305 3306 3307 3308 |
/* need the manual connection? */ if (num > 1) snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); /* unmute mixer widget inputs */ |
afcd55150 ALSA: hda - Merge... |
3309 3310 |
if (nid_has_mute(codec, mix, HDA_INPUT)) { snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
1d045db96 ALSA: hda - Split... |
3311 |
AMP_IN_UNMUTE(0)); |
afcd55150 ALSA: hda - Merge... |
3312 |
snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
1d045db96 ALSA: hda - Split... |
3313 |
AMP_IN_UNMUTE(1)); |
afcd55150 ALSA: hda - Merge... |
3314 |
} |
1d045db96 ALSA: hda - Split... |
3315 |
/* initialize volume */ |
afcd55150 ALSA: hda - Merge... |
3316 3317 3318 3319 |
nid = alc_look_for_out_vol_nid(codec, pin, dac); if (nid) snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); |
43dea228a ALSA: hda - Fix s... |
3320 3321 3322 3323 3324 3325 |
/* unmute DAC if it's not assigned to a mixer */ nid = alc_look_for_out_mute_nid(codec, pin, dac); if (nid == mix && nid_has_mute(codec, dac, HDA_OUTPUT)) snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); |
1d045db96 ALSA: hda - Split... |
3326 |
} |
bec15c3a5 [ALSA] hda-codec ... |
3327 |
|
1d045db96 ALSA: hda - Split... |
3328 |
static void alc_auto_init_multi_out(struct hda_codec *codec) |
bec15c3a5 [ALSA] hda-codec ... |
3329 3330 |
{ struct alc_spec *spec = codec->spec; |
1d045db96 ALSA: hda - Split... |
3331 3332 |
int pin_type = get_pin_type(spec->autocfg.line_out_type); int i; |
bec15c3a5 [ALSA] hda-codec ... |
3333 |
|
1d045db96 ALSA: hda - Split... |
3334 3335 3336 3337 3338 3339 |
for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; if (nid) alc_auto_set_output_and_unmute(codec, nid, pin_type, spec->multiout.dac_nids[i]); } |
bec15c3a5 [ALSA] hda-codec ... |
3340 |
} |
1d045db96 ALSA: hda - Split... |
3341 |
static void alc_auto_init_extra_out(struct hda_codec *codec) |
e9427969f ALSA: hda - Conso... |
3342 3343 |
{ struct alc_spec *spec = codec->spec; |
8cd0775da ALSA: hda - Fix i... |
3344 |
int i; |
675c1aa3c ALSA: hda - Fix o... |
3345 |
hda_nid_t pin, dac; |
e9427969f ALSA: hda - Conso... |
3346 |
|
636030e90 ALSA: HDA: Fixup ... |
3347 |
for (i = 0; i < spec->autocfg.hp_outs; i++) { |
716eef032 ALSA: hda/realtek... |
3348 3349 |
if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) break; |
e23832ac1 ALSA: hda - Suppo... |
3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 |
pin = spec->autocfg.hp_pins[i]; if (!pin) break; dac = spec->multiout.hp_out_nid[i]; if (!dac) { if (i > 0 && spec->multiout.hp_out_nid[0]) dac = spec->multiout.hp_out_nid[0]; else dac = spec->multiout.dac_nids[0]; } |
675c1aa3c ALSA: hda - Fix o... |
3360 3361 |
alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); } |
8cd0775da ALSA: hda - Fix i... |
3362 |
for (i = 0; i < spec->autocfg.speaker_outs; i++) { |
716eef032 ALSA: hda/realtek... |
3363 3364 |
if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) break; |
8cd0775da ALSA: hda - Fix i... |
3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 |
pin = spec->autocfg.speaker_pins[i]; if (!pin) break; dac = spec->multiout.extra_out_nid[i]; if (!dac) { if (i > 0 && spec->multiout.extra_out_nid[0]) dac = spec->multiout.extra_out_nid[0]; else dac = spec->multiout.dac_nids[0]; } |
675c1aa3c ALSA: hda - Fix o... |
3375 3376 |
alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); } |
bc9f98a98 [ALSA] hda-codec ... |
3377 |
} |
df694daa3 [ALSA] hda-codec ... |
3378 |
/* |
1d045db96 ALSA: hda - Split... |
3379 |
* multi-io helper |
df694daa3 [ALSA] hda-codec ... |
3380 |
*/ |
1d045db96 ALSA: hda - Split... |
3381 |
static int alc_auto_fill_multi_ios(struct hda_codec *codec, |
07b18f69a ALSA: hda/realtek... |
3382 3383 |
unsigned int location, int offset) |
df694daa3 [ALSA] hda-codec ... |
3384 |
{ |
1d045db96 ALSA: hda - Split... |
3385 3386 |
struct alc_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; |
c267468e9 ALSA: hda - Prefe... |
3387 |
hda_nid_t prime_dac = spec->private_dac_nids[0]; |
07b18f69a ALSA: hda/realtek... |
3388 |
int type, i, dacs, num_pins = 0; |
ea1fb29ac ALSA: hda - fix s... |
3389 |
|
07b18f69a ALSA: hda/realtek... |
3390 |
dacs = spec->multiout.num_dacs; |
1d045db96 ALSA: hda - Split... |
3391 3392 3393 |
for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t nid = cfg->inputs[i].pin; |
07b18f69a ALSA: hda/realtek... |
3394 |
hda_nid_t dac = 0; |
1d045db96 ALSA: hda - Split... |
3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 |
unsigned int defcfg, caps; if (cfg->inputs[i].type != type) continue; defcfg = snd_hda_codec_get_pincfg(codec, nid); if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX) continue; if (location && get_defcfg_location(defcfg) != location) continue; caps = snd_hda_query_pin_caps(codec, nid); if (!(caps & AC_PINCAP_OUT)) continue; |
07b18f69a ALSA: hda/realtek... |
3406 3407 3408 3409 3410 3411 3412 |
if (offset && offset + num_pins < dacs) { dac = spec->private_dac_nids[offset + num_pins]; if (!alc_auto_is_dac_reachable(codec, nid, dac)) dac = 0; } if (!dac) dac = alc_auto_look_for_dac(codec, nid); |
1d045db96 ALSA: hda - Split... |
3413 3414 3415 3416 3417 3418 3419 |
if (!dac) continue; spec->multi_io[num_pins].pin = nid; spec->multi_io[num_pins].dac = dac; num_pins++; spec->private_dac_nids[spec->multiout.num_dacs++] = dac; } |
863b45180 ALSA: hda - Fix c... |
3420 |
} |
07b18f69a ALSA: hda/realtek... |
3421 |
spec->multiout.num_dacs = dacs; |
c267468e9 ALSA: hda - Prefe... |
3422 3423 |
if (num_pins < 2) { /* clear up again */ |
07b18f69a ALSA: hda/realtek... |
3424 3425 |
memset(spec->private_dac_nids + dacs, 0, sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - dacs)); |
c267468e9 ALSA: hda - Prefe... |
3426 |
spec->private_dac_nids[0] = prime_dac; |
1d045db96 ALSA: hda - Split... |
3427 |
return 0; |
c267468e9 ALSA: hda - Prefe... |
3428 |
} |
1d045db96 ALSA: hda - Split... |
3429 |
return num_pins; |
a361d84bf [ALSA] hda-codec ... |
3430 |
} |
1d045db96 ALSA: hda - Split... |
3431 3432 |
static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
a361d84bf [ALSA] hda-codec ... |
3433 |
{ |
1d045db96 ALSA: hda - Split... |
3434 |
struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
a361d84bf [ALSA] hda-codec ... |
3435 |
struct alc_spec *spec = codec->spec; |
a361d84bf [ALSA] hda-codec ... |
3436 |
|
1d045db96 ALSA: hda - Split... |
3437 3438 3439 3440 3441 3442 3443 3444 3445 |
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = spec->multi_ios + 1; if (uinfo->value.enumerated.item > spec->multi_ios) uinfo->value.enumerated.item = spec->multi_ios; sprintf(uinfo->value.enumerated.name, "%dch", (uinfo->value.enumerated.item + 1) * 2); return 0; } |
a361d84bf [ALSA] hda-codec ... |
3446 |
|
1d045db96 ALSA: hda - Split... |
3447 3448 3449 3450 3451 3452 3453 3454 |
static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2; return 0; } |
a361d84bf [ALSA] hda-codec ... |
3455 |
|
1d045db96 ALSA: hda - Split... |
3456 3457 3458 3459 |
static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output) { struct alc_spec *spec = codec->spec; hda_nid_t nid = spec->multi_io[idx].pin; |
a361d84bf [ALSA] hda-codec ... |
3460 |
|
1d045db96 ALSA: hda - Split... |
3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 |
if (!spec->multi_io[idx].ctl_in) spec->multi_io[idx].ctl_in = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); if (output) { snd_hda_codec_update_cache(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE, 0); alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac); } else { if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE); snd_hda_codec_update_cache(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->multi_io[idx].ctl_in); |
4f574b7b1 ALSA: hda - More ... |
3480 |
} |
1d045db96 ALSA: hda - Split... |
3481 |
return 0; |
a361d84bf [ALSA] hda-codec ... |
3482 |
} |
1d045db96 ALSA: hda - Split... |
3483 3484 |
static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
a361d84bf [ALSA] hda-codec ... |
3485 |
{ |
1d045db96 ALSA: hda - Split... |
3486 |
struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
f6c7e5461 [ALSA] hda-codec ... |
3487 |
struct alc_spec *spec = codec->spec; |
1d045db96 ALSA: hda - Split... |
3488 |
int i, ch; |
a361d84bf [ALSA] hda-codec ... |
3489 |
|
1d045db96 ALSA: hda - Split... |
3490 3491 3492 3493 3494 3495 3496 3497 3498 |
ch = ucontrol->value.enumerated.item[0]; if (ch < 0 || ch > spec->multi_ios) return -EINVAL; if (ch == (spec->ext_channel_count - 1) / 2) return 0; spec->ext_channel_count = (ch + 1) * 2; for (i = 0; i < spec->multi_ios; i++) alc_set_multi_io(codec, i, i < ch); spec->multiout.max_channels = spec->ext_channel_count; |
7b1655f5f ALSA: hda - Re-ad... |
3499 3500 |
if (spec->need_dac_fix && !spec->const_channel_count) spec->multiout.num_dacs = spec->multiout.max_channels / 2; |
1d045db96 ALSA: hda - Split... |
3501 3502 |
return 1; } |
3abf2f363 ALSA: hda - Fix p... |
3503 |
|
1d045db96 ALSA: hda - Split... |
3504 3505 3506 3507 3508 3509 |
static const struct snd_kcontrol_new alc_auto_channel_mode_enum = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", .info = alc_auto_ch_mode_info, .get = alc_auto_ch_mode_get, .put = alc_auto_ch_mode_put, |
a361d84bf [ALSA] hda-codec ... |
3510 |
}; |
23c09b009 ALSA: hda - Suppo... |
3511 |
static int alc_auto_add_multi_channel_mode(struct hda_codec *codec) |
a361d84bf [ALSA] hda-codec ... |
3512 |
{ |
1d045db96 ALSA: hda - Split... |
3513 |
struct alc_spec *spec = codec->spec; |
a361d84bf [ALSA] hda-codec ... |
3514 |
|
c267468e9 ALSA: hda - Prefe... |
3515 |
if (spec->multi_ios > 0) { |
1d045db96 ALSA: hda - Split... |
3516 |
struct snd_kcontrol_new *knew; |
a361d84bf [ALSA] hda-codec ... |
3517 |
|
1d045db96 ALSA: hda - Split... |
3518 3519 3520 3521 3522 3523 3524 |
knew = alc_kcontrol_new(spec); if (!knew) return -ENOMEM; *knew = alc_auto_channel_mode_enum; knew->name = kstrdup("Channel Mode", GFP_KERNEL); if (!knew->name) return -ENOMEM; |
a361d84bf [ALSA] hda-codec ... |
3525 |
} |
1d045db96 ALSA: hda - Split... |
3526 3527 |
return 0; } |
a361d84bf [ALSA] hda-codec ... |
3528 |
|
1d045db96 ALSA: hda - Split... |
3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 |
/* filter out invalid adc_nids (and capsrc_nids) that don't give all * active input pins */ static void alc_remove_invalid_adc_nids(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; const struct hda_input_mux *imux; hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)]; hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)]; int i, n, nums; |
a361d84bf [ALSA] hda-codec ... |
3539 |
|
1d045db96 ALSA: hda - Split... |
3540 3541 3542 3543 3544 |
imux = spec->input_mux; if (!imux) return; if (spec->dyn_adc_switch) return; |
a361d84bf [ALSA] hda-codec ... |
3545 |
|
1d045db96 ALSA: hda - Split... |
3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 |
nums = 0; for (n = 0; n < spec->num_adc_nids; n++) { hda_nid_t cap = spec->private_capsrc_nids[n]; int num_conns = snd_hda_get_conn_list(codec, cap, NULL); for (i = 0; i < imux->num_items; i++) { hda_nid_t pin = spec->imux_pins[i]; if (pin) { if (get_connection_index(codec, cap, pin) < 0) break; } else if (num_conns <= imux->items[i].index) break; } if (i >= imux->num_items) { adc_nids[nums] = spec->private_adc_nids[n]; capsrc_nids[nums++] = cap; |
22971e3a7 ALSA: hda - add d... |
3561 3562 |
} } |
1d045db96 ALSA: hda - Split... |
3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 |
if (!nums) { /* check whether ADC-switch is possible */ if (!alc_check_dyn_adc_switch(codec)) { printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" " using fallback 0x%x ", codec->chip_name, spec->private_adc_nids[0]); spec->num_adc_nids = 1; spec->auto_mic = 0; return; |
22971e3a7 ALSA: hda - add d... |
3573 |
} |
1d045db96 ALSA: hda - Split... |
3574 3575 3576 3577 3578 3579 |
} else if (nums != spec->num_adc_nids) { memcpy(spec->private_adc_nids, adc_nids, nums * sizeof(hda_nid_t)); memcpy(spec->private_capsrc_nids, capsrc_nids, nums * sizeof(hda_nid_t)); spec->num_adc_nids = nums; |
22971e3a7 ALSA: hda - add d... |
3580 |
} |
aef9d318b [ALSA] hda-codec ... |
3581 |
|
1d045db96 ALSA: hda - Split... |
3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 |
if (spec->auto_mic) alc_auto_mic_check_imux(codec); /* check auto-mic setups */ else if (spec->input_mux->num_items == 1) spec->num_adc_nids = 1; /* reduce to a single ADC */ } /* * initialize ADC paths */ static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx) { struct alc_spec *spec = codec->spec; hda_nid_t nid; nid = spec->adc_nids[adc_idx]; /* mute ADC */ |
44c024005 ALSA: hda - Fix a... |
3598 |
if (nid_has_mute(codec, nid, HDA_INPUT)) { |
1d045db96 ALSA: hda - Split... |
3599 3600 3601 3602 |
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)); return; |
a361d84bf [ALSA] hda-codec ... |
3603 |
} |
1d045db96 ALSA: hda - Split... |
3604 3605 3606 |
if (!spec->capsrc_nids) return; nid = spec->capsrc_nids[adc_idx]; |
44c024005 ALSA: hda - Fix a... |
3607 |
if (nid_has_mute(codec, nid, HDA_OUTPUT)) |
1d045db96 ALSA: hda - Split... |
3608 3609 3610 3611 |
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); } |
2134ea4f3 [ALSA] hda-codec ... |
3612 |
|
1d045db96 ALSA: hda - Split... |
3613 3614 3615 3616 |
static void alc_auto_init_input_src(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int c, nums; |
d6cc9fabd ALSA: hda - Parse... |
3617 |
|
1d045db96 ALSA: hda - Split... |
3618 3619 3620 3621 3622 3623 3624 3625 3626 |
for (c = 0; c < spec->num_adc_nids; c++) alc_auto_init_adc(codec, c); if (spec->dyn_adc_switch) nums = 1; else nums = spec->num_adc_nids; for (c = 0; c < nums; c++) alc_mux_select(codec, 0, spec->cur_mux[c], true); } |
2134ea4f3 [ALSA] hda-codec ... |
3627 |
|
1d045db96 ALSA: hda - Split... |
3628 3629 3630 3631 3632 3633 3634 3635 3636 |
/* add mic boosts if needed */ static int alc_auto_add_mic_boost(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; int i, err; int type_idx = 0; hda_nid_t nid; const char *prev_label = NULL; |
ea1fb29ac ALSA: hda - fix s... |
3637 |
|
1d045db96 ALSA: hda - Split... |
3638 3639 3640 3641 3642 3643 3644 3645 3646 |
for (i = 0; i < cfg->num_inputs; i++) { if (cfg->inputs[i].type > AUTO_PIN_MIC) break; nid = cfg->inputs[i].pin; if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { const char *label; char boost_label[32]; label = hda_get_autocfg_input_label(codec, cfg, i); |
24de183ed ALSA: hda/realtek... |
3647 3648 |
if (spec->shared_mic_hp && !strcmp(label, "Misc")) label = "Headphone Mic"; |
1d045db96 ALSA: hda - Split... |
3649 3650 3651 3652 3653 |
if (prev_label && !strcmp(label, prev_label)) type_idx++; else type_idx = 0; prev_label = label; |
bf1b02258 ALSA: hda - Add a... |
3654 |
|
1d045db96 ALSA: hda - Split... |
3655 3656 3657 3658 3659 3660 3661 3662 3663 |
snprintf(boost_label, sizeof(boost_label), "%s Boost Volume", label); err = add_control(spec, ALC_CTL_WIDGET_VOL, boost_label, type_idx, HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); if (err < 0) return err; } } |
a361d84bf [ALSA] hda-codec ... |
3664 3665 |
return 0; } |
1d045db96 ALSA: hda - Split... |
3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 |
/* select or unmute the given capsrc route */ static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, int idx) { if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, HDA_AMP_MUTE, 0); } else if (snd_hda_get_conn_list(codec, cap, NULL) > 1) { snd_hda_codec_write_cache(codec, cap, 0, AC_VERB_SET_CONNECT_SEL, idx); } } |
f6a92248a [ALSA] hda-codec ... |
3678 |
|
1d045db96 ALSA: hda - Split... |
3679 3680 3681 3682 3683 |
/* set the default connection to that pin */ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) { struct alc_spec *spec = codec->spec; int i; |
f6a92248a [ALSA] hda-codec ... |
3684 |
|
1d045db96 ALSA: hda - Split... |
3685 3686 3687 |
if (!pin) return 0; for (i = 0; i < spec->num_adc_nids; i++) { |
61071594f ALSA: hda/realtek... |
3688 |
hda_nid_t cap = get_capsrc(spec, i); |
1d045db96 ALSA: hda - Split... |
3689 |
int idx; |
f53281e62 ALSA: hda - Add s... |
3690 |
|
1d045db96 ALSA: hda - Split... |
3691 3692 3693 3694 3695 3696 3697 3698 |
idx = get_connection_index(codec, cap, pin); if (idx < 0) continue; select_or_unmute_capsrc(codec, cap, idx); return i; /* return the found index */ } return -1; /* not found */ } |
e01bf5091 ALSA: hda - Fix A... |
3699 |
|
1d045db96 ALSA: hda - Split... |
3700 3701 3702 3703 3704 |
/* initialize some special cases for input sources */ static void alc_init_special_input_src(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int i; |
84898e87c ALSA: hda - Add A... |
3705 |
|
1d045db96 ALSA: hda - Split... |
3706 3707 3708 |
for (i = 0; i < spec->autocfg.num_inputs; i++) init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin); } |
84898e87c ALSA: hda - Add A... |
3709 |
|
1d045db96 ALSA: hda - Split... |
3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 |
/* assign appropriate capture mixers */ static void set_capture_mixer(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; static const struct snd_kcontrol_new *caps[2][3] = { { alc_capture_mixer_nosrc1, alc_capture_mixer_nosrc2, alc_capture_mixer_nosrc3 }, { alc_capture_mixer1, alc_capture_mixer2, alc_capture_mixer3 }, }; |
f6a92248a [ALSA] hda-codec ... |
3722 |
|
1d045db96 ALSA: hda - Split... |
3723 |
/* check whether either of ADC or MUX has a volume control */ |
44c024005 ALSA: hda - Fix a... |
3724 |
if (!nid_has_volume(codec, spec->adc_nids[0], HDA_INPUT)) { |
1d045db96 ALSA: hda - Split... |
3725 3726 |
if (!spec->capsrc_nids) return; /* no volume */ |
44c024005 ALSA: hda - Fix a... |
3727 |
if (!nid_has_volume(codec, spec->capsrc_nids[0], HDA_OUTPUT)) |
1d045db96 ALSA: hda - Split... |
3728 3729 3730 |
return; /* no volume in capsrc, too */ spec->vol_in_capsrc = 1; } |
60db6b53f ALSA: hda - Add s... |
3731 |
|
1d045db96 ALSA: hda - Split... |
3732 3733 3734 |
if (spec->num_adc_nids > 0) { int mux = 0; int num_adcs = 0; |
64154835c ALSA: hda - Add l... |
3735 |
|
1d045db96 ALSA: hda - Split... |
3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 |
if (spec->input_mux && spec->input_mux->num_items > 1) mux = 1; if (spec->auto_mic) { num_adcs = 1; mux = 0; } else if (spec->dyn_adc_switch) num_adcs = 1; if (!num_adcs) { if (spec->num_adc_nids > 3) spec->num_adc_nids = 3; else if (!spec->num_adc_nids) return; num_adcs = spec->num_adc_nids; } spec->cap_mixer = caps[mux][num_adcs - 1]; } } |
f53281e62 ALSA: hda - Add s... |
3753 |
|
1d045db96 ALSA: hda - Split... |
3754 |
/* |
e47706295 ALSA: hda - Provi... |
3755 3756 3757 3758 3759 |
* standard auto-parser initializations */ static void alc_auto_init_std(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; |
3a93897ea ALSA: hda - Manag... |
3760 |
spec->use_jack_tbl = 1; |
e47706295 ALSA: hda - Provi... |
3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 |
alc_auto_init_multi_out(codec); alc_auto_init_extra_out(codec); alc_auto_init_analog_input(codec); alc_auto_init_input_src(codec); alc_auto_init_digital(codec); if (spec->unsol_event) alc_inithook(codec); } /* |
1d045db96 ALSA: hda - Split... |
3771 3772 3773 3774 3775 |
* Digital-beep handlers */ #ifdef CONFIG_SND_HDA_INPUT_BEEP #define set_beep_amp(spec, nid, idx, dir) \ ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) |
84898e87c ALSA: hda - Add A... |
3776 |
|
1d045db96 ALSA: hda - Split... |
3777 3778 3779 3780 3781 3782 3783 |
static const struct snd_pci_quirk beep_white_list[] = { SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), {} |
fe3eb0a73 ALSA: hda - Add s... |
3784 |
}; |
1d045db96 ALSA: hda - Split... |
3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 |
static inline int has_cdefine_beep(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; const struct snd_pci_quirk *q; q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); if (q) return q->value; return spec->cdefine.enable_pcbeep; } #else #define set_beep_amp(spec, nid, idx, dir) /* NOP */ #define has_cdefine_beep(codec) 0 #endif |
84898e87c ALSA: hda - Add A... |
3798 |
|
1d045db96 ALSA: hda - Split... |
3799 3800 3801 3802 |
/* parse the BIOS configuration and set up the alc_spec */ /* return 1 if successful, 0 if the proper config is not found, * or a negative error code */ |
3e6179b84 ALSA: hda - Merge... |
3803 3804 3805 |
static int alc_parse_auto_config(struct hda_codec *codec, const hda_nid_t *ignore_nids, const hda_nid_t *ssid_nids) |
1d045db96 ALSA: hda - Split... |
3806 3807 |
{ struct alc_spec *spec = codec->spec; |
23c09b009 ALSA: hda - Suppo... |
3808 |
struct auto_pin_cfg *cfg = &spec->autocfg; |
1d045db96 ALSA: hda - Split... |
3809 |
int err; |
26f5df265 ALSA: hda - Add A... |
3810 |
|
53c334add ALSA: hda - Rewri... |
3811 3812 |
err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids, spec->parse_flags); |
1d045db96 ALSA: hda - Split... |
3813 3814 |
if (err < 0) return err; |
23c09b009 ALSA: hda - Suppo... |
3815 3816 |
if (!cfg->line_outs) { if (cfg->dig_outs || cfg->dig_in_pin) { |
3e6179b84 ALSA: hda - Merge... |
3817 3818 3819 3820 |
spec->multiout.max_channels = 2; spec->no_analog = 1; goto dig_only; } |
1d045db96 ALSA: hda - Split... |
3821 |
return 0; /* can't find valid BIOS pin config */ |
3e6179b84 ALSA: hda - Merge... |
3822 |
} |
23c09b009 ALSA: hda - Suppo... |
3823 |
|
06503670a ALSA: hda/realtek... |
3824 3825 |
if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->line_outs <= cfg->hp_outs) { |
23c09b009 ALSA: hda - Suppo... |
3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 |
/* use HP as primary out */ cfg->speaker_outs = cfg->line_outs; memcpy(cfg->speaker_pins, cfg->line_out_pins, sizeof(cfg->speaker_pins)); cfg->line_outs = cfg->hp_outs; memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins)); cfg->hp_outs = 0; memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); cfg->line_out_type = AUTO_PIN_HP_OUT; } |
1d045db96 ALSA: hda - Split... |
3836 3837 3838 |
err = alc_auto_fill_dac_nids(codec); if (err < 0) return err; |
23c09b009 ALSA: hda - Suppo... |
3839 3840 3841 |
err = alc_auto_add_multi_channel_mode(codec); if (err < 0) return err; |
23c09b009 ALSA: hda - Suppo... |
3842 |
err = alc_auto_create_multi_out_ctls(codec, cfg); |
1d045db96 ALSA: hda - Split... |
3843 3844 3845 3846 3847 3848 3849 3850 |
if (err < 0) return err; err = alc_auto_create_hp_out(codec); if (err < 0) return err; err = alc_auto_create_speaker_out(codec); if (err < 0) return err; |
24de183ed ALSA: hda/realtek... |
3851 3852 3853 |
err = alc_auto_create_shared_input(codec); if (err < 0) return err; |
1d045db96 ALSA: hda - Split... |
3854 3855 3856 |
err = alc_auto_create_input_ctls(codec); if (err < 0) return err; |
84898e87c ALSA: hda - Add A... |
3857 |
|
1d045db96 ALSA: hda - Split... |
3858 |
spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
f53281e62 ALSA: hda - Add s... |
3859 |
|
3e6179b84 ALSA: hda - Merge... |
3860 |
dig_only: |
1d045db96 ALSA: hda - Split... |
3861 |
alc_auto_parse_digital(codec); |
f6a92248a [ALSA] hda-codec ... |
3862 |
|
3e6179b84 ALSA: hda - Merge... |
3863 3864 3865 3866 3867 |
if (!spec->no_analog) alc_remove_invalid_adc_nids(codec); if (ssid_nids) alc_ssid_check(codec, ssid_nids); |
64154835c ALSA: hda - Add l... |
3868 |
|
3e6179b84 ALSA: hda - Merge... |
3869 3870 3871 3872 3873 3874 |
if (!spec->no_analog) { alc_auto_check_switches(codec); err = alc_auto_add_mic_boost(codec); if (err < 0) return err; } |
f6a92248a [ALSA] hda-codec ... |
3875 |
|
3e6179b84 ALSA: hda - Merge... |
3876 3877 |
if (spec->kctls.list) add_mixer(spec, spec->kctls.list); |
f6a92248a [ALSA] hda-codec ... |
3878 |
|
1d045db96 ALSA: hda - Split... |
3879 |
return 1; |
60db6b53f ALSA: hda - Add s... |
3880 |
} |
f6a92248a [ALSA] hda-codec ... |
3881 |
|
3e6179b84 ALSA: hda - Merge... |
3882 3883 3884 3885 3886 3887 |
static int alc880_parse_auto_config(struct hda_codec *codec) { static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); } |
1d045db96 ALSA: hda - Split... |
3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 |
#ifdef CONFIG_SND_HDA_POWER_SAVE static const struct hda_amp_list alc880_loopbacks[] = { { 0x0b, HDA_INPUT, 0 }, { 0x0b, HDA_INPUT, 1 }, { 0x0b, HDA_INPUT, 2 }, { 0x0b, HDA_INPUT, 3 }, { 0x0b, HDA_INPUT, 4 }, { } /* end */ }; #endif |
f6a92248a [ALSA] hda-codec ... |
3898 |
|
1d045db96 ALSA: hda - Split... |
3899 |
/* |
ee3b29693 ALSA: hda/realtek... |
3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 |
* ALC880 fix-ups */ enum { ALC880_FIXUP_GPIO2, ALC880_FIXUP_MEDION_RIM, }; static const struct alc_fixup alc880_fixups[] = { [ALC880_FIXUP_GPIO2] = { .type = ALC_FIXUP_VERBS, .v.verbs = alc_gpio2_init_verbs, }, [ALC880_FIXUP_MEDION_RIM] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, { } }, .chained = true, .chain_id = ALC880_FIXUP_GPIO2, }, }; static const struct snd_pci_quirk alc880_fixup_tbl[] = { SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), {} }; /* |
1d045db96 ALSA: hda - Split... |
3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 |
* board setups */ #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS #define alc_board_config \ snd_hda_check_board_config #define alc_board_codec_sid_config \ snd_hda_check_board_codec_sid_config #include "alc_quirks.c" #else #define alc_board_config(codec, nums, models, tbl) -1 #define alc_board_codec_sid_config(codec, nums, models, tbl) -1 #define setup_preset(codec, x) /* NOP */ #endif |
64154835c ALSA: hda - Add l... |
3944 |
|
1d045db96 ALSA: hda - Split... |
3945 3946 3947 3948 3949 3950 |
/* * OK, here we have finally the patch for ALC880 */ #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS #include "alc880_quirks.c" #endif |
4f5d17062 ALSA: hda - Clean... |
3951 |
|
1d045db96 ALSA: hda - Split... |
3952 |
static int patch_alc880(struct hda_codec *codec) |
60db6b53f ALSA: hda - Add s... |
3953 |
{ |
1d045db96 ALSA: hda - Split... |
3954 3955 3956 |
struct alc_spec *spec; int board_config; int err; |
f6a92248a [ALSA] hda-codec ... |
3957 |
|
1d045db96 ALSA: hda - Split... |
3958 3959 3960 |
spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; |
3b8510ce9 ALSA: hda - Add c... |
3961 |
|
1d045db96 ALSA: hda - Split... |
3962 |
codec->spec = spec; |
64154835c ALSA: hda - Add l... |
3963 |
|
1d045db96 ALSA: hda - Split... |
3964 |
spec->mixer_nid = 0x0b; |
7b1655f5f ALSA: hda - Re-ad... |
3965 |
spec->need_dac_fix = 1; |
f53281e62 ALSA: hda - Add s... |
3966 |
|
1d045db96 ALSA: hda - Split... |
3967 3968 3969 3970 3971 3972 3973 3974 |
board_config = alc_board_config(codec, ALC880_MODEL_LAST, alc880_models, alc880_cfg_tbl); if (board_config < 0) { printk(KERN_INFO "hda_codec: %s: BIOS auto-probing. ", codec->chip_name); board_config = ALC_MODEL_AUTO; } |
f53281e62 ALSA: hda - Add s... |
3975 |
|
1d045db96 ALSA: hda - Split... |
3976 |
if (board_config == ALC_MODEL_AUTO) { |
ee3b29693 ALSA: hda/realtek... |
3977 3978 3979 3980 3981 |
alc_pick_fixup(codec, NULL, alc880_fixup_tbl, alc880_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); } if (board_config == ALC_MODEL_AUTO) { |
1d045db96 ALSA: hda - Split... |
3982 3983 |
/* automatic parse from the BIOS config */ err = alc880_parse_auto_config(codec); |
e16fb6d14 ALSA: hda/realtek... |
3984 3985 |
if (err < 0) goto error; |
1d045db96 ALSA: hda - Split... |
3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 |
#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using 3-stack mode... "); board_config = ALC880_3ST; } #endif } |
84898e87c ALSA: hda - Add A... |
3996 |
|
fde48a1f8 ALSA: HDA: Realte... |
3997 3998 |
if (board_config != ALC_MODEL_AUTO) { spec->vmaster_nid = 0x0c; |
1d045db96 ALSA: hda - Split... |
3999 |
setup_preset(codec, &alc880_presets[board_config]); |
fde48a1f8 ALSA: HDA: Realte... |
4000 |
} |
fe3eb0a73 ALSA: hda - Add s... |
4001 |
|
60a6a8425 ALSA: hda - Fix O... |
4002 |
if (!spec->no_analog && !spec->adc_nids) { |
1d045db96 ALSA: hda - Split... |
4003 4004 4005 4006 |
alc_auto_fill_adc_caps(codec); alc_rebuild_imux_for_auto_mic(codec); alc_remove_invalid_adc_nids(codec); } |
3e6179b84 ALSA: hda - Merge... |
4007 4008 4009 4010 4011 4012 |
if (!spec->no_analog && !spec->cap_mixer) set_capture_mixer(codec); if (!spec->no_analog) { err = snd_hda_attach_beep_device(codec, 0x1); |
e16fb6d14 ALSA: hda/realtek... |
4013 4014 |
if (err < 0) goto error; |
3e6179b84 ALSA: hda - Merge... |
4015 4016 |
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); } |
f53281e62 ALSA: hda - Add s... |
4017 |
|
ee3b29693 ALSA: hda/realtek... |
4018 |
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
1d045db96 ALSA: hda - Split... |
4019 4020 |
codec->patch_ops = alc_patch_ops; if (board_config == ALC_MODEL_AUTO) |
e47706295 ALSA: hda - Provi... |
4021 |
spec->init_hook = alc_auto_init_std; |
1d045db96 ALSA: hda - Split... |
4022 4023 4024 4025 |
#ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc880_loopbacks; #endif |
f53281e62 ALSA: hda - Add s... |
4026 |
|
1d045db96 ALSA: hda - Split... |
4027 |
return 0; |
e16fb6d14 ALSA: hda/realtek... |
4028 4029 4030 4031 |
error: alc_free(codec); return err; |
226b1ec8c ALSA: hda - Fix s... |
4032 |
} |
1d045db96 ALSA: hda - Split... |
4033 |
|
60db6b53f ALSA: hda - Add s... |
4034 |
/* |
1d045db96 ALSA: hda - Split... |
4035 |
* ALC260 support |
60db6b53f ALSA: hda - Add s... |
4036 |
*/ |
1d045db96 ALSA: hda - Split... |
4037 |
static int alc260_parse_auto_config(struct hda_codec *codec) |
f6a92248a [ALSA] hda-codec ... |
4038 |
{ |
1d045db96 ALSA: hda - Split... |
4039 |
static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; |
3e6179b84 ALSA: hda - Merge... |
4040 4041 |
static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 }; return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); |
f6a92248a [ALSA] hda-codec ... |
4042 |
} |
1d045db96 ALSA: hda - Split... |
4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 |
#ifdef CONFIG_SND_HDA_POWER_SAVE static const struct hda_amp_list alc260_loopbacks[] = { { 0x07, HDA_INPUT, 0 }, { 0x07, HDA_INPUT, 1 }, { 0x07, HDA_INPUT, 2 }, { 0x07, HDA_INPUT, 3 }, { 0x07, HDA_INPUT, 4 }, { } /* end */ }; #endif |
0ec33d1f9 ALSA: hda - Refac... |
4053 |
|
1d045db96 ALSA: hda - Split... |
4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 |
/* * Pin config fixes */ enum { PINFIX_HP_DC5750, }; static const struct alc_fixup alc260_fixups[] = { [PINFIX_HP_DC5750] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x11, 0x90130110 }, /* speaker */ { } } }, }; static const struct snd_pci_quirk alc260_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), {} }; /* */ #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS #include "alc260_quirks.c" #endif static int patch_alc260(struct hda_codec *codec) |
977ddd6b2 ALSA: hda - Set u... |
4083 |
{ |
1d045db96 ALSA: hda - Split... |
4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 |
struct alc_spec *spec; int err, board_config; spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; codec->spec = spec; spec->mixer_nid = 0x07; board_config = alc_board_config(codec, ALC260_MODEL_LAST, alc260_models, alc260_cfg_tbl); if (board_config < 0) { snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing. ", codec->chip_name); board_config = ALC_MODEL_AUTO; |
977ddd6b2 ALSA: hda - Set u... |
4102 |
} |
0ec33d1f9 ALSA: hda - Refac... |
4103 |
|
1d045db96 ALSA: hda - Split... |
4104 4105 4106 |
if (board_config == ALC_MODEL_AUTO) { alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
977ddd6b2 ALSA: hda - Set u... |
4107 |
} |
1d045db96 ALSA: hda - Split... |
4108 4109 4110 |
if (board_config == ALC_MODEL_AUTO) { /* automatic parse from the BIOS config */ err = alc260_parse_auto_config(codec); |
e16fb6d14 ALSA: hda/realtek... |
4111 4112 |
if (err < 0) goto error; |
1d045db96 ALSA: hda - Split... |
4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 |
#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode... "); board_config = ALC260_BASIC; } #endif } |
977ddd6b2 ALSA: hda - Set u... |
4123 |
|
fde48a1f8 ALSA: HDA: Realte... |
4124 |
if (board_config != ALC_MODEL_AUTO) { |
1d045db96 ALSA: hda - Split... |
4125 |
setup_preset(codec, &alc260_presets[board_config]); |
fde48a1f8 ALSA: HDA: Realte... |
4126 4127 |
spec->vmaster_nid = 0x08; } |
977ddd6b2 ALSA: hda - Set u... |
4128 |
|
60a6a8425 ALSA: hda - Fix O... |
4129 |
if (!spec->no_analog && !spec->adc_nids) { |
1d045db96 ALSA: hda - Split... |
4130 4131 4132 4133 |
alc_auto_fill_adc_caps(codec); alc_rebuild_imux_for_auto_mic(codec); alc_remove_invalid_adc_nids(codec); } |
3e6179b84 ALSA: hda - Merge... |
4134 4135 4136 4137 4138 4139 |
if (!spec->no_analog && !spec->cap_mixer) set_capture_mixer(codec); if (!spec->no_analog) { err = snd_hda_attach_beep_device(codec, 0x1); |
e16fb6d14 ALSA: hda/realtek... |
4140 4141 |
if (err < 0) goto error; |
3e6179b84 ALSA: hda - Merge... |
4142 4143 |
set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); } |
977ddd6b2 ALSA: hda - Set u... |
4144 |
|
1d045db96 ALSA: hda - Split... |
4145 |
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
1a99d4a46 ALSA: hda - Fix A... |
4146 |
|
1d045db96 ALSA: hda - Split... |
4147 4148 |
codec->patch_ops = alc_patch_ops; if (board_config == ALC_MODEL_AUTO) |
8452a982f ALSA: hda - Merge... |
4149 |
spec->init_hook = alc_auto_init_std; |
1d045db96 ALSA: hda - Split... |
4150 4151 4152 4153 4154 |
spec->shutup = alc_eapd_shutup; #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc260_loopbacks; #endif |
6981d1843 ALSA: hda - Add a... |
4155 |
|
1d045db96 ALSA: hda - Split... |
4156 |
return 0; |
e16fb6d14 ALSA: hda/realtek... |
4157 4158 4159 4160 |
error: alc_free(codec); return err; |
6981d1843 ALSA: hda - Add a... |
4161 |
} |
1d045db96 ALSA: hda - Split... |
4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 |
/* * ALC882/883/885/888/889 support * * ALC882 is almost identical with ALC880 but has cleaner and more flexible * configuration. Each pin widget can choose any input DACs and a mixer. * Each ADC is connected from a mixer of all inputs. This makes possible * 6-channel independent captures. * * In addition, an independent DAC for the multi-playback (not used in this * driver yet). */ #ifdef CONFIG_SND_HDA_POWER_SAVE #define alc882_loopbacks alc880_loopbacks #endif /* * Pin config fixes */ |
ff818c24c ALSA: hda - Add f... |
4181 |
enum { |
5c0ebfbe5 ALSA: hda/realtek... |
4182 4183 4184 4185 4186 4187 |
ALC882_FIXUP_ABIT_AW9D_MAX, ALC882_FIXUP_LENOVO_Y530, ALC882_FIXUP_PB_M5210, ALC882_FIXUP_ACER_ASPIRE_7736, ALC882_FIXUP_ASUS_W90V, ALC889_FIXUP_VAIO_TT, |
0e7cc2e74 ALSA: hda/realtek... |
4188 |
ALC888_FIXUP_EEE1601, |
177943a39 ALSA: hda/realtek... |
4189 |
ALC882_FIXUP_EAPD, |
7a6069bf6 ALSA: hda/realtek... |
4190 |
ALC883_FIXUP_EAPD, |
8812c4f96 ALSA: hda/realtek... |
4191 |
ALC883_FIXUP_ACER_EAPD, |
eb844d51c ALSA: hda/realtek... |
4192 |
ALC882_FIXUP_GPIO3, |
68ef0561e ALSA: hda/realtek... |
4193 4194 |
ALC889_FIXUP_COEF, ALC882_FIXUP_ASUS_W2JC, |
c3e837bbc ALSA: hda/realtek... |
4195 4196 4197 |
ALC882_FIXUP_ACER_ASPIRE_4930G, ALC882_FIXUP_ACER_ASPIRE_8930G, ALC882_FIXUP_ASPIRE_8930G_VERBS, |
5671087ff ALSA: hda/realtek... |
4198 |
ALC885_FIXUP_MACPRO_GPIO, |
ff818c24c ALSA: hda - Add f... |
4199 |
}; |
68ef0561e ALSA: hda/realtek... |
4200 4201 4202 4203 4204 4205 4206 |
static void alc889_fixup_coef(struct hda_codec *codec, const struct alc_fixup *fix, int action) { if (action != ALC_FIXUP_ACT_INIT) return; alc889_coef_init(codec); } |
5671087ff ALSA: hda/realtek... |
4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 |
/* toggle speaker-output according to the hp-jack state */ static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) { unsigned int gpiostate, gpiomask, gpiodir; gpiostate = snd_hda_codec_read(codec, codec->afg, 0, AC_VERB_GET_GPIO_DATA, 0); if (!muted) gpiostate |= (1 << pin); else gpiostate &= ~(1 << pin); gpiomask = snd_hda_codec_read(codec, codec->afg, 0, AC_VERB_GET_GPIO_MASK, 0); gpiomask |= (1 << pin); gpiodir = snd_hda_codec_read(codec, codec->afg, 0, AC_VERB_GET_GPIO_DIRECTION, 0); gpiodir |= (1 << pin); snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_SET_GPIO_MASK, gpiomask); snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_SET_GPIO_DIRECTION, gpiodir); msleep(1); snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_SET_GPIO_DATA, gpiostate); } /* set up GPIO at initialization */ static void alc885_fixup_macpro_gpio(struct hda_codec *codec, const struct alc_fixup *fix, int action) { if (action != ALC_FIXUP_ACT_INIT) return; alc882_gpio_mute(codec, 0, 0); alc882_gpio_mute(codec, 1, 0); } |
1d045db96 ALSA: hda - Split... |
4249 |
static const struct alc_fixup alc882_fixups[] = { |
5c0ebfbe5 ALSA: hda/realtek... |
4250 |
[ALC882_FIXUP_ABIT_AW9D_MAX] = { |
1d045db96 ALSA: hda - Split... |
4251 4252 4253 4254 4255 |
.type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x15, 0x01080104 }, /* side */ { 0x16, 0x01011012 }, /* rear */ { 0x17, 0x01016011 }, /* clfe */ |
2785591a9 ALSA: hda - Add f... |
4256 |
{ } |
145a902bf ALSA: HDA: Enable... |
4257 4258 |
} }, |
5c0ebfbe5 ALSA: hda/realtek... |
4259 |
[ALC882_FIXUP_LENOVO_Y530] = { |
b5bfbc670 ALSA: hda - Reorg... |
4260 4261 |
.type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { |
1d045db96 ALSA: hda - Split... |
4262 4263 |
{ 0x15, 0x99130112 }, /* rear int speakers */ { 0x16, 0x99130111 }, /* subwoofer */ |
ac6124079 ALSA: HDA: Enable... |
4264 4265 4266 |
{ } } }, |
5c0ebfbe5 ALSA: hda/realtek... |
4267 |
[ALC882_FIXUP_PB_M5210] = { |
b5bfbc670 ALSA: hda - Reorg... |
4268 4269 |
.type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { |
1d045db96 ALSA: hda - Split... |
4270 |
{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, |
357f915ec ALSA: hda - Fix E... |
4271 4272 4273 |
{} } }, |
5c0ebfbe5 ALSA: hda/realtek... |
4274 |
[ALC882_FIXUP_ACER_ASPIRE_7736] = { |
1d045db96 ALSA: hda - Split... |
4275 4276 |
.type = ALC_FIXUP_SKU, .v.sku = ALC_FIXUP_SKU_IGNORE, |
6981d1843 ALSA: hda - Add a... |
4277 |
}, |
5c0ebfbe5 ALSA: hda/realtek... |
4278 |
[ALC882_FIXUP_ASUS_W90V] = { |
5cdf745eb ALSA: hda - Fix p... |
4279 4280 4281 4282 4283 4284 |
.type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x16, 0x99130110 }, /* fix sequence for CLFE */ { } } }, |
5c0ebfbe5 ALSA: hda/realtek... |
4285 4286 4287 4288 4289 4290 4291 |
[ALC889_FIXUP_VAIO_TT] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x17, 0x90170111 }, /* hidden surround speaker */ { } } }, |
0e7cc2e74 ALSA: hda/realtek... |
4292 4293 4294 4295 4296 4297 4298 |
[ALC888_FIXUP_EEE1601] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, { } } |
177943a39 ALSA: hda/realtek... |
4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 |
}, [ALC882_FIXUP_EAPD] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { /* change to EAPD mode */ { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, { } } }, |
7a6069bf6 ALSA: hda/realtek... |
4309 4310 4311 4312 4313 4314 4315 4316 4317 |
[ALC883_FIXUP_EAPD] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { /* change to EAPD mode */ { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, { } } }, |
8812c4f96 ALSA: hda/realtek... |
4318 4319 4320 4321 4322 4323 4324 4325 4326 |
[ALC883_FIXUP_ACER_EAPD] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { /* eanable EAPD on Acer laptops */ { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, { } } }, |
eb844d51c ALSA: hda/realtek... |
4327 4328 4329 4330 |
[ALC882_FIXUP_GPIO3] = { .type = ALC_FIXUP_VERBS, .v.verbs = alc_gpio3_init_verbs, }, |
68ef0561e ALSA: hda/realtek... |
4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 |
[ALC882_FIXUP_ASUS_W2JC] = { .type = ALC_FIXUP_VERBS, .v.verbs = alc_gpio1_init_verbs, .chained = true, .chain_id = ALC882_FIXUP_EAPD, }, [ALC889_FIXUP_COEF] = { .type = ALC_FIXUP_FUNC, .v.func = alc889_fixup_coef, }, |
c3e837bbc ALSA: hda/realtek... |
4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 |
[ALC882_FIXUP_ACER_ASPIRE_4930G] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x16, 0x99130111 }, /* CLFE speaker */ { 0x17, 0x99130112 }, /* surround speaker */ { } } }, [ALC882_FIXUP_ACER_ASPIRE_8930G] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x16, 0x99130111 }, /* CLFE speaker */ { 0x1b, 0x99130112 }, /* surround speaker */ { } }, .chained = true, .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS, }, [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { /* additional init verbs for Acer Aspire 8930G */ .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { /* Enable all DACs */ /* DAC DISABLE/MUTE 1? */ /* setting bits 1-5 disables DAC nids 0x02-0x06 * apparently. Init=0x38 */ { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, /* DAC DISABLE/MUTE 2? */ /* some bit here disables the other DACs. * Init=0x4900 */ { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, /* DMIC fix * This laptop has a stereo digital microphone. * The mics are only 1cm apart which makes the stereo * useless. However, either the mic or the ALC889 * makes the signal become a difference/sum signal * instead of standard stereo, which is annoying. * So instead we flip this bit which makes the * codec replicate the sum signal to both channels, * turning it into a normal mono mic. */ /* DMIC_CONTROL? Init value = 0x0001 */ { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, { } } }, |
5671087ff ALSA: hda/realtek... |
4392 4393 4394 4395 |
[ALC885_FIXUP_MACPRO_GPIO] = { .type = ALC_FIXUP_FUNC, .v.func = alc885_fixup_macpro_gpio, }, |
ff818c24c ALSA: hda - Add f... |
4396 |
}; |
1d045db96 ALSA: hda - Split... |
4397 |
static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
8812c4f96 ALSA: hda/realtek... |
4398 4399 4400 4401 4402 4403 |
SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD), |
c3e837bbc ALSA: hda/realtek... |
4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 |
SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", ALC882_FIXUP_ACER_ASPIRE_8930G), SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", ALC882_FIXUP_ACER_ASPIRE_8930G), SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", ALC882_FIXUP_ACER_ASPIRE_4930G), |
5c0ebfbe5 ALSA: hda/realtek... |
4418 |
SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), |
ac9b1cddf ALSA: hda/realtek... |
4419 |
SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), |
177943a39 ALSA: hda/realtek... |
4420 |
SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), |
5c0ebfbe5 ALSA: hda/realtek... |
4421 |
SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), |
68ef0561e ALSA: hda/realtek... |
4422 |
SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), |
0e7cc2e74 ALSA: hda/realtek... |
4423 |
SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), |
ac9b1cddf ALSA: hda/realtek... |
4424 |
SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), |
5671087ff ALSA: hda/realtek... |
4425 4426 4427 4428 4429 4430 4431 |
/* All Apple entries are in codec SSIDs */ SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), |
7a6069bf6 ALSA: hda/realtek... |
4432 |
SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), |
eb844d51c ALSA: hda/realtek... |
4433 |
SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), |
5c0ebfbe5 ALSA: hda/realtek... |
4434 |
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), |
7a6069bf6 ALSA: hda/realtek... |
4435 4436 |
SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), |
ac9b1cddf ALSA: hda/realtek... |
4437 |
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), |
68ef0561e ALSA: hda/realtek... |
4438 |
SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF), |
ff818c24c ALSA: hda - Add f... |
4439 4440 |
{} }; |
f6a92248a [ALSA] hda-codec ... |
4441 |
/* |
1d045db96 ALSA: hda - Split... |
4442 |
* BIOS auto configuration |
f6a92248a [ALSA] hda-codec ... |
4443 |
*/ |
1d045db96 ALSA: hda - Split... |
4444 4445 4446 |
/* almost identical with ALC880 parser... */ static int alc882_parse_auto_config(struct hda_codec *codec) { |
1d045db96 ALSA: hda - Split... |
4447 |
static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; |
3e6179b84 ALSA: hda - Merge... |
4448 4449 |
static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 }; return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids); |
1d045db96 ALSA: hda - Split... |
4450 |
} |
b896b4ebf ALSA: hda - Fix n... |
4451 |
|
1d045db96 ALSA: hda - Split... |
4452 4453 4454 4455 4456 4457 4458 |
/* */ #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS #include "alc882_quirks.c" #endif static int patch_alc882(struct hda_codec *codec) |
f6a92248a [ALSA] hda-codec ... |
4459 4460 |
{ struct alc_spec *spec; |
1d045db96 ALSA: hda - Split... |
4461 |
int err, board_config; |
f6a92248a [ALSA] hda-codec ... |
4462 4463 4464 4465 4466 4467 |
spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; codec->spec = spec; |
1f0f4b803 ALSA: hda - Reduc... |
4468 |
spec->mixer_nid = 0x0b; |
1d045db96 ALSA: hda - Split... |
4469 4470 4471 4472 4473 4474 4475 4476 |
switch (codec->vendor_id) { case 0x10ec0882: case 0x10ec0885: break; default: /* ALC883 and variants */ alc_fix_pll_init(codec, 0x20, 0x0a, 10); break; |
c793bec55 ALSA: hda - Don't... |
4477 |
} |
977ddd6b2 ALSA: hda - Set u... |
4478 |
|
e16fb6d14 ALSA: hda/realtek... |
4479 4480 4481 |
err = alc_codec_rename_from_preset(codec); if (err < 0) goto error; |
b25396994 ALSA: hda/realtek... |
4482 4483 4484 4485 |
board_config = alc_board_config(codec, ALC882_MODEL_LAST, alc882_models, NULL); if (board_config < 0) board_config = alc_board_codec_sid_config(codec, |
1d045db96 ALSA: hda - Split... |
4486 |
ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); |
f6a92248a [ALSA] hda-codec ... |
4487 4488 |
if (board_config < 0) { |
9a11f1aa8 ALSA: hda - Rewor... |
4489 4490 4491 |
printk(KERN_INFO "hda_codec: %s: BIOS auto-probing. ", codec->chip_name); |
1d045db96 ALSA: hda - Split... |
4492 |
board_config = ALC_MODEL_AUTO; |
f6a92248a [ALSA] hda-codec ... |
4493 |
} |
1d045db96 ALSA: hda - Split... |
4494 4495 |
if (board_config == ALC_MODEL_AUTO) { alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); |
b5bfbc670 ALSA: hda - Reorg... |
4496 4497 |
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); } |
ff818c24c ALSA: hda - Add f... |
4498 |
|
1d045db96 ALSA: hda - Split... |
4499 4500 4501 |
alc_auto_parse_customize_define(codec); if (board_config == ALC_MODEL_AUTO) { |
f6a92248a [ALSA] hda-codec ... |
4502 |
/* automatic parse from the BIOS config */ |
1d045db96 ALSA: hda - Split... |
4503 |
err = alc882_parse_auto_config(codec); |
e16fb6d14 ALSA: hda/realtek... |
4504 4505 |
if (err < 0) goto error; |
f6a92248a [ALSA] hda-codec ... |
4506 |
} |
fde48a1f8 ALSA: HDA: Realte... |
4507 |
if (board_config != ALC_MODEL_AUTO) { |
1d045db96 ALSA: hda - Split... |
4508 |
setup_preset(codec, &alc882_presets[board_config]); |
fde48a1f8 ALSA: HDA: Realte... |
4509 4510 |
spec->vmaster_nid = 0x0c; } |
f6a92248a [ALSA] hda-codec ... |
4511 |
|
60a6a8425 ALSA: hda - Fix O... |
4512 |
if (!spec->no_analog && !spec->adc_nids) { |
d6cc9fabd ALSA: hda - Parse... |
4513 |
alc_auto_fill_adc_caps(codec); |
21268961d ALSA: hda - More ... |
4514 |
alc_rebuild_imux_for_auto_mic(codec); |
d6cc9fabd ALSA: hda - Parse... |
4515 |
alc_remove_invalid_adc_nids(codec); |
84898e87c ALSA: hda - Add A... |
4516 |
} |
3e6179b84 ALSA: hda - Merge... |
4517 4518 |
if (!spec->no_analog && !spec->cap_mixer) set_capture_mixer(codec); |
1d045db96 ALSA: hda - Split... |
4519 |
|
3e6179b84 ALSA: hda - Merge... |
4520 4521 |
if (!spec->no_analog && has_cdefine_beep(codec)) { err = snd_hda_attach_beep_device(codec, 0x1); |
e16fb6d14 ALSA: hda/realtek... |
4522 4523 |
if (err < 0) goto error; |
1d045db96 ALSA: hda - Split... |
4524 |
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
3e6179b84 ALSA: hda - Merge... |
4525 |
} |
f6a92248a [ALSA] hda-codec ... |
4526 |
|
b5bfbc670 ALSA: hda - Reorg... |
4527 |
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
ff818c24c ALSA: hda - Add f... |
4528 |
|
f6a92248a [ALSA] hda-codec ... |
4529 |
codec->patch_ops = alc_patch_ops; |
1d045db96 ALSA: hda - Split... |
4530 |
if (board_config == ALC_MODEL_AUTO) |
e47706295 ALSA: hda - Provi... |
4531 |
spec->init_hook = alc_auto_init_std; |
bf1b02258 ALSA: hda - Add a... |
4532 |
|
f6a92248a [ALSA] hda-codec ... |
4533 4534 |
#ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) |
1d045db96 ALSA: hda - Split... |
4535 |
spec->loopback.amplist = alc882_loopbacks; |
f6a92248a [ALSA] hda-codec ... |
4536 4537 4538 |
#endif return 0; |
e16fb6d14 ALSA: hda/realtek... |
4539 4540 4541 4542 |
error: alc_free(codec); return err; |
f6a92248a [ALSA] hda-codec ... |
4543 |
} |
df694daa3 [ALSA] hda-codec ... |
4544 |
|
df694daa3 [ALSA] hda-codec ... |
4545 |
/* |
1d045db96 ALSA: hda - Split... |
4546 |
* ALC262 support |
df694daa3 [ALSA] hda-codec ... |
4547 |
*/ |
1d045db96 ALSA: hda - Split... |
4548 |
static int alc262_parse_auto_config(struct hda_codec *codec) |
df694daa3 [ALSA] hda-codec ... |
4549 |
{ |
1d045db96 ALSA: hda - Split... |
4550 |
static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; |
3e6179b84 ALSA: hda - Merge... |
4551 4552 |
static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 }; return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids); |
df694daa3 [ALSA] hda-codec ... |
4553 |
} |
df694daa3 [ALSA] hda-codec ... |
4554 |
/* |
1d045db96 ALSA: hda - Split... |
4555 |
* Pin config fixes |
df694daa3 [ALSA] hda-codec ... |
4556 |
*/ |
cfc9b06f0 ALSA: hda - Add a... |
4557 |
enum { |
ea4e7af12 ALSA: hda/realtek... |
4558 4559 4560 |
ALC262_FIXUP_FSC_H270, ALC262_FIXUP_HP_Z200, ALC262_FIXUP_TYAN, |
12837c983 ALSA: hda/realtek... |
4561 |
ALC262_FIXUP_TOSHIBA_RX1, |
c470150c5 ALSA: hda/realtek... |
4562 |
ALC262_FIXUP_LENOVO_3000, |
b42590b86 ALSA: hda/realtek... |
4563 4564 |
ALC262_FIXUP_BENQ, ALC262_FIXUP_BENQ_T31, |
cfc9b06f0 ALSA: hda - Add a... |
4565 |
}; |
1d045db96 ALSA: hda - Split... |
4566 |
static const struct alc_fixup alc262_fixups[] = { |
ea4e7af12 ALSA: hda/realtek... |
4567 |
[ALC262_FIXUP_FSC_H270] = { |
b5bfbc670 ALSA: hda - Reorg... |
4568 4569 |
.type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { |
1d045db96 ALSA: hda - Split... |
4570 4571 4572 4573 4574 4575 |
{ 0x14, 0x99130110 }, /* speaker */ { 0x15, 0x0221142f }, /* front HP */ { 0x1b, 0x0121141f }, /* rear HP */ { } } }, |
ea4e7af12 ALSA: hda/realtek... |
4576 |
[ALC262_FIXUP_HP_Z200] = { |
1d045db96 ALSA: hda - Split... |
4577 4578 4579 |
.type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x16, 0x99130120 }, /* internal speaker */ |
73413b120 ALSA: hda - embed... |
4580 4581 |
{ } } |
cfc9b06f0 ALSA: hda - Add a... |
4582 |
}, |
ea4e7af12 ALSA: hda/realtek... |
4583 4584 4585 4586 4587 4588 4589 |
[ALC262_FIXUP_TYAN] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x1993e1f0 }, /* int AUX */ { } } }, |
12837c983 ALSA: hda/realtek... |
4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 |
[ALC262_FIXUP_TOSHIBA_RX1] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x90170110 }, /* speaker */ { 0x15, 0x0421101f }, /* HP */ { 0x1a, 0x40f000f0 }, /* N/A */ { 0x1b, 0x40f000f0 }, /* N/A */ { 0x1e, 0x40f000f0 }, /* N/A */ } }, |
c470150c5 ALSA: hda/realtek... |
4600 4601 4602 4603 |
[ALC262_FIXUP_LENOVO_3000] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, |
b42590b86 ALSA: hda/realtek... |
4604 4605 4606 4607 4608 4609 4610 4611 |
{} }, .chained = true, .chain_id = ALC262_FIXUP_BENQ, }, [ALC262_FIXUP_BENQ] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { |
c470150c5 ALSA: hda/realtek... |
4612 4613 4614 4615 4616 |
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, {} } }, |
b42590b86 ALSA: hda/realtek... |
4617 4618 4619 4620 4621 4622 4623 4624 |
[ALC262_FIXUP_BENQ_T31] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, {} } }, |
cfc9b06f0 ALSA: hda - Add a... |
4625 |
}; |
1d045db96 ALSA: hda - Split... |
4626 |
static const struct snd_pci_quirk alc262_fixup_tbl[] = { |
ea4e7af12 ALSA: hda/realtek... |
4627 |
SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), |
3dcd3be33 ALSA: hda/realtek... |
4628 4629 |
SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), |
ea4e7af12 ALSA: hda/realtek... |
4630 |
SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), |
12837c983 ALSA: hda/realtek... |
4631 4632 |
SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", ALC262_FIXUP_TOSHIBA_RX1), |
ea4e7af12 ALSA: hda/realtek... |
4633 |
SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), |
c470150c5 ALSA: hda/realtek... |
4634 |
SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), |
b42590b86 ALSA: hda/realtek... |
4635 4636 |
SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), |
cfc9b06f0 ALSA: hda - Add a... |
4637 4638 |
{} }; |
df694daa3 [ALSA] hda-codec ... |
4639 |
|
1d045db96 ALSA: hda - Split... |
4640 4641 4642 4643 |
#ifdef CONFIG_SND_HDA_POWER_SAVE #define alc262_loopbacks alc880_loopbacks #endif |
1d045db96 ALSA: hda - Split... |
4644 4645 |
/* */ |
1d045db96 ALSA: hda - Split... |
4646 |
static int patch_alc262(struct hda_codec *codec) |
df694daa3 [ALSA] hda-codec ... |
4647 4648 |
{ struct alc_spec *spec; |
df694daa3 [ALSA] hda-codec ... |
4649 |
int err; |
dc041e0b1 [ALSA] sound: Cha... |
4650 |
spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
df694daa3 [ALSA] hda-codec ... |
4651 4652 |
if (spec == NULL) return -ENOMEM; |
f12ab1e07 [ALSA] hda-codec ... |
4653 |
codec->spec = spec; |
df694daa3 [ALSA] hda-codec ... |
4654 |
|
1d045db96 ALSA: hda - Split... |
4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 |
spec->mixer_nid = 0x0b; #if 0 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is * under-run */ { int tmp; snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); } #endif alc_auto_parse_customize_define(codec); |
1f0f4b803 ALSA: hda - Reduc... |
4670 |
|
1d045db96 ALSA: hda - Split... |
4671 |
alc_fix_pll_init(codec, 0x20, 0x0a, 10); |
42399f7a7 ALSA: hda/realtek... |
4672 4673 |
alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
9c7f852e8 [ALSA] Fix/add su... |
4674 |
|
42399f7a7 ALSA: hda/realtek... |
4675 4676 4677 4678 |
/* automatic parse from the BIOS config */ err = alc262_parse_auto_config(codec); if (err < 0) goto error; |
df694daa3 [ALSA] hda-codec ... |
4679 |
|
60a6a8425 ALSA: hda - Fix O... |
4680 |
if (!spec->no_analog && !spec->adc_nids) { |
21268961d ALSA: hda - More ... |
4681 4682 4683 4684 |
alc_auto_fill_adc_caps(codec); alc_rebuild_imux_for_auto_mic(codec); alc_remove_invalid_adc_nids(codec); } |
3e6179b84 ALSA: hda - Merge... |
4685 4686 |
if (!spec->no_analog && !spec->cap_mixer) |
c7a8eb103 ALSA: hda - Fix m... |
4687 |
set_capture_mixer(codec); |
3e6179b84 ALSA: hda - Merge... |
4688 4689 4690 |
if (!spec->no_analog && has_cdefine_beep(codec)) { err = snd_hda_attach_beep_device(codec, 0x1); |
e16fb6d14 ALSA: hda/realtek... |
4691 4692 |
if (err < 0) goto error; |
1d045db96 ALSA: hda - Split... |
4693 |
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
3e6179b84 ALSA: hda - Merge... |
4694 |
} |
2134ea4f3 [ALSA] hda-codec ... |
4695 |
|
b5bfbc670 ALSA: hda - Reorg... |
4696 |
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
7fa90e873 ALSA: hda - Enhan... |
4697 |
|
df694daa3 [ALSA] hda-codec ... |
4698 |
codec->patch_ops = alc_patch_ops; |
42399f7a7 ALSA: hda/realtek... |
4699 |
spec->init_hook = alc_auto_init_std; |
1d045db96 ALSA: hda - Split... |
4700 |
spec->shutup = alc_eapd_shutup; |
c97259df3 ALSA: hda: Refact... |
4701 |
#ifdef CONFIG_SND_HDA_POWER_SAVE |
cb53c626e [ALSA] hda-intel ... |
4702 |
if (!spec->loopback.amplist) |
1d045db96 ALSA: hda - Split... |
4703 |
spec->loopback.amplist = alc262_loopbacks; |
cb53c626e [ALSA] hda-intel ... |
4704 |
#endif |
ea1fb29ac ALSA: hda - fix s... |
4705 |
|
1da177e4c Linux-2.6.12-rc2 |
4706 |
return 0; |
e16fb6d14 ALSA: hda/realtek... |
4707 4708 4709 4710 |
error: alc_free(codec); return err; |
1da177e4c Linux-2.6.12-rc2 |
4711 4712 4713 |
} /* |
1d045db96 ALSA: hda - Split... |
4714 |
* ALC268 |
f32610eda [ALSA] hda-codec ... |
4715 |
*/ |
1d045db96 ALSA: hda - Split... |
4716 4717 4718 4719 4720 4721 4722 4723 |
/* bind Beep switches of both NID 0x0f and 0x10 */ static const struct hda_bind_ctls alc268_bind_beep_sw = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 0 }, |
f32610eda [ALSA] hda-codec ... |
4724 |
}; |
1d045db96 ALSA: hda - Split... |
4725 4726 4727 4728 |
static const struct snd_kcontrol_new alc268_beep_mixer[] = { HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), { } |
f32610eda [ALSA] hda-codec ... |
4729 |
}; |
1d045db96 ALSA: hda - Split... |
4730 4731 4732 4733 4734 4735 |
/* set PCBEEP vol = 0, mute connections */ static const struct hda_verb alc268_beep_init_verbs[] = { {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, { } |
f32610eda [ALSA] hda-codec ... |
4736 4737 4738 4739 4740 |
}; /* * BIOS auto configuration */ |
1d045db96 ALSA: hda - Split... |
4741 |
static int alc268_parse_auto_config(struct hda_codec *codec) |
f32610eda [ALSA] hda-codec ... |
4742 |
{ |
3e6179b84 ALSA: hda - Merge... |
4743 |
static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
f32610eda [ALSA] hda-codec ... |
4744 |
struct alc_spec *spec = codec->spec; |
3e6179b84 ALSA: hda - Merge... |
4745 4746 4747 4748 4749 |
int err = alc_parse_auto_config(codec, NULL, alc268_ssids); if (err > 0) { if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) { add_mixer(spec, alc268_beep_mixer); add_verb(spec, alc268_beep_init_verbs); |
1d045db96 ALSA: hda - Split... |
4750 |
} |
1d045db96 ALSA: hda - Split... |
4751 |
} |
3e6179b84 ALSA: hda - Merge... |
4752 |
return err; |
f32610eda [ALSA] hda-codec ... |
4753 |
} |
1d045db96 ALSA: hda - Split... |
4754 4755 |
/* */ |
1d045db96 ALSA: hda - Split... |
4756 |
static int patch_alc268(struct hda_codec *codec) |
f32610eda [ALSA] hda-codec ... |
4757 4758 |
{ struct alc_spec *spec; |
1d045db96 ALSA: hda - Split... |
4759 |
int i, has_beep, err; |
f32610eda [ALSA] hda-codec ... |
4760 4761 4762 4763 4764 4765 |
spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; codec->spec = spec; |
1d045db96 ALSA: hda - Split... |
4766 |
/* ALC268 has no aa-loopback mixer */ |
1f0f4b803 ALSA: hda - Reduc... |
4767 |
|
6ebb80530 ALSA: hda - Remov... |
4768 4769 |
/* automatic parse from the BIOS config */ err = alc268_parse_auto_config(codec); |
e16fb6d14 ALSA: hda/realtek... |
4770 4771 |
if (err < 0) goto error; |
f32610eda [ALSA] hda-codec ... |
4772 |
|
1d045db96 ALSA: hda - Split... |
4773 4774 4775 4776 4777 4778 4779 |
has_beep = 0; for (i = 0; i < spec->num_mixers; i++) { if (spec->mixers[i] == alc268_beep_mixer) { has_beep = 1; break; } } |
f32610eda [ALSA] hda-codec ... |
4780 |
|
1d045db96 ALSA: hda - Split... |
4781 4782 |
if (has_beep) { err = snd_hda_attach_beep_device(codec, 0x1); |
e16fb6d14 ALSA: hda/realtek... |
4783 4784 |
if (err < 0) goto error; |
1d045db96 ALSA: hda - Split... |
4785 4786 4787 4788 4789 4790 4791 |
if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) /* override the amp caps for beep generator */ snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, (0x0c << AC_AMPCAP_OFFSET_SHIFT) | (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | (0 << AC_AMPCAP_MUTE_SHIFT)); |
2f8932863 [ALSA] hda - show... |
4792 |
} |
60a6a8425 ALSA: hda - Fix O... |
4793 |
if (!spec->no_analog && !spec->adc_nids) { |
d6cc9fabd ALSA: hda - Parse... |
4794 |
alc_auto_fill_adc_caps(codec); |
21268961d ALSA: hda - More ... |
4795 |
alc_rebuild_imux_for_auto_mic(codec); |
d6cc9fabd ALSA: hda - Parse... |
4796 |
alc_remove_invalid_adc_nids(codec); |
dd704698f ALSA: hda - Don't... |
4797 |
} |
f32610eda [ALSA] hda-codec ... |
4798 |
|
3e6179b84 ALSA: hda - Merge... |
4799 |
if (!spec->no_analog && !spec->cap_mixer) |
1d045db96 ALSA: hda - Split... |
4800 |
set_capture_mixer(codec); |
f32610eda [ALSA] hda-codec ... |
4801 4802 |
codec->patch_ops = alc_patch_ops; |
6ebb80530 ALSA: hda - Remov... |
4803 |
spec->init_hook = alc_auto_init_std; |
1c716153a ALSA: hda - Intro... |
4804 |
spec->shutup = alc_eapd_shutup; |
1d045db96 ALSA: hda - Split... |
4805 |
|
f32610eda [ALSA] hda-codec ... |
4806 |
return 0; |
e16fb6d14 ALSA: hda/realtek... |
4807 4808 4809 4810 |
error: alc_free(codec); return err; |
f32610eda [ALSA] hda-codec ... |
4811 4812 4813 |
} /* |
1d045db96 ALSA: hda - Split... |
4814 |
* ALC269 |
bc9f98a98 [ALSA] hda-codec ... |
4815 |
*/ |
1d045db96 ALSA: hda - Split... |
4816 4817 4818 |
#ifdef CONFIG_SND_HDA_POWER_SAVE #define alc269_loopbacks alc880_loopbacks #endif |
e14063481 [ALSA] hda-codec ... |
4819 |
|
1d045db96 ALSA: hda - Split... |
4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 |
static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { .substreams = 1, .channels_min = 2, .channels_max = 8, .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ /* NID is set in alc_build_pcms */ .ops = { .open = alc_playback_pcm_open, .prepare = alc_playback_pcm_prepare, .cleanup = alc_playback_pcm_cleanup |
bc9f98a98 [ALSA] hda-codec ... |
4830 4831 |
}, }; |
1d045db96 ALSA: hda - Split... |
4832 4833 4834 4835 4836 4837 |
static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ /* NID is set in alc_build_pcms */ |
bc9f98a98 [ALSA] hda-codec ... |
4838 |
}; |
291702f01 [ALSA] Support A... |
4839 |
|
1d045db96 ALSA: hda - Split... |
4840 4841 4842 4843 4844 4845 4846 4847 4848 |
#ifdef CONFIG_SND_HDA_POWER_SAVE static int alc269_mic2_for_mute_led(struct hda_codec *codec) { switch (codec->subsystem_id) { case 0x103c1586: return 1; } return 0; } |
6dda9f4a9 [ALSA] hda - Add ... |
4849 |
|
1d045db96 ALSA: hda - Split... |
4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 |
static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) { /* update mute-LED according to the speaker mute state */ if (nid == 0x01 || nid == 0x14) { int pinval; if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) & HDA_AMP_MUTE) pinval = 0x24; else pinval = 0x20; /* mic2 vref pin is used for mute LED control */ snd_hda_codec_update_cache(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinval); } return alc_check_power_status(codec, nid); } #endif /* CONFIG_SND_HDA_POWER_SAVE */ |
9541ba1d6 ALSA: hda - Add s... |
4868 |
|
1d045db96 ALSA: hda - Split... |
4869 4870 4871 4872 4873 |
/* different alc269-variants */ enum { ALC269_TYPE_ALC269VA, ALC269_TYPE_ALC269VB, ALC269_TYPE_ALC269VC, |
bc9f98a98 [ALSA] hda-codec ... |
4874 4875 4876 |
}; /* |
1d045db96 ALSA: hda - Split... |
4877 |
* BIOS auto configuration |
bc9f98a98 [ALSA] hda-codec ... |
4878 |
*/ |
1d045db96 ALSA: hda - Split... |
4879 4880 |
static int alc269_parse_auto_config(struct hda_codec *codec) { |
1d045db96 ALSA: hda - Split... |
4881 |
static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; |
3e6179b84 ALSA: hda - Merge... |
4882 4883 4884 4885 4886 |
static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 }; static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 }; struct alc_spec *spec = codec->spec; const hda_nid_t *ssids = spec->codec_variant == ALC269_TYPE_ALC269VA ? alc269va_ssids : alc269_ssids; |
bc9f98a98 [ALSA] hda-codec ... |
4887 |
|
3e6179b84 ALSA: hda - Merge... |
4888 |
return alc_parse_auto_config(codec, alc269_ignore, ssids); |
1d045db96 ALSA: hda - Split... |
4889 |
} |
bc9f98a98 [ALSA] hda-codec ... |
4890 |
|
1d045db96 ALSA: hda - Split... |
4891 4892 4893 4894 4895 4896 4897 4898 4899 |
static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) { int val = alc_read_coef_idx(codec, 0x04); if (power_up) val |= 1 << 11; else val &= ~(1 << 11); alc_write_coef_idx(codec, 0x04, val); } |
291702f01 [ALSA] Support A... |
4900 |
|
1d045db96 ALSA: hda - Split... |
4901 4902 |
static void alc269_shutup(struct hda_codec *codec) { |
1bb7e43e2 ALSA: hda/realtek... |
4903 |
if ((alc_get_coef0(codec) & 0x00ff) == 0x017) |
1d045db96 ALSA: hda - Split... |
4904 |
alc269_toggle_power_output(codec, 0); |
1bb7e43e2 ALSA: hda/realtek... |
4905 |
if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
1d045db96 ALSA: hda - Split... |
4906 4907 4908 4909 |
alc269_toggle_power_output(codec, 0); msleep(150); } } |
291702f01 [ALSA] Support A... |
4910 |
|
2a43952a9 ALSA: hda - Make ... |
4911 |
#ifdef CONFIG_PM |
1d045db96 ALSA: hda - Split... |
4912 4913 |
static int alc269_resume(struct hda_codec *codec) { |
1bb7e43e2 ALSA: hda/realtek... |
4914 |
if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
1d045db96 ALSA: hda - Split... |
4915 4916 4917 |
alc269_toggle_power_output(codec, 0); msleep(150); } |
8c427226e [ALSA] hda-codec ... |
4918 |
|
1d045db96 ALSA: hda - Split... |
4919 |
codec->patch_ops.init(codec); |
f1d4e28b2 ALSA: hda - Add m... |
4920 |
|
1bb7e43e2 ALSA: hda/realtek... |
4921 |
if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { |
1d045db96 ALSA: hda - Split... |
4922 4923 4924 |
alc269_toggle_power_output(codec, 1); msleep(200); } |
f1d4e28b2 ALSA: hda - Add m... |
4925 |
|
1bb7e43e2 ALSA: hda/realtek... |
4926 |
if ((alc_get_coef0(codec) & 0x00ff) == 0x018) |
1d045db96 ALSA: hda - Split... |
4927 |
alc269_toggle_power_output(codec, 1); |
f1d4e28b2 ALSA: hda - Add m... |
4928 |
|
1d045db96 ALSA: hda - Split... |
4929 4930 4931 4932 4933 |
snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); hda_call_check_power_status(codec, 0x01); return 0; } |
2a43952a9 ALSA: hda - Make ... |
4934 |
#endif /* CONFIG_PM */ |
f1d4e28b2 ALSA: hda - Add m... |
4935 |
|
1d045db96 ALSA: hda - Split... |
4936 4937 4938 4939 |
static void alc269_fixup_hweq(struct hda_codec *codec, const struct alc_fixup *fix, int action) { int coef; |
f1d4e28b2 ALSA: hda - Add m... |
4940 |
|
1d045db96 ALSA: hda - Split... |
4941 4942 4943 4944 4945 |
if (action != ALC_FIXUP_ACT_INIT) return; coef = alc_read_coef_idx(codec, 0x1e); alc_write_coef_idx(codec, 0x1e, coef | 0x80); } |
f1d4e28b2 ALSA: hda - Add m... |
4946 |
|
1d045db96 ALSA: hda - Split... |
4947 4948 4949 4950 4951 4952 4953 4954 4955 |
static void alc271_fixup_dmic(struct hda_codec *codec, const struct alc_fixup *fix, int action) { static const struct hda_verb verbs[] = { {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, {} }; unsigned int cfg; |
f1d4e28b2 ALSA: hda - Add m... |
4956 |
|
1d045db96 ALSA: hda - Split... |
4957 4958 4959 4960 4961 4962 |
if (strcmp(codec->chip_name, "ALC271X")) return; cfg = snd_hda_codec_get_pincfg(codec, 0x12); if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) snd_hda_sequence_write(codec, verbs); } |
f1d4e28b2 ALSA: hda - Add m... |
4963 |
|
017f2a104 ALSA: hda - Imple... |
4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 |
static void alc269_fixup_pcm_44k(struct hda_codec *codec, const struct alc_fixup *fix, int action) { struct alc_spec *spec = codec->spec; if (action != ALC_FIXUP_ACT_PROBE) return; /* Due to a hardware problem on Lenovo Ideadpad, we need to * fix the sample rate of analog I/O to 44.1kHz */ spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; } |
adabb3ec8 ALSA: hda - Fix d... |
4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 |
static void alc269_fixup_stereo_dmic(struct hda_codec *codec, const struct alc_fixup *fix, int action) { int coef; if (action != ALC_FIXUP_ACT_INIT) return; /* The digital-mic unit sends PDM (differential signal) instead of * the standard PCM, thus you can't record a valid mono stream as is. * Below is a workaround specific to ALC269 to control the dmic * signal source as mono. */ coef = alc_read_coef_idx(codec, 0x07); alc_write_coef_idx(codec, 0x07, coef | 0x80); } |
245199116 ALSA: hda - Repla... |
4993 4994 |
static void alc269_quanta_automute(struct hda_codec *codec) { |
42cf0d015 ALSA: HDA: Refact... |
4995 |
update_outputs(codec); |
245199116 ALSA: hda - Repla... |
4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 |
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x0c); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0x680); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x0c); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0x480); } static void alc269_fixup_quanta_mute(struct hda_codec *codec, const struct alc_fixup *fix, int action) { struct alc_spec *spec = codec->spec; if (action != ALC_FIXUP_ACT_PROBE) return; spec->automute_hook = alc269_quanta_automute; } |
1d045db96 ALSA: hda - Split... |
5016 5017 5018 5019 5020 5021 5022 5023 5024 |
enum { ALC269_FIXUP_SONY_VAIO, ALC275_FIXUP_SONY_VAIO_GPIO2, ALC269_FIXUP_DELL_M101Z, ALC269_FIXUP_SKU_IGNORE, ALC269_FIXUP_ASUS_G73JW, ALC269_FIXUP_LENOVO_EAPD, ALC275_FIXUP_SONY_HWEQ, ALC271_FIXUP_DMIC, |
017f2a104 ALSA: hda - Imple... |
5025 |
ALC269_FIXUP_PCM_44K, |
adabb3ec8 ALSA: hda - Fix d... |
5026 |
ALC269_FIXUP_STEREO_DMIC, |
245199116 ALSA: hda - Repla... |
5027 5028 |
ALC269_FIXUP_QUANTA_MUTE, ALC269_FIXUP_LIFEBOOK, |
a4297b5db ALSA: hda - Rewri... |
5029 5030 5031 5032 |
ALC269_FIXUP_AMIC, ALC269_FIXUP_DMIC, ALC269VB_FIXUP_AMIC, ALC269VB_FIXUP_DMIC, |
f1d4e28b2 ALSA: hda - Add m... |
5033 |
}; |
1d045db96 ALSA: hda - Split... |
5034 5035 5036 5037 5038 5039 5040 |
static const struct alc_fixup alc269_fixups[] = { [ALC269_FIXUP_SONY_VAIO] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, {} } |
f1d4e28b2 ALSA: hda - Add m... |
5041 |
}, |
1d045db96 ALSA: hda - Split... |
5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 |
[ALC275_FIXUP_SONY_VAIO_GPIO2] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, { } }, .chained = true, .chain_id = ALC269_FIXUP_SONY_VAIO }, [ALC269_FIXUP_DELL_M101Z] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { /* Enables internal speaker */ {0x20, AC_VERB_SET_COEF_INDEX, 13}, {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, {} } }, [ALC269_FIXUP_SKU_IGNORE] = { .type = ALC_FIXUP_SKU, .v.sku = ALC_FIXUP_SKU_IGNORE, }, [ALC269_FIXUP_ASUS_G73JW] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x17, 0x99130111 }, /* subwoofer */ { } } }, [ALC269_FIXUP_LENOVO_EAPD] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, {} } }, [ALC275_FIXUP_SONY_HWEQ] = { .type = ALC_FIXUP_FUNC, .v.func = alc269_fixup_hweq, .chained = true, .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 }, [ALC271_FIXUP_DMIC] = { .type = ALC_FIXUP_FUNC, .v.func = alc271_fixup_dmic, |
f1d4e28b2 ALSA: hda - Add m... |
5089 |
}, |
017f2a104 ALSA: hda - Imple... |
5090 5091 5092 5093 |
[ALC269_FIXUP_PCM_44K] = { .type = ALC_FIXUP_FUNC, .v.func = alc269_fixup_pcm_44k, }, |
adabb3ec8 ALSA: hda - Fix d... |
5094 5095 5096 5097 |
[ALC269_FIXUP_STEREO_DMIC] = { .type = ALC_FIXUP_FUNC, .v.func = alc269_fixup_stereo_dmic, }, |
245199116 ALSA: hda - Repla... |
5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 |
[ALC269_FIXUP_QUANTA_MUTE] = { .type = ALC_FIXUP_FUNC, .v.func = alc269_fixup_quanta_mute, }, [ALC269_FIXUP_LIFEBOOK] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x1a, 0x2101103f }, /* dock line-out */ { 0x1b, 0x23a11040 }, /* dock mic-in */ { } }, .chained = true, .chain_id = ALC269_FIXUP_QUANTA_MUTE }, |
a4297b5db ALSA: hda - Rewri... |
5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 |
[ALC269_FIXUP_AMIC] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x15, 0x0121401f }, /* HP out */ { 0x18, 0x01a19c20 }, /* mic */ { 0x19, 0x99a3092f }, /* int-mic */ { } }, }, [ALC269_FIXUP_DMIC] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x12, 0x99a3092f }, /* int-mic */ { 0x14, 0x99130110 }, /* speaker */ { 0x15, 0x0121401f }, /* HP out */ { 0x18, 0x01a19c20 }, /* mic */ { } }, }, [ALC269VB_FIXUP_AMIC] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x18, 0x01a19c20 }, /* mic */ { 0x19, 0x99a3092f }, /* int-mic */ { 0x21, 0x0121401f }, /* HP out */ { } }, }, |
2267ea976 ALSA: HDA: Fix ty... |
5142 |
[ALC269VB_FIXUP_DMIC] = { |
a4297b5db ALSA: hda - Rewri... |
5143 5144 5145 5146 5147 5148 5149 5150 5151 |
.type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x12, 0x99a3092f }, /* int-mic */ { 0x14, 0x99130110 }, /* speaker */ { 0x18, 0x01a19c20 }, /* mic */ { 0x21, 0x0121401f }, /* HP out */ { } }, }, |
f1d4e28b2 ALSA: hda - Add m... |
5152 |
}; |
1d045db96 ALSA: hda - Split... |
5153 |
static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
017f2a104 ALSA: hda - Imple... |
5154 |
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
adabb3ec8 ALSA: hda - Fix d... |
5155 5156 5157 5158 5159 |
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
1d045db96 ALSA: hda - Split... |
5160 5161 5162 5163 5164 5165 |
SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), |
245199116 ALSA: hda - Repla... |
5166 |
SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), |
1d045db96 ALSA: hda - Split... |
5167 5168 5169 5170 5171 |
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), |
245199116 ALSA: hda - Repla... |
5172 |
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE), |
017f2a104 ALSA: hda - Imple... |
5173 |
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), |
1d045db96 ALSA: hda - Split... |
5174 |
SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), |
a4297b5db ALSA: hda - Rewri... |
5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 |
#if 1 /* Below is a quirk table taken from the old code. * Basically the device should work as is without the fixup table. * If BIOS doesn't give a proper info, enable the corresponding * fixup entry. */ SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC), SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC), SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC), #endif {} }; static const struct alc_model_fixup alc269_fixup_models[] = { {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, |
1d045db96 ALSA: hda - Split... |
5231 |
{} |
6dda9f4a9 [ALSA] hda - Add ... |
5232 |
}; |
6dda9f4a9 [ALSA] hda - Add ... |
5233 |
|
1d045db96 ALSA: hda - Split... |
5234 5235 5236 |
static int alc269_fill_coef(struct hda_codec *codec) { int val; |
ebb83eeb6 ALSA: hda - More ... |
5237 |
|
1bb7e43e2 ALSA: hda/realtek... |
5238 |
if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { |
1d045db96 ALSA: hda - Split... |
5239 5240 5241 |
alc_write_coef_idx(codec, 0xf, 0x960b); alc_write_coef_idx(codec, 0xe, 0x8817); } |
ebb83eeb6 ALSA: hda - More ... |
5242 |
|
1bb7e43e2 ALSA: hda/realtek... |
5243 |
if ((alc_get_coef0(codec) & 0x00ff) == 0x016) { |
1d045db96 ALSA: hda - Split... |
5244 5245 5246 |
alc_write_coef_idx(codec, 0xf, 0x960b); alc_write_coef_idx(codec, 0xe, 0x8814); } |
ebb83eeb6 ALSA: hda - More ... |
5247 |
|
1bb7e43e2 ALSA: hda/realtek... |
5248 |
if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { |
1d045db96 ALSA: hda - Split... |
5249 5250 5251 5252 |
val = alc_read_coef_idx(codec, 0x04); /* Power up output pin */ alc_write_coef_idx(codec, 0x04, val | (1<<11)); } |
ebb83eeb6 ALSA: hda - More ... |
5253 |
|
1bb7e43e2 ALSA: hda/realtek... |
5254 |
if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
1d045db96 ALSA: hda - Split... |
5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 |
val = alc_read_coef_idx(codec, 0xd); if ((val & 0x0c00) >> 10 != 0x1) { /* Capless ramp up clock control */ alc_write_coef_idx(codec, 0xd, val | (1<<10)); } val = alc_read_coef_idx(codec, 0x17); if ((val & 0x01c0) >> 6 != 0x4) { /* Class D power on reset */ alc_write_coef_idx(codec, 0x17, val | (1<<7)); } } |
ebb83eeb6 ALSA: hda - More ... |
5266 |
|
1d045db96 ALSA: hda - Split... |
5267 5268 |
val = alc_read_coef_idx(codec, 0xd); /* Class D */ alc_write_coef_idx(codec, 0xd, val | (1<<14)); |
bc9f98a98 [ALSA] hda-codec ... |
5269 |
|
1d045db96 ALSA: hda - Split... |
5270 5271 |
val = alc_read_coef_idx(codec, 0x4); /* HP */ alc_write_coef_idx(codec, 0x4, val | (1<<11)); |
6dda9f4a9 [ALSA] hda - Add ... |
5272 |
|
1d045db96 ALSA: hda - Split... |
5273 5274 |
return 0; } |
a7f2371f9 ALSA: hda - Split... |
5275 |
|
1d045db96 ALSA: hda - Split... |
5276 5277 |
/* */ |
1d045db96 ALSA: hda - Split... |
5278 5279 5280 |
static int patch_alc269(struct hda_codec *codec) { struct alc_spec *spec; |
20ca0c350 ALSA: hda/realtek... |
5281 |
int err = 0; |
291702f01 [ALSA] Support A... |
5282 |
|
1d045db96 ALSA: hda - Split... |
5283 5284 5285 |
spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; |
bc9f98a98 [ALSA] hda-codec ... |
5286 |
|
1d045db96 ALSA: hda - Split... |
5287 |
codec->spec = spec; |
8c427226e [ALSA] hda-codec ... |
5288 |
|
1d045db96 ALSA: hda - Split... |
5289 |
spec->mixer_nid = 0x0b; |
f1d4e28b2 ALSA: hda - Add m... |
5290 |
|
1d045db96 ALSA: hda - Split... |
5291 |
alc_auto_parse_customize_define(codec); |
f1d4e28b2 ALSA: hda - Add m... |
5292 |
|
e16fb6d14 ALSA: hda/realtek... |
5293 5294 5295 |
err = alc_codec_rename_from_preset(codec); if (err < 0) goto error; |
1d045db96 ALSA: hda - Split... |
5296 5297 |
if (codec->vendor_id == 0x10ec0269) { spec->codec_variant = ALC269_TYPE_ALC269VA; |
1bb7e43e2 ALSA: hda/realtek... |
5298 5299 |
switch (alc_get_coef0(codec) & 0x00f0) { case 0x0010: |
1d045db96 ALSA: hda - Split... |
5300 |
if (codec->bus->pci->subsystem_vendor == 0x1025 && |
e16fb6d14 ALSA: hda/realtek... |
5301 |
spec->cdefine.platform_type == 1) |
20ca0c350 ALSA: hda/realtek... |
5302 |
err = alc_codec_rename(codec, "ALC271X"); |
1d045db96 ALSA: hda - Split... |
5303 |
spec->codec_variant = ALC269_TYPE_ALC269VB; |
1bb7e43e2 ALSA: hda/realtek... |
5304 5305 |
break; case 0x0020: |
e16fb6d14 ALSA: hda/realtek... |
5306 5307 |
if (codec->bus->pci->subsystem_vendor == 0x17aa && codec->bus->pci->subsystem_device == 0x21f3) |
20ca0c350 ALSA: hda/realtek... |
5308 |
err = alc_codec_rename(codec, "ALC3202"); |
1d045db96 ALSA: hda - Split... |
5309 |
spec->codec_variant = ALC269_TYPE_ALC269VC; |
1bb7e43e2 ALSA: hda/realtek... |
5310 5311 |
break; default: |
1d045db96 ALSA: hda - Split... |
5312 |
alc_fix_pll_init(codec, 0x20, 0x04, 15); |
1bb7e43e2 ALSA: hda/realtek... |
5313 |
} |
e16fb6d14 ALSA: hda/realtek... |
5314 5315 |
if (err < 0) goto error; |
1d045db96 ALSA: hda - Split... |
5316 5317 |
alc269_fill_coef(codec); } |
6dda9f4a9 [ALSA] hda - Add ... |
5318 |
|
a4297b5db ALSA: hda - Rewri... |
5319 5320 5321 |
alc_pick_fixup(codec, alc269_fixup_models, alc269_fixup_tbl, alc269_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
6dda9f4a9 [ALSA] hda - Add ... |
5322 |
|
a4297b5db ALSA: hda - Rewri... |
5323 5324 |
/* automatic parse from the BIOS config */ err = alc269_parse_auto_config(codec); |
e16fb6d14 ALSA: hda/realtek... |
5325 5326 |
if (err < 0) goto error; |
6dda9f4a9 [ALSA] hda - Add ... |
5327 |
|
60a6a8425 ALSA: hda - Fix O... |
5328 |
if (!spec->no_analog && !spec->adc_nids) { |
1d045db96 ALSA: hda - Split... |
5329 5330 5331 5332 |
alc_auto_fill_adc_caps(codec); alc_rebuild_imux_for_auto_mic(codec); alc_remove_invalid_adc_nids(codec); } |
6dda9f4a9 [ALSA] hda - Add ... |
5333 |
|
3e6179b84 ALSA: hda - Merge... |
5334 |
if (!spec->no_analog && !spec->cap_mixer) |
1d045db96 ALSA: hda - Split... |
5335 |
set_capture_mixer(codec); |
3e6179b84 ALSA: hda - Merge... |
5336 5337 5338 |
if (!spec->no_analog && has_cdefine_beep(codec)) { err = snd_hda_attach_beep_device(codec, 0x1); |
e16fb6d14 ALSA: hda/realtek... |
5339 5340 |
if (err < 0) goto error; |
1d045db96 ALSA: hda - Split... |
5341 |
set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
3e6179b84 ALSA: hda - Merge... |
5342 |
} |
f1d4e28b2 ALSA: hda - Add m... |
5343 |
|
1d045db96 ALSA: hda - Split... |
5344 |
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
622e84cdf ALSA: hda - Add q... |
5345 |
|
1d045db96 ALSA: hda - Split... |
5346 |
codec->patch_ops = alc_patch_ops; |
2a43952a9 ALSA: hda - Make ... |
5347 |
#ifdef CONFIG_PM |
1d045db96 ALSA: hda - Split... |
5348 5349 |
codec->patch_ops.resume = alc269_resume; #endif |
a4297b5db ALSA: hda - Rewri... |
5350 |
spec->init_hook = alc_auto_init_std; |
1d045db96 ALSA: hda - Split... |
5351 |
spec->shutup = alc269_shutup; |
ebb83eeb6 ALSA: hda - More ... |
5352 |
|
1d045db96 ALSA: hda - Split... |
5353 5354 5355 5356 5357 5358 |
#ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc269_loopbacks; if (alc269_mic2_for_mute_led(codec)) codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps; #endif |
ebb83eeb6 ALSA: hda - More ... |
5359 |
|
1d045db96 ALSA: hda - Split... |
5360 |
return 0; |
e16fb6d14 ALSA: hda/realtek... |
5361 5362 5363 5364 |
error: alc_free(codec); return err; |
1d045db96 ALSA: hda - Split... |
5365 |
} |
f1d4e28b2 ALSA: hda - Add m... |
5366 |
|
1d045db96 ALSA: hda - Split... |
5367 5368 5369 |
/* * ALC861 */ |
622e84cdf ALSA: hda - Add q... |
5370 |
|
1d045db96 ALSA: hda - Split... |
5371 |
static int alc861_parse_auto_config(struct hda_codec *codec) |
6dda9f4a9 [ALSA] hda - Add ... |
5372 |
{ |
1d045db96 ALSA: hda - Split... |
5373 |
static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; |
3e6179b84 ALSA: hda - Merge... |
5374 5375 |
static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 }; return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); |
604401a92 ALSA: hda - Minor... |
5376 |
} |
1d045db96 ALSA: hda - Split... |
5377 5378 5379 5380 5381 5382 5383 5384 5385 |
#ifdef CONFIG_SND_HDA_POWER_SAVE static const struct hda_amp_list alc861_loopbacks[] = { { 0x15, HDA_INPUT, 0 }, { 0x15, HDA_INPUT, 1 }, { 0x15, HDA_INPUT, 2 }, { 0x15, HDA_INPUT, 3 }, { } /* end */ }; #endif |
ce764ab22 ALSA: hda - Add c... |
5386 |
|
ce764ab22 ALSA: hda - Add c... |
5387 |
|
1d045db96 ALSA: hda - Split... |
5388 5389 5390 5391 |
/* Pin config fixes */ enum { PINFIX_FSC_AMILO_PI1505, }; |
7085ec12a ALSA: hda - Fix /... |
5392 |
|
1d045db96 ALSA: hda - Split... |
5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 |
static const struct alc_fixup alc861_fixups[] = { [PINFIX_FSC_AMILO_PI1505] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x0b, 0x0221101f }, /* HP */ { 0x0f, 0x90170310 }, /* speaker */ { } } }, }; |
7085ec12a ALSA: hda - Fix /... |
5403 |
|
1d045db96 ALSA: hda - Split... |
5404 5405 5406 5407 |
static const struct snd_pci_quirk alc861_fixup_tbl[] = { SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), {} }; |
3af9ee6b8 ALSA: hda - Check... |
5408 |
|
1d045db96 ALSA: hda - Split... |
5409 5410 |
/* */ |
1d045db96 ALSA: hda - Split... |
5411 |
static int patch_alc861(struct hda_codec *codec) |
7085ec12a ALSA: hda - Fix /... |
5412 |
{ |
1d045db96 ALSA: hda - Split... |
5413 |
struct alc_spec *spec; |
1d045db96 ALSA: hda - Split... |
5414 |
int err; |
7085ec12a ALSA: hda - Fix /... |
5415 |
|
1d045db96 ALSA: hda - Split... |
5416 5417 5418 |
spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; |
3af9ee6b8 ALSA: hda - Check... |
5419 |
|
1d045db96 ALSA: hda - Split... |
5420 5421 5422 |
codec->spec = spec; spec->mixer_nid = 0x15; |
cb4e48241 ALSA: hda - Remov... |
5423 5424 |
alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
3af9ee6b8 ALSA: hda - Check... |
5425 |
|
cb4e48241 ALSA: hda - Remov... |
5426 5427 |
/* automatic parse from the BIOS config */ err = alc861_parse_auto_config(codec); |
e16fb6d14 ALSA: hda/realtek... |
5428 5429 |
if (err < 0) goto error; |
3af9ee6b8 ALSA: hda - Check... |
5430 |
|
60a6a8425 ALSA: hda - Fix O... |
5431 |
if (!spec->no_analog && !spec->adc_nids) { |
1d045db96 ALSA: hda - Split... |
5432 5433 5434 5435 |
alc_auto_fill_adc_caps(codec); alc_rebuild_imux_for_auto_mic(codec); alc_remove_invalid_adc_nids(codec); } |
7085ec12a ALSA: hda - Fix /... |
5436 |
|
3e6179b84 ALSA: hda - Merge... |
5437 |
if (!spec->no_analog && !spec->cap_mixer) |
1d045db96 ALSA: hda - Split... |
5438 |
set_capture_mixer(codec); |
3e6179b84 ALSA: hda - Merge... |
5439 5440 5441 |
if (!spec->no_analog) { err = snd_hda_attach_beep_device(codec, 0x23); |
e16fb6d14 ALSA: hda/realtek... |
5442 5443 |
if (err < 0) goto error; |
3e6179b84 ALSA: hda - Merge... |
5444 5445 |
set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); } |
7085ec12a ALSA: hda - Fix /... |
5446 |
|
1d045db96 ALSA: hda - Split... |
5447 5448 5449 |
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); codec->patch_ops = alc_patch_ops; |
cb4e48241 ALSA: hda - Remov... |
5450 |
spec->init_hook = alc_auto_init_std; |
1d045db96 ALSA: hda - Split... |
5451 |
#ifdef CONFIG_SND_HDA_POWER_SAVE |
cb4e48241 ALSA: hda - Remov... |
5452 |
spec->power_hook = alc_power_eapd; |
1d045db96 ALSA: hda - Split... |
5453 5454 5455 5456 5457 |
if (!spec->loopback.amplist) spec->loopback.amplist = alc861_loopbacks; #endif return 0; |
e16fb6d14 ALSA: hda/realtek... |
5458 5459 5460 5461 |
error: alc_free(codec); return err; |
7085ec12a ALSA: hda - Fix /... |
5462 |
} |
1d045db96 ALSA: hda - Split... |
5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 |
/* * ALC861-VD support * * Based on ALC882 * * In addition, an independent DAC */ #ifdef CONFIG_SND_HDA_POWER_SAVE #define alc861vd_loopbacks alc880_loopbacks #endif |
1d045db96 ALSA: hda - Split... |
5473 |
static int alc861vd_parse_auto_config(struct hda_codec *codec) |
bc9f98a98 [ALSA] hda-codec ... |
5474 |
{ |
1d045db96 ALSA: hda - Split... |
5475 |
static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; |
3e6179b84 ALSA: hda - Merge... |
5476 5477 |
static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 }; return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids); |
ce764ab22 ALSA: hda - Add c... |
5478 |
} |
1d045db96 ALSA: hda - Split... |
5479 |
enum { |
8fdcb6fe4 ALSA: hda - Resto... |
5480 5481 |
ALC660VD_FIX_ASUS_GPIO1, ALC861VD_FIX_DALLAS, |
1d045db96 ALSA: hda - Split... |
5482 |
}; |
ce764ab22 ALSA: hda - Add c... |
5483 |
|
8fdcb6fe4 ALSA: hda - Resto... |
5484 5485 5486 5487 5488 5489 5490 5491 5492 |
/* exclude VREF80 */ static void alc861vd_fixup_dallas(struct hda_codec *codec, const struct alc_fixup *fix, int action) { if (action == ALC_FIXUP_ACT_PRE_PROBE) { snd_hda_override_pin_caps(codec, 0x18, 0x00001714); snd_hda_override_pin_caps(codec, 0x19, 0x0000171c); } } |
1d045db96 ALSA: hda - Split... |
5493 5494 5495 5496 |
static const struct alc_fixup alc861vd_fixups[] = { [ALC660VD_FIX_ASUS_GPIO1] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { |
8fdcb6fe4 ALSA: hda - Resto... |
5497 |
/* reset GPIO1 */ |
1d045db96 ALSA: hda - Split... |
5498 5499 5500 5501 5502 5503 |
{0x01, AC_VERB_SET_GPIO_MASK, 0x03}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, { } } }, |
8fdcb6fe4 ALSA: hda - Resto... |
5504 5505 5506 5507 |
[ALC861VD_FIX_DALLAS] = { .type = ALC_FIXUP_FUNC, .v.func = alc861vd_fixup_dallas, }, |
1d045db96 ALSA: hda - Split... |
5508 |
}; |
ce764ab22 ALSA: hda - Add c... |
5509 |
|
1d045db96 ALSA: hda - Split... |
5510 |
static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { |
8fdcb6fe4 ALSA: hda - Resto... |
5511 |
SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS), |
1d045db96 ALSA: hda - Split... |
5512 |
SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), |
8fdcb6fe4 ALSA: hda - Resto... |
5513 |
SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS), |
1d045db96 ALSA: hda - Split... |
5514 5515 |
{} }; |
ce764ab22 ALSA: hda - Add c... |
5516 |
|
1d045db96 ALSA: hda - Split... |
5517 5518 5519 5520 |
static const struct hda_verb alc660vd_eapd_verbs[] = { {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, { } |
ce764ab22 ALSA: hda - Add c... |
5521 |
}; |
1d045db96 ALSA: hda - Split... |
5522 5523 |
/* */ |
1d045db96 ALSA: hda - Split... |
5524 |
static int patch_alc861vd(struct hda_codec *codec) |
ce764ab22 ALSA: hda - Add c... |
5525 |
{ |
1d045db96 ALSA: hda - Split... |
5526 |
struct alc_spec *spec; |
cb4e48241 ALSA: hda - Remov... |
5527 |
int err; |
ce764ab22 ALSA: hda - Add c... |
5528 |
|
1d045db96 ALSA: hda - Split... |
5529 5530 5531 5532 5533 5534 5535 |
spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; codec->spec = spec; spec->mixer_nid = 0x0b; |
cb4e48241 ALSA: hda - Remov... |
5536 5537 |
alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
1d045db96 ALSA: hda - Split... |
5538 |
|
cb4e48241 ALSA: hda - Remov... |
5539 5540 |
/* automatic parse from the BIOS config */ err = alc861vd_parse_auto_config(codec); |
e16fb6d14 ALSA: hda/realtek... |
5541 5542 |
if (err < 0) goto error; |
ce764ab22 ALSA: hda - Add c... |
5543 |
|
1d045db96 ALSA: hda - Split... |
5544 5545 5546 5547 |
if (codec->vendor_id == 0x10ec0660) { /* always turn on EAPD */ add_verb(spec, alc660vd_eapd_verbs); } |
60a6a8425 ALSA: hda - Fix O... |
5548 |
if (!spec->no_analog && !spec->adc_nids) { |
1d045db96 ALSA: hda - Split... |
5549 5550 5551 |
alc_auto_fill_adc_caps(codec); alc_rebuild_imux_for_auto_mic(codec); alc_remove_invalid_adc_nids(codec); |
ce764ab22 ALSA: hda - Add c... |
5552 |
} |
1d045db96 ALSA: hda - Split... |
5553 |
|
3e6179b84 ALSA: hda - Merge... |
5554 5555 5556 5557 5558 |
if (!spec->no_analog && !spec->cap_mixer) set_capture_mixer(codec); if (!spec->no_analog) { err = snd_hda_attach_beep_device(codec, 0x23); |
e16fb6d14 ALSA: hda/realtek... |
5559 5560 |
if (err < 0) goto error; |
3e6179b84 ALSA: hda - Merge... |
5561 5562 |
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); } |
1d045db96 ALSA: hda - Split... |
5563 |
|
1d045db96 ALSA: hda - Split... |
5564 5565 5566 |
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); codec->patch_ops = alc_patch_ops; |
cb4e48241 ALSA: hda - Remov... |
5567 |
spec->init_hook = alc_auto_init_std; |
1d045db96 ALSA: hda - Split... |
5568 5569 5570 5571 5572 |
spec->shutup = alc_eapd_shutup; #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc861vd_loopbacks; #endif |
ce764ab22 ALSA: hda - Add c... |
5573 |
return 0; |
e16fb6d14 ALSA: hda/realtek... |
5574 5575 5576 5577 |
error: alc_free(codec); return err; |
ce764ab22 ALSA: hda - Add c... |
5578 |
} |
1d045db96 ALSA: hda - Split... |
5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 |
/* * ALC662 support * * ALC662 is almost identical with ALC880 but has cleaner and more flexible * configuration. Each pin widget can choose any input DACs and a mixer. * Each ADC is connected from a mixer of all inputs. This makes possible * 6-channel independent captures. * * In addition, an independent DAC for the multi-playback (not used in this * driver yet). */ #ifdef CONFIG_SND_HDA_POWER_SAVE #define alc662_loopbacks alc880_loopbacks #endif /* * BIOS auto configuration */ |
bc9f98a98 [ALSA] hda-codec ... |
5597 5598 |
static int alc662_parse_auto_config(struct hda_codec *codec) { |
4c6d72d13 ALSA: hda - Const... |
5599 |
static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; |
3e6179b84 ALSA: hda - Merge... |
5600 5601 5602 |
static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 }; static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 }; const hda_nid_t *ssids; |
ee979a143 ALSA: hda - Add m... |
5603 |
|
6227cdced ALSA: hda - Add A... |
5604 5605 |
if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) |
3e6179b84 ALSA: hda - Merge... |
5606 |
ssids = alc663_ssids; |
6227cdced ALSA: hda - Add A... |
5607 |
else |
3e6179b84 ALSA: hda - Merge... |
5608 5609 |
ssids = alc662_ssids; return alc_parse_auto_config(codec, alc662_ignore, ssids); |
bc9f98a98 [ALSA] hda-codec ... |
5610 |
} |
6be7948ff ALSA: hda: Add fi... |
5611 |
static void alc272_fixup_mario(struct hda_codec *codec, |
b5bfbc670 ALSA: hda - Reorg... |
5612 |
const struct alc_fixup *fix, int action) |
6fc398cb3 ALSA: hda - Apply... |
5613 |
{ |
b5bfbc670 ALSA: hda - Reorg... |
5614 |
if (action != ALC_FIXUP_ACT_PROBE) |
6fc398cb3 ALSA: hda - Apply... |
5615 |
return; |
6be7948ff ALSA: hda: Add fi... |
5616 5617 5618 5619 5620 5621 5622 5623 5624 |
if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, (0x3b << AC_AMPCAP_OFFSET_SHIFT) | (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | (0 << AC_AMPCAP_MUTE_SHIFT))) printk(KERN_WARNING "hda_codec: failed to override amp caps for NID 0x2 "); } |
6cb3b707f ALSA: HDA: Add fi... |
5625 |
enum { |
2df03514d ALSA: hda: Add sp... |
5626 |
ALC662_FIXUP_ASPIRE, |
6cb3b707f ALSA: HDA: Add fi... |
5627 |
ALC662_FIXUP_IDEAPAD, |
6be7948ff ALSA: hda: Add fi... |
5628 |
ALC272_FIXUP_MARIO, |
d2ebd4798 ALSA: hda - Fix E... |
5629 |
ALC662_FIXUP_CZC_P10T, |
94024cd1a ALSA: HDA: Fix au... |
5630 |
ALC662_FIXUP_SKU_IGNORE, |
e59ea3ed9 ALSA: hda - Add a... |
5631 |
ALC662_FIXUP_HP_RP5800, |
53c334add ALSA: hda - Rewri... |
5632 5633 5634 5635 5636 5637 5638 5639 |
ALC662_FIXUP_ASUS_MODE1, ALC662_FIXUP_ASUS_MODE2, ALC662_FIXUP_ASUS_MODE3, ALC662_FIXUP_ASUS_MODE4, ALC662_FIXUP_ASUS_MODE5, ALC662_FIXUP_ASUS_MODE6, ALC662_FIXUP_ASUS_MODE7, ALC662_FIXUP_ASUS_MODE8, |
6cb3b707f ALSA: HDA: Add fi... |
5640 5641 5642 |
}; static const struct alc_fixup alc662_fixups[] = { |
2df03514d ALSA: hda: Add sp... |
5643 |
[ALC662_FIXUP_ASPIRE] = { |
b5bfbc670 ALSA: hda - Reorg... |
5644 5645 |
.type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { |
2df03514d ALSA: hda: Add sp... |
5646 5647 5648 5649 |
{ 0x15, 0x99130112 }, /* subwoofer */ { } } }, |
6cb3b707f ALSA: HDA: Add fi... |
5650 |
[ALC662_FIXUP_IDEAPAD] = { |
b5bfbc670 ALSA: hda - Reorg... |
5651 5652 |
.type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { |
6cb3b707f ALSA: HDA: Add fi... |
5653 5654 5655 5656 |
{ 0x17, 0x99130112 }, /* subwoofer */ { } } }, |
6be7948ff ALSA: hda: Add fi... |
5657 |
[ALC272_FIXUP_MARIO] = { |
b5bfbc670 ALSA: hda - Reorg... |
5658 5659 |
.type = ALC_FIXUP_FUNC, .v.func = alc272_fixup_mario, |
d2ebd4798 ALSA: hda - Fix E... |
5660 5661 5662 5663 5664 5665 5666 5667 |
}, [ALC662_FIXUP_CZC_P10T] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, {} } }, |
94024cd1a ALSA: HDA: Fix au... |
5668 5669 5670 |
[ALC662_FIXUP_SKU_IGNORE] = { .type = ALC_FIXUP_SKU, .v.sku = ALC_FIXUP_SKU_IGNORE, |
c6b358748 ALSA: hda - Fix p... |
5671 |
}, |
e59ea3ed9 ALSA: hda - Add a... |
5672 5673 5674 5675 5676 5677 5678 5679 5680 |
[ALC662_FIXUP_HP_RP5800] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x0221201f }, /* HP out */ { } }, .chained = true, .chain_id = ALC662_FIXUP_SKU_IGNORE }, |
53c334add ALSA: hda - Rewri... |
5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 |
[ALC662_FIXUP_ASUS_MODE1] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x18, 0x01a19c20 }, /* mic */ { 0x19, 0x99a3092f }, /* int-mic */ { 0x21, 0x0121401f }, /* HP out */ { } }, .chained = true, .chain_id = ALC662_FIXUP_SKU_IGNORE }, [ALC662_FIXUP_ASUS_MODE2] = { |
2996bdbaa ALSA: hda - Remov... |
5694 5695 5696 5697 5698 5699 5700 5701 |
.type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x18, 0x01a19820 }, /* mic */ { 0x19, 0x99a3092f }, /* int-mic */ { 0x1b, 0x0121401f }, /* HP out */ { } }, |
53c334add ALSA: hda - Rewri... |
5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 |
.chained = true, .chain_id = ALC662_FIXUP_SKU_IGNORE }, [ALC662_FIXUP_ASUS_MODE3] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x15, 0x0121441f }, /* HP */ { 0x18, 0x01a19840 }, /* mic */ { 0x19, 0x99a3094f }, /* int-mic */ { 0x21, 0x01211420 }, /* HP2 */ { } }, .chained = true, .chain_id = ALC662_FIXUP_SKU_IGNORE }, [ALC662_FIXUP_ASUS_MODE4] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x16, 0x99130111 }, /* speaker */ { 0x18, 0x01a19840 }, /* mic */ { 0x19, 0x99a3094f }, /* int-mic */ { 0x21, 0x0121441f }, /* HP */ { } }, .chained = true, .chain_id = ALC662_FIXUP_SKU_IGNORE }, [ALC662_FIXUP_ASUS_MODE5] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x15, 0x0121441f }, /* HP */ { 0x16, 0x99130111 }, /* speaker */ { 0x18, 0x01a19840 }, /* mic */ { 0x19, 0x99a3094f }, /* int-mic */ { } }, .chained = true, .chain_id = ALC662_FIXUP_SKU_IGNORE }, [ALC662_FIXUP_ASUS_MODE6] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x15, 0x01211420 }, /* HP2 */ { 0x18, 0x01a19840 }, /* mic */ { 0x19, 0x99a3094f }, /* int-mic */ { 0x1b, 0x0121441f }, /* HP */ { } }, .chained = true, .chain_id = ALC662_FIXUP_SKU_IGNORE }, [ALC662_FIXUP_ASUS_MODE7] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x17, 0x99130111 }, /* speaker */ { 0x18, 0x01a19840 }, /* mic */ { 0x19, 0x99a3094f }, /* int-mic */ { 0x1b, 0x01214020 }, /* HP */ { 0x21, 0x0121401f }, /* HP */ { } }, .chained = true, .chain_id = ALC662_FIXUP_SKU_IGNORE }, [ALC662_FIXUP_ASUS_MODE8] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x12, 0x99a30970 }, /* int-mic */ { 0x15, 0x01214020 }, /* HP */ { 0x17, 0x99130111 }, /* speaker */ { 0x18, 0x01a19840 }, /* mic */ { 0x21, 0x0121401f }, /* HP */ { } }, .chained = true, .chain_id = ALC662_FIXUP_SKU_IGNORE |
2996bdbaa ALSA: hda - Remov... |
5784 |
}, |
6cb3b707f ALSA: HDA: Add fi... |
5785 |
}; |
a9111321f ALSA: hda - Const... |
5786 |
static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
53c334add ALSA: hda - Rewri... |
5787 |
SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), |
a6c47a85b ALSA: HDA: Add su... |
5788 |
SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), |
94024cd1a ALSA: HDA: Fix au... |
5789 |
SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), |
2df03514d ALSA: hda: Add sp... |
5790 |
SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
e59ea3ed9 ALSA: hda - Add a... |
5791 |
SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
53c334add ALSA: hda - Rewri... |
5792 |
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), |
a0e90acc6 ALSA: hda: Add Sa... |
5793 |
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), |
d41185882 ALSA: hda - Added... |
5794 |
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), |
6cb3b707f ALSA: HDA: Add fi... |
5795 |
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), |
d2ebd4798 ALSA: hda - Fix E... |
5796 |
SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), |
53c334add ALSA: hda - Rewri... |
5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 |
#if 0 /* Below is a quirk table taken from the old code. * Basically the device should work as is without the fixup table. * If BIOS doesn't give a proper info, enable the corresponding * fixup entry. */ SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7), SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7), SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8), SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5), SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4), #endif |
6cb3b707f ALSA: HDA: Add fi... |
5855 5856 |
{} }; |
6be7948ff ALSA: hda: Add fi... |
5857 5858 |
static const struct alc_model_fixup alc662_fixup_models[] = { {.id = ALC272_FIXUP_MARIO, .name = "mario"}, |
53c334add ALSA: hda - Rewri... |
5859 5860 5861 5862 5863 5864 5865 5866 |
{.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"}, {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"}, {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, |
6be7948ff ALSA: hda: Add fi... |
5867 5868 |
{} }; |
6cb3b707f ALSA: HDA: Add fi... |
5869 |
|
1d045db96 ALSA: hda - Split... |
5870 5871 |
/* */ |
bc9f98a98 [ALSA] hda-codec ... |
5872 5873 5874 |
static int patch_alc662(struct hda_codec *codec) { struct alc_spec *spec; |
20ca0c350 ALSA: hda/realtek... |
5875 |
int err = 0; |
bc9f98a98 [ALSA] hda-codec ... |
5876 5877 5878 5879 5880 5881 |
spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (!spec) return -ENOMEM; codec->spec = spec; |
1f0f4b803 ALSA: hda - Reduc... |
5882 |
spec->mixer_nid = 0x0b; |
53c334add ALSA: hda - Rewri... |
5883 5884 |
/* handle multiple HPs as is */ spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; |
da00c2449 ALSA: hda - Add p... |
5885 |
alc_auto_parse_customize_define(codec); |
2c3bf9abb [ALSA] hda - Fix ... |
5886 |
alc_fix_pll_init(codec, 0x20, 0x04, 15); |
e16fb6d14 ALSA: hda/realtek... |
5887 5888 5889 |
err = alc_codec_rename_from_preset(codec); if (err < 0) goto error; |
1bb7e43e2 ALSA: hda/realtek... |
5890 |
if ((alc_get_coef0(codec) & (1 << 14)) && |
e16fb6d14 ALSA: hda/realtek... |
5891 5892 5893 5894 |
codec->bus->pci->subsystem_vendor == 0x1025 && spec->cdefine.platform_type == 1) { if (alc_codec_rename(codec, "ALC272X") < 0) goto error; |
20ca0c350 ALSA: hda/realtek... |
5895 |
} |
274693f37 ALSA: hda - Add A... |
5896 |
|
b9c5106cd ALSA: hda - Remov... |
5897 5898 5899 5900 5901 |
alc_pick_fixup(codec, alc662_fixup_models, alc662_fixup_tbl, alc662_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); /* automatic parse from the BIOS config */ err = alc662_parse_auto_config(codec); |
e16fb6d14 ALSA: hda/realtek... |
5902 5903 |
if (err < 0) goto error; |
bc9f98a98 [ALSA] hda-codec ... |
5904 |
|
60a6a8425 ALSA: hda - Fix O... |
5905 |
if (!spec->no_analog && !spec->adc_nids) { |
d6cc9fabd ALSA: hda - Parse... |
5906 |
alc_auto_fill_adc_caps(codec); |
21268961d ALSA: hda - More ... |
5907 |
alc_rebuild_imux_for_auto_mic(codec); |
d6cc9fabd ALSA: hda - Parse... |
5908 |
alc_remove_invalid_adc_nids(codec); |
dd704698f ALSA: hda - Don't... |
5909 |
} |
bc9f98a98 [ALSA] hda-codec ... |
5910 |
|
3e6179b84 ALSA: hda - Merge... |
5911 |
if (!spec->no_analog && !spec->cap_mixer) |
b59bdf3b0 ALSA: hda - Check... |
5912 |
set_capture_mixer(codec); |
cec27c891 ALSA: hda - Add s... |
5913 |
|
3e6179b84 ALSA: hda - Merge... |
5914 5915 |
if (!spec->no_analog && has_cdefine_beep(codec)) { err = snd_hda_attach_beep_device(codec, 0x1); |
e16fb6d14 ALSA: hda/realtek... |
5916 5917 |
if (err < 0) goto error; |
da00c2449 ALSA: hda - Add p... |
5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 |
switch (codec->vendor_id) { case 0x10ec0662: set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); break; case 0x10ec0272: case 0x10ec0663: case 0x10ec0665: set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); break; case 0x10ec0273: set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); break; } |
cec27c891 ALSA: hda - Add s... |
5931 |
} |
2134ea4f3 [ALSA] hda-codec ... |
5932 |
|
b5bfbc670 ALSA: hda - Reorg... |
5933 |
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
bc9f98a98 [ALSA] hda-codec ... |
5934 |
codec->patch_ops = alc_patch_ops; |
b9c5106cd ALSA: hda - Remov... |
5935 |
spec->init_hook = alc_auto_init_std; |
1c716153a ALSA: hda - Intro... |
5936 |
spec->shutup = alc_eapd_shutup; |
6cb3b707f ALSA: HDA: Add fi... |
5937 |
|
cb53c626e [ALSA] hda-intel ... |
5938 5939 5940 5941 |
#ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc662_loopbacks; #endif |
bc9f98a98 [ALSA] hda-codec ... |
5942 5943 |
return 0; |
801f49d3b ALSA: hda - ALC88... |
5944 |
|
e16fb6d14 ALSA: hda/realtek... |
5945 5946 5947 |
error: alc_free(codec); return err; |
b478b9984 ALSA: hda - Add s... |
5948 |
} |
bc9f98a98 [ALSA] hda-codec ... |
5949 |
/* |
d1eb57f47 ALSA: hda - Suppo... |
5950 5951 |
* ALC680 support */ |
d1eb57f47 ALSA: hda - Suppo... |
5952 |
|
d1eb57f47 ALSA: hda - Suppo... |
5953 5954 |
static int alc680_parse_auto_config(struct hda_codec *codec) { |
3e6179b84 ALSA: hda - Merge... |
5955 |
return alc_parse_auto_config(codec, NULL, NULL); |
d1eb57f47 ALSA: hda - Suppo... |
5956 |
} |
d1eb57f47 ALSA: hda - Suppo... |
5957 |
/* |
d1eb57f47 ALSA: hda - Suppo... |
5958 |
*/ |
d1eb57f47 ALSA: hda - Suppo... |
5959 5960 5961 |
static int patch_alc680(struct hda_codec *codec) { struct alc_spec *spec; |
d1eb57f47 ALSA: hda - Suppo... |
5962 5963 5964 5965 5966 5967 5968 |
int err; spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; codec->spec = spec; |
1f0f4b803 ALSA: hda - Reduc... |
5969 |
/* ALC680 has no aa-loopback mixer */ |
1ebec5f2a ALSA: hda - Remov... |
5970 5971 5972 5973 5974 |
/* automatic parse from the BIOS config */ err = alc680_parse_auto_config(codec); if (err < 0) { alc_free(codec); return err; |
d1eb57f47 ALSA: hda - Suppo... |
5975 |
} |
3e6179b84 ALSA: hda - Merge... |
5976 |
if (!spec->no_analog && !spec->cap_mixer) |
d1eb57f47 ALSA: hda - Suppo... |
5977 |
set_capture_mixer(codec); |
d1eb57f47 ALSA: hda - Suppo... |
5978 |
codec->patch_ops = alc_patch_ops; |
1ebec5f2a ALSA: hda - Remov... |
5979 |
spec->init_hook = alc_auto_init_std; |
d1eb57f47 ALSA: hda - Suppo... |
5980 5981 5982 5983 5984 |
return 0; } /* |
1da177e4c Linux-2.6.12-rc2 |
5985 5986 |
* patch entries */ |
a9111321f ALSA: hda - Const... |
5987 |
static const struct hda_codec_preset snd_hda_preset_realtek[] = { |
296f03380 ALSA: hda - Add s... |
5988 |
{ .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, |
1da177e4c Linux-2.6.12-rc2 |
5989 |
{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, |
df694daa3 [ALSA] hda-codec ... |
5990 |
{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, |
f6a92248a [ALSA] hda-codec ... |
5991 |
{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, |
a361d84bf [ALSA] hda-codec ... |
5992 |
{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, |
f6a92248a [ALSA] hda-codec ... |
5993 |
{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, |
ebb83eeb6 ALSA: hda - More ... |
5994 |
{ .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, |
01afd41f5 ALSA: hda - Add s... |
5995 |
{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, |
ebb83eeb6 ALSA: hda - More ... |
5996 |
{ .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, |
296f03380 ALSA: hda - Add s... |
5997 |
{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, |
f32610eda [ALSA] hda-codec ... |
5998 |
{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
bc9f98a98 [ALSA] hda-codec ... |
5999 |
.patch = patch_alc861 }, |
f32610eda [ALSA] hda-codec ... |
6000 6001 6002 |
{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, |
bc9f98a98 [ALSA] hda-codec ... |
6003 |
{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", |
4953550a6 ALSA: hda - Merge... |
6004 |
.patch = patch_alc882 }, |
bc9f98a98 [ALSA] hda-codec ... |
6005 6006 |
{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", .patch = patch_alc662 }, |
cc667a72d ALSA: HDA: Add ne... |
6007 6008 |
{ .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", .patch = patch_alc662 }, |
6dda9f4a9 [ALSA] hda - Add ... |
6009 |
{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, |
cec27c891 ALSA: hda - Add s... |
6010 |
{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, |
6227cdced ALSA: hda - Add A... |
6011 |
{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, |
d1eb57f47 ALSA: hda - Suppo... |
6012 |
{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, |
f32610eda [ALSA] hda-codec ... |
6013 |
{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
1da177e4c Linux-2.6.12-rc2 |
6014 |
{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
4953550a6 ALSA: hda - Merge... |
6015 |
{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, |
669faba27 ALSA: hda - Fix a... |
6016 |
{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", |
4953550a6 ALSA: hda - Merge... |
6017 |
.patch = patch_alc882 }, |
cb308f97a [ALSA] hda - Fix ... |
6018 |
{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", |
4953550a6 ALSA: hda - Merge... |
6019 |
.patch = patch_alc882 }, |
df694daa3 [ALSA] hda-codec ... |
6020 |
{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, |
e16fb6d14 ALSA: hda/realtek... |
6021 |
{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, |
4442608d4 ALSA: hda - Add A... |
6022 |
{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", |
4953550a6 ALSA: hda - Merge... |
6023 |
.patch = patch_alc882 }, |
e16fb6d14 ALSA: hda/realtek... |
6024 |
{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, |
4953550a6 ALSA: hda - Merge... |
6025 |
{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, |
274693f37 ALSA: hda - Add A... |
6026 |
{ .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, |
e16fb6d14 ALSA: hda/realtek... |
6027 |
{ .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, |
1da177e4c Linux-2.6.12-rc2 |
6028 6029 |
{} /* terminator */ }; |
1289e9e8b ALSA: hda - Modul... |
6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 |
MODULE_ALIAS("snd-hda-codec-id:10ec*"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Realtek HD-audio codec"); static struct hda_codec_preset_list realtek_list = { .preset = snd_hda_preset_realtek, .owner = THIS_MODULE, }; static int __init patch_realtek_init(void) { return snd_hda_add_codec_preset(&realtek_list); } static void __exit patch_realtek_exit(void) { snd_hda_delete_codec_preset(&realtek_list); } module_init(patch_realtek_init) module_exit(patch_realtek_exit) |