Re: [PATCH v1 1/3] usb: typec: Add helper to check cable altmode support
From: Andrei Kuchynski
Date: Mon Jun 15 2026 - 07:29:43 EST
On Thu, Jun 11, 2026 at 8:47 PM Benson Leung <bleung@xxxxxxxxxx> wrote:
>
> On Thu, Jun 11, 2026 at 12:21:44PM +0000, Andrei Kuchynski wrote:
> > Introduce typec_cable_altmode_unsupported function to evaluate whether an
> > alternate mode is restricted based on the connected cable's properties.
> >
> > Implement validation logic that parses the cable's identity to catch
> > incompatible setups early. Alternate modes are restricted over:
>
> I think I follow this logic, and it is correct, but it may be harder to
> understand for a passing code observer who aren't deeply versed in how USB-C
> cables work. I think maybe additional comments on each of these resolution
> cases may be helpful.
>
Hi Benson,
Thanks for your review!
I will add descriptions for all the steps as you suggested.
> > - cables lacking an identity header
>
> Cable lacking an ID Header indicates a non-emarked cable, which in the case
> of a detachable C-to-C cable, can only be guaranteed to have USB 2.0 data path
> (D+ and D-).
>
> > - passive cables with USB 2.0 speed
>
> In this case, it's an affirmative confirmation from an e-marked cable
> (ID Header present, rest of e-mark present), we are sure it's a USB 2.0-only
> cable.
>
> > - active cables unless they have corresponding plugs
>
> This case is a little bit nuanced. The "corresponding plugs" means that this
> cable has an e-marker, supports modal operation, and the SOP' alt mode nodes
> are created. You're looking for a 1:1 match based on SVIDs that this cable
> has support for the alt mode being queried here. If yes, then alt mode is
> supported. If there's no match, then the alt mode is unsupported.
>
Yes. The altmode is supported if the cable's SOP' alt mode was registered.
Otherwise, the alt mode is unsupported if the cable is active.
> >
> > The function returns false if the cable is not registered or the identifier
> > is not set.
> >
> > Signed-off-by: Andrei Kuchynski <akuchynski@xxxxxxxxxxxx>
> > ---
> > drivers/usb/typec/class.c | 35 +++++++++++++++++++++++++++++++++++
> > include/linux/usb/typec.h | 1 +
> > 2 files changed, 36 insertions(+)
> >
> > diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
> > index 0977581ad1b6e..f7f1adbaab7e6 100644
> > --- a/drivers/usb/typec/class.c
> > +++ b/drivers/usb/typec/class.c
> > @@ -1429,6 +1429,41 @@ int typec_cable_is_active(struct typec_cable *cable)
> > }
> > EXPORT_SYMBOL_GPL(typec_cable_is_active);
> >
> > +/**
> > + * typec_cable_altmode_unsupported - Check if a cable restricts altmode
> > + * @alt: The Alternate Mode to evaluate
> > + *
> > + * Returns true if the connected cable is incapable of handling the altmode.
> > + */
> > +bool typec_cable_altmode_unsupported(struct typec_altmode *alt)
> > +{
> > + struct typec_altmode *plug;
> > + struct typec_cable *cable;
> > + bool unsupported = false;
> > +
> > + plug = typec_altmode_get_plug(alt, TYPEC_PLUG_SOP_P);
> > + if (plug) {
>
> In this case, we have an affirmative match on alt mode
> being queried, so the cable supports this alt mode, which is why you return
> false, meaning alt mode is supported.
>
Right. Here we know for sure that the cable supports the alt mode.
> > + typec_altmode_put_plug(plug);
> > + return false;
> > + }
> > +
>
> Past this point, there is no SOP' alt mode object matching the alt mode.
> The only way to return supported is if we find the cable is a passive cable
> of at least USB3 Gen 1 or better speed.
>
The function returns 'unsupported'. This is important because if the cable
isn't registered or the cable identity isn't specified, we can not assert
that the cable supports altmode. However, we can assert that no
restrictions are defined.
Checking cable && cable->identity pointers is necessary not only for
safety reasons, but also to confirm that we have information about the
cable.
> > + cable = typec_cable_get(typec_altmode2port(alt));
> > + if (cable && cable->identity) {
> > + const u32 id_header = cable->identity->id_header;
> > + const u32 speed = VDO_TYPEC_CABLE_SPEED(cable->identity->vdo[0]);
> > +
> > + if (!id_header || PD_IDH_PTYPE(id_header) == IDH_PTYPE_ACABLE)
> > + unsupported = true;
> > + else if (PD_IDH_PTYPE(id_header) == IDH_PTYPE_PCABLE)
> > + unsupported = (speed == CABLE_USB2_ONLY);
>
> This might be a little easier to follow if this was a switch statement on
> PD_IDH_PTYPE(id_header) so the reader can see what different behavior is between
> PCABLE and ACABLE.
>
Good point. I will change it.
Thanks,
Andrei