From patchwork Tue Jun 27 14:59:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Cooper X-Patchwork-Id: 9812257 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B1BF860351 for ; Tue, 27 Jun 2017 15:03:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E68FA28111 for ; Tue, 27 Jun 2017 15:03:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DB3BA28401; Tue, 27 Jun 2017 15:03:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 487CD28111 for ; Tue, 27 Jun 2017 15:03:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=JPwUBA2ZMdrt+3AT/I1zlS5afBo3pzCWyQc4Luvp51I=; b=O8vBVEWBVEMlV6taPFerN5nlq3 UX31RLgx8u8B45GY+ptiMapJ8XqpNmOVrXNThrG46fZxkEV1PDPJ6VGi184N+5fqoFH155+lz3u5N 1yyFUcP07CL3QWuI0t+RxivpoZe5JbzJ1WhrpfWwXpYMfb9+mbL7c5QQ1fNpdpNL/qwnT+XFM+P0q pwhqbTK4zEV5rvEH8oNPtwqdMmPz1PhwFI6usx0keibrG21RqR6UFqfLKaXdD+zW66VYIzyOGysmB 6axWMSnasxHu2SuEfJPCVnnRvn4FOfpSxAHUH+35kXv/RJnKlxv72TmPDAc5bWFzlZEnAG2DPKzGC ZAJ5AKwg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dPs1N-00030K-CG; Tue, 27 Jun 2017 15:03:17 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dPs0e-0002CO-Cs for linux-arm-kernel@bombadil.infradead.org; Tue, 27 Jun 2017 15:02:32 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=Q46hXHd0nW2WRWXTAbpNAkaBsBtz2kyJP0xB1NZrA+4=; b=lkVjnXe8o5x8/N4rSwG6b6K7V ohrfBDbHjON3jW4cOyUUr3rEV3t51WL1DLL0nOyKR/X9X3pNk6P99gC1PWSqV5AdYdNQAx5u/hD+/ UdKtOWMsZCnqcU4l6x2G4I57oxc/7gmOzBWdaoSobHuVLLn1zISES8p0ZdRHajqF1w7ybwA7FB4xI B/WGihAkYrnlS35LqfCYERrtPVwqhgoAwoTACO3MokJdoTT7SotZXseTfcwDzIc7zPeA+5bZcM99f wHJnZyrSNzvoT+A/kEVGX3NpdjL4UOqV5ioFQTRFTbaguVyFmPZ5fJrL1R1mfJTQcTgbcM96AE0iG dW3UHeSNg==; Received: from lpdvrndsmtp01.broadcom.com ([192.19.229.170] helo=rnd-relay.smtp.broadcom.com) by merlin.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dPs0b-00060J-Jj for linux-arm-kernel@lists.infradead.org; Tue, 27 Jun 2017 15:02:30 +0000 Received: from mail-irv-17.broadcom.com (mail-irv-17.lvn.broadcom.net [10.75.224.233]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id BDBE730C011; Tue, 27 Jun 2017 08:02:05 -0700 (PDT) Received: from stbsrv-and-3.and.broadcom.com (stbsrv-and-3.and.broadcom.com [10.28.16.21]) by mail-irv-17.broadcom.com (Postfix) with ESMTP id 3059681EA6; Tue, 27 Jun 2017 08:02:04 -0700 (PDT) From: Al Cooper To: linux-kernel@vger.kernel.org Subject: [PATCH v3 4/4] phy: usb: phy-brcm-usb: Add ability to force DRD mode to host or device Date: Tue, 27 Jun 2017 10:59:13 -0400 Message-Id: <1498575553-19311-5-git-send-email-alcooperx@gmail.com> X-Mailer: git-send-email 1.9.0.138.g2de3478 In-Reply-To: <1498575553-19311-1-git-send-email-alcooperx@gmail.com> References: <1498575553-19311-1-git-send-email-alcooperx@gmail.com> X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , devicetree@vger.kernel.org, Florian Fainelli , Greg Kroah-Hartman , Al Cooper , Rob Herring , Kishon Vijay Abraham I , Al Cooper , bcm-kernel-feedback-list@broadcom.com, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Cooper When the usb phy device mode is set to "drd", the USB port will switch between device and host modes depending on what's plugged into the port. Customers have asked for the ability to force host or device mode from software. This commit adds sysfs entries to the phy device that allow this. The sysfs for the phy device can be found at: /sys/bus/platform/drivers/brcmstb-usb-phy/*.usb-phy The following sysfs entries were added: - "dr_mode" (RO) - The current phy "dr_mode" setting. It will be set to one of the following values: - "host" - host mode - "peripheral " - device mode - "drd" - switch between device and host mode based on installed device - "typec-pd" - device/host mode is controller by the USB Type-C PD protocol. If "dr_mode" is "drd" - "drd_select" (RW) - It will be set to one of the following values: - "host" - force host mode - "device" - force device mode - "auto" - allow normal auto selection of host/device based on inserted USB device Signed-off-by: Al Cooper --- drivers/phy/broadcom/phy-brcm-usb.c | 85 +++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c index cd18616..e30fde8 100644 --- a/drivers/phy/broadcom/phy-brcm-usb.c +++ b/drivers/phy/broadcom/phy-brcm-usb.c @@ -27,6 +27,8 @@ #include "phy-brcm-usb-init.h" +static DEFINE_MUTEX(sysfs_lock); + enum brcm_usb_phy_id { BRCM_USB_PHY_2_0 = 0, BRCM_USB_PHY_3_0, @@ -45,6 +47,12 @@ struct value_to_name_map { { USB_CTLR_MODE_TYPEC_PD, "typec-pd" } }; +static struct value_to_name_map brcm_dual_mode_to_name[] = { + { 0, "host" }, + { 1, "device" }, + { 2, "auto" }, +}; + struct brcm_usb_phy { struct phy *phy; unsigned int id; @@ -156,6 +164,73 @@ static int name_to_value(struct value_to_name_map *table, int count, return -EINVAL; } +static const char *value_to_name(struct value_to_name_map *table, int count, + int value) +{ + if (value >= count) + return "unknown"; + return table[value].name; +} + +static ssize_t dr_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct brcm_usb_phy_data *priv = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", + value_to_name(&brcm_dr_mode_to_name[0], + ARRAY_SIZE(brcm_dr_mode_to_name), + priv->ini.mode)); +} +static DEVICE_ATTR_RO(dr_mode); + +static ssize_t dual_select_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct brcm_usb_phy_data *priv = dev_get_drvdata(dev); + int value; + int res; + + mutex_lock(&sysfs_lock); + res = name_to_value(&brcm_dual_mode_to_name[0], + ARRAY_SIZE(brcm_dual_mode_to_name), buf, &value); + if (!res) { + brcm_usb_init_set_dual_select(&priv->ini, value); + res = len; + } + mutex_unlock(&sysfs_lock); + return res; +} + +static ssize_t dual_select_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct brcm_usb_phy_data *priv = dev_get_drvdata(dev); + int value; + + mutex_lock(&sysfs_lock); + value = brcm_usb_init_get_dual_select(&priv->ini); + mutex_unlock(&sysfs_lock); + return sprintf(buf, "%s\n", + value_to_name(&brcm_dual_mode_to_name[0], + ARRAY_SIZE(brcm_dual_mode_to_name), + value)); +} +static DEVICE_ATTR_RW(dual_select); + +static struct attribute *brcm_usb_phy_attrs[] = { + &dev_attr_dr_mode.attr, + &dev_attr_dual_select.attr, + NULL +}; + +static const struct attribute_group brcm_usb_phy_group = { + .attrs = brcm_usb_phy_attrs, +}; + static int brcm_usb_phy_probe(struct platform_device *pdev) { struct resource *res; @@ -262,6 +337,16 @@ static int brcm_usb_phy_probe(struct platform_device *pdev) brcm_usb_init_ipp(&priv->ini); + /* + * Create sysfs entries for mode. + * Remove "dual_select" attribute if not in dual mode + */ + if (priv->ini.mode != USB_CTLR_MODE_DRD) + brcm_usb_phy_attrs[1] = NULL; + err = sysfs_create_group(&dev->kobj, &brcm_usb_phy_group); + if (err) + dev_warn(&pdev->dev, "Error creating sysfs attributes\n"); + /* start with everything off */ if (priv->has_xhci) brcm_usb_uninit_xhci(&priv->ini);