iMX8MN USB OTG role reversal

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMX8MN USB OTG role reversal

Jump to solution
1,648 Views
dvlogic
Contributor III

Hi,

I'm trying to dynamically configure my custom i.MX8M nano board to switch USB roles from host mode to gadget (or peripheral).  I currently have my board configured as a USB host and I'm able to enumerate a USB FTDI serial device. All works as expected.

I would like to configure the dr_mode as "otg" and setup my board to either be a host device as I have today or dynamically switch it to be a USB mass storage peripheral (gadget).

I can't find any working examples and I'm hoping someone could help me.  It seems when I configure my DTS to be dr_mode = "otg" with usb-role-switch enabled, I can't get any USB functionality to work.  If I run some USB mass storage gadget example code, the best I get is an error "udc-core: couldn't find an available UDC or it's busy"

I'm confident my USB hardware is correct since I can run the uboot "ums mmc 2" command to make my board enumerate as a mass storage USB device.  Also, as stated above, I can connect the USB to a FTDI serial port and configure it as a my DTS to be dr_mode = "host" and that works too.

I'm currently running a custom Linux build based on imx-5.10.72-2.2.0 (Yocto hardknott).  

 

Labels (1)
0 Kudos
1 Solution
1,584 Views
dvlogic
Contributor III

I solved this today through a whole lot of trial and error.  

I made my DTS for usbotg as follows:

&usbotg1 {
	dr_mode = "otg";
	hnp-disable;
	srp-disable;
	adp-disable;
	disable-over-current;
	usb-role-switch;
	role-switch-default-mode = "host";
	samsung,picophy-pre-emp-curr-control = <3>;
	samsung,picophy-dc-vol-level-adjust = <7>;
	status = "okay";

	assigned-clocks = <&clk IMX8MN_CLK_USB_BUS>,
			  <&clk IMX8MN_CLK_USB_CORE_REF>;
	assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>,
				 <&clk IMX8MN_SYS_PLL1_100M>;
};

And then after I configured my mass_storage device in the /sys/kernel/config/usb_gadget path, I had to do the following to get it to enumerate to my host.

echo device > /sys/bus/platform/devices/ci_hdrc.0/usb_role/ci_hdrc.0-role-switch/role

 

The final missing thing that I want to figure out is how to know when the host has ejected/un-mounted my mass storage USB gadget so that I can take action on what was transferred from the host to my device.

 

 

View solution in original post

5 Replies
1,610 Views
Dhruvit
NXP TechSupport
NXP TechSupport

Hi @dvlogic,

I hope you are doing well
 
 If I run some USB mass storage gadget example code, the best I get is an error "udc-core: couldn't find an available UDC or it's busy"
=> Please try to add the below configuration in the kernel.
USB_G_SERIAL [=m]
Kindly refer to section 4.9 USB of i.MX Linux Reference Manual for more configuration.
 
If it does not solve the issue, kindly share your device tree node.
 
Thanks & Regards,
Dhruvit Vasavada
0 Kudos
1,591 Views
dvlogic
Contributor III

No the solution you posted still doesn't work for me. 

The problem I was having with udc-core was related to me adding the following config to my kernel build "CONFIG_USB_FSL_USB2" - this was a stupid cut-n-paste from some other post.

Now I am back to trying to get my device to work in gadget "peripheral" mode.  The fundamental problem is my custom hardware is designed with only a USB-A port (which is doesn't expose the USB_ID pin to the external host).  The USB_ID pin is floating on the hardware.  In addition VBus is hardwired to +5 volts.

With the driver, I am able to set the role as "host" had communicate with external USB peripherals.  However, when I set the role as gadget and program a USB gadget config, I never can get my board to enumerate to an external host. 

I'm convinced there must be a software work-around since the same hardware will enumerate as a mass storage gadget device when I boot directly to U-Boot and run the command "ums mmc 2"

Let me know if you have any thoughts on where I should look for a software work-around.

Thanks!

0 Kudos
1,585 Views
dvlogic
Contributor III

I solved this today through a whole lot of trial and error.  

I made my DTS for usbotg as follows:

&usbotg1 {
	dr_mode = "otg";
	hnp-disable;
	srp-disable;
	adp-disable;
	disable-over-current;
	usb-role-switch;
	role-switch-default-mode = "host";
	samsung,picophy-pre-emp-curr-control = <3>;
	samsung,picophy-dc-vol-level-adjust = <7>;
	status = "okay";

	assigned-clocks = <&clk IMX8MN_CLK_USB_BUS>,
			  <&clk IMX8MN_CLK_USB_CORE_REF>;
	assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>,
				 <&clk IMX8MN_SYS_PLL1_100M>;
};

And then after I configured my mass_storage device in the /sys/kernel/config/usb_gadget path, I had to do the following to get it to enumerate to my host.

echo device > /sys/bus/platform/devices/ci_hdrc.0/usb_role/ci_hdrc.0-role-switch/role

 

The final missing thing that I want to figure out is how to know when the host has ejected/un-mounted my mass storage USB gadget so that I can take action on what was transferred from the host to my device.

 

 

1,553 Views
Dhruvit
NXP TechSupport
NXP TechSupport

Hi @dvlogic,

I hope you are doing well
 
If your issue is resolved, should we close this thread?
 
Thanks & Regards,
Dhruvit Vasavada

0 Kudos
1,547 Views
dvlogic
Contributor III
Yes, I even self marked it as solved - go ahead and close!
0 Kudos