From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f48.google.com (mail-ej1-f48.google.com [209.85.218.48]) (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 95F8E3F822C for ; Fri, 26 Jun 2026 14:27:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.48 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782484038; cv=none; b=J/WlImkFaNVKKZKKEdCudk55j3NcEoTA9zsugbXDlyBFwFR9OH4hCcTtd64hIwH2OMan1T6eEoaplcvrGBDW6aJlV6PqaHJ3Nc4nXRgFl0F/3iEddQ8nxolRKp5m/Wr93YvqWWrqaMYx8+IWaC1P17P3g5MZa1bqPK1HZxxHi3Y= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782484038; c=relaxed/simple; bh=x2uu1ellr0i43e+q8ybl9FUPAJocaRHRLLotF9ztVKk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QbjULKdmy6q/fvjXjE+fPrUvB5FyWcXW/F/u2IQbhwpO66U7Vtw11PUE/CqNMMbdyaR4Eq1CPnPrZhovb7/hjM1ZoyT0j5vpVl0dHNg8H8T3Dc2uTtFJidhC4iOPGqwnQIhFBEu2vejjxfgplOhZ4NcTVaTjXfx4cLHsLnLeu9Q= 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=cffcSudZ; arc=none smtp.client-ip=209.85.218.48 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="cffcSudZ" Received: by mail-ej1-f48.google.com with SMTP id a640c23a62f3a-c0e12cb1d90so110845266b.2 for ; Fri, 26 Jun 2026 07:27:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1782484029; x=1783088829; 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=6lcpW4k9A5UfDIIIPyGAlobBpqHG09WlpCDTZRLp2JA=; b=cffcSudZRvGvGKUB++0/oFWtmo0Y2VD3AtCVdxOfON+LieWal/ykQBYRatmtMmPwU5 JhqmnCoYQn2vH2a98BeTivi+WpzvM2o7ce/YqSuRvfH6hcDCWiaCQnvCnfKSv3iUtVa9 vOk7LNAvkH0tW2Q08QzpvpgEyM2Fs7EL5+TtM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782484029; x=1783088829; 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=6lcpW4k9A5UfDIIIPyGAlobBpqHG09WlpCDTZRLp2JA=; b=nAK1pxztIJg5+6ZavNbHh/EF+tMEic5zr/w6s5JD064Cyo+da22S3JsOqQGElJhfzJ FDr8+wpCw1bcGNarAwUfG1iaCQDweGNCWnFW5E4rSu3sf4WIQ5kDcNywVpjWp3FIBAvL +ba7tkywXwgPSO8nHO2Ct/6ZKU+LOHJSiMzLrsnSfFwenwa39FGKsvmuKhoE+8Rclteo a63e6mfHEa6tOB83dqHEq+YWUrrxJw46yTy6Z+EgYik7/LBlkzjqxuO4BRWshGgUbQxd yiuZIO5a2VmX+gLawAwR1j5XNQvHOIgk8YIiCOIr+PFSmS46apOSOcscR+IcDzeZ3P8t WdFg== X-Forwarded-Encrypted: i=1; AHgh+Ro57YiIZZ+sm17vaJQd4W2cc8vQHm0b73L+NU3YNY6MMDpTR+jJxZqvk+tHBvXmCdnADwzGlEPkzJi/ku0=@vger.kernel.org X-Gm-Message-State: AOJu0YxAWkVwuijp8v8zoDjFsMwieq6advHW9cQ9IKEGuovM9zAF312Z r8xD0ZHRIW52kZ62L8LqRRRHzg52QC0giHEPjG87juZEAX7CP/m9+AfeLJeBF1Voiw== X-Gm-Gg: AfdE7ck78KoxAT63pr90XspE6cEzndKOB44x+W9wTLXsFamBrPHzCQZ4ZJyxIVjzFP+ 6HMEd+Lhd92NHI2Idf3D5l+LRuFD95ZRxMTu+7rgkokCDi76HQpn8VVgOWNyWulyzJKjmaSv3R5 OU7Lsxzsp+IJV4W71ZfKkKUroKgZvsqEp+0hoD+Ae6YGIVZ8SZ10dsIy+f77Ovi660yoDL5J5Tq A9eSt0LnlazmjF7XQvIK6mDm5DGQj3nfyVaytLhVxqFtum4bsskJfqFRcuAf0Eeeew+xhabsF9p zswIHcEByz+SCX6E2bTIzbQ7KPyTUrG+zR+P6ZbaqDjS+z3k2P4gI15DPVjTpD9mWxmJNzxe7K7 VujOx3A8l+4spACwPLj5GaxybA8uk9XnACRXoqomdXKq6IFWydVm8RZUcE39WjMPAqx4eCkFc0a +b+Nr8e2Ur/X888HWUpt2+sRDMQA8GUx09QzhUuacJ1sjQisqBwYfiu74irrk0lMRKUHSpQzsTk UUNMgM4NQ== X-Received: by 2002:a17:906:385b:b0:c12:34f0:f7c2 with SMTP id a640c23a62f3a-c1234f0f9c6mr23933066b.65.1782484029044; Fri, 26 Jun 2026 07:27:09 -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-c11fbba6787sm355968666b.6.2026.06.26.07.27.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Jun 2026 07:27:08 -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 v3 1/3] usb: typec: Add helper to check cable altmode support Date: Fri, 26 Jun 2026 14:27:00 +0000 Message-ID: <20260626142702.1941182-2-akuchynski@chromium.org> X-Mailer: git-send-email 2.55.0.rc0.799.gd6f94ed593-goog In-Reply-To: <20260626142702.1941182-1-akuchynski@chromium.org> References: <20260626142702.1941182-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. Suggested-by: Heikki Krogerus Signed-off-by: Andrei Kuchynski --- Changes in V3: - Extracted core verification logic into a static helper function - Added an enum to handle supported, unsupported, and unknown cable states drivers/usb/typec/class.c | 71 +++++++++++++++++++++++++++++++++++++++ include/linux/usb/typec.h | 1 + 2 files changed, 72 insertions(+) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 0977581ad1b6e..e9f34eb14ceff 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1429,6 +1429,77 @@ int typec_cable_is_active(struct typec_cable *cable) } EXPORT_SYMBOL_GPL(typec_cable_is_active); +enum typec_cable_altmode_support { + CABLE_SUPPORT_UNKNOWN, + CABLE_SUPPORTED, + CABLE_NOT_SUPPORTED, +}; + +static enum typec_cable_altmode_support +typec_cable_check_altmode_support(struct typec_cable *cable, + struct typec_altmode *alt) +{ + struct typec_altmode *plug; + u32 speed; + + /* + * Check if the cable has an e-marker, supports modal operation, and the + * SOP' altmode nodes are created. + */ + plug = typec_altmode_get_plug(alt, TYPEC_PLUG_SOP_P); + if (plug) { + typec_altmode_put_plug(plug); + return CABLE_SUPPORTED; + } + + /* The identity is not specified */ + if (!cable->identity) + return CABLE_SUPPORT_UNKNOWN; + + /* Non-e-marked cable */ + if (!cable->identity->id_header) + return CABLE_NOT_SUPPORTED; + + switch (PD_IDH_PTYPE(cable->identity->id_header)) { + case IDH_PTYPE_PCABLE: + speed = VDO_TYPEC_CABLE_SPEED(cable->identity->vdo[0]); + if (speed == CABLE_USB2_ONLY) + return CABLE_NOT_SUPPORTED; + return CABLE_SUPPORTED; + case IDH_PTYPE_ACABLE: + /* + * 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. + */ + return CABLE_NOT_SUPPORTED; + } + + return CABLE_SUPPORT_UNKNOWN; +} + +/** + * 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) +{ + enum typec_cable_altmode_support support = CABLE_SUPPORT_UNKNOWN; + struct typec_cable *cable; + + cable = typec_cable_get(typec_altmode2port(alt)); + if (cable) { + support = typec_cable_check_altmode_support(cable, alt); + typec_cable_put(cable); + } + + return support == CABLE_NOT_SUPPORTED; +} +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.799.gd6f94ed593-goog