完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
前言
平台: rk3288 ,有USB2.0 OTG控制器* 1,USB2.0HOST* 1,EHCI*1(网上说也是USB2.0,具体区别不明) 项目需求:硬件上没有做 otg 模式切换的设计(host模式、device模式), 需要软件上来做软切换的设计。 一般的 otg 接口都是做硬件触发切换的,要想实现软切换, 首先要知道硬件原来是如何切换的,屏蔽掉硬件原来的切换检测代码, 再加上一个软切换的接口,思路明确,问题易解。 一、硬件是如何触发切换的? otg 是使用DWC2同时实现HOST和DEVICE功能 控制器上引出5个脚,OTG_DM|PM,OTG_ID,OTG_VBUS,OTG_EXTR,另一个GPIOX OTG_EXTR:43.2ohm到地,调节电阻可调节USB信号质量,不同芯片阻值不同 GPIOX:用于控制是否输出USB向外5V OTG_VBUS:输入信号!别被名字骗了,用于USB DEVICE检测VBUS电平,连PC约为3V,无为0V OTG_ID:输入信号,用于识别外接设备为模式(host,dev),默认上拉处于Dev,如果控制器进入HOST 文档描述:DWC2是通过检测 OTG_ID 脚上的电平来切换模式的, OTG_ID 脚电平变化触发控制器的ID脚中断,然后由软件来切换模式。 由这个描述,可以认为之前修改思路是可以的。 二、软件是如何切换的? rk3288的SDK中提供了两套驱动:dwc2,dwc_otg_310;用其一即可 这里使用的是dwc2驱动,找到如下函数: irqreturn_t dwc2_handle_common_intr(int irq, void *dev) { struct dwc2_hsotg *hsotg = dev; u32 gintsts; irqreturn_t retval = IRQ_NONE; spin_lock(&hsotg->lock); if (!dwc2_is_controller_alive(hsotg)) { dev_warn(hsotg->dev, "Controller is deadn"); goto out; } gintsts = dwc2_read_common_intr(hsotg); if (gintsts & ~GINTSTS_PRtiNT) retval = IRQ_HANDLED; if (gintsts & GINTSTS_MODEMIS) dwc2_handle_mode_mismatch_intr(hsotg); if (gintsts & GINTSTS_OTGINT) dwc2_handle_otg_intr(hsotg); if (gintsts & GINTSTS_CONIDSTSCHNG) dwc2_handle_conn_id_status_change_intr(hsotg); if (gintsts & GINTSTS_DISCONNINT) dwc2_handle_disconnect_intr(hsotg); ... ... } 如代码所示,dwc给到中断后,会触发以上中断处理函数, 函数根据寄存器值来判断是何种中断,并进行相应操作, 不难看出如果ID电平变化,应该触发的是 dwc2_handle_conn_id_status_change_intr static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) { u32 gintmsk; /* Clear interrupt */ dwc2_writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS); /* Need to disable SOF interrupt immediately */ gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk &= ~GINTSTS_SOF; dwc2_writel(gintmsk, hsotg->regs + GINTMSK); dev_dbg(hsotg->dev, " ++Connector ID Status Change Interrupt++ (%s)n", dwc2_is_host_mode(hsotg) ? "Host" : "Device"); /* * Need to schedule a work, as there are possible DELAY function calls. * Release lock before scheduling workq as it holds spinlock during * scheduling. */ if (hsotg->wq_otg) { spin_unlock(&hsotg->lock); queue_work(hsotg->wq_otg, &hsotg->wf_otg); spin_lock(&hsotg->lock); } } 好像没看到具体的切换操作,最后面跑了一个work,来看下这个work INIT_WORK(&hsotg->wf_otg, dwc2_conn_id_status_change); static void dwc2_conn_id_status_change(struct work_struct *work) { struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg, wf_otg); u32 count = 0; u32 gotgctl; unsigned long flags; dev_dbg(hsotg->dev, "%s()n", __func__); if (!hsotg->ll_phy_enabled && dwc2_is_host_mode(hsotg)) dwc2_lowlevel_phy_enable(hsotg); gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); dev_dbg(hsotg->dev, "gotgctl=%0xn", gotgctl); dev_dbg(hsotg->dev, "gotgctl.b.conidsts=%dn", !!(gotgctl & GOTGCTL_CONID_B)); /* B-Device connector (Device Mode) */ if (gotgctl & GOTGCTL_CONID_B) { dwc2_vbus_supply_exit(hsotg); /* Wait for switch to device mode */ dev_dbg(hsotg->dev, "connId Bn"); ... ... } else { host: /* A-Device connector (Host Mode) */ dev_dbg(hsotg->dev, "connId An"); ... ... } } 看这注释,没错就是这里了,嘻嘻嘻。 三、功能的实现及一些问题 问题一:如何设置开机默认的状态 项目中OTG_ID明明是下拉的,但是开机后却发现是device,具体原因未明,在初始化时可做一下处理 static int dwc2_driver_probe(struct platform_device *dev) { ... if (hsotg->dr_mode != USB_DR_MODE_HOST) { retval = dwc2_gadget_init(hsotg, hsotg->irq); if (retval) goto error; hsotg->gadget_enabled = 1; } if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) { retval = dwc2_hcd_init(hsotg, hsotg->irq); if (retval) { if (hsotg->gadget_enabled) dwc2_hsotg_remove(hsotg); goto error; } hsotg->hcd_enabled = 1; } // add if (hsotg->dr_mode == USB_DR_MODE_OTG) { hsotg->dr_mode = USB_DR_MODE_HOST; dwc2_force_dr_mode(hsotg); } // add end ... } 问题二:如何去掉原有的检测 去掉软件上对 id 切换的检测,方法:注释掉比较是否是 id 切换 if 语句。 问题三:如何添加节点 接口就做一个store就可以了,把 dwc2_conn_id_status_change 代码搬过去稍作修改即可。 总结 需要某功能前,应该仔细阅读一下源码,有没有提供相应功能,很多时候都是有相应接口的, 即便没有,源码中也大可能会有同功能的代码段,可以借鉴。 原作者:唯见月寒日暖 |
|
相关推荐
1个回答
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
353 浏览 1 评论
1758 浏览 1 评论
3013 浏览 1 评论
synopsys 的design ware:DW_fpv_div,浮点数除法器,默认32位下,想提升覆盖率(TMAX),如果用功能case去提升覆盖率呢?
3751 浏览 1 评论
RK3588 GStreamer调试四路鱼眼摄像头四宫格显示报错
6562 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 23:11 , Processed in 1.358202 second(s), Total 71, Slave 55 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号