通常情况下,usb设备作为device使用时是需要从host端供电的(5 V)。因此,手机主板功能开发时,如果考虑支持OTG功能,则需要外接一颗芯片对外供电。在展讯平台上,我们外接的是FAN54015这颗IC,支持charge/otg(供电)功能。
但是,公司最近在帮客户调试的一个项目上,客户要求在没有外接供电IC的情况下支持OTG功能。我们提出,没有供电怎么办?客户说,木有事,他们的USB 设备自带5V电源。我们再提出,没有OTG中断检测怎么办?客户又说,接一个跳线到中断脚,当usb device接入时,手动将跳线接地。好吧,话说到这个份上,那我们开撸吧,不,开始实现这个功能吧,不过……
要确保usb device电源的供电能力(电流)满足usb设备的工作电流要求。
要确保usb device电源的供电能力(电流)满足usb设备的工作电流要求。
要确保usb device电源的供电能力(电流)满足usb设备的工作电流要求。
1. 修改OTG中断检测gpio口配置,将其配置为EIC模式,输入使能
{REG_PIN_EXTINT1, BIT_PIN_SLP_AP|BIT_PIN_NULL|BITS_PIN_DS(1)|BITS_PIN_AF(0)|BIT_PIN_WPU|BIT_PIN_SLP_WPU|BIT_PIN_SLP_IE},
2. 修改DTS文件里的usb配置,设置OTG检测脚
gpios = <&a_eic_gpio 0 0>,<&d_eic_gpio 1 0>;
3. Kernel config配置
// 打开UMS的支持
CONFIG_USB_STORAGE=y
// 打开Host模式的支持
# CONFIG_SPRD_USB_DEVICE_ONLY is not set
4. 将dwc_otg_hcd_linux.c文件usb_otg_cable_detect_work函数里的OTG对外供电的代码注释掉,因为我们已经不需要对usb device供电了
void usb_otg_cable_detect_work(void *p)
{
dwc_otg_device_t *otg_dev = p;
struct sprd_usb_platform_data *platform_data =&otg_dev->platform_data;
int value = 0;
int vbus_irq;
vbus_irq = usb_get_vbus_irq();
value = usb_get_id_state();
if (value){
pr_info("usb otg cable detect work plug out\n");
#ifdef CONFIG_SPRD_EXT_IC_POWER
sprd_extic_otg_power(0); //Turn off ext ic otg func
udc_disable();
mdelay(10);//charge pump need time to turn off
#else
//otg_cable_disconnect(otg_dev->core_if);
// charge_pump_set(platform_data->gpio_boost,0);//注释掉
udc_disable();
mdelay(10);//charge pump need time to turn off
#endif
enable_irq(vbus_irq);
} else {
pr_info("usb otg cable detect work plug in\n");
#ifdef CONFIG_SPRD_EXT_IC_POWER
sprd_extic_otg_power(1); //Turn off ext ic otg func
udc_enable();
#else
// charge_pump_set(platform_data->gpio_boost,1);// 注释掉
udc_enable();
#endif
dwc_otg_core_fore_host(otg_dev->core_if);
dwc_otg_core_init(otg_dev->core_if);
_start(otg_dev->hcd);
dwc_otg_enable_global_interrupts(otg_dev->core_if);
}
}
5. 开启上层支持host ums的控制开关,scx35_xxxx.mk文件里加入如下代码:
ifndef ENABLE_OTG_USBDISK
ENABLE_OTG_USBDISK := true
endif
6. Fstab修改:
Device/sprd/scx35/emmc/fstab_dt.sc8830
/devices/dwc_otg.0/usb1/1-1/1-1:1.0 auto vfat defaults voldmanaged=usbdisk:auto
修改为
/devices/f5116000.usb/usb1/1-1/1-1:1.0 auto vfat defaults voldmanaged=usbdisk:auto
注意:
(1) OTG功能的中断检测脚一定使用带硬件防抖功能的中断脚(在7731上就是eint0/eint1)。我们曾经尝试使用其他普通的中断脚,结果中断异常。
(2) USB device的供电能力一定要满足usb设备的工作电流要求。在调试中,由于客户的usb device的供电能力不足,导致系统出现了开机死机重启、读取usb device时重启、鼠标功能正常而U盘不识别等异常现象。在我们直接外接一个5V DC电源对USB 设备供电后,上述问题消失(在实验中我们发现:usb鼠标的工作电流约为10-15ma,而U盘的工作电流约为40-70ma)。
但是,公司最近在帮客户调试的一个项目上,客户要求在没有外接供电IC的情况下支持OTG功能。我们提出,没有供电怎么办?客户说,木有事,他们的USB 设备自带5V电源。我们再提出,没有OTG中断检测怎么办?客户又说,接一个跳线到中断脚,当usb device接入时,手动将跳线接地。好吧,话说到这个份上,那我们开撸吧,不,开始实现这个功能吧,不过……
要确保usb device电源的供电能力(电流)满足usb设备的工作电流要求。
要确保usb device电源的供电能力(电流)满足usb设备的工作电流要求。
要确保usb device电源的供电能力(电流)满足usb设备的工作电流要求。
重要的事情连说3遍,因为客户做的usb设备自带电源供电能力不足(电压测量达到5v),导致在调试过程中出现了系统开机重启,进入OTG功能重启等等异常问题,使得我们颇费一番周折,才顺利实现了OTG功能。兄弟们,这可是血的教训啊。
1. 修改OTG中断检测gpio口配置,将其配置为EIC模式,输入使能
{REG_PIN_EXTINT1, BIT_PIN_SLP_AP|BIT_PIN_NULL|BITS_PIN_DS(1)|BITS_PIN_AF(0)|BIT_PIN_WPU|BIT_PIN_SLP_WPU|BIT_PIN_SLP_IE},
2. 修改DTS文件里的usb配置,设置OTG检测脚
gpios = <&a_eic_gpio 0 0>,<&d_eic_gpio 1 0>;
3. Kernel config配置
// 打开UMS的支持
CONFIG_USB_STORAGE=y
// 打开Host模式的支持
# CONFIG_SPRD_USB_DEVICE_ONLY is not set
4. 将dwc_otg_hcd_linux.c文件usb_otg_cable_detect_work函数里的OTG对外供电的代码注释掉,因为我们已经不需要对usb device供电了
void usb_otg_cable_detect_work(void *p)
{
dwc_otg_device_t *otg_dev = p;
struct sprd_usb_platform_data *platform_data =&otg_dev->platform_data;
int value = 0;
int vbus_irq;
vbus_irq = usb_get_vbus_irq();
value = usb_get_id_state();
if (value){
pr_info("usb otg cable detect work plug out\n");
#ifdef CONFIG_SPRD_EXT_IC_POWER
sprd_extic_otg_power(0); //Turn off ext ic otg func
udc_disable();
mdelay(10);//charge pump need time to turn off
#else
//otg_cable_disconnect(otg_dev->core_if);
// charge_pump_set(platform_data->gpio_boost,0);//注释掉
udc_disable();
mdelay(10);//charge pump need time to turn off
#endif
enable_irq(vbus_irq);
} else {
pr_info("usb otg cable detect work plug in\n");
#ifdef CONFIG_SPRD_EXT_IC_POWER
sprd_extic_otg_power(1); //Turn off ext ic otg func
udc_enable();
#else
// charge_pump_set(platform_data->gpio_boost,1);// 注释掉
udc_enable();
#endif
dwc_otg_core_fore_host(otg_dev->core_if);
dwc_otg_core_init(otg_dev->core_if);
_start(otg_dev->hcd);
dwc_otg_enable_global_interrupts(otg_dev->core_if);
}
}
5. 开启上层支持host ums的控制开关,scx35_xxxx.mk文件里加入如下代码:
ifndef ENABLE_OTG_USBDISK
ENABLE_OTG_USBDISK := true
endif
6. Fstab修改:
Device/sprd/scx35/emmc/fstab_dt.sc8830
/devices/dwc_otg.0/usb1/1-1/1-1:1.0 auto vfat defaults voldmanaged=usbdisk:auto
修改为
/devices/f5116000.usb/usb1/1-1/1-1:1.0 auto vfat defaults voldmanaged=usbdisk:auto
注意:
(1) OTG功能的中断检测脚一定使用带硬件防抖功能的中断脚(在7731上就是eint0/eint1)。我们曾经尝试使用其他普通的中断脚,结果中断异常。
(2) USB device的供电能力一定要满足usb设备的工作电流要求。在调试中,由于客户的usb device的供电能力不足,导致系统出现了开机死机重启、读取usb device时重启、鼠标功能正常而U盘不识别等异常现象。在我们直接外接一个5V DC电源对USB 设备供电后,上述问题消失(在实验中我们发现:usb鼠标的工作电流约为10-15ma,而U盘的工作电流约为40-70ma)。