ANX7688 USB-C HDMI bridge on PinePhone (+ USB-C PD)
Hardware
USB-C connector on PinePhone can be used for:
- USB 2.0 dual role data (aka OTG, aka On-The-Go)
- Configuring PMIC (AXP803) input current limit based on
the
Battery Charging Specification
- DisplayPort alternate mode (with a HDMI dongle or USB-C dock)
- Sinking current from USB-C PD charger, or sourcing current to USB-C device like a dock or USB-C hub
- Communicating with USB-C peripherals over CC pins
Current driver status
My latest anx7688 driver work can always be found in my anx-5.15 branch.
The driver handles several things:
- powering up ANX7688 regulators
- monitoring cable detection signal produced by ANX7688 and enabling ANX7688 power based on that
- communication with ANX7688 over I2C
- programming OCM (on-chip microcontroller that controls the PD functionality) firmware into EEPROM inside ANX7688
- configuring ANX7688 firmware within 100ms of the OCM booting the firmware with PinePhone's power and data capabilities
- configuring ANX7688 firmware to enable DisplayPort Alternate Mode
- receiving and sending firmware messages
- communication with sun4i-usb-phy driver to perform USB data role switches and to inform the PHY of VBUS status
- communication with axp20×-usb-supply driver to tell it to change the input current limit based on PD negotiation results
There are some changes to other drivers that are necessary to make this all work:
- modifications to sun4i-usb-phy driver to be able to receive data role changes from anx7688 driver
- modifications to the PMIC driver to make N_VBUSEN an input and to allow adding a vin-supply to the drivevbus regulator
- modifications to the PMIC driver to allow it to use results of PD negotiation instead of USB2.0 style BC1.2 power negotiation
Known issues
- https://xnux.eu/log/#045
- https://xnux.eu/log/#039
- the driver should properly
react to SVID/DP_ALT messages (it ignores them currently, just
logs them)
- it's unclear to me what effects this has on Alt-DP support (it may limit the use of Pinephone with some monitors/dock combinations)
Using the driver
ANX7688 comes preprogramed with factory test firmware. This is not
useable for PinePhone, and it's necessary to re-program the firmware with the
one meant for standalone application
of ANX7688.
You can get
the latest binary of the firmware from my firmware tree.
It's named anx7688-fw.bin
. To flash the firmware, you
need to:
- copy
anx7688-fw.bin
to/lib/firmware
echo 1 > /sys/class/typec/port0/device/flash_eeprom
Then the driver will work automatically.
PMIC and battery charging from USB
Default state without any anx7688 driver and with anx7688 chip shut down is to sink current from USB-C VBUS based on the type of port detected by AXP803 (PMIC), according to Battery Charging Specification 1.2. PMIC is able to detect SDP, CDP or DCP. ACA is not supported, and is not meant for USB-C devices anyway. SDP is regular USB port on your computer. DCP is a dumb USB port with shorted D+/D- lines, typically found on USB wall chargers. CDP is like SDP (allows data communication), but with ability to source higher charging currents. SDP can source 500mA for USB 2.0 ports, and 900mA for USB 3.0 ports. PMIC in PinePhone can't detect USB 3.0 by itself, so even if PinePhone is connected to USB 3.0 SDP, it PMIC will set input current limit to 500mA. Charging port type detection is done once after VBUS is detected. All of the above is unrelated to USB-C PD, and it will work with any USB-A to USB-C cable + regular USB-A adapters.
There are plenty of USB wall adapters with USB-A ports marked as capable of providing 2.1A. These work fine with PinePhone. These chargers:
- work without any software intervention, and the need to negotiate power requirements over USB-C CC pins via ANX7688 firmware (which is only done after Linux boots and powers up ANX7688)
- provide enough power for both (fast)-charging and using the
phone at the same time
- charging limit of the battery is 5W, phone consumes 3–5W when turned on
- 5V/2.1A charger can provide 10W, which is enough power budget for both charging and phone use
- will work even if you kill the battery and are unable to boot Linux
USB-C PD chargers
For USB-C PD charger to work correctly, ANX7688 needs to be powered up and correctly initialized each time a USB-C cable is plugged in. ANX7688 firmware needs to be loaded from internal EEPROM to SRAM and the Linux driver needs to communicate with this firmware via some custom protocol invented by Analogix. On-chip-microcontroller (OCM) that runs the firmware, then controls and monitors the CC pins and sends/relays PD messages from other side of the USB-C cable.
This is more complicated than the above mentioned BC1.2 spec, and thus more prone to implementation errors, and software bugs. As of September 2021, many of the most obvious issues are already ironed out, and Pinephone charging works fine with normal USB-PD Type-C chargers that support at least 5V/3A output. Using a pine convergence dock powered from such chargers is also supported, although you may run into some edge case situations. If you do, reconnecting the dock to the phone should fix those.
Using an USB-C Hub
I have bought a 4-port USB-C to 4× USB-A hub BML 4hub USB-C and it works with the current driver and modded PinePhone (with switches removed). The hub doesn't seem to need VCONN voltage.
Using an USB-C Dock with HDMI port
I have bought a USB-C dock with 3× USB-A USB 3.0 ports, HDMI port, and SD card reader (UMAX U-Connect Type-C Multiport H7 and it almost works with the current driver. The only feature that doesn't work is SD card reader. HDMI output works.
Pinephone HDMI output issues (hot plug detection signal HW issue)
- The issue is present on all Pinephone batches (as of September 2021)
- See https://xnux.eu/log/#045 for details and a workaround
Sofware workaround for CC pins HW bug in PP 1.0 – 1.2
(This and the following sections are only relevant to older pinephone batches that have a HW bug preventing USB-PD from working)
Video out can never be achieved via a SW workaround. It's not possible to even detect cable orientation without CC pins working correctly, let alone negotiate the alt mode switch. It's not possible to detect cable plug/unplug via CC pins. It is only possible to detect VBUS presence via PMIC and only if it's not supplied by the phone already and that is not enough to detect plugin of unpowered devices.
Without working CC pins, it's not possible to make the other side of the cable consume power from PP, or to stop providing its own power. In broken devices CC pins are shorted to the ground, which is an invalid state of CC pins. The charging works at all only because this doesn't matter for USB-C ↔ USB-A cable use. PD chargers are certainly free to interpret this as invalid state and not provide any power over VBUS.
It is only possible to switch data role, or enable/disable VBUS on the PP side. And it will only work if the other side of the cable is dumb enough, or by design has a matching data/power role.
So any SW workaround for the HW issue PP has is limited to enabling OTG host functionality for devices that can't supply power to PP in any way (to be safe), and that are dumb enough to just accept VBUS power without negotiation.
That is, it may be possible for some USB-C hubs. There's no way PP can tell the USB-C peripheral to use the power from the PP, so if the hub is a bit smarter, and will not pass power to devices unless that is properly negotiated, it will not work either.
Certainly any workaround is not safe for a PD enabled docks that have PD input ports, can supply power to CC pins, etc.
Hardware bugs
There are several hardware issues in the circuit around ANX7688 on PinePhone, and it unfortunately needs to be modified to function correctly.
Thankfully, the modifications are mostly component removals. Both modifications are described here:
USB-C CC pins are grounded when VCONN switches are off
I discovered that all the current PP variants (1.0–1.2, Braveheart and at least a part of UBports CE batch) have a major issue, that prevents CC pins from working correctly. This issue will be fixed in revision 1.2a by a component swap.
It's therefore not possible to perform any kind of negotiation and communication over the USB-C CC pins. It's not fixable in SW. It's not possible to configure any USB-C peripherals correctly.
There's a HW mod that you can do to fix CC pins from being hogged by the VCONN switches by removing the switches, or replacing them with a suitable replacement. See my howto, or video from adnidor, or video from mozzwald.
After this HW mod, you'll be able to use USB-C peripherals that don't need VCONN with the driver in my tree if you removed the switches.
ANX7688 draining the battery in a few days when the phone is off
After poweroff PP variants 1.0 and 1.1 still consume around ~20–30mA (this is fixed on 1.2), and this drains the battery in ~2 days even if the phone is turned off.
Samuel Holland discovered that this is fixable by desoldering
U1301
and shorting R1309
. I've made a quick howto on how to do this.