请选择 进入手机版 | 继续访问电脑版

mtk平台typec模拟耳机补丁

[复制链接]
蝶蝶已蝶已蝶蝶 发表于 2021-1-3 12:07:16 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
typec模拟耳机在某些高端手机上已经很常见了,但拿到的代码默认不支持typec模拟耳机(在某些平台上默认就是typec模拟耳机),那只能自己修改了。
这里用的版本为Android11,kernel4.19。
由于默认的耳机检测驱动mt6357-accdet.c已换成ko的形式(非ko方式可忽略该修改),导致无法调用该驱动里的函数,先把该驱动编译进内核。
defconfig加入CONFIG_SND_SOC_MT6357_ACCDET=y
BoardConfig.mk
  1. @@ -53,8 +53,7 @@ BOARD_FLASH_BLOCK_SIZE := 4096 KERNEL_OUT ?= $(OUT_DIR)/target/project/$(TARGET_DEVICE)/obj/KERNEL_OBJ # in-tree kernel modules installed to vendor # For Common-BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_OUT)/sound/soc/codecs/mt6357-accdet.ko \-                   $(KERNEL_OUT)/kernel/trace/trace_mmstat.ko \+BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_OUT)/kernel/trace/trace_mmstat.ko \
复制代码
然后将CC脚检测到的耳机信号发出来 
  1. --- a/kernel-4.19/drivers/misc/mediatek/typec/tcpc/rt_pd_manager.c+++ b/kernel-4.19/drivers/misc/mediatek/typec/tcpc/rt_pd_manager.c@@ -52,7 +52,7 @@ void __attribute__((weak)) usb_dpdm_pulldown(bool enable) {         pr_notice("%s is not defined\n", __func__); }-+extern void typec_headphone_irq_handler(int state); static int pd_tcp_notifier_call(struct notifier_block *nb,                                 unsigned long event, void *data) {@@ -91,10 +91,12 @@ static int pd_tcp_notifier_call(struct notifier_block *nb,                 if (noti->typec_state.old_state == TYPEC_UNATTACHED &&                         noti->typec_state.new_state == TYPEC_ATTACHED_AUDIO) {                         /* AUDIO plug in */+                        typec_headphone_irq_handler(1);                         pr_info("%s audio plug in\n", __func__);                 } else if (noti->typec_state.old_state == TYPEC_ATTACHED_AUDIO                         && noti->typec_state.new_state == TYPEC_UNATTACHED) {                         /* AUDIO plug out */+                        typec_headphone_irq_handler(0);                         pr_info("%s audio plug out\n", __func__);                 }                 break;
复制代码
在mt6357-accdet.c加入如下修改 
  1. +void typec_headphone_irq_handler(int state)+{+        if (accdet->cur_eint_state == EINT_PLUG_IN) {+                accdet->cur_eint_state = EINT_PLUG_OUT;+        } else {+                accdet->cur_eint_state = EINT_PLUG_IN;+                mod_timer(&micbias_timer,jiffies + MICBIAS_DISABLE_TIMER);+        }+        queue_work(accdet->eint_workqueue, &accdet->eint_work);+}+EXPORT_SYMBOL(typec_headphone_irq_handler);
复制代码
这时,系统已经能检测到耳机了,播放音乐能正常听到音乐。
但检测到都是3段耳机,理论上正插和反插有一次是对的,不需要举行mic和gnd的切换。
这时丈量micbias电压(有将micbias关闭的地方屏蔽),妥妥的0v。
 
跟mtk沟通,说要屏蔽住这里
  1.         ret = of_property_read_u32(node,                        "headset-eint-num", &tmp);        if (ret)                tmp = 0;        if (tmp == 0)                accdet->data->caps |= ACCDET_PMIC_EINT0;        else if (tmp == 1)                accdet->data->caps |= ACCDET_PMIC_EINT1;        else if (tmp == 2)                accdet->data->caps |= ACCDET_PMIC_BI_EINT;
复制代码
同时加入如下修改
  1. &pmic_accdet{+        headset-use-ap-eint=;}
复制代码

屏蔽后,正插能识别到4段耳机,反插识别为3段耳机。推测PMIC_EINT的作用是accdet中断来了,才华打开micbias,但由于触发不了accdet中断,导致micbias无法开启。
如果像小米一样接纳自动切换mic和gnd的ic FSA4480(https://github.com/MiCode/Xiaomi_Kernel_OpenSource/blob/cezanne-q-oss/drivers/misc/mediatek/accdet/mt6359/accdet.c),这里的工作已经是完成了。
但这里接纳切换ic是需要手工识别的,还需判定mic引脚的电压,如果电压偏低,需要举行切换。
用dct工具设置切换ic的引脚为平凡gpio模式,同时确认该引脚没有被占用
  1. +&pmic_accdet{+        pinctrl-names ="mic_state1","mic_state2";+        pinctrl-0 = ;+        pinctrl-1 = ;+};+&pio {+        mic_state1:mic_state1{+                pins_cmd_dat {+                        pinmux = ;+                        slew-rate = ;  //1输出 0输入+                        bias-disable;+                        output-low;+                };+        };+        mic_state2:mic_state2{+                pins_cmd_dat {+                        pinmux = ;+                        slew-rate = ;+                        bias-disable;+                        output-high;+                };+        };+};
复制代码
在probe中加入如下函数mic_gpio_get(pdev);
  1. static inline int mic_gpio_get(struct platform_device *platform_device){        int ret = 0;        accdet->pinctrl = devm_pinctrl_get(&platform_device->dev);        if (IS_ERR(accdet->pinctrl)) {                ret = PTR_ERR(accdet->pinctrl);                return ret;        }        accdet->mic1 = pinctrl_lookup_state(accdet->pinctrl,                        "mic_state1");        if (IS_ERR(accdet->mic1)) {                ret = PTR_ERR(accdet->mic1);                return ret;        }        accdet->mic2 = pinctrl_lookup_state(accdet->pinctrl,                        "mic_state2");        if (IS_ERR(accdet->mic2)) {                ret = PTR_ERR(accdet->mic2);                return ret;        }        return 0;}
复制代码
  1. --- a/kernel-4.19/sound/soc/codecs/mt6357-accdet.c+++ b/kernel-4.19/sound/soc/codecs/mt6357-accdet.c@@ -99,6 +99,8 @@ struct mt63xx_accdet_data {         /* when caps include ACCDET_AP_GPIO_EINT */         struct pinctrl *pinctrl;         struct pinctrl_state *pins_eint;+        struct pinctrl_state *mic1;+        struct pinctrl_state *mic2;         u32 gpiopin;         u32 gpio_hp_deb;         u32 gpioirq;
复制代码

这里的600对应0.6v,实际该值改为0.4v,应该也是可以的。 

来源:https://blog.csdn.net/mike8825/article/details/112062132
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )