Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

platform/chrome: cros_ec_typec: Add support for setting USB mode via sysfs

This patch implements USB mode setting via a sysfs interface in
cros_ec_typec driver. User-space applications can now change the current
USB mode by writing to "usb_mode" sysfs entry, replacing the previous
ioctl-based method.
The embedded controller (EC) currently supports only entering USB4 mode
and exiting all modes (including altmodes). Both of these operations
trigger Data Reset Message, even if no USB Mode is active.
Additionally, the patch exposes the USB modes supported by the port via
"usb_capability" sysfs attribute.

Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
Link: https://lore.kernel.org/r/20250210130419.4110130-1-akuchynski@chromium.org
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>

authored by

Andrei Kuchynski and committed by
Tzung-Bi Shih
9fc83373 435a3d78

+29
+28
drivers/platform/chrome/cros_ec_typec.c
··· 42 42 #endif 43 43 } 44 44 45 + static int cros_typec_enter_usb_mode(struct typec_port *tc_port, enum usb_mode mode) 46 + { 47 + struct cros_typec_port *port = typec_get_drvdata(tc_port); 48 + struct ec_params_typec_control req = { 49 + .port = port->port_num, 50 + .command = (mode == USB_MODE_USB4) ? 51 + TYPEC_CONTROL_COMMAND_ENTER_MODE : TYPEC_CONTROL_COMMAND_EXIT_MODES, 52 + .mode_to_enter = CROS_EC_ALTMODE_USB4 53 + }; 54 + 55 + return cros_ec_cmd(port->typec_data->ec, 0, EC_CMD_TYPEC_CONTROL, 56 + &req, sizeof(req), NULL, 0); 57 + } 58 + 59 + static const struct typec_operations cros_typec_usb_mode_ops = { 60 + .enter_usb_mode = cros_typec_enter_usb_mode 61 + }; 62 + 45 63 static int cros_typec_parse_port_props(struct typec_capability *cap, 46 64 struct fwnode_handle *fwnode, 47 65 struct device *dev) ··· 101 83 return ret; 102 84 cap->prefer_role = ret; 103 85 } 86 + 87 + if (fwnode_property_present(fwnode, "usb2-port")) 88 + cap->usb_capability |= USB_CAPABILITY_USB2; 89 + if (fwnode_property_present(fwnode, "usb3-port")) 90 + cap->usb_capability |= USB_CAPABILITY_USB3; 91 + if (fwnode_property_present(fwnode, "usb4-port")) 92 + cap->usb_capability |= USB_CAPABILITY_USB4; 104 93 105 94 cros_typec_role_switch_quirk(fwnode); 106 95 ··· 403 378 ret = cros_typec_parse_port_props(cap, fwnode, dev); 404 379 if (ret < 0) 405 380 goto unregister_ports; 381 + 382 + cap->driver_data = cros_port; 383 + cap->ops = &cros_typec_usb_mode_ops; 406 384 407 385 cros_port->port = typec_register_port(dev, cap); 408 386 if (IS_ERR(cros_port->port)) {
+1
drivers/platform/chrome/cros_ec_typec.h
··· 18 18 enum { 19 19 CROS_EC_ALTMODE_DP = 0, 20 20 CROS_EC_ALTMODE_TBT, 21 + CROS_EC_ALTMODE_USB4, 21 22 CROS_EC_ALTMODE_MAX, 22 23 }; 23 24