Re: [PATCH v2 05/10] usb: tcpm: add setup_host_mode/device_mode/disable_src_vbus APIs
Sebastian Reichel <[email protected]>
| Newsgroups | gmane.comp.boot-loaders.u-boot.general,gmane.comp.boot-loaders.u-boot |
|---|---|
| Message-ID | <ano-_jXlvnruhCny@venus> |
Hi, On Sun, Jun 21, 2026 at 10:06:41AM +0800, Peng Fan (OSS) wrote: > From: Peng Fan <[email protected]> > > Add lightweight Type-C mode setup functions that bypass the TCPM state > machine and call TCPCI driver ops directly: > > - tcpm_setup_host_mode(): set CC=Rp, detect device, set polarity, > source VBUS > - tcpm_setup_device_mode(): set CC=Rd, detect host, set polarity > - tcpm_disable_src_vbus(): stop sourcing VBUS > > These are used by board_usb_init/cleanup to configure the Type-C port > for USB host or device mode without running the full PD state machine. > > Signed-off-by: Peng Fan <[email protected]> > --- I don't see a user for these functions in this series, so maybe the patch can just be dropped? Generally it seems sensible to change the name to something like * tcpm_force_host_mode() * tcpm_force_device_mode() * tcpm_force_disable_vbus() Also I think these functions deserve a comment header describing when and why these functions should be used or not used. Avoiding the state machine risks hard reset from the remote side, if proper PD is being used later on. Greetings, -- Sebastian > drivers/usb/tcpm/tcpm-uclass.c | 87 ++++++++++++++++++++++++++++++++++++++++++ > include/usb/tcpm.h | 4 ++ > 2 files changed, 91 insertions(+) > > diff --git a/drivers/usb/tcpm/tcpm-uclass.c b/drivers/usb/tcpm/tcpm-uclass.c > index d4fe260e0db..e0f7ce62a79 100644 > --- a/drivers/usb/tcpm/tcpm-uclass.c > +++ b/drivers/usb/tcpm/tcpm-uclass.c > @@ -8,6 +8,7 @@ > #include <dm/device.h> > #include <dm/device_compat.h> > #include <dm/uclass.h> > +#include <linux/delay.h> > #include <linux/err.h> > #include <usb/tcpm.h> > #include "tcpm-internal.h" > @@ -140,6 +141,92 @@ static int tcpm_post_bind(struct udevice *dev) > return 0; > } > > +int tcpm_setup_host_mode(struct udevice *dev, enum typec_cc_polarity *polarity) > +{ > + const struct dm_tcpm_ops *ops = dev_get_driver_ops(dev); > + enum typec_cc_status cc1, cc2; > + int ret; > + > + ops->set_vbus(dev, false, false); > + > + ops->set_cc(dev, TYPEC_CC_RP_DEF); > + > + mdelay(100); > + > + ret = ops->get_cc(dev, &cc1, &cc2); > + if (ret) { > + dev_err(dev, "Failed to get cc for host mode: %d\n", ret); > + return ret; > + } > + > + if (cc1 == TYPEC_CC_RD) { > + *polarity = TYPEC_POLARITY_CC1; > + } else if (cc2 == TYPEC_CC_RD) { > + *polarity = TYPEC_POLARITY_CC2; > + } else { > + dev_err(dev, "no device detected (cc1=%d cc2=%d)\n", cc1, cc2); > + return -ENODEV; > + } > + > + ret = ops->set_polarity(dev, *polarity); > + if (ret) > + return ret; > + > + ops->set_vbus(dev, true, false); > + mdelay(300); > + > + return 0; > +} > + > +int tcpm_setup_device_mode(struct udevice *dev, enum typec_cc_polarity *polarity) > +{ > + const struct dm_tcpm_ops *ops = dev_get_driver_ops(dev); > + enum typec_cc_status cc1, cc2; > + int ret, retry; > + > + ops->set_vbus(dev, false, false); > + > + ops->set_cc(dev, TYPEC_CC_RD); > + > + if (ops->start_toggling) > + ops->start_toggling(dev, TYPEC_PORT_SNK, TYPEC_CC_RD); > + > + for (retry = 0; retry < 20; retry++) { > + mdelay(100); > + > + ret = ops->get_cc(dev, &cc1, &cc2); > + if (ret) { > + dev_err(dev, "Failed to get cc for device mode: %d\n", ret); > + return ret; > + } > + > + if (cc1 != TYPEC_CC_OPEN || cc2 != TYPEC_CC_OPEN) > + break; > + } > + > + if (cc1 != TYPEC_CC_OPEN && cc2 == TYPEC_CC_OPEN) { > + *polarity = TYPEC_POLARITY_CC1; > + } else if (cc1 == TYPEC_CC_OPEN && cc2 != TYPEC_CC_OPEN) { > + *polarity = TYPEC_POLARITY_CC2; > + } else { > + dev_err(dev, "no host detected (cc1=%d cc2=%d)\n", cc1, cc2); > + return -ENODEV; > + } > + > + ret = ops->set_polarity(dev, *polarity); > + if (ret) > + return ret; > + > + return 0; > +} > + > +int tcpm_disable_src_vbus(struct udevice *dev) > +{ > + const struct dm_tcpm_ops *ops = dev_get_driver_ops(dev); > + > + return ops->set_vbus(dev, false, false); > +} > + > UCLASS_DRIVER(tcpm) = { > .id = UCLASS_TCPM, > .name = "tcpm", > diff --git a/include/usb/tcpm.h b/include/usb/tcpm.h > index 10f0515fe12..caa67a5639d 100644 > --- a/include/usb/tcpm.h > +++ b/include/usb/tcpm.h > @@ -96,4 +96,8 @@ enum typec_data_role tcpm_get_data_role(struct udevice *dev); > bool tcpm_is_connected(struct udevice *dev); > const char *tcpm_get_state(struct udevice *dev); > > +int tcpm_setup_host_mode(struct udevice *dev, enum typec_cc_polarity *polarity); > +int tcpm_setup_device_mode(struct udevice *dev, enum typec_cc_polarity *polarity); > +int tcpm_disable_src_vbus(struct udevice *dev); > + > #endif /* __LINUX_USB_TCPM_H */ > > -- > 2.51.0 >
signature.asc
(application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE72YNB0Y/i3JqeVQT2O7X88g7+poFAmp6QkIACgkQ2O7X88g7 +poSSA//aolmS5FsD9yjwyiL++x7MfId4MxKrXTqFrR30EPvckgqmbWekix6vOQc Nw6c/jbAUhyU4f3zLlU1gH8TR8iDvQfkk7JiWXYCgKd1weIMcRaN6U5ABtPQr/do G9zl1kbyhz0DotM2I0uByRP5QSlqPHPSyWZJc+CWkqbnP6YZSxJIwi97SIKZ7nqJ zi9qHyKFwoqJ12PcIiwDhcSTytmKWauWU7OAfDQBntWMj9DWu3Vb7A3lTdVPbqY5 h4+AfwqS5UeDdwrQigrYc+KlTzpcLKq/rwaGpTV3qOTS8QaahOnKGVimUpXadfoE UdlxsO+hpWgpOzm8QBPVW4xOmheCWqttfKF+jBLD3c4EvPVWML9FQqlM9njJ+Se6 vwRelpWJmnHM1foII0N2yHF4gkmHLt6H06mv7eNGLXXzWlK34hZpTqOWcT0wHdhB MC6mnsvYwCLqdTn13v1+b2FwXKYN8xT7x0MTeWZAXzmkFok0jE4ZtjiQWKw9qoSH eh3ghXntRXULtqfGOfR3PsUCvKaOQf5lQnLTBccjxbtYFj6bfCrU1HtDpgs15yd+ tHY1SqTvCS94kizkLQR6l3JNBUH4xs681kkyQ/A/35O6GRV3nfn4d1hMeG+F141w +BMCmlGrEbGnwUQBFuLJNJK1FR97y15MpCWEYnNkoS41u+a/oag= =rXmG -----END PGP SIGNATURE-----