From patchwork Thu Oct 8 06:15:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268421 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1D0CC47095 for ; Thu, 8 Oct 2020 06:17:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7ACA9217BA for ; Thu, 8 Oct 2020 06:17:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="oR18h0Dq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728550AbgJHGQH (ORCPT ); Thu, 8 Oct 2020 02:16:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726245AbgJHGQF (ORCPT ); Thu, 8 Oct 2020 02:16:05 -0400 Received: from mail-qt1-x84a.google.com (mail-qt1-x84a.google.com [IPv6:2607:f8b0:4864:20::84a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3DC78C061755 for ; Wed, 7 Oct 2020 23:16:05 -0700 (PDT) Received: by mail-qt1-x84a.google.com with SMTP id b12so3055181qte.11 for ; Wed, 07 Oct 2020 23:16:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=w1vMQU/BkMb9kT/YLUI7Npn0R76aHLFoFk8FE0lAloQ=; b=oR18h0DqcKWUE6LMmngOUAiHEPQGT1hrKXEtX79uB0E/tLwRY6BQsadmDcDuwHkYAm dSe5jLSnVRMZcZfsR7X9x/I6IQcxbyB93Y+NNjCpODP6h43695X3XL+unbbW9ScApz5u FZKsGGT5op4zmil6YLzjDFhzLU8YiqOBREqlpqgS97HC7BjLihWJNpIB2ktpFTKwic6J hTuMBjhVVBO7bLNAmwKu3NhQjUwMFVaZmt3wu6GRQCvnNIpllaqS4ka+wIlZW1Bo2ZxS mZQBEiTs6xwA8n7IYaMq+pMqJXxiv4UN2/2szZDE0v8nvs4InGtI7YjQC2oYCXsQl+TJ s4Tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=w1vMQU/BkMb9kT/YLUI7Npn0R76aHLFoFk8FE0lAloQ=; b=SWNKPUftXXP9TsauYRkmyVKMgsm8MOQ7aKgk3P+uvXfFIVfJ4tyYN6g9yQp/1IyhSP KY+962y2euW0AYysdWXQwelQh6JQlMoJg49DpJWX6dlqSJEAAmunCqW74Oi1Enjs62kb wqS3Ed/tPbnotYmOdPGVrBVd5iprp06oB1wuWmKBP1u3rBIwetVLsy6ybbKF8wrycL2u 13d9zhgsEwSVr7/Ceg6kkZBckTyzshQauGWiorRPhcNht4FbzZUWwcLibjw+pG/HAQRq Skp/7vqsFm5K2c9jzqz0zueVJzofyzHQ9HsbZYy5iemot4BsjQJHPaVoWMKY8UonIMl2 ZhgQ== X-Gm-Message-State: AOAM531B2vn2L7FgZNyPTiW//haliy9uEUEBiqqVRIm4TjeV55DQhD6w l5QXF/pE8iUZ8Bx5tyvJyP8jaN+J1AA= X-Google-Smtp-Source: ABdhPJzRh9cJ5NxPokUHIc7XMPOSKRKLyVAc8CHFQkfgm+bmKjIOrAhqzy27ZPldN+JTVS5+grsGtlWMDGg= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:ad4:40c6:: with SMTP id x6mr6777681qvp.20.1602137764371; Wed, 07 Oct 2020 23:16:04 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:42 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-2-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 01/15] usb: typec: tcpci: Add a getter method to retrieve tcpm_port reference From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Allow chip level drivers to retrieve reference to tcpm_port. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- Change since v1: - Changing patch version to v6 to fix version number confusion. Change since v6: - Rebase on usb-next - Added Reviewed-by from Heikki. Change since v7: - Rebase on usb-next Change since v8: - None Change since v9: - None --- drivers/usb/typec/tcpm/tcpci.c | 6 ++++++ drivers/usb/typec/tcpm/tcpci.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index 7d9491ba62fb..b960fe5a0f28 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -38,6 +38,12 @@ struct tcpci_chip { struct tcpci_data data; }; +struct tcpm_port *tcpci_get_tcpm_port(struct tcpci *tcpci) +{ + return tcpci->port; +} +EXPORT_SYMBOL_GPL(tcpci_get_tcpm_port); + static inline struct tcpci *tcpc_to_tcpci(struct tcpc_dev *tcpc) { return container_of(tcpc, struct tcpci, tcpc); diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h index cf9d8b63adcb..04c49a0b0368 100644 --- a/drivers/usb/typec/tcpm/tcpci.h +++ b/drivers/usb/typec/tcpm/tcpci.h @@ -150,4 +150,6 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data); void tcpci_unregister_port(struct tcpci *tcpci); irqreturn_t tcpci_irq(struct tcpci *tcpci); +struct tcpm_port; +struct tcpm_port *tcpci_get_tcpm_port(struct tcpci *tcpci); #endif /* __LINUX_USB_TCPCI_H */ From patchwork Thu Oct 8 06:15:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268428 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1F15CC433E7 for ; Thu, 8 Oct 2020 06:16:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BF59920782 for ; Thu, 8 Oct 2020 06:16:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="XGy9aFVN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728612AbgJHGQM (ORCPT ); Thu, 8 Oct 2020 02:16:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36718 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728579AbgJHGQI (ORCPT ); Thu, 8 Oct 2020 02:16:08 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 29E6EC0613D6 for ; Wed, 7 Oct 2020 23:16:07 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id h9so3060655pfe.10 for ; Wed, 07 Oct 2020 23:16:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=26IIu7qceTcnJ+EWRo/AlWoSuX681bHhRQl11AqMEdc=; b=XGy9aFVNL/KY2Z5k9dUuZch+bB7ApdJZSU0DKyD41f3aqv7l474cmRuAISbEV6qa56 Vkp5sAGy8s5DeFlomTgAEazCj62rzKHw04ol+eFWSM0hyHIdwVyQxYhe5EaWY7z1VrZh jRWbXmG94jhIWuBhxkHmCC0ZIU9SMyq7pPVozYeZJ5AoeTyT5iqA0u3+1+zUHks0sOA8 RBrQwu/u/WtPXptXzxi56H1N4bLq9xU7BZnAnBpCVmGIuyEYE6lWySPVSB/kBs3ENVlv 27RZ93eo699wgcZlcO+qgJY6wz/RKlei8NTHOToptzrkx/lyg2+CVga7Oje1MSqpci12 3QTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=26IIu7qceTcnJ+EWRo/AlWoSuX681bHhRQl11AqMEdc=; b=DqbahLQRLJ3XMIC1urrsERtiETm14I3aS5bLgOsluA+DVAP8YGclwILl3jm5ctMI7T 3rrbQVEw3IeX5Q8wsn03NnyMXHEnoTxqqate59NkF9kCiBGd30ZmhZ2vFSD2bQZf0XkJ sW220ONv2TN26U4SeBaoEd0DNYYUE6cKdWY9c6j+3iZ9SGEj0O65p9sfvhT9mgwySayc UHSsm50XLsZ1c+rkSyzngVj6U85uYxwht3ZKH6SiovW5DQ6Tc+vQVWhcuxRj69CcO8LG xUJ5Pt3ImnPtNHICqZqmCWhovswwYIN8gL3Mc1P136reunMuNtJD7E9Mc7BnL2ebQtmH 1KaQ== X-Gm-Message-State: AOAM531Yuu7ALuhhLo/5C70CArdu0/ci48ZvP8t878k7dTVuCwDyPYhw 1hwFFUenZUjLkv8AHmB5Og6upBCcEWQ= X-Google-Smtp-Source: ABdhPJzutHXINK/HYTbrVV4jZqonDi/mJtIjT06Hq1tXwHeWrtqr9VbVfRjjqA0J37fA4NnwWmiHZj0V9qc= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a62:cfc6:0:b029:155:5057:7deb with SMTP id b189-20020a62cfc60000b029015550577debmr1526038pfg.43.1602137766594; Wed, 07 Oct 2020 23:16:06 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:43 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-3-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 02/15] usb: typec: tcpci: Add set_vbus tcpci callback From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org set_vbus callback allows TCPC which are TCPCI based, however, does not support turning on sink and source mode through Command.SinkVbus and Command.SourceVbusDefaultVoltage. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- Changes since v1: - Changing patch version to v6 to fix version number confusion. Changes since v6: - Rebase on usb-next Changes since v7: - Added Reviewed-by: Heikki - Rebase change Change since v8: - None Change since v9: - None --- drivers/usb/typec/tcpm/tcpci.c | 7 +++++++ drivers/usb/typec/tcpm/tcpci.h | 1 + 2 files changed, 8 insertions(+) diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index b960fe5a0f28..d6a6fac82d48 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -328,6 +328,13 @@ static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink) struct tcpci *tcpci = tcpc_to_tcpci(tcpc); int ret; + if (tcpci->data->set_vbus) { + ret = tcpci->data->set_vbus(tcpci, tcpci->data, source, sink); + /* Bypass when ret > 0 */ + if (ret != 0) + return ret < 0 ? ret : 0; + } + /* Disable both source and sink first before enabling anything */ if (!source) { diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h index 04c49a0b0368..4d441bdf24d5 100644 --- a/drivers/usb/typec/tcpm/tcpci.h +++ b/drivers/usb/typec/tcpm/tcpci.h @@ -144,6 +144,7 @@ struct tcpci_data { bool enable); int (*start_drp_toggling)(struct tcpci *tcpci, struct tcpci_data *data, enum typec_cc_status cc); + int (*set_vbus)(struct tcpci *tcpci, struct tcpci_data *data, bool source, bool sink); }; struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data); From patchwork Thu Oct 8 06:15:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268753 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 912D6C46466 for ; Thu, 8 Oct 2020 06:16:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3A07021897 for ; Thu, 8 Oct 2020 06:16:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="TcQlrlgY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727605AbgJHGQZ (ORCPT ); Thu, 8 Oct 2020 02:16:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36726 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728600AbgJHGQJ (ORCPT ); Thu, 8 Oct 2020 02:16:09 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27607C0613D2 for ; Wed, 7 Oct 2020 23:16:09 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id y7so3044082pff.20 for ; Wed, 07 Oct 2020 23:16:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=qREnjimRvXvFv14cu2Mdee7FTQw1clOjNi7le952Vyw=; b=TcQlrlgY6FCgtg3cVzVVSia+tZL5ToTRLB3TQ3Z3BSmx0AeDXVkonOCCympIMCPA60 xZITTW6+FY/82C6MVAyur+WQv+Sbaf8ErZqPHPOSwWgUCAmEbHXEjI3Ho5ys6ZChI5wH xGoWs3AxR3T88L6srkvgsIGoOSL+uogtov/fDRXaIpXvRfvLY5eBAuFc5VKoAfbRfa1t yRdG70DxamhpyzHuEnbnvdyMjO2l/gOXsDYplgHNLTAz0QqQcrd5PfEwxpYSNEV+vJEy 05wZm6dV+XvcNdz/EMiSQLWeqdI8xc7IMsagkwv1zAXsWTRVRpBPPsU7irZl/XjQHeET cHsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=qREnjimRvXvFv14cu2Mdee7FTQw1clOjNi7le952Vyw=; b=kvSt2DPTXSddskkgz5gal0v66pRsvpiF1IJNTC7CJKIWuoit+ZUQC41CIktvWlBKgA HGn8gLy5Vjn3ck+hHTCExiGLZeipyQ9tXHXm4zhWeMJOFvPU1EiHjdqJdN8eynkXPYN2 8PT2u5KGm9DpwAi/o9twp9U9IhMs+HSLrLl/h2PEEZn1VR67qKCHzKPeDgeQkM6vXHiX zyIT+YGif4Uzn9MX6nohIQReoX/p3SqRZRUQm/KbDOqoSL2vSpazD8Hp1FnyB9dryufQ N3O3B7yfltgc/Z9WY+CRvJ50XkQ84sAHBl914syBoFXOu/3m1DqG+qpsoNyw4dB2L1Za 42IQ== X-Gm-Message-State: AOAM531Fsiy6XQBtS2bqxd3qRSWTY3ZhDWa2R2FnF6KmgTsuaMchETuX NSilbotHSi9RzLdH8//LYrM9Q9OGDoo= X-Google-Smtp-Source: ABdhPJzvHDLGP+igoqH53dJ2k49U6QLMJba95bZHrAFiCqofD8WzzcI1hZpnEsj2C3HhyRTk/GQlHKJPkZ4= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a17:90a:b896:: with SMTP id o22mr4704764pjr.130.1602137768574; Wed, 07 Oct 2020 23:16:08 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:44 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-4-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 03/15] dt-bindings: usb: Maxim type-c controller device tree binding document From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Add device tree binding document for Maxim TCPCI based Type-C chip driver Signed-off-by: Badhri Jagan Sridharan --- Changes since v1: - Changing patch version to v6 to fix version number confusion. Changes since v6: - Migrated to yaml format. Changes since v7: - Rebase on usb-next Changes since v8: - Fix errors from make dt_binding_check as suggested by Rob Herring. Changes since v9: - additionalProperties: false as suggested by Rob Herring. --- .../devicetree/bindings/usb/maxim,tcpci.yaml | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/maxim,tcpci.yaml diff --git a/Documentation/devicetree/bindings/usb/maxim,tcpci.yaml b/Documentation/devicetree/bindings/usb/maxim,tcpci.yaml new file mode 100644 index 000000000000..12e0ece1b515 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/maxim,tcpci.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/usb/maxim,tcpci.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Maxim TCPCI Type-C PD controller DT bindings + +maintainers: + - Badhri Jagan Sridharan + +description: Maxim TCPCI Type-C PD controller + +properties: + compatible: + enum: + - maxim,tcpci + + interrupts: + maxItems: 1 + + connector: + type: object + $ref: ../connector/usb-connector.yaml# + description: + Properties for usb c connector. + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + #include + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + maxtcpc@25 { + compatible = "maxim,tcpc"; + reg = <0x25>; + interrupt-parent = <&gpa8>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + + connector { + compatible = "usb-c-connector"; + label = "USB-C"; + data-role = "dual"; + power-role = "dual"; + try-power-role = "sink"; + self-powered; + op-sink-microwatt = <2600000>; + source-pdos = ; + sink-pdos = ; + }; + }; + }; +... From patchwork Thu Oct 8 06:15:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268427 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BBEECC4363C for ; Thu, 8 Oct 2020 06:16:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4EC76206BE for ; Thu, 8 Oct 2020 06:16:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="rZgNuzvj" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728696AbgJHGQY (ORCPT ); Thu, 8 Oct 2020 02:16:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36738 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728611AbgJHGQM (ORCPT ); Thu, 8 Oct 2020 02:16:12 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DCD6C0613D5 for ; Wed, 7 Oct 2020 23:16:11 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id r9so2845202plo.13 for ; Wed, 07 Oct 2020 23:16:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=B2we/eW3GsP6GsOJXudMZkf6NAHRJz6peAChklTIF6s=; b=rZgNuzvjgLGzPnZ9caZvEP7QmZbhMi7UjUNM33rL/dxyu8VdFFz32LVmfpNM/MoPWJ UI+X/fKfwCWPzQJHIvnrMW4M0PUpBg/qlYZW6B1s/IOt6qpFC4+J7gCZCsxBXkXCdzhg VM+V2h3ehRnFpilPP9qOkl2FNJiTOzlsxfjTiH2ib0v033gh3mqcyrf11/WMSXEGu5JF tH08S4nZGsUxjMTTVRdGdgE0ZPH3h0Ida62ReWsNUJDIukSDJqu+XMkCpy0Z37zOzPS8 L6uubec+Vpnu5uxSZ6JCpB7tRmctP1dSdWxYIQ+hAZmcrAd7w3Xy60cBVzOCZmEmrkL1 2W2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=B2we/eW3GsP6GsOJXudMZkf6NAHRJz6peAChklTIF6s=; b=bHe8wsM2mOCuKfELN+Xv0KbXjMbR/qNrZ08uygHO3HtoTBqRImkxy95KupxBc56S1m /zYSdQxeJnLMmKQflKL7Zk80miAhrf3LMqIMtsKolIKKTvnws/9T+UG5uCY8b3M2dhmv 4/B5U6ezKgvORWiS/AaESmKLlnE9yvYtKNALh0kIyLzq33yZuWZYjEfrPcj45BysxEC9 r6Wq5wIlynlvh7lGI8mV9kK0BDrnbNcqIQA5nvX73u7Bzkh7GTO0qnKFkq+3wPYBHU+n ks0ksGehUSSumErzHz9E7KbsH6Y6q23OXlTP2TCnB8J8O2O0aJ0mVXmoaWzzyODdd6Ih 1cXg== X-Gm-Message-State: AOAM532VHuuXkZ/M3EwFSOvvKVrbOdvrV/tD59mUgW2XxFzlA+c4vgGf km3Kj3UV3M9aOc0XHZhVIDwjxmXNE78= X-Google-Smtp-Source: ABdhPJxuZrPkH227fkdz+Oodqn4imEqQIkqcTER3D5cGM42syrky+JgWk3QA0DmLiBhIerMpC5LWkA0OeHk= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a17:90a:dc06:: with SMTP id i6mr6618022pjv.162.1602137770583; Wed, 07 Oct 2020 23:16:10 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:45 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-5-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 04/15] usb: typec: tcpci_maxim: Chip level TCPC driver From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Chip level TCPC driver for Maxim's TCPCI implementation. This TCPC implementation does not support the following commands: COMMAND.SinkVbus, COMMAND.SourceVbusDefaultVoltage, COMMAND.SourceVbusHighVoltage. Instead the sinking and sourcing from vbus is supported by writes to custom registers. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- Changes since v1: - Changing patch version to v6 to fix version number confusion. - Removed setting USB_PSY and terminating description with period as suggested by Randy. Changes since v6: - Addressed Heikki comments: - Removed TX discarded message - Removed the redundant TCPC_POWER_STATUS_UNINIT check - Cleaned up irq setup routine Changes since v7: - Added reviewed-by: Heikki Changes since v8: - None Changes since v9: - None --- drivers/usb/typec/tcpm/Kconfig | 6 + drivers/usb/typec/tcpm/Makefile | 15 +- drivers/usb/typec/tcpm/tcpci.h | 1 + drivers/usb/typec/tcpm/tcpci_maxim.c | 461 +++++++++++++++++++++++++++ 4 files changed, 476 insertions(+), 7 deletions(-) create mode 100644 drivers/usb/typec/tcpm/tcpci_maxim.c diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig index 58a64e1bf627..557f392fe24d 100644 --- a/drivers/usb/typec/tcpm/Kconfig +++ b/drivers/usb/typec/tcpm/Kconfig @@ -35,6 +35,12 @@ config TYPEC_MT6360 USB Type-C. It works with Type-C Port Controller Manager to provide USB PD and USB Type-C functionalities. +config TYPEC_TCPCI_MAXIM + tristate "Maxim TCPCI based Type-C chip driver" + help + MAXIM TCPCI based Type-C/PD chip driver. Works with + with Type-C Port Controller Manager. + endif # TYPEC_TCPCI config TYPEC_FUSB302 diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile index 7592ccb8c526..7d499f3569fd 100644 --- a/drivers/usb/typec/tcpm/Makefile +++ b/drivers/usb/typec/tcpm/Makefile @@ -1,8 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_TYPEC_TCPM) += tcpm.o -obj-$(CONFIG_TYPEC_FUSB302) += fusb302.o -obj-$(CONFIG_TYPEC_WCOVE) += typec_wcove.o -typec_wcove-y := wcove.o -obj-$(CONFIG_TYPEC_TCPCI) += tcpci.o -obj-$(CONFIG_TYPEC_RT1711H) += tcpci_rt1711h.o -obj-$(CONFIG_TYPEC_MT6360) += tcpci_mt6360.o +obj-$(CONFIG_TYPEC_TCPM) += tcpm.o +obj-$(CONFIG_TYPEC_FUSB302) += fusb302.o +obj-$(CONFIG_TYPEC_WCOVE) += typec_wcove.o +typec_wcove-y := wcove.o +obj-$(CONFIG_TYPEC_TCPCI) += tcpci.o +obj-$(CONFIG_TYPEC_RT1711H) += tcpci_rt1711h.o +obj-$(CONFIG_TYPEC_MT6360) += tcpci_mt6360.o +obj-$(CONFIG_TYPEC_TCPCI_MAXIM) += tcpci_maxim.o diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h index 4d441bdf24d5..82f021a82456 100644 --- a/drivers/usb/typec/tcpm/tcpci.h +++ b/drivers/usb/typec/tcpm/tcpci.h @@ -109,6 +109,7 @@ #define TCPC_RX_BYTE_CNT 0x30 #define TCPC_RX_BUF_FRAME_TYPE 0x31 +#define TCPC_RX_BUF_FRAME_TYPE_SOP 0 #define TCPC_RX_HDR 0x32 #define TCPC_RX_DATA 0x34 /* through 0x4f */ diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c new file mode 100644 index 000000000000..91337ddb4962 --- /dev/null +++ b/drivers/usb/typec/tcpm/tcpci_maxim.c @@ -0,0 +1,461 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020, Google LLC + * + * MAXIM TCPCI based TCPC driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tcpci.h" + +#define PD_ACTIVITY_TIMEOUT_MS 10000 + +#define TCPC_VENDOR_ALERT 0x80 + +#define TCPC_RECEIVE_BUFFER_COUNT_OFFSET 0 +#define TCPC_RECEIVE_BUFFER_FRAME_TYPE_OFFSET 1 +#define TCPC_RECEIVE_BUFFER_RX_BYTE_BUF_OFFSET 2 + +/* + * LongMessage not supported, hence 32 bytes for buf to be read from RECEIVE_BUFFER. + * DEVICE_CAPABILITIES_2.LongMessage = 0, the value in READABLE_BYTE_COUNT reg shall be + * less than or equal to 31. Since, RECEIVE_BUFFER len = 31 + 1(READABLE_BYTE_COUNT). + */ +#define TCPC_RECEIVE_BUFFER_LEN 32 + +#define MAX_BUCK_BOOST_SID 0x69 +#define MAX_BUCK_BOOST_OP 0xb9 +#define MAX_BUCK_BOOST_OFF 0 +#define MAX_BUCK_BOOST_SOURCE 0xa +#define MAX_BUCK_BOOST_SINK 0x5 + +struct max_tcpci_chip { + struct tcpci_data data; + struct tcpci *tcpci; + struct device *dev; + struct i2c_client *client; + struct tcpm_port *port; +}; + +static const struct regmap_range max_tcpci_tcpci_range[] = { + regmap_reg_range(0x00, 0x95) +}; + +const struct regmap_access_table max_tcpci_tcpci_write_table = { + .yes_ranges = max_tcpci_tcpci_range, + .n_yes_ranges = ARRAY_SIZE(max_tcpci_tcpci_range), +}; + +static const struct regmap_config max_tcpci_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x95, + .wr_table = &max_tcpci_tcpci_write_table, +}; + +static struct max_tcpci_chip *tdata_to_max_tcpci(struct tcpci_data *tdata) +{ + return container_of(tdata, struct max_tcpci_chip, data); +} + +static int max_tcpci_read16(struct max_tcpci_chip *chip, unsigned int reg, u16 *val) +{ + return regmap_raw_read(chip->data.regmap, reg, val, sizeof(u16)); +} + +static int max_tcpci_write16(struct max_tcpci_chip *chip, unsigned int reg, u16 val) +{ + return regmap_raw_write(chip->data.regmap, reg, &val, sizeof(u16)); +} + +static int max_tcpci_read8(struct max_tcpci_chip *chip, unsigned int reg, u8 *val) +{ + return regmap_raw_read(chip->data.regmap, reg, val, sizeof(u8)); +} + +static int max_tcpci_write8(struct max_tcpci_chip *chip, unsigned int reg, u8 val) +{ + return regmap_raw_write(chip->data.regmap, reg, &val, sizeof(u8)); +} + +static void max_tcpci_init_regs(struct max_tcpci_chip *chip) +{ + u16 alert_mask = 0; + int ret; + + ret = max_tcpci_write16(chip, TCPC_ALERT, 0xffff); + if (ret < 0) { + dev_err(chip->dev, "Error writing to TCPC_ALERT ret:%d\n", ret); + return; + } + + ret = max_tcpci_write16(chip, TCPC_VENDOR_ALERT, 0xffff); + if (ret < 0) { + dev_err(chip->dev, "Error writing to TCPC_VENDOR_ALERT ret:%d\n", ret); + return; + } + + alert_mask = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_TX_FAILED | + TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_RX_STATUS | TCPC_ALERT_CC_STATUS | + TCPC_ALERT_VBUS_DISCNCT | TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_POWER_STATUS; + + ret = max_tcpci_write16(chip, TCPC_ALERT_MASK, alert_mask); + if (ret < 0) { + dev_err(chip->dev, "Error writing to TCPC_ALERT_MASK ret:%d\n", ret); + return; + } + + /* Enable vbus voltage monitoring and voltage alerts */ + ret = max_tcpci_write8(chip, TCPC_POWER_CTRL, 0); + if (ret < 0) { + dev_err(chip->dev, "Error writing to TCPC_POWER_CTRL ret:%d\n", ret); + return; + } +} + +static void process_rx(struct max_tcpci_chip *chip, u16 status) +{ + struct pd_message msg; + u8 count, frame_type, rx_buf[TCPC_RECEIVE_BUFFER_LEN]; + int ret, payload_index; + u8 *rx_buf_ptr; + + /* + * READABLE_BYTE_COUNT: Indicates the number of bytes in the RX_BUF_BYTE_x registers + * plus one (for the RX_BUF_FRAME_TYPE) Table 4-36. + * Read the count and frame type. + */ + ret = regmap_raw_read(chip->data.regmap, TCPC_RX_BYTE_CNT, rx_buf, 2); + if (ret < 0) { + dev_err(chip->dev, "TCPC_RX_BYTE_CNT read failed ret:%d", ret); + return; + } + + count = rx_buf[TCPC_RECEIVE_BUFFER_COUNT_OFFSET]; + frame_type = rx_buf[TCPC_RECEIVE_BUFFER_FRAME_TYPE_OFFSET]; + + if (count == 0 || frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP) { + max_tcpci_write16(chip, TCPC_ALERT, TCPC_ALERT_RX_STATUS); + dev_err(chip->dev, "%s", count == 0 ? "error: count is 0" : + "error frame_type is not SOP"); + return; + } + + if (count > sizeof(struct pd_message) || count + 1 > TCPC_RECEIVE_BUFFER_LEN) { + dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d", count); + return; + } + + /* + * Read count + 1 as RX_BUF_BYTE_x is hidden and can only be read through + * TCPC_RX_BYTE_CNT + */ + count += 1; + ret = regmap_raw_read(chip->data.regmap, TCPC_RX_BYTE_CNT, rx_buf, count); + if (ret < 0) { + dev_err(chip->dev, "Error: TCPC_RX_BYTE_CNT read failed: %d", ret); + return; + } + + rx_buf_ptr = rx_buf + TCPC_RECEIVE_BUFFER_RX_BYTE_BUF_OFFSET; + msg.header = cpu_to_le16(*(u16 *)rx_buf_ptr); + rx_buf_ptr = rx_buf_ptr + sizeof(msg.header); + for (payload_index = 0; payload_index < pd_header_cnt_le(msg.header); payload_index++, + rx_buf_ptr += sizeof(msg.payload[0])) + msg.payload[payload_index] = cpu_to_le32(*(u32 *)rx_buf_ptr); + + /* + * Read complete, clear RX status alert bit. + * Clear overflow as well if set. + */ + ret = max_tcpci_write16(chip, TCPC_ALERT, status & TCPC_ALERT_RX_BUF_OVF ? + TCPC_ALERT_RX_STATUS | TCPC_ALERT_RX_BUF_OVF : + TCPC_ALERT_RX_STATUS); + if (ret < 0) + return; + + tcpm_pd_receive(chip->port, &msg); +} + +static int max_tcpci_set_vbus(struct tcpci *tcpci, struct tcpci_data *tdata, bool source, bool sink) +{ + struct max_tcpci_chip *chip = tdata_to_max_tcpci(tdata); + u8 buffer_source[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_SOURCE}; + u8 buffer_sink[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_SINK}; + u8 buffer_none[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_OFF}; + struct i2c_client *i2c = chip->client; + int ret; + + struct i2c_msg msgs[] = { + { + .addr = MAX_BUCK_BOOST_SID, + .flags = i2c->flags & I2C_M_TEN, + .len = 2, + .buf = source ? buffer_source : sink ? buffer_sink : buffer_none, + }, + }; + + if (source && sink) { + dev_err(chip->dev, "Both source and sink set\n"); + return -EINVAL; + } + + ret = i2c_transfer(i2c->adapter, msgs, 1); + + return ret < 0 ? ret : 1; +} + +static void process_power_status(struct max_tcpci_chip *chip) +{ + u8 pwr_status; + int ret; + + ret = max_tcpci_read8(chip, TCPC_POWER_STATUS, &pwr_status); + if (ret < 0) + return; + + if (pwr_status == 0xff) + max_tcpci_init_regs(chip); + else + tcpm_vbus_change(chip->port); +} + +static void process_tx(struct max_tcpci_chip *chip, u16 status) +{ + if (status & TCPC_ALERT_TX_SUCCESS) + tcpm_pd_transmit_complete(chip->port, TCPC_TX_SUCCESS); + else if (status & TCPC_ALERT_TX_DISCARDED) + tcpm_pd_transmit_complete(chip->port, TCPC_TX_DISCARDED); + else if (status & TCPC_ALERT_TX_FAILED) + tcpm_pd_transmit_complete(chip->port, TCPC_TX_FAILED); + + /* Reinit regs as Hard reset sets them to default value */ + if ((status & TCPC_ALERT_TX_SUCCESS) && (status & TCPC_ALERT_TX_FAILED)) + max_tcpci_init_regs(chip); +} + +static irqreturn_t _max_tcpci_irq(struct max_tcpci_chip *chip, u16 status) +{ + u16 mask; + int ret; + + /* + * Clear alert status for everything except RX_STATUS, which shouldn't + * be cleared until we have successfully retrieved message. + */ + if (status & ~TCPC_ALERT_RX_STATUS) { + mask = status & TCPC_ALERT_RX_BUF_OVF ? + status & ~(TCPC_ALERT_RX_STATUS | TCPC_ALERT_RX_BUF_OVF) : + status & ~TCPC_ALERT_RX_STATUS; + ret = max_tcpci_write16(chip, TCPC_ALERT, mask); + if (ret < 0) { + dev_err(chip->dev, "ALERT clear failed\n"); + return ret; + } + } + + if (status & TCPC_ALERT_RX_BUF_OVF && !(status & TCPC_ALERT_RX_STATUS)) { + ret = max_tcpci_write16(chip, TCPC_ALERT, (TCPC_ALERT_RX_STATUS | + TCPC_ALERT_RX_BUF_OVF)); + if (ret < 0) { + dev_err(chip->dev, "ALERT clear failed\n"); + return ret; + } + } + + if (status & TCPC_ALERT_RX_STATUS) + process_rx(chip, status); + + if (status & TCPC_ALERT_VBUS_DISCNCT) + tcpm_vbus_change(chip->port); + + if (status & TCPC_ALERT_CC_STATUS) + tcpm_cc_change(chip->port); + + if (status & TCPC_ALERT_POWER_STATUS) + process_power_status(chip); + + if (status & TCPC_ALERT_RX_HARD_RST) { + tcpm_pd_hard_reset(chip->port); + max_tcpci_init_regs(chip); + } + + if (status & TCPC_ALERT_TX_SUCCESS || status & TCPC_ALERT_TX_DISCARDED || status & + TCPC_ALERT_TX_FAILED) + process_tx(chip, status); + + return IRQ_HANDLED; +} + +static irqreturn_t max_tcpci_irq(int irq, void *dev_id) +{ + struct max_tcpci_chip *chip = dev_id; + u16 status; + irqreturn_t irq_return; + int ret; + + if (!chip->port) + return IRQ_HANDLED; + + ret = max_tcpci_read16(chip, TCPC_ALERT, &status); + if (ret < 0) { + dev_err(chip->dev, "ALERT read failed\n"); + return ret; + } + while (status) { + irq_return = _max_tcpci_irq(chip, status); + /* Do not return if the ALERT is already set. */ + ret = max_tcpci_read16(chip, TCPC_ALERT, &status); + if (ret < 0) + break; + } + + return irq_return; +} + +static irqreturn_t max_tcpci_isr(int irq, void *dev_id) +{ + struct max_tcpci_chip *chip = dev_id; + + pm_wakeup_event(chip->dev, PD_ACTIVITY_TIMEOUT_MS); + + if (!chip->port) + return IRQ_HANDLED; + + return IRQ_WAKE_THREAD; +} + +static int max_tcpci_init_alert(struct max_tcpci_chip *chip, struct i2c_client *client) +{ + int ret; + + ret = devm_request_threaded_irq(chip->dev, client->irq, max_tcpci_isr, max_tcpci_irq, + (IRQF_TRIGGER_LOW | IRQF_ONESHOT), dev_name(chip->dev), + chip); + + if (ret < 0) + return ret; + + enable_irq_wake(client->irq); + return 0; +} + +static int max_tcpci_start_toggling(struct tcpci *tcpci, struct tcpci_data *tdata, + enum typec_cc_status cc) +{ + struct max_tcpci_chip *chip = tdata_to_max_tcpci(tdata); + + max_tcpci_init_regs(chip); + + return 0; +} + +static int tcpci_init(struct tcpci *tcpci, struct tcpci_data *data) +{ + /* + * Generic TCPCI overwrites the regs once this driver initializes + * them. Prevent this by returning -1. + */ + return -1; +} + +static int max_tcpci_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) +{ + int ret; + struct max_tcpci_chip *chip; + u8 power_status; + + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->client = client; + chip->data.regmap = devm_regmap_init_i2c(client, &max_tcpci_regmap_config); + if (IS_ERR(chip->data.regmap)) { + dev_err(&client->dev, "Regmap init failed\n"); + return PTR_ERR(chip->data.regmap); + } + + chip->dev = &client->dev; + i2c_set_clientdata(client, chip); + + ret = max_tcpci_read8(chip, TCPC_POWER_STATUS, &power_status); + if (ret < 0) + return ret; + + /* Chip level tcpci callbacks */ + chip->data.set_vbus = max_tcpci_set_vbus; + chip->data.start_drp_toggling = max_tcpci_start_toggling; + chip->data.TX_BUF_BYTE_x_hidden = true; + chip->data.init = tcpci_init; + + max_tcpci_init_regs(chip); + chip->tcpci = tcpci_register_port(chip->dev, &chip->data); + if (IS_ERR_OR_NULL(chip->tcpci)) { + dev_err(&client->dev, "TCPCI port registration failed"); + ret = PTR_ERR(chip->tcpci); + return PTR_ERR(chip->tcpci); + } + chip->port = tcpci_get_tcpm_port(chip->tcpci); + ret = max_tcpci_init_alert(chip, client); + if (ret < 0) + goto unreg_port; + + device_init_wakeup(chip->dev, true); + return 0; + +unreg_port: + tcpci_unregister_port(chip->tcpci); + + return ret; +} + +static int max_tcpci_remove(struct i2c_client *client) +{ + struct max_tcpci_chip *chip = i2c_get_clientdata(client); + + if (!IS_ERR_OR_NULL(chip->tcpci)) + tcpci_unregister_port(chip->tcpci); + + return 0; +} + +static const struct i2c_device_id max_tcpci_id[] = { + { "maxtcpc", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max_tcpci_id); + +#ifdef CONFIG_OF +static const struct of_device_id max_tcpci_of_match[] = { + { .compatible = "maxim,tcpc", }, + {}, +}; +MODULE_DEVICE_TABLE(of, max_tcpci_of_match); +#endif + +static struct i2c_driver max_tcpci_i2c_driver = { + .driver = { + .name = "maxtcpc", + .of_match_table = of_match_ptr(max_tcpci_of_match), + }, + .probe = max_tcpci_probe, + .remove = max_tcpci_remove, + .id_table = max_tcpci_id, +}; +module_i2c_driver(max_tcpci_i2c_driver); + +MODULE_AUTHOR("Badhri Jagan Sridharan "); +MODULE_DESCRIPTION("Maxim TCPCI based USB Type-C Port Controller Interface Driver"); +MODULE_LICENSE("GPL v2"); From patchwork Thu Oct 8 06:15:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268754 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4ACE7C4363C for ; Thu, 8 Oct 2020 06:16:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ED87A2173E for ; Thu, 8 Oct 2020 06:16:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="AO+qSVcM" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728618AbgJHGQO (ORCPT ); Thu, 8 Oct 2020 02:16:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36748 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728615AbgJHGQN (ORCPT ); Thu, 8 Oct 2020 02:16:13 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4D16FC061755 for ; Wed, 7 Oct 2020 23:16:13 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id a16so3062794pfk.2 for ; Wed, 07 Oct 2020 23:16:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=pU3ntvw5VhyZXXSja7TGihUxq3Mbbo0tGAqQrbv/0ac=; b=AO+qSVcMVuJZ04dE9/iT/5aA9BjaV24JVS38BBrQ0dTuXUAbTbnmmrXwM2WrE4rZtn kiATLCnfIwm3X+mWZB6Fa4UHvbxJoOd6triutiLSnsDqFaTlEnpYIFKdcOjcMHWLCKPT HFpJp6DGy616Lv3QerL04buG0pAVcVEYUFJUtKxSVVrfeuVpYDP4fwv2XLtENJ6OCi+V bdGP5rsHFNzSRjUGoRiw/mA8BJuqZncMobcDpgnHHN/q4WrGIjJTi6SjpBIMwoT9TST8 w7DV2fq0GVrZv35cJETsShKeDoe0x4Obwx7Y54H31BqUZbptx9N0Jyb/TvMiGoCGOnBx 0qNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=pU3ntvw5VhyZXXSja7TGihUxq3Mbbo0tGAqQrbv/0ac=; b=nHa07zkJalPsm40gHGabAzCiCTOK6IzbpHMIkc+IRZHHLUeAtTdsHFKbRWAyDH+Y17 GQPPu/cWElQZvvvrAuRv2VNfoBMwzYoJOoN3YUQJnTIuyhbKgL0yBoUEpARRDuUCqhd1 NJkB4wUVyuXkOmHBsG8MT88P2D4gQbfE/25fD3t1MvBV4R4/nC7a/LMkq6Lbm+uncs1G KjDotsoht0dZq4X1aXPFLsHPziYw8MLdCpQ79HP6T5XPnawKf0QOryPEbToyHOS2iu++ d1I11Q8x4a3LsTTkmejMgh1BnBSzKjASuIpcM0gmL+Ji4wy6qXPz8yXr/8M+/KQXL6Gs wxLw== X-Gm-Message-State: AOAM530+Q1PI98HJeyaIxEJTUcOV4rermEdTxeI+AzTunDuQNNMk54VI KOrQpQXYwCfdWw+6d6QGgT9pEg4SCmM= X-Google-Smtp-Source: ABdhPJwD/rV3SqOiQdV3MQ6wQLteef9mSzob81GfSTpoiJIuCieKJd9HRFp8oMPGKl92bdbnY4HBTsXIKRk= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a63:d257:: with SMTP id t23mr6247833pgi.212.1602137772764; Wed, 07 Oct 2020 23:16:12 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:46 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-6-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 05/15] dt-bindings: connector: Add property to set initial current cap for FRS From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org This change adds frs-typec-current which allows setting the initial current capability of the new source when vSafe5V is applied during PD3.0 sink Fast Role Swap. Signed-off-by: Badhri Jagan Sridharan --- Changes since v1: - Changing patch version to v6 to fix version number confusion. Changes since v6: - Removed the redundant usb-connector.txt that I created by mistake. - Moved to yaml. Changes since v7: - Rebase Changes since v8: - Redefine new-source-frs-typec-current as string enums to address Rob Herring's comment. Changes since v9: - Removed FRS constants from usb bindings. --- .../bindings/connector/usb-connector.yaml | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml index 9bd52e63c935..d9f65e81065e 100644 --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml @@ -142,6 +142,32 @@ properties: required: - port@0 + new-source-frs-typec-current: + description: Initial current capability of the new source when vSafe5V + is applied during PD3.0 Fast Role Swap. "Table 6-14 Fixed Supply PDO - Sink" + of "USB Power Delivery Specification Revision 3.0, Version 1.2" provides the + different power levels and "6.4.1.3.1.6 Fast Role Swap USB Type-C Current" + provides a detailed description of the field. The sink PDO from current source + reflects the current source's(i.e. transmitter of the FRS signal) power + requirement during fr swap. The current sink (i.e. receiver of the FRS signal), + a.k.a new source, should check if it will be able to satisfy the current source's, + new sink's, requirement during frswap before enabling the frs signal reception. + This property refers to maximum current capability that the current sink can + satisfy. During FRS, VBUS voltage is at 5V, as the partners are in implicit + contract, hence, the power level is only a function of the current capability. + "not-supported" implies sink to source fast role swap not supported. + "default" refers to default USB power level as described by + "Table 6-14 Fixed Supply PDO - Sink". + "1.5A" refers to 1.5A@5V. + "3.0A" refers to 3.0A@5V. + + $ref: /schemas/types.yaml#/definitions/string + enum: + - not-supported + - default + - 1.5A + - 3.0A + required: - compatible From patchwork Thu Oct 8 06:15:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268426 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 131C8C433E7 for ; Thu, 8 Oct 2020 06:16:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A1B7120782 for ; Thu, 8 Oct 2020 06:16:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dg13mJqN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728659AbgJHGQe (ORCPT ); Thu, 8 Oct 2020 02:16:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36760 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728582AbgJHGQR (ORCPT ); Thu, 8 Oct 2020 02:16:17 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 64C86C0613D2 for ; Wed, 7 Oct 2020 23:16:15 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id c67so3027535pfb.23 for ; Wed, 07 Oct 2020 23:16:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=x3yLI0m+s5YafT4Db65uDDjStzzP9Zdop2FaW1CqmTw=; b=dg13mJqNzwfL9hV+G8LgxGinlJFNuS4NZXprH2ZF7pP09+znyWhLqfR8+LrQ1dQMgs dUTrMXqbbatAjksSDvDG3z94aSabqAXFMfoQ0ydPlxl2Eq60YwKBklAvbd7iYghYX3as 4VvJYLMCReapfEqJzATfhQM8AD0Q9T8vxqVQ6k10aTE8Mr6zNylmIZaFPDCd2cVG1IgO ya5Vr66jDtsw/1unUlWwuFxX1V2RUMSg+xXIbAXJHNZQqPbiB/Us9ezJx8u7Bt5iUUYg wINxquUPCuP3pqA71NAyHbLpPuuBhfXEhmImHHhKN6qbyDGBcvQLG2og7nGgOfGoQGkR +pog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=x3yLI0m+s5YafT4Db65uDDjStzzP9Zdop2FaW1CqmTw=; b=TYBDpQpoKWGAM0TBi2vhaN1+5x6BlGCSGoyJDQ9jtQPwc13d8KgO6W2GWAb7NTM+QP ndp6vZcRNWh7ctjLDLmydDEl0YP1lXFbPiQ8yz/WhEl1TDyDE2Y27SSnnTahuH0cikVM HjkojPuzq0Uy73+1hm62vDy5MvdXd0q1PWwNCv06KWpYBBwYJZEwQJW/qnnm6kflc6jS jXRJxv0v5GsCqEY7yB+hX2Imb4DdYLpk/RuG8s26p9ROyjP0fUtSGy1tlquZMtveg5qt bPRW4/X5JyNCPx4sjXZNFXSNHXskzOkMjp2bKJ03vmoCjLzid2CY3uZtREQ9vfNc3eX8 2DqA== X-Gm-Message-State: AOAM531jYVBSCxyMTyrgpMUXNiuB84AbdcHS2BhfrT0XcJTOXeyrd5eo vCfXfzddZmMODKotYn8bCxyPcGu4+LI= X-Google-Smtp-Source: ABdhPJzEcAg5e9d9/JezPLnR8Ava1zG4z7ceykkG64RSYbnmrfF9Zr1vIh57v2/ZHMKvnD6x7kPYVkaH9X8= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a05:6a00:23cc:b029:142:2501:34e5 with SMTP id g12-20020a056a0023ccb0290142250134e5mr6278487pfc.62.1602137774852; Wed, 07 Oct 2020 23:16:14 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:47 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-7-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 06/15] usb: typec: tcpm: Add support for Sink Fast Role SWAP(FRS) From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org PD 3.0 spec defines a new mechanism for power role swap called Fast role swap. This change enables TCPM to support FRS when acting as sink. Once the explicit contract is negotiated, sink port is expected to query the source port for sink caps to determine whether the source is FRS capable. Bits 23 & 24 of fixed pdo of the sink caps from the source, when set, indicates the current needed by the source when fast role swap is in progress(Implicit contract phasae). 0 indicates that the source does not support Fast Role Swap. Upon receiving the FRS signal from the source, TCPC(TCPM_FRS_EVENT) informs TCPM to start the Fast role swap sequence. 1. TCPM sends FRS PD message: FR_SWAP_SEND 2. If response is not received within the expiry of SenderResponseTimer, Error recovery is triggered.: FR_SWAP_SEND_TIMEOUT 3. Upon receipt of the accept message, TCPM waits for PSSourceOffTimer for PS_READY message from the partner: FR_SWAP_SNK_SRC_NEW_SINK_READY. TCPC is expected to autonomously turn on vbus once the FRS signal is received and vbus voltage falls below vsafe5v within tSrcFrSwap. This is different from traditional power role swap where the vbus sourcing is turned on by TCPM. 4. By this time, TCPC most likely would have started to source vbus, TCPM waits for tSrcFrSwap to see if the lower level TCPC driver signals TCPM_SOURCING_VBUS event: FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED. 5. When TCPC signals sourcing vbus, TCPM sends PS_READY msg and changes the CC pin from Rd to Rp. This is the end of fast role swap sequence and TCPM initiates the sequnce to negotiate explicit contract by transitioning into SRC_STARTUP after SwapSrcStart. The code is written based on the sequence described in "Figure 8-107: Dual-role Port in Sink to Source Fast Role Swap State Diagram" of USB Power Delivery Specification Revision 3.0, Version 1.2. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- Changes since v1: - Changing patch version to v6 to fix version number confusion. - Rebased on top of usb-next and resolved conflicts due to the below changes: 3ed8e1c2ac99 usb: typec: tcpm: Migrate workqueue to RT priority for processing events 6bbe2a90a0bb usb: typec: tcpm: During PR_SWAP, source caps should be sent only after tSwapSourceStart - enable_frs sequence is now run as part of the same kthread that runs the state machines. - Fixed the implicit fallthrough warning in the switch case for FR_SWAP_CANCEL case. Changes since v6: - Moved frs_current from caps to tcpm_port as Heikki suggested. Changes since v7: - Added Reviewed-by: Heikki Changes since v8: - No change. Changes since v9: - No change --- drivers/usb/typec/tcpm/tcpm.c | 229 +++++++++++++++++++++++++++++++++- include/linux/usb/pd.h | 19 +-- include/linux/usb/tcpm.h | 8 +- 3 files changed, 244 insertions(+), 12 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 92806547f485..55535c4f66bf 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -106,6 +106,13 @@ S(VCONN_SWAP_TURN_ON_VCONN), \ S(VCONN_SWAP_TURN_OFF_VCONN), \ \ + S(FR_SWAP_SEND), \ + S(FR_SWAP_SEND_TIMEOUT), \ + S(FR_SWAP_SNK_SRC_TRANSITION_TO_OFF), \ + S(FR_SWAP_SNK_SRC_NEW_SINK_READY), \ + S(FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED), \ + S(FR_SWAP_CANCEL), \ + \ S(SNK_TRY), \ S(SNK_TRY_WAIT), \ S(SNK_TRY_WAIT_DEBOUNCE), \ @@ -127,6 +134,9 @@ S(GET_PPS_STATUS_SEND), \ S(GET_PPS_STATUS_SEND_TIMEOUT), \ \ + S(GET_SINK_CAP), \ + S(GET_SINK_CAP_TIMEOUT), \ + \ S(ERROR_RECOVERY), \ S(PORT_RESET), \ S(PORT_RESET_WAIT_OFF) @@ -170,11 +180,25 @@ enum adev_actions { ADEV_ATTENTION, }; +/* + * Initial current capability of the new source when vSafe5V is applied during PD3.0 Fast Role Swap. + * Based on "Table 6-14 Fixed Supply PDO - Sink" of "USB Power Delivery Specification Revision 3.0, + * Version 1.2" + */ +enum frs_typec_current { + FRS_NOT_SUPPORTED, + FRS_DEFAULT_POWER, + FRS_5V_1P5A, + FRS_5V_3A, +}; + /* Events from low level driver */ #define TCPM_CC_EVENT BIT(0) #define TCPM_VBUS_EVENT BIT(1) #define TCPM_RESET_EVENT BIT(2) +#define TCPM_FRS_EVENT BIT(3) +#define TCPM_SOURCING_VBUS BIT(4) #define LOG_BUFFER_ENTRIES 1024 #define LOG_BUFFER_ENTRY_SIZE 128 @@ -184,6 +208,8 @@ enum adev_actions { #define SVID_DISCOVERY_MAX 16 #define ALTMODE_DISCOVERY_MAX (SVID_DISCOVERY_MAX * MODE_DISCOVERY_MAX) +#define GET_SINK_CAP_RETRY_MS 100 + struct pd_mode_data { int svid_index; /* current SVID index */ int nsvids; @@ -261,6 +287,8 @@ struct tcpm_port { struct kthread_work state_machine; struct hrtimer vdm_state_machine_timer; struct kthread_work vdm_state_machine; + struct hrtimer enable_frs_timer; + struct kthread_work enable_frs; bool state_machine_running; struct completion tx_complete; @@ -335,6 +363,12 @@ struct tcpm_port { /* port belongs to a self powered device */ bool self_powered; + /* FRS */ + enum frs_typec_current frs_current; + + /* Sink caps have been queried */ + bool sink_cap_done; + #ifdef CONFIG_DEBUG_FS struct dentry *dentry; struct mutex logbuffer_lock; /* log buffer access lock */ @@ -940,6 +974,16 @@ static void mod_vdm_delayed_work(struct tcpm_port *port, unsigned int delay_ms) } } +static void mod_enable_frs_delayed_work(struct tcpm_port *port, unsigned int delay_ms) +{ + if (delay_ms) { + hrtimer_start(&port->enable_frs_timer, ms_to_ktime(delay_ms), HRTIMER_MODE_REL); + } else { + hrtimer_cancel(&port->enable_frs_timer); + kthread_queue_work(port->wq, &port->enable_frs); + } +} + static void tcpm_set_state(struct tcpm_port *port, enum tcpm_state state, unsigned int delay_ms) { @@ -1669,6 +1713,9 @@ static void tcpm_pd_data_request(struct tcpm_port *port, unsigned int cnt = pd_header_cnt_le(msg->header); unsigned int rev = pd_header_rev_le(msg->header); unsigned int i; + enum frs_typec_current frs_current; + bool frs_enable; + int ret; switch (type) { case PD_DATA_SOURCE_CAP: @@ -1738,7 +1785,21 @@ static void tcpm_pd_data_request(struct tcpm_port *port, /* We don't do anything with this at the moment... */ for (i = 0; i < cnt; i++) port->sink_caps[i] = le32_to_cpu(msg->payload[i]); + + frs_current = (port->sink_caps[0] & PDO_FIXED_FRS_CURR_MASK) >> + PDO_FIXED_FRS_CURR_SHIFT; + frs_enable = frs_current && (frs_current <= port->frs_current); + tcpm_log(port, + "Port partner FRS capable partner_frs_current:%u port_frs_current:%u enable:%c", + frs_current, port->frs_current, frs_enable ? 'y' : 'n'); + if (frs_enable) { + ret = port->tcpc->enable_frs(port->tcpc, true); + tcpm_log(port, "Enable FRS %s, ret:%d\n", ret ? "fail" : "success", ret); + } + port->nr_sink_caps = cnt; + port->sink_cap_done = true; + tcpm_set_state(port, SNK_READY, 0); break; case PD_DATA_VENDOR_DEF: tcpm_handle_vdm_request(port, msg->payload, cnt); @@ -1833,6 +1894,9 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, case VCONN_SWAP_WAIT_FOR_VCONN: tcpm_set_state(port, VCONN_SWAP_TURN_OFF_VCONN, 0); break; + case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF: + tcpm_set_state(port, FR_SWAP_SNK_SRC_NEW_SINK_READY, 0); + break; default: break; } @@ -1872,6 +1936,13 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, -EAGAIN : -EOPNOTSUPP); tcpm_set_state(port, VCONN_SWAP_CANCEL, 0); break; + case FR_SWAP_SEND: + tcpm_set_state(port, FR_SWAP_CANCEL, 0); + break; + case GET_SINK_CAP: + port->sink_cap_done = true; + tcpm_set_state(port, ready_state(port), 0); + break; default: break; } @@ -1906,6 +1977,9 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, case VCONN_SWAP_SEND: tcpm_set_state(port, VCONN_SWAP_START, 0); break; + case FR_SWAP_SEND: + tcpm_set_state(port, FR_SWAP_SNK_SRC_TRANSITION_TO_OFF, 0); + break; default: break; } @@ -2806,6 +2880,10 @@ static void tcpm_reset_port(struct tcpm_port *port) port->try_src_count = 0; port->try_snk_count = 0; port->usb_type = POWER_SUPPLY_USB_TYPE_C; + port->nr_sink_caps = 0; + port->sink_cap_done = false; + if (port->tcpc->enable_frs) + port->tcpc->enable_frs(port->tcpc, false); power_supply_changed(port->psy); } @@ -3356,10 +3434,9 @@ static void run_state_machine(struct tcpm_port *port) tcpm_swap_complete(port, 0); tcpm_typec_connect(port); tcpm_check_send_discover(port); + mod_enable_frs_delayed_work(port, 0); tcpm_pps_complete(port, port->pps_status); - power_supply_changed(port->psy); - break; /* Accessory states */ @@ -3383,9 +3460,13 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, HARD_RESET_START, 0); break; case HARD_RESET_START: + port->sink_cap_done = false; + if (port->tcpc->enable_frs) + port->tcpc->enable_frs(port->tcpc, false); port->hard_reset_count++; port->tcpc->set_pd_rx(port->tcpc, false); tcpm_unregister_altmodes(port); + port->nr_sink_caps = 0; port->send_discover = true; if (port->pwr_role == TYPEC_SOURCE) tcpm_set_state(port, SRC_HARD_RESET_VBUS_OFF, @@ -3517,6 +3598,35 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, ready_state(port), 0); break; + case FR_SWAP_SEND: + if (tcpm_pd_send_control(port, PD_CTRL_FR_SWAP)) { + tcpm_set_state(port, ERROR_RECOVERY, 0); + break; + } + tcpm_set_state_cond(port, FR_SWAP_SEND_TIMEOUT, PD_T_SENDER_RESPONSE); + break; + case FR_SWAP_SEND_TIMEOUT: + tcpm_set_state(port, ERROR_RECOVERY, 0); + break; + case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF: + tcpm_set_state(port, ERROR_RECOVERY, PD_T_PS_SOURCE_OFF); + break; + case FR_SWAP_SNK_SRC_NEW_SINK_READY: + if (port->vbus_source) + tcpm_set_state(port, FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED, 0); + else + tcpm_set_state(port, ERROR_RECOVERY, PD_T_RECEIVER_RESPONSE); + break; + case FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED: + tcpm_set_pwr_role(port, TYPEC_SOURCE); + if (tcpm_pd_send_control(port, PD_CTRL_PS_RDY)) { + tcpm_set_state(port, ERROR_RECOVERY, 0); + break; + } + tcpm_set_cc(port, tcpm_rp_cc(port)); + tcpm_set_state(port, SRC_STARTUP, PD_T_SWAP_SRC_START); + break; + /* PR_Swap states */ case PR_SWAP_ACCEPT: tcpm_pd_send_control(port, PD_CTRL_ACCEPT); @@ -3640,6 +3750,12 @@ static void run_state_machine(struct tcpm_port *port) else tcpm_set_state(port, SNK_READY, 0); break; + case FR_SWAP_CANCEL: + if (port->pwr_role == TYPEC_SOURCE) + tcpm_set_state(port, SRC_READY, 0); + else + tcpm_set_state(port, SNK_READY, 0); + break; case BIST_RX: switch (BDO_MODE_MASK(port->bist_request)) { @@ -3674,6 +3790,14 @@ static void run_state_machine(struct tcpm_port *port) case GET_PPS_STATUS_SEND_TIMEOUT: tcpm_set_state(port, ready_state(port), 0); break; + case GET_SINK_CAP: + tcpm_pd_send_control(port, PD_CTRL_GET_SINK_CAP); + tcpm_set_state(port, GET_SINK_CAP_TIMEOUT, PD_T_SENDER_RESPONSE); + break; + case GET_SINK_CAP_TIMEOUT: + port->sink_cap_done = true; + tcpm_set_state(port, ready_state(port), 0); + break; case ERROR_RECOVERY: tcpm_swap_complete(port, -EPROTO); tcpm_pps_complete(port, -EPROTO); @@ -3889,6 +4013,13 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, * Ignore it. */ break; + case FR_SWAP_SEND: + case FR_SWAP_SEND_TIMEOUT: + case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF: + case FR_SWAP_SNK_SRC_NEW_SINK_READY: + case FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED: + /* Do nothing, CC change expected */ + break; case PORT_RESET: case PORT_RESET_WAIT_OFF: @@ -3959,6 +4090,9 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port) case SRC_TRY_DEBOUNCE: /* Do nothing, waiting for sink detection */ break; + case FR_SWAP_SNK_SRC_NEW_SINK_READY: + tcpm_set_state(port, FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED, 0); + break; case PORT_RESET: case PORT_RESET_WAIT_OFF: @@ -4038,6 +4172,14 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port) */ break; + case FR_SWAP_SEND: + case FR_SWAP_SEND_TIMEOUT: + case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF: + case FR_SWAP_SNK_SRC_NEW_SINK_READY: + case FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED: + /* Do nothing, vbus drop expected */ + break; + default: if (port->pwr_role == TYPEC_SINK && port->attached) @@ -4092,6 +4234,25 @@ static void tcpm_pd_event_handler(struct kthread_work *work) if (port->tcpc->get_cc(port->tcpc, &cc1, &cc2) == 0) _tcpm_cc_change(port, cc1, cc2); } + if (events & TCPM_FRS_EVENT) { + if (port->state == SNK_READY) + tcpm_set_state(port, FR_SWAP_SEND, 0); + else + tcpm_log(port, "Discarding FRS_SIGNAL! Not in sink ready"); + } + if (events & TCPM_SOURCING_VBUS) { + tcpm_log(port, "sourcing vbus"); + /* + * In fast role swap case TCPC autonomously sources vbus. Set vbus_source + * true as TCPM wouldn't have called tcpm_set_vbus. + * + * When vbus is sourced on the command on TCPM i.e. TCPM called + * tcpm_set_vbus to source vbus, vbus_source would already be true. + */ + port->vbus_source = true; + _tcpm_pd_vbus_on(port); + } + spin_lock(&port->pd_event_lock); } spin_unlock(&port->pd_event_lock); @@ -4125,6 +4286,50 @@ void tcpm_pd_hard_reset(struct tcpm_port *port) } EXPORT_SYMBOL_GPL(tcpm_pd_hard_reset); +void tcpm_sink_frs(struct tcpm_port *port) +{ + spin_lock(&port->pd_event_lock); + port->pd_events = TCPM_FRS_EVENT; + spin_unlock(&port->pd_event_lock); + kthread_queue_work(port->wq, &port->event_work); +} +EXPORT_SYMBOL_GPL(tcpm_sink_frs); + +void tcpm_sourcing_vbus(struct tcpm_port *port) +{ + spin_lock(&port->pd_event_lock); + port->pd_events = TCPM_SOURCING_VBUS; + spin_unlock(&port->pd_event_lock); + kthread_queue_work(port->wq, &port->event_work); +} +EXPORT_SYMBOL_GPL(tcpm_sourcing_vbus); + +static void tcpm_enable_frs_work(struct kthread_work *work) +{ + struct tcpm_port *port = container_of(work, struct tcpm_port, enable_frs); + + mutex_lock(&port->lock); + /* Not FRS capable */ + if (!port->connected || port->port_type != TYPEC_PORT_DRP || + port->pwr_opmode != TYPEC_PWR_MODE_PD || + !port->tcpc->enable_frs || + /* Sink caps queried */ + port->sink_cap_done || port->negotiated_rev < PD_REV30) + goto unlock; + + /* Send when the state machine is idle */ + if (port->state != SNK_READY || port->vdm_state != VDM_STATE_DONE || port->send_discover) + goto resched; + + tcpm_set_state(port, GET_SINK_CAP, 0); + port->sink_cap_done = true; + +resched: + mod_enable_frs_delayed_work(port, GET_SINK_CAP_RETRY_MS); +unlock: + mutex_unlock(&port->lock); +} + static int tcpm_dr_set(struct typec_port *p, enum typec_data_role data) { struct tcpm_port *port = typec_get_drvdata(p); @@ -4532,7 +4737,7 @@ static int tcpm_fw_get_caps(struct tcpm_port *port, { const char *cap_str; int ret; - u32 mw; + u32 mw, frs_current; if (!fwnode) return -EINVAL; @@ -4601,6 +4806,13 @@ static int tcpm_fw_get_caps(struct tcpm_port *port, port->self_powered = fwnode_property_read_bool(fwnode, "self-powered"); + /* FRS can only be supported byb DRP ports */ + if (port->port_type == TYPEC_PORT_DRP) { + ret = fwnode_property_read_u32(fwnode, "frs-typec-current", &frs_current); + if (ret >= 0 && frs_current <= FRS_5V_3A) + port->frs_current = frs_current; + } + return 0; } @@ -4845,6 +5057,14 @@ static enum hrtimer_restart vdm_state_machine_timer_handler(struct hrtimer *time return HRTIMER_NORESTART; } +static enum hrtimer_restart enable_frs_timer_handler(struct hrtimer *timer) +{ + struct tcpm_port *port = container_of(timer, struct tcpm_port, enable_frs_timer); + + kthread_queue_work(port->wq, &port->enable_frs); + return HRTIMER_NORESTART; +} + struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) { struct tcpm_port *port; @@ -4874,10 +5094,13 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) kthread_init_work(&port->state_machine, tcpm_state_machine_work); kthread_init_work(&port->vdm_state_machine, vdm_state_machine_work); kthread_init_work(&port->event_work, tcpm_pd_event_handler); + kthread_init_work(&port->enable_frs, tcpm_enable_frs_work); hrtimer_init(&port->state_machine_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); port->state_machine_timer.function = state_machine_timer_handler; hrtimer_init(&port->vdm_state_machine_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); port->vdm_state_machine_timer.function = vdm_state_machine_timer_handler; + hrtimer_init(&port->enable_frs_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + port->enable_frs_timer.function = enable_frs_timer_handler; spin_lock_init(&port->pd_event_lock); diff --git a/include/linux/usb/pd.h b/include/linux/usb/pd.h index f842e4589bd2..3a805e2ecbc9 100644 --- a/include/linux/usb/pd.h +++ b/include/linux/usb/pd.h @@ -219,14 +219,16 @@ enum pd_pdo_type { #define PDO_CURR_MASK 0x3ff #define PDO_PWR_MASK 0x3ff -#define PDO_FIXED_DUAL_ROLE BIT(29) /* Power role swap supported */ -#define PDO_FIXED_SUSPEND BIT(28) /* USB Suspend supported (Source) */ -#define PDO_FIXED_HIGHER_CAP BIT(28) /* Requires more than vSafe5V (Sink) */ -#define PDO_FIXED_EXTPOWER BIT(27) /* Externally powered */ -#define PDO_FIXED_USB_COMM BIT(26) /* USB communications capable */ -#define PDO_FIXED_DATA_SWAP BIT(25) /* Data role swap supported */ -#define PDO_FIXED_VOLT_SHIFT 10 /* 50mV units */ -#define PDO_FIXED_CURR_SHIFT 0 /* 10mA units */ +#define PDO_FIXED_DUAL_ROLE BIT(29) /* Power role swap supported */ +#define PDO_FIXED_SUSPEND BIT(28) /* USB Suspend supported (Source) */ +#define PDO_FIXED_HIGHER_CAP BIT(28) /* Requires more than vSafe5V (Sink) */ +#define PDO_FIXED_EXTPOWER BIT(27) /* Externally powered */ +#define PDO_FIXED_USB_COMM BIT(26) /* USB communications capable */ +#define PDO_FIXED_DATA_SWAP BIT(25) /* Data role swap supported */ +#define PDO_FIXED_FRS_CURR_MASK (BIT(24) | BIT(23)) /* FR_Swap Current (Sink) */ +#define PDO_FIXED_FRS_CURR_SHIFT 23 +#define PDO_FIXED_VOLT_SHIFT 10 /* 50mV units */ +#define PDO_FIXED_CURR_SHIFT 0 /* 10mA units */ #define PDO_FIXED_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_FIXED_VOLT_SHIFT) #define PDO_FIXED_CURR(ma) ((((ma) / 10) & PDO_CURR_MASK) << PDO_FIXED_CURR_SHIFT) @@ -454,6 +456,7 @@ static inline unsigned int rdo_max_power(u32 rdo) #define PD_T_DB_DETECT 10000 /* 10 - 15 seconds */ #define PD_T_SEND_SOURCE_CAP 150 /* 100 - 200 ms */ #define PD_T_SENDER_RESPONSE 60 /* 24 - 30 ms, relaxed */ +#define PD_T_RECEIVER_RESPONSE 15 /* 15ms max */ #define PD_T_SOURCE_ACTIVITY 45 #define PD_T_SINK_ACTIVITY 135 #define PD_T_SINK_WAIT_CAP 240 diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h index 89f58760cf48..09762d26fa0c 100644 --- a/include/linux/usb/tcpm.h +++ b/include/linux/usb/tcpm.h @@ -78,8 +78,11 @@ enum tcpm_transmit_type { * automatically if a connection is established. * @try_role: Optional; called to set a preferred role * @pd_transmit:Called to transmit PD message - * @mux: Pointer to multiplexer data * @set_bist_data: Turn on/off bist data mode for compliance testing + * @enable_frs: + * Optional; Called to enable/disable PD 3.0 fast role swap. + * Enabling frs is accessory dependent as not all PD3.0 + * accessories support fast role swap. */ struct tcpc_dev { struct fwnode_handle *fwnode; @@ -105,6 +108,7 @@ struct tcpc_dev { int (*pd_transmit)(struct tcpc_dev *dev, enum tcpm_transmit_type type, const struct pd_message *msg); int (*set_bist_data)(struct tcpc_dev *dev, bool on); + int (*enable_frs)(struct tcpc_dev *dev, bool enable); }; struct tcpm_port; @@ -114,6 +118,8 @@ void tcpm_unregister_port(struct tcpm_port *port); void tcpm_vbus_change(struct tcpm_port *port); void tcpm_cc_change(struct tcpm_port *port); +void tcpm_sink_frs(struct tcpm_port *port); +void tcpm_sourcing_vbus(struct tcpm_port *port); void tcpm_pd_receive(struct tcpm_port *port, const struct pd_message *msg); void tcpm_pd_transmit_complete(struct tcpm_port *port, From patchwork Thu Oct 8 06:15:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268752 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 12881C47095 for ; Thu, 8 Oct 2020 06:16:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B78B020760 for ; Thu, 8 Oct 2020 06:16:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="I9eyIs2k" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728800AbgJHGQd (ORCPT ); Thu, 8 Oct 2020 02:16:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36772 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728671AbgJHGQT (ORCPT ); Thu, 8 Oct 2020 02:16:19 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A7796C0613D5 for ; Wed, 7 Oct 2020 23:16:17 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id j10so4320146ybl.19 for ; Wed, 07 Oct 2020 23:16:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=ZWt32l+TYej4QZMKFfY95w9ZTUY2cd5q7xBhuPrv2GI=; b=I9eyIs2kIUFWoxtwQtA7ec3LUj1pH6B3md1TP5nBXfiuDTTwqxwtp5BpDCZwAeUuKM ALSFc0BOgnx0PUmeY6J60CQkizYl5pU46uhReVmaOQotWGBFMP0pgNZPT5dreSqWNtJb eXBQc6G42RhUK8sg5xDy0vDtgpbapsHJFib6sgtreDNLmX35N5cH3T2Ho14y59DNEMRF /iI8Q5o7lqyYKb4wUtS2/BTzCshy5371BoY0hZDNCIkCUVu7ZCeV2v/ztS7lgEU6vfUa uSNUlO+j5gKmbbHsq1anBle32oTrKdii0bH+4JFU1szlSifnp1pf8XSOlwKCujzX5ebC IwBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ZWt32l+TYej4QZMKFfY95w9ZTUY2cd5q7xBhuPrv2GI=; b=UHafnLtUDYpHjYkEoaf+jrQnUOLt4ByDW0ZE6/e5KuClbchx2NfFeo3p5wX9x8b+a9 o/nlICeMu51+f+9b9TCdQ5R1Ba4f/boM2AXB9uGRS/WnuDM8jM6KryrDoYCn8jtTU8J2 2sfAyvB1hox3fy9T+di0MFEFAKDveU2hgrTL4qZ2/1mAQPhTqnRJ8DwW9j9lJpe4geeF d1cX7qcUadO7jKar2mqd2mIqeM2fJ2oMvE3cq4eu3T7evcw4FqKe5uMiv9TQnZ+bD4X9 eQ/0hd0HTh/cObgI9gr+EQnBRe9DQsAJlt0OnrKN3tEYzqXSk2H2oeqf2jvHHQ1xMdb2 8aXw== X-Gm-Message-State: AOAM530cYnODyB5im8dg+DTWzZVmHIxfFyfHw6Jpg2/jOx/qUdfvjl2n qcd8NBUVYsd7QQmg33yOS3+JA4Cwvgg= X-Google-Smtp-Source: ABdhPJzvCTboVjYa8W43Yu74CZ2RF96C33+yc2tzLEfZLYnZ07jzVNxeX2pZ6Z7OvM63kEbjFM7qJDpWMEg= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a25:bd0c:: with SMTP id f12mr843402ybk.392.1602137776918; Wed, 07 Oct 2020 23:16:16 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:48 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-8-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 07/15] usb: typec: tcpci: Implement callbacks for FRS From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Implement tcpc.enable_frs to enable TCPC to receive Fast role swap signal. Additionally set the sink disconnect threshold to 4v to prevent disconnect during Fast Role swap. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- Changes since v1: - Changing patch version to v6 to fix version number confusion. Changes since v6: - Rebase on usb-next. - Fixed formatting error. - Added Reviewed-by: Heikki. Changes since v7: - Rebase on usb-next. Changes since v8: - None. Changes since v9: - None. --- drivers/usb/typec/tcpm/tcpci.c | 17 +++++++++++++++++ drivers/usb/typec/tcpm/tcpci.h | 8 ++++++++ 2 files changed, 25 insertions(+) diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index d6a6fac82d48..f9f0af64da5f 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -268,6 +268,22 @@ static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable) enable ? TCPC_POWER_CTRL_VCONN_ENABLE : 0); } +static int tcpci_enable_frs(struct tcpc_dev *dev, bool enable) +{ + struct tcpci *tcpci = tcpc_to_tcpci(dev); + int ret; + + /* To prevent disconnect during FRS, set disconnect threshold to 3.5V */ + ret = tcpci_write16(tcpci, TCPC_VBUS_SINK_DISCONNECT_THRESH, enable ? 0 : 0x8c); + if (ret < 0) + return ret; + + ret = regmap_update_bits(tcpci->regmap, TCPC_POWER_CTRL, TCPC_FAST_ROLE_SWAP_EN, enable ? + TCPC_FAST_ROLE_SWAP_EN : 0); + + return ret; +} + static int tcpci_set_bist_data(struct tcpc_dev *tcpc, bool enable) { struct tcpci *tcpci = tcpc_to_tcpci(tcpc); @@ -611,6 +627,7 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data) tcpci->tcpc.set_roles = tcpci_set_roles; tcpci->tcpc.pd_transmit = tcpci_pd_transmit; tcpci->tcpc.set_bist_data = tcpci_set_bist_data; + tcpci->tcpc.enable_frs = tcpci_enable_frs; err = tcpci_parse_config(tcpci); if (err < 0) diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h index 82f021a82456..5ef07a56d67a 100644 --- a/drivers/usb/typec/tcpm/tcpci.h +++ b/drivers/usb/typec/tcpm/tcpci.h @@ -16,6 +16,7 @@ #define TCPC_PD_INT_REV 0xa #define TCPC_ALERT 0x10 +#define TCPC_ALERT_EXTND BIT(14) #define TCPC_ALERT_EXTENDED_STATUS BIT(13) #define TCPC_ALERT_VBUS_DISCNCT BIT(11) #define TCPC_ALERT_RX_BUF_OVF BIT(10) @@ -37,6 +38,9 @@ #define TCPC_EXTENDED_STATUS_MASK 0x16 #define TCPC_EXTENDED_STATUS_MASK_VSAFE0V BIT(0) +#define TCPC_ALERT_EXTENDED_MASK 0x17 +#define TCPC_SINK_FAST_ROLE_SWAP BIT(0) + #define TCPC_CONFIG_STD_OUTPUT 0x18 #define TCPC_TCPC_CTRL 0x19 @@ -63,6 +67,7 @@ #define TCPC_POWER_CTRL 0x1c #define TCPC_POWER_CTRL_VCONN_ENABLE BIT(0) +#define TCPC_FAST_ROLE_SWAP_EN BIT(7) #define TCPC_CC_STATUS 0x1d #define TCPC_CC_STATUS_TOGGLING BIT(5) @@ -74,11 +79,14 @@ #define TCPC_POWER_STATUS 0x1e #define TCPC_POWER_STATUS_UNINIT BIT(6) +#define TCPC_POWER_STATUS_SOURCING_VBUS BIT(4) #define TCPC_POWER_STATUS_VBUS_DET BIT(3) #define TCPC_POWER_STATUS_VBUS_PRES BIT(2) #define TCPC_FAULT_STATUS 0x1f +#define TCPC_ALERT_EXTENDED 0x21 + #define TCPC_COMMAND 0x23 #define TCPC_CMD_WAKE_I2C 0x11 #define TCPC_CMD_DISABLE_VBUS_DETECT 0x22 From patchwork Thu Oct 8 06:15:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268424 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8C3EC47420 for ; Thu, 8 Oct 2020 06:16:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8A98020760 for ; Thu, 8 Oct 2020 06:16:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="nAVkaEcn" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728713AbgJHGQm (ORCPT ); Thu, 8 Oct 2020 02:16:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36796 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728722AbgJHGQZ (ORCPT ); Thu, 8 Oct 2020 02:16:25 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B85E2C0613D9 for ; Wed, 7 Oct 2020 23:16:19 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id v7so2821491plp.23 for ; Wed, 07 Oct 2020 23:16:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=JGnbDdcxJxj3se75rgmrjhN39DHldDWoTPiiMZNtj7E=; b=nAVkaEcnDmhVbSpWNYTTx5pXdK06HUScBVwcpxTI232E63s1kszyjkbCWJLMlXqJe3 0vPZZdSd4tde7l696itSjzsbv2L2VXb3yT5MYjlGAq3rGWBJn/G0EPEeb0NCnDU7XX+N QjygauJUQFTf69p5AbYmSjtXBI47Pl1nSNPEGwTsnnl4XDznAG/z7b4fg1NL19IPUzjw u5NSLAkKpgF0KwjNPLhUlfxYPZT8vDOMRSGGIiKbLeCgBmApuUuYH8mdFdcHArBrtGRR a3dguMsZWwbthsBDveFuafcOxnEPbjmc43vFKrqP1JzcNEKIL1TbM+5LSwigAZjglsSu KkcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=JGnbDdcxJxj3se75rgmrjhN39DHldDWoTPiiMZNtj7E=; b=ubDbhWmgyXv2wflflk2bxZMuuTSi4nKWG6Na/YSvQbVUFOnRrrKSEBG/SxeNeKR9KB IKz21mavcKpyoL4CxSzabMCMBXbP1PtFJeK8tLqf16l/83tprRaoIetmtF69WnW9cNhS aiWjCHB0+kdK3RPCTKXu/K50m5ac7vOLhIj6bDLhuFKo8CD4dHWXN7Wbqdx+pgjGz0eD 4CAjQyy6jVpCGsCgxaUnpAoCIQp0O7x5wAn6ypumj7FCzVOjgPffVw/amy/SiyEyzxcU ihVQCIvELViTR7Km7NEPM6gcllaxR/lM6r68AoyIdsPVYM69iA392aRIN8LMTfo8xd5m Ye7Q== X-Gm-Message-State: AOAM530wXUIRKRd/4IKejWSK9CLJ22G9+CMo+CBnuzLK74m5Jtfe++yk prhBBuCjTMEw5QvZ83KBHpPn56iOERA= X-Google-Smtp-Source: ABdhPJwwOAXPiSstHERTXmDe5W6qA8MIBrre2VpOrw4LQzT/B2TmkkuLJltxEt45kH3aGKmVuzaOyDLKN7Q= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a63:f04c:: with SMTP id s12mr6027108pgj.425.1602137779013; Wed, 07 Oct 2020 23:16:19 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:49 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-9-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 08/15] usb: typec: tcpci_maxim: Add support for Sink FRS From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Upon receiving ALERT_EXTENDED.TCPC_SINK_FAST_ROLE_SWAP signal tcpm to start Sink fast role swap signal. Inform when TCPM is sourcing vbus. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- Changes since v1: - Changing patch version to v6 to fix version number confusion. Changes since v6: - rebase on usb-next - Added Reviewed-by: Heikki Changes since v7: - Rebase on usb-next Changes since v8: - None. Changes since v9: - None. --- drivers/usb/typec/tcpm/tcpci_maxim.c | 50 +++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c index 91337ddb4962..723d7dd38f75 100644 --- a/drivers/usb/typec/tcpm/tcpci_maxim.c +++ b/drivers/usb/typec/tcpm/tcpci_maxim.c @@ -106,13 +106,22 @@ static void max_tcpci_init_regs(struct max_tcpci_chip *chip) return; } + ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED, 0xff); + if (ret < 0) { + dev_err(chip->dev, "Unable to clear TCPC_ALERT_EXTENDED ret:%d\n", ret); + return; + } + alert_mask = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_TX_FAILED | TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_RX_STATUS | TCPC_ALERT_CC_STATUS | - TCPC_ALERT_VBUS_DISCNCT | TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_POWER_STATUS; + TCPC_ALERT_VBUS_DISCNCT | TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_POWER_STATUS | + /* Enable Extended alert for detecting Fast Role Swap Signal */ + TCPC_ALERT_EXTND; ret = max_tcpci_write16(chip, TCPC_ALERT_MASK, alert_mask); if (ret < 0) { - dev_err(chip->dev, "Error writing to TCPC_ALERT_MASK ret:%d\n", ret); + dev_err(chip->dev, + "Error enabling TCPC_ALERT: TCPC_ALERT_MASK write failed ret:%d\n", ret); return; } @@ -122,6 +131,10 @@ static void max_tcpci_init_regs(struct max_tcpci_chip *chip) dev_err(chip->dev, "Error writing to TCPC_POWER_CTRL ret:%d\n", ret); return; } + + ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED_MASK, TCPC_SINK_FAST_ROLE_SWAP); + if (ret < 0) + return; } static void process_rx(struct max_tcpci_chip *chip, u16 status) @@ -225,10 +238,23 @@ static void process_power_status(struct max_tcpci_chip *chip) if (ret < 0) return; - if (pwr_status == 0xff) + if (pwr_status == 0xff) { max_tcpci_init_regs(chip); - else + } else if (pwr_status & TCPC_POWER_STATUS_SOURCING_VBUS) { + tcpm_sourcing_vbus(chip->port); + /* + * Alawys re-enable boost here. + * In normal case, when say an headset is attached, TCPM would + * have instructed to TCPC to enable boost, so the call is a + * no-op. + * But for Fast Role Swap case, Boost turns on autonomously without + * AP intervention, but, needs AP to enable source mode explicitly + * for AP to regain control. + */ + max_tcpci_set_vbus(chip->tcpci, &chip->data, true, false); + } else { tcpm_vbus_change(chip->port); + } } static void process_tx(struct max_tcpci_chip *chip, u16 status) @@ -249,6 +275,7 @@ static irqreturn_t _max_tcpci_irq(struct max_tcpci_chip *chip, u16 status) { u16 mask; int ret; + u8 reg_status; /* * Clear alert status for everything except RX_STATUS, which shouldn't @@ -274,6 +301,21 @@ static irqreturn_t _max_tcpci_irq(struct max_tcpci_chip *chip, u16 status) } } + if (status & TCPC_ALERT_EXTND) { + ret = max_tcpci_read8(chip, TCPC_ALERT_EXTENDED, ®_status); + if (ret < 0) + return ret; + + ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED, reg_status); + if (ret < 0) + return ret; + + if (reg_status & TCPC_SINK_FAST_ROLE_SWAP) { + dev_info(chip->dev, "FRS Signal"); + tcpm_sink_frs(chip->port); + } + } + if (status & TCPC_ALERT_RX_STATUS) process_rx(chip, status); From patchwork Thu Oct 8 06:15:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268750 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28A2FC04EBE for ; Thu, 8 Oct 2020 06:16:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D770C20760 for ; Thu, 8 Oct 2020 06:16:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="A7j9tS/X" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728890AbgJHGQs (ORCPT ); Thu, 8 Oct 2020 02:16:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36798 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728731AbgJHGQZ (ORCPT ); Thu, 8 Oct 2020 02:16:25 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 19F21C0613DA for ; Wed, 7 Oct 2020 23:16:22 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id s128so4354545ybc.21 for ; Wed, 07 Oct 2020 23:16:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=6JgTqSJgT9+U2Syccyfmiliq6LISdJLZP+XxLV6n+5o=; b=A7j9tS/Xb9DrkemXROGwYAZIAH+oeggvQAtQS8NT4NivaYZZ6Gmv4It4sMocaubIfD Jx9rzrubwyZJMbRss6U4D6JGmRjl361sqzabsDSWWzX3FsZMLxNJolMPCucrwNXWeQpQ YBA689pJCngPpawU+lcAdLlxebL7Bi7xngIgjPf49duV4NrNVTwmyFmqpD0vCVbtsEFZ v+iVPcpYicJLsD1e8iIRLMv+GfHALCKatJVOf7uPNAyv6KunbwBreFNPT8PaDtoRfTTF yrv0rgVqQwvn0a2c77Vz2vO+hJDaI4p6gXRsu9HDLNPaEH8gTl4MILgk1yuVW/GWGq31 Ftmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=6JgTqSJgT9+U2Syccyfmiliq6LISdJLZP+XxLV6n+5o=; b=bKQEupp9eUb8IdkUbPl/xiTeLLLNbweyUKBR4sG1WSQAEliaAebgsRgCWHjG+WujUG T9DmGaDxTo3TDlccayhv0VIjvvI2NiGpgCDaXAx7CxF2GQDwsCaOdJrKtRA0yhZXa8cB hfo1PiT2r96WB8Wzc3MX0CANmTD1YtyzUIs/Et6C5q3RLsjMAHSupjJ7inr6fQyVSn4G xiGoSO1B4jRd5NlHTCM5agM3NFTkQUKFAig6nI4P/enkOcg2nJ2JBHGBjiOoDXXj9kHr N5W/PuXuTxrVsgtnqq4iMmpdzym7OY7hLEATOJuJOGAEOJrbpjyCTn6/wEdmwfF76oXA lmCw== X-Gm-Message-State: AOAM532uyl3Zmvzpb64r2V2N61d2uONSp+3yEFdqg5iH8FfDsE2sNU3J gWNhS8rBaOBWzHW/CiRSFr0nDZ0X/68= X-Google-Smtp-Source: ABdhPJzszkClNH2usU/jYbzUnTVxrHehknearvSOg97dOsiJLg5nDDh+HSoFqt1uJKk3pOloWFkeGejaaqk= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a25:2393:: with SMTP id j141mr9028667ybj.462.1602137781268; Wed, 07 Oct 2020 23:16:21 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:50 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-10-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 09/15] usb: typec: tcpm: frs sourcing vbus callback From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org During FRS hardware autonomously starts to source vbus. Provide callback to perform chip specific operations. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- Introduced in v9. No chages since then. --- drivers/usb/typec/tcpm/tcpm.c | 9 +++++++++ include/linux/usb/tcpm.h | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 55535c4f66bf..02b7f623f584 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -4090,7 +4090,16 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port) case SRC_TRY_DEBOUNCE: /* Do nothing, waiting for sink detection */ break; + case FR_SWAP_SEND: + case FR_SWAP_SEND_TIMEOUT: + case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF: + case FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED: + if (port->tcpc->frs_sourcing_vbus) + port->tcpc->frs_sourcing_vbus(port->tcpc); + break; case FR_SWAP_SNK_SRC_NEW_SINK_READY: + if (port->tcpc->frs_sourcing_vbus) + port->tcpc->frs_sourcing_vbus(port->tcpc); tcpm_set_state(port, FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED, 0); break; diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h index 09762d26fa0c..7303f518ba49 100644 --- a/include/linux/usb/tcpm.h +++ b/include/linux/usb/tcpm.h @@ -83,6 +83,9 @@ enum tcpm_transmit_type { * Optional; Called to enable/disable PD 3.0 fast role swap. * Enabling frs is accessory dependent as not all PD3.0 * accessories support fast role swap. + * @frs_sourcing_vbus: + * Optional; Called to notify that vbus is now being sourced. + * Low level drivers can perform chip specific operations, if any. */ struct tcpc_dev { struct fwnode_handle *fwnode; @@ -109,6 +112,7 @@ struct tcpc_dev { const struct pd_message *msg); int (*set_bist_data)(struct tcpc_dev *dev, bool on); int (*enable_frs)(struct tcpc_dev *dev, bool enable); + void (*frs_sourcing_vbus)(struct tcpc_dev *dev); }; struct tcpm_port; From patchwork Thu Oct 8 06:15:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268423 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A7B9AC47095 for ; Thu, 8 Oct 2020 06:16:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5F49020760 for ; Thu, 8 Oct 2020 06:16:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ECVBCFHo" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728883AbgJHGQs (ORCPT ); Thu, 8 Oct 2020 02:16:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728600AbgJHGQZ (ORCPT ); Thu, 8 Oct 2020 02:16:25 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B98EAC0613DF for ; Wed, 7 Oct 2020 23:16:23 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id a16so3063098pfk.2 for ; Wed, 07 Oct 2020 23:16:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=IvjkXzvW+6lNlW1+WxkRnhzLSIktZGiqYABylT0P1Jw=; b=ECVBCFHoGJFmlpmlKxY54GiGeVoQi6NcJEP/nSDJkt2B6grDRwwJGVDCa0/LgBWVIN zn3PmJb0jK4lLns5VDA6CDyZZiIy76K5gxtplBJjT+t0x20Vzl2/OuMwwPuMlrJfHzC3 na1Ihx/iD9EBZF54ppUOafLfUg1+coxmJrS5sdHLZ4VlErLuxMfw8ZpUHC78jfcT9bYu UlwUJnUoltWqbrZorRJLBggOsSnavm13Yi1tSLHhxI5qRV37U7JtrNdbCouaEBuAeucq 3RcR2MJ0QMToN5dgsg1RHrTMd8y2MWrcund/qlE4TFVRfKsFAdaXkF6ClR+Hygfylov+ xfgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=IvjkXzvW+6lNlW1+WxkRnhzLSIktZGiqYABylT0P1Jw=; b=mjS4yWNth2mTkEhXPQVq0vbdHeBZLXvRmBB9bogg3Z5UerpF9M1vujbcUHnVlyQK6R o+4QzEUvzOql9jFCIEcspjSIurgxXqgBSC+jKw7d2Ea1KFZgmyWycZcw3x02Myi6YvWG LD6EsnpNJ9uifNLEbS3iuKngDt6g3AKp3+gpR0hHI6Opl4hzaKyrsOe5/UciZAP6LMuZ Qy3gF+a2sMLyLCEB2/nRv/ZzlSafWvYsDlCP0ZpkLzgtS8LjRdruRwICAJlD9OXI/q/z 9jWkdE4ccABaFtu2k7qlhFs9RPeDIV7GxaN7QDMB2MzhPPkcqBg/VNOlS/asRhlH5HUk jNbg== X-Gm-Message-State: AOAM532JeQ10KtYj3bccYvHKF0ODFZbhUGBgNPUIeCqPes2/9PWvWIE0 eJCl2NVBA4QCUTbuyGM/FfN2C/09wrU= X-Google-Smtp-Source: ABdhPJy9elM1FPyXKazUGzgY9O12LDmXbvBYh2mrZEhM4EuaT853sVF3jhlNBHpNw/AT77Zg5Yvy7W4Gzyg= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a62:1414:0:b029:152:44af:42e with SMTP id 20-20020a6214140000b029015244af042emr6108924pfu.66.1602137783217; Wed, 07 Oct 2020 23:16:23 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:51 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-11-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 10/15] usb: typec: tcpci: frs sourcing vbus callback From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org During FRS hardware autonomously starts to source vbus. Provide callback to perform chip specific operations. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- v9 is the first version of this patch in the series. Added to fix occasional bug of vbus turning back on when disconnecting the FRS accessory after disconnect. No changes since v9. --- drivers/usb/typec/tcpm/tcpci.c | 9 +++++++++ drivers/usb/typec/tcpm/tcpci.h | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index f9f0af64da5f..f91688e43991 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -284,6 +284,14 @@ static int tcpci_enable_frs(struct tcpc_dev *dev, bool enable) return ret; } +static void tcpci_frs_sourcing_vbus(struct tcpc_dev *dev) +{ + struct tcpci *tcpci = tcpc_to_tcpci(dev); + + if (tcpci->data->frs_sourcing_vbus) + tcpci->data->frs_sourcing_vbus(tcpci, tcpci->data); +} + static int tcpci_set_bist_data(struct tcpc_dev *tcpc, bool enable) { struct tcpci *tcpci = tcpc_to_tcpci(tcpc); @@ -628,6 +636,7 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data) tcpci->tcpc.pd_transmit = tcpci_pd_transmit; tcpci->tcpc.set_bist_data = tcpci_set_bist_data; tcpci->tcpc.enable_frs = tcpci_enable_frs; + tcpci->tcpc.frs_sourcing_vbus = tcpci_frs_sourcing_vbus; err = tcpci_parse_config(tcpci); if (err < 0) diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h index 5ef07a56d67a..b418fe11b527 100644 --- a/drivers/usb/typec/tcpm/tcpci.h +++ b/drivers/usb/typec/tcpm/tcpci.h @@ -143,6 +143,9 @@ /* * @TX_BUF_BYTE_x_hidden * optional; Set when TX_BUF_BYTE_x can only be accessed through I2C_WRITE_BYTE_COUNT. + * @frs_sourcing_vbus: + * Optional; Callback to perform chip specific operations when FRS + * is sourcing vbus. */ struct tcpci; struct tcpci_data { @@ -154,6 +157,7 @@ struct tcpci_data { int (*start_drp_toggling)(struct tcpci *tcpci, struct tcpci_data *data, enum typec_cc_status cc); int (*set_vbus)(struct tcpci *tcpci, struct tcpci_data *data, bool source, bool sink); + void (*frs_sourcing_vbus)(struct tcpci *tcpci, struct tcpci_data *data); }; struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data); From patchwork Thu Oct 8 06:15:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268751 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8ED75C47423 for ; Thu, 8 Oct 2020 06:16:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3D7BC20782 for ; Thu, 8 Oct 2020 06:16:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dQCwYaSw" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728579AbgJHGQl (ORCPT ); Thu, 8 Oct 2020 02:16:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36812 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728761AbgJHGQ0 (ORCPT ); Thu, 8 Oct 2020 02:16:26 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E7263C061755 for ; Wed, 7 Oct 2020 23:16:25 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id bb2so2836344plb.8 for ; Wed, 07 Oct 2020 23:16:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=U+7VAuX+6NzBlNSRK3/qbo0mKYXrvm3847FJpD+uNy8=; b=dQCwYaSwe7s2rwAuCm8wl5BjFAMR41J9778DmKbkwQ2duUvQ+nZFy7s7uVfmewQT7c M3ypo/V4MyLSbrbsN3rgnwDY91G4T/gnVf7uG5kJ1y2uGl1NP+1Dm599LSGXA+EDDYfA 76n6csYDJGD6zAhuURrvnitoOtwAGJ1Lw43ahlxi7e/Nm5mtXaMT5Iv+aiomhltQIoaV PUJ/EaFdy5N6wrXqKPdcd2YrKTCEQRswzPNZDHvFm400bvJU2sARuf3bS4IJncsSYuh3 xaGdmpy1a6TerpnrAwGuwP2+0e642AKdZCcLn9ptxR6nenakUhlatfWMuvJ8UB8gwbP8 oFNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=U+7VAuX+6NzBlNSRK3/qbo0mKYXrvm3847FJpD+uNy8=; b=tOV0X57QyNaQylHzZpVZchFq14ig+GDnsI2fDBujODYgMsPplCUYrEwSHc58Q6gQYN dJZqLfHx5CG+7aG1hk869mnJ0G4pkwZLHqrR9gBBzKNMwxxISTZ5bbhFIYu09tjlektL 5vqPjJeSzCwzSfYhHie6PMM2xi/moSlrUuELp3X0OYIgBAP3M6RWmHcdTJ4rq9wvIBA2 +3bmffiSaz2NOLCfSyJ2q4Hji6Uidvv62IBf1Xp2Wl5jfpmGiEL7jRRUxKqeKBagBm+o KiHDF9QUT0dtA6AfyDmYyqB6vFd9icIXkGEk2R6QL7NyN5E8SMd1CtvP/GMqzzlL6Zl6 PrnA== X-Gm-Message-State: AOAM530e+z7NoG3jV2MUT0wUGPhurNkhwJm825qMr3eLYwW6fV4itVPo 2qoXBYm10b3go+AAvq+c3ABP+bQWnhM= X-Google-Smtp-Source: ABdhPJzb15aIk6jg4abLXX9Q3hsayACHVYwt5r9kKE5YZXk9QEOn+tEMf6kmkIUcGC4HEvb88zNom85vr+g= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:aa7:9592:0:b029:13e:d13d:a054 with SMTP id z18-20020aa795920000b029013ed13da054mr6175887pfj.26.1602137785394; Wed, 07 Oct 2020 23:16:25 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:52 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-12-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 11/15] usb: typec: tcpci_max77759: Fix vbus stuck on upon diconnecting sink From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Occasionally, POWER_STATUS.sourcing_vbus takes a while to clear after writing to MAX_BUCK_BOOST_OP register. This causes vbus to turn back on while disconnecting the sink. Overcome this issue by writing into MAX_BUCK_BOOST_OP during frs while sourcing vbu, instead of always into the register whenever POWER_STATUS.sourcing_vbus is set. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- v9 is the first version of this patch. Added to fix occasional bug of vbus turning back on when disconnecting the FRS accessory after disconnect. No changes since v9. --- drivers/usb/typec/tcpm/tcpci_maxim.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c index 723d7dd38f75..43dcad95e897 100644 --- a/drivers/usb/typec/tcpm/tcpci_maxim.c +++ b/drivers/usb/typec/tcpm/tcpci_maxim.c @@ -238,23 +238,22 @@ static void process_power_status(struct max_tcpci_chip *chip) if (ret < 0) return; - if (pwr_status == 0xff) { + if (pwr_status == 0xff) max_tcpci_init_regs(chip); - } else if (pwr_status & TCPC_POWER_STATUS_SOURCING_VBUS) { + else if (pwr_status & TCPC_POWER_STATUS_SOURCING_VBUS) tcpm_sourcing_vbus(chip->port); - /* - * Alawys re-enable boost here. - * In normal case, when say an headset is attached, TCPM would - * have instructed to TCPC to enable boost, so the call is a - * no-op. - * But for Fast Role Swap case, Boost turns on autonomously without - * AP intervention, but, needs AP to enable source mode explicitly - * for AP to regain control. - */ - max_tcpci_set_vbus(chip->tcpci, &chip->data, true, false); - } else { + else tcpm_vbus_change(chip->port); - } +} + +static void max_tcpci_frs_sourcing_vbus(struct tcpci *tcpci, struct tcpci_data *tdata) +{ + /* + * For Fast Role Swap case, Boost turns on autonomously without + * AP intervention, but, needs AP to enable source mode explicitly + * for AP to regain control. + */ + max_tcpci_set_vbus(tcpci, tdata, true, false); } static void process_tx(struct max_tcpci_chip *chip, u16 status) @@ -441,6 +440,7 @@ static int max_tcpci_probe(struct i2c_client *client, const struct i2c_device_id chip->data.start_drp_toggling = max_tcpci_start_toggling; chip->data.TX_BUF_BYTE_x_hidden = true; chip->data.init = tcpci_init; + chip->data.frs_sourcing_vbus = max_tcpci_frs_sourcing_vbus; max_tcpci_init_regs(chip); chip->tcpci = tcpci_register_port(chip->dev, &chip->data); From patchwork Thu Oct 8 06:15:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268749 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E88BC433E7 for ; Thu, 8 Oct 2020 06:16:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 574A520760 for ; Thu, 8 Oct 2020 06:16:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="uTtb7+of" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728839AbgJHGQ5 (ORCPT ); Thu, 8 Oct 2020 02:16:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36802 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728853AbgJHGQj (ORCPT ); Thu, 8 Oct 2020 02:16:39 -0400 Received: from mail-qk1-x749.google.com (mail-qk1-x749.google.com [IPv6:2607:f8b0:4864:20::749]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B9C0C0613D5 for ; Wed, 7 Oct 2020 23:16:28 -0700 (PDT) Received: by mail-qk1-x749.google.com with SMTP id u2so3190021qka.2 for ; Wed, 07 Oct 2020 23:16:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=0afO4rLOQPn7gMI304N6qXvrtGMWMCYRRtjs+1Xakek=; b=uTtb7+ofg2OG2cMxwvSTM2ldRGL9kdaDpJYxmAGOxlU+yr3Pf6MYmh72p3yN1ZAsZX efWu1MU32eMvtPiiJncf7TWqHAsFyz9sVVk1tK/Jn3evALFgUaRvRTYo8vQuhjXjHnzz SfWLx1OmApfzw3IecLiCLTq1fBw6yQd9mdE/9QxOCaUxm/2BNej6YvCmmRF6lKwYwqAs ls6P5dVR7LD3cCOzYYHO2EVlY8F80qCr85fLvtYibkuQnHsns8ugy0J3vfdB/Zoapaik z9++1Y3n+yOfk6SONNEaV+M0Fm3xu2FyqMJoiG+Un/GFJWCO03WFSxx4BkSEVouFDpuF QJvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=0afO4rLOQPn7gMI304N6qXvrtGMWMCYRRtjs+1Xakek=; b=lyH3i5aw6pxWhJl8HnC1A3r0YTQpWUKWu6KBUgD9PLS9/veJ9lPNl4Fgrvgau/I4DB BdrpiR6z69jutZ80JzmRS9wWl4bHxauqzV48bEwBeAGR10phHxVNwt9p3PnR4mNKYb9Q TLX+cHtY8akriMg3NzT7t6FTdF1NGiGxa2hlBO8F5fWmduFo9Sjvo1dj6F07w/HnN+ry 8LW5yELiCXy38RYDhtgBZ5ffMaWJJzqE3pYrvCkIlW1N+TGhEbckyxKKpcW8OiQPFnjM EBOasD4mq71VObnWkeI+lpkZenKPGrz+sALFgU9YsmzTFEKmnEf1n8Af1H6X2tEgWDs/ zwOg== X-Gm-Message-State: AOAM530dtEpyMa+Eergdc188Dx6wTtHNreVJF1OHzsgK98/xjXnZ522F r6KuJMHdz2Yw9KoMZnAbGJrTDxDsKls= X-Google-Smtp-Source: ABdhPJw7WhaRaqeR0L0lv1rj1FaUtUibazC8dkI2MQFvFXuAhurO32cj3J0XQeNK5domXhl9EEiQoRnQ7lY= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a0c:b39a:: with SMTP id t26mr6518189qve.19.1602137787303; Wed, 07 Oct 2020 23:16:27 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:53 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-13-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 12/15] usb: typec: tcpm: Parse frs type-c current from device tree From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org New source's current capability is now defined as string based device tree property through new-source-frs-typec-current. Refactor tcpm code to parse new-source-frs-typec-current and infer local port's new source current capability during frs. Signed-off-by: Badhri Jagan Sridharan --- v9 is the first version of this patch in this series to rebase TCPM code to read new source frs current from new-source-frs-typec-current. No changes since v9. --- drivers/usb/typec/tcpm/tcpm.c | 41 +++++++++++++++++++---------------- include/linux/usb/typec.h | 12 ++++++++++ 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 02b7f623f584..d5a3e2b3bea2 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -180,16 +180,11 @@ enum adev_actions { ADEV_ATTENTION, }; -/* - * Initial current capability of the new source when vSafe5V is applied during PD3.0 Fast Role Swap. - * Based on "Table 6-14 Fixed Supply PDO - Sink" of "USB Power Delivery Specification Revision 3.0, - * Version 1.2" - */ -enum frs_typec_current { - FRS_NOT_SUPPORTED, - FRS_DEFAULT_POWER, - FRS_5V_1P5A, - FRS_5V_3A, +static const char * const typec_new_source_frs_current[] = { + [FRS_NOT_SUPPORTED] = "not-supported", + [FRS_DEFAULT_POWER] = "default", + [FRS_5V_1P5A] = "1.5A", + [FRS_5V_3A] = "3.0A", }; /* Events from low level driver */ @@ -364,7 +359,7 @@ struct tcpm_port { bool self_powered; /* FRS */ - enum frs_typec_current frs_current; + enum typec_new_source_frs_current new_source_frs_current; /* Sink caps have been queried */ bool sink_cap_done; @@ -1713,7 +1708,7 @@ static void tcpm_pd_data_request(struct tcpm_port *port, unsigned int cnt = pd_header_cnt_le(msg->header); unsigned int rev = pd_header_rev_le(msg->header); unsigned int i; - enum frs_typec_current frs_current; + enum typec_new_source_frs_current partner_frs_current; bool frs_enable; int ret; @@ -1786,12 +1781,13 @@ static void tcpm_pd_data_request(struct tcpm_port *port, for (i = 0; i < cnt; i++) port->sink_caps[i] = le32_to_cpu(msg->payload[i]); - frs_current = (port->sink_caps[0] & PDO_FIXED_FRS_CURR_MASK) >> + partner_frs_current = (port->sink_caps[0] & PDO_FIXED_FRS_CURR_MASK) >> PDO_FIXED_FRS_CURR_SHIFT; - frs_enable = frs_current && (frs_current <= port->frs_current); + frs_enable = partner_frs_current && (partner_frs_current <= + port->new_source_frs_current); tcpm_log(port, "Port partner FRS capable partner_frs_current:%u port_frs_current:%u enable:%c", - frs_current, port->frs_current, frs_enable ? 'y' : 'n'); + partner_frs_current, port->new_source_frs_current, frs_enable ? 'y' : 'n'); if (frs_enable) { ret = port->tcpc->enable_frs(port->tcpc, true); tcpm_log(port, "Enable FRS %s, ret:%d\n", ret ? "fail" : "success", ret); @@ -4746,7 +4742,8 @@ static int tcpm_fw_get_caps(struct tcpm_port *port, { const char *cap_str; int ret; - u32 mw, frs_current; + u32 mw; + const char *new_source_frs_current; if (!fwnode) return -EINVAL; @@ -4817,9 +4814,15 @@ static int tcpm_fw_get_caps(struct tcpm_port *port, /* FRS can only be supported byb DRP ports */ if (port->port_type == TYPEC_PORT_DRP) { - ret = fwnode_property_read_u32(fwnode, "frs-typec-current", &frs_current); - if (ret >= 0 && frs_current <= FRS_5V_3A) - port->frs_current = frs_current; + ret = fwnode_property_read_string(fwnode, "new-source-frs-typec-current", + &new_source_frs_current); + if (!ret) { + ret = match_string(typec_new_source_frs_current, + ARRAY_SIZE(typec_new_source_frs_current), + new_source_frs_current); + if (ret >= 0) + port->new_source_frs_current = ret; + } } return 0; diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 6be558045942..3198b89fa451 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -72,6 +72,18 @@ enum typec_orientation { TYPEC_ORIENTATION_REVERSE, }; +/* + * Based on "Table 6-14 Fixed Supply PDO - Sink" of "USB Power Delivery Specification Revision 3.0, + * Version 1.2" + * Initial current capability of the new source when vSafe5V is applied. + */ +enum typec_new_source_frs_current { + FRS_NOT_SUPPORTED, + FRS_DEFAULT_POWER, + FRS_5V_1P5A, + FRS_5V_3A, +}; + /* * struct enter_usb_data - Enter_USB Message details * @eudo: Enter_USB Data Object From patchwork Thu Oct 8 06:15:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268425 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27A33C4727E for ; Thu, 8 Oct 2020 06:16:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D3ECF20782 for ; Thu, 8 Oct 2020 06:16:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="mNMAOTdU" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728851AbgJHGQj (ORCPT ); Thu, 8 Oct 2020 02:16:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36808 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728412AbgJHGQi (ORCPT ); Thu, 8 Oct 2020 02:16:38 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0FB1BC0613E2 for ; Wed, 7 Oct 2020 23:16:30 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id v4so203370ybp.3 for ; Wed, 07 Oct 2020 23:16:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=GjCc+BQkNqKSsKaA/WplKUyBVW0UGrqMAZUqUladaLM=; b=mNMAOTdUE549pA1vBLa0xlJl2DtepK4ZRhiLM0QF82FkDuuyDMHjtOyDdYrY9DNHtK oaEVZ53iAMGaUt8Pgp0PRKucNYmejbhR2AAMK50NC+W9D9ogB7hvNj1UmBZAMeAhgiPB 1asuQEZiPBJyrkkD4eg9V0K4jGraGxlidw0RFZA8eXdnYIIL2lSm7ZD0MyVJaPLyGarq 9/je4jc1vJ5ZkMyoup0Ph6Oj+DVsG2IngP4zXGN7+NDAglskG6FiwO8neTxTsdKZO7GO EmQwBwcEY1cMH4unzzc36st1ax5FRhaWXNWdkBjKq8TUj17RUll/H3LYtPLqbKgZSmnp d4tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=GjCc+BQkNqKSsKaA/WplKUyBVW0UGrqMAZUqUladaLM=; b=dOYS+cqDfQj+FEcPmbFS2HElAKLy+3W+uXm3ict3zN4O3b6EDYe7oIMFfcGVIfOvI5 3jYVBtKA4G06D+AnjIFc9hpQfx3Y2NcHBZHddjfoVSqI/8mUt3wStv20ZC1Kest6suaJ zzZntgB+hQAdzbQ9IEwsl/GZvI2b9yf5ZZttjsoUTAlnSMpB8gh3KBp8038BkbzHgXge 7TdvfzMYags8nRFtQe3QLNoGKjeD4t3zLsD4M3m5uQllBTgg1mVklvGWT5LywIRM80gh Qy0vQ61I7sNEVYJNwGAs6qda+AaGjDYlnSDyPcWjb7ir//5TtOO+FQ0JYkeqvngf6nIM kNFg== X-Gm-Message-State: AOAM5334EK/zMq2M7nrw8UZXQlX4QKTo/Z8+17SLA+VPJd5xD4LvM2yP EtuuLHRpjcrjCiJ8HCmlfM+xoHqt1iI= X-Google-Smtp-Source: ABdhPJzw4x4l4Msd/pS1Y6RiCAeIrWU4Iz05D1UDL3YFVodLdqhIcGiLm6uyT/nuVvEkqP5oiunssN376wQ= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a25:a290:: with SMTP id c16mr9189840ybi.84.1602137789208; Wed, 07 Oct 2020 23:16:29 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:54 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-14-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 13/15] usb: typec: tcpm: Implement enabling Auto Discharge disconnect support From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org TCPCI spec allows TCPC hardware to autonomously discharge the vbus capacitance upon disconnect. The expectation is that the TCPM enables AutoDischargeDisconnect while entering SNK/SRC_ATTACHED states. Hardware then automously discharges vbus when the vbus falls below a certain threshold i.e. VBUS_SINK_DISCONNECT_THRESHOLD. Apart from enabling the vbus discharge circuit, AutoDischargeDisconnect is also used a flag to move TCPCI based TCPC implementations into Attached.Snk/Attached.Src state as mentioned in Figure 4-15. TCPC State Diagram before a Connection of the USB Type-C Port Controller Interface Specification. In such TCPC implementations, setting AutoDischargeDisconnect would prevent TCPC into entering "Connection_Invalid" state as well. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- Changes since v1: - Changing patch version to v6 to fix version number confusion. Changes since v6: - Fixed incorrect data_role error that I introduced by mistake in the previous version. Changes since v7: - Rebase on usb-next Changes since v8: - Removing the call to tcpm_set_auto_vbus_discharge_threshold in the source path. - Changes since v9: - None --- drivers/usb/typec/tcpm/tcpm.c | 60 ++++++++++++++++++++++++++++++++--- include/linux/usb/tcpm.h | 15 +++++++++ 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index d5a3e2b3bea2..51a14d282109 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -1701,6 +1701,24 @@ static void tcpm_handle_alert(struct tcpm_port *port, const __le32 *payload, } } +static int tcpm_set_auto_vbus_discharge_threshold(struct tcpm_port *port, + enum typec_pwr_opmode mode, bool pps_active, + u32 requested_vbus_voltage) +{ + int ret; + + if (!port->tcpc->set_auto_vbus_discharge_threshold) + return 0; + + ret = port->tcpc->set_auto_vbus_discharge_threshold(port->tcpc, mode, pps_active, + requested_vbus_voltage); + tcpm_log_force(port, + "set_auto_vbus_discharge_threshold mode:%d pps_active:%c vbus:%u ret:%d", + mode, pps_active ? 'y' : 'n', requested_vbus_voltage, ret); + + return ret; +} + static void tcpm_pd_data_request(struct tcpm_port *port, const struct pd_message *msg) { @@ -1871,6 +1889,10 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, port->current_limit, port->supply_voltage); port->explicit_contract = true; + tcpm_set_auto_vbus_discharge_threshold(port, + TYPEC_PWR_MODE_PD, + port->pps_data.active, + port->supply_voltage); tcpm_set_state(port, SNK_READY, 0); } else { /* @@ -2785,8 +2807,12 @@ static int tcpm_src_attach(struct tcpm_port *port) if (ret < 0) return ret; - ret = tcpm_set_roles(port, true, TYPEC_SOURCE, - tcpm_data_role_for_source(port)); + if (port->tcpc->enable_auto_vbus_discharge) { + ret = port->tcpc->enable_auto_vbus_discharge(port->tcpc, true); + tcpm_log_force(port, "enable vbus discharge ret:%d", ret); + } + + ret = tcpm_set_roles(port, true, TYPEC_SOURCE, tcpm_data_role_for_source(port)); if (ret < 0) return ret; @@ -2853,6 +2879,12 @@ static void tcpm_unregister_altmodes(struct tcpm_port *port) static void tcpm_reset_port(struct tcpm_port *port) { + int ret; + + if (port->tcpc->enable_auto_vbus_discharge) { + ret = port->tcpc->enable_auto_vbus_discharge(port->tcpc, false); + tcpm_log_force(port, "Disable vbus discharge ret:%d", ret); + } tcpm_unregister_altmodes(port); tcpm_typec_disconnect(port); port->attached = false; @@ -2917,8 +2949,13 @@ static int tcpm_snk_attach(struct tcpm_port *port) if (ret < 0) return ret; - ret = tcpm_set_roles(port, true, TYPEC_SINK, - tcpm_data_role_for_sink(port)); + if (port->tcpc->enable_auto_vbus_discharge) { + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, VSAFE5V); + ret = port->tcpc->enable_auto_vbus_discharge(port->tcpc, true); + tcpm_log_force(port, "enable vbus discharge ret:%d", ret); + } + + ret = tcpm_set_roles(port, true, TYPEC_SINK, tcpm_data_role_for_sink(port)); if (ret < 0) return ret; @@ -3502,6 +3539,8 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, SRC_UNATTACHED, PD_T_PS_SOURCE_ON); break; case SNK_HARD_RESET_SINK_OFF: + /* Do not discharge/disconnect during hard reseet */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, 0); memset(&port->pps_data, 0, sizeof(port->pps_data)); tcpm_set_vconn(port, false); if (port->pd_capable) @@ -3544,6 +3583,7 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_charge(port, true); } tcpm_set_attached_state(port, true); + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, VSAFE5V); tcpm_set_state(port, SNK_STARTUP, 0); break; @@ -3645,6 +3685,10 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, PR_SWAP_SNK_SRC_SINK_OFF, 0); break; case PR_SWAP_SRC_SNK_TRANSITION_OFF: + /* + * Prevent vbus discharge circuit from turning on during PR_SWAP + * as this is not a disconnect. + */ tcpm_set_vbus(port, false); port->explicit_contract = false; /* allow time for Vbus discharge, must be < tSrcSwapStdby */ @@ -3673,9 +3717,17 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state_cond(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON); break; case PR_SWAP_SRC_SNK_SINK_ON: + /* Set the vbus disconnect threshold for implicit contract */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, VSAFE5V); tcpm_set_state(port, SNK_STARTUP, 0); break; case PR_SWAP_SNK_SRC_SINK_OFF: + /* + * Prevent vbus discharge circuit from turning on during PR_SWAP + * as this is not a disconnect. + */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, + port->pps_data.active, 0); tcpm_set_charge(port, false); tcpm_set_state(port, hard_reset_state(port), PD_T_PS_SOURCE_OFF); diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h index 7303f518ba49..e68aaa12886f 100644 --- a/include/linux/usb/tcpm.h +++ b/include/linux/usb/tcpm.h @@ -86,6 +86,18 @@ enum tcpm_transmit_type { * @frs_sourcing_vbus: * Optional; Called to notify that vbus is now being sourced. * Low level drivers can perform chip specific operations, if any. + * @enable_auto_vbus_discharge: + * Optional; TCPCI spec based TCPC implementations can optionally + * support hardware to autonomously dischrge vbus upon disconnecting + * as sink or source. TCPM signals TCPC to enable the mechanism upon + * entering connected state and signals disabling upon disconnect. + * @set_auto_vbus_discharge_threshold: + * Mandatory when enable_auto_vbus_discharge is implemented. TCPM + * calls this function to allow lower levels drivers to program the + * vbus threshold voltage below which the vbus discharge circuit + * will be turned on. requested_vbus_voltage is set to 0 when vbus + * is going to disappear knowingly i.e. during PR_SWAP and + * HARD_RESET etc. */ struct tcpc_dev { struct fwnode_handle *fwnode; @@ -113,6 +125,9 @@ struct tcpc_dev { int (*set_bist_data)(struct tcpc_dev *dev, bool on); int (*enable_frs)(struct tcpc_dev *dev, bool enable); void (*frs_sourcing_vbus)(struct tcpc_dev *dev); + int (*enable_auto_vbus_discharge)(struct tcpc_dev *dev, bool enable); + int (*set_auto_vbus_discharge_threshold)(struct tcpc_dev *dev, enum typec_pwr_opmode mode, + bool pps_active, u32 requested_vbus_voltage); }; struct tcpm_port; From patchwork Thu Oct 8 06:15:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268748 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5F1B8C46466 for ; Thu, 8 Oct 2020 06:17:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ECE3D20760 for ; Thu, 8 Oct 2020 06:17:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="JXlLTnib" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728930AbgJHGRH (ORCPT ); Thu, 8 Oct 2020 02:17:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728836AbgJHGQi (ORCPT ); Thu, 8 Oct 2020 02:16:38 -0400 Received: from mail-qt1-x849.google.com (mail-qt1-x849.google.com [IPv6:2607:f8b0:4864:20::849]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E2CFAC0613E5 for ; Wed, 7 Oct 2020 23:16:31 -0700 (PDT) Received: by mail-qt1-x849.google.com with SMTP id t40so3055498qtc.19 for ; Wed, 07 Oct 2020 23:16:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=ebMLL3uQjmDQf27Z+hcIGJGbzI6/4R/tQRAYIq3vKl8=; b=JXlLTnib43C3WXIOzSQrHV561AgM1lwqnXeY5/6dTnyH5lU2iRoNASrDjXM7q2eJT0 r9W7B7J3LUhIGFhXq2dZzV8CPdDqDWy2EPcXr/YJosA8u4vNY/Gh6pwhtFxdjAXh30pF 5tAXsFTL2z1T8cektqJGJ2f52t3qQH/z5qyJ5NDDZuIQsQTfBs/9GMwkZL/03sX+PZaq XMzpUWfL+rdShCeLqA8xeN/Mw6raWUYBmUyjMKxk6cupBYZu/uYp/buPjBtJkB1FM1VT SX4yFT2zqMUEmnJcCwMvf+HIFUcNgthCtj7OVoNVN0fHCRP1E2DiAlYU3PLuVCUJJsIL 8TZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ebMLL3uQjmDQf27Z+hcIGJGbzI6/4R/tQRAYIq3vKl8=; b=PwGdkqSNRVhMMz0nrfK5c+HyeJIsTOWRy8Lj38KRjq3u4DWwAAz9hWXsxEA6FJrCse vnc9vINuDy+eOuZuZAxBpDp4cz3f8Y+DUs5kqLXA/QVUuMeD3papfI8qafIKjYcF/QpT auJxd/X5c07BygI3rPK8H//LH5Ta2wg3MahuJ8sOC0aSjBokCLXYQ7L4tJtEXtxGkkQy XwDZIfw+8J2RnLGovkFz2poosvOJYAWwpxLXFtdmMKx0MUeEWapRZXefYw3PcvUUOtrs 73zvtJFPqvEAig7VU1XJhZCPPbDX9T1QWMM7QTMifCbcI/jNy2FS0gSAYVbGXLDdXTHm XJDQ== X-Gm-Message-State: AOAM532jPIXU7I8c+5tdOd4VPjl9yZ9qLaQqZDx1NjKjV8NM/N+Vqi+Q eENRpxUCecOCdnXm9C+7q8ECl22ZJsw= X-Google-Smtp-Source: ABdhPJwNmYJzXx8mim9diJUMMT/spOt5aVujkZBCx8HuI9Q5zNK1iPsbj0QG1HN4Aw/25UdMR0OWRmhfDWc= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:ad4:458d:: with SMTP id x13mr6927461qvu.4.1602137791024; Wed, 07 Oct 2020 23:16:31 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:55 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-15-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 14/15] usb: typec: tcpci: Implement Auto discharge disconnect callbacks From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org vImplement callbacks for enabling/disabling POWER_CONTROL.AutoDischargeDisconnect. Programs VBUS_SINK_DISCONNECT_THRESHOLD based on the voltage requested as sink, mode of operation. The programmed threshold is based on vSinkDisconnect and vSinkDisconnectPD values. Add auto_discharge_disconnect to tdata to allow TCPC chip level drivers enable AutoDischargeDisconnect. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- Changes since v1: - Changing patch version to v6 to fix version number confusion. Changes since v6: - Rebase on usb-next. Changes since v7: Heikki's suggestion: - Moved the actual write to TCPC_VBUS_SINK_DISCONNECT_THRESH as it's common to all chip drivers. - Renaming the tcpci_data callback as get_auto_vbus_discharge_threshold Changes since v8: - Removed get_auto_vbus_discharge_threshold callback and moved the logic to program the default threshold for TCPC_VBUS_SINK_DISCONNECT_THRESH into the TCPCI code. Changes since v9: - none --- drivers/usb/typec/tcpm/tcpci.c | 63 +++++++++++++++++++++++++++++++++- drivers/usb/typec/tcpm/tcpci.h | 14 ++++++-- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index f91688e43991..12d983a75510 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -18,7 +18,10 @@ #include "tcpci.h" -#define PD_RETRY_COUNT 3 +#define PD_RETRY_COUNT 3 +#define AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV 3500 +#define AUTO_DISCHARGE_PD_HEADROOM_MV 850 +#define AUTO_DISCHARGE_PPS_HEADROOM_MV 1250 struct tcpci { struct device *dev; @@ -268,6 +271,58 @@ static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable) enable ? TCPC_POWER_CTRL_VCONN_ENABLE : 0); } +static int tcpci_enable_auto_vbus_discharge(struct tcpc_dev *dev, bool enable) +{ + struct tcpci *tcpci = tcpc_to_tcpci(dev); + int ret; + + ret = regmap_update_bits(tcpci->regmap, TCPC_POWER_CTRL, TCPC_POWER_CTRL_AUTO_DISCHARGE, + enable ? TCPC_POWER_CTRL_AUTO_DISCHARGE : 0); + return ret; +} + +static int tcpci_set_auto_vbus_discharge_threshold(struct tcpc_dev *dev, enum typec_pwr_opmode mode, + bool pps_active, u32 requested_vbus_voltage_mv) +{ + struct tcpci *tcpci = tcpc_to_tcpci(dev); + unsigned int pwr_ctrl, threshold = 0; + int ret; + + /* + * Indicates that vbus is going to go away due PR_SWAP, hard reset etc. + * Do not discharge vbus here. + */ + if (requested_vbus_voltage_mv == 0) + goto write_thresh; + + ret = regmap_read(tcpci->regmap, TCPC_POWER_CTRL, &pwr_ctrl); + if (ret < 0) + return ret; + + if (pwr_ctrl & TCPC_FAST_ROLE_SWAP_EN) { + /* To prevent disconnect when the source is fast role swap is capable. */ + threshold = AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV; + } else if (mode == TYPEC_PWR_MODE_PD) { + if (pps_active) + threshold = (95 * requested_vbus_voltage_mv / 100) - + AUTO_DISCHARGE_PD_HEADROOM_MV; + else + threshold = (95 * requested_vbus_voltage_mv / 100) - + AUTO_DISCHARGE_PPS_HEADROOM_MV; + } else { + /* 3.5V for non-pd sink */ + threshold = AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV; + } + + threshold = threshold / TCPC_VBUS_SINK_DISCONNECT_THRESH_LSB_MV; + + if (threshold > TCPC_VBUS_SINK_DISCONNECT_THRESH_MAX) + return -EINVAL; + +write_thresh: + return tcpci_write16(tcpci, TCPC_VBUS_SINK_DISCONNECT_THRESH, threshold); +} + static int tcpci_enable_frs(struct tcpc_dev *dev, bool enable) { struct tcpci *tcpci = tcpc_to_tcpci(dev); @@ -638,6 +693,12 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data) tcpci->tcpc.enable_frs = tcpci_enable_frs; tcpci->tcpc.frs_sourcing_vbus = tcpci_frs_sourcing_vbus; + if (tcpci->data->auto_discharge_disconnect) { + tcpci->tcpc.enable_auto_vbus_discharge = tcpci_enable_auto_vbus_discharge; + tcpci->tcpc.set_auto_vbus_discharge_threshold = + tcpci_set_auto_vbus_discharge_threshold; + } + err = tcpci_parse_config(tcpci); if (err < 0) return ERR_PTR(err); diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h index b418fe11b527..3fe313655f0c 100644 --- a/drivers/usb/typec/tcpm/tcpci.h +++ b/drivers/usb/typec/tcpm/tcpci.h @@ -8,6 +8,8 @@ #ifndef __LINUX_USB_TCPCI_H #define __LINUX_USB_TCPCI_H +#include + #define TCPC_VENDOR_ID 0x0 #define TCPC_PRODUCT_ID 0x2 #define TCPC_BCD_DEV 0x4 @@ -67,6 +69,7 @@ #define TCPC_POWER_CTRL 0x1c #define TCPC_POWER_CTRL_VCONN_ENABLE BIT(0) +#define TCPC_POWER_CTRL_AUTO_DISCHARGE BIT(4) #define TCPC_FAST_ROLE_SWAP_EN BIT(7) #define TCPC_CC_STATUS 0x1d @@ -133,6 +136,8 @@ #define TCPC_VBUS_VOLTAGE 0x70 #define TCPC_VBUS_SINK_DISCONNECT_THRESH 0x72 +#define TCPC_VBUS_SINK_DISCONNECT_THRESH_LSB_MV 25 +#define TCPC_VBUS_SINK_DISCONNECT_THRESH_MAX 0x3ff #define TCPC_VBUS_STOP_DISCHARGE_THRESH 0x74 #define TCPC_VBUS_VOLTAGE_ALARM_HI_CFG 0x76 #define TCPC_VBUS_VOLTAGE_ALARM_LO_CFG 0x78 @@ -140,17 +145,22 @@ /* I2C_WRITE_BYTE_COUNT + 1 when TX_BUF_BYTE_x is only accessible I2C_WRITE_BYTE_COUNT */ #define TCPC_TRANSMIT_BUFFER_MAX_LEN 31 +struct tcpci; + /* - * @TX_BUF_BYTE_x_hidden + * @TX_BUF_BYTE_x_hidden: * optional; Set when TX_BUF_BYTE_x can only be accessed through I2C_WRITE_BYTE_COUNT. * @frs_sourcing_vbus: * Optional; Callback to perform chip specific operations when FRS * is sourcing vbus. + * @auto_discharge_disconnect: + * Optional; Enables TCPC to autonously discharge vbus on disconnect. */ -struct tcpci; struct tcpci_data { struct regmap *regmap; unsigned char TX_BUF_BYTE_x_hidden:1; + unsigned char auto_discharge_disconnect:1; + int (*init)(struct tcpci *tcpci, struct tcpci_data *data); int (*set_vconn)(struct tcpci *tcpci, struct tcpci_data *data, bool enable); From patchwork Thu Oct 8 06:15:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Badhri Jagan Sridharan X-Patchwork-Id: 268422 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.4 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 46BEBC04EBE for ; Thu, 8 Oct 2020 06:16:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EF43D20760 for ; Thu, 8 Oct 2020 06:16:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dLyHE+NK" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728911AbgJHGQ5 (ORCPT ); Thu, 8 Oct 2020 02:16:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36856 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728837AbgJHGQi (ORCPT ); Thu, 8 Oct 2020 02:16:38 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10288C0613E6 for ; Wed, 7 Oct 2020 23:16:34 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id e190so4367540ybf.18 for ; Wed, 07 Oct 2020 23:16:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=6GCQRlFJvWAm6bVyoR4JADJgZDrlGQ+tF0P2tDjAwQ4=; b=dLyHE+NKdQx6N3xp8Uj0u2R2VKofMtLTZbJqX8MtTRl8FhWle9nCzpI2P9+fYPIo0m 63b5xQhRL/DjD/toLWYMiH1Ax8C/upXf/Sj8+oSDqMga8KA9ZzrOzMQ/W4hWBmW+tH2y +ohwZCkSNbr4REb60eP9JKyuul04eKFo3xMlrFyauZ8sZKfy18SK5nhSEY51H2EbJn0R X5MPqZEAUaTsF9GdTK+OPZ7lbomAv6YIPCSVfDJ34wGFbFAQ2zMj7jwCM8Uz9J1hIOQ4 71ByrlPz2ptjDEhJXFkIHnDUSCAlxtuhc0gLPLOd+1jFS52qb0s51Jonjsakkt2de7Vm ZU6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=6GCQRlFJvWAm6bVyoR4JADJgZDrlGQ+tF0P2tDjAwQ4=; b=N83DSuM+x4uM+SLgRqa7iosdETfvyokbYJsvDVFsVtCF+lhbY6RCpTBdICOSAOOwPO koxZReuzFiosVLYTVQU0mNcB/i94o8T3o97dmqxI725AXXVnwArNIwz5B8usQIsEAoZw HQZiIY0fSbrUPymu8f6sapwSBXm66LyoppzfohTkCRoL3ob9Bvsq37V99AyhYEdPQTog R7jVKyO2Ry2En4Kf5QyXmBuSdHuWVx6PhPixfT3TOp6n59rTZqxGx+4XN5AJnLsfZGTK qymHE9Gm1CwsmT0mgxdCUpfTQdNHbdbgzQiiSUdmEEiXs6zT3+MyDi663+7H79XMrt0x XHIw== X-Gm-Message-State: AOAM533xQ3mRFY5mD9QnFuesILZfnwDCiD/Ylsfg9zsE/bQo+PJPAom6 bvUVy0SUJ5RA8nXpSDk6cCH3SmJ7jDU= X-Google-Smtp-Source: ABdhPJzR1jVNVW1InfbNo/DsP2kOzfsXrTXKg75iI2BfBahjQzKg4bl254IPLZohE8W45uopVL6I/TAa6Us= Sender: "badhri via sendgmr" X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a25:3184:: with SMTP id x126mr9152093ybx.141.1602137793300; Wed, 07 Oct 2020 23:16:33 -0700 (PDT) Date: Wed, 7 Oct 2020 23:15:56 -0700 In-Reply-To: <20201008061556.1402293-1-badhri@google.com> Message-Id: <20201008061556.1402293-16-badhri@google.com> Mime-Version: 1.0 References: <20201008061556.1402293-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.806.g8561365e88-goog Subject: [PATCH v10 15/15] usb: typec: tcpci_maxim: Enable auto discharge disconnect From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Lee Jones , Mark Brown , Maxime Ripard , Alexandre Belloni , Thierry Reding , Prashant Malani , Badhri Jagan Sridharan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, Amelie Delaunay Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Enable auto discharge disconnect for Maxim TCPC. Signed-off-by: Badhri Jagan Sridharan Reviewed-by: Heikki Krogerus --- Changes since v1: - Changing patch version to v6 to fix version number confusion. Changes since v6: - Rebase on usb-next. Changes since v7: - Heikki's suggestion: Moved the actual write of TCPC_VBUS_SINK_DISCONNECT_THRES register to tcpci code. Changes since v8: - Moved the logic to program the default values of TCPC_VBUS_SINK_DISCONNECT_THRESH into the tcpci code. Changes since v9: - none. --- drivers/usb/typec/tcpm/tcpci_maxim.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c index 43dcad95e897..55dea33387ec 100644 --- a/drivers/usb/typec/tcpm/tcpci_maxim.c +++ b/drivers/usb/typec/tcpm/tcpci_maxim.c @@ -441,6 +441,7 @@ static int max_tcpci_probe(struct i2c_client *client, const struct i2c_device_id chip->data.TX_BUF_BYTE_x_hidden = true; chip->data.init = tcpci_init; chip->data.frs_sourcing_vbus = max_tcpci_frs_sourcing_vbus; + chip->data.auto_discharge_disconnect = true; max_tcpci_init_regs(chip); chip->tcpci = tcpci_register_port(chip->dev, &chip->data);