USB HOST和device切換原理--基於imx8qm

USB_HOST_GADGET_SWITCH

相關文件

  • kernel_imx\arch\arm64\boot\dts\freescale\fsl-imx8qm-mek-domu.dts: 如果開機固定爲host模式,只需修改dr_mode = “host”;如果需要OTG功能切換,底層是根據ID PIN引腳的高低電平進行判斷(host device),軟件上通過otgsc register判斷。
    &usbotg1 {
    	pinctrl-names = "default";
    	pinctrl-0 = <&pinctrl_usbotg1>;
    	srp-disable;
    	hnp-disable;
    	adp-disable;
    	power-polarity-active-high;
    	disable-over-current;
    	dr_mode = "host";
    	status = "okay";
    };
    
  • kernel_imx/drivers/usb/common/common.c
    --------------------------------------------------
    platform_device->
        ci_get_platdata(dev, platdata);
            ->usb_get_dr_mode(dev);
    --------------------------------------------------
    
    enum usb_dr_mode usb_get_dr_mode(struct device *dev)
    {               
            const char *dr_mode;
            int err;
            
            err = device_property_read_string(dev, "dr_mode", &dr_mode);
            if (err < 0)
                    return USB_DR_MODE_UNKNOWN;
                    
            return usb_get_dr_mode_from_string(dr_mode);
    }       
    EXPORT_SYMBOL_GPL(usb_get_dr_mode); 
    
    
  • kernel_imx\drivers\usb\chipidea\core.c: 由於我們ID腳懸空,則不適用OTG功能,在DTS中直接設置成host,則進入else判斷分支。
    --------------------------------------------------
    ci_hdrc_probe->
        -> ci->role = ci_get_role(ci);
    --------------------------------------------------    
    static enum ci_role ci_get_role(struct ci_hdrc *ci)
    {
    	if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
    		if (ci->is_otg) {
    			hw_write_otgsc(ci, OTGSC_IDIE, OTGSC_IDIE);
    			return ci_otg_role(ci);
    		} else {
    			/*
    			 * If the controller is not OTG capable, but support
    			 * role switch, the defalt role is gadget, and the
    			 * user can switch it through debugfs.
    			 */
    			return CI_ROLE_GADGET;
    		}
    	} else {
    		return ci->roles[CI_ROLE_HOST]
    			? CI_ROLE_HOST
    			: CI_ROLE_GADGET;
    	}
    }
    
  • kernel_imx/drivers/usb/chipidea/otg.c: 此爲OTG功能時讀取OTGSC寄存器進行判斷。
    /**             
     * ci_otg_role - pick role based on ID pin state
     * @ci: the controller  
     */             
    enum ci_role ci_otg_role(struct ci_hdrc *ci)
    {
            enum ci_role role = hw_read_otgsc(ci, OTGSC_ID)
                    ? CI_ROLE_GADGET
                    : CI_ROLE_HOST;
                            
            return role;
    }  
    
    /**
     * hw_read_otgsc returns otgsc register bits value.
     * @mask: bitfield mask
     */
    u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
    {
            struct ci_hdrc_cable *cable;
            u32 val = hw_read(ci, OP_OTGSC, mask);
    
            /*
             * If using extcon framework for VBUS and/or ID signal
             * detection overwrite OTGSC register value
             */
            cable = &ci->platdata->vbus_extcon;
            if (!IS_ERR(cable->edev)) {
                    if (cable->changed)
                            val |= OTGSC_BSVIS;
                    else
                            val &= ~OTGSC_BSVIS;
    
                    if (cable->connected)
                            val |= OTGSC_BSV;
                    else
                            val &= ~OTGSC_BSV;
    
                    if (cable->enabled)
                            val |= OTGSC_BSVIE;
                    else
                            val &= ~OTGSC_BSVIE;
            }
    
            cable = &ci->platdata->id_extcon;
            if (!IS_ERR(cable->edev)) {
                    if (cable->changed)
                            val |= OTGSC_IDIS;
                    else
                            val &= ~OTGSC_IDIS;
    
                    if (cable->connected)
                            val &= ~OTGSC_ID; /* host */
                    else
                            val |= OTGSC_ID; /* device */
    
                    if (cable->enabled)
                            val |= OTGSC_IDIE;
                    else
                            val &= ~OTGSC_IDIE;
            }
    
            return val & mask;
    }
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章