mtk平台耳机检测流程记录

耳机检测方案

检测方案1(主流方案):耳机插拔中断接的PMIC (HP_EINT+ACCDET)

CONFIG_ACCDET_EINT_IRQ  &&  CONFIG_ACCDET_SUPPORT_EINT0
CONFIG_ACCDET_EINT_IRQ  &&  CONFIG_ACCDET_SUPPORT_EINT1//平台默认的是EINT0,EINT1不确定具体作用

采用默认的方案,工程师不用调试,接上耳机,手机就能识别到耳机,很方便。
       

 检测方案2:耳机插拔中断接AP(EINT_EAR+ACCDET)  这种方式,需要稍微修改下代码

 

共同点:ACCDET用来检测mic的存在

差异:用不同的中断来检测耳机的插拔,默认都是用PMIC上的中断来检测耳机的插入,使用AP中断的方式来检测耳机感觉像是替补。

先看下耳机检测流程(HP_EINT+ACCDET kernel4.14)

pmic_register_interrupt_callback(INT_ACCDET_EINT0,accdet_eint_handler);

static void accdet_eint_handler(void)
{
	accdet_irq_handle();
}

void accdet_irq_handle(void)
{
...
	pmic_eint_queue_work(eintID);
...
}

static int pmic_eint_queue_work(int eintID)
{
...
#ifdef CONFIG_ACCDET_SUPPORT_EINT0
	if (cur_eint_state == EINT_PIN_PLUG_IN) {
		cur_eint_state = EINT_PIN_PLUG_OUT;
	} else {
		cur_eint_state = EINT_PIN_PLUG_IN;
	}
	queue_work(eint_workqueue, &eint_work); //INIT_WORK(&eint_work, eint_work_callback);
#endif
...
}

static void eint_work_callback(struct work_struct *work)
{
	if (cur_eint_state == EINT_PIN_PLUG_IN) {
		accdet_init();

		/* set PWM IDLE  on */
		pmic_write(ACCDET_STATE_SWCTRL,(pmic_read(ACCDET_STATE_SWCTRL) | ACCDET_PWM_IDLE));
#ifdef CONFIG_ACCDET_EINT_IRQ
#ifdef CONFIG_ACCDET_SUPPORT_EINT0
		enable_accdet(ACCDET_EINT0_PWM_IDLE_B11 | ACCDET_PWM_EN);
#endif
#else
		enable_accdet(ACCDET_PWM_EN);//开启micbias
#endif
	} else {
		/* clc Accdet PWM idle */
		pmic_write(ACCDET_STATE_SWCTRL,pmic_read(ACCDET_STATE_SWCTRL) & (~ACCDET_PWM_IDLE));
		disable_accdet();
		headset_plug_out();
	}

#ifdef CONFIG_ACCDET_EINT
	enable_irq(accdet_irq);
	pr_info("accdet %s enable_irq !!\n", __func__);
#endif
}

这时就可以触发accdet中断(检测耳机类型)

pmic_register_interrupt_callback(INT_ACCDET, accdet_int_handler);
static void accdet_int_handler(void)
{
	accdet_irq_handle();
}

void accdet_irq_handle(void)
{
...	
#ifdef CONFIG_ACCDET_EINT_IRQ
	eintID = get_triggered_eint();
#endif
	irq_status = pmic_read(ACCDET_IRQ_STS);

	if ((irq_status & ACCDET_IRQ_B0) && (eintID == 0)) {
		accdet_queue_work();
	}
}
...	
}

static void accdet_queue_work(void)
{
...	
	ret = queue_work(accdet_workqueue, &accdet_work);//INIT_WORK(&accdet_work, accdet_work_callback);
...	
}

static void accdet_work_callback(struct work_struct *work)
{
...	
	check_cable_type();
...
}

注意到了没有accdet_irq_handle函数跑了两遍,分别跑里面不同的部分。

以后的按键检测重复跑accdet_int_handler。

以上是根据代码分析到的流程。为什么要分析上述流程呢,因为楼主使用的硬件的需要用accdect only的方式来检测typce非标耳机(pmic不带cc脚,不能识别到标准typec耳机,如果使用其他ic来检测耳机会增加成本)。accdect only的方式,mtk说kernel3.18以后都没有维护了,只能自己来实现了,调完了再记录下吧。

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,关于你的第一个问题:i2c总线工作原理和MTK平台配置流程,我可以为你解答。 一、i2c总线工作原理 i2c(Inter-Integrated Circuit)总线是一种串行总线,它由两根线构成:SDA(数据线)和SCL(时钟线)。i2c总线采用主从模式进行通信,主设备负责发起通信请求,从设备则被动地响应请求。 i2c总线的数据传输是通过时钟信号进行同步的。在传输数据时,主设备向从设备发送一个起始信号,再发送从设备的地址和读写位,接着从设备响应确认信号,主设备继续发送数据,从设备再次响应确认信号,直到传输完成,主设备发送停止信号。 二、MTK平台配置流程 1. 打开内核配置菜单 在Linux内核源码树中,使用make menuconfig命令打开内核配置菜单。 2. 配置i2c驱动 在内核配置菜单中,选择Device Drivers -> I2C support -> I2C Hardware Bus support,打开i2c总线驱动的配置选项。 3. 配置MTK i2c控制器 在内核配置菜单中,选择Device Drivers -> I2C support -> I2C Hardware Bus support -> Mediatek I2C controller,打开MTK i2c控制器的配置选项。 4. 配置i2c设备驱动 在内核配置菜单中,选择Device Drivers -> I2C support -> I2C device interface,打开i2c设备驱动的配置选项。 5. 生成内核镜像和设备树 完成内核配置后,使用make命令生成内核镜像和设备树文件。 6. 加载内核模块 将内核镜像和设备树文件烧录到设备上,并加载i2c驱动模块,即可使用MTK平台的i2c总线进行通信。 以上就是关于i2c总线工作原理和MTK平台配置流程的简要介绍,希望能够对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值