[TRACKING] Controlling Power Direction for USB C

Nice work!

When you say reading UCSI version, do you mean reading from EC_MEMMAP_UCSI_VERSION? I notice you mention the address should be ORed with 0x3, but the bits set in EC_MEMMAP_UCSI_VERSION (0x12) overlap with that. There’d be no way to distinguish address 0x10 from 0x12 given that ORing. Perhaps this is related to the problem? I don’t see anything that looks like it could be referencing EC_MEMMAP_UCSI_VERSION’s address in SSDT8 though, so maybe the driver code to read the version simply doesn’t have the address? I could just be barking up the wrong tree of course.

Nah, in this case it looks like Linux is issuing _DSM(..., 2) to trigger a UCSI read, and then pulling VER1 and VER2 from the USBC opregion. Unfortunately, those values are never populated, as SSDT8 never writes to them. This is before it issues any other commands.

I think what ends up happening is this:

  1. Linux issues _DSM(..., 2 /* read */); the opregion is either default-initialized or zeroed.
  2. This flows right into a read from 0x8020 (or, EM1 0x20) via ACPI bytecode
  3. This read populates opregion fields MGI0..MGIF and CCI0..CCI3 with whatever’s in EM1 0x20
  4. Linux reads VER1..VER2, which was not touched, so it gets 00 00
  5. The ucsi_acpi driver bails out because that is an invalid version.

Skipping the version check by forcing it to the correct version from EM1 0x12 results in some success in enumerating the ports and their initial states, but it quickly goes off the rails and the driver starts to complain as UCSI_GET_PDOS, UCSI_GET_CONNECTOR_STATUS and more fail to generate valid responses. I wonder why it starts out “okay”.

Do you know if proper working of USB-PD, while Thunderbolt is in operation (with both DisplayPort and USB 3), depends on the functionality you are investigating here?

I’m connecting my laptop to a Thunderbolt screen with USB-PD but charging is super slow and starts/stops quite often.

I don’t believe so. This is just to give the operating system additional optional control over PD, and it should be able to function normally without it.

1 Like

Thanks. I also noticed the following kernel logs when running mainline kernel. Not sure if it’s of any use to you:

$ sudo dmesg | grep cros
[   67.391816] cros_ec_lpcs cros_ec_lpcs.0: Chrome EC device registered
[   67.665039] cros-usbpd-charger cros-usbpd-charger.2.auto: No USB PD charging ports found
[   67.673102] cros-usbpd-charger cros-usbpd-charger.2.auto: Unexpected number of charge port count
[   67.673105] cros-usbpd-charger cros-usbpd-charger.2.auto: Failing probe (err:0xffffffb9)
[   67.673107] cros-usbpd-charger: probe of cros-usbpd-charger.2.auto failed with error -71
[  217.998856] cros_ec_lpcs cros_ec_lpcs.0: bad packet checksum 1a
[  378.442694] cros-ec-dev cros-ec-dev.1.auto: Some logs may have been dropped...

EDIT: oh I assume this is expected, since EC is not controlling the PD functionality of the ports directly.

1 Like

In your case (sorry, I’ll be brief so as to not take this too far off topic) it might be worth capturing logs from /sys/kernel/debug/cros_ec/console_log when you connect your Thunderbolt screen. It should contain a bunch of info about what power levels it’s seeing/negotiating.

5 Likes

Hello all; I’m hoping I can make my Framework machine send power to an ASUS Zenscreen by USB C - the display only has one C port, and when using as a display the screen is unable to charge. When charging, unable to display.

The charger is able to display and charge in parallel using my employer’s macbook,
so this seems like a Framework power direction issue.

I cloned https://github.com/DHowett/framework-ec,
ran sudo apt install gcc-arm-none-eabi libftdi1-dev,
and ran make utils.

Seems like my ectool is being blocked during simple commands:

grace@chesapeake:~/src/framework-ec$ sudo build/bds/util/ectool typecstatus 0
Cannot open lockfile /run/lock/cros_ec_lockCould not acquire GEC lock.

Also, compiling the EC binary image based on README as a guide, is broken:

grace@chesapeake:~/src/framework-ec$ make BOARD=hx20 CROSS_COMPILE=arm-none-eabi-
Makefile:25: *** unable to locate BOARD hx20.  Stop.

I could use a simple recipe enabling me to reproduce your success on changing the power direction, or some commands I can use to learn more regarding my errors.

I am running Ubuntu Desktop 22.04, and my logs are also missing:

grace@chesapeake:~/src/framework-ec$ sudo cat /sys/kernel/debug/cros_ec/console_log
cat: /sys/kernel/debug/cros_ec/console_log: No such file or directory

