|
@@ -594,7 +594,7 @@ static void call_update_outputs(struct hda_codec *codec)
|
|
|
}
|
|
|
|
|
|
/* standard HP-automute helper */
|
|
|
-static void alc_hp_automute(struct hda_codec *codec)
|
|
|
+static void alc_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
|
|
|
{
|
|
|
struct alc_spec *spec = codec->spec;
|
|
|
|
|
@@ -607,7 +607,7 @@ static void alc_hp_automute(struct hda_codec *codec)
|
|
|
}
|
|
|
|
|
|
/* standard line-out-automute helper */
|
|
|
-static void alc_line_automute(struct hda_codec *codec)
|
|
|
+static void alc_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
|
|
|
{
|
|
|
struct alc_spec *spec = codec->spec;
|
|
|
|
|
@@ -627,7 +627,7 @@ static void alc_line_automute(struct hda_codec *codec)
|
|
|
snd_hda_get_conn_index(codec, mux, nid, 0)
|
|
|
|
|
|
/* standard mic auto-switch helper */
|
|
|
-static void alc_mic_automute(struct hda_codec *codec)
|
|
|
+static void alc_mic_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
|
|
|
{
|
|
|
struct alc_spec *spec = codec->spec;
|
|
|
hda_nid_t *pins = spec->imux_pins;
|
|
@@ -648,25 +648,8 @@ static void alc_mic_automute(struct hda_codec *codec)
|
|
|
alc_mux_select(codec, 0, spec->int_mic_idx, false);
|
|
|
}
|
|
|
|
|
|
-/* handle the specified unsol action (ALC_XXX_EVENT) */
|
|
|
-static void alc_exec_unsol_event(struct hda_codec *codec, int action)
|
|
|
-{
|
|
|
- switch (action) {
|
|
|
- case ALC_HP_EVENT:
|
|
|
- alc_hp_automute(codec);
|
|
|
- break;
|
|
|
- case ALC_FRONT_EVENT:
|
|
|
- alc_line_automute(codec);
|
|
|
- break;
|
|
|
- case ALC_MIC_EVENT:
|
|
|
- alc_mic_automute(codec);
|
|
|
- break;
|
|
|
- }
|
|
|
- snd_hda_jack_report_sync(codec);
|
|
|
-}
|
|
|
-
|
|
|
/* update the master volume per volume-knob's unsol event */
|
|
|
-static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
|
|
|
+static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack)
|
|
|
{
|
|
|
unsigned int val;
|
|
|
struct snd_kcontrol *kctl;
|
|
@@ -678,7 +661,7 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
|
|
|
uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
|
|
|
if (!uctl)
|
|
|
return;
|
|
|
- val = snd_hda_codec_read(codec, nid, 0,
|
|
|
+ val = snd_hda_codec_read(codec, jack->nid, 0,
|
|
|
AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
|
|
|
val &= HDA_AMP_VOLMASK;
|
|
|
uctl->value.integer.value[0] = val;
|
|
@@ -687,37 +670,19 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
|
|
|
kfree(uctl);
|
|
|
}
|
|
|
|
|
|
-/* unsolicited event for HP jack sensing */
|
|
|
-static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
|
|
|
+static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
|
|
|
{
|
|
|
- int action;
|
|
|
-
|
|
|
- if (codec->vendor_id == 0x10ec0880)
|
|
|
- res >>= 28;
|
|
|
- else
|
|
|
- res >>= 26;
|
|
|
- action = snd_hda_jack_get_action(codec, res);
|
|
|
- if (action == ALC_DCVOL_EVENT) {
|
|
|
- /* Execute the dc-vol event here as it requires the NID
|
|
|
- * but we don't pass NID to alc_exec_unsol_event().
|
|
|
- * Once when we convert all static quirks to the auto-parser,
|
|
|
- * this can be integerated into there.
|
|
|
- */
|
|
|
- struct hda_jack_tbl *jack;
|
|
|
- jack = snd_hda_jack_tbl_get_from_tag(codec, res);
|
|
|
- if (jack)
|
|
|
- alc_update_knob_master(codec, jack->nid);
|
|
|
- return;
|
|
|
- }
|
|
|
- alc_exec_unsol_event(codec, action);
|
|
|
+ /* For some reason, the res given from ALC880 is broken.
|
|
|
+ Here we adjust it properly. */
|
|
|
+ snd_hda_jack_unsol_event(codec, res >> 2);
|
|
|
}
|
|
|
|
|
|
/* call init functions of standard auto-mute helpers */
|
|
|
static void alc_inithook(struct hda_codec *codec)
|
|
|
{
|
|
|
- alc_hp_automute(codec);
|
|
|
- alc_line_automute(codec);
|
|
|
- alc_mic_automute(codec);
|
|
|
+ alc_hp_automute(codec, NULL);
|
|
|
+ alc_line_automute(codec, NULL);
|
|
|
+ alc_mic_automute(codec, NULL);
|
|
|
}
|
|
|
|
|
|
/* additional initialization for ALC888 variants */
|
|
@@ -999,7 +964,8 @@ static void alc_init_automute(struct hda_codec *codec)
|
|
|
continue;
|
|
|
snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
|
|
|
nid);
|
|
|
- snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT);
|
|
|
+ snd_hda_jack_detect_enable_callback(codec, nid, ALC_HP_EVENT,
|
|
|
+ alc_hp_automute);
|
|
|
spec->detect_hp = 1;
|
|
|
}
|
|
|
|
|
@@ -1011,10 +977,10 @@ static void alc_init_automute(struct hda_codec *codec)
|
|
|
continue;
|
|
|
snd_printdd("realtek: Enable Line-Out "
|
|
|
"auto-muting on NID 0x%x\n", nid);
|
|
|
- snd_hda_jack_detect_enable(codec, nid,
|
|
|
- ALC_FRONT_EVENT);
|
|
|
+ snd_hda_jack_detect_enable_callback(codec, nid, ALC_FRONT_EVENT,
|
|
|
+ alc_line_automute);
|
|
|
spec->detect_lo = 1;
|
|
|
- }
|
|
|
+ }
|
|
|
spec->automute_lo_possible = spec->detect_hp;
|
|
|
}
|
|
|
|
|
@@ -1110,10 +1076,12 @@ static bool alc_auto_mic_check_imux(struct hda_codec *codec)
|
|
|
return false; /* no corresponding imux */
|
|
|
}
|
|
|
|
|
|
- snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT);
|
|
|
+ snd_hda_jack_detect_enable_callback(codec, spec->ext_mic_pin,
|
|
|
+ ALC_MIC_EVENT, alc_mic_automute);
|
|
|
if (spec->dock_mic_pin)
|
|
|
- snd_hda_jack_detect_enable(codec, spec->dock_mic_pin,
|
|
|
- ALC_MIC_EVENT);
|
|
|
+ snd_hda_jack_detect_enable_callback(codec, spec->dock_mic_pin,
|
|
|
+ ALC_MIC_EVENT,
|
|
|
+ alc_mic_automute);
|
|
|
|
|
|
spec->auto_mic_valid_imux = 1;
|
|
|
spec->auto_mic = 1;
|
|
@@ -2473,7 +2441,7 @@ static const struct hda_codec_ops alc_patch_ops = {
|
|
|
.build_pcms = alc_build_pcms,
|
|
|
.init = alc_init,
|
|
|
.free = alc_free,
|
|
|
- .unsol_event = alc_unsol_event,
|
|
|
+ .unsol_event = snd_hda_jack_unsol_event,
|
|
|
#ifdef CONFIG_PM
|
|
|
.resume = alc_resume,
|
|
|
#endif
|
|
@@ -2484,6 +2452,7 @@ static const struct hda_codec_ops alc_patch_ops = {
|
|
|
.reboot_notify = alc_shutup,
|
|
|
};
|
|
|
|
|
|
+
|
|
|
/* replace the codec chip_name with the given string */
|
|
|
static int alc_codec_rename(struct hda_codec *codec, const char *name)
|
|
|
{
|
|
@@ -4447,7 +4416,7 @@ static void alc880_fixup_vol_knob(struct hda_codec *codec,
|
|
|
const struct alc_fixup *fix, int action)
|
|
|
{
|
|
|
if (action == ALC_FIXUP_ACT_PROBE)
|
|
|
- snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT);
|
|
|
+ snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master);
|
|
|
}
|
|
|
|
|
|
static const struct alc_fixup alc880_fixups[] = {
|
|
@@ -4812,6 +4781,8 @@ static int patch_alc880(struct hda_codec *codec)
|
|
|
}
|
|
|
|
|
|
codec->patch_ops = alc_patch_ops;
|
|
|
+ codec->patch_ops.unsol_event = alc880_unsol_event;
|
|
|
+
|
|
|
|
|
|
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
|
|
|
|
|
@@ -4866,7 +4837,8 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
|
|
|
spec->detect_hp = 1;
|
|
|
spec->automute_speaker = 1;
|
|
|
spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
|
|
|
- snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
|
|
|
+ snd_hda_jack_detect_enable_callback(codec, 0x0f, ALC_HP_EVENT,
|
|
|
+ alc_hp_automute);
|
|
|
snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs);
|
|
|
}
|
|
|
}
|