From patchwork Wed Jul 8 09:45:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Ivan T. Ivanov" X-Patchwork-Id: 6743461 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: X-Original-To: patchwork-linux-arm-msm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 3C4EB9F2F0 for ; Wed, 8 Jul 2015 09:46:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 35B02207AE for ; Wed, 8 Jul 2015 09:46:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0FEE420791 for ; Wed, 8 Jul 2015 09:46:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934340AbbGHJqG (ORCPT ); Wed, 8 Jul 2015 05:46:06 -0400 Received: from mail-wi0-f180.google.com ([209.85.212.180]:34006 "EHLO mail-wi0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933711AbbGHJqD (ORCPT ); Wed, 8 Jul 2015 05:46:03 -0400 Received: by wifm2 with SMTP id m2so83863124wif.1 for ; Wed, 08 Jul 2015 02:46:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=lAS7m8mW6lB57dxyxb/JbcdLVHLjTTUhu7hg5e7vpMg=; b=O3ROea9T1D9twfHNgHlY32J1sggm4QodTnO6b9jX+ZKZHsXK9uGrzy6wTMV74QeGJO FWZGmbSrQMOWkNk40FvvZ/rFcxGbcWQeqxSsEtZs4pbj55mPxusCMbSfP3HabIJbVK+M qDhcOkF54YaOaPhp2MHHfvAQysJhSopJd4hkqiQsLVpjvmwSHCDFgWUB6n96D/yHwx4N F9ySX89BQHupzFHPDmsvx4Ret/ceBqkHN9jWYC8gmPgZz7hYNE9A/OXPleB6GyaWf9+0 uLQkf9z7jpCEhR0Sq9PXChXFofaBSBJ0iNG269V9MJ8D3AFYLJHJacmLxgIi2yqgQ7+K 8kQw== X-Gm-Message-State: ALoCoQlENmA8MdpQ3fEOXrYwTnvACYllezUTMcYsb630y+vFQqHI/6Hy9xb4NZ3GrWM4o6bhxEIK X-Received: by 10.180.9.38 with SMTP id w6mr6759090wia.57.1436348761251; Wed, 08 Jul 2015 02:46:01 -0700 (PDT) Received: from localhost.localdomain ([37.157.136.206]) by smtp.googlemail.com with ESMTPSA id u6sm2482376wja.40.2015.07.08.02.46.00 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 08 Jul 2015 02:46:00 -0700 (PDT) From: "Ivan T. Ivanov" To: Felipe Balbi Cc: Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , Greg Kroah-Hartman , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [PATCH] usb: phy: msm: Add D+/D- lines route control Date: Wed, 8 Jul 2015 12:45:54 +0300 Message-Id: <1436348754-6728-1-git-send-email-ivan.ivanov@linaro.org> X-Mailer: git-send-email 1.9.1 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP apq8016-sbc board is using Dual SPDT USB Switch (TC7USB40MU), witch is controlled by GPIO to de/multiplex D+/D- USB lines to USB2513B Hub and uB connector. Add support for this. Signed-off-by: Ivan T. Ivanov --- .../devicetree/bindings/usb/msm-hsusb.txt | 4 ++ drivers/usb/phy/phy-msm-usb.c | 47 ++++++++++++++++++++++ include/linux/usb/msm_hsusb.h | 7 ++++ 3 files changed, 58 insertions(+) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" 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/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt index bd8d9e7..8654a3e 100644 --- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt +++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt @@ -52,6 +52,10 @@ Required properties: Optional properties: - dr_mode: One of "host", "peripheral" or "otg". Defaults to "otg" +- switch-gpio: A phandle + gpio-specifier pair. Some boards are using Dual + SPDT USB Switch, witch is cotrolled by GPIO to de/multiplex + D+/D- USB lines between connectors. + - qcom,phy-init-sequence: PHY configuration sequence values. This is related to Device Mode Eye Diagram test. Start address at which these values will be written is ULPI_EXT_VENDOR_SPECIFIC. Value of -1 is reserved as diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 00c49bb..57c75fb 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include #include #include @@ -1471,6 +1473,14 @@ static int msm_otg_vbus_notifier(struct notifier_block *nb, unsigned long event, else clear_bit(B_SESS_VLD, &motg->inputs); + if (test_bit(B_SESS_VLD, &motg->inputs)) { + /* Switch D+/D- lines to Device connector */ + gpiod_set_value_cansleep(motg->switch_gpio, 0); + } else { + /* Switch D+/D- lines to Hub */ + gpiod_set_value_cansleep(motg->switch_gpio, 1); + } + schedule_work(&motg->sm_work); return NOTIFY_DONE; @@ -1546,6 +1556,11 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) motg->manual_pullup = of_property_read_bool(node, "qcom,manual-pullup"); + motg->switch_gpio = devm_gpiod_get_optional(&pdev->dev, "switch", + GPIOD_OUT_LOW); + if (IS_ERR(motg->switch_gpio)) + return PTR_ERR(motg->switch_gpio); + ext_id = ERR_PTR(-ENODEV); ext_vbus = ERR_PTR(-ENODEV); if (of_property_read_bool(node, "extcon")) { @@ -1615,6 +1630,19 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) return 0; } +static int msm_otg_reboot_notify(struct notifier_block *this, + unsigned long code, void *unused) +{ + struct msm_otg *motg = container_of(this, struct msm_otg, reboot); + + /* + * Ensure that D+/D- lines are routed to uB connector, so + * we could load bootloader/kernel at next reboot + */ + gpiod_set_value_cansleep(motg->switch_gpio, 0); + return NOTIFY_DONE; +} + static int msm_otg_probe(struct platform_device *pdev) { struct regulator_bulk_data regs[3]; @@ -1779,6 +1807,17 @@ static int msm_otg_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Can not create mode change file\n"); } + if (test_bit(B_SESS_VLD, &motg->inputs)) { + /* Switch D+/D- lines to Device connector */ + gpiod_set_value_cansleep(motg->switch_gpio, 0); + } else { + /* Switch D+/D- lines to Hub */ + gpiod_set_value_cansleep(motg->switch_gpio, 1); + } + + motg->reboot.notifier_call = msm_otg_reboot_notify; + register_reboot_notifier(&motg->reboot); + pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); @@ -1805,11 +1844,19 @@ static int msm_otg_remove(struct platform_device *pdev) if (phy->otg->host || phy->otg->gadget) return -EBUSY; + unregister_reboot_notifier(&motg->reboot); + if (motg->id.conn.edev) extcon_unregister_interest(&motg->id.conn); if (motg->vbus.conn.edev) extcon_unregister_interest(&motg->vbus.conn); + /* + * Ensure that D+/D- lines are routed to uB connector, so + * we could load bootloader/kernel at next reboot + */ + gpiod_set_value_cansleep(motg->switch_gpio, 0); + msm_otg_debugfs_cleanup(); cancel_delayed_work_sync(&motg->chg_work); cancel_work_sync(&motg->sm_work); diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h index e55a150..536a72c 100644 --- a/include/linux/usb/msm_hsusb.h +++ b/include/linux/usb/msm_hsusb.h @@ -155,6 +155,10 @@ struct msm_usb_cable { * starting controller using usbcmd run/stop bit. * @vbus: VBUS signal state trakining, using extcon framework * @id: ID signal state trakining, using extcon framework + * @switch_gpio: Descriptor for GPIO used to control external Dual + * SPDT USB Switch. + * @reboot: Used to inform the driver to route USB D+/D- line to Device + * connector */ struct msm_otg { struct usb_phy phy; @@ -188,6 +192,9 @@ struct msm_otg { struct msm_usb_cable vbus; struct msm_usb_cable id; + + struct gpio_desc *switch_gpio; + struct notifier_block reboot; }; #endif