Ah, the instructions in the README are from the upstream project and do not reflect the build steps for the modifications I’ve made. You’ll want to follow the steps here.

I do feel I should let you know, though: there’s nothing ectool can do about this problem. The EC is not the Type-C Port Controller. There are two Cypress CCG5s that handle that job. Unless you communicate with them via I2C passthrough, that knowledge may not help.

You will only be able to access the logs on kernels 5.19+. Before that, the cros_ec_lpcs driver would not talk to the Framework Laptop.

Much obliged for the guide link.
Digging deeper, I see there may simply be a voltage mismatch;
https://www.asus.com/us/support/FAQ/1040205
I do remain eager to upgrade my kernel and examine my logs.

I am having the same issue with a power bank - my laptop cannot be charged, and the power bank is charged by my laptop instead. I cannot directly control the direction on my power bank, unfortunately. So I hope to do it on Linux via the controls in /sys/class/typec.

I’ve read through the thread, but it is a bit unclear to me how it was (partially) fixed. Shall I patch the ucsi_acpi driver or the EC? It would be nice if @DHowett could give me a bit more instructions here. Thank you!

I’m following this. I have not yet vetted power banks yet (making sure they are delivering enough to actually work without causing issues. So I’ll be following this.

1 Like

Thank you @Matt_Hartley for tracking this issue!

The power bank can output 100W and has no issue charging other high-power devices. It is based on a popular IP5389 IC. I have several power banks based on this IC, and they unfortunately do not have the functionality of switching input/output directions. They occasionally work and can output 100W if I plug/unplug them multiple times. The USB-C port on the power bank is also used for charging, so both the power bank and the laptop are DRP (Dual Role Port) devices, and the PD controller may get confused. I guess it is hard to robustly choose which device should output power in this situation, so a manual selection of power direction is necessary.

I also have a 12th gen (new) Framework laptop, and it also has the same problem - it cannot be reliably charged using this power bank.

It would be nice to have appropriate controls via /sys/class/typec or other interfaces. I will be very excited if the Framework team can fix the EC/ACPI so port direction selection can work out of the box. Thank you :heart:

1 Like

I’ve noticed that the laptop starts charging the powerbank if, when I insert the cable, the battery is fully charged. Otherwise it’s always goes from power bank to laptop.

1 Like

Just chiming in to say “me too!” :joy:

I bought a heavy duty power bank to use with my Framework laptop since the battery doesn’t last long using Linux… and my laptop is charging the power bank! :person_facepalming: :sob:

1 Like

I think it would be useful to have everyone with a successfully working brand/model of power bank to chime in. Since it’s difficult for me to replicate each of these, this would be useful for us. Thanks!

3 Likes

Solution!

Anker PowerCore III Elite 26K

First press the round button on the top the power bank to wake it up. (The circle of indicator lights on the button will light up). Then plug in the Framework laptop. The power bank will charge the laptop!

(Note that I need to plug in the laptop immediately after waking up the power bank. If I wait too long, the power bank will auto-off, and then plugging in the laptop will cause the power bank to be charged from the laptop.)

I’ve been experimenting more and now I think it’s random. It doesn’t matter if I wake up the power bank first, sometimes it will charge one way, sometimes the other. I just happened to see it charging the laptop after waking up the power bank.

But this is still a solution, if an inelegant one. I can simply plug in the laptop repeatably until it starts charging the laptop.

:tada:

3 Likes

The most reliable method I’ve found for my two Anker power banks is to plug the bank into the laptop while the laptop is off. Since the laptop won’t supply power out its USB ports while off, this pretty much always gets power flowing from the bank to the laptop.

3 Likes

I tried this and the power bank does charge my laptop when it is off, however during the boot process of Windows/Linux the USB port will be reset and then the laptop starts to charge the power bank again. This is very annoying since I cannot charge my laptop while using it.

I also tried to plug/unplug multiple times. Sometimes the power bank charges the laptop for a few seconds, but soon the USB controller seems to be reset and then the laptop starts to charge the power bank instead. It would be great to have a proper control of charge direction.

My power bank is a generic model bought from aliexpress but it internally uses a popular IP5389 charging IC like these ones: https://www.aliexpress.us/item/3256804459348420.html https://www.aliexpress.us/item/3256804058674314.html
https://www.aliexpress.us/item/3256804101065420.html

1 Like

I wish I read this before, I just finished building my 5s3p battery based on the IP5389 and I have the same issue
@Matt_Hartley, do you know what it would take to fix this ?
Can the USB PD module be updated through firmware updates ? Is it open sourced ?

Any updates about this issue ?
Looks like one is supposed to switch sink/source mode in /sys/class/typec/port0/power_role but /sys/class/typec remains empty on my linux.

3 Likes