Hi All,
I want to know the overcurrent handling mechanism in linux USB driver of AM335x. Using SDK7.0, linux-3.12. I want to know how exactly it is done based on hardware pin notification.
Regards,
Gangadhar
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi All,
I want to know the overcurrent handling mechanism in linux USB driver of AM335x. Using SDK7.0, linux-3.12. I want to know how exactly it is done based on hardware pin notification.
Regards,
Gangadhar
Hi Gangadhar,
I will forward this to the USB experts for clarification.
There is no discrete OC input on AM335x SoC.
The SoC relies on the USBn_VBUS pin to determine when the USB power switch has experienced an error and will assert VBUS_ERROR and clear the session bit when the voltage of this pin falls below the threshold value as a result of said error.
Many customers utilize a GPIO on the SoC for OC notifications from the USB power switch/supply when such functionality is desired.
Gangadhar Gangu said:I want to know whether overcurrent handling is done in linux driver or clearing of session bit by SoC is sufficient.
When USBn_VBUS detects VBUS voltage drops below the valid threshold, the SoC will clear the session and generate VBUS_ERROR interrupt. The linux driver will try to recover the condition by setting the session.
In SDK6.0 or older releases, this recover has no retry limit - the driver will set the session whenever VBUS_ERROR interrupt is generated. But since SDK7.0, the driver will only retry upto three times. If all the three retries failed, the driver will leave the session off, and the host port is disabled.
Well, if the issue is indeed caused by overcurrent condition, I think fixing this error condition to ensure overcurrent never happen is the best approach. The current driver does not have a way to keep the port disabled and re-enalbe it after the offensive device is removed.
Ok, please try the following from the console to see if it re-enables the port.
# cd /sys/bus/usb/drivers/usb
# ls
bind uevent unbind usb0 usb1
(assume you want to enable usb1 port)
# echo unbind > usb1
# echo bind > usb1
# echo usb1 > unbind
# echo usb1 > bind
AM335x doesn't have a dedicated USB OC pin so USBn_VBUS is used to monitor the state of VBUS. If VBUS droops below ~4.4V while in session the controller will assume the power switch is in OC and will exit the session and de-assert DRVVBUS (if in Host mode).
What kind of interference is causing a 1V drop in VBUS? Can you describe your cable? Do you have the required >=120uF of capacitance on VBUS?
I'm not an expert on the power switches, but based on a cursory review of the data manual I don't see this as being a big problem. I'd always prefer that bulk capacitance be placed as close to the sink (the USB socket in this case) as possible though. Any chance you could replace C35 with =>120uF and retest?
Also, FB8 and FB7 shouldn't typically be needed.
Alessio Cellante said:I have the kernel 3.8.13-bone30 and Ubuntu saucy as OS. I tried the commands posted above but it doesn't make effect.
Please try it again and ensure you do it right.
# cd /sys/bus/usb/drivers/usb
# ls
bind uevent unbind usb0 usb1
(assume you want to enable usb1 port)
# echo usb1 > unbind
# echo usb1 > bind
Please note that depending on your kernel config, you might get 'usb0 usb1' or 'usb1 usb2' under this directory. Regardless, the one with lower suffix is for MUSB0 port, and the one with higher suffix is for MUSB1 port. Please ensure you unbind/bind the right port.
Alessio Cellante said:Frequently the "unbind" requires about 1 minute and a half to complete. Is it normal?
I don't think it is normal. I've never seen it takes that long.
Alessio Cellante said:Sometimes during I wait for unbind completion the whole system reboots itself.
It sounds like the system locked up then watch dog ticked in which causes system reboot.
Alessio Cellante said:Do you know about the usb driver sources?
The usb source is under drivers/usb/{core,musb}/.
Alessio Cellante said:Are they available somewhere?
I am not sure where you got your 3.8.13-bone30 kernel from, but I do know it is not released/supported by TI.
Alessio Cellante said:I can watch inside them in order to find some low level action that (if possible) I can implement in a PRU module in order to only re-enable the usb power.
I would say this is very dangerous hacking, unless you know kernel USB module very well. I would think the best solution is to fix the over-current condition.
Alessio Cellante said:Is there drivers or kernel released/supported by TI for this AM335x that was tested with this unit?
Here is TI released Linux package for AM335x: http://software-dl.ti.com/processor-sw/esd/PROCESSOR-SDK-LINUX-AM335X/latest/index_FDS.html.
Alessio Cellante said:And that is possible to use for restoring correctly the usb session?
No, neither TI kernel or community mainline kernel provides an interface for manipulating the session. It supposed to be transparent to upper layer applications, if the board is designed correctly.
Alessio Cellante said:I can't understand the low level instruction for usb initilization reading the TechnicalReferenceManual. Can you help me in this way?
I am sorry, but I am unable to help you on this. We don't support non-TI released or customized Linux driver/kernel.
Ok, in mainline kernel v4.1 I do have a patch to add an interface to manually enable/disable session, please check the mainline patch: usb: musb: add softconnect for host mode, but I am not sure it will solve your problem, since over-current condition causes an internal flag set in musb driver, I never checked if this flag will be cleared when disable/enable session.
Alessio Cellante said:At this point the device that is connected won't restart. To resume its operation I need to physically unplug and reconnect the device again.
I observed that if the device is disconnected after 'unbind' and a different one is plugged in before 'bind', the new device starts working automatically after 'bind'.
I confirm that I observe the same on am335x EVM. I will be traveling for a few weeks from next week, and will take a look at this once I am back.
Alessio Cellante said:Assuming all is working fine and there are no overcurrent issues with USB, when I use this command:
# echo usb1 > unbind
I can disable the USB functionality.
To resume it, I do:
# echo usb1 > bind
At this point the device that is connected won't restart. To resume its operation I need to physically unplug and reconnect the device again.
It turns out that unbind/bind the usb core driver does not notify the musb controller driver, which causes the failure of enumerating the plugged device. So instead the right sequence should be unbind/bind the musb-dsps driver as following:
# echo '47401400.usb' > /sys/bus/platform/drivers/musb-dsps/unbind
# echo '47401400.usb' > /sys/bus/platform/drivers/musb-dsps/bind
This is for MUSB0 port. For MUSB1 port please use '47401c00.usb' in the commands above.
Please also note that if the port is in otg mode (dr_mode = otg in DT file), you also have to reload the gadget driver after rebind musb-dsps driver.
# modprobe -r <the-gadget-driver>
# modprobe <the-gadget-driver>