From patchwork Wed Jul 12 01:02:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 107430 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp173837qge; Tue, 11 Jul 2017 18:03:40 -0700 (PDT) X-Received: by 10.98.148.25 with SMTP id m25mr52960494pfe.7.1499821420710; Tue, 11 Jul 2017 18:03:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499821420; cv=none; d=google.com; s=arc-20160816; b=XAkRpEdLK7TWjGImtoRhltvIQCo+tVKbfguTp3NwYWQN18yZ8Ly3tOFnj9QGkfWb7C 0Rue23tzV5er954RuC8x6MVB3UjC18YWsZZZzOLL/q6Yk00iFa6lWLV7BV4Rkmyy3XK/ jH3LClVRJiKN31aVb/wHhH14TBvARCbBjdAKqmiv78/z9gWNRlfDrzEppJFTV9yNyAud 3WdXDRoTxvdPlALbCMFE5U0fKmOHpzPgh39vGG+iBnCUuyWsZl8sQs3iooz/vfUaGIjT IFJyLm6FDZ6GgKMfTQt8gsSi6SwnCA7U9lkqYx8VK+C/8ibUPZCqnvp8PC+jsh+tXt+c 1Ltg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=WisfCyQDoSQZ3/Zkvfrz3CGstznQndqTSBVmu9O0kNE=; b=dP8dV2yk7GZNvph4Ts2fUwmbIZWVTAZK7WEmoXjq0Zir9W58ghUeF7KE/mlV2VSKP2 h+ciWiragXDkZvyilF7iyBxOUd91jFyo20CyFspKxUsylfCBz2/Bbs/dyzn4ZLlNAsay N3WPbuiuBP4GUOybSv6RGGMcCu9Sarce3Rs4EMaHj6PhGMDAAclN/9w0FlYOvkCddYL2 o1J7NlSAt5Ex7jezkRE9EbatQ4bd9bSHO29xto/609jG+ogTzAu0thrZD86s15rdziGF +7xzGH4S8z2yrf6AWpGdck0Kxi5X4W/EZvPhBYUV89J04QfjjCDie+s48oOvYweBUwmB rFpQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.b=kO19SFbX; spf=pass (google.com: best guess record for domain of linux-usb-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-usb-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b8si709370ple.3.2017.07.11.18.03.40; Tue, 11 Jul 2017 18:03:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-usb-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.b=kO19SFbX; spf=pass (google.com: best guess record for domain of linux-usb-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-usb-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932857AbdGLBDY (ORCPT + 4 others); Tue, 11 Jul 2017 21:03:24 -0400 Received: from mail-pg0-f51.google.com ([74.125.83.51]:36364 "EHLO mail-pg0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756326AbdGLBDB (ORCPT ); Tue, 11 Jul 2017 21:03:01 -0400 Received: by mail-pg0-f51.google.com with SMTP id u62so4275330pgb.3 for ; Tue, 11 Jul 2017 18:03:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=SnVLsasyuKSlr94shIPM/o9Y2VoqEPL8Y6hVX5D6WpE=; b=kO19SFbXnoruiQOyaLmQiWqTvmeiLi9skbDBhlRGyg/fZaZod/iRS9V27SsUZWy17+ Q8a5fRNbKOG25KNqc/bNk/4MUvzEl8tL6n+8L8Nck/JRfz09L1M6kISAu0YLWs1ExAjJ lHkTevo6o1SMJC/CCQEtl/M1XNPqWZxOQvI4E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=SnVLsasyuKSlr94shIPM/o9Y2VoqEPL8Y6hVX5D6WpE=; b=pQCgoBrVaqifrw/RIh9ozufph2HJ3xz346oZBXq+A06yS9F5RoUSQti+Ml0CV4l/bA b4DhQLXbEhSB+d9QuisdNfIVzn+duAFTuC8XYivgrbZ18YLaVxkBm37di6Vt7u6tp5ZV IdaQXylEYI38L3ajx1UsZvQ9NN7UZ2ez10qZhDO8obEW5pemgFUAHtDUaMjtqH25Rmmi 416SAhvhUf+Bx77l/Ago+EItDJPhP2McZ5ceyK76Cq8YWiNtpNMbD5D14HfEPEPZbU3I uqv0yXglndrpnINNX8YmBPsbSLRK5GMUn5oDRpy5weFSdKv7WFO4rGyZWlcX9rJIFq6G 7Tug== X-Gm-Message-State: AIVw110u0fgb9EoiSc6Hbx7JKCCwYKrThZo9uaSgD25a222L8OIDXnug aOHS/+PcZwF2xNs1 X-Received: by 10.98.33.132 with SMTP id o4mr52779006pfj.11.1499821381013; Tue, 11 Jul 2017 18:03:01 -0700 (PDT) Received: from localhost.localdomain (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id o8sm839571pgn.52.2017.07.11.18.02.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 11 Jul 2017 18:03:00 -0700 (PDT) From: Stephen Boyd To: Peter Chen Cc: linux-usb@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Rob Herring , Rob Clark , Andy Gross , Peter Rosin , Peter Chen , Greg Kroah-Hartman Subject: [PATCH 2/3] usb: chipidea: Hook into mux framework to toggle usb switch Date: Tue, 11 Jul 2017 18:02:54 -0700 Message-Id: <20170712010255.26855-3-stephen.boyd@linaro.org> X-Mailer: git-send-email 2.10.0.297.gf6727b0 In-Reply-To: <20170712010255.26855-1-stephen.boyd@linaro.org> References: <20170712010255.26855-1-stephen.boyd@linaro.org> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org On the db410c 96boards platform we have a TC7USB40MU on the board to mux the D+/D- lines coming from the controller between a micro usb "device" port and a USB hub for "host" roles[1]. During a role switch, we need to toggle this mux to forward the D+/D- lines to either the port or the hub. Add the necessary code to do the role switch in chipidea core via the generic mux framework. Board configurations like on db410c are expected to change roles via the sysfs API described in Documentation/ABI/testing/sysfs-platform-chipidea-usb2. [1] https://github.com/96boards/documentation/raw/master/ConsumerEdition/DragonBoard-410c/HardwareDocs/Schematics_DragonBoard.pdf Cc: Peter Rosin Cc: Peter Chen Cc: Greg Kroah-Hartman Cc: Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 8 ++++++++ drivers/usb/chipidea/core.c | 17 +++++++++++++++++ drivers/usb/chipidea/host.c | 10 ++++++++++ drivers/usb/chipidea/udc.c | 11 +++++++++++ include/linux/usb/chipidea.h | 14 ++++++++++++++ 5 files changed, 60 insertions(+) -- 2.10.0.297.gf6727b0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt index 0e03344e2e8b..96ce81d975d5 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt @@ -76,6 +76,11 @@ Optional properties: needs to make sure it does not send more than 90% maximum_periodic_data_per_frame. The use case is multiple transactions, but less frame rate. +- mux-controls: The mux control for toggling host/device output of this + controller. +- mux-control-names: Shall be "usb_switch" if mux-controls is specified. +- usb-switch-states: Two u32's defining the state to set on the mux for the + host mode and device modes respectively. i.mx specific properties - fsl,usbmisc: phandler of non-core register device, with one @@ -102,4 +107,7 @@ Example: rx-burst-size-dword = <0x10>; extcon = <0>, <&usb_id>; phy-clkgate-delay-us = <400>; + mux-controls = <&usb_switch>; + mux-control-names = "usb_switch"; + usb-switch-states = <0>, <1>; }; diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index b17ed3a9a304..6531d771f296 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -64,6 +64,7 @@ #include #include #include +#include #include "ci.h" #include "udc.h" @@ -606,6 +607,7 @@ static int ci_get_platdata(struct device *dev, { struct extcon_dev *ext_vbus, *ext_id; struct ci_hdrc_cable *cable; + struct ci_hdrc_switch *usb_switch; int ret; if (!platdata->phy_mode) @@ -690,6 +692,21 @@ static int ci_get_platdata(struct device *dev, if (of_find_property(dev->of_node, "non-zero-ttctrl-ttha", NULL)) platdata->flags |= CI_HDRC_SET_NON_ZERO_TTHA; + if (IS_ENABLED(CONFIG_MULTIPLEXER)) { + usb_switch = &platdata->usb_switch; + usb_switch->mux = devm_mux_control_get(dev, "usb_switch"); + if (!IS_ERR(usb_switch->mux)) { + if (of_property_read_u32_index(dev->of_node, + "usb-switch-states", + 0, &usb_switch->device)) + return -EINVAL; + if (of_property_read_u32_index(dev->of_node, + "usb-switch-states", + 1, &usb_switch->host)) + return -EINVAL; + } + } + ext_id = ERR_PTR(-ENODEV); ext_vbus = ERR_PTR(-ENODEV); if (of_property_read_bool(dev->of_node, "extcon")) { diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 18cb8e46262d..9fd23ecc2da3 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "../host/ehci.h" @@ -123,6 +124,13 @@ static int host_start(struct ci_hdrc *ci) if (usb_disabled()) return -ENODEV; + if (!IS_ERR(ci->platdata->usb_switch.mux)) { + ret = mux_control_select(ci->platdata->usb_switch.mux, + ci->platdata->usb_switch.host); + if (ret) + return ret; + } + hcd = __usb_create_hcd(&ci_ehci_hc_driver, ci->dev->parent, ci->dev, dev_name(ci->dev), NULL); if (!hcd) @@ -205,6 +213,8 @@ static void host_stop(struct ci_hdrc *ci) if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) && (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON)) regulator_disable(ci->platdata->reg_vbus); + if (!IS_ERR(ci->platdata->usb_switch.mux)) + mux_control_deselect(ci->platdata->usb_switch.mux); } ci->hcd = NULL; ci->otg.host = NULL; diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index d68b125796f9..ab3355905740 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "ci.h" #include "udc.h" @@ -1899,6 +1900,13 @@ static int udc_start(struct ci_hdrc *ci) ci->gadget.name = ci->platdata->name; ci->gadget.otg_caps = otg_caps; + if (!IS_ERR(ci->platdata->usb_switch.mux)) { + retval = mux_control_select(ci->platdata->usb_switch.mux, + ci->platdata->usb_switch.device); + if (retval) + return retval; + } + if (ci->is_otg && (otg_caps->hnp_support || otg_caps->srp_support || otg_caps->adp_support)) ci->gadget.is_otg = 1; @@ -1982,6 +1990,9 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci) hw_write_otgsc(ci, OTGSC_BSVIE | OTGSC_BSVIS, OTGSC_BSVIS); ci->vbus_active = 0; + + if (!IS_ERR(ci->platdata->usb_switch.mux)) + mux_control_deselect(ci->platdata->usb_switch.mux); } /** diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index c5fdfcf99828..559bd470b8c0 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -9,6 +9,7 @@ #include struct ci_hdrc; +struct mux_control; /** * struct ci_hdrc_cable - structure for external connector cable state tracking @@ -29,6 +30,18 @@ struct ci_hdrc_cable { struct notifier_block nb; }; +/** + * struct ci_hdrc_switch - structure for usb mux control + * @mux: mux to set @host state or @device state on during role switch + * @host: Value to set for mux to connect D+/D- to host D+/D- lines + * @device: Value to set for mux to connect D+/D- to device D+/D- lines + */ +struct ci_hdrc_switch { + struct mux_control *mux; + int host; + int device; +}; + struct ci_hdrc_platform_data { const char *name; /* offset of the capability registers */ @@ -74,6 +87,7 @@ struct ci_hdrc_platform_data { /* VBUS and ID signal state tracking, using extcon framework */ struct ci_hdrc_cable vbus_extcon; struct ci_hdrc_cable id_extcon; + struct ci_hdrc_switch usb_switch; u32 phy_clkgate_delay_us; };