mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-06 05:13:18 +00:00
ALSA: hda: conexant: Fix headset auto detect fail in the polling mode
The previous fix (7aeb259086
) 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:7aeb259086
("ALSA: hda/conexant: Fix headset auto detect fail in cx8070 and SN6140") Co-developed-by: bo liu <bo.liu@senarytech.com> Signed-off-by: bo liu <bo.liu@senarytech.com> Signed-off-by: songxiebing <songxiebing@kylinos.cn> Link: https://patch.msgid.link/20240726100726.50824-1-soxiebing@163.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
e8b96a66ae
commit
e60dc98122
@ -21,12 +21,6 @@
|
||||
#include "hda_jack.h"
|
||||
#include "hda_generic.h"
|
||||
|
||||
enum {
|
||||
CX_HEADSET_NOPRESENT = 0,
|
||||
CX_HEADSET_PARTPRESENT,
|
||||
CX_HEADSET_ALLPRESENT,
|
||||
};
|
||||
|
||||
struct conexant_spec {
|
||||
struct hda_gen_spec gen;
|
||||
|
||||
@ -48,7 +42,6 @@ struct conexant_spec {
|
||||
unsigned int gpio_led;
|
||||
unsigned int gpio_mute_led_mask;
|
||||
unsigned int gpio_mic_led_mask;
|
||||
unsigned int headset_present_flag;
|
||||
bool is_cx8070_sn6140;
|
||||
};
|
||||
|
||||
@ -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;
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
unsigned int mic_present;
|
||||
|
||||
/* 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.
|
||||
* 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_tag = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0);
|
||||
if ((phone_tag & (res >> AC_UNSOL_RES_TAG_SHIFT)) ||
|
||||
(mic_tag & (res >> AC_UNSOL_RES_TAG_SHIFT))) {
|
||||
phone_present = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_PIN_SENSE, 0x0);
|
||||
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);
|
||||
mic_present = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0);
|
||||
if (!(mic_present & AC_PINSENSE_PRESENCE)) /* mic plugout */
|
||||
snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20);
|
||||
else
|
||||
cx_process_headset_plugin(codec);
|
||||
}
|
||||
|
||||
static int cx_auto_suspend(struct hda_codec *codec)
|
||||
@ -305,7 +269,7 @@ static const struct hda_codec_ops cx_auto_patch_ops = {
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = cx_auto_init,
|
||||
.free = cx_auto_free,
|
||||
.unsol_event = cx_jack_unsol_event,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
.suspend = cx_auto_suspend,
|
||||
.check_power_status = snd_hda_gen_check_power_status,
|
||||
};
|
||||
@ -1163,7 +1127,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
|
||||
case 0x14f11f86:
|
||||
case 0x14f11f87:
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user