aboutsummaryrefslogtreecommitdiffstats
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.c680
1 files changed, 446 insertions, 234 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index ed8fcbd6000..169b3837af5 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
@@ -103,6 +104,7 @@ enum {
ALC262_NEC,
ALC262_TOSHIBA_S06,
ALC262_TOSHIBA_RX1,
+ ALC262_TYAN,
ALC262_AUTO,
ALC262_MODEL_LAST /* last tag */
};
@@ -238,6 +240,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 +255,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 +279,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 +305,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 +317,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
@@ -336,6 +351,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 +408,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;
@@ -810,6 +827,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 +939,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 */
@@ -1375,8 +1393,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 +1499,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,
@@ -1706,8 +1720,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 +1896,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 +1928,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 +2002,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 +2030,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 +2044,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 +2070,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 +2980,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 +3071,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 +3099,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 +3125,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 +3150,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,7 +3211,7 @@ 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
@@ -3559,7 +3608,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 +3651,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 +3832,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 +3870,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 +4163,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++) {
@@ -4221,7 +4270,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 +4301,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,7 +4327,7 @@ 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,10 +4344,6 @@ 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] = {
@@ -4295,6 +4355,13 @@ static void set_capture_mixer(struct alc_spec *spec)
spec->cap_mixer = caps[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 +4397,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 +4429,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;
@@ -4505,12 +4579,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 +4770,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 +4814,6 @@ 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 */
};
@@ -4767,8 +4831,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 */
};
@@ -5272,8 +5334,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 +5531,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++) {
@@ -5623,7 +5683,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,7 +5691,7 @@ 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;
@@ -5701,8 +5761,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,
@@ -5857,6 +5916,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 +5947,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 +6119,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 +6145,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 +6196,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 +6304,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 */
};
@@ -6900,18 +6962,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;
conns = snd_hda_get_connections(codec, nid, conn_list,
ARRAY_SIZE(conn_list));
if (conns < 0)
continue;
+ mux_idx = c >= spec->num_mux_defs ? 0 : c;
+ imux = &spec->input_mux[mux_idx];
for (idx = 0; idx < conns; idx++) {
/* if the current connection is the selected one,
* unmute it as default - otherwise mute it
@@ -6924,8 +6989,20 @@ static void alc882_auto_init_input_src(struct hda_codec *codec)
break;
}
}
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE, mute);
+ /* check if we have a selector or mixer
+ * we could check for the widget type instead, but
+ * just check for Amp-In presence (in case of mixer
+ * without amp-in there is something wrong, this
+ * function shouldn't be used or capsrc nid is wrong)
+ */
+ if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
+ mute);
+ else if (mute != AMP_IN_MUTE(idx))
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_CONNECT_SEL,
+ idx);
}
}
}
@@ -7053,6 +7130,12 @@ static int patch_alc882(struct hda_codec *codec)
}
}
+ err = snd_hda_attach_beep_device(codec, 0x1);
+ if (err < 0) {
+ alc_free(codec);
+ return err;
+ }
+
if (board_config != ALC882_AUTO)
setup_preset(spec, &alc882_presets[board_config]);
@@ -7073,7 +7156,7 @@ static int patch_alc882(struct hda_codec *codec)
spec->stream_digital_playback = &alc882_pcm_digital_playback;
spec->stream_digital_capture = &alc882_pcm_digital_capture;
- spec->is_mix_capture = 1; /* matrix-style capture */
+ spec->capture_style = CAPT_MIX; /* matrix-style capture */
if (!spec->adc_nids && spec->input_mux) {
/* check whether NID 0x07 is valid */
unsigned int wcap = get_wcaps(codec, 0x07);
@@ -7090,6 +7173,7 @@ static int patch_alc882(struct hda_codec *codec)
}
}
set_capture_mixer(spec);
+ set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
spec->vmaster_nid = 0x0c;
@@ -7141,10 +7225,14 @@ static hda_nid_t alc883_adc_nids_rev[2] = {
0x09, 0x08
};
+#define alc889_adc_nids alc880_adc_nids
+
static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
+#define alc889_capsrc_nids alc882_capsrc_nids
+
/* input MUX */
/* FIXME: should be a matrix-type input source selection */
@@ -7362,8 +7450,6 @@ static struct snd_kcontrol_new alc883_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 */
};
@@ -7426,8 +7512,6 @@ static struct snd_kcontrol_new alc883_3ST_2ch_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 */
};
@@ -7451,8 +7535,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_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 */
};
@@ -7477,8 +7559,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_MUTE("Front 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 */
};
@@ -7502,8 +7582,6 @@ static struct snd_kcontrol_new alc883_fivestack_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 */
};
@@ -8201,7 +8279,7 @@ static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
{
switch (res >> 26) {
case ALC880_HP_EVENT:
- printk("hp_event\n");
+ /* printk(KERN_DEBUG "hp_event\n"); */
alc888_6st_dell_front_automute(codec);
break;
}
@@ -8467,9 +8545,12 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
ALC888_ACER_ASPIRE_4930G),
SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
ALC888_ACER_ASPIRE_4930G),
+ SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
+ SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
ALC888_ACER_ASPIRE_4930G),
- SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
+ /* default Acer */
+ SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER),
SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
@@ -8515,7 +8596,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
- SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
+ SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550",
@@ -8540,6 +8621,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
{}
};
+static hda_nid_t alc1200_slave_dig_outs[] = {
+ ALC883_DIGOUT_NID, 0,
+};
+
static struct alc_config_preset alc883_presets[] = {
[ALC883_3ST_2ch_DIG] = {
.mixers = { alc883_3ST_2ch_mixer },
@@ -8880,6 +8965,7 @@ static struct alc_config_preset alc883_presets[] = {
.dac_nids = alc883_dac_nids,
.dig_out_nid = ALC1200_DIGOUT_NID,
.dig_in_nid = ALC883_DIGIN_NID,
+ .slave_dig_outs = alc1200_slave_dig_outs,
.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
.channel_mode = alc883_sixstack_modes,
.input_mux = &alc883_capture_source,
@@ -8966,6 +9052,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
int err = alc880_parse_auto_config(codec);
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ int i;
if (err < 0)
return err;
@@ -8979,6 +9067,26 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
/* hack - override the init verbs */
spec->init_verbs[0] = alc883_auto_init_verbs;
+ /* setup input_mux for ALC889 */
+ if (codec->vendor_id == 0x10ec0889) {
+ /* digital-mic input pin is excluded in alc880_auto_create..()
+ * because it's under 0x18
+ */
+ if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
+ cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
+ struct hda_input_mux *imux = &spec->private_imux[0];
+ for (i = 1; i < 3; i++)
+ memcpy(&spec->private_imux[i],
+ &spec->private_imux[0],
+ sizeof(spec->private_imux[0]));
+ imux->items[imux->num_items].label = "Int DMic";
+ imux->items[imux->num_items].index = 0x0b;
+ imux->num_items++;
+ spec->num_mux_defs = 3;
+ spec->input_mux = spec->private_imux;
+ }
+ }
+
return 1; /* config found */
}
@@ -9030,6 +9138,12 @@ static int patch_alc883(struct hda_codec *codec)
}
}
+ err = snd_hda_attach_beep_device(codec, 0x1);
+ if (err < 0) {
+ alc_free(codec);
+ return err;
+ }
+
if (board_config != ALC883_AUTO)
setup_preset(spec, &alc883_presets[board_config]);
@@ -9042,14 +9156,36 @@ static int patch_alc883(struct hda_codec *codec)
spec->stream_name_analog = "ALC888 Analog";
spec->stream_name_digital = "ALC888 Digital";
}
+ if (!spec->num_adc_nids) {
+ spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
+ spec->adc_nids = alc883_adc_nids;
+ }
+ if (!spec->capsrc_nids)
+ spec->capsrc_nids = alc883_capsrc_nids;
+ spec->capture_style = CAPT_MIX; /* matrix-style capture */
break;
case 0x10ec0889:
spec->stream_name_analog = "ALC889 Analog";
spec->stream_name_digital = "ALC889 Digital";
+ if (!spec->num_adc_nids) {
+ spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
+ spec->adc_nids = alc889_adc_nids;
+ }
+ if (!spec->capsrc_nids)
+ spec->capsrc_nids = alc889_capsrc_nids;
+ spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
+ capture */
break;
default:
spec->stream_name_analog = "ALC883 Analog";
spec->stream_name_digital = "ALC883 Digital";
+ if (!spec->num_adc_nids) {
+ spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
+ spec->adc_nids = alc883_adc_nids;
+ }
+ if (!spec->capsrc_nids)
+ spec->capsrc_nids = alc883_capsrc_nids;
+ spec->capture_style = CAPT_MIX; /* matrix-style capture */
break;
}
@@ -9060,15 +9196,9 @@ static int patch_alc883(struct hda_codec *codec)
spec->stream_digital_playback = &alc883_pcm_digital_playback;
spec->stream_digital_capture = &alc883_pcm_digital_capture;
- if (!spec->num_adc_nids) {
- spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
- spec->adc_nids = alc883_adc_nids;
- }
- if (!spec->capsrc_nids)
- spec->capsrc_nids = alc883_capsrc_nids;
- spec->is_mix_capture = 1; /* matrix-style capture */
if (!spec->cap_mixer)
set_capture_mixer(spec);
+ set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
spec->vmaster_nid = 0x0c;
@@ -9121,8 +9251,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
- /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
@@ -9143,8 +9271,6 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
- /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
{ } /* end */
@@ -9253,8 +9379,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
{ } /* end */
@@ -9283,8 +9407,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
{ } /* end */
};
@@ -9432,6 +9554,67 @@ static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc262_tyan_mixer[] = {
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
+ HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
+ { } /* end */
+};
+
+static struct hda_verb alc262_tyan_verbs[] = {
+ /* Headphone automute */
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+ /* P11 AUX_IN, white 4-pin connector */
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
+ {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
+ {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
+
+ {}
+};
+
+/* unsolicited event for HP jack sensing */
+static void alc262_tyan_automute(struct hda_codec *codec)
+{
+ unsigned int mute;
+ unsigned int present;
+
+ snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
+ present = snd_hda_codec_read(codec, 0x1b, 0,
+ AC_VERB_GET_PIN_SENSE, 0);
+ present = (present & 0x80000000) != 0;
+ if (present) {
+ /* mute line output on ATX panel */
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
+ } else {
+ /* unmute line output if necessary */
+ mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+ }
+}
+
+static void alc262_tyan_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) != ALC880_HP_EVENT)
+ return;
+ alc262_tyan_automute(codec);
+}
+
#define alc262_capture_mixer alc882_capture_mixer
#define alc262_capture_alt_mixer alc882_capture_alt_mixer
@@ -9898,8 +10081,6 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
},
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
@@ -10471,8 +10652,14 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
alc262_ignore);
if (err < 0)
return err;
- if (!spec->autocfg.line_outs)
+ if (!spec->autocfg.line_outs) {
+ if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
+ spec->multiout.max_channels = 2;
+ spec->no_analog = 1;
+ goto dig_only;
+ }
return 0; /* can't find valid BIOS pin config */
+ }
err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
if (err < 0)
return err;
@@ -10482,8 +10669,11 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
- if (spec->autocfg.dig_out_pin)
+ dig_only:
+ if (spec->autocfg.dig_outs) {
spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
+ spec->dig_out_type = spec->autocfg.dig_out_type[0];
+ }
if (spec->autocfg.dig_in_pin)
spec->dig_in_nid = ALC262_DIGIN_NID;
@@ -10492,7 +10682,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
add_verb(spec, alc262_volume_init_verbs);
spec->num_mux_defs = 1;
- spec->input_mux = &spec->private_imux;
+ spec->input_mux = &spec->private_imux[0];
err = alc_auto_add_mic_boost(codec);
if (err < 0)
@@ -10540,20 +10730,17 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
[ALC262_ULTRA] = "ultra",
[ALC262_LENOVO_3000] = "lenovo-3000",
[ALC262_NEC] = "nec",
+ [ALC262_TYAN] = "tyan",
[ALC262_AUTO] = "auto",
};
static struct snd_pci_quirk alc262_cfg_tbl[] = {
SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
- SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
- SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
- SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
- SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
- SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
- SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
- SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
- SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
+ SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
+ ALC262_HP_BPC),
+ SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
+ ALC262_HP_BPC),
SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
@@ -10580,8 +10767,9 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
- SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
- SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
+ SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
+ SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
+ ALC262_ULTRA),
SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
@@ -10798,6 +10986,19 @@ static struct alc_config_preset alc262_presets[] = {
.unsol_event = alc262_hippo_unsol_event,
.init_hook = alc262_hippo_automute,
},
+ [ALC262_TYAN] = {
+ .mixers = { alc262_tyan_mixer },
+ .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
+ .num_dacs = ARRAY_SIZE(alc262_dac_nids),
+ .dac_nids = alc262_dac_nids,
+ .hp_nid = 0x02,
+ .dig_out_nid = ALC262_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc262_modes),
+ .channel_mode = alc262_modes,
+ .input_mux = &alc262_capture_source,
+ .unsol_event = alc262_tyan_unsol_event,
+ .init_hook = alc262_tyan_automute,
+ },
};
static int patch_alc262(struct hda_codec *codec)
@@ -10850,6 +11051,14 @@ static int patch_alc262(struct hda_codec *codec)
}
}
+ if (!spec->no_analog) {
+ err = snd_hda_attach_beep_device(codec, 0x1);
+ if (err < 0) {
+ alc_free(codec);
+ return err;
+ }
+ }
+
if (board_config != ALC262_AUTO)
setup_preset(spec, &alc262_presets[board_config]);
@@ -10861,7 +11070,7 @@ static int patch_alc262(struct hda_codec *codec)
spec->stream_digital_playback = &alc262_pcm_digital_playback;
spec->stream_digital_capture = &alc262_pcm_digital_capture;
- spec->is_mix_capture = 1;
+ spec->capture_style = CAPT_MIX;
if (!spec->adc_nids && spec->input_mux) {
/* check whether NID 0x07 is valid */
unsigned int wcap = get_wcaps(codec, 0x07);
@@ -10878,8 +11087,10 @@ static int patch_alc262(struct hda_codec *codec)
spec->capsrc_nids = alc262_capsrc_nids;
}
}
- if (!spec->cap_mixer)
+ if (!spec->cap_mixer && !spec->no_analog)
set_capture_mixer(spec);
+ if (!spec->no_analog)
+ set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
spec->vmaster_nid = 0x0c;
@@ -11259,19 +11470,13 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
static struct hda_verb alc268_base_init_verbs[] = {
/* Unmute DAC0-1 and set vol = 0 */
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
/*
* Set up output mixers (0x0c - 0x0e)
*/
/* set vol=0 to output mixers */
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -11290,9 +11495,7 @@ static struct hda_verb alc268_base_init_verbs[] = {
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
/* set PCBEEP vol = 0, mute connections */
{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -11314,10 +11517,8 @@ static struct hda_verb alc268_base_init_verbs[] = {
*/
static struct hda_verb alc268_volume_init_verbs[] = {
/* set output DAC */
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
@@ -11325,16 +11526,12 @@ static struct hda_verb alc268_volume_init_verbs[] = {
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
- {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
/* set PCBEEP vol = 0, mute connections */
{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -11533,7 +11730,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
static int alc268_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, idx1;
for (i = 0; i < AUTO_PIN_LAST; i++) {
@@ -11627,9 +11824,14 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
alc268_ignore);
if (err < 0)
return err;
- if (!spec->autocfg.line_outs)
+ if (!spec->autocfg.line_outs) {
+ if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
+ spec->multiout.max_channels = 2;
+ spec->no_analog = 1;
+ goto dig_only;
+ }
return 0; /* can't find valid BIOS pin config */
-
+ }
err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
if (err < 0)
return err;
@@ -11639,10 +11841,12 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
spec->multiout.max_channels = 2;
+ dig_only:
/* digital only support output */
- if (spec->autocfg.dig_out_pin)
+ if (spec->autocfg.dig_outs) {
spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
-
+ spec->dig_out_type = spec->autocfg.dig_out_type[0];
+ }
if (spec->kctls.list)
add_mixer(spec, spec->kctls.list);
@@ -11651,7 +11855,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
add_verb(spec, alc268_volume_init_verbs);
spec->num_mux_defs = 1;
- spec->input_mux = &spec->private_imux;
+ spec->input_mux = &spec->private_imux[0];
err = alc_auto_add_mic_boost(codec);
if (err < 0)
@@ -11719,7 +11923,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
static struct alc_config_preset alc268_presets[] = {
[ALC267_QUANTA_IL1] = {
- .mixers = { alc267_quanta_il1_mixer },
+ .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc267_quanta_il1_verbs },
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
@@ -11801,7 +12005,8 @@ static struct alc_config_preset alc268_presets[] = {
},
[ALC268_ACER_ASPIRE_ONE] = {
.mixers = { alc268_acer_aspire_one_mixer,
- alc268_capture_alt_mixer },
+ alc268_beep_mixer,
+ alc268_capture_alt_mixer },
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_acer_aspire_one_verbs },
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
@@ -11870,7 +12075,7 @@ static int patch_alc268(struct hda_codec *codec)
{
struct alc_spec *spec;
int board_config;
- int err;
+ int i, has_beep, err;
spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
@@ -11919,15 +12124,30 @@ static int patch_alc268(struct hda_codec *codec)
spec->stream_digital_playback = &alc268_pcm_digital_playback;
- if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
- /* override the amp caps for beep generator */
- snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
+ has_beep = 0;
+ for (i = 0; i < spec->num_mixers; i++) {
+ if (spec->mixers[i] == alc268_beep_mixer) {
+ has_beep = 1;
+ break;
+ }
+ }
+
+ if (has_beep) {
+ err = snd_hda_attach_beep_device(codec, 0x1);
+ if (err < 0) {
+ alc_free(codec);
+ return err;
+ }
+ 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));
+ }
- if (!spec->adc_nids && spec->input_mux) {
+ if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
/* check whether NID 0x07 is valid */
unsigned int wcap = get_wcaps(codec, 0x07);
int i;
@@ -12008,8 +12228,6 @@ static struct snd_kcontrol_new alc269_base_mixer[] = {
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
- HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
@@ -12036,8 +12254,6 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
{ }
};
@@ -12061,8 +12277,6 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
{ }
};
@@ -12099,13 +12313,6 @@ static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
{ } /* end */
};
-/* beep control */
-static struct snd_kcontrol_new alc269_beep_mixer[] = {
- HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
- HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
- { } /* end */
-};
-
static struct hda_verb alc269_quanta_fl1_verbs[] = {
{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -12505,7 +12712,7 @@ static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
*/
if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
- struct hda_input_mux *imux = &spec->private_imux;
+ struct hda_input_mux *imux = &spec->private_imux[0];
imux->items[imux->num_items].label = "Int Mic";
imux->items[imux->num_items].index = 0x05;
imux->num_items++;
@@ -12529,7 +12736,7 @@ static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
static int alc269_parse_auto_config(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- int i, err;
+ int err;
static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -12546,22 +12753,15 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
- if (spec->autocfg.dig_out_pin)
+ if (spec->autocfg.dig_outs)
spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
if (spec->kctls.list)
add_mixer(spec, spec->kctls.list);
- /* create a beep mixer control if the pin 0x1d isn't assigned */
- for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
- if (spec->autocfg.input_pins[i] == 0x1d)
- break;
- if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
- add_mixer(spec, alc269_beep_mixer);
-
add_verb(spec, alc269_init_verbs);
spec->num_mux_defs = 1;
- spec->input_mux = &spec->private_imux;
+ spec->input_mux = &spec->private_imux[0];
/* set default input source */
snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
0, AC_VERB_SET_CONNECT_SEL,
@@ -12571,7 +12771,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
if (err < 0)
return err;
- if (!spec->cap_mixer)
+ if (!spec->cap_mixer && !spec->no_analog)
set_capture_mixer(spec);
store_pin_configs(codec);
@@ -12671,7 +12871,7 @@ static struct alc_config_preset alc269_presets[] = {
.init_hook = alc269_eeepc_dmic_inithook,
},
[ALC269_FUJITSU] = {
- .mixers = { alc269_fujitsu_mixer, alc269_beep_mixer },
+ .mixers = { alc269_fujitsu_mixer },
.cap_mixer = alc269_epc_capture_mixer,
.init_verbs = { alc269_init_verbs,
alc269_eeepc_dmic_init_verbs },
@@ -12736,6 +12936,12 @@ static int patch_alc269(struct hda_codec *codec)
}
}
+ err = snd_hda_attach_beep_device(codec, 0x1);
+ if (err < 0) {
+ alc_free(codec);
+ return err;
+ }
+
if (board_config != ALC269_AUTO)
setup_preset(spec, &alc269_presets[board_config]);
@@ -12752,6 +12958,7 @@ static int patch_alc269(struct hda_codec *codec)
spec->capsrc_nids = alc269_capsrc_nids;
if (!spec->cap_mixer)
set_capture_mixer(spec);
+ set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
codec->patch_ops = alc_patch_ops;
if (board_config == ALC269_AUTO)
@@ -13002,8 +13209,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
{ }
};
@@ -13477,7 +13682,7 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
static int alc861_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, idx1;
for (i = 0; i < AUTO_PIN_LAST; i++) {
@@ -13605,7 +13810,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
- if (spec->autocfg.dig_out_pin)
+ if (spec->autocfg.dig_outs)
spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
if (spec->kctls.list)
@@ -13614,7 +13819,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
add_verb(spec, alc861_auto_init_verbs);
spec->num_mux_defs = 1;
- spec->input_mux = &spec->private_imux;
+ spec->input_mux = &spec->private_imux[0];
spec->adc_nids = alc861_adc_nids;
spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
@@ -13829,6 +14034,12 @@ static int patch_alc861(struct hda_codec *codec)
}
}
+ err = snd_hda_attach_beep_device(codec, 0x23);
+ if (err < 0) {
+ alc_free(codec);
+ return err;
+ }
+
if (board_config != ALC861_AUTO)
setup_preset(spec, &alc861_presets[board_config]);
@@ -13840,6 +14051,8 @@ static int patch_alc861(struct hda_codec *codec)
spec->stream_digital_playback = &alc861_pcm_digital_playback;
spec->stream_digital_capture = &alc861_pcm_digital_capture;
+ set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
+
spec->vmaster_nid = 0x03;
codec->patch_ops = alc_patch_ops;
@@ -13996,9 +14209,6 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, 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 */
};
@@ -14022,9 +14232,6 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, 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 */
};
@@ -14063,8 +14270,6 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
{ } /* end */
};
@@ -14375,9 +14580,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
- SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
- SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
- SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
+ SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
{}
};
@@ -14709,7 +14912,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
- if (spec->autocfg.dig_out_pin)
+ if (spec->autocfg.dig_outs)
spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
if (spec->kctls.list)
@@ -14718,7 +14921,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
add_verb(spec, alc861vd_volume_init_verbs);
spec->num_mux_defs = 1;
- spec->input_mux = &spec->private_imux;
+ spec->input_mux = &spec->private_imux[0];
err = alc_auto_add_mic_boost(codec);
if (err < 0)
@@ -14775,6 +14978,12 @@ static int patch_alc861vd(struct hda_codec *codec)
}
}
+ err = snd_hda_attach_beep_device(codec, 0x23);
+ if (err < 0) {
+ alc_free(codec);
+ return err;
+ }
+
if (board_config != ALC861VD_AUTO)
setup_preset(spec, &alc861vd_presets[board_config]);
@@ -14797,9 +15006,10 @@ static int patch_alc861vd(struct hda_codec *codec)
spec->adc_nids = alc861vd_adc_nids;
spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
spec->capsrc_nids = alc861vd_capsrc_nids;
- spec->is_mix_capture = 1;
+ spec->capture_style = CAPT_MIX;
set_capture_mixer(spec);
+ set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
spec->vmaster_nid = 0x02;
@@ -14988,8 +15198,6 @@ static struct snd_kcontrol_new alc662_3ST_2ch_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),
{ } /* end */
};
@@ -15011,8 +15219,6 @@ static struct snd_kcontrol_new alc662_3ST_6ch_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),
{ } /* end */
};
@@ -15988,56 +16194,55 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
};
static struct snd_pci_quirk alc662_cfg_tbl[] = {
- SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
- SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
- SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
- SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
- SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
- SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
+ SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
+ SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
+ SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
+ SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
+ SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
+ /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
- SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
- SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
- SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
+ SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
+ SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
+ /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
+ SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
- SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
- SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
- SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
- SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
+ SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
+ SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
+ SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
+ SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
ALC662_3ST_6ch_DIG),
- SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
- SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
- SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
ALC662_3ST_6ch_DIG),
SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
+ SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
ALC662_3ST_6ch_DIG),
- SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
- SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
- SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
+ SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
+ ALC663_ASUS_H13),
{}
};
@@ -16357,7 +16562,7 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
if (alc880_is_fixed_pin(pin)) {
nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
- /* printk("DAC nid=%x\n",nid); */
+ /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
/* specify the DAC as the extra output */
if (!spec->multiout.hp_nid)
spec->multiout.hp_nid = nid;
@@ -16391,7 +16596,7 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
static int alc662_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++) {
@@ -16515,14 +16720,14 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
- if (spec->autocfg.dig_out_pin)
+ if (spec->autocfg.dig_outs)
spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
if (spec->kctls.list)
add_mixer(spec, spec->kctls.list);
spec->num_mux_defs = 1;
- spec->input_mux = &spec->private_imux;
+ spec->input_mux = &spec->private_imux[0];
add_verb(spec, alc662_auto_init_verbs);
if (codec->vendor_id == 0x10ec0663)
@@ -16584,6 +16789,12 @@ static int patch_alc662(struct hda_codec *codec)
}
}
+ err = snd_hda_attach_beep_device(codec, 0x1);
+ if (err < 0) {
+ alc_free(codec);
+ return err;
+ }
+
if (board_config != ALC662_AUTO)
setup_preset(spec, &alc662_presets[board_config]);
@@ -16607,10 +16818,11 @@ static int patch_alc662(struct hda_codec *codec)
spec->adc_nids = alc662_adc_nids;
spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
spec->capsrc_nids = alc662_capsrc_nids;
- spec->is_mix_capture = 1;
+ spec->capture_style = CAPT_MIX;
if (!spec->cap_mixer)
set_capture_mixer(spec);
+ set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
spec->vmaster_nid = 0x02;