Nanopi neo: enable USB1 riser cards

In the NanoPI NEO, the Allwinner H3 SoC's USB1 and USB2 interfaces are routed to the board's expansion header. A common use case of this board is to attach peripherals -- such as 4G LTE modems -- via riser cards attached to the expansion header. The upstream kernel's device tree for this board leaves the USB1 and USB2 interfaces disabled by default. Thus, OpenWRT based on this device tree does not recognize such riser cards.

Other distributions such as Armbian provide device tree overlays, which users can install on demand and survive kernel updates, to make USB1 or USB2 available on demand. I don't see a viable mechanism to add device tree overlays to this board in OpenWRT, much less something that would survive a sysupgrade.

As a workaround, I have created a local patch which enables USB1 by default for self-builds of OpenWRT. It functions as expected. As long as I continue to self-build, this will meet my needs; however it would be convenient to find a solution that allows me to use owut to keep the device up to date with upstream builds.

As far as I can tell, I don't think there is a major downside to this patch, even for use in the general case, since my reading of the H3 datasheet suggests that the physical pins used for USB cannot be muxed for any alternative uses. And so from a logical perspective there is zero opportunity cost for enabling their USB functions full-time, since they can never be used for any other purpose; electrically, the risk associated with this seems fundamentally no different from USB headers left unconnected on a generic PC motherboard.

How receptive would the project likely be to a pull request which always enables USB1 by default for the NanoPI NEO?

1 Like

Note: In this context USB1 and USB2 refer to instances of the USB peripheral in the SoC, not revisions of the Universal Serial Bus specification.

Are those headers driven by xhci ehci ohci in some combo?
If so add only required modules to support the port as if it was a common USB port in%o a makef*le for platform.

Yes, simultaneously both ohci and ehci.

It requires patches to the board's dts/dtb, otherwise no kernel modules will recognize the ports.

I have it all working locally, my query is more about whether or not my modification is likely to be accepted for inclusion in the official OpenWRT repositories so that I can take advantage of owut for future upgrades.

It's not like You can plug simple USB cable to exposed pins (like in x86 motherboard) and expect it to work, or is it? If it requires some logic board then I don't think it'll get accepted, but I could be wrong, I'm not a committer, You won't know until You try.

More elegant solutions would be:

  1. Enable CONFIG_OF_OVERLAY in sunxi kernel config and add dtbocfg package to OpenWrt repo which would allow adding overlay on running system.

  2. Check mediatek/filogic subtarget, there are image recipes which have added overlays. Re-implement that in sunxi target.

  3. Use U-Boot package to overlay OpenWrt's provided dtb by adding appropriate command to https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=package/boot/uboot-sunxi/uEnv-default.txt which would use whatever overlay it would find on kernel partition.

2 Likes

Arguably, yeah it would be that simple. The D+, D-, +5V, and GND pins from the header could be directly connected to the exposed wires of a USB cable with the A side cut off, and the B side of the cable would function totally normally.

Are the pins ESD protected or go straight to the SoC? Without the protection it's dangerous and arguably enabling USB pins could encourage users to use them in unsafe manner.

That’s a fair question, I’ll review the schematics when I get home.

Conceptually, I like the idea of enabling the dtbo infrastructure, and supplying overlays in an as needed basis. I’m just worried that I could quickly find myself in over my head.

The USB1, USB2 signals leading to the expansion header do not have surge suppression diodes attached. By comparison, the USB3 signals leading to the onboard Type A port on the board do.

(Oddly, I see that the USB0 signals leading to the power supply/OTG port also don't have surge suppression diodes. With an enclosure in place, it's impractical to even power up the board without attaching something to this port. Maybe attaching excessive circuitry to these signals could interfere with the bootstrapping pull-up/pull-downs that are required to negotiate the OTG protocol?)

1 Like

OTG ports are slightly different kind of beast, they usually have already good protection as part of controller logic. I've seen some boards having suppression diodes (it's always best to have them) while some have none.

In Your case the easiest option is the 3rd one. Simply add check for any existing dtbo file in kernel partition on SD card and load it if it exists. Check the documentation at https://docs.u-boot.org/en/latest/usage/fdt_overlays.html#manually-loading-and-applying-overlays. If You also want for OpenWrt build system to build overlay and add it to appropriate place that means a bit more intrusive changes.

So I guess my use case would be to backup the dtbo file and uboot script onto the data partition; make sure those backups are included in the list of files preserved by sysupgrade; run owut or luci-asu; and then replace the dtbo and uboot script back on the boot partition as a post-install step?

I was thinking You searched for more ad-hoc solution not involving preserving through sysupgrade. With changed requirement You'll need to combine 2nd and 3rd step (unless You want to change kernel image to fit image for sunxi target).

  1. Prepare U-boot like instructed previously
  2. Add dt-overlay to FEATURES in target/linux/sunxi/Makefile
  3. Add DEVICE_DTS_OVERLAY variable to nanopi-neo recipe in target/linux/sunxi/image/cortexa7.mk
  4. Copy dtbo to kernel partition with common recipe in target/linux/sunxi/Makefile

This should get what You want. There won't be the need to backup dtbo, since it will be in new image. Unfortunately this doesn't scale well if someone would like to add another overlay, some of the overlays would conflict with each other. U-boot would need some kind of list which overlay/overlays would be used (something like config.txt in RPi world). This list of overlay/overlays would be only thing needed to be backed up and restored during sysupgrade. You could do that like it's done in RPI target/linux/bcm27xx/base-files/lib/upgrade/keep.d/platform.

Hum, now we are back into possibilities which I fear might not be supported by the project maintainers for addition in the official repos. Which would mean I’d probably have no choice but to continue compiling my own images.

In which case I might just be better off just keeping the locally patched dts file with the USB peripheral enabled by default.

It's always, You won't know until You try. Maybe @wigyori can weight in on the ideas mentioned.

Anyway, rebuilding whole image just for small change in dts is bit overkill. Try out the 1st solution I mentioned. Some time ago I've posted Makefile for dtbocfg https://lists.openwrt.org/pipermail/openwrt-devel/2023-January/040311.html. With that package in place You could add /etc/rc.local comands to load Your dtbo from kernel partition. Add that dtbo to files backed-up on sysupgrade (rc.local is already backed-up) and You should be all set, just remember to have dtbocfg included on every image You'll use on upgrade.

1 Like