From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f50.google.com (mail-ej1-f50.google.com [209.85.218.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D9C1B39EF1F for ; Mon, 22 Jun 2026 09:39:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782121161; cv=none; b=K1qPHoxcU8wZUsNPSCCVkILXVrQfJ79mCZNEvvhw/mw3jzZBNeRdpQNV0KrhsBtsla6QyM8398uWa6mSDd1gKfWWrboibLWYUmLqGlH+137qoO3e++nPpQ1TjcX5EOjOTtjdcvGIIx7BY5nhEv0d6CQXMIBzlkDVKoUzfpbeEIA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782121161; c=relaxed/simple; bh=W/hxCxFm3JSr3l16UWLcD/2KmwUb7IDk9ZJdrIhdDpc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YaTCEFODtpsmGxEOfY4tdrn6sHyKGPyr8IyRCCqNUzqJti98gHDMxIEMZIeL5K/MxEi6nUvxlp4i0N3wVr0/AEIzLiyk2Ehh3EjgTaqlDDDeJE+4tNKii/h1IJeBbRQ8gIn24hwTL1D3MYCNwYcZImkNjOfz+NtrfwkkASiJCk0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=EG0qIL4J; arc=none smtp.client-ip=209.85.218.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="EG0qIL4J" Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-c029505b389so872368066b.1 for ; Mon, 22 Jun 2026 02:39:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1782121157; x=1782725957; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/auvlQ4YTi8Y85gn6vldbCwdOq0jgt+QLellMT7drJ0=; b=EG0qIL4JnlRtCj69JCHVKpzYhQI07Gy84lB8tDdthHorcPIsqyeSJTpxhiODSVYQmH pVgvfrvUWuU+7qZ7mOok4IQjHtFWoE87WVAUuHTip7SHQsb00kqmLLZ07Eetp3dDL/2u zT9D2xOXv72zfkCg5Y8gKSHSdwtQ8KI0SfE4Y= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782121157; x=1782725957; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=/auvlQ4YTi8Y85gn6vldbCwdOq0jgt+QLellMT7drJ0=; b=UlqCboVLwOAfObSTEYeAcMgLz5EPtid33K/CuKIgN97jvHHc4JHNbEG2ORE1uBelro oG3WNPjtjY1j5p9KjUubeMrjeICcpgDONojbmMFdfnk2epbp4ROlVvwRlvXqUKj35ung 2VbxtRgahiHvSTw6kTFJRuhcr2t1W6726kN8WW7mtRbKShkXHAKyI8EN/fr+hHd7u0rb adQIZMpXSuKhedXpmiS1A30pY1gs23IRztVWrJKLH8PQrHMEUOk5j2quhv9JDYht/wpO n5sJvyj36AZG+V36Zldw5oU3r324P16hOt+321cqSkUBKOLMva5/V2ViFeypRza//ZfZ mMZA== X-Forwarded-Encrypted: i=1; AFNElJ+7Qn0na0/5JU+KTUrRtVhqNwL0rEOk6WxxgKjfKjPFcKzuIXl1tK1dR2fTpUY4GsIw4I/RW0ybDPeeWow=@vger.kernel.org X-Gm-Message-State: AOJu0Yygg5nUN31Tr5sDYnq/j4rTiioqv3jcJOdp+Y3dStgSEmHHQqqU O9sWCYrr0UDx+BzHAp0cQxRKwKkya92t8Tl862dQOgZTzUEhql/xs1WcFcQPVBMYr1oWo3zyRcO d1Ro= X-Gm-Gg: AfdE7cm7wdQkvKEe8nSetq10FWyItvL0XC93EOzUrdxSgvNs4IXUMlsLiMAU3D/qRJz tCDBe2aOw0J/4r6WbYYHmOPCrqn2e8mciS/XRcx1xWg6s/YgnQFDFFblYbGko+ls9kjrej24bAY 7B4RqWWq2wPbfqdvM6U+5Y10nx2rv1P/RGboQOdT6prKjW7QuOEO27tARq9LE9tD342FJsZFfvD OGEL+JhGun3ovMGYp648/FylcWEc7JvoazHElojXUsCrVoArRQvcjMimcBGo+FsDoubE5+a31Ns mrpDCm1WspI33AofhEhMD/TNDC3gXqGIc298Q8p80Frdy61NWfAkT6Bi3qPLPbCg1yqSdaA7ShM GoBkjanmaQuCNZUb1ruLx2P4wNdXVg8xXNfT94PInCN1nnC8axqg8bld48BN4fFBw0gqvsLLNTI 6/H3KXkpBTzzxTZ1Rg21IkrZXA1W2GqCzlsCisTCSQDCk28Wm+81zPtt31L+YgGJGh7Zwmyo9UE o3hSGWkBw== X-Received: by 2002:a17:907:25c5:b0:bec:52f4:28ef with SMTP id a640c23a62f3a-c09b9c6e67cmr637445166b.22.1782121157156; Mon, 22 Jun 2026 02:39:17 -0700 (PDT) Received: from akuchynski.c.googlers.com.com (208.220.32.34.bc.googleusercontent.com. [34.32.220.208]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c0c610e526asm324855566b.51.2026.06.22.02.39.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Jun 2026 02:39:16 -0700 (PDT) From: Andrei Kuchynski To: Heikki Krogerus , Benson Leung , Jameson Thies Cc: Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Andrei Kuchynski Subject: [PATCH v2 1/3] usb: typec: Add helper to check cable altmode support Date: Mon, 22 Jun 2026 09:39:08 +0000 Message-ID: <20260622093910.1210089-2-akuchynski@chromium.org> X-Mailer: git-send-email 2.55.0.rc0.738.g0c8ab3ebcc-goog In-Reply-To: <20260622093910.1210089-1-akuchynski@chromium.org> References: <20260622093910.1210089-1-akuchynski@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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: - cables lacking an identity header - passive cables with USB 2.0 speed - active cables unless they have corresponding plugs The function returns false if the cable is not registered or the identifier is not set. Signed-off-by: Andrei Kuchynski --- Changes in V2: - Replaced the if/else chain with a switch-case block. - Added detailed inline comments explaining the USB PD cable specification constraints. - Separated the check for non-e-marked cables. drivers/usb/typec/class.c | 65 +++++++++++++++++++++++++++++++++++++++ include/linux/usb/typec.h | 1 + 2 files changed, 66 insertions(+) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 0977581ad1b6e..972c870e3ce51 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1429,6 +1429,71 @@ 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; + + /* + * Check if the cable has an e-marker, supports modal operation, and the + * SOP' altmode nodes are created. If yes, then altmode is supported. + */ + plug = typec_altmode_get_plug(alt, TYPEC_PLUG_SOP_P); + if (plug) { + typec_altmode_put_plug(plug); + return false; + } + + /* + * Check if the cable is registered and its identity is specified. + * If not, the cable altmode restriction cannot be checked. + */ + 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]); + + /* + * A cable lacking an ID Header indicates a non-e-marked cable, + * can only be guaranteed to have a USB 2.0 data path (D+ and D-). + */ + if (!id_header) { + unsupported = true; + } else { + switch (PD_IDH_PTYPE(id_header)) { + /* + * If the speed field explicitly declares it is a + * USB 2.0-only cable, altmode is unsupported. + */ + case IDH_PTYPE_PCABLE: + unsupported = (speed == CABLE_USB2_ONLY); + break; + /* + * Active cables must establish an SOP' communication + * node. Since that check failed at the beginning of + * this function, this active cable does not support + * this specific altmode. + */ + case IDH_PTYPE_ACABLE: + unsupported = true; + break; + } + } + } + if (cable) + typec_cable_put(cable); + + return unsupported; +} +EXPORT_SYMBOL_GPL(typec_cable_altmode_unsupported); + /** * typec_cable_set_identity - Report result from Discover Identity command * @cable: The cable updated identity values diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index d61ec38216fa9..10a783b738efd 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -337,6 +337,7 @@ void typec_unregister_cable(struct typec_cable *cable); struct typec_cable *typec_cable_get(struct typec_port *port); void typec_cable_put(struct typec_cable *cable); int typec_cable_is_active(struct typec_cable *cable); +bool typec_cable_altmode_unsupported(struct typec_altmode *alt); struct typec_plug *typec_register_plug(struct typec_cable *cable, struct typec_plug_desc *desc); -- 2.55.0.rc0.738.g0c8ab3ebcc-goog