From patchwork Mon Feb 24 09:30:03 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Barinov X-Patchwork-Id: 3707881 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BE699BF13A for ; Mon, 24 Feb 2014 09:30:50 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BC5CF20154 for ; Mon, 24 Feb 2014 09:30:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AF18020149 for ; Mon, 24 Feb 2014 09:30:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751595AbaBXJar (ORCPT ); Mon, 24 Feb 2014 04:30:47 -0500 Received: from mail-la0-f53.google.com ([209.85.215.53]:53560 "EHLO mail-la0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752074AbaBXJaN (ORCPT ); Mon, 24 Feb 2014 04:30:13 -0500 Received: by mail-la0-f53.google.com with SMTP id e16so5345820lan.12 for ; Mon, 24 Feb 2014 01:30:12 -0800 (PST) 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:in-reply-to :references; bh=PT/fl4k3pESfbIHGCnRTH2dh37TtMjuqRaEbh5e3EWI=; b=AboXzUb/2uX5b9OOGUsW6tPYRRvySKnj5x/YSMG6rbWh76T6+wAO0Z6Me6uO9gIDIx 0sejXHZG+znPk28Ll8JM5LGgDkt1sdj7SZhlZ4AGouK/nxFFQHY8NqCYf/9/E85rkVrD NCc8fQJiHEr81uD5edkCwGNelQH7i5PIG3/L0btmv0KMn7H2QenCupRf/ITv7tpfU+bv /ip6zYY6q9Sgdx1yP/cTq5LVkoDJwcPX5W5600NRJdW9drq/cp6decUAkY01hIOdvjfk QSNEPEqEu83/qqGXFwIocJ0fZ0SjFcyYnukbvCTiPak/JGoee6/uRdPHwrgUEVlYycTd SoXQ== X-Gm-Message-State: ALoCoQmHTKccfYK/WZXku+Ui03D4+gsqhuo4gCv7sA/vGvhWCwmLgGaEL/fEadt9YEwSZk0OTvPx X-Received: by 10.153.11.129 with SMTP id ei1mr11424202lad.78.1393234212007; Mon, 24 Feb 2014 01:30:12 -0800 (PST) Received: from localhost.localdomain ([46.32.73.80]) by mx.google.com with ESMTPSA id qx7sm17976619lbb.9.2014.02.24.01.30.10 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 24 Feb 2014 01:30:11 -0800 (PST) From: To: Cc: , linux-gpio@vger.kernel.org, , , , , , Subject: [PATCH V5 3/4] ARM: shmobile: koelsch: Add USBHS and internal PCI USB support Date: Mon, 24 Feb 2014 13:30:03 +0400 Message-Id: <1393234204-24096-4-git-send-email-vladimir.barinov@cogentembedded.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1393234204-24096-1-git-send-email-vladimir.barinov@cogentembedded.com> References: <1393234204-24096-1-git-send-email-vladimir.barinov@cogentembedded.com> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 From: Valentine Barshak This adds the following to R-Car M2 Koelsch board: - USBHS PHY - USBHS device in usb0 - internal PCI USB host device on usb1 USBHS is configured for usb0 and cable id is checked at probe. USB PCI is configured for usb1. The USB phy is bound to ether USB host or USBHS device respectively, hence configured to ether channel 0 or 2 for usb0 and usb1. Signed-off-by: Valentine Barshak Signed-off-by: Vladimir Barinov Changes in V5: * get rid from PCI USB on usb0 * moved MAX3355E ID pin check in usbhs probe Changes in V4: * folded USBHS and internal PCI USB related patches together * added handling of ID pin from MAX3355E chip * removed ifdefs Changes in V3: * fixed a typo in the log message; * fixed the USB1 device name in the pinmux table. Changes in V2: * capitalized ARM in the subject; * rebased on top the latest devel tag; * added pipe_type array to the usbhs platform info since it differs from the default. * capitalized ARM in the subject; * rebased on top the latest devel tag. --- arch/arm/mach-shmobile/board-koelsch.c | 172 +++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: build/arch/arm/mach-shmobile/board-koelsch.c =================================================================== --- build.orig/arch/arm/mach-shmobile/board-koelsch.c 2014-02-24 11:48:43.221536471 +0400 +++ build/arch/arm/mach-shmobile/board-koelsch.c 2014-02-24 12:14:30.933504710 +0400 @@ -36,12 +36,15 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include #include #include #include @@ -367,6 +370,168 @@ DEFINE_RES_IRQ(gic_spi(168)), }; +/* USBHS */ +static const struct resource usbhs_resources[] __initconst = { + DEFINE_RES_MEM(0xe6590000, 0x100), + DEFINE_RES_IRQ(gic_spi(107)), +}; + +struct usbhs_private { + struct renesas_usbhs_platform_info info; + struct usb_phy *phy; +}; + +#define usbhs_get_priv(pdev) \ + container_of(renesas_usbhs_get_info(pdev), struct usbhs_private, info) + +static int usbhs_power_ctrl(struct platform_device *pdev, + void __iomem *base, int enable) +{ + struct usbhs_private *priv = usbhs_get_priv(pdev); + + if (!priv->phy) + return -ENODEV; + + if (enable) { + int retval = usb_phy_init(priv->phy); + + if (!retval) + retval = usb_phy_set_suspend(priv->phy, 0); + return retval; + } + + usb_phy_set_suspend(priv->phy, 1); + usb_phy_shutdown(priv->phy); + return 0; +} + +static int usbhs_hardware_init(struct platform_device *pdev) +{ + struct usbhs_private *priv = usbhs_get_priv(pdev); + struct usb_phy *phy; + int ret; + + /* Check MAX3355E ID pin */ + gpio_request_one(RCAR_GP_PIN(5, 31), GPIOF_IN, NULL); + if (!gpio_get_value(RCAR_GP_PIN(5, 31))) { + pr_warn("Error: USB0 cable selects host mode\n"); + ret = -ENOTSUPP; + goto error; + } + + phy = usb_get_phy_dev(&pdev->dev, 0); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + priv->phy = phy; + return 0; + +error: + gpio_free(RCAR_GP_PIN(5, 31)); + return ret; +} + +static int usbhs_hardware_exit(struct platform_device *pdev) +{ + struct usbhs_private *priv = usbhs_get_priv(pdev); + + if (!priv->phy) + return 0; + + usb_put_phy(priv->phy); + priv->phy = NULL; + + gpio_free(RCAR_GP_PIN(5, 31)); + return 0; +} + +static int usbhs_get_id(struct platform_device *pdev) +{ + return USBHS_GADGET; +} + +static u32 koelsch_usbhs_pipe_type[] = { + USB_ENDPOINT_XFER_CONTROL, + USB_ENDPOINT_XFER_ISOC, + USB_ENDPOINT_XFER_ISOC, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, +}; + +static struct usbhs_private usbhs_priv __initdata = { + .info = { + .platform_callback = { + .power_ctrl = usbhs_power_ctrl, + .hardware_init = usbhs_hardware_init, + .hardware_exit = usbhs_hardware_exit, + .get_id = usbhs_get_id, + }, + .driver_param = { + .buswait_bwait = 4, + .pipe_type = koelsch_usbhs_pipe_type, + .pipe_size = ARRAY_SIZE(koelsch_usbhs_pipe_type), + }, + } +}; + +static void __init koelsch_add_usb0_gadget(void) +{ + usb_bind_phy("renesas_usbhs", 0, "usb_phy_rcar_gen2"); + platform_device_register_resndata(&platform_bus, + "renesas_usbhs", -1, + usbhs_resources, + ARRAY_SIZE(usbhs_resources), + &usbhs_priv.info, + sizeof(usbhs_priv.info)); +} + +/* Internal PCI1 */ +static const struct resource pci1_resources[] __initconst = { + DEFINE_RES_MEM(0xee0d0000, 0x10000), /* CFG */ + DEFINE_RES_MEM(0xee0c0000, 0x10000), /* MEM */ + DEFINE_RES_IRQ(gic_spi(113)), +}; + +static void __init koelsch_add_usb1_host(void) +{ + platform_device_register_simple("pci-rcar-gen2", + 1, pci1_resources, + ARRAY_SIZE(pci1_resources)); +} + +/* USBHS PHY */ +static const struct rcar_gen2_phy_platform_data usbhs_phy_pdata __initconst = { + .chan0_pci = 0, /* Channel 0 is USBHS */ + .chan2_pci = 1, /* Channel 2 is PCI USB host */ +}; + +static const struct resource usbhs_phy_resources[] __initconst = { + DEFINE_RES_MEM(0xe6590100, 0x100), +}; + +/* Add all available USB devices */ +static void __init koelsch_add_usb_devices(void) +{ + platform_device_register_resndata(&platform_bus, "usb_phy_rcar_gen2", + -1, usbhs_phy_resources, + ARRAY_SIZE(usbhs_phy_resources), + &usbhs_phy_pdata, + sizeof(usbhs_phy_pdata)); + koelsch_add_usb0_gadget(); + koelsch_add_usb1_host(); +} + static const struct pinctrl_map koelsch_pinctrl_map[] = { /* DU */ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7791", "pfc-r8a7791", @@ -429,6 +594,12 @@ "sdhi2_ctrl", "sdhi2"), PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7791", "sdhi2_cd", "sdhi2"), + /* USB0 */ + PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-r8a7791", + "usb0", "usb0"), + /* USB1 */ + PIN_MAP_MUX_GROUP_DEFAULT("pci-rcar-gen2.1", "pfc-r8a7791", + "usb1", "usb1"), }; static void __init koelsch_add_standard_devices(void) @@ -485,6 +656,7 @@ sdhi2_resources, ARRAY_SIZE(sdhi2_resources), &sdhi2_info, sizeof(struct sh_mobile_sdhi_info)); + koelsch_add_usb_devices(); } /*