summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/board-colibri_t30.c
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2012-11-27 14:14:28 +0100
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2012-11-27 14:14:28 +0100
commitd0e6263f20cc9295eb746eebe2024f67d7e8e80e (patch)
treee49cb52244a0a8269ab61857c95812321e0bbcb6 /arch/arm/mach-tegra/board-colibri_t30.c
parent967cc9459883fad434ae199fdfd575fcfd89568b (diff)
colibri_t30: usb: integrate otg functionality
Integrate USB OTG functionality similar to Colibri T20.
Diffstat (limited to 'arch/arm/mach-tegra/board-colibri_t30.c')
-rw-r--r--arch/arm/mach-tegra/board-colibri_t30.c258
1 files changed, 162 insertions, 96 deletions
diff --git a/arch/arm/mach-tegra/board-colibri_t30.c b/arch/arm/mach-tegra/board-colibri_t30.c
index 2caced721226..4f8a182ea237 100644
--- a/arch/arm/mach-tegra/board-colibri_t30.c
+++ b/arch/arm/mach-tegra/board-colibri_t30.c
@@ -22,6 +22,7 @@
#include <asm/mach-types.h>
#include <linux/clk.h>
+#include <linux/colibri_usb.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
@@ -67,6 +68,9 @@
#define ETHERNET_VBUS_GPIO TEGRA_GPIO_PDD2
#define ETHERNET_RESET_GPIO TEGRA_GPIO_PDD0
+#define USB_CABLE_DETECT_GPIO TEGRA_GPIO_PK5 /* USBC_DET */
+#define USB_HOST_POWER_GPIO TEGRA_GPIO_PW2 /* USBH_PEN */
+
/* Audio */
static struct tegra_asoc_platform_data colibri_t30_audio_sgtl5000_pdata = {
@@ -533,126 +537,192 @@ static void __init colibri_t30_uart_init(void)
/* USB */
-#if defined(CONFIG_USB_SUPPORT)
-#if 0
-static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = {
- .port_otg = true,
- .has_hostpc = true,
- .phy_intf = TEGRA_USB_PHY_INTF_UTMI,
- .op_mode = TEGRA_USB_OPMODE_HOST,
- .u_data.host = {
- .vbus_gpio = -1,
- .vbus_reg = "vdd_vbus_micro_usb",
- .hot_plug = true,
- .remote_wakeup_supported = true,
- .power_off_on_suspend = true,
- },
+static struct tegra_usb_platform_data tegra_udc_pdata = {
+ .has_hostpc = true,
+ .op_mode = TEGRA_USB_OPMODE_DEVICE,
+ .phy_intf = TEGRA_USB_PHY_INTF_UTMI,
+ .port_otg = true,
.u_cfg.utmi = {
- .hssync_start_delay = 0,
- .elastic_limit = 16,
- .idle_wait_delay = 17,
- .term_range_adj = 6,
- .xcvr_setup = 15,
- .xcvr_lsfslew = 2,
- .xcvr_lsrslew = 2,
- .xcvr_setup_offset = 0,
- .xcvr_use_fuses = 1,
+ .elastic_limit = 16,
+ .hssync_start_delay = 0,
+ .idle_wait_delay = 17,
+ .term_range_adj = 6,
+ .xcvr_lsfslew = 2,
+ .xcvr_lsrslew = 2,
+ .xcvr_setup = 8,
+ .xcvr_setup_offset = 0,
+ .xcvr_use_fuses = 1,
+ },
+ .u_data.dev = {
+ .charging_supported = false,
+ .remote_wakeup_supported = false,
+ .vbus_gpio = -1,
+ .vbus_pmu_irq = 0,
},
};
-#endif
-static struct tegra_usb_platform_data tegra_ehci2_utmi_pdata = {
- .port_otg = false,
- .has_hostpc = true,
- .phy_intf = TEGRA_USB_PHY_INTF_UTMI,
- .op_mode = TEGRA_USB_OPMODE_HOST,
- .u_data.host = {
- .vbus_gpio = -1,
- .hot_plug = false,
- .remote_wakeup_supported = true,
- .power_off_on_suspend = true,
- },
+static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = {
+ .has_hostpc = true,
+ .op_mode = TEGRA_USB_OPMODE_HOST,
+ .phy_intf = TEGRA_USB_PHY_INTF_UTMI,
+ .port_otg = true,
.u_cfg.utmi = {
- .hssync_start_delay = 0,
- .elastic_limit = 16,
- .idle_wait_delay = 17,
- .term_range_adj = 6,
- .xcvr_setup = 15,
- .xcvr_lsfslew = 2,
- .xcvr_lsrslew = 2,
- .xcvr_setup_offset = 0,
- .xcvr_use_fuses = 1,
+ .elastic_limit = 16,
+ .hssync_start_delay = 0,
+ .idle_wait_delay = 17,
+ .term_range_adj = 6,
+ .xcvr_lsfslew = 2,
+ .xcvr_lsrslew = 2,
+ .xcvr_setup = 15,
+ .xcvr_setup_offset = 0,
+ .xcvr_use_fuses = 1,
},
-};
-
-static struct tegra_usb_platform_data tegra_ehci3_utmi_pdata = {
- .port_otg = false,
- .has_hostpc = true,
- .phy_intf = TEGRA_USB_PHY_INTF_UTMI,
- .op_mode = TEGRA_USB_OPMODE_HOST,
.u_data.host = {
- .vbus_gpio = TEGRA_GPIO_PW2, /* USBH_PEN */
- .vbus_gpio_inverted = 1,
-// .vbus_reg = NULL,
-// .vbus_reg = "vdd_vbus_typea_usb",
- .hot_plug = true,
- .remote_wakeup_supported = true,
- .power_off_on_suspend = true,
+ .hot_plug = true,
+ .power_off_on_suspend = true,
+ .remote_wakeup_supported = true,
+ .vbus_gpio = -1,
+ .vbus_reg = NULL,
},
+};
+
+static struct tegra_usb_platform_data tegra_ehci2_utmi_pdata = {
+ .has_hostpc = true,
+ .op_mode = TEGRA_USB_OPMODE_HOST,
+ .phy_intf = TEGRA_USB_PHY_INTF_UTMI,
+ .port_otg = false,
.u_cfg.utmi = {
- .hssync_start_delay = 0,
- .elastic_limit = 16,
- .idle_wait_delay = 17,
- .term_range_adj = 6,
- .xcvr_setup = 8,
- .xcvr_lsfslew = 2,
- .xcvr_lsrslew = 2,
- .xcvr_setup_offset = 0,
- .xcvr_use_fuses = 1,
+ .elastic_limit = 16,
+ .hssync_start_delay = 0,
+ .idle_wait_delay = 17,
+ .term_range_adj = 6,
+ .xcvr_lsfslew = 2,
+ .xcvr_lsrslew = 2,
+ .xcvr_setup = 15,
+ .xcvr_setup_offset = 0,
+ .xcvr_use_fuses = 1,
+ },
+ .u_data.host = {
+ .hot_plug = false,
+ .power_off_on_suspend = true,
+ .remote_wakeup_supported = true,
+ .vbus_gpio = -1,
+ .vbus_reg = NULL,
},
};
-#if 0
-static struct tegra_usb_platform_data tegra_udc_pdata = {
- .port_otg = true,
- .has_hostpc = true,
- .phy_intf = TEGRA_USB_PHY_INTF_UTMI,
- .op_mode = TEGRA_USB_OPMODE_DEVICE,
- .u_data.dev = {
- .vbus_pmu_irq = 0,
- .vbus_gpio = -1,
- .charging_supported = false,
- .remote_wakeup_supported = false,
- },
+static struct tegra_usb_platform_data tegra_ehci3_utmi_pdata = {
+ .has_hostpc = true,
+ .op_mode = TEGRA_USB_OPMODE_HOST,
+ .phy_intf = TEGRA_USB_PHY_INTF_UTMI,
+ .port_otg = false,
.u_cfg.utmi = {
- .hssync_start_delay = 0,
- .elastic_limit = 16,
- .idle_wait_delay = 17,
- .term_range_adj = 6,
- .xcvr_setup = 8,
- .xcvr_lsfslew = 2,
- .xcvr_lsrslew = 2,
- .xcvr_setup_offset = 0,
- .xcvr_use_fuses = 1,
+ .elastic_limit = 16,
+ .hssync_start_delay = 0,
+ .idle_wait_delay = 17,
+ .term_range_adj = 6,
+ .xcvr_lsfslew = 2,
+ .xcvr_lsrslew = 2,
+ .xcvr_setup = 8,
+ .xcvr_setup_offset = 0,
+ .xcvr_use_fuses = 1,
+ },
+ .u_data.host = {
+ .hot_plug = true,
+ .power_off_on_suspend = true,
+ .remote_wakeup_supported = true,
+ .vbus_gpio = USB_HOST_POWER_GPIO, /* USBH_PEN */
+ .vbus_gpio_inverted = 1,
+ .vbus_reg = NULL,
},
};
+#ifndef CONFIG_USB_TEGRA_OTG
+static struct platform_device *tegra_usb_otg_host_register(void)
+{
+ struct platform_device *pdev;
+ void *platform_data;
+ int val;
+
+ pdev = platform_device_alloc(tegra_ehci1_device.name,
+ tegra_ehci1_device.id);
+ if (!pdev)
+ return NULL;
+
+ val = platform_device_add_resources(pdev, tegra_ehci1_device.resource,
+ tegra_ehci1_device.num_resources);
+ if (val)
+ goto error;
+
+ pdev->dev.dma_mask = tegra_ehci1_device.dev.dma_mask;
+ pdev->dev.coherent_dma_mask = tegra_ehci1_device.dev.coherent_dma_mask;
+
+ platform_data = kmalloc(sizeof(struct tegra_usb_platform_data),
+ GFP_KERNEL);
+ if (!platform_data)
+ goto error;
+
+ memcpy(platform_data, &tegra_ehci1_utmi_pdata,
+ sizeof(struct tegra_usb_platform_data));
+ pdev->dev.platform_data = platform_data;
+
+ val = platform_device_add(pdev);
+ if (val)
+ goto error_add;
+
+ return pdev;
+
+error_add:
+ kfree(platform_data);
+error:
+ pr_err("%s: failed to add the host controller device\n", __func__);
+ platform_device_put(pdev);
+ return NULL;
+}
+
+static void tegra_usb_otg_host_unregister(struct platform_device *pdev)
+{
+ kfree(pdev->dev.platform_data);
+ pdev->dev.platform_data = NULL;
+ platform_device_unregister(pdev);
+}
+
+static struct colibri_otg_platform_data colibri_otg_pdata = {
+ .cable_detect_gpio = USB_CABLE_DETECT_GPIO,
+ .host_register = &tegra_usb_otg_host_register,
+ .host_unregister = &tegra_usb_otg_host_unregister,
+};
+#else /* !CONFIG_USB_TEGRA_OTG */
static struct tegra_usb_otg_data tegra_otg_pdata = {
.ehci_device = &tegra_ehci1_device,
.ehci_pdata = &tegra_ehci1_utmi_pdata,
};
-#endif
+#endif /* !CONFIG_USB_TEGRA_OTG */
+
+#ifndef CONFIG_USB_TEGRA_OTG
+struct platform_device colibri_otg_device = {
+ .name = "colibri-otg",
+ .id = -1,
+ .dev = {
+ .platform_data = &colibri_otg_pdata,
+ },
+};
+#endif /* !CONFIG_USB_TEGRA_OTG */
static void colibri_t30_usb_init(void)
{
-#if 0
- /* OTG should be the first to be registered */
+ /* OTG should be the first to be registered
+ EHCI instance 0: USB1_DP/N -> USBOTG_P/N */
+#ifndef CONFIG_USB_TEGRA_OTG
+ platform_device_register(&colibri_otg_device);
+#else /* !CONFIG_USB_TEGRA_OTG */
tegra_otg_device.dev.platform_data = &tegra_otg_pdata;
platform_device_register(&tegra_otg_device);
+#endif /* !CONFIG_USB_TEGRA_OTG */
/* setup the udc platform data */
tegra_udc_device.dev.platform_data = &tegra_udc_pdata;
-#endif
+ platform_device_register(&tegra_udc_device);
/* EHCI instance 1: ASIX ETH */
tegra_ehci2_device.dev.platform_data = &tegra_ehci2_utmi_pdata;
@@ -662,16 +732,12 @@ static void colibri_t30_usb_init(void)
tegra_ehci3_device.dev.platform_data = &tegra_ehci3_utmi_pdata;
platform_device_register(&tegra_ehci3_device);
}
-#else /* CONFIG_USB_SUPPORT */
-static inline void colibri_t30_usb_init(void) { }
-#endif /* CONFIG_USB_SUPPORT */
static struct platform_device *colibri_t30_devices[] __initdata = {
&tegra_pmu_device,
#if defined(CONFIG_RTC_DRV_TEGRA)
&tegra_rtc_device,
#endif
- &tegra_udc_device,
#if defined(CONFIG_TEGRA_IOVMM_SMMU) || defined(CONFIG_TEGRA_IOMMU_SMMU)
&tegra_smmu_device,
#endif