Commit e60dc981 authored by songxiebing's avatar songxiebing Committed by Takashi Iwai

ALSA: hda: conexant: Fix headset auto detect fail in the polling mode

The previous fix (7aeb2590) only handles the unsol_event reporting
during interrupts and does not include the polling mode used to set
jackroll_ms, so now we are replacing it with
snd_hda_jack_detect_enable_callback.

Fixes: 7aeb2590 ("ALSA: hda/conexant: Fix headset auto detect fail in cx8070 and SN6140")
Co-developed-by: default avatarbo liu <bo.liu@senarytech.com>
Signed-off-by: default avatarbo liu <bo.liu@senarytech.com>
Signed-off-by: default avatarsongxiebing <songxiebing@kylinos.cn>
Link: https://patch.msgid.link/20240726100726.50824-1-soxiebing@163.comSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent e8b96a66
...@@ -21,12 +21,6 @@ ...@@ -21,12 +21,6 @@
#include "hda_jack.h" #include "hda_jack.h"
#include "hda_generic.h" #include "hda_generic.h"
enum {
CX_HEADSET_NOPRESENT = 0,
CX_HEADSET_PARTPRESENT,
CX_HEADSET_ALLPRESENT,
};
struct conexant_spec { struct conexant_spec {
struct hda_gen_spec gen; struct hda_gen_spec gen;
...@@ -48,7 +42,6 @@ struct conexant_spec { ...@@ -48,7 +42,6 @@ struct conexant_spec {
unsigned int gpio_led; unsigned int gpio_led;
unsigned int gpio_mute_led_mask; unsigned int gpio_mute_led_mask;
unsigned int gpio_mic_led_mask; unsigned int gpio_mic_led_mask;
unsigned int headset_present_flag;
bool is_cx8070_sn6140; bool is_cx8070_sn6140;
}; };
...@@ -250,48 +243,19 @@ static void cx_process_headset_plugin(struct hda_codec *codec) ...@@ -250,48 +243,19 @@ static void cx_process_headset_plugin(struct hda_codec *codec)
} }
} }
static void cx_update_headset_mic_vref(struct hda_codec *codec, unsigned int res) static void cx_update_headset_mic_vref(struct hda_codec *codec, struct hda_jack_callback *event)
{ {
unsigned int phone_present, mic_persent, phone_tag, mic_tag; unsigned int mic_present;
struct conexant_spec *spec = codec->spec;
/* In cx8070 and sn6140, the node 16 can only be config to headphone or disabled, /* In cx8070 and sn6140, the node 16 can only be config to headphone or disabled,
* the node 19 can only be config to microphone or disabled. * the node 19 can only be config to microphone or disabled.
* Check hp&mic tag to process headset pulgin&plugout. * Check hp&mic tag to process headset pulgin&plugout.
*/ */
phone_tag = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0); mic_present = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0);
mic_tag = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0); if (!(mic_present & AC_PINSENSE_PRESENCE)) /* mic plugout */
if ((phone_tag & (res >> AC_UNSOL_RES_TAG_SHIFT)) || snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20);
(mic_tag & (res >> AC_UNSOL_RES_TAG_SHIFT))) { else
phone_present = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_PIN_SENSE, 0x0); cx_process_headset_plugin(codec);
if (!(phone_present & AC_PINSENSE_PRESENCE)) {/* headphone plugout */
spec->headset_present_flag = CX_HEADSET_NOPRESENT;
snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20);
return;
}
if (spec->headset_present_flag == CX_HEADSET_NOPRESENT) {
spec->headset_present_flag = CX_HEADSET_PARTPRESENT;
} else if (spec->headset_present_flag == CX_HEADSET_PARTPRESENT) {
mic_persent = snd_hda_codec_read(codec, 0x19, 0,
AC_VERB_GET_PIN_SENSE, 0x0);
/* headset is present */
if ((phone_present & AC_PINSENSE_PRESENCE) &&
(mic_persent & AC_PINSENSE_PRESENCE)) {
cx_process_headset_plugin(codec);
spec->headset_present_flag = CX_HEADSET_ALLPRESENT;
}
}
}
}
static void cx_jack_unsol_event(struct hda_codec *codec, unsigned int res)
{
struct conexant_spec *spec = codec->spec;
if (spec->is_cx8070_sn6140)
cx_update_headset_mic_vref(codec, res);
snd_hda_jack_unsol_event(codec, res);
} }
static int cx_auto_suspend(struct hda_codec *codec) static int cx_auto_suspend(struct hda_codec *codec)
...@@ -305,7 +269,7 @@ static const struct hda_codec_ops cx_auto_patch_ops = { ...@@ -305,7 +269,7 @@ static const struct hda_codec_ops cx_auto_patch_ops = {
.build_pcms = snd_hda_gen_build_pcms, .build_pcms = snd_hda_gen_build_pcms,
.init = cx_auto_init, .init = cx_auto_init,
.free = cx_auto_free, .free = cx_auto_free,
.unsol_event = cx_jack_unsol_event, .unsol_event = snd_hda_jack_unsol_event,
.suspend = cx_auto_suspend, .suspend = cx_auto_suspend,
.check_power_status = snd_hda_gen_check_power_status, .check_power_status = snd_hda_gen_check_power_status,
}; };
...@@ -1163,7 +1127,7 @@ static int patch_conexant_auto(struct hda_codec *codec) ...@@ -1163,7 +1127,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
case 0x14f11f86: case 0x14f11f86:
case 0x14f11f87: case 0x14f11f87:
spec->is_cx8070_sn6140 = true; spec->is_cx8070_sn6140 = true;
spec->headset_present_flag = CX_HEADSET_NOPRESENT; snd_hda_jack_detect_enable_callback(codec, 0x19, cx_update_headset_mic_vref);
break; break;
} }
......
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