ANX7688 USB-C HDMI bridge on PinePhone (+ USB-C PD)
USB-C connector on PinePhone can be used for:
- USB 2.0 dual role data (aka OTG)
- Configuring PMIC (AXP803) input current limit based on
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 pp-5.8 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 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
- In some configurations (with 3A
USB-C PD charger) AXP803 resets the VBUS input current limit by itself to 500mA,
so PP will not charge (much)
- Forcing the input current limit back up leads to instability (looks like AXP is resetting the limit due to voltage drop on VBUS) and input current fluctuates between 0 and ~1.3A
- With all the docks I have I can't power the PinePhone from them without the above issue happening and causing issues for USB bus enumeration
- It's possible that voltage drop at PMIC terminals is too big when the input current is too high, and PMIC has a limit for the lowest VBUS voltage it allows. After that limit is crossed, the input curren limit is reset to the lowest value (500mA).
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.
get the latest binary of the firmware from my firmware tree.
anx7688-fw.bin. To flash the firmware, you
echo 1 > /sys/class/typec/port0/device/flash_eeprom
Then the driver will work automatically.
PMIC USB Battery Charging
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 ports marked as 2.1A. These are ideal chargers for PinePhone, because they:
- 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
- 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
I recommend these regular BC1.2 spec chargers over USB-C PD chargers, which may not work without software intervention.
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 of course more complicated than the above mentioned BC1.2 spec, and thus more prone to implementation errors, and software bugs.
The Linux driver currently doesn't implement USB-C PD in any complex way. It just configures ANX7688 to notify the other side about the source/sink capabilities of PinePhone (source 500mA, sink 3A at 5V).
Linux driver doesn't yet communicate with PMIC driver to notify it about the current sourcing ability of the other side of the USB-C cable, so USB-C PD charger will only work if it can match the sinking requirements of PinePhone (3A at 5V).
My experience is that my 3A/5V PD charger without
anx7688 driver loaded just keeps disconnecting in a loop if I rise the current
sinking limit above the default for SDP port (>500mA). With the driver
loaded, PinePhone can sink more current without getting disconnects from my PD
charger. The current limit in PMIC needs to be set manually via
In the future, this will be done automatically by the driver.
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 and modded PinePhone (with switches removed). The only feature that doesn't work is SD card reader (may need VCONN). HDMI output works without VCONN.
Sofware workaround for CC pins HW bug in PP 1.0 – 1.2
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.
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.