Due to returning the email and resending it//答复: [PATCH 1/3] Fix headset auto detect fail in cx8070 and SN6140

Message ID 009d01da3939$a1517440$e3f45cc0$@senarytech.com
State New
Headers
Series Due to returning the email and resending it//答复: [PATCH 1/3] Fix headset auto detect fail in cx8070 and SN6140 |

Commit Message

bo liu Dec. 28, 2023, 2:57 a.m. UTC
  FYI

Best Regards
Bo Liu (刘博)
Cell#: +86-18986160629
 Email: bo.liu@senarytech.com
深圳前海深蕾半导体有限公司
湖北省武汉市东湖高新技术开发区关山大道355号铭丰大厦
16楼1601-1603室
 Room 1601-1603,mTower, No. 355 Guanshan Avenue, 
 East Lake High-tech Development Zone, Wuhan, Hubei Province.
 
-----邮件原件-----
发件人: bo liu <bo.liu@senarytech.com> 
发送时间: 2023年12月27日 15:10
收件人: perex@perex.cz; tiwai@suse.com
抄送: linux-sound@vger.kernel.org; linux-kernel@vger.kernel.org; bo liu <bo.liu@senarytech.com>
主题: [PATCH 1/3] Fix headset auto detect fail in cx8070 and SN6140

CX8070 and SN6140 will get wrong headset type when use OMTP headset, then the headset mic will not work.

Signed-off-by: bo liu <bo.liu@senarytech.com>
---
 sound/pci/hda/patch_conexant.c | 75 +++++++++++++++++++++++++++++++++-
 1 file changed, 74 insertions(+), 1 deletion(-)

 	cxt_init_gpio_led(codec);
 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
 
+	switch (codec->core.vendor_id) {
+	case 0x14f11f86:
+	case 0x14f11f87:
+		/* fix some headset recognize fail issue */
+		snd_hda_codec_write(codec, 0x1c, 0, 0x320, 0x010);
+		snd_hda_codec_write(codec, 0x1c, 0, 0x3b0, 0xe10);
+		snd_hda_codec_write(codec, 0x1c, 0, 0x4f0, 0x0eb);
+		/* fix reboot headset recognize fail issue */
+		mic_persent = snd_hda_codec_read(codec, 0x19, 0, 0xf09, 0x0);
+		if (mic_persent&0x80000000) {
+			snd_hda_codec_write(codec, 0x19, 0, 0x707, 0x24);
+		} else {
+			snd_hda_codec_write(codec, 0x19, 0, 0x707, 0x20);
+		}
+		break;
+	}
+
 	return 0;
 }
 
@@ -191,6 +209,60 @@ static void cx_auto_free(struct hda_codec *codec)
 	cx_auto_shutdown(codec);
 	snd_hda_gen_free(codec);
 }
+ 
+static int headset_present_flag;
+static void cx_jack_unsol_event(struct hda_codec *codec, unsigned int 
+res) {
+	unsigned int val,phone_present,mic_persent,phone_tag,mic_tag;
+	unsigned int count=0;
+	
+	switch (codec->core.vendor_id) {
+	case 0x14f11f86:
+	case 0x14f11f87:
+		/* check hp&mic tag to process headset pulgin&plugout */
+		phone_tag = snd_hda_codec_read(codec, 0x16, 0, 0xf08, 0x0);
+		mic_tag = snd_hda_codec_read(codec, 0x19, 0, 0xf08, 0x0);
+		if((phone_tag&(res>>26)) || (mic_tag&(res>>26))) {
+			//msleep(600);
+			phone_present = snd_hda_codec_read(codec, 0x16, 0, 0xf09, 0x0);
+			if(!(phone_present&0x80000000)) {/* headphone plugout */
+				headset_present_flag = 0;
+				snd_hda_codec_write(codec, 0x19, 0, 0x707, 0x20);
+				break;
+			}
+			if (headset_present_flag == 0) {
+				headset_present_flag = 1;
+			} else if(headset_present_flag == 1) {
+				mic_persent = snd_hda_codec_read(codec, 0x19, 0, 0xf09, 0x0);
+				if ((phone_present&0x80000000)&&(mic_persent&0x80000000)) {/* headset is present */
+					/* wait headset detect done */
+					do {
+						val = snd_hda_codec_read(codec, 0x1c, 0, 0xca0, 0x0);
+						if(val&0x080) {
+							break;
+						}
+						msleep(10);
+						count += 1;
+					} while(count > 5);
+					val = snd_hda_codec_read(codec, 0x1c, 0, 0xcb0, 0x0);
+					if(val&0x800) {
+						codec_dbg(codec, "headset plugin, type is CTIA\n");
+						snd_hda_codec_write(codec, 0x19, 0, 0x707, 0x24);
+					} else if(val&0x400) {
+						codec_dbg(codec, "headset plugin, type is OMTP\n");
+						snd_hda_codec_write(codec, 0x19, 0, 0x707, 0x24);
+					} else {
+						codec_dbg(codec, "headphone plugin\n");
+					}
+					headset_present_flag = 2;
+				}
+			}
+		}
+		break;
+	}
+
+	snd_hda_jack_unsol_event(codec, res);
+}
 
 #ifdef CONFIG_PM
 static int cx_auto_suspend(struct hda_codec *codec) @@ -205,7 +277,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 = snd_hda_jack_unsol_event,
+	.unsol_event = cx_jack_unsol_event,
 #ifdef CONFIG_PM
 	.suspend = cx_auto_suspend,
 	.check_power_status = snd_hda_gen_check_power_status, @@ -1042,6 +1114,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
 	codec->spec = spec;
 	codec->patch_ops = cx_auto_patch_ops;
 
+	headset_present_flag = 0;
 	cx_auto_parse_eapd(codec);
 	spec->gen.own_eapd_ctl = 1;
 
--
2.34.1
  

Patch

diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index a889cccdd607..2d58595bfbdd 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -166,6 +166,7 @@  static void cxt_init_gpio_led(struct hda_codec *codec)
 
 static int cx_auto_init(struct hda_codec *codec)  {
+	unsigned int mic_persent;
 	struct conexant_spec *spec = codec->spec;
 	snd_hda_gen_init(codec);
 	if (!spec->dynamic_eapd)
@@ -174,6 +175,23 @@  static int cx_auto_init(struct hda_codec *codec)