From nobody Tue Jun 23 17:22:14 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 065A8C433EF for ; Tue, 1 Mar 2022 13:20:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234995AbiCANVi (ORCPT ); Tue, 1 Mar 2022 08:21:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38850 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234068AbiCANVa (ORCPT ); Tue, 1 Mar 2022 08:21:30 -0500 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8D9AD9BB9C for ; Tue, 1 Mar 2022 05:20:49 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id n14so20458988wrq.7 for ; Tue, 01 Mar 2022 05:20:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pqrs.dk; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=e9I6Gr81p9RgEFrXcG5x2Wrj3Yq74XLrak4Xgl7o68Y=; b=ByMoPlOaBOuEhwZX1OE5tsZtqDWMZ+NErAiXaCiAfUE2ntkDEiBAkPM8LpOEh1S2V2 /PjVAdl6Gy7cDH09xvE3jBHB+mRb77BfXyZtkw3VvALKL4TKo/EvAHmX4eQVHgAZPQwV vmb1Z83QwAsaHHaDM9GmJnMwx/uC0G0Xwxwao= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=e9I6Gr81p9RgEFrXcG5x2Wrj3Yq74XLrak4Xgl7o68Y=; b=t/OcLF74dlyxcvPEMq6MhiqFE8ppHbFFN4mqgDsVAilw+1HCXoSamvphHlDvfGPj9i UPzJtjgU8zdIF0H4hosHRuqweE1W+GVHYUZJJ0nYlDhIGnN10Ls5C/yvwMctz3CEVZZn SJrRjNJagxx7f7Yw469pbvSYgsK1NdkVfIMvUj6rcwGKDiDfmYY+sCJQLoi6hKvvcHpx ADM8tFZU7O6BGe7t8yMJSEKcFv1304Dq3Ug4Hu4P9FIscvFyiMVrnaeWFKnnWlQL+tLt ZgqyF4BRzQiohCnQf8KylmV8S+feTXxEf9ORREYsjo0y635pPuwWkvcmzrxYIwAetlfz 3Qyw== X-Gm-Message-State: AOAM531zVDOdwx3h5E2/v11aByRwVtoqDl/FcZTAsLEmpmdvrl3Qsvlg jrlJkQ6/81w/xKb6rBQ1gTGE0w== X-Google-Smtp-Source: ABdhPJy5JugLamchQE82Lczi++biGY20rULCNgTL2PA2mauvLrn3sAdoxDVPL+K0ZcepGPSfetXuLw== X-Received: by 2002:a5d:5302:0:b0:1ed:e1d2:f0fd with SMTP id e2-20020a5d5302000000b001ede1d2f0fdmr19971115wrv.585.1646140847860; Tue, 01 Mar 2022 05:20:47 -0800 (PST) Received: from capella.. (80.71.142.18.ipv4.parknet.dk. [80.71.142.18]) by smtp.gmail.com with ESMTPSA id i12-20020adfe48c000000b001ef6eab4c81sm13258492wrm.96.2022.03.01.05.20.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Mar 2022 05:20:47 -0800 (PST) From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= To: Greg Kroah-Hartman , Rob Herring , Heikki Krogerus , =?UTF-8?q?=A0ipraga?= Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/4] dt-bindings: usb: add TUSB320xA Type-C port controller Date: Tue, 1 Mar 2022 14:20:05 +0100 Message-Id: <20220301132010.115258-2-alvin@pqrs.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220301132010.115258-1-alvin@pqrs.dk> References: <20220301132010.115258-1-alvin@pqrs.dk> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alvin =C5=A0ipraga The TUSB320xA is a non-PD Type-C port controller managed over I2C. Signed-off-by: Alvin =C5=A0ipraga --- .../devicetree/bindings/usb/ti,tusb320xa.yaml | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/ti,tusb320xa.yaml diff --git a/Documentation/devicetree/bindings/usb/ti,tusb320xa.yaml b/Docu= mentation/devicetree/bindings/usb/ti,tusb320xa.yaml new file mode 100644 index 000000000000..a93d53ddd01c --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ti,tusb320xa.yaml @@ -0,0 +1,78 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/ti,tusb320xa.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TUSB320xA Type-C port controller DT bindings + +description: + The Texas Instruments TUSB320xA is a USB Type-C port controller which + supports role and plug orientation detection using the CC pins. It is + compatible with the USB Type-C Cable and Connector Specification v1.1. + +maintainers: + - Alvin =C5=A0ipraga + +properties: + compatible: + enum: + - ti,tusb320la + - ti,tusb320ha + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + patternProperties: + '^port@': + $ref: /schemas/graph.yaml#/properties/port + description: + OF graph bindings modelling any "usb-role-switch" or "accessory"= mux. + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + tcpc@47 { + compatible =3D "ti,tusb320la"; + reg =3D <0x47>; + interrupt-parent =3D <&gpio5>; + interrupts =3D <2 IRQ_TYPE_LEVEL_LOW>; + + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@0 { + reg =3D <0>; + typec1_mux: endpoint { + remote-endpoint =3D <&usb_audio_mux1>; + }; + }; + + port@1 { + reg =3D <1>; + typec1_dr_sw: endpoint { + remote-endpoint =3D <&usbotg1_drd_sw>; + }; + }; + }; + }; + }; --=20 2.35.1 From nobody Tue Jun 23 17:22:14 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0DD37C433EF for ; Tue, 1 Mar 2022 13:21:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235007AbiCANVk (ORCPT ); Tue, 1 Mar 2022 08:21:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38878 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234975AbiCANVc (ORCPT ); Tue, 1 Mar 2022 08:21:32 -0500 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF9089BB81 for ; Tue, 1 Mar 2022 05:20:51 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id bk29so3188539wrb.4 for ; Tue, 01 Mar 2022 05:20:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pqrs.dk; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EX7x1WLeV89mTenKTRjKxeZqDFfAAfBdLkab9/KTRFU=; b=TmkG97zcvctztj0cYcA9OROjVUsaem9cmT+XGazETkehN80XgxzmgoH4MbJrE+tUHp 4VoyO1s9D1FJeM6R7rKRnw3RgRitb7Hs098qcWx7CAWrHbWh6p+dBRJC+sNzST1Xl4XL 650FV+qHUHteM3HY/ct40vL1L/XJmIcmYvlfM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EX7x1WLeV89mTenKTRjKxeZqDFfAAfBdLkab9/KTRFU=; b=JcgXD1Ce+barQRuBj6jXyLXJs9LUpsj0tnVSv3bPG5audj8LahpJgWIrwTlNsc/ZUa V9zubtPp9AYZ9x4Mq/O9QWnNIg3nPE37MeUxmUOQh9UHtoHdpK24/2qHv5ihlV4kDXVd QALMKsO/c4AZlszMMpdfD5saIxqOKus7eCme/clM/B40jhlrVtaw6ZKGZZZjgJ/w6p4v V3YwfWjG74u8511fdVArFjj5FeFCdaHboA31BoCg6UoEJwWxxnUKL8ELieST3jmxpbqr 8v9Uqj3wYgrhsVE39cKseD606zTJjPHhzxLgCgS8Ibc17MiS0hI+erX7apsRabh4tg3D W5mg== X-Gm-Message-State: AOAM531gRehWGyJzhvvhJJFPe9BNwTPI7rn8YpKzPs7w5oyuqt0R0f2w R6z8ITr7VcEdJp4m9G3DInmK+w== X-Google-Smtp-Source: ABdhPJwRE/3HFFsGWfsejA9PpDzCYob2PkUibpYrTch3RhB8qmtJNFi8JLnGsmSI6SBkT62DuIpF5w== X-Received: by 2002:a5d:4a8b:0:b0:1ef:9566:71c4 with SMTP id o11-20020a5d4a8b000000b001ef956671c4mr9769298wrq.400.1646140850254; Tue, 01 Mar 2022 05:20:50 -0800 (PST) Received: from capella.. (80.71.142.18.ipv4.parknet.dk. [80.71.142.18]) by smtp.gmail.com with ESMTPSA id i12-20020adfe48c000000b001ef6eab4c81sm13258492wrm.96.2022.03.01.05.20.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Mar 2022 05:20:49 -0800 (PST) From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= To: Greg Kroah-Hartman , Rob Herring , Heikki Krogerus , =?UTF-8?q?=A0ipraga?= Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/4] dt-bindings: usb: add TS5USBA224 USB/Audio switch mux Date: Tue, 1 Mar 2022 14:20:06 +0100 Message-Id: <20220301132010.115258-3-alvin@pqrs.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220301132010.115258-1-alvin@pqrs.dk> References: <20220301132010.115258-1-alvin@pqrs.dk> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alvin =C5=A0ipraga The TS5USBA224 is a USB High Speed/Audio switch mux IC controlled via GPIO. It is typically composed with a Type-C port controller with Audio Accessory mode detection. Signed-off-by: Alvin =C5=A0ipraga --- .../bindings/usb/ti,ts5usba224.yaml | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/ti,ts5usba224.yaml diff --git a/Documentation/devicetree/bindings/usb/ti,ts5usba224.yaml b/Doc= umentation/devicetree/bindings/usb/ti,ts5usba224.yaml new file mode 100644 index 000000000000..0a488b961906 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ti,ts5usba224.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/ti,ts5usba224.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TS5USBA224 USB 2.0 High Speed and Audio mux DT bindings + +description: + The Texas Instruments TS5USBA224 is a double-pole, double throw + (DPDT) multiplexer that includes a low-distortion audio switch and a + USB 2.0 High Speed switch in the same package. + +maintainers: + - Alvin =C5=A0ipraga + +properties: + compatible: + enum: + - ti,ts5usba224 + + asel-gpio: + description: Output GPIO for A_SEL signal + maxItems: 1 + + accessory: + type: boolean + description: + Indicates that this is an Accessory Mode mux. + + port: + $ref: /schemas/graph.yaml#/properties/port + description: + OF graph bindings modelling a Type-C port controller. + +required: + - compatible + - asel-gpio + - accessory + - port + +additionalProperties: false + +examples: + - | + usbaudiomux@0 { + compatible =3D "ti,ts5usba224"; + asel-gpios =3D <&gpio1 7 GPIO_ACTIVE_HIGH>; + accessory; + + port { + usb_audio_mux1: endpoint { + remote-endpoint =3D <&typec1_mux>; + }; + }; + }; --=20 2.35.1 From nobody Tue Jun 23 17:22:14 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4D1FC433EF for ; Tue, 1 Mar 2022 13:21:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235013AbiCANVn (ORCPT ); Tue, 1 Mar 2022 08:21:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234989AbiCANVh (ORCPT ); Tue, 1 Mar 2022 08:21:37 -0500 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0F4199BB83 for ; Tue, 1 Mar 2022 05:20:54 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id p9so20456769wra.12 for ; Tue, 01 Mar 2022 05:20:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pqrs.dk; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=t5QdSkZobRcNw0sMBE5JQ8DioZepLNwTSt32gkTtTW8=; b=LSG1kPXdKa0PM1JDG02Ko7nl5UrO0y5WKjksOzwPwpV88b5CVGkgGVPC6qlnNi7tlf EfvhwsxfmZVCq+NqAp09nooPX3lYWczG2AqFmuLaPIMMC85prkky079pxPbMnk5YKQNV eAn//RXyws1lbLyTh45Xm+lpHY5/HYI56fuIA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=t5QdSkZobRcNw0sMBE5JQ8DioZepLNwTSt32gkTtTW8=; b=WfrSnXCb2T5OxikJSYthmbnqJfavIHiQlEC2NI5kdfw2Ekp/LhHywvju/O5ivdOnl0 daSrmnAFutLNgBFXgEB652QNU3EddcN3SP16Fx7l+ybEAbyXEb1hgWOPXtj6OZ11NPM6 nCGuKxQPyu27V5uKt0sOAR/nti04d9BF+u6i0L5Nd4wvKSkSV12Y0XSuNcTWKJCbqWRo XkGa9H/Vq8makI3VcnJQLfj2KESJYPsUuz6W7XSMiVuuVHlolfsbCK9y/qzoXPHpLKVf 0tnGU6YyRccvRMTDGgrbcIXG3e5r0EL/8iAtRaE+cWhc+A/IZPXs14uXoSVIr2gogjvD +p8A== X-Gm-Message-State: AOAM530xAxAtNIkUkMFv9zDWreazNOIIuUg6d1BIjrrklSfhItd8Kgj+ WOxq6F2uRsg8ncBKNvJKQlQuRLN1qeBHh5wy X-Google-Smtp-Source: ABdhPJw9/jFZBqJ1KR0CRgunqf8sGSgmR+KdvVcqFMPgFa/hAebORW/5RIpHeisPFDZAdZUTZswKRQ== X-Received: by 2002:a05:6000:1284:b0:1f0:16e0:2058 with SMTP id f4-20020a056000128400b001f016e02058mr2047242wrx.379.1646140852501; Tue, 01 Mar 2022 05:20:52 -0800 (PST) Received: from capella.. (80.71.142.18.ipv4.parknet.dk. [80.71.142.18]) by smtp.gmail.com with ESMTPSA id i12-20020adfe48c000000b001ef6eab4c81sm13258492wrm.96.2022.03.01.05.20.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Mar 2022 05:20:52 -0800 (PST) From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= To: Greg Kroah-Hartman , Rob Herring , Heikki Krogerus , =?UTF-8?q?=A0ipraga?= Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/4] usb: typec: add TUSB320xA driver Date: Tue, 1 Mar 2022 14:20:07 +0100 Message-Id: <20220301132010.115258-4-alvin@pqrs.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220301132010.115258-1-alvin@pqrs.dk> References: <20220301132010.115258-1-alvin@pqrs.dk> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alvin =C5=A0ipraga The TUSB320LA and TUSB320HA (or LAI, HAI) chips are I2C controlled non-PD Type-C port controllers. They support detection of cable orientation, port attachment state, and role, including Audio Accessory and Debug Accessory modes. Add a typec class driver for this family. Note that there already exists an extcon driver for the TUSB320 (a slightly older revision that does not support setting role preference or disabling the CC state machine). This driver is loosely based on that one. Signed-off-by: Alvin =C5=A0ipraga Reported-by: kernel test robot --- drivers/usb/typec/Kconfig | 12 + drivers/usb/typec/Makefile | 1 + drivers/usb/typec/tusb320xa.c | 517 ++++++++++++++++++++++++++++++++++ 3 files changed, 530 insertions(+) create mode 100644 drivers/usb/typec/tusb320xa.c diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig index 8f921213b17d..fd752524814d 100644 --- a/drivers/usb/typec/Kconfig +++ b/drivers/usb/typec/Kconfig @@ -75,6 +75,18 @@ config TYPEC_HD3SS3220 If you choose to build this driver as a dynamically linked module, the module will be called hd3ss3220.ko. =20 +config TYPEC_TUSB320XA + tristate "TI TUSB320xA Type-C DRP Port controller driver" + depends on USB_ROLE_SWITCH + depends on I2C + select REGMAP_I2C + help + Say Y or M here if your system has a TUSB320xA Type-C DRP port + controller. + + If you choose to build this driver as a dynamically linked module, the + module will be called tusb320xa.ko. + config TYPEC_STUSB160X tristate "STMicroelectronics STUSB160x Type-C controller driver" depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile index 43626acc0aaf..493e4796ca65 100644 --- a/drivers/usb/typec/Makefile +++ b/drivers/usb/typec/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_TYPEC_TCPM) +=3D tcpm/ obj-$(CONFIG_TYPEC_UCSI) +=3D ucsi/ obj-$(CONFIG_TYPEC_TPS6598X) +=3D tipd/ obj-$(CONFIG_TYPEC_HD3SS3220) +=3D hd3ss3220.o +obj-$(CONFIG_TYPEC_TUSB320XA) +=3D tusb320xa.o obj-$(CONFIG_TYPEC_QCOM_PMIC) +=3D qcom-pmic-typec.o obj-$(CONFIG_TYPEC_STUSB160X) +=3D stusb160x.o obj-$(CONFIG_TYPEC_RT1719) +=3D rt1719.o diff --git a/drivers/usb/typec/tusb320xa.c b/drivers/usb/typec/tusb320xa.c new file mode 100644 index 000000000000..b955143e24fc --- /dev/null +++ b/drivers/usb/typec/tusb320xa.c @@ -0,0 +1,517 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * TI TUSB320LA/TUSB320HA Type-C DRP Port controller driver + * + * Based on the drivers/extcon/extcon-tusb320.c driver by Michael Auchter. + * + * Copyright (c) 2021 Alvin =C5=A0ipraga + * Copyright (c) 2020 Michael Auchter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TUSB320XA_REG8 0x08 +#define TUSB320XA_REG8_ACCESSORY_CONNECTED GENMASK(3, 1) + +#define TUSB320XA_REG9 0x09 +#define TUSB320XA_REG9_ATTACHED_STATE GENMASK(7, 6) +#define TUSB320XA_REG9_CABLE_DIR BIT(5) +#define TUSB320XA_REG9_INTERRUPT_STATUS BIT(4) + +#define TUSB320XA_REGA 0x0A +#define TUSB320XA_REGA_MODE_SELECT GENMASK(5, 4) +#define TUSB320XA_REGA_I2C_SOFT_RESET BIT(3) +#define TUSB320XA_REGA_SOURCE_PREF GENMASK(2, 1) +#define TUSB320XA_REGA_DISABLE_TERM BIT(0) + +enum tusb320xa_accessory { + TUSB320XA_ACCESSORY_NONE =3D 0, + /* 0b001 ~ 0b011 are reserved */ + TUSB320XA_ACCESSORY_AUDIO =3D 4, + TUSB320XA_ACCESSORY_AUDIO_CHARGETHRU =3D 5, + TUSB320XA_ACCESSORY_DEBUG_DFP =3D 6, + TUSB320XA_ACCESSORY_DEBUG_UFP =3D 7, +}; + +static const char *const tusb320xa_accessories[] =3D { + [TUSB320XA_ACCESSORY_NONE] =3D "none", + [TUSB320XA_ACCESSORY_AUDIO] =3D "audio", + [TUSB320XA_ACCESSORY_AUDIO_CHARGETHRU] =3D "audio with charge thru", + [TUSB320XA_ACCESSORY_DEBUG_DFP] =3D "debug while DFP", + [TUSB320XA_ACCESSORY_DEBUG_UFP] =3D "debug while UFP", +}; + +enum tusb320xa_attached_state { + TUSB320XA_ATTACHED_STATE_NONE =3D 0, + TUSB320XA_ATTACHED_STATE_DFP =3D 1, + TUSB320XA_ATTACHED_STATE_UFP =3D 2, + TUSB320XA_ATTACHED_STATE_ACC =3D 3, +}; + +static const char *const tusb320xa_attached_states[] =3D { + [TUSB320XA_ATTACHED_STATE_NONE] =3D "not attached", + [TUSB320XA_ATTACHED_STATE_DFP] =3D "downstream facing port", + [TUSB320XA_ATTACHED_STATE_UFP] =3D "upstream facing port", + [TUSB320XA_ATTACHED_STATE_ACC] =3D "accessory", +}; + +enum tusb320xa_cable_dir { + TUSB320XA_CABLE_DIR_CC1 =3D 0, + TUSB320XA_CABLE_DIR_CC2 =3D 1, +}; + +static const char *const tusb320xa_cable_directions[] =3D { + [TUSB320XA_CABLE_DIR_CC1] =3D "CC1", + [TUSB320XA_CABLE_DIR_CC2] =3D "CC2", +}; + +enum tusb320xa_mode { + TUSB320XA_MODE_PORT =3D 0, + TUSB320XA_MODE_UFP =3D 1, + TUSB320XA_MODE_DFP =3D 2, + TUSB320XA_MODE_DRP =3D 3, +}; + +enum tusb320xa_source_pref { + TUSB320XA_SOURCE_PREF_DRP =3D 0, + TUSB320XA_SOURCE_PREF_TRY_SNK =3D 1, + /* 0b10 is reserved */ + TUSB320XA_SOURCE_PREF_TRY_SRC =3D 3, +}; + +struct tusb320xa { + struct device *dev; + struct regmap *regmap; + struct typec_port *port; + struct usb_role_switch *role_sw; + struct mutex lock; + int irq; +}; + +static int tusb320xa_check_signature(struct tusb320xa *tusb) +{ + static const char sig[] =3D { '\0', 'T', 'U', 'S', 'B', '3', '2', '0' }; + unsigned int val; + int i, ret; + + mutex_lock(&tusb->lock); + + for (i =3D 0; i < sizeof(sig); i++) { + ret =3D regmap_read(tusb->regmap, sizeof(sig) - 1 - i, &val); + if (ret) + goto done; + + if (val !=3D sig[i]) { + dev_err(tusb->dev, "signature mismatch!\n"); + ret =3D -ENODEV; + goto done; + } + } + +done: + mutex_unlock(&tusb->lock); + + return ret; +} + +static int tusb320xa_reset(struct tusb320xa *tusb) +{ + int ret; + + mutex_lock(&tusb->lock); + + /* Disable CC state machine */ + ret =3D regmap_write_bits(tusb->regmap, TUSB320XA_REGA, + TUSB320XA_REGA_DISABLE_TERM, + FIELD_PREP(TUSB320XA_REGA_DISABLE_TERM, 1)); + if (ret) + goto done; + + /* Set to DRP by default, overriding any hardwired PORT setting */ + ret =3D regmap_write_bits(tusb->regmap, TUSB320XA_REGA, + TUSB320XA_REGA_MODE_SELECT, + FIELD_PREP(TUSB320XA_REGA_MODE_SELECT, + TUSB320XA_MODE_DRP)); + if (ret) + goto done; + + /* Wait 5 ms per datasheet specification */ + usleep_range(5000, 10000); + + /* Perform soft reset */ + ret =3D regmap_write_bits(tusb->regmap, TUSB320XA_REGA, + TUSB320XA_REGA_I2C_SOFT_RESET, + FIELD_PREP(TUSB320XA_REGA_I2C_SOFT_RESET, 1)); + if (ret) + goto done; + + /* Wait 95 ms for chip to reset per datasheet specification */ + msleep(95); + + /* Clear any old interrupt status bit */ + ret =3D regmap_write_bits(tusb->regmap, TUSB320XA_REG9, + TUSB320XA_REG9_INTERRUPT_STATUS, + FIELD_PREP(TUSB320XA_REG9_INTERRUPT_STATUS, 1)); + if (ret) + goto done; + + /* Re-enable CC state machine */ + ret =3D regmap_write_bits(tusb->regmap, TUSB320XA_REGA, + TUSB320XA_REGA_DISABLE_TERM, + FIELD_PREP(TUSB320XA_REGA_DISABLE_TERM, 0)); + if (ret) + goto done; + +done: + mutex_unlock(&tusb->lock); + + return ret; +} + +static int tusb320xa_sync_state(struct tusb320xa *tusb) +{ + enum tusb320xa_attached_state attached_state; + enum tusb320xa_cable_dir cable_dir; + enum tusb320xa_accessory accessory; + enum typec_orientation typec_orientation; + enum typec_data_role typec_data_role; + int typec_mode; + enum usb_role usb_role; + unsigned int reg8; + unsigned int reg9; + int ret; + + ret =3D regmap_read(tusb->regmap, TUSB320XA_REG8, ®8); + if (ret) + return ret; + + ret =3D regmap_read(tusb->regmap, TUSB320XA_REG9, ®9); + if (ret) + return ret; + + attached_state =3D FIELD_GET(TUSB320XA_REG9_ATTACHED_STATE, reg9); + cable_dir =3D FIELD_GET(TUSB320XA_REG9_CABLE_DIR, reg9); + accessory =3D FIELD_GET(TUSB320XA_REG8_ACCESSORY_CONNECTED, reg8); + + dev_dbg(tusb->dev, + "attached state: %s, cable direction: %s, accessory: %s\n", + tusb320xa_attached_states[attached_state], + tusb320xa_cable_directions[cable_dir], + tusb320xa_accessories[accessory]); + + if (cable_dir =3D=3D TUSB320XA_CABLE_DIR_CC1) + typec_orientation =3D TYPEC_ORIENTATION_NORMAL; + else + typec_orientation =3D TYPEC_ORIENTATION_REVERSE; + + switch (attached_state) { + case TUSB320XA_ATTACHED_STATE_NONE: + typec_orientation =3D TYPEC_ORIENTATION_NONE; + typec_data_role =3D TYPEC_HOST; + typec_mode =3D TYPEC_STATE_USB; + usb_role =3D USB_ROLE_NONE; + break; + case TUSB320XA_ATTACHED_STATE_DFP: + typec_data_role =3D TYPEC_HOST; + typec_mode =3D TYPEC_STATE_USB; + usb_role =3D USB_ROLE_HOST; + break; + case TUSB320XA_ATTACHED_STATE_UFP: + typec_data_role =3D TYPEC_DEVICE; + typec_mode =3D TYPEC_STATE_USB; + usb_role =3D USB_ROLE_DEVICE; + break; + case TUSB320XA_ATTACHED_STATE_ACC: + typec_data_role =3D TYPEC_HOST; + usb_role =3D USB_ROLE_HOST; + + if (accessory =3D=3D TUSB320XA_ACCESSORY_AUDIO || + accessory =3D=3D TUSB320XA_ACCESSORY_AUDIO_CHARGETHRU) { + typec_mode =3D TYPEC_MODE_AUDIO; + } else if (accessory =3D=3D TUSB320XA_ACCESSORY_DEBUG_DFP || + accessory =3D=3D TUSB320XA_ACCESSORY_DEBUG_UFP) { + typec_mode =3D TYPEC_MODE_DEBUG; + } else { + dev_warn(tusb->dev, "unknown accessory type: %d\n", + accessory); + typec_mode =3D TYPEC_STATE_USB; + } + + break; + } + + typec_set_orientation(tusb->port, typec_orientation); + typec_set_data_role(tusb->port, typec_data_role); + typec_set_mode(tusb->port, typec_mode); + usb_role_switch_set_role(tusb->role_sw, usb_role); + + return ret; +} + +static int tusb320xa_set_source_pref(struct tusb320xa *tusb, + enum tusb320xa_source_pref pref) +{ + int ret; + + mutex_lock(&tusb->lock); + + ret =3D regmap_update_bits(tusb->regmap, TUSB320XA_REGA, + TUSB320XA_REGA_SOURCE_PREF, + FIELD_PREP(TUSB320XA_REGA_SOURCE_PREF, pref)); + + mutex_unlock(&tusb->lock); + + return ret; +} + +static int tusb320xa_set_mode(struct tusb320xa *tusb, enum tusb320xa_mode = mode) +{ + int ret; + + mutex_lock(&tusb->lock); + + /* Disable CC state machine */ + ret =3D regmap_write_bits(tusb->regmap, TUSB320XA_REGA, + TUSB320XA_REGA_DISABLE_TERM, + FIELD_PREP(TUSB320XA_REGA_DISABLE_TERM, 1)); + if (ret) + goto done; + + /* Set the desired port mode */ + ret =3D regmap_write_bits(tusb->regmap, TUSB320XA_REGA, + TUSB320XA_REGA_MODE_SELECT, + FIELD_PREP(TUSB320XA_REGA_MODE_SELECT, mode)); + if (ret) + goto done; + + /* Wait 5 ms per datasheet specification */ + usleep_range(5000, 10000); + + /* Re-enable CC state machine */ + ret =3D regmap_write_bits(tusb->regmap, TUSB320XA_REGA, + TUSB320XA_REGA_DISABLE_TERM, + FIELD_PREP(TUSB320XA_REGA_DISABLE_TERM, 0)); + if (ret) + goto done; + +done: + mutex_unlock(&tusb->lock); + + return ret; +} + +static int tusb320xa_try_role(struct typec_port *port, int role) +{ + struct tusb320xa *tusb =3D typec_get_drvdata(port); + enum tusb320xa_source_pref pref; + + switch (role) { + case TYPEC_NO_PREFERRED_ROLE: + pref =3D TUSB320XA_SOURCE_PREF_DRP; + break; + case TYPEC_SINK: + pref =3D TUSB320XA_SOURCE_PREF_TRY_SNK; + break; + case TYPEC_SOURCE: + pref =3D TUSB320XA_SOURCE_PREF_TRY_SRC; + break; + default: + dev_warn(tusb->dev, "unknown port role %d\n", role); + return -EINVAL; + } + + return tusb320xa_set_source_pref(tusb, pref); +} + +static int tusb320xa_port_type_set(struct typec_port *port, + enum typec_port_type type) +{ + struct tusb320xa *tusb =3D typec_get_drvdata(port); + enum tusb320xa_mode mode; + + switch (type) { + case TYPEC_PORT_SRC: + mode =3D TUSB320XA_MODE_DFP; + break; + case TYPEC_PORT_SNK: + mode =3D TUSB320XA_MODE_UFP; + break; + case TYPEC_PORT_DRP: + mode =3D TUSB320XA_MODE_DRP; + break; + default: + dev_warn(tusb->dev, "unknown port type %d\n", type); + return -EINVAL; + } + + return tusb320xa_set_mode(tusb, mode); +} + +static const struct typec_operations tusb320xa_ops =3D { + .try_role =3D tusb320xa_try_role, + .port_type_set =3D tusb320xa_port_type_set, +}; + +static irqreturn_t tusb320xa_irq_handler_thread(int irq, void *dev_id) +{ + struct tusb320xa *tusb =3D dev_id; + unsigned int reg; + int ret; + + mutex_lock(&tusb->lock); + + /* Check interrupt status bit */ + ret =3D regmap_read(tusb->regmap, TUSB320XA_REG9, ®); + if (ret) + goto unhandled; + + if (!(reg & TUSB320XA_REG9_INTERRUPT_STATUS)) + goto unhandled; + + /* Clear interrupt status bit */ + ret =3D regmap_write(tusb->regmap, TUSB320XA_REG9, reg); + if (ret) + goto unhandled; + + ret =3D tusb320xa_sync_state(tusb); + if (ret) + dev_err_ratelimited(tusb->dev, + "failed to sync state in irq: %d\n", ret); + + mutex_unlock(&tusb->lock); + + return IRQ_HANDLED; + +unhandled: + mutex_unlock(&tusb->lock); + + return IRQ_NONE; +} + +static const struct regmap_config tusb320xa_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + .disable_locking =3D true, +}; + +void tusb320xa_action_role_sw_put(void *data) +{ + struct usb_role_switch *role_sw =3D data; + + usb_role_switch_put(role_sw); +} + +void tusb320xa_action_unregister_port(void *data) +{ + struct typec_port *port =3D data; + + typec_unregister_port(port); +} + +static int tusb320xa_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tusb320xa *tusb; + struct typec_capability typec_cap =3D {}; + int ret; + + tusb =3D devm_kzalloc(&client->dev, sizeof(*tusb), GFP_KERNEL); + if (!tusb) + return -ENOMEM; + + tusb->dev =3D &client->dev; + mutex_init(&tusb->lock); + + tusb->irq =3D client->irq; + if (!tusb->irq) + return -EINVAL; + + tusb->regmap =3D devm_regmap_init_i2c(client, &tusb320xa_regmap_config); + if (IS_ERR(tusb->regmap)) + return PTR_ERR(tusb->regmap); + + tusb->role_sw =3D usb_role_switch_get(tusb->dev); + if (IS_ERR(tusb->role_sw)) + return PTR_ERR(tusb->role_sw); + + ret =3D devm_add_action_or_reset(tusb->dev, tusb320xa_action_role_sw_put, + tusb->role_sw); + if (ret) + return ret; + + ret =3D tusb320xa_check_signature(tusb); + if (ret) + return ret; + + ret =3D tusb320xa_reset(tusb); + if (ret) + return ret; + + typec_cap.type =3D TYPEC_PORT_DRP; + typec_cap.data =3D TYPEC_PORT_DRD; + typec_cap.revision =3D USB_TYPEC_REV_1_1; + typec_cap.prefer_role =3D TYPEC_NO_PREFERRED_ROLE; + typec_cap.accessory[TYPEC_ACCESSORY_NONE] =3D 1; + typec_cap.accessory[TYPEC_ACCESSORY_AUDIO] =3D 1; + typec_cap.accessory[TYPEC_ACCESSORY_DEBUG] =3D 1; + typec_cap.orientation_aware =3D 1; + typec_cap.fwnode =3D dev_fwnode(tusb->dev); + typec_cap.driver_data =3D tusb; + typec_cap.ops =3D &tusb320xa_ops; + + tusb->port =3D typec_register_port(tusb->dev, &typec_cap); + if (IS_ERR(tusb->port)) + return PTR_ERR(tusb->port); + + ret =3D devm_add_action_or_reset(tusb->dev, + tusb320xa_action_unregister_port, + tusb->port); + if (ret) + return ret; + + ret =3D devm_request_threaded_irq(tusb->dev, tusb->irq, NULL, + tusb320xa_irq_handler_thread, + IRQF_ONESHOT | IRQF_TRIGGER_LOW, + "tusb320xa", tusb); + if (ret) + return ret; + + i2c_set_clientdata(client, tusb); + + return 0; +} + +static const struct of_device_id tusb320xa_dt_match[] =3D { + { + .compatible =3D "ti,tusb320la", + }, + { + .compatible =3D "ti,tusb320ha", + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, tusb320xa_dt_match); + +static struct i2c_driver tusb320xa_driver =3D { + .driver =3D { + .name =3D "tusb320xa", + .of_match_table =3D tusb320xa_dt_match, + }, + .probe =3D tusb320xa_probe, +}; + +module_i2c_driver(tusb320xa_driver); + +MODULE_AUTHOR("Alvin =C5=A0ipraga "); +MODULE_DESCRIPTION("TI TUSB320xA USB Type-C controller driver"); +MODULE_LICENSE("GPL v2"); --=20 2.35.1 From nobody Tue Jun 23 17:22:14 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1E70C433F5 for ; Tue, 1 Mar 2022 13:21:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235014AbiCANVv (ORCPT ); Tue, 1 Mar 2022 08:21:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39346 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234989AbiCANVr (ORCPT ); Tue, 1 Mar 2022 08:21:47 -0500 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 879BB9BBBF for ; Tue, 1 Mar 2022 05:20:56 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id c18-20020a7bc852000000b003806ce86c6dso1218065wml.5 for ; Tue, 01 Mar 2022 05:20:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pqrs.dk; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LF9kgMFX85Ga09K9b/Ao/dCg3JfyKCcVGPAMfvGhvZU=; b=joc0ZPemSKUrcLuqrcJDX7pUpA60Pbv32CtO/Te/5qSVtWnVsK4znw0CUnC30TWO3g kjBHgR1inpSJ9qiOxuLfiTo/GlVxfX2784npf8zUgfK/QW1ODq26z3YrMcnnnzLJHbWV /GWVHAISiEKzgw1DXSzRm38jnlvcVWp0okjcs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LF9kgMFX85Ga09K9b/Ao/dCg3JfyKCcVGPAMfvGhvZU=; b=OMd4H4yll4v6/g42MuCEgydb7/exicKFsWwIxAQbs2dBZ1sMH1SrPxQIswvV44yPpH BWQWxlgJClR9x1V+SPyDWKHOXHRgd0pyymmSBSOnopSRKXy5uOucUgHYIxtut9Mgi57m zX4eTinRJtdLtH9ehh6VXmmbfi3KYnQrR2bP0vE8d6cWqlVfIx4CjDBeyWxhkXHKHaIG B0v5bCEjOPNLpbrotCsI3YSaP/yWAQ/witp31xhMMATieRG0sPdHiz89NhwYoGp1oNZX 5ftI9an9WisdrscmquxgWyv+SQugXbWxFSRuVyyJhGVLMmMZbKld9VPGV9YwjBDmFyk6 gUMA== X-Gm-Message-State: AOAM531twa0EgHNO+ImacB7ZAkWQasY40kk60uhI89+NJPJZ/XLNpKEa V0bVM9j135mqyCf/OkDgVYttClYOzJAt0IDY X-Google-Smtp-Source: ABdhPJwnAmZtoeC8/AIV6oMl+kZFFH0eLQyXSV86ZYYQPU3UJZlxiSTP5z5PuVWFe2W039zB5LEQmQ== X-Received: by 2002:a05:600c:3203:b0:381:b544:7970 with SMTP id r3-20020a05600c320300b00381b5447970mr1950003wmp.144.1646140855026; Tue, 01 Mar 2022 05:20:55 -0800 (PST) Received: from capella.. (80.71.142.18.ipv4.parknet.dk. [80.71.142.18]) by smtp.gmail.com with ESMTPSA id i12-20020adfe48c000000b001ef6eab4c81sm13258492wrm.96.2022.03.01.05.20.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Mar 2022 05:20:54 -0800 (PST) From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= To: Greg Kroah-Hartman , Rob Herring , Heikki Krogerus , =?UTF-8?q?=A0ipraga?= Cc: linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/4] usb: typec: mux: add TS5USBA224 driver Date: Tue, 1 Mar 2022 14:20:08 +0100 Message-Id: <20220301132010.115258-5-alvin@pqrs.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220301132010.115258-1-alvin@pqrs.dk> References: <20220301132010.115258-1-alvin@pqrs.dk> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alvin =C5=A0ipraga The TS5USBA224 USB High Speed/Audio switch mux is typically used together with a Type-C port controller such as the TUSB320LAI. Below is a simplified typical application on an embedded platform: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90 = =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90 =E2=94=82 =E2=94=82 I2C =E2=94=82 = =E2=94=82 =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=A4 I2C =E2=94=82 =E2=94=82 TUSB320LAI =E2=94=82 INT_N =E2=94=82 = =E2=94=82 =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=A4 System-on- =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 = Chip =E2=94=82 =E2=94=82 CC1 CC2 =E2=94=82 =E2=94=8C=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=A4 GPIO =E2=94=82 =E2=94=94=E2=94=80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94=80=E2=94=AC= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=98 =E2= =94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2= =94=82 USBOTG =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2= =94=82 VBUS D+ D- =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2= =94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=AC=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94=80= =E2=94=AC=E2=94=80=E2=94=80=E2=94=98 =E2=94=82 =E2=94=82 =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=82=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=98 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=8C=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=B4=E2=94=80=E2=94=80=E2=94=90 =E2=94=82 = =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 A_SEL =E2= =94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2= =94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 D+ =E2= =94=9C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=98 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2= =94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=8C=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=A4 D+/L D- =E2=94=9C=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=98 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 = =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=8C=E2=94=80=E2= =94=80=E2=94=A4 D-/R =E2=94=82 Line_L =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 = L =E2=94=9C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80 =E2=94=B4 =E2=94=B4 =E2=94=B4 =E2=94=B4 =E2=94=B4 =E2=94=82 = =E2=94=82 Line_R USB Type-C port =E2=94=82 R =E2=94=9C=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 =E2=94=82 =E2=94=82 TS5USBA224 =E2=94=82 =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=98 This driver controls the TS5USBA224 via the A_SEL pin. In addition, it registers itself as a Type-C mux device. In the above scenario, the driver may be notified via the port controller driver if the CC pins indicate that an Audio Accessory is connected or not. Signed-off-by: Alvin =C5=A0ipraga --- drivers/usb/typec/mux/Kconfig | 10 +++ drivers/usb/typec/mux/Makefile | 1 + drivers/usb/typec/mux/ts5usba224.c | 102 +++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 drivers/usb/typec/mux/ts5usba224.c diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig index edead555835e..82c25b117652 100644 --- a/drivers/usb/typec/mux/Kconfig +++ b/drivers/usb/typec/mux/Kconfig @@ -19,4 +19,14 @@ config TYPEC_MUX_INTEL_PMC control the USB role switch and also the multiplexer/demultiplexer switches used with USB Type-C Alternate Modes. =20 +config TYPEC_MUX_TS5USBA224 + tristate "TI TS5USBA224 USB High Speed/Audio switch mux driver" + select GPIOLIB + help + Say Y or M if your system has a TI TS5USBA224 USB High Speed/Audio + switch mux controller paired with a USB Type-C port controller. + + If you choose to build this driver as a dynamically linked module, the + module will be called ts5usba224.ko. + endmenu diff --git a/drivers/usb/typec/mux/Makefile b/drivers/usb/typec/mux/Makefile index 280a6f553115..4b5f318656a0 100644 --- a/drivers/usb/typec/mux/Makefile +++ b/drivers/usb/typec/mux/Makefile @@ -2,3 +2,4 @@ =20 obj-$(CONFIG_TYPEC_MUX_PI3USB30532) +=3D pi3usb30532.o obj-$(CONFIG_TYPEC_MUX_INTEL_PMC) +=3D intel_pmc_mux.o +obj-$(CONFIG_TYPEC_MUX_TS5USBA224) +=3D ts5usba224.o diff --git a/drivers/usb/typec/mux/ts5usba224.c b/drivers/usb/typec/mux/ts5= usba224.c new file mode 100644 index 000000000000..4935dc8a0725 --- /dev/null +++ b/drivers/usb/typec/mux/ts5usba224.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * TI TS5USBA224 USB 2.0/audio switch mux driver + * + * Copyright (c) 2021 Alvin =C5=A0ipraga + */ + +#include +#include +#include +#include +#include +#include + +struct ts5usba224 { + struct device *dev; + struct typec_mux *mux; + struct gpio_desc *a_sel; +}; + +static int ts5usba224_mux_set(struct typec_mux *mux, + struct typec_mux_state *state) +{ + struct ts5usba224 *chip =3D typec_mux_get_drvdata(mux); + + switch (state->mode) { + case TYPEC_MODE_AUDIO: + gpiod_set_value_cansleep(chip->a_sel, 1); + dev_dbg(chip->dev, "audio switch enabled\n"); + break; + case TYPEC_STATE_USB: + case TYPEC_MODE_USB2: + default: + dev_dbg(chip->dev, "audio switch disabled\n"); + gpiod_set_value_cansleep(chip->a_sel, 0); + break; + } + + return 0; +} + +static int ts5usba224_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct typec_mux_desc mux_desc =3D {}; + struct ts5usba224 *chip; + int ret; + + chip =3D devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->dev =3D dev; + + chip->a_sel =3D devm_gpiod_get(dev, "asel", GPIOD_OUT_LOW); + if (IS_ERR(chip->a_sel)) { + ret =3D PTR_ERR(chip->a_sel); + return dev_err_probe(dev, ret, "failed to get A_SEL GPIO\n"); + } + + mux_desc.drvdata =3D chip; + mux_desc.fwnode =3D dev->fwnode; + mux_desc.set =3D ts5usba224_mux_set; + + chip->mux =3D typec_mux_register(dev, &mux_desc); + if (IS_ERR(chip->mux)) + return PTR_ERR(chip->mux); + + platform_set_drvdata(pdev, chip); + + return 0; +} + +static int ts5usba224_remove(struct platform_device *pdev) +{ + struct ts5usba224 *chip =3D platform_get_drvdata(pdev); + + typec_mux_unregister(chip->mux); + + return 0; +} + +static const struct of_device_id ts5usba224_of_match[] =3D { + { .compatible =3D "ti,ts5usba224", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ts5usba224_of_match); + +static struct platform_driver ts5usba224_driver =3D { + .driver =3D { + .name =3D "ts5usba224", + .of_match_table =3D of_match_ptr(ts5usba224_of_match), + }, + .probe =3D ts5usba224_probe, + .remove =3D ts5usba224_remove, +}; + +module_platform_driver(ts5usba224_driver); + +MODULE_AUTHOR("Alvin =C5=A0ipraga "); +MODULE_DESCRIPTION("TI TS5USBA224 mux driver"); +MODULE_LICENSE("GPL"); --=20 2.35.1