From patchwork Tue Aug 25 04:21:57 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: 258779 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=-12.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT 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 B9BE5C433E1 for ; Tue, 25 Aug 2020 04:22:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 962782072D for ; Tue, 25 Aug 2020 04:22:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="jkhAZg0i" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728405AbgHYEW1 (ORCPT ); Tue, 25 Aug 2020 00:22:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50828 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725970AbgHYEW0 (ORCPT ); Tue, 25 Aug 2020 00:22:26 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B8A3AC061574 for ; Mon, 24 Aug 2020 21:22:25 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id 78so1902088pgf.5 for ; Mon, 24 Aug 2020 21:22: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=JEUp//OgrqIdq4oBTWKdSUH95jBvEG8vdsM1vuPs8Tc=; b=jkhAZg0iMscEcFm/RUujA72vXdC5gOQalIMPfd5KOkCgy0trvRgRNN31LwH8axbb7i xOLx4FM+xYzv2EGDoGafREwUQoWb2M+/oQkPRZlswGJnaPNb8tdZwjkBj1fnwNhV576/ R0y80iV4KLLDO566lEoAvw6xLv1BQdZffvioxrcRTOZVQMglHb96tE6o9Xjskbs7rhkf ApskSMLxthNLqOY1aRI+2ijCMAJLe5FnQYOcxBmE0yrHJfckDTTYByGE5JXdgtLrQw3I nUpd3w8XVA8y4JfSuoVObQcUCdk71hZLCS2c00zANEgCy3TZ0y47FfmqCp4xPp8G1mQo iu3Q== 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=JEUp//OgrqIdq4oBTWKdSUH95jBvEG8vdsM1vuPs8Tc=; b=N06ihSy2WR2S2HYPsA7wSvNRXQCJ1q7FBWQk4G8CbRrEbSJNR2qtIVBl8qHrspwZRA pfQCr6zbFj4pGzTqOvPaogarpoBZYhJGunpffGcFllt66jOPgjyKmgwfMLQavZHVnxKv 3QJPrAS9L9SCMl2VnBzftjk/awvOqsO13bULyXMm6tWOXbmFKlLKPuo5VI6PARxv8okk riRsuuNLXyn0R/WMhWF3wFj5h/JbwncGDNc8RiYQuiZZkQka9GVQnIpquljV1rTnZ9qv OCl14lokS2Mh20PKpJpgUW1Dkz9vQqzmNM6mb/iZZ4layhlCzJvw2fgz6i/7RbzqHiq9 JK/Q== X-Gm-Message-State: AOAM533bgYjc3HTVMt1211NMt3qsayAZNWZJoNACvPZIBlMFNQQ9qE68 FWJFwqakND4nOHc/410OchKuZTxysIg= X-Google-Smtp-Source: ABdhPJyqxUn6kmdMRMpi7HMnXOCyU5kHwFBq5l3bMwOsEy7jvpoqAEAyF30GuaZPav1y862SjZOY2YhBsHQ= X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a17:90a:bd8a:: with SMTP id z10mr72361pjr.12.1598329345209; Mon, 24 Aug 2020 21:22:25 -0700 (PDT) Date: Mon, 24 Aug 2020 21:21:57 -0700 In-Reply-To: <20200825042210.300632-1-badhri@google.com> Message-Id: <20200825042210.300632-2-badhri@google.com> Mime-Version: 1.0 References: <20200825042210.300632-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.297.g1956fa8f8d-goog Subject: [PATCH 01/14 v1] usb: typec: tcpci: Add register definitions to tcpci From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Badhri Jagan Sridharan Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Add register definitions to trap extended alerts. Signed-off-by: Badhri Jagan Sridharan --- drivers/usb/typec/tcpm/tcpci.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h index 11c36d086c86..fd26ca35814c 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_EXTENDED_STATUS BIT(13) #define TCPC_ALERT_VBUS_DISCNCT BIT(11) #define TCPC_ALERT_RX_BUF_OVF BIT(10) #define TCPC_ALERT_FAULT BIT(9) @@ -32,6 +33,10 @@ #define TCPC_ALERT_MASK 0x12 #define TCPC_POWER_STATUS_MASK 0x14 #define TCPC_FAULT_STATUS_MASK 0x15 + +#define TCPC_EXTENDED_STATUS_MASK 0x16 +#define TCPC_EXTENDED_STATUS_MASK_VSAFE0V BIT(0) + #define TCPC_CONFIG_STD_OUTPUT 0x18 #define TCPC_TCPC_CTRL 0x19 From patchwork Tue Aug 25 04:21:59 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: 258778 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=-12.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT 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 7153DC433E1 for ; Tue, 25 Aug 2020 04:22:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 461282072D for ; Tue, 25 Aug 2020 04:22:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="n72OI6Mo" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728520AbgHYEWf (ORCPT ); Tue, 25 Aug 2020 00:22:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50856 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728483AbgHYEWe (ORCPT ); Tue, 25 Aug 2020 00:22:34 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 654F2C061574 for ; Mon, 24 Aug 2020 21:22:34 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id t13so924463pjd.0 for ; Mon, 24 Aug 2020 21:22: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=F8R7yB/uW413X5BedlVvfs1XP30S/Fpzu0dI0Wqxoxc=; b=n72OI6MoEkQhfKUwJdHzWFQo0b8hAvkNDSD1jmWoyZQ0V8OJBU2zf9TYkIjQYpXtCo dUStaSep5gflMaYcmcL10S6XR/DnqRv7amQsr9GxaBe2MnDAxILEhPQWW3VG5ABPS2vh gDTLW7GGp0hfHW1TCkZJkfAAwPALmBk/VDLkGb6JSOt8XzTD1AjuqshMjX8wseVt5E8S RY6f27PWDyrpbj01THKYTfJ5h+K5UhMQJSGDLhuErTYtZvRFeFQGkDh7vmu1PbxIrVWT SBPc9z1H4Ln+WHTzwN1F8WXvd1I+1D7wnSbQtdxyTo2Gbffbf9SRmBA2yLbXStxxNNxR C0yQ== 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=F8R7yB/uW413X5BedlVvfs1XP30S/Fpzu0dI0Wqxoxc=; b=mmHY8U/qv22uZV8LlP0qbhhyoNWoG2rQ7PDnVspff7i0ngne7/oB5H3sdiGMKZEQmU baLkp0oHL3iwrxnbuttjeGB0sD3jsk/heMSrnfri0pLYhBdPpE6tBX/ey5/I7uTjLlQB WahUg2zY+Tf53j08bhoc3gwD2OOOAt/6W3j+b33TvtQ2Hwv8ACLBIXq3Jxk6fd3AJoyV daTcbOThRlfAkVu1qT/oQCCnZXmNFR/WQ7S1UR/oix4ba46mtxh/ci2j4eMujqMyt/PS 95vKmRXUyISq2bIWi75AkU0uVXF7bhyazO9n2zmnbLz38+O0BWIIThr6mdJnK6QQAzHi A9ew== X-Gm-Message-State: AOAM530pCEIKHBiDEBVqi4y+x5v1A1en0RHALXiuGZDpP+Q1iMCrDJ7u kxtSQDvQaOTN/RfwonzaJXheGBDUxuk= X-Google-Smtp-Source: ABdhPJzj5NrEqS6R/E/pway38JrzWHE+PYmAiWI5fTlEcegdm6POulaQfy5AaYM7tiD79DhVVquGuO7tQkA= X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a17:90a:638c:: with SMTP id f12mr249425pjj.1.1598329353549; Mon, 24 Aug 2020 21:22:33 -0700 (PDT) Date: Mon, 24 Aug 2020 21:21:59 -0700 In-Reply-To: <20200825042210.300632-1-badhri@google.com> Message-Id: <20200825042210.300632-4-badhri@google.com> Mime-Version: 1.0 References: <20200825042210.300632-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.297.g1956fa8f8d-goog Subject: [PATCH 03/14 v1] usb: typec: tcpci: update ROLE_CONTROL for DRP From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Badhri Jagan Sridharan Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org ROLE_CONTROL register would not have the actual CC terminations unless the port does not set ROLE_CONTROL.DRP. For DRP ports, CC_STATUS.cc1/cc2 indicates the final terminations applied when TCPC enters potential_connect_as_source/_sink. For DRP ports, infer port role from CC_STATUS and set corresponding CC terminations before setting the orientation. Signed-off-by: Badhri Jagan Sridharan --- drivers/usb/typec/tcpm/tcpci.c | 37 +++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index 90d348caa6a8..9e814d454d14 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -191,12 +191,47 @@ static int tcpci_set_polarity(struct tcpc_dev *tcpc, struct tcpci *tcpci = tcpc_to_tcpci(tcpc); unsigned int reg; int ret; + enum typec_cc_status cc1, cc2; - /* Keep the disconnect cc line open */ + /* Obtain Rp setting from role control */ ret = regmap_read(tcpci->regmap, TCPC_ROLE_CTRL, ®); if (ret < 0) return ret; + ret = tcpci_get_cc(tcpc, &cc1, &cc2); + if (ret < 0) + return ret; + + /* + * When port has drp toggling enabled, ROLE_CONTROL would only have the initial + * terminations for the toggling and does not indicate the final cc + * terminations when ConnectionResult is 0 i.e. drp toggling stops and + * the connection is resolbed. Infer port role from TCPC_CC_STATUS based on the + * terminations seen. The port role is then used to set the cc terminations. + */ + if (reg & TCPC_ROLE_CTRL_DRP) { + /* Disable DRP for the OPEN setting to take effect */ + reg = reg & ~TCPC_ROLE_CTRL_DRP; + + if (polarity == TYPEC_POLARITY_CC2) { + reg &= ~(TCPC_ROLE_CTRL_CC2_MASK << TCPC_ROLE_CTRL_CC2_SHIFT); + /* Local port is source */ + if (cc2 == TYPEC_CC_RD) + /* Role control would have the Rp setting when DRP was enabled */ + reg |= TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC2_SHIFT; + else + reg |= TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC2_SHIFT; + } else { + reg &= ~(TCPC_ROLE_CTRL_CC1_MASK << TCPC_ROLE_CTRL_CC1_SHIFT); + /* Local port is source */ + if (cc1 == TYPEC_CC_RD) + /* Role control would have the Rp setting when DRP was enabled */ + reg |= TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC1_SHIFT; + else + reg |= TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC1_SHIFT; + } + } + if (polarity == TYPEC_POLARITY_CC2) reg |= TCPC_ROLE_CTRL_CC_OPEN << TCPC_ROLE_CTRL_CC1_SHIFT; else From patchwork Tue Aug 25 04:22:02 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: 258775 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=-12.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT 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 B2D53C433E3 for ; Tue, 25 Aug 2020 04:23:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8C0E82072D for ; Tue, 25 Aug 2020 04:23:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="B42heZaf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726163AbgHYEWq (ORCPT ); Tue, 25 Aug 2020 00:22:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728598AbgHYEWn (ORCPT ); Tue, 25 Aug 2020 00:22:43 -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 3AFDAC061574 for ; Mon, 24 Aug 2020 21:22:43 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id w17so13264177ybl.9 for ; Mon, 24 Aug 2020 21:22:43 -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=LaXEwiyj3MgKPctp60ipXsQUebEP+5mdaxvo+R2WRtw=; b=B42heZafxHivLXm0aOGdLVibiLm0qF8L3IvB4FKYWSdfzVeQcw8YAoeM3uGV1iASBk QStfkWVxSFPTJbJeD+It4FOLb8AjJ6vzLOe/RMg5JAwfkLpFm5XN3y5xQ4gwduYKMZ+2 vWdM3FW1wS9yUociub30p+hdr04vhK5WAMaVU8lDzlMMy2NnH7lFDgTo8bhkinl8MzJF zoCrgkEXwTmjv1GHk59JMRF8DZ233ezppxpssME2uLw+CUQySOth4LrkUA7PLVcxjk7s UP+7OdA2NtD/Lupell9hj0Q35a70qWkW9PZdrQXvC3bqXphEGo4779HmR5NuOEPnBPly lOiQ== 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=LaXEwiyj3MgKPctp60ipXsQUebEP+5mdaxvo+R2WRtw=; b=joYVCdyq6I5svNBh+xVEUWOVMfnJECmvYuDjE3ozJhishQbS70ehmRspNjuuel1JWE BqBp6/im3u8AlCfRB6oi0Q+ySE2z7haKIiIZ9mxjHssi/xQq9RCmpGXZSlWi+IB0iXD4 D+6p2c97wSS67n8QAmGMUX2GOkhno8JsjtQllh69BtygXX6nAao2zDJJJQWxDkZdmKbh zQXXu4SP/46NHO9KNL6kQkvBL4M5kj1EPv8R0alfb4CP1vA5mVXgK+XjGEJTN9p+dfFS Yjd5laZ5d0VVMTkvhPgwvmfLZZ1APPtczeayFho/Ts7Slp0rQFaYkwOam7XiT5rQywaf sxew== X-Gm-Message-State: AOAM530xOSn3nfu05TeFMYuAJuiAg9H4YWhOxtLbFvm5zrstzMc+APzM dxDd3Sv7TqBcQkGvXVidCpn5TMT2rNc= X-Google-Smtp-Source: ABdhPJxFkE/6S2bXb/DiC+7xpTwEG+Px60JIceRAjFDtnoEnF2XgbQDbE3vGU5rXuA/vyLvl2tJtvpOXlRs= X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a25:3b0d:: with SMTP id i13mr11726889yba.314.1598329362488; Mon, 24 Aug 2020 21:22:42 -0700 (PDT) Date: Mon, 24 Aug 2020 21:22:02 -0700 In-Reply-To: <20200825042210.300632-1-badhri@google.com> Message-Id: <20200825042210.300632-7-badhri@google.com> Mime-Version: 1.0 References: <20200825042210.300632-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.297.g1956fa8f8d-goog Subject: [PATCH 06/14 v1] dt-bindings: usb: Maxim type-c controller device tree binding document From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Badhri Jagan Sridharan Sender: linux-usb-owner@vger.kernel.org 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 --- .../devicetree/bindings/usb/maxim,tcpci.txt | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/maxim,tcpci.txt diff --git a/Documentation/devicetree/bindings/usb/maxim,tcpci.txt b/Documentation/devicetree/bindings/usb/maxim,tcpci.txt new file mode 100644 index 000000000000..8a5b08e57b2d --- /dev/null +++ b/Documentation/devicetree/bindings/usb/maxim,tcpci.txt @@ -0,0 +1,44 @@ +Maxim TCPCI Type-C PD controller: +--------------------------------- + +Required properties: +- compatible: should be set maxim,tcpci: + +- reg: 0x25:the i2c slave address of typec port controller device. +- interrupt-parent: the phandle to the interrupt controller which provides + the interrupt. +- usbpd,usbpd_int: interrupt specification for tcpci alert. + +Required sub-node: +- connector: The "usb-c-connector" attached to the tcpci chip, the bindings + of connector node are specified in + Documentation/devicetree/bindings/connector/usb-connector.txt + +maxtcpc: maxtcpc@25 { + status = "okay"; + compatible = "maxim,tcpc"; + reg = <0x25>; + interrupt-parent = <&gpa8>; + usbpd,usbpd_int = <&gpa8 2 GPIO_ACTIVE_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 Tue Aug 25 04:22:03 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: 258773 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=-12.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT 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 4C357C433DF for ; Tue, 25 Aug 2020 04:23:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 194712072D for ; Tue, 25 Aug 2020 04:23:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="dX5uz47r" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728543AbgHYEXh (ORCPT ); Tue, 25 Aug 2020 00:23:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50902 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728548AbgHYEWp (ORCPT ); Tue, 25 Aug 2020 00:22:45 -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 2FFA3C061574 for ; Mon, 24 Aug 2020 21:22:45 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id x6so13375119ybp.10 for ; Mon, 24 Aug 2020 21:22:45 -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=sFdYqBQlTSkB+FFqFlpawTx7xM2r9WYQ3mb5WM7+TDQ=; b=dX5uz47rOdNS32QHVSWJzNCzMTPaSaOMrw2hwaJLtbyBStRFrCNExIdSuqI2aBsbka HHM6794Ikzpr4ubevzqkxqj5nERllwBBabxaFdvdaH2qbOdhvzfFjezAg0GbZqfeq52f t0nNIdyaDkQN2z6Jf/uj/xzlLC+Y1rbNHuXHOsfxnvA7znqHu2PIMUa8g+HxCJCyL77+ EMePiPFP4uTQWPB3UAOsH2G/fpIVM9O5dDbqnZWFm7cJigQA1fmkfRVmk6XO/2f/UsYE gYLmC2D0HAth92diZQZ8czf8O4KCgkH4bPCv/nhrEqI+iUT60Qx7/trveJqst5Xmz5CR 5dPA== 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=sFdYqBQlTSkB+FFqFlpawTx7xM2r9WYQ3mb5WM7+TDQ=; b=kiHlZQYeG388oDnanbIy3WNWkn5qsXv4zi9N2fV9xHAgaFZeYYT5v1uL2I1FqP4Rpv M4wXfcs586lr+tCPRU3fG6kiP3jZWwmCsBV7a3mKSJtx1SYD66I+Xsj5367yp1W7FQxt JZTRRx2F5pQiuIozYPxBYvepZyJZSdCpIRiTzF4dQEgMfd8V3eZQVXqzRj+aN/2bTIFH 5hS2hw5c4kIVj/9VlRiufKk0GnSEHvLNrsbMWalTSg3cfyOmYSQWdl5PKa26ZYCVPTkF da7oh7Oq42tBohb1eFWKmXdz/AcIL6t4rP6MfOe7YEMPyC2GT08ptqunI1BuDU2rwBRu 5bQg== X-Gm-Message-State: AOAM533gXb+lqewzgQKK6RD3TA9j4OZSloDhv7UrTG7AUCEng3DJydJs a0+So6p2Wsy8GoLJvfortXAawTm9tmw= X-Google-Smtp-Source: ABdhPJyhAYrZP4syB+/LfKRsjiHSevArYgDQeEQwJ784AAKb9XLYH3OQm2uDpxYkuL+OQ7f8RrFPtNkYJWk= X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a25:ca83:: with SMTP id a125mr12717448ybg.513.1598329364377; Mon, 24 Aug 2020 21:22:44 -0700 (PDT) Date: Mon, 24 Aug 2020 21:22:03 -0700 In-Reply-To: <20200825042210.300632-1-badhri@google.com> Message-Id: <20200825042210.300632-8-badhri@google.com> Mime-Version: 1.0 References: <20200825042210.300632-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.297.g1956fa8f8d-goog Subject: [PATCH 07/14 v1] usb: typec: tcpci_maxim: Chip level TCPC driver From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Badhri Jagan Sridharan Sender: linux-usb-owner@vger.kernel.org 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 --- drivers/usb/typec/tcpm/Kconfig | 6 + drivers/usb/typec/tcpm/Makefile | 13 +- drivers/usb/typec/tcpm/tcpci.h | 1 + drivers/usb/typec/tcpm/tcpci_maxim.c | 474 +++++++++++++++++++++++++++ 4 files changed, 488 insertions(+), 6 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 fa3f39336246..7c9722b02afe 100644 --- a/drivers/usb/typec/tcpm/Kconfig +++ b/drivers/usb/typec/tcpm/Kconfig @@ -27,6 +27,12 @@ config TYPEC_RT1711H 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" + select USB_PSY + help + MAXIM TCPCI based Type-C chip driver + endif # TYPEC_TCPCI config TYPEC_FUSB302 diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile index a5ff6c8eb892..58d001cf0dd2 100644 --- a/drivers/usb/typec/tcpm/Makefile +++ b/drivers/usb/typec/tcpm/Makefile @@ -1,7 +1,8 @@ # 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_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_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..b61f290a8f96 --- /dev/null +++ b/drivers/usb/typec/tcpm/tcpci_maxim.c @@ -0,0 +1,474 @@ +// 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_TX_DISCARDED) + dev_info(chip->dev, "TX_DISCARDED"); + + 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, irq_gpio; + + irq_gpio = of_get_named_gpio(client->dev.of_node, "usbpd,usbpd_int", 0); + client->irq = gpio_to_irq(irq_gpio); + if (!client->irq) + return -ENODEV; + + 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; + + if (power_status & TCPC_POWER_STATUS_UNINIT) { + dev_err(&client->dev, "TCPC not ready!"); + return -EPROBE_DEFER; + } + + /* 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 Tue Aug 25 04:22:04 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: 258776 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=-12.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT 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 5EA1EC433DF for ; Tue, 25 Aug 2020 04:23:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 344FC20737 for ; Tue, 25 Aug 2020 04:23:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="SWck33LS" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728675AbgHYEW6 (ORCPT ); Tue, 25 Aug 2020 00:22:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728619AbgHYEWs (ORCPT ); Tue, 25 Aug 2020 00:22:48 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3276EC061755 for ; Mon, 24 Aug 2020 21:22:47 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id 78so1902634pgf.5 for ; Mon, 24 Aug 2020 21:22:47 -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=xSJS/XKA/aUbgtCi/q0K7inzUjymBY7nSgjzrufvP5I=; b=SWck33LSi0EUA97KEivGtM62HLq7cI9NPByz2VNQN5Yj76sbRwA6eIbsgtw8t23Bo1 4dpzmutg2ZM1LAJHCqo01eRTrUM9a/MKq6F7uNwM1uO7gJn/bocbf5OvUlnWy0M1yraV Heefpw9QTivgPe9clxyaQp7XfjjLvU8jD8sjFD0WyP3mliSoP4ypB5g3bjOc+uzw8zUs orCxBMEIdseOw4S9L+tyozs83Lp0XsJT0NoekcAenBCZytN4OLq9EQ9I+2MMKYZI9fwt 1DdK4dQP6isJnXpvq278juj4El9L1p4/f5qH5gTMSnu/Ndpk/krM/OppVWZLdRoGxIRE nT7A== 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=xSJS/XKA/aUbgtCi/q0K7inzUjymBY7nSgjzrufvP5I=; b=Ifi3rkEJf96CU1M4cdX4wF0kRUcyXZtRUyb/rozYXP39E3Bre6AQx+j8yiwYi9H3Aw hj5oDUMor0Gxf0jZUgzr+qjF1cSewubuZ8bidKp/W2MkqhnjOjInyGDX6s4pojHhUTXb BV5SXhDkYL+aAqyCcAXnjd1TEsR6Z2gcXOR0zZM50TLMPXX0+MVY7mozymlp/MALYsyE fkN/96nK9RVEP04qSkxSBT+b2P1gY9KDetUnPuoXa0HasMeIHQbj+bLO6EXLOcxyYQF5 al++zWiq+aeL7iKM0JBJumr6CaNifdmHYDCecV3YxxZ34624s+poACpFg+80TeY86PFO objg== X-Gm-Message-State: AOAM532wSvb+0qiHqh8P3Ik2/NmIOzWVxqa9H9mpfH1/r3dFGWzBzxQi luBWCwLorM8hraC5g9BdDEDuS2DvaH8= X-Google-Smtp-Source: ABdhPJwHNxFi0Ec+H6bmOoX2PQxOar5hmeGLFWZaRs3cPffAINCKLYgzjt/DsBEo87S7HZEhfXLkegbK/LQ= X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a63:3e0c:: with SMTP id l12mr2515256pga.190.1598329366531; Mon, 24 Aug 2020 21:22:46 -0700 (PDT) Date: Mon, 24 Aug 2020 21:22:04 -0700 In-Reply-To: <20200825042210.300632-1-badhri@google.com> Message-Id: <20200825042210.300632-9-badhri@google.com> Mime-Version: 1.0 References: <20200825042210.300632-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.297.g1956fa8f8d-goog Subject: [PATCH 08/14 v1] dt-bindings: connector: Add property to set initial current cap for FRS From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Badhri Jagan Sridharan Sender: linux-usb-owner@vger.kernel.org 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 --- .../bindings/connector/usb-connector.txt | 128 ++++++++++++++++++ include/dt-bindings/usb/pd.h | 10 ++ 2 files changed, 138 insertions(+) create mode 100644 Documentation/devicetree/bindings/connector/usb-connector.txt diff --git a/Documentation/devicetree/bindings/connector/usb-connector.txt b/Documentation/devicetree/bindings/connector/usb-connector.txt new file mode 100644 index 000000000000..e2f6e0f07d00 --- /dev/null +++ b/Documentation/devicetree/bindings/connector/usb-connector.txt @@ -0,0 +1,128 @@ +USB Connector +============= + +USB connector node represents physical USB connector. It should be +a child of USB interface controller. + +Required properties: +- compatible: describes type of the connector, must be one of: + "usb-a-connector", + "usb-b-connector", + "usb-c-connector". + +Optional properties: +- label: symbolic name for the connector, +- type: size of the connector, should be specified in case of USB-A, USB-B + non-fullsize connectors: "mini", "micro". + +Optional properties for usb-c-connector: +- power-role: should be one of "source", "sink" or "dual"(DRP) if typec + connector has power support. +- try-power-role: preferred power role if "dual"(DRP) can support Try.SNK + or Try.SRC, should be "sink" for Try.SNK or "source" for Try.SRC. +- data-role: should be one of "host", "device", "dual"(DRD) if typec + connector supports USB data. +- frs-typec-current - 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. + 0: Fast role swap not supported + 1: Default USB Power + 2: 1.5A @ 5V + 3: 3A @ 5V. + +Required properties for usb-c-connector with power delivery support: +- source-pdos: An array of u32 with each entry providing supported power + source data object(PDO), the detailed bit definitions of PDO can be found + in "Universal Serial Bus Power Delivery Specification" chapter 6.4.1.2 + Source_Capabilities Message, the order of each entry(PDO) should follow + the PD spec chapter 6.4.1. Required for power source and power dual role. + User can specify the source PDO array via PDO_FIXED/BATT/VAR/PPS_APDO() + defined in dt-bindings/usb/pd.h. +- sink-pdos: An array of u32 with each entry providing supported power + sink data object(PDO), the detailed bit definitions of PDO can be found + in "Universal Serial Bus Power Delivery Specification" chapter 6.4.1.3 + Sink Capabilities Message, the order of each entry(PDO) should follow + the PD spec chapter 6.4.1. Required for power sink and power dual role. + User can specify the sink PDO array via PDO_FIXED/BATT/VAR/PPS_APDO() defined + in dt-bindings/usb/pd.h. +- op-sink-microwatt: Sink required operating power in microwatt, if source + can't offer the power, Capability Mismatch is set. Required for power + sink and power dual role. + +Required nodes: +- any data bus to the connector should be modeled using the OF graph bindings + specified in bindings/graph.txt, unless the bus is between parent node and + the connector. Since single connector can have multpile data buses every bus + has assigned OF graph port number as follows: + 0: High Speed (HS), present in all connectors, + 1: Super Speed (SS), present in SS capable connectors, + 2: Sideband use (SBU), present in USB-C. + +Examples +-------- + +1. Micro-USB connector with HS lines routed via controller (MUIC): + +muic-max77843@66 { + ... + usb_con: connector { + compatible = "usb-b-connector"; + label = "micro-USB"; + type = "micro"; + }; +}; + +2. USB-C connector attached to CC controller (s2mm005), HS lines routed +to companion PMIC (max77865), SS lines to USB3 PHY and SBU to DisplayPort. +DisplayPort video lines are routed to the connector via SS mux in USB3 PHY. + +ccic: s2mm005@33 { + ... + usb_con: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usb_con_hs: endpoint { + remote-endpoint = <&max77865_usbc_hs>; + }; + }; + port@1 { + reg = <1>; + usb_con_ss: endpoint { + remote-endpoint = <&usbdrd_phy_ss>; + }; + }; + port@2 { + reg = <2>; + usb_con_sbu: endpoint { + remote-endpoint = <&dp_aux>; + }; + }; + }; + }; +}; + +3. USB-C connector attached to a typec port controller(ptn5110), which has +power delivery support and enables drp. + +typec: ptn5110@50 { + ... + usb_con: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + power-role = "dual"; + try-power-role = "sink"; + source-pdos = ; + sink-pdos = ; + op-sink-microwatt = <10000000>; + }; +}; diff --git a/include/dt-bindings/usb/pd.h b/include/dt-bindings/usb/pd.h index 985f2bbd4d24..db1ad4532197 100644 --- a/include/dt-bindings/usb/pd.h +++ b/include/dt-bindings/usb/pd.h @@ -35,6 +35,16 @@ #define VSAFE5V 5000 /* mv units */ +/* + * 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. + */ +#define FRS_NOT_SUPPORTED 0 +#define FRS_DEFAULT_POWER 1 +#define FRS_5V_1P5A 2 +#define FRS_5V_3A 3 + #define PDO_BATT_MAX_VOLT_SHIFT 20 /* 50mV units */ #define PDO_BATT_MIN_VOLT_SHIFT 10 /* 50mV units */ #define PDO_BATT_MAX_PWR_SHIFT 0 /* 250mW units */ From patchwork Tue Aug 25 04:22:07 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: 258774 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=-12.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT 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 5F5A0C433E3 for ; Tue, 25 Aug 2020 04:23:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 37DDF2072D for ; Tue, 25 Aug 2020 04:23:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="YqtZ49pJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728745AbgHYEX2 (ORCPT ); Tue, 25 Aug 2020 00:23:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728653AbgHYEWy (ORCPT ); Tue, 25 Aug 2020 00:22:54 -0400 Received: from mail-qv1-xf4a.google.com (mail-qv1-xf4a.google.com [IPv6:2607:f8b0:4864:20::f4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 681F9C061755 for ; Mon, 24 Aug 2020 21:22:54 -0700 (PDT) Received: by mail-qv1-xf4a.google.com with SMTP id h6so7896208qvz.14 for ; Mon, 24 Aug 2020 21:22:54 -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=Nv5tc6KahqHd2NBKcfPXCDAaClr/I8kOXQmUHCJ9qWQ=; b=YqtZ49pJFfw//Tms6srxB9cmG6SIMAsPfgiC2cbBRjzdOKnk3y7KFv8E5qzMu+TQza aMQp2eGCeAlq0EKOoTbiQZoj6jnqDkiErdDtaXvfFO2DAXy2N6MZW2xx0uMV8zgo/+hA KWUzDsx+qQpyUDgyuEQwYOx+rF/BDpRhb+NSSMhCu1r0f/erlqTu2+legGwWHWUsKrzy VQGnzfaBKfu+c717oQoHVwwPSRyOU9Q9cLiT5KkmVKWDcej3+suM5Ky9F784FXv2gRxY X7AIZtPk2y/kzUtNpcaCJ3PAqu3L7+rIsEfA3+N2BzABpSNa/gYL6b6P4Zv55ZyliTI1 TffQ== 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=Nv5tc6KahqHd2NBKcfPXCDAaClr/I8kOXQmUHCJ9qWQ=; b=VbMogXdL/IyZu8jpP3PXeU6TqraAvRaSPq9wBZw4EU0wPAQG/HOxzoLGOIQ9AbAnqO k3Gz4KRAfPDp8KC1UArQnGmENe7L61jw3M6zdLhRxczXEYsYFKw+ofBx5snJ+BkYQMtG /Bwwd9cDXwQ0c/uOYe8ePqEH3/+WZEzB7Lsx7qQbIu/kaSg2CC/ec9K2hoZ0h0pD+CLK hKOk5qi0eGQRwWl35Ez+kQMWj/ZcKyDaZ8fZ3rK6prFJRASrgsXSP3RqmPmp3Nw6bCfh mCUd1bJt6LSayla11HjU0y7SqZVME4n8Iyqnv/1xjs8aROPyG9JgLMB6+qmdroslH3yd 9pUg== X-Gm-Message-State: AOAM5333+i73bak6539f5YvCAgxLlF+A8+7NlIfs7IihgZVdZYbKUaTO ywPVDF3UwMqzwVjplUZUeK/m7JHKL0g= X-Google-Smtp-Source: ABdhPJyxdJTRBEww26jqyEBYkoSZj8teumSAJ0bi3oYNf5zYDACJTuOdVs9cm1hocyvPsrPZUaRz/v9WtsE= X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a0c:f607:: with SMTP id r7mr8103797qvm.219.1598329373011; Mon, 24 Aug 2020 21:22:53 -0700 (PDT) Date: Mon, 24 Aug 2020 21:22:07 -0700 In-Reply-To: <20200825042210.300632-1-badhri@google.com> Message-Id: <20200825042210.300632-12-badhri@google.com> Mime-Version: 1.0 References: <20200825042210.300632-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.297.g1956fa8f8d-goog Subject: [PATCH 11/14 v1] usb: typec: tcpci_maxim: Add support for Sink FRS From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Badhri Jagan Sridharan Sender: linux-usb-owner@vger.kernel.org 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 --- 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 b61f290a8f96..6ba808ad901a 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 Tue Aug 25 04:22:09 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: 258777 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=-12.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT 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 0B3FAC433E3 for ; Tue, 25 Aug 2020 04:23:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D9FA82072D for ; Tue, 25 Aug 2020 04:23:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="iiGIlPDO" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728696AbgHYEXA (ORCPT ); Tue, 25 Aug 2020 00:23:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50950 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728684AbgHYEW6 (ORCPT ); Tue, 25 Aug 2020 00:22:58 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 81D8BC061574 for ; Mon, 24 Aug 2020 21:22:58 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id lx6so890844pjb.9 for ; Mon, 24 Aug 2020 21:22:58 -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=MSjuJlqwZbeT/5gqoAJ2R9KeJjOh0ok3YdAVNY4kQaQ=; b=iiGIlPDOuad/QAjayZvFuF9m6tB9LjCXcmIMy8uLi85cby6M0mje5/RE6FryMc5jzU 87st0DVi/rwSFdumypv1bjZ0JYLvyFksJxFRNcHzHvf+e346hdcQbVySpRqhFcxI8haY gbsCaQmSxvd99S0w6IZUjp6qfkQ3SPhtcxkcYZE+DTnPyymDT8aodQrGhmfMSnVg8bi3 IDuZr2O5DkdTDn615ZI/QDSQOxU2ijLydeA5tmwhEq9sS2V4ZJrJlLuU8v192ha3J62P Hzq2Vb9L9PB7Yi65Xwt2tSfmEx3vGH0WaCRwfZh7GXhq0IHD6/Lewyn428Pgp+tO7T7g IvRQ== 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=MSjuJlqwZbeT/5gqoAJ2R9KeJjOh0ok3YdAVNY4kQaQ=; b=hsFdDPjLTgTtPogDZ7496xjZAojtld5Rkhm5sjjIsB2beiFD8XP8w7cPUi3a/fTT6P qmOfFsOPL4kMfBMKyY32LofZK5j/VOZW5Q8Kz6Et8C6i2tv7ytNAvE0gFic55rnzrct9 bi9PrXXOGoj/GdaoYZTB4zfGMqCGOl4vfBKfhaqmRJUHsjydZo6VIFpaQOT51u9Iak3j Payk61rfzHQRmO7nTCcIYpTkUIHj0FNRFrku3nTOBusDTr0Hb6mhl4blmIQsuC25NTCG Obhnu8VDdsMLlUQjYfqqY7uYIpQv2xH0nK2lp4i+kKLsX/eSt53eCbZfrd935m391YiO vZfA== X-Gm-Message-State: AOAM531O2gbxGnLn2QACmPIW20gkA7Hwq4gbLppGCBxBuceNVehe5YCV MhlrETeghwSNEzi84xsBW4DMHwM4pPA= X-Google-Smtp-Source: ABdhPJzBTyW+pz3D1TsoZ/ckSs2GKW2XpSlJoOPGekFFwT/3u4C/xG6pxz48LFAsil4v0+HC4sTHI9Hsi7E= X-Received: from badhri.mtv.corp.google.com ([2620:15c:211:1:f292:1cff:fee0:66cf]) (user=badhri job=sendgmr) by 2002:a05:6a00:22cc:: with SMTP id f12mr6383025pfj.42.1598329377892; Mon, 24 Aug 2020 21:22:57 -0700 (PDT) Date: Mon, 24 Aug 2020 21:22:09 -0700 In-Reply-To: <20200825042210.300632-1-badhri@google.com> Message-Id: <20200825042210.300632-14-badhri@google.com> Mime-Version: 1.0 References: <20200825042210.300632-1-badhri@google.com> X-Mailer: git-send-email 2.28.0.297.g1956fa8f8d-goog Subject: [PATCH 13/14 v1] usb: typec: tcpci: Implement Auto discharge disconnect callbacks From: Badhri Jagan Sridharan To: Guenter Roeck , Heikki Krogerus , Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Badhri Jagan Sridharan Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Implement callbacks for enabling/disabling POWER_CONTROL.AutoDischargeDisconnect. 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 --- drivers/usb/typec/tcpm/tcpci.c | 33 +++++++++++++++++++++++++++++++++ drivers/usb/typec/tcpm/tcpci.h | 22 ++++++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index 13d2e1c2ff20..e876f13ddf31 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -268,6 +268,33 @@ 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_role port_role, + enum typec_pwr_opmode mode, bool pps_active, + u32 requested_vbus_voltage) +{ + struct tcpci *tcpci = tcpc_to_tcpci(dev); + int (*set_auto_vbus_threshold)(struct tcpci *tcpci, struct tcpci_data *data, + enum typec_role port_role, enum typec_pwr_opmode mode, + bool pps_active, u32 requested_vbus_voltage); + + set_auto_vbus_threshold = tcpci->data->set_auto_vbus_discharge_threshold; + if (set_auto_vbus_threshold) + return set_auto_vbus_threshold(tcpci, tcpci->data, port_role, mode, pps_active, + requested_vbus_voltage); + + return 0; +} + static int tcpci_enable_frs(struct tcpc_dev *dev, bool enable) { struct tcpci *tcpci = tcpc_to_tcpci(dev); @@ -628,6 +655,12 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data) tcpci->tcpc.set_bist_data = tcpci_set_bist_data; tcpci->tcpc.enable_frs = tcpci_enable_frs; + 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 5ef07a56d67a..6a0aea34e544 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 25 +#define TCPC_VBUS_SINK_DISCONNECT_THRESH_MAX 1023 #define TCPC_VBUS_STOP_DISCHARGE_THRESH 0x74 #define TCPC_VBUS_VOLTAGE_ALARM_HI_CFG 0x76 #define TCPC_VBUS_VOLTAGE_ALARM_LO_CFG 0x78 @@ -140,20 +145,33 @@ /* 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. + * @auto_discharge_disconnect: + * Optional; Enables TCPC to autonously discharge vbus on disconnect. + * @set_auto_vbus_discharge_threshold: + * Mandatory when @auto_discharge_disconnect is sets. Allows + * programming the voltage threshold of vbus below which TCPC + * enables the vbus discharge circuit. */ -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); 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); + int (*set_auto_vbus_discharge_threshold)(struct tcpci *tcpci, struct tcpci_data *data, + enum typec_role port_role, + enum typec_pwr_opmode mode, bool pps_active, + u32 requested_vbus_voltage); }; struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data);