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设备的时候,电压是 0V
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