有无TYPE-C方案,主从识别和耳机的插拔检测不同;有TYPE-C情况下,主要为TYPE-C逻辑进行侦测;而没有TYPE-C的方案;主从区分需要USB-ID detect管脚进行判断,耳机则靠HP-DET进行区分;
传统侦测方式
主从侦测
在没有TYPE-C的硬件上,主要靠USB-ID管脚的上下拉来区分主从;
耳机侦测
耳机结构
3.5mm耳机插头有三段(TRS,Tip-Ring-Sleeve)和四段(TRRS,Tip-Ring-Sleeve)之分,其中三段的不带麦克风,尾段(Sleeve)是公共地;中间环(Ring)是右声道,尖部(Tip)是左声道,四节的分两种,一种是CTIA,一种是OMTP;
HP-L耳机左声道,HP-R耳机右声道,GND接地,V-Mic语音麦克风
耳机座以及传统耳机侦测介绍
耳机座分为支持欧标设计的耳机座和支持美标的耳机座。另外从耳机座左声道的检测方式来又可以分为”Normal-closed type”(常闭型)和“Normal -type”(常开型)两种。设计图如下:
. 在常闭型中,不接耳机时,耳机座左声道和检测端HS-DET接触,接入耳机时,HS-DET与HPH-L不导通
. 在常开型中,不接耳机时,耳机座左声道和检测端HS-DET不接触,插入耳机时,HS-DET与HPH-L导通
如图为常开型结构,HP-DET上拉,当插入耳机后HP-DET和HP-OUTL导通,DET下拉引起软件中断。软件上通过debounce后,检测到持续的低电平,于是认为耳机插入;这时候需要判断,插入的还是三段还是四段,平台上打开mic_bias,当插入的是三段耳机,MIC被拉低,于是判断为三段耳机;若为四段耳机,MIC接近于MIC_BIAS,软件判断该处的直流电压为四段耳机;当按键按下时,MIC的电压发生变化,触发了系统中断,之后软件通过采样该处的电压值确定按下了哪一个按键;
TYPE-C方案侦测方式讲解
TYPE-C主要电路如下
Type-C连接并没有在物理结构上区分DFP(Host)和UFP(Device),无连接时DFP未给VBUS供电,连接后通过CC信号线配置,确认连接有效,VBUS供电打开并确认使用哪一个端口传输数据;
状态说明
如图所示
DFP的CC1/CC2会接上拉电阻Rp或电流源,UFP的CC1/CC2会接下拉电阻Rd,AUDIO设备则会接两个下拉电阻
如何确认当前TYPE_C接入设备类型:
echo 1 > /sys/class/axp/axp_num
echo 0x37 > /sys/class/axp_reg && cat /sys/class/axp/axp_reg
若读出状态为ATTACH_SNK 说明接入的是适配器或pc
若读出的状态为ATTACH_SOURCE 说明此时作为host
如读出为AUDIO_ACSY,说明此时为音频设备
TS5USBA224RSWR:
用于将D-,D+在(USB0-DM,USB0-DP),(HPOUTL,HPOUTR)两种模式之间切换;由于VBUS默认低后,无法满足通过SEL切换状态,故VBUS一般设置为高;通过ASEL来设置高低实现切换
TS3A226AE:
可以用于区分三四节耳机,并且可以将MIC和GROUND区分出来,降低软件设计复杂度;
使用TYPE-C方案时,TYPE-C 中断服务程序负责将D-,D+选择为USB模式的Dp,Dm或者为耳机模式HP-OUTL,HP-OUTR;并通知音频驱动耳机接入;
软件流程为:
一:bmu驱动产生中断:
irqreturn_t axp_tc_in_isr(int irq, void *data)
{
struct axp_charger_dev *chg_dev = data;
#ifdef CONFIG_TYPE_C_AUDIO
struct axp_usb_info *usb = chg_dev->spy_info->usb;
u8 cc_mode = 0;
/*axp_usbac_in(chg_dev);*/
cc_mode = usb->get_cc_mode(chg_dev); //获取cc 侦测结果
if (cc_mode == AUDIO_ACSY) { //如果为音频设备
usb->set_sel_mode(chg_dev, 1); //D+ D- 连接到耳机的左右声道
call_notifier_call_chain(1); //通知耳机驱动耳机接入
} else {
usb->set_sel_mode(chg_dev, 0); //D+ D- 连接到 USB的 Dp,Dm口
call_notifier_call_chain(0); //通知耳机驱动拔出
}
#endif
axp_change(chg_dev);
return IRQ_HANDLED;
}
二:耳机接受到通知:
static int type_c_chain_notify(struct notifier_block *nb, unsigned long mode, void *_unused)
{
struct mc_private *ctx = container_of(nb, struct mc_private, type_c_chain_nb);
if (mode) {
ctx->detect_state = PLUG_IN; //切换接入状态
printk("%s PLUG_IN", __func__);
} else {
ctx->detect_state = PLUG_OUT;
printk("%s PLUG_OUT", __func__);
}
schedule_delayed_work(&ctx->hs_detect_work,
msecs_to_jiffies(10)); //执行音频相关的处理函数
return 0;
}
软件配置demo
使能TYPE-C SINK与SOURCE 检测功能:
一:sys_config.fex中:
usb_id_gpio = "axp_ctrl"
二:deconfig中
CONFIG_TYPE_C=y
使能TYPE-C耳机功能
一:如原理图所示,使用的是PH10作为选通管脚,故对pmu_typc_c_sel进行配置
[charger0]
compatible = "bmu1760-charger"
pmu_type_c_sel = port:PH10<1><default><default><0>
pmu_chg_ic_temp = 0
pmu_battery_rdc = 100
pmu_battery_cap = 4200
二:deconfig中
CONFIG_TYPE_C_AUDIO=y