lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 24 Sep 2013 15:46:05 +0200
From:	Paul Chavent <Paul.Chavent@...ra.fr>
To:	nsekhar@...com, khilman@...prootsystems.com,
	linux@....linux.org.uk,
	davinci-linux-open-source@...ux.davincidsp.com,
	linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org
Cc:	Paul Chavent <Paul.Chavent@...ra.fr>
Subject: [PATCH] ARM: davinci: usb: provide minimal support for da850.

As for the da830 and hawk boards, the da850 can provide minimalist usb
1.1 implementation. Moreover, this patch has only been tested with the
OHCI (on an OMAP L138 EVM / DA850 board), not with the Inventra HC
(that seems broken for the DA8XX).

This patch is inspired by the hawk board implementation.

Signed-off-by: Paul Chavent <paul.chavent@...ra.fr>
---
 arch/arm/mach-davinci/board-da850-evm.c | 153 ++++++++++++++++++++++++++++++++
 1 file changed, 153 insertions(+)

diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index dd1fb24..f0bee9d 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -62,6 +62,9 @@
 
 #define DA850_MII_MDIO_CLKEN_PIN	GPIO_TO_PIN(2, 6)
 
+#define DA850_USB1_VBUS_PIN		GPIO_TO_PIN(2, 4)
+#define DA850_USB1_OC_PIN		GPIO_TO_PIN(6, 13)
+
 static struct mtd_partition da850evm_spiflash_part[] = {
 	[0] = {
 		.name = "UBL",
@@ -1431,6 +1434,155 @@ static __init int da850_wl12xx_init(void)
 
 #endif /* CONFIG_DA850_WL12XX */
 
+#ifdef CONFIG_USB
+
+static irqreturn_t da850_usb_ocic_irq(int irq, void *dev_id);
+static da8xx_ocic_handler_t da850_usb_ocic_handler;
+
+static const short da850_usb11_pins[] = {
+	DA850_GPIO2_4, DA850_GPIO6_13,
+	-1
+};
+
+static int da850_usb_set_power(unsigned port, int on)
+{
+	gpio_set_value(DA850_USB1_VBUS_PIN, on);
+	return 0;
+}
+
+static int da850_usb_get_power(unsigned port)
+{
+	return gpio_get_value(DA850_USB1_VBUS_PIN);
+}
+
+static int da850_usb_get_oci(unsigned port)
+{
+	return !gpio_get_value(DA850_USB1_OC_PIN);
+}
+
+static int da850_usb_ocic_notify(da8xx_ocic_handler_t handler)
+{
+	int irq         = gpio_to_irq(DA850_USB1_OC_PIN);
+	int error       = 0;
+
+	if (handler != NULL) {
+		da850_usb_ocic_handler = handler;
+
+		error = request_irq(irq, da850_usb_ocic_irq,
+					IRQF_DISABLED | IRQF_TRIGGER_RISING |
+					IRQF_TRIGGER_FALLING,
+					"OHCI over-current indicator", NULL);
+		if (error)
+			pr_err("%s: could not request IRQ to watch "
+				"over-current indicator changes\n", __func__);
+	} else {
+		free_irq(irq, NULL);
+	}
+	return error;
+}
+
+static struct da8xx_ohci_root_hub da850_usb11_pdata = {
+	.set_power      = da850_usb_set_power,
+	.get_power      = da850_usb_get_power,
+	.get_oci        = da850_usb_get_oci,
+	.ocic_notify    = da850_usb_ocic_notify,
+	/* TPS2087 switch @ 5V */
+	.potpgt         = (3 + 1) / 2,  /* 3 ms max */
+};
+
+static irqreturn_t da850_usb_ocic_irq(int irq, void *dev_id)
+{
+	da850_usb_ocic_handler(&da850_usb11_pdata, 1);
+	return IRQ_HANDLED;
+}
+
+static __init void da850_usb_init(void)
+{
+	void __iomem *cfg_chip2_base;
+	int ret;
+	u32 val;
+
+	/*
+	 * Set up USB clock/mode in the CFGCHIP2 register.
+	 */
+
+	cfg_chip2_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG);
+
+	val = __raw_readl(cfg_chip2_base);
+
+	/* USB2.0 PHY reference clock is 24 MHz */
+	val &= ~CFGCHIP2_REFFREQ;
+	val |=  CFGCHIP2_REFFREQ_24MHZ;
+
+	/*
+	 * Select internal reference clock for USB 2.0 PHY
+	 * and use it as a clock source for USB 1.1 PHY
+	 * (this is the default setting anyway).
+	 */
+	 val &= ~CFGCHIP2_USB1PHYCLKMUX;
+	 val |=  CFGCHIP2_USB2PHYCLKMUX;
+
+	/*
+	 * We have to override VBUS/ID signals when MUSB is configured into the
+	 * host-only mode -- ID pin will float if no cable is connected, so the
+	 * controller won't be able to drive VBUS thinking that it's a B-device.
+	 * Otherwise, we want to use the OTG mode and enable VBUS comparators.
+	 */
+	val &= ~CFGCHIP2_OTGMODE;
+#ifdef	CONFIG_USB_MUSB_HOST
+	val |=  CFGCHIP2_FORCE_HOST;
+#else
+	val |=  CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN;
+#endif
+
+	/* configure the CFGCHIP2 register */
+	__raw_writel(val, cfg_chip2_base);
+
+	ret = davinci_cfg_reg_list(da850_usb11_pins);
+	if (ret) {
+		pr_warn("%s: USB 1.1 PinMux setup failed: %d\n", __func__, ret);
+		return;
+	}
+
+	ret = gpio_request_one(DA850_USB1_VBUS_PIN,
+			GPIOF_DIR_OUT, "USB1 VBUS");
+	if (ret < 0) {
+		pr_err("%s: failed to request GPIO for USB 1.1 port "
+			"power control: %d\n", __func__, ret);
+		return;
+	}
+
+	ret = gpio_request_one(DA850_USB1_OC_PIN,
+			GPIOF_DIR_IN, "USB1 OC");
+	if (ret < 0) {
+		pr_err("%s: failed to request GPIO for USB 1.1 port "
+			"over-current indicator: %d\n", __func__, ret);
+		goto usb11_setup_oc_fail;
+	}
+
+	ret = da8xx_register_usb11(&da850_usb11_pdata);
+	if (ret) {
+		pr_warn("%s: USB 1.1 registration failed: %d\n", __func__, ret);
+		goto usb11_setup_fail;
+	}
+
+	return;
+
+usb11_setup_fail:
+	gpio_free(DA850_USB1_OC_PIN);
+usb11_setup_oc_fail:
+	gpio_free(DA850_USB1_VBUS_PIN);
+}
+
+#else /* CONFIG_USB */
+
+static __init void da850_usb_init(void)
+{
+	return 0;
+}
+
+#endif /* CONFIG_USB */
+
 #define DA850EVM_SATA_REFCLKPN_RATE	(100 * 1000 * 1000)
 
 static __init void da850_evm_init(void)
@@ -1453,6 +1605,7 @@ static __init void da850_evm_init(void)
 	if (ret)
 		pr_warn("%s: I2C0 registration failed: %d\n", __func__, ret);
 
+	da850_usb_init();
 
 	ret = da8xx_register_watchdog();
 	if (ret)
-- 
1.7.12.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