13

Say I have a laptop and a powerbank (or two laptops) with USB type C connected together, then how is it decided which charges which?

Is it controlled by the driver? Does Linux kernel supports such control?

Update:

I see this patch set (currently v14) but it's not in mainline yet.

https://lwn.net/Articles/710741/

But something called UCSI is in 4.10 already:

http://lxr.free-electrons.com/source/drivers/usb/misc/Kconfig

270 config UCSI
271         tristate "USB Type-C Connector System Software Interface driver"
272         depends on ACPI
273         help
274           UCSI driver is meant to be used as a convenience tool for desktop and
275           server systems that are not equipped to handle USB in device mode. It
276           will always select USB host role for the USB Type-C ports on systems
277           that provide UCSI interface.

So is it correct to say that the Linux kernel driver for this problem is work in progress as of 4.10?

  • 2
    I know my android phone gives me the option to choose "Charge this device" or "Supply Power" so my assumption is it can be controlled by the driver/OS. – heavyd Mar 17 '17 at 21:10
  • 1
    Good question. And it looks like this is ripe for a userspace/contrib UI to be written by the community. Would be nice to have a UI like Android has to control the flow of power. – Elijah Lynn Oct 25 '22 at 21:08

3 Answers3

9

In Linux you can control the direction of power on a given port by writing "source" or "sink" to the appropriate sysfs control, eg.:

# echo source >/sys/class/typec/port0/power_role
# cat /sys/class/typec/port0/power_role
[source] sink

The term in bracket indicates how is power currently flowing. See the kernel documentation see: https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-typec

Of course all of this works only if the device connected to the USB Type-C port supports Power Delivery. So it won't work with a typical Type-C power adapter or most Type-C portable batteries as they rarely support PD as of 2019.

Marc Bevand
  • 106
  • 1
  • 1
  • This is actually the patch that I linked in the question. It's finally merged in the 4.19 cycle. – user3528438 Sep 25 '19 at 04:23
  • 1
    You can control direction of power on a "given port" if the "given port" supports Power Delivery in hardware, which includes the port on a "given gadget". Which is a very big "IF", since USB, Type-C, and PD are nearly independent specifications, and all depends on how a manufacturer of a "given device" feels about implementing all 3 together. So to believe that some "term in bracket" on some Linux terminal window controls anything is very naive. – Ale..chenski Sep 26 '19 at 03:07
  • 2
    Ale..chenski: not naive at all. If the port doesn't support PD, or if the remote device doesn't support PD, the echo command will clearly indicate it with an Input/Output Error or Operation Not Supported error. See power_role_store() in drivers/usb/typec/class.c. Whatever is shown in bracket is what is supported by the port, supported by the device, and successfully configured at the hardware level. – Marc Bevand Sep 26 '19 at 05:21
  • This answer makes sense, however, I am getting (even with sudo) the error:

    warning: An error occurred while redirecting file '/sys/class/typec/port1/power_role' open: Permission denied.

    – Elijah Lynn Oct 25 '22 at 21:01
  • The file exists and I can cat it out just fine. Kernel 5.19. – Elijah Lynn Oct 25 '22 at 21:07
  • 3
    If you do sudo echo sink > /sys... shell tries to open the file for writing before it runs sudo. Have you tried sudo bash -c 'echo sink > /sys...`? – Zaar Hai Nov 20 '22 at 07:35
  • @MarcBevand I'm getting Input/output error while trying to write to the /sys/class/typec/port0/power_role. Is there a way around it? My power-bank is capable of 20v@2.5A and /sys/class/typec/port0/power_operation_mode (while PB charges the laptop) is usb_power_delivery (P.S. I'm on kernel 5.16.64) – Zaar Hai Nov 20 '22 at 07:38
  • Thanks Zaar, I tried the sudo bash -c wrapper and now I don't get permission denied but get "bash: line 1: echo: write error: Invalid argument". – Elijah Lynn Feb 02 '23 at 19:10
  • If I echo "sink" it works, but "source" gives invalid argument. So it appears it is not liking the name of the argument. Because I tried stripping the newline out of echo with echo -n and that doesn't make a difference. – Elijah Lynn Feb 02 '23 at 19:19
  • I found the source for my kernel, 6.1.8 and did verify that the two valid role names are in fact "source" and "sink", https://elixir.bootlin.com/linux/v6.1.8/source/drivers/usb/typec/class.c#L1312. I also tried "duel" without success. – Elijah Lynn Feb 02 '23 at 19:32
  • If I unplug the power brick then I get "bash: line 1: echo: write error: Input/output error" and if it is plugged in I get "bash: echo: write error: Invalid argument". Progress! – Elijah Lynn Feb 02 '23 at 19:37
  • Worth noting is that cat /sys/class/typec/port1/vconn_source == "no". I wonder if that needs to be "yes". I did an ls -al on /sys/class/typec/port1/ and there are other file configs of note, like supported_accessory_modes (none), power_operation_mode (usb_power_delivery) and preferred_role (null/empty). – Elijah Lynn Feb 02 '23 at 19:43
  • Updating vconn_source is "bash: line 1: /sys/class/typec/port1/vconn_source: Permission denied" even with the sudo bash wrapper, and then I see the file perms for root are only read, not read/write. Only files that have write are data_role and power_role so that is good to know. – Elijah Lynn Feb 02 '23 at 19:46
  • The power bank I have is a RavPower PD Pioneer 20000 (Model RP-PB201) and on the back it says PD Input: 5v- 3a and so on, so it looks like it supports PD input. Maybe the kernel isn't seeing it that way though... – Elijah Lynn Feb 02 '23 at 20:36
  • Still doesn't work on Lenovo Thinkpad Yoga 6, even with kernel 6.1.34 – Zaar Hai Jun 25 '23 at 09:54
  • I've red [1] and the quickly unplugging and plugging back does reverse the direction.

    [1] https://superuser.com/a/1690557/233703

    – Zaar Hai Dec 16 '23 at 11:49
5

USB type C connected together, then how is it decided which charges which?

This is all convoluted beyond comprehension so far. Type-C connector carries two roles

  1. data communication
  2. power delivery.

These are nearly independent functions. The entire functionality depends on whether

  1. both ports are USB hosts
  2. both ports are USB devices
  3. one port is Dual-role-Data and another is not
  4. one port is Dual-role-power

...

n. both ports are DRD and DRP,

I lost all permutations here. The UCSI is an attempt by Microsoft to tame this vast permutivity into API standard. For major ideas, see this presentation, and many more publications on "UCSI interface".

Prasanna
  • 4,074
Ale..chenski
  • 12,712
0

As Marc's answered above, PD direction can be controlled through /sys/class/typec/port*/power_role, however, if it does NOT work, like it does on my Thinkpad Yoga 6:

sudo bash -c 'echo sink > /sys/class/typec/port1/power_role'
bash: line 1: echo: write error: Invalid argument

Then you can try the "hardware" method by quickly re-plugging your powerbank as mentioned by this answer.

Originally I was sceptical myself, but surprisingly it works! It took some practice - you need to unplug and plug it back quick but not too quick. In my case I use Romoss PPD20 powerbank and I need to unplug it for about half a second - just until the charging indicator stops flashing.

Giacomo1968
  • 55,001
Zaar Hai
  • 101