aboutsummaryrefslogtreecommitdiff
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c1194
1 files changed, 797 insertions, 397 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 6c26afcb826..82097790f6f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -30,6 +30,7 @@
#include <sound/core.h>
#include "hda_codec.h"
#include "hda_local.h"
+#include "hda_beep.h"
#define ALC880_FRONT_EVENT 0x01
#define ALC880_DCVOL_EVENT 0x02
@@ -77,6 +78,7 @@ enum {
ALC260_ACER,
ALC260_WILL,
ALC260_REPLACER_672V,
+ ALC260_FAVORIT100,
#ifdef CONFIG_SND_DEBUG
ALC260_TEST,
#endif
@@ -103,6 +105,7 @@ enum {
ALC262_NEC,
ALC262_TOSHIBA_S06,
ALC262_TOSHIBA_RX1,
+ ALC262_TYAN,
ALC262_AUTO,
ALC262_MODEL_LAST /* last tag */
};
@@ -238,6 +241,13 @@ enum {
ALC883_MODEL_LAST,
};
+/* styles of capture selection */
+enum {
+ CAPT_MUX = 0, /* only mux based */
+ CAPT_MIX, /* only mixer based */
+ CAPT_1MUX_MIX, /* first mux and other mixers */
+};
+
/* for GPIO Poll */
#define GPIO_MASK 0x03
@@ -246,6 +256,7 @@ struct alc_spec {
struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
unsigned int num_mixers;
struct snd_kcontrol_new *cap_mixer; /* capture mixer */
+ unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
const struct hda_verb *init_verbs[5]; /* initialization verbs
* don't forget NULL
@@ -269,13 +280,15 @@ struct alc_spec {
* dig_out_nid and hp_nid are optional
*/
hda_nid_t alt_dac_nid;
+ hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
+ int dig_out_type;
/* capture */
unsigned int num_adc_nids;
hda_nid_t *adc_nids;
hda_nid_t *capsrc_nids;
hda_nid_t dig_in_nid; /* digital-in NID; optional */
- unsigned char is_mix_capture; /* matrix-style capture (non-mux) */
+ int capture_style; /* capture style (CAPT_*) */
/* capture source */
unsigned int num_mux_defs;
@@ -293,7 +306,7 @@ struct alc_spec {
/* dynamic controls, init_verbs and input_mux */
struct auto_pin_cfg autocfg;
struct snd_array kctls;
- struct hda_input_mux private_imux;
+ struct hda_input_mux private_imux[3];
hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
/* hooks */
@@ -305,6 +318,9 @@ struct alc_spec {
unsigned int jack_present: 1;
unsigned int master_sw: 1;
+ /* other flags */
+ unsigned int no_analog :1; /* digital I/O only */
+
/* for virtual master */
hda_nid_t vmaster_nid;
#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -314,13 +330,6 @@ struct alc_spec {
/* for PLL fix */
hda_nid_t pll_nid;
unsigned int pll_coef_idx, pll_coef_bit;
-
-#ifdef SND_HDA_NEEDS_RESUME
-#define ALC_MAX_PINS 16
- unsigned int num_pins;
- hda_nid_t pin_nids[ALC_MAX_PINS];
- unsigned int pin_cfgs[ALC_MAX_PINS];
-#endif
};
/*
@@ -336,6 +345,7 @@ struct alc_config_preset {
hda_nid_t *dac_nids;
hda_nid_t dig_out_nid; /* optional */
hda_nid_t hp_nid; /* optional */
+ hda_nid_t *slave_dig_outs;
unsigned int num_adc_nids;
hda_nid_t *adc_nids;
hda_nid_t *capsrc_nids;
@@ -392,7 +402,8 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
imux = &spec->input_mux[mux_idx];
- if (spec->is_mix_capture) {
+ if (spec->capture_style &&
+ !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
/* Matrix-mixer style (e.g. ALC882) */
unsigned int *cur_val = &spec->cur_mux[adc_idx];
unsigned int i, idx;
@@ -750,6 +761,24 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
#endif /* CONFIG_SND_DEBUG */
/*
+ * 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;
+
+ if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
+ unsigned int pincap;
+ pincap = snd_hda_query_pin_caps(codec, nid);
+ pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
+ if (pincap & AC_PINCAP_VREF_80)
+ val = PIN_VREF80;
+ }
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+}
+
+/*
*/
static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
{
@@ -810,6 +839,7 @@ static void setup_preset(struct alc_spec *spec,
spec->multiout.num_dacs = preset->num_dacs;
spec->multiout.dac_nids = preset->dac_nids;
spec->multiout.dig_out_nid = preset->dig_out_nid;
+ spec->multiout.slave_dig_outs = preset->slave_dig_outs;
spec->multiout.hp_nid = preset->hp_nid;
spec->num_mux_defs = preset->num_mux_defs;
@@ -921,7 +951,7 @@ static void alc_mic_automute(struct hda_codec *codec)
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
#else
-#define alc_mic_automute(codec) /* NOP */
+#define alc_mic_automute(codec) do {} while(0) /* NOP */
#endif /* disabled */
/* unsolicited event for HP jack sensing */
@@ -952,7 +982,7 @@ static void alc888_coef_init(struct hda_codec *codec)
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);
- if ((tmp & 0xf0) == 2)
+ if ((tmp & 0xf0) == 0x20)
/* alc888S-VC */
snd_hda_codec_read(codec, 0x20, 0,
AC_VERB_SET_PROC_COEF, 0x830);
@@ -991,8 +1021,7 @@ static void alc_subsystem_id(struct hda_codec *codec,
nid = 0x1d;
if (codec->vendor_id == 0x10ec0260)
nid = 0x17;
- ass = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_CONFIG_DEFAULT, 0);
+ ass = snd_hda_codec_get_pincfg(codec, nid);
if (!(ass & 1) && !(ass & 0x100000))
return;
if ((ass >> 30) != 1) /* no physical connection */
@@ -1166,16 +1195,8 @@ static void alc_fix_pincfg(struct hda_codec *codec,
return;
cfg = pinfix[quirk->value];
- for (; cfg->nid; cfg++) {
- int i;
- u32 val = cfg->val;
- for (i = 0; i < 4; i++) {
- snd_hda_codec_write(codec, cfg->nid, 0,
- AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
- val & 0xff);
- val >>= 8;
- }
- }
+ for (; cfg->nid; cfg++)
+ snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
}
/*
@@ -1375,8 +1396,6 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
{ } /* end */
};
@@ -1483,8 +1502,6 @@ static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1578,8 +1595,7 @@ static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
snd_hda_mixer_amp_switch_put);
}
-#define DEFINE_CAPMIX(num) \
-static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
+#define _DEFINE_CAPMIX(num) \
{ \
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
.name = "Capture Switch", \
@@ -1600,7 +1616,9 @@ static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
.get = alc_cap_vol_get, \
.put = alc_cap_vol_put, \
.tlv = { .c = alc_cap_vol_tlv }, \
- }, \
+ }
+
+#define _DEFINE_CAPSRC(num) \
{ \
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
/* .name = "Capture Source", */ \
@@ -1609,15 +1627,28 @@ static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
.info = alc_mux_enum_info, \
.get = alc_mux_enum_get, \
.put = alc_mux_enum_put, \
- }, \
- { } /* end */ \
+ }
+
+#define DEFINE_CAPMIX(num) \
+static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
+ _DEFINE_CAPMIX(num), \
+ _DEFINE_CAPSRC(num), \
+ { } /* end */ \
+}
+
+#define DEFINE_CAPMIX_NOSRC(num) \
+static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
+ _DEFINE_CAPMIX(num), \
+ { } /* end */ \
}
/* up to three ADCs */
DEFINE_CAPMIX(1);
DEFINE_CAPMIX(2);
DEFINE_CAPMIX(3);
-
+DEFINE_CAPMIX_NOSRC(1);
+DEFINE_CAPMIX_NOSRC(2);
+DEFINE_CAPMIX_NOSRC(3);
/*
* ALC880 5-stack model
@@ -1706,8 +1737,6 @@ static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Channel Mode",
@@ -1884,13 +1913,6 @@ static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
{ } /* end */
};
-/* additional mixers to alc880_asus_mixer */
-static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
- HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
- { } /* end */
-};
-
/* TCL S700 */
static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -1923,8 +1945,6 @@ static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Channel Mode",
@@ -1999,6 +2019,13 @@ static const char *alc_slave_sws[] = {
static void alc_free_kctls(struct hda_codec *codec);
+/* additional beep mixers; the actual parameters are overwritten at build */
+static struct snd_kcontrol_new alc_beep_mixer[] = {
+ HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
+ { } /* end */
+};
+
static int alc_build_controls(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -2020,11 +2047,13 @@ static int alc_build_controls(struct hda_codec *codec)
spec->multiout.dig_out_nid);
if (err < 0)
return err;
- err = snd_hda_create_spdif_share_sw(codec,
- &spec->multiout);
- if (err < 0)
- return err;
- spec->multiout.share_spdif = 1;
+ if (!spec->no_analog) {
+ err = snd_hda_create_spdif_share_sw(codec,
+ &spec->multiout);
+ if (err < 0)
+ return err;
+ spec->multiout.share_spdif = 1;
+ }
}
if (spec->dig_in_nid) {
err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
@@ -2032,8 +2061,24 @@ static int alc_build_controls(struct hda_codec *codec)
return err;
}
+ /* create beep controls if needed */
+ if (spec->beep_amp) {
+ struct snd_kcontrol_new *knew;
+ 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;
+ err = snd_hda_ctl_add(codec, kctl);
+ if (err < 0)
+ return err;
+ }
+ }
+
/* if we have no master control, let's create it */
- if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
+ if (!spec->no_analog &&
+ !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
unsigned int vmaster_tlv[4];
snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
HDA_OUTPUT, vmaster_tlv);
@@ -2042,7 +2087,8 @@ static int alc_build_controls(struct hda_codec *codec)
if (err < 0)
return err;
}
- if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
+ if (!spec->no_analog &&
+ !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
err = snd_hda_add_vmaster(codec, "Master Playback Switch",
NULL, alc_slave_sws);
if (err < 0)
@@ -2951,6 +2997,14 @@ static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
stream_tag, format, substream);
}
+static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ struct alc_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
+}
+
static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
@@ -3034,7 +3088,8 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = {
.ops = {
.open = alc880_dig_playback_pcm_open,
.close = alc880_dig_playback_pcm_close,
- .prepare = alc880_dig_playback_pcm_prepare
+ .prepare = alc880_dig_playback_pcm_prepare,
+ .cleanup = alc880_dig_playback_pcm_cleanup
},
};
@@ -3061,6 +3116,9 @@ static int alc_build_pcms(struct hda_codec *codec)
codec->num_pcms = 1;
codec->pcm_info = info;
+ if (spec->no_analog)
+ goto skip_analog;
+
info->name = spec->stream_name_analog;
if (spec->stream_analog_playback) {
if (snd_BUG_ON(!spec->multiout.dac_nids))
@@ -3084,12 +3142,17 @@ static int alc_build_pcms(struct hda_codec *codec)
}
}
+ skip_analog:
/* SPDIF for stream index #1 */
if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
codec->num_pcms = 2;
+ codec->slave_dig_outs = spec->multiout.slave_dig_outs;
info = spec->pcm_rec + 1;
info->name = spec->stream_name_digital;
- info->pcm_type = HDA_PCM_TYPE_SPDIF;
+ if (spec->dig_out_type)
+ info->pcm_type = spec->dig_out_type;
+ else
+ info->pcm_type = HDA_PCM_TYPE_SPDIF;
if (spec->multiout.dig_out_nid &&
spec->stream_digital_playback) {
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
@@ -3104,6 +3167,9 @@ static int alc_build_pcms(struct hda_codec *codec)
codec->spdif_status_reset = 1;
}
+ if (spec->no_analog)
+ return 0;
+
/* If the use of more than one ADC is requested for the current
* model, configure a second analog capture-only PCM.
*/
@@ -3162,65 +3228,17 @@ static void alc_free(struct hda_codec *codec)
alc_free_kctls(codec);
kfree(spec);
- codec->spec = NULL; /* to be sure */
+ snd_hda_detach_beep_device(codec);
}
#ifdef SND_HDA_NEEDS_RESUME
-static void store_pin_configs(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- hda_nid_t nid, end_nid;
-
- end_nid = codec->start_nid + codec->num_nodes;
- for (nid = codec->start_nid; nid < end_nid; nid++) {
- unsigned int wid_caps = get_wcaps(codec, nid);
- unsigned int wid_type =
- (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
- if (wid_type != AC_WID_PIN)
- continue;
- if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
- break;
- spec->pin_nids[spec->num_pins] = nid;
- spec->pin_cfgs[spec->num_pins] =
- snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_CONFIG_DEFAULT, 0);
- spec->num_pins++;
- }
-}
-
-static void resume_pin_configs(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->num_pins; i++) {
- hda_nid_t pin_nid = spec->pin_nids[i];
- unsigned int pin_config = spec->pin_cfgs[i];
- snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
- pin_config & 0x000000ff);
- snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
- (pin_config & 0x0000ff00) >> 8);
- snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
- (pin_config & 0x00ff0000) >> 16);
- snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
- pin_config >> 24);
- }
-}
-
static int alc_resume(struct hda_codec *codec)
{
- resume_pin_configs(codec);
codec->patch_ops.init(codec);
snd_hda_codec_resume_amp(codec);
snd_hda_codec_resume_cache(codec);
return 0;
}
-#else
-#define store_pin_configs(codec)
#endif
/*
@@ -3559,7 +3577,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
- SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
+ SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
@@ -3602,7 +3620,8 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
- SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
+ /* default Intel */
+ SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
{}
@@ -3782,7 +3801,7 @@ static struct alc_config_preset alc880_presets[] = {
.input_mux = &alc880_capture_source,
},
[ALC880_UNIWILL_DIG] = {
- .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
+ .mixers = { alc880_asus_mixer },
.init_verbs = { alc880_volume_init_verbs,
alc880_pin_asus_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
@@ -3820,8 +3839,7 @@ static struct alc_config_preset alc880_presets[] = {
.init_hook = alc880_uniwill_p53_hp_automute,
},
[ALC880_FUJITSU] = {
- .mixers = { alc880_fujitsu_mixer,
- alc880_pcbeep_mixer, },
+ .mixers = { alc880_fujitsu_mixer },
.init_verbs = { alc880_volume_init_verbs,
alc880_uniwill_p53_init_verbs,
alc880_beep_init_verbs },
@@ -4114,7 +4132,7 @@ static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
const struct auto_pin_cfg *cfg)
{
- struct hda_input_mux *imux = &spec->private_imux;
+ struct hda_input_mux *imux = &spec->private_imux[0];
int i, err, idx;
for (i = 0; i < AUTO_PIN_LAST; i++) {
@@ -4202,11 +4220,9 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
for (i = 0; i < AUTO_PIN_LAST; i++) {
hda_nid_t nid = spec->autocfg.input_pins[i];
if (alc880_is_input_pin(nid)) {
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- i <= AUTO_PIN_FRONT_MIC ?
- PIN_VREF80 : PIN_IN);
- if (nid != ALC880_PIN_CD_NID)
+ alc_set_input_pin(codec, nid, i);
+ if (nid != ALC880_PIN_CD_NID &&
+ (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_AMP_GAIN_MUTE,
AMP_OUT_MUTE);
@@ -4221,7 +4237,7 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
static int alc880_parse_auto_config(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- int err;
+ int i, err;
static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -4252,8 +4268,23 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
- if (spec->autocfg.dig_out_pin)
- spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
+ /* check multiple SPDIF-out (for recent codecs) */
+ for (i = 0; i < spec->autocfg.dig_outs; i++) {
+ hda_nid_t dig_nid;
+ err = snd_hda_get_connections(codec,
+ spec->autocfg.dig_out_pins[i],
+ &dig_nid, 1);
+ if (err < 0)
+ continue;
+ if (!i)
+ spec->multiout.dig_out_nid = dig_nid;
+ else {
+ spec->multiout.slave_dig_outs = spec->slave_dig_outs;
+ spec->slave_dig_outs[i - 1] = dig_nid;
+ if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
+ break;
+ }
+ }
if (spec->autocfg.dig_in_pin)
spec->dig_in_nid = ALC880_DIGIN_NID;
@@ -4263,9 +4294,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
add_verb(spec, alc880_volume_init_verbs);
spec->num_mux_defs = 1;
- spec->input_mux = &spec->private_imux;
+ spec->input_mux = &spec->private_imux[0];
- store_pin_configs(codec);
return 1;
}
@@ -4280,21 +4310,33 @@ static void alc880_auto_init(struct hda_codec *codec)
alc_inithook(codec);
}
-/*
- * OK, here we have finally the patch for ALC880
- */
-
static void set_capture_mixer(struct alc_spec *spec)
{
- static struct snd_kcontrol_new *caps[3] = {
- alc_capture_mixer1,
- alc_capture_mixer2,
- alc_capture_mixer3,
+ static 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 },
};
- if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3)
- spec->cap_mixer = caps[spec->num_adc_nids - 1];
+ if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
+ int mux;
+ if (spec->input_mux && spec->input_mux->num_items > 1)
+ mux = 1;
+ else
+ mux = 0;
+ spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
+ }
}
+#define set_beep_amp(spec, nid, idx, dir) \
+ ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
+
+/*
+ * OK, here we have finally the patch for ALC880
+ */
+
static int patch_alc880(struct hda_codec *codec)
{
struct alc_spec *spec;
@@ -4330,6 +4372,12 @@ static int patch_alc880(struct hda_codec *codec)
}
}
+ err = snd_hda_attach_beep_device(codec, 0x1);
+ if (err < 0) {
+ alc_free(codec);
+ return err;
+ }
+
if (board_config != ALC880_AUTO)
setup_preset(spec, &alc880_presets[board_config]);
@@ -4356,6 +4404,7 @@ static int patch_alc880(struct hda_codec *codec)
}
}
set_capture_mixer(spec);
+ set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
spec->vmaster_nid = 0x0c;
@@ -4463,6 +4512,26 @@ static struct hda_input_mux alc260_acer_capture_sources[2] = {
},
},
};
+
+/* Maxdata Favorit 100XS */
+static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
+ {
+ .num_items = 2,
+ .items = {
+ { "Line/Mic", 0x0 },
+ { "CD", 0x4 },
+ },
+ },
+ {
+ .num_items = 3,
+ .items = {
+ { "Line/Mic", 0x0 },
+ { "CD", 0x4 },
+ { "Mixer", 0x5 },
+ },
+ },
+};
+
/*
* This is just place-holder, so there's something for alc_build_pcms to look
* at when it calculates the maximum number of channels. ALC260 has no mixer
@@ -4505,12 +4574,6 @@ static struct snd_kcontrol_new alc260_input_mixer[] = {
{ } /* end */
};
-static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
- HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
- { } /* end */
-};
-
/* update HP, line and mono out pins according to the master switch */
static void alc260_hp_master_update(struct hda_codec *codec,
hda_nid_t hp, hda_nid_t line,
@@ -4702,8 +4765,6 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
- HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
{ } /* end */
@@ -4748,8 +4809,18 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = {
HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
- HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
+ { } /* end */
+};
+
+/* Maxdata Favorit 100XS: one output and one input (0x12) jack
+ */
+static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
+ ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
+ HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
+ ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
{ } /* end */
};
@@ -4767,8 +4838,6 @@ static struct snd_kcontrol_new alc260_will_mixer[] = {
ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
{ } /* end */
};
@@ -5126,6 +5195,89 @@ static struct hda_verb alc260_acer_init_verbs[] = {
{ }
};
+/* Initialisation sequence for Maxdata Favorit 100XS
+ * (adapted from Acer init verbs).
+ */
+static struct hda_verb alc260_favorit100_init_verbs[] = {
+ /* GPIO 0 enables the output jack.
+ * Turn this on and rely on the standard mute
+ * methods whenever the user wants to turn these outputs off.
+ */
+ {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
+ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
+ {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
+ /* Line/Mic input jack is connected to Mic1 pin */
+ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
+ /* Ensure all other unused pins are disabled and muted. */
+ {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+ {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ /* Disable digital (SPDIF) pins */
+ {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
+ {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
+
+ /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
+ * bus when acting as outputs.
+ */
+ {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
+ {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
+
+ /* Start with output sum widgets muted and their output gains at min */
+ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+ {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+
+ /* Unmute Line-out pin widget amp left and right
+ * (no equiv mixer ctrl)
+ */
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ /* Unmute Mic1 and Line1 pin widget input buffers since they start as
+ * inputs. If the pin mode is changed by the user the pin mode control
+ * will take care of enabling the pin's input/output buffers as needed.
+ * Therefore there's no need to enable the input buffer at this
+ * stage.
+ */
+ {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+ /* Mute capture amp left and right */
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ /* Set ADC connection select to match default mixer setting - mic
+ * (on mic1 pin)
+ */
+ {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+ /* Do similar with the second ADC: mute capture input amp and
+ * set ADC connection to mic to match ALSA's default state.
+ */
+ {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+ /* Mute all inputs to mixer widget (even unconnected ones) */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
+
+ { }
+};
+
static struct hda_verb alc260_will_verbs[] = {
{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -5272,8 +5424,6 @@ static struct snd_kcontrol_new alc260_test_mixer[] = {
HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
@@ -5471,7 +5621,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
const struct auto_pin_cfg *cfg)
{
- struct hda_input_mux *imux = &spec->private_imux;
+ struct hda_input_mux *imux = &spec->private_imux[0];
int i, err, idx;
for (i = 0; i < AUTO_PIN_LAST; i++) {
@@ -5546,11 +5696,9 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
for (i = 0; i < AUTO_PIN_LAST; i++) {
hda_nid_t nid = spec->autocfg.input_pins[i];
if (nid >= 0x12) {
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- i <= AUTO_PIN_FRONT_MIC ?
- PIN_VREF80 : PIN_IN);
- if (nid != ALC260_PIN_CD_NID)
+ alc_set_input_pin(codec, nid, i);
+ if (nid != ALC260_PIN_CD_NID &&
+ (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_AMP_GAIN_MUTE,
AMP_OUT_MUTE);
@@ -5623,7 +5771,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
spec->multiout.max_channels = 2;
- if (spec->autocfg.dig_out_pin)
+ if (spec->autocfg.dig_outs)
spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
if (spec->kctls.list)
add_mixer(spec, spec->kctls.list);
@@ -5631,9 +5779,8 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
add_verb(spec, alc260_volume_init_verbs);
spec->num_mux_defs = 1;
- spec->input_mux = &spec->private_imux;
+ spec->input_mux = &spec->private_imux[0];
- store_pin_configs(codec);
return 1;
}
@@ -5670,6 +5817,7 @@ static const char *alc260_models[ALC260_MODEL_LAST] = {
[ALC260_ACER] = "acer",
[ALC260_WILL] = "will",
[ALC260_REPLACER_672V] = "replacer",
+ [ALC260_FAVORIT100] = "favorit100",
#ifdef CONFIG_SND_DEBUG
[ALC260_TEST] = "test",
#endif
@@ -5679,6 +5827,7 @@ static const char *alc260_models[ALC260_MODEL_LAST] = {
static struct snd_pci_quirk alc260_cfg_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
+ SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
@@ -5701,8 +5850,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
static struct alc_config_preset alc260_presets[] = {
[ALC260_BASIC] = {
.mixers = { alc260_base_output_mixer,
- alc260_input_mixer,
- alc260_pc_beep_mixer },
+ alc260_input_mixer },
.init_verbs = { alc260_init_verbs },
.num_dacs = ARRAY_SIZE(alc260_dac_nids),
.dac_nids = alc260_dac_nids,
@@ -5781,6 +5929,18 @@ static struct alc_config_preset alc260_presets[] = {
.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
.input_mux = alc260_acer_capture_sources,
},
+ [ALC260_FAVORIT100] = {
+ .mixers = { alc260_favorit100_mixer },
+ .init_verbs = { alc260_favorit100_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc260_dac_nids),
+ .dac_nids = alc260_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
+ .adc_nids = alc260_dual_adc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc260_modes),
+ .channel_mode = alc260_modes,
+ .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
+ .input_mux = alc260_favorit100_capture_sources,
+ },
[ALC260_WILL] = {
.mixers = { alc260_will_mixer },
.init_verbs = { alc260_init_verbs, alc260_will_verbs },
@@ -5857,6 +6017,12 @@ static int patch_alc260(struct hda_codec *codec)
}
}
+ err = snd_hda_attach_beep_device(codec, 0x1);
+ if (err < 0) {
+ alc_free(codec);
+ return err;
+ }
+
if (board_config != ALC260_AUTO)
setup_preset(spec, &alc260_presets[board_config]);
@@ -5882,6 +6048,7 @@ static int patch_alc260(struct hda_codec *codec)
}
}
set_capture_mixer(spec);
+ set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
spec->vmaster_nid = 0x08;
@@ -6053,8 +6220,6 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
{ } /* end */
};
@@ -6081,8 +6246,6 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
{ } /* end */
};
@@ -6134,8 +6297,6 @@ static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
{ } /* end */
};
@@ -6244,8 +6405,10 @@ static struct snd_kcontrol_new alc882_macpro_mixer[] = {
HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
+ /* FIXME: this looks suspicious...
HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
+ */
{ } /* end */
};
@@ -6877,19 +7040,9 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec)
for (i = 0; i < AUTO_PIN_LAST; i++) {
hda_nid_t nid = spec->autocfg.input_pins[i];
- unsigned int vref;
if (!nid)
continue;
- vref = PIN_IN;
- if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
- unsigned int pincap;
- pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
- if ((pincap >> AC_PINCAP_VREF_SHIFT) &
- AC_PINCAP_VREF_80)
- vref = PIN_VREF80;
- }
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
+ alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_AMP_GAIN_MUTE,
@@ -6900,18 +7053,21 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec)
static void alc882_auto_init_input_src(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- const struct hda_input_mux *imux = spec->input_mux;
int c;
for (c = 0; c < spec->num_adc_nids; c++) {
hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
hda_nid_t nid = spec->capsrc_nids[c];
+ unsigned int mux_idx;
+ const struct hda_input_mux *imux;
int conns, mute, idx, item;