Commit 3866f0b0 authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela

[ALSA] hda-codec - Add the support of Dell OEM laptops with ALC268

Added the support of Dell OEM laptops (Vostro 1200) with ALC268 codec.
The new model=dell is provided.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent f0747ee6
...@@ -825,6 +825,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ...@@ -825,6 +825,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
3stack 3-stack model 3stack 3-stack model
toshiba Toshiba A205 toshiba Toshiba A205
acer Acer laptops acer Acer laptops
dell Dell OEM laptops (Vostro 1200)
test for testing/debugging purpose, almost all controls can test for testing/debugging purpose, almost all controls can
adjusted. Appearing only when compiled with adjusted. Appearing only when compiled with
$CONFIG_SND_DEBUG=y $CONFIG_SND_DEBUG=y
......
...@@ -106,6 +106,7 @@ enum { ...@@ -106,6 +106,7 @@ enum {
ALC268_3ST, ALC268_3ST,
ALC268_TOSHIBA, ALC268_TOSHIBA,
ALC268_ACER, ALC268_ACER,
ALC268_DELL,
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
ALC268_TEST, ALC268_TEST,
#endif #endif
...@@ -9424,6 +9425,49 @@ static void alc268_acer_init_hook(struct hda_codec *codec) ...@@ -9424,6 +9425,49 @@ static void alc268_acer_init_hook(struct hda_codec *codec)
alc268_acer_automute(codec, 1); alc268_acer_automute(codec, 1);
} }
static struct snd_kcontrol_new alc268_dell_mixer[] = {
/* output mixer control */
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
{ }
};
static struct hda_verb alc268_dell_verbs[] = {
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
{ }
};
/* mute/unmute internal speaker according to the hp jack and mute state */
static void alc268_dell_automute(struct hda_codec *codec)
{
unsigned int present;
unsigned int mute;
present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
if (present & 0x80000000)
mute = HDA_AMP_MUTE;
else
mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
}
static void alc268_dell_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) != ALC880_HP_EVENT)
return;
alc268_dell_automute(codec);
}
#define alc268_dell_init_hook alc268_dell_automute
/* /*
* generic initialization of ADC, input mixers and output mixers * generic initialization of ADC, input mixers and output mixers
*/ */
...@@ -9842,6 +9886,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = { ...@@ -9842,6 +9886,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = {
[ALC268_3ST] = "3stack", [ALC268_3ST] = "3stack",
[ALC268_TOSHIBA] = "toshiba", [ALC268_TOSHIBA] = "toshiba",
[ALC268_ACER] = "acer", [ALC268_ACER] = "acer",
[ALC268_DELL] = "dell",
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
[ALC268_TEST] = "test", [ALC268_TEST] = "test",
#endif #endif
...@@ -9851,6 +9896,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = { ...@@ -9851,6 +9896,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = {
static struct snd_pci_quirk alc268_cfg_tbl[] = { static struct snd_pci_quirk alc268_cfg_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
...@@ -9903,6 +9949,19 @@ static struct alc_config_preset alc268_presets[] = { ...@@ -9903,6 +9949,19 @@ static struct alc_config_preset alc268_presets[] = {
.unsol_event = alc268_acer_unsol_event, .unsol_event = alc268_acer_unsol_event,
.init_hook = alc268_acer_init_hook, .init_hook = alc268_acer_init_hook,
}, },
[ALC268_DELL] = {
.mixers = { alc268_dell_mixer },
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_dell_verbs },
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
.dac_nids = alc268_dac_nids,
.hp_nid = 0x02,
.num_channel_mode = ARRAY_SIZE(alc268_modes),
.channel_mode = alc268_modes,
.unsol_event = alc268_dell_unsol_event,
.init_hook = alc268_dell_init_hook,
.input_mux = &alc268_capture_source,
},
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
[ALC268_TEST] = { [ALC268_TEST] = {
.mixers = { alc268_test_mixer, alc268_capture_mixer }, .mixers = { alc268_test_mixer, alc268_capture_mixer },
...@@ -9967,28 +10026,24 @@ static int patch_alc268(struct hda_codec *codec) ...@@ -9967,28 +10026,24 @@ static int patch_alc268(struct hda_codec *codec)
spec->stream_name_digital = "ALC268 Digital"; spec->stream_name_digital = "ALC268 Digital";
spec->stream_digital_playback = &alc268_pcm_digital_playback; spec->stream_digital_playback = &alc268_pcm_digital_playback;
if (board_config == ALC268_AUTO) { if (!spec->adc_nids && spec->input_mux) {
if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */
/* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07);
unsigned int wcap = get_wcaps(codec, 0x07);
/* get type */
/* get type */ wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (wcap != AC_WID_AUD_IN) {
if (wcap != AC_WID_AUD_IN) { spec->adc_nids = alc268_adc_nids_alt;
spec->adc_nids = alc268_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
spec->num_adc_nids = spec->mixers[spec->num_mixers] =
ARRAY_SIZE(alc268_adc_nids_alt);
spec->mixers[spec->num_mixers] =
alc268_capture_alt_mixer; alc268_capture_alt_mixer;
spec->num_mixers++; spec->num_mixers++;
} else { } else {
spec->adc_nids = alc268_adc_nids; spec->adc_nids = alc268_adc_nids;
spec->num_adc_nids = spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
ARRAY_SIZE(alc268_adc_nids); spec->mixers[spec->num_mixers] =
spec->mixers[spec->num_mixers] = alc268_capture_mixer;
alc268_capture_mixer; spec->num_mixers++;
spec->num_mixers++;
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment