mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 09:19:51 +00:00
[ALSA] hda-codec - Add new modesl for Realtek codecs
Changes from Realtek driver: - New models hippo and hippo_1 for ALC262 - New models tagra-dig and tagra-2ch-dig for ALC883 - New id for ALC660 codec chip Signed-off-by: Kailang Yang <kailang@realtek.com.tw> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
This commit is contained in:
parent
a53d1aece3
commit
ccc656ce5f
2 changed files with 534 additions and 6 deletions
|
@ -801,6 +801,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
fujitsu Fujitsu Laptop
|
||||
hp-bpc HP xw4400/6400/8400/9400 laptops
|
||||
benq Benq ED8
|
||||
hippo Hippo (ATI) with jack detection
|
||||
hippo_1 Hippo (Benq) with jack detection
|
||||
basic fixed pin assignment w/o SPDIF
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
|
@ -818,6 +820,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
6stack-dig-demo 6-jack digital for Intel demo board
|
||||
acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
|
||||
medion Medion Laptops
|
||||
targa-dig Targa/MSI
|
||||
targa-2ch-dig Targs/MSI with 2-channel
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC861/660
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
#include "hda_codec.h"
|
||||
#include "hda_local.h"
|
||||
|
||||
#define ALC880_FRONT_EVENT 0x01
|
||||
#define ALC880_DCVOL_EVENT 0x02
|
||||
#define ALC880_HP_EVENT 0x04
|
||||
#define ALC880_MIC_EVENT 0x08
|
||||
|
||||
/* ALC880 board config type */
|
||||
enum {
|
||||
|
@ -49,6 +53,8 @@ enum {
|
|||
ALC880_ASUS_W1V,
|
||||
ALC880_ASUS_DIG2,
|
||||
ALC880_UNIWILL_DIG,
|
||||
ALC880_UNIWILL,
|
||||
ALC880_UNIWILL_P53,
|
||||
ALC880_CLEVO,
|
||||
ALC880_TCL_S700,
|
||||
ALC880_LG,
|
||||
|
@ -77,6 +83,8 @@ enum {
|
|||
/* ALC262 models */
|
||||
enum {
|
||||
ALC262_BASIC,
|
||||
ALC262_HIPPO,
|
||||
ALC262_HIPPO_1,
|
||||
ALC262_FUJITSU,
|
||||
ALC262_HP_BPC,
|
||||
ALC262_BENQ_ED8,
|
||||
|
@ -111,6 +119,8 @@ enum {
|
|||
ALC883_3ST_6ch_DIG,
|
||||
ALC883_3ST_6ch,
|
||||
ALC883_6ST_DIG,
|
||||
ALC883_TARGA_DIG,
|
||||
ALC883_TARGA_2ch_DIG,
|
||||
ALC888_DEMO_BOARD,
|
||||
ALC883_ACER,
|
||||
ALC883_MEDION,
|
||||
|
@ -1017,6 +1027,46 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
|
|||
{ } /* end */
|
||||
};
|
||||
|
||||
/* Uniwill */
|
||||
static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
|
||||
HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
|
||||
HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
|
||||
HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
|
||||
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
|
||||
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, 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("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("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",
|
||||
.info = alc_ch_mode_info,
|
||||
.get = alc_ch_mode_get,
|
||||
.put = alc_ch_mode_put,
|
||||
},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
|
||||
HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
|
||||
HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
|
||||
HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/*
|
||||
* build control elements
|
||||
*/
|
||||
|
@ -1250,6 +1300,154 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
/*
|
||||
* Uniwill pin configuration:
|
||||
* HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
|
||||
* line = 0x1a
|
||||
*/
|
||||
static struct hda_verb alc880_uniwill_init_verbs[] = {
|
||||
{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
|
||||
|
||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
|
||||
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
|
||||
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
|
||||
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
|
||||
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
|
||||
|
||||
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
|
||||
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
|
||||
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
|
||||
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
|
||||
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
|
||||
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
|
||||
/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
|
||||
/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
|
||||
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
|
||||
|
||||
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
|
||||
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
|
||||
|
||||
{ }
|
||||
};
|
||||
|
||||
/*
|
||||
* Uniwill P53
|
||||
* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
|
||||
*/
|
||||
static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
|
||||
{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
|
||||
|
||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
|
||||
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
|
||||
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
|
||||
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
|
||||
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
|
||||
|
||||
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
|
||||
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
|
||||
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
|
||||
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
|
||||
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
|
||||
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
|
||||
|
||||
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
|
||||
{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
|
||||
|
||||
{ }
|
||||
};
|
||||
|
||||
/* toggle speaker-output according to the hp-jack state */
|
||||
static void alc880_uniwill_automute(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int present;
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x14, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
|
||||
snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x18, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
|
||||
snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
|
||||
}
|
||||
|
||||
static void alc880_uniwill_unsol_event(struct hda_codec *codec,
|
||||
unsigned int res)
|
||||
{
|
||||
/* Looks like the unsol event is incompatible with the standard
|
||||
* definition. 4bit tag is placed at 28 bit!
|
||||
*/
|
||||
if ((res >> 28) == ALC880_HP_EVENT ||
|
||||
(res >> 28) == ALC880_MIC_EVENT)
|
||||
alc880_uniwill_automute(codec);
|
||||
}
|
||||
|
||||
static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int present;
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x14, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
|
||||
|
||||
snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
}
|
||||
|
||||
static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int present;
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x21, 0,
|
||||
AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
|
||||
|
||||
snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
|
||||
0x7f, present);
|
||||
snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
|
||||
0x7f, present);
|
||||
|
||||
snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
|
||||
0x7f, present);
|
||||
snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
|
||||
0x7f, present);
|
||||
|
||||
}
|
||||
static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
|
||||
unsigned int res)
|
||||
{
|
||||
/* Looks like the unsol event is incompatible with the standard
|
||||
* definition. 4bit tag is placed at 28 bit!
|
||||
*/
|
||||
if ((res >> 28) == ALC880_HP_EVENT)
|
||||
alc880_uniwill_p53_hp_automute(codec);
|
||||
if ((res >> 28) == ALC880_DCVOL_EVENT)
|
||||
alc880_uniwill_p53_dcvol_automute(codec);
|
||||
}
|
||||
|
||||
/* FIXME! */
|
||||
/*
|
||||
* F1734 pin configuration:
|
||||
|
@ -2262,7 +2460,10 @@ static struct hda_board_config alc880_cfg_tbl[] = {
|
|||
{ .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 },
|
||||
|
||||
{ .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
|
||||
{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },
|
||||
{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },
|
||||
{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9070, .config = ALC880_UNIWILL },
|
||||
{ .pci_subvendor = 0x1734, .pci_subdevice = 0x10ac, .config = ALC880_UNIWILL },
|
||||
{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9077, .config = ALC880_UNIWILL_P53 },
|
||||
|
||||
{ .modelname = "F1734", .config = ALC880_F1734 },
|
||||
{ .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 },
|
||||
|
@ -2440,7 +2641,8 @@ static struct alc_config_preset alc880_presets[] = {
|
|||
},
|
||||
[ALC880_UNIWILL_DIG] = {
|
||||
.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
|
||||
.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs },
|
||||
.init_verbs = { alc880_volume_init_verbs,
|
||||
alc880_pin_asus_init_verbs },
|
||||
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
|
||||
.dac_nids = alc880_asus_dac_nids,
|
||||
.dig_out_nid = ALC880_DIGOUT_NID,
|
||||
|
@ -2449,6 +2651,32 @@ static struct alc_config_preset alc880_presets[] = {
|
|||
.need_dac_fix = 1,
|
||||
.input_mux = &alc880_capture_source,
|
||||
},
|
||||
[ALC880_UNIWILL] = {
|
||||
.mixers = { alc880_uniwill_mixer },
|
||||
.init_verbs = { alc880_volume_init_verbs,
|
||||
alc880_uniwill_init_verbs },
|
||||
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
|
||||
.dac_nids = alc880_asus_dac_nids,
|
||||
.dig_out_nid = ALC880_DIGOUT_NID,
|
||||
.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
|
||||
.channel_mode = alc880_threestack_modes,
|
||||
.need_dac_fix = 1,
|
||||
.input_mux = &alc880_capture_source,
|
||||
.unsol_event = alc880_uniwill_unsol_event,
|
||||
.init_hook = alc880_uniwill_automute,
|
||||
},
|
||||
[ALC880_UNIWILL_P53] = {
|
||||
.mixers = { alc880_uniwill_p53_mixer },
|
||||
.init_verbs = { alc880_volume_init_verbs,
|
||||
alc880_uniwill_p53_init_verbs },
|
||||
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
|
||||
.dac_nids = alc880_asus_dac_nids,
|
||||
.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
|
||||
.channel_mode = alc880_w810_modes,
|
||||
.input_mux = &alc880_capture_source,
|
||||
.unsol_event = alc880_uniwill_p53_unsol_event,
|
||||
.init_hook = alc880_uniwill_p53_hp_automute,
|
||||
},
|
||||
[ALC880_CLEVO] = {
|
||||
.mixers = { alc880_three_stack_mixer },
|
||||
.init_verbs = { alc880_volume_init_verbs,
|
||||
|
@ -4912,6 +5140,62 @@ static snd_kcontrol_new_t alc883_fivestack_mixer[] = {
|
|||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc883_tagra_mixer[] = {
|
||||
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
|
||||
HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
|
||||
HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
|
||||
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, 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("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("Capture Volume", 0x08, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
/* .name = "Capture Source", */
|
||||
.name = "Input Source",
|
||||
.count = 2,
|
||||
.info = alc883_mux_enum_info,
|
||||
.get = alc883_mux_enum_get,
|
||||
.put = alc883_mux_enum_put,
|
||||
},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
|
||||
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, 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("Capture Volume", 0x08, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
|
||||
HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
/* .name = "Capture Source", */
|
||||
.name = "Input Source",
|
||||
.count = 2,
|
||||
.info = alc883_mux_enum_info,
|
||||
.get = alc883_mux_enum_get,
|
||||
.put = alc883_mux_enum_put,
|
||||
},
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc883_chmode_mixer[] = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
|
@ -5000,6 +5284,45 @@ static struct hda_verb alc883_init_verbs[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
static struct hda_verb alc883_tagra_verbs[] = {
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
|
||||
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
|
||||
|
||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||
|
||||
{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
|
||||
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
|
||||
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
|
||||
|
||||
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
|
||||
{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
|
||||
{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
|
||||
{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
|
||||
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/* toggle speaker-output according to the hp-jack state */
|
||||
static void alc883_tagra_automute(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int present;
|
||||
|
||||
present = snd_hda_codec_read(codec, 0x14, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
|
||||
snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
|
||||
0x80, present ? 0x80 : 0);
|
||||
snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
|
||||
}
|
||||
|
||||
static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
|
||||
{
|
||||
if ((res >> 26) == ALC880_HP_EVENT)
|
||||
alc883_tagra_automute(codec);
|
||||
}
|
||||
|
||||
/*
|
||||
* generic initialization of ADC, input mixers and output mixers
|
||||
*/
|
||||
|
@ -5101,9 +5424,9 @@ static struct hda_board_config alc883_cfg_tbl[] = {
|
|||
.config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/
|
||||
{ .modelname = "3stack-6ch", .config = ALC883_3ST_6ch },
|
||||
{ .pci_subvendor = 0x108e, .pci_subdevice = 0x534d,
|
||||
.config = ALC883_3ST_6ch },
|
||||
{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd601,
|
||||
.config = ALC883_3ST_6ch }, /* D102GGC */
|
||||
.config = ALC883_3ST_6ch },
|
||||
{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd601,
|
||||
.config = ALC883_3ST_6ch }, /* D102GGC */
|
||||
{ .modelname = "6stack-dig", .config = ALC883_6ST_DIG },
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x6668,
|
||||
.config = ALC883_6ST_DIG }, /* MSI */
|
||||
|
@ -5111,6 +5434,32 @@ static struct hda_board_config alc883_cfg_tbl[] = {
|
|||
.config = ALC883_6ST_DIG }, /* MSI K9A Platinum (MS-7280) */
|
||||
{ .pci_subvendor = 0x105b, .pci_subdevice = 0x6668,
|
||||
.config = ALC883_6ST_DIG }, /* Foxconn */
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x7187,
|
||||
.config = ALC883_6ST_DIG }, /* MSI */
|
||||
{ .modelname = "targa-dig", .config = ALC883_TARGA_DIG },
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x4314,
|
||||
.config = ALC883_TARGA_DIG }, /* MSI */
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x3fcc,
|
||||
.config = ALC883_TARGA_DIG }, /* MSI */
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x3fc1,
|
||||
.config = ALC883_TARGA_DIG }, /* MSI */
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x3fc3,
|
||||
.config = ALC883_TARGA_DIG }, /* MSI */
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x4314,
|
||||
.config = ALC883_TARGA_DIG }, /* MSI */
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x4319,
|
||||
.config = ALC883_TARGA_DIG }, /* MSI */
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x3ef9,
|
||||
.config = ALC883_TARGA_DIG }, /* MSI */
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x4324,
|
||||
.config = ALC883_TARGA_DIG }, /* MSI */
|
||||
{ .modelname = "targa-2ch-dig", .config = ALC883_TARGA_2ch_DIG },
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x0579,
|
||||
.config = ALC883_TARGA_2ch_DIG }, /* MSI */
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0xa422,
|
||||
.config = ALC883_TARGA_2ch_DIG }, /* MSI */
|
||||
{ .pci_subvendor = 0x1462, .pci_subdevice = 0x3b7f,
|
||||
.config = ALC883_TARGA_2ch_DIG }, /* MSI */
|
||||
{ .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD },
|
||||
{ .modelname = "acer", .config = ALC883_ACER },
|
||||
{ .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/,
|
||||
|
@ -5178,6 +5527,35 @@ static struct alc_config_preset alc883_presets[] = {
|
|||
.channel_mode = alc883_sixstack_modes,
|
||||
.input_mux = &alc883_capture_source,
|
||||
},
|
||||
[ALC883_TARGA_DIG] = {
|
||||
.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
|
||||
.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
|
||||
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
|
||||
.dac_nids = alc883_dac_nids,
|
||||
.dig_out_nid = ALC883_DIGOUT_NID,
|
||||
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
|
||||
.adc_nids = alc883_adc_nids,
|
||||
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
|
||||
.channel_mode = alc883_3ST_6ch_modes,
|
||||
.need_dac_fix = 1,
|
||||
.input_mux = &alc883_capture_source,
|
||||
.unsol_event = alc883_tagra_unsol_event,
|
||||
.init_hook = alc883_tagra_automute,
|
||||
},
|
||||
[ALC883_TARGA_2ch_DIG] = {
|
||||
.mixers = { alc883_tagra_2ch_mixer},
|
||||
.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
|
||||
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
|
||||
.dac_nids = alc883_dac_nids,
|
||||
.dig_out_nid = ALC883_DIGOUT_NID,
|
||||
.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
|
||||
.adc_nids = alc883_adc_nids,
|
||||
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
|
||||
.channel_mode = alc883_3ST_2ch_modes,
|
||||
.input_mux = &alc883_capture_source,
|
||||
.unsol_event = alc883_tagra_unsol_event,
|
||||
.init_hook = alc883_tagra_automute,
|
||||
},
|
||||
[ALC888_DEMO_BOARD] = {
|
||||
.mixers = { alc883_base_mixer, alc883_chmode_mixer },
|
||||
.init_verbs = { alc883_init_verbs },
|
||||
|
@ -5408,6 +5786,24 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
|
|||
{ } /* end */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
|
||||
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, 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("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
|
||||
/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("PC Beelp 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 */
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
|
||||
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
|
||||
|
@ -5512,6 +5908,103 @@ static struct hda_verb alc262_init_verbs[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
static struct hda_verb alc262_hippo_unsol_verbs[] = {
|
||||
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
|
||||
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct hda_verb alc262_hippo1_unsol_verbs[] = {
|
||||
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
|
||||
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
|
||||
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
|
||||
|
||||
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
|
||||
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
|
||||
{}
|
||||
};
|
||||
|
||||
/* mute/unmute internal speaker according to the hp jack and mute state */
|
||||
static void alc262_hippo_automute(struct hda_codec *codec, int force)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
unsigned int mute;
|
||||
|
||||
if (force || ! spec->sense_updated) {
|
||||
unsigned int present;
|
||||
/* need to execute and sync at first */
|
||||
snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
|
||||
present = snd_hda_codec_read(codec, 0x15, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0);
|
||||
spec->jack_present = (present & 0x80000000) != 0;
|
||||
spec->sense_updated = 1;
|
||||
}
|
||||
if (spec->jack_present) {
|
||||
/* mute internal speaker */
|
||||
snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
|
||||
0x80, 0x80);
|
||||
snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
|
||||
0x80, 0x80);
|
||||
} else {
|
||||
/* unmute internal speaker if necessary */
|
||||
mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
|
||||
snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
|
||||
0x80, mute & 0x80);
|
||||
mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
|
||||
snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
|
||||
0x80, mute & 0x80);
|
||||
}
|
||||
}
|
||||
|
||||
/* unsolicited event for HP jack sensing */
|
||||
static void alc262_hippo_unsol_event(struct hda_codec *codec,
|
||||
unsigned int res)
|
||||
{
|
||||
if ((res >> 26) != ALC880_HP_EVENT)
|
||||
return;
|
||||
alc262_hippo_automute(codec, 1);
|
||||
}
|
||||
|
||||
static void alc262_hippo1_automute(struct hda_codec *codec, int force)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
unsigned int mute;
|
||||
|
||||
if (force || ! spec->sense_updated) {
|
||||
unsigned int present;
|
||||
/* need to execute and sync at first */
|
||||
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);
|
||||
spec->jack_present = (present & 0x80000000) != 0;
|
||||
spec->sense_updated = 1;
|
||||
}
|
||||
if (spec->jack_present) {
|
||||
/* mute internal speaker */
|
||||
snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
|
||||
0x80, 0x80);
|
||||
snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
|
||||
0x80, 0x80);
|
||||
} else {
|
||||
/* unmute internal speaker if necessary */
|
||||
mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
|
||||
snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
|
||||
0x80, mute & 0x80);
|
||||
mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
|
||||
snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
|
||||
0x80, mute & 0x80);
|
||||
}
|
||||
}
|
||||
|
||||
/* unsolicited event for HP jack sensing */
|
||||
static void alc262_hippo1_unsol_event(struct hda_codec *codec,
|
||||
unsigned int res)
|
||||
{
|
||||
if ((res >> 26) != ALC880_HP_EVENT)
|
||||
return;
|
||||
alc262_hippo1_automute(codec, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* fujitsu model
|
||||
* 0x14 = headphone/spdif-out, 0x15 = internal speaker
|
||||
|
@ -5921,6 +6414,12 @@ static void alc262_auto_init(struct hda_codec *codec)
|
|||
*/
|
||||
static struct hda_board_config alc262_cfg_tbl[] = {
|
||||
{ .modelname = "basic", .config = ALC262_BASIC },
|
||||
{ .modelname = "hippo",
|
||||
.pci_subvendor =0x1002, .pci_subdevice = 0x437b,
|
||||
.config = ALC262_HIPPO},
|
||||
{ .modelname = "hippo_1",
|
||||
.pci_subvendor =0x17ff, .pci_subdevice = 0x058f,
|
||||
.config = ALC262_HIPPO_1},
|
||||
{ .modelname = "fujitsu", .config = ALC262_FUJITSU },
|
||||
{ .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397,
|
||||
.config = ALC262_FUJITSU },
|
||||
|
@ -5953,6 +6452,30 @@ static struct alc_config_preset alc262_presets[] = {
|
|||
.channel_mode = alc262_modes,
|
||||
.input_mux = &alc262_capture_source,
|
||||
},
|
||||
[ALC262_HIPPO] = {
|
||||
.mixers = { alc262_base_mixer },
|
||||
.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
|
||||
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
|
||||
.dac_nids = alc262_dac_nids,
|
||||
.hp_nid = 0x03,
|
||||
.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_hippo_unsol_event,
|
||||
},
|
||||
[ALC262_HIPPO_1] = {
|
||||
.mixers = { alc262_hippo1_mixer },
|
||||
.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_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_hippo1_unsol_event,
|
||||
},
|
||||
[ALC262_FUJITSU] = {
|
||||
.mixers = { alc262_fujitsu_mixer },
|
||||
.init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
|
||||
|
@ -6983,7 +7506,8 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
|
|||
{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
|
||||
{ .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861",
|
||||
.patch = patch_alc861 },
|
||||
{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
|
||||
{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
|
||||
.patch = patch_alc861 },
|
||||
{ .id = 0x10ec0660, .name = "ALC660", .patch = patch_alc861 },
|
||||
{} /* terminator */
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue