看我解决Linux下的OTG切换问题

本文详细介绍了如何解决Linux系统中OTG切换导致的问题,包括硬件原理图分析、软件控制的dts部分、引脚初始化代码,以及USB触发中断的处理。通过分析和调试,最终找到解决方案是在OTG拔出时调用特定函数使USB进入device状态。
摘要由CSDN通过智能技术生成

1.硬件原理图

看下面的原理图

VCC_OTG_EN 引脚,这个脚主要是用来控制给外部OTG设备提供电源控制的。如果设备作为DEVICE设备,​这时候VBUS的电是由外部提供的,比如通过USB线和电脑连接,这个时候,VBUS的电压是由电脑提供的。​

如果设备作为HOST设备,比如连接U盘,我们需要给U盘提供VBUS电压,就需要控制VCC_OTG_EN引脚给VBUS提供电压。

USB_OTG_ID 脚​  

这个脚用来判断有OTG设备插

VBUS电压检测,这个电路看不懂有什么作用,硬件设计预期是希望如果有外部的USB设备给设备供电,就切换模式,但是实际上,不管设备作为HOST还是DEVICE,这个电压会一直存在。​所以总觉得这个设计有点问题。

 

 ID脚电压,没有插入OTG设备的时候,电压是​​1.79v​​,插入OTG设备的时候,电压是 ​​0​​V

2.软件控制
dts 部分

&usb0 {
 pinctrl-names = "iddig_irq_init", "drvvbus_init", "drvvbus_low", "drvvbus_high";
 pinctrl-0 = <&usb0_iddig>;
 pinctrl-1 = <&usb0_drvvbus>;
 pinctrl-2 = <&usb0_drvvbus_low>;
 pinctrl-3 = <&usb0_drvvbus_high>;
 usb-power-supply = <&mt6392_vusb_reg>;

 drvvbus_gpio = <&pio 0 2>;
 iddig_gpio = <&pio 41 2>;

 status = "okay";
};

774 /* USB GPIO start */
775         usb0_drvvbus: drvvbus_init {
776                 pins_cmd_dat {
777                         pins = <MT8167_PIN_0_EINT0__FUNC_GPIO0>;
778                         output-low;
779                 };
780         };
781
782         usb0_drvvbus_high: drvvbus_high {
783                 pins_cmd_dat {
784                         pins = <MT8167_PIN_0_EINT0__FUNC_GPIO0>;
785                         slew-rate = <1>;
786                         output-high;
787                 };
788         };
789
790         usb0_drvvbus_low: drvvbus_low {
791                 pins_cmd_dat {
792                         pins = <MT8167_PIN_0_EINT0__FUNC_GPIO0>;
793                         slew-rate = <1>;
794                         output-low;
795                 };
796         };
797         usb0_iddig: iddig_irq_init {
798                 pins_cmd_dat {
799                         pins = <MT8167_PIN_41_KPROW1__FUNC_IDDIG>;
800                         slew-rate = <0>;
801                         bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
802                 };
803         };
804 /* USB GPIO end */
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
引脚初始化部分

void mt_usb_init_drvvbus(void)
{
#if (!(defined(SWITCH_CHARGER) || defined(FPGA_PLATFORM))) && !(defined(OTG_BOOST_BY_SWITCH_CHARGER))
#ifdef CONFIG_OF
#if defined(CONFIG_MTK_LEGACY)
 mt_set_gpio_mode(drvvbus_pin, drvvbus_pin_mode);/*should set GPIO2 as gpio mode.*/
 mt_set_gpio_dir(drvvbus_pin, GPIO_DIR_OUT);
 mt_get_gpio_pull_enable(drvvbus_pin);
 mt_set_gpio_pull_select(drvvbus_pin, GPIO_PULL_UP);
#else
 int ret = 0;

 DBG(0, "****%s:%d Init Drive VBUS!!!!!\n", __func__, __LINE__);
 if (drvvbus_pin < 0)
  return;

 if (IS_ERR(pinctrl))
  return;

 pinctrl_drvvbus = pinctrl_lookup_state(pinctrl, "drvvbus_init");
 if (IS_ERR(pinctrl_drvvbus)) {
  ret = PTR_ERR(pinctrl_drvvbus);
  dev_err(mtk_musb->controller, "Cannot find usb pinctrl drvvbus\n");
 }

 pinctrl_drvvbus_low = pinctrl_lookup_state(pinctrl, "drvvbus_low");
 if (IS_ERR(pinctrl_drvvbus_low)) {
  ret = PTR_ERR(pinctrl_drvvbus_low);
  dev_err(mtk_musb->controller, "Cannot find usb pinctrl drvvbus_low\n");
 }

 pinctrl_drvvbus_high = pinctrl_lookup_state(pinctrl, "drvvbus_high");
 if (IS_ERR(pinctrl_drvvbus_high)) {
  ret = PTR_ERR(pinctrl_drvvbus_high);
  dev_err(mtk_musb->controller, "Cannot find usb pinctrl drvvbus_high\n");
 }

 if (!IS_ERR(pinctrl_drvvbus)) {
  pinctrl_select_state(pinctrl, pinctrl_drvvbus);
  DBG(0, "****%s:%d end Init Drive VBUS KS!!!!!\n", __func__, __LINE__);
 }
#endif
#else
 mt_set_gpio_mode(GPIO_OTG_DRVVBUS_PIN, GPIO_OTG_DRVVBUS_PIN_M_GPIO);/*should set GPIO2 as gpio mode.*/
 mt_set_gpio_dir(GPIO_OTG_DRVVBUS_PIN, GPIO_DIR_OUT);
 mt_get_gpio_pull_enable(GPIO_OTG_DRVVBUS_PIN);
 mt_set_gpio_pull_select(GPIO_OTG_DRVVBUS_PIN, GPIO_PULL_UP);
#endif
#endif
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
3

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值