Merge branch 'fix/hda' into for-linus
This commit is contained in:
commit
6321bd634e
2 changed files with 128 additions and 27 deletions
|
@ -1230,6 +1230,8 @@ static void alc_init_auto_mic(struct hda_codec *codec)
|
||||||
return; /* invalid entry */
|
return; /* invalid entry */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!ext || !fixed)
|
||||||
|
return;
|
||||||
if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
|
if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
|
||||||
return; /* no unsol support */
|
return; /* no unsol support */
|
||||||
snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
|
snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
|
||||||
|
@ -4812,6 +4814,49 @@ static void fixup_automic_adc(struct hda_codec *codec)
|
||||||
spec->auto_mic = 0; /* disable auto-mic to be sure */
|
spec->auto_mic = 0; /* disable auto-mic to be sure */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* choose the ADC/MUX containing the input pin and initialize the setup */
|
||||||
|
static void fixup_single_adc(struct hda_codec *codec)
|
||||||
|
{
|
||||||
|
struct alc_spec *spec = codec->spec;
|
||||||
|
hda_nid_t pin;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* search for the input pin; there must be only one */
|
||||||
|
for (i = 0; i < AUTO_PIN_LAST; i++) {
|
||||||
|
if (spec->autocfg.input_pins[i]) {
|
||||||
|
pin = spec->autocfg.input_pins[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!pin)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* set the default connection to that pin */
|
||||||
|
for (i = 0; i < spec->num_adc_nids; i++) {
|
||||||
|
hda_nid_t cap = spec->capsrc_nids ?
|
||||||
|
spec->capsrc_nids[i] : spec->adc_nids[i];
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
idx = get_connection_index(codec, cap, pin);
|
||||||
|
if (idx < 0)
|
||||||
|
continue;
|
||||||
|
/* use only this ADC */
|
||||||
|
if (spec->capsrc_nids)
|
||||||
|
spec->capsrc_nids += i;
|
||||||
|
spec->adc_nids += i;
|
||||||
|
spec->num_adc_nids = 1;
|
||||||
|
/* select or unmute this route */
|
||||||
|
if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
|
||||||
|
snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
|
||||||
|
HDA_AMP_MUTE, 0);
|
||||||
|
} else {
|
||||||
|
snd_hda_codec_write_cache(codec, cap, 0,
|
||||||
|
AC_VERB_SET_CONNECT_SEL, idx);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void set_capture_mixer(struct hda_codec *codec)
|
static void set_capture_mixer(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct alc_spec *spec = codec->spec;
|
struct alc_spec *spec = codec->spec;
|
||||||
|
@ -4824,14 +4869,15 @@ static void set_capture_mixer(struct hda_codec *codec)
|
||||||
alc_capture_mixer3 },
|
alc_capture_mixer3 },
|
||||||
};
|
};
|
||||||
if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
|
if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
|
||||||
int mux;
|
int mux = 0;
|
||||||
if (spec->auto_mic) {
|
if (spec->auto_mic)
|
||||||
mux = 0;
|
|
||||||
fixup_automic_adc(codec);
|
fixup_automic_adc(codec);
|
||||||
} else if (spec->input_mux && spec->input_mux->num_items > 1)
|
else if (spec->input_mux) {
|
||||||
mux = 1;
|
if (spec->input_mux->num_items > 1)
|
||||||
else
|
mux = 1;
|
||||||
mux = 0;
|
else if (spec->input_mux->num_items == 1)
|
||||||
|
fixup_single_adc(codec);
|
||||||
|
}
|
||||||
spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
|
spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7094,8 +7140,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
|
||||||
HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
|
HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
|
||||||
HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
|
HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
|
||||||
HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
|
HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
|
||||||
HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
|
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
|
||||||
HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
|
HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
|
||||||
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
|
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
|
||||||
HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
|
HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
|
||||||
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
|
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
|
||||||
|
@ -7496,6 +7542,7 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
|
||||||
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
|
||||||
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
|
||||||
{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
|
{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
|
||||||
|
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
|
||||||
/* Front Mic pin: input vref at 80% */
|
/* Front Mic pin: input vref at 80% */
|
||||||
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
|
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
|
||||||
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
|
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
|
||||||
|
@ -7680,6 +7727,27 @@ static void alc885_mbp3_setup(struct hda_codec *codec)
|
||||||
spec->autocfg.speaker_pins[0] = 0x14;
|
spec->autocfg.speaker_pins[0] = 0x14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void alc885_mb5_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_stereo(codec, 0x18, HDA_OUTPUT, 0,
|
||||||
|
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
|
||||||
|
snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
|
||||||
|
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void alc885_mb5_unsol_event(struct hda_codec *codec,
|
||||||
|
unsigned int res)
|
||||||
|
{
|
||||||
|
/* Headphone insertion or removal. */
|
||||||
|
if ((res >> 26) == ALC880_HP_EVENT)
|
||||||
|
alc885_mb5_automute(codec);
|
||||||
|
}
|
||||||
|
|
||||||
static void alc885_imac91_automute(struct hda_codec *codec)
|
static void alc885_imac91_automute(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
unsigned int present;
|
unsigned int present;
|
||||||
|
@ -9126,6 +9194,8 @@ static struct alc_config_preset alc882_presets[] = {
|
||||||
.input_mux = &mb5_capture_source,
|
.input_mux = &mb5_capture_source,
|
||||||
.dig_out_nid = ALC882_DIGOUT_NID,
|
.dig_out_nid = ALC882_DIGOUT_NID,
|
||||||
.dig_in_nid = ALC882_DIGIN_NID,
|
.dig_in_nid = ALC882_DIGIN_NID,
|
||||||
|
.unsol_event = alc885_mb5_unsol_event,
|
||||||
|
.init_hook = alc885_mb5_automute,
|
||||||
},
|
},
|
||||||
[ALC885_MACPRO] = {
|
[ALC885_MACPRO] = {
|
||||||
.mixers = { alc882_macpro_mixer },
|
.mixers = { alc882_macpro_mixer },
|
||||||
|
@ -11179,7 +11249,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
|
||||||
}
|
}
|
||||||
|
|
||||||
#define alc262_auto_create_input_ctls \
|
#define alc262_auto_create_input_ctls \
|
||||||
alc880_auto_create_input_ctls
|
alc882_auto_create_input_ctls
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* generic initialization of ADC, input mixers and output mixers
|
* generic initialization of ADC, input mixers and output mixers
|
||||||
|
@ -14855,6 +14925,8 @@ static int patch_alc861(struct hda_codec *codec)
|
||||||
spec->stream_digital_playback = &alc861_pcm_digital_playback;
|
spec->stream_digital_playback = &alc861_pcm_digital_playback;
|
||||||
spec->stream_digital_capture = &alc861_pcm_digital_capture;
|
spec->stream_digital_capture = &alc861_pcm_digital_capture;
|
||||||
|
|
||||||
|
if (!spec->cap_mixer)
|
||||||
|
set_capture_mixer(codec);
|
||||||
set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
|
set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
|
||||||
|
|
||||||
spec->vmaster_nid = 0x03;
|
spec->vmaster_nid = 0x03;
|
||||||
|
@ -17251,7 +17323,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
|
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
|
||||||
SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
|
SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
|
||||||
ALC662_3ST_6ch_DIG),
|
ALC662_3ST_6ch_DIG),
|
||||||
SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4),
|
SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
|
||||||
SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
|
SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
|
||||||
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
|
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
|
||||||
ALC662_3ST_6ch_DIG),
|
ALC662_3ST_6ch_DIG),
|
||||||
|
|
|
@ -4730,6 +4730,26 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hp_blike_system(u32 subsystem_id);
|
||||||
|
|
||||||
|
static void set_hp_led_gpio(struct hda_codec *codec)
|
||||||
|
{
|
||||||
|
struct sigmatel_spec *spec = codec->spec;
|
||||||
|
switch (codec->vendor_id) {
|
||||||
|
case 0x111d7608:
|
||||||
|
/* GPIO 0 */
|
||||||
|
spec->gpio_led = 0x01;
|
||||||
|
break;
|
||||||
|
case 0x111d7600:
|
||||||
|
case 0x111d7601:
|
||||||
|
case 0x111d7602:
|
||||||
|
case 0x111d7603:
|
||||||
|
/* GPIO 3 */
|
||||||
|
spec->gpio_led = 0x08;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This method searches for the mute LED GPIO configuration
|
* This method searches for the mute LED GPIO configuration
|
||||||
* provided as OEM string in SMBIOS. The format of that string
|
* provided as OEM string in SMBIOS. The format of that string
|
||||||
|
@ -4741,6 +4761,14 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
|
||||||
*
|
*
|
||||||
* So, HP B-series like systems may have HP_Mute_LED_0 (current models)
|
* So, HP B-series like systems may have HP_Mute_LED_0 (current models)
|
||||||
* or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
|
* or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* The dv-series laptops don't seem to have the HP_Mute_LED* strings in
|
||||||
|
* SMBIOS - at least the ones I have seen do not have them - which include
|
||||||
|
* my own system (HP Pavilion dv6-1110ax) and my cousin's
|
||||||
|
* HP Pavilion dv9500t CTO.
|
||||||
|
* Need more information on whether it is true across the entire series.
|
||||||
|
* -- kunal
|
||||||
*/
|
*/
|
||||||
static int find_mute_led_gpio(struct hda_codec *codec)
|
static int find_mute_led_gpio(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
|
@ -4751,28 +4779,27 @@ static int find_mute_led_gpio(struct hda_codec *codec)
|
||||||
while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
|
while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
|
||||||
NULL, dev))) {
|
NULL, dev))) {
|
||||||
if (sscanf(dev->name, "HP_Mute_LED_%d_%d",
|
if (sscanf(dev->name, "HP_Mute_LED_%d_%d",
|
||||||
&spec->gpio_led_polarity,
|
&spec->gpio_led_polarity,
|
||||||
&spec->gpio_led) == 2) {
|
&spec->gpio_led) == 2) {
|
||||||
spec->gpio_led = 1 << spec->gpio_led;
|
spec->gpio_led = 1 << spec->gpio_led;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sscanf(dev->name, "HP_Mute_LED_%d",
|
if (sscanf(dev->name, "HP_Mute_LED_%d",
|
||||||
&spec->gpio_led_polarity) == 1) {
|
&spec->gpio_led_polarity) == 1) {
|
||||||
switch (codec->vendor_id) {
|
set_hp_led_gpio(codec);
|
||||||
case 0x111d7608:
|
return 1;
|
||||||
/* GPIO 0 */
|
|
||||||
spec->gpio_led = 0x01;
|
|
||||||
return 1;
|
|
||||||
case 0x111d7600:
|
|
||||||
case 0x111d7601:
|
|
||||||
case 0x111d7602:
|
|
||||||
case 0x111d7603:
|
|
||||||
/* GPIO 3 */
|
|
||||||
spec->gpio_led = 0x08;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fallback case - if we don't find the DMI strings,
|
||||||
|
* we statically set the GPIO - if not a B-series system.
|
||||||
|
*/
|
||||||
|
if (!hp_blike_system(codec->subsystem_id)) {
|
||||||
|
set_hp_led_gpio(codec);
|
||||||
|
spec->gpio_led_polarity = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5548,6 +5575,8 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
|
||||||
spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
|
spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
|
||||||
spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e);
|
spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e);
|
||||||
|
|
||||||
|
snd_printdd("Found board config: %d\n", spec->board_config);
|
||||||
|
|
||||||
switch (spec->board_config) {
|
switch (spec->board_config) {
|
||||||
case STAC_HP_M4:
|
case STAC_HP_M4:
|
||||||
/* enable internal microphone */
|
/* enable internal microphone */
|
||||||
|
|
Loading…
Reference in a new issue