Skip to contentSkip to conversation

usb: otg: Adding twl6030-usb transceiver driver for

PATCH Superseded Hema HK 2 participants 4 messages Dec 8, 2010 2 messages not in the archive

Subsystems (4)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Hema HK

author
#0 lore raw

PATCH 2/7 usb: otg: Adding twl6030-usb transceiver driver for

Adding the twl6030-usb transceiver support for OMAP4 musb driver.

OMAP4 supports 2 types of transceiver interface.

1. UTMI: The PHY is embedded within OMAP4. The transceiver functionality is split between the twl6030 PMIC chip and OMAP4430. The VBUS, ID pin sensing and OTG SRP generation part is integrated in TWL6030 and UTMI PHY functionality is embedded within the OMAP4430.

There is no direct interactions between the MUSB controller and TWL6030 chip to communicate the session-valid, session-end and ID-GND events. It has to be done through a software by setting/resetting bits in one of the control module register of OMAP4430 which in turn toggles the appropriate signals to MUSB controller.

The internal transceiver has functional clocks and powerdown bits to powerdown the PHY for power saving.

Since there is no option available for having 2 transceiver drivers for one USB controller, internal PHY specific APIs are passed through plaform_data function pointers to use in the twl6030-usb transceiver driver.

2. ULPI interface is provided for off-chip transceivers.

Cc Felipe Balbi <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc David Brownell <[email protected]>
---
 arch/arm/mach-omap2/omap_phy_internal.c |  133 ++++++++
 arch/arm/plat-omap/include/plat/usb.h   |    4 
 drivers/usb/otg/Makefile                |    1 
 drivers/usb/otg/twl6030-usb.c           |  514 ++++++++++++++++++++++++++++++++
 4 files changed, 652 insertions(+)
arch/arm/mach-omap2/omap_phy_internal.c new file +148 -0
Index: linux-2.6/arch/arm/mach-omap2/omap_phy_internal.c
===================================================================
@@ -0,0 +1,148 @@
+/*
+  * This file configures the internal USB PHY in OMAP4430. Used
+  * with TWL6030 transceiver and MUSB on OMAP4430.
+  *
+  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  *Author: Hema HK <[email protected]>
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/usb.h>
+
+#include <plat/usb.h>
+
+/* OMAP control module register for UTMI PHY */
+#define CONTROL_DEV_CONF		0x300
+#define PHY_PD				0x1
+
+#define USBOTGHS_CONTROL		0x33c
+#define	AVALID				BIT(0)
+#define	BVALID				BIT(1)
+#define	VBUSVALID			BIT(2)
+#define	SESSEND				BIT(3)
+#define	IDDIG				BIT(4)
+
+static struct clk *phyclk, *clk48m, *clk32k;
+static void __iomem *ctrl_base;
+
+int omap4430_phy_init(struct device *dev)
+{
+	ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K);
+	if (!ctrl_base) {
+		dev_err(dev, "control module ioremap failed\n");
+		return -ENOMEM;
+	}
+	/* Power down the phy */
+	__raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+	phyclk = clk_get(dev, "ocp2scp_usb_phy_ick");
+
+	if (IS_ERR(phyclk)) {
+		dev_err(dev, "cannot clk_get ocp2scp_usb_phy_ick\n");
+		iounmap(ctrl_base);
+		return PTR_ERR(phyclk);
+	}
+
+	clk48m = clk_get(dev, "ocp2scp_usb_phy_phy_48m");
+	if (IS_ERR(clk48m)) {
+		dev_err(dev, "cannot clk_get ocp2scp_usb_phy_phy_48m\n");
+		clk_put(phyclk);
+		iounmap(ctrl_base);
+		return PTR_ERR(clk48m);
+	}
+
+	clk32k = clk_get(dev, "usb_phy_cm_clk32k");
+	if (IS_ERR(clk32k)) {
+		dev_err(dev, "cannot clk_get usb_phy_cm_clk32k\n");
+		clk_put(phyclk);
+		clk_put(clk48m);
+		iounmap(ctrl_base);
+		return PTR_ERR(clk32k);
+	}
+	return 0;
+}
+
+int omap4430_phy_set_clk(struct device *dev, int on)
+{
+	static int state;
+
+	if (on && !state) {
+		/* Enable the phy clocks */
+		clk_enable(phyclk);
+		clk_enable(clk48m);
+		clk_enable(clk32k);
+		state = 1;
+	} else if (state) {
+		/* Disable the phy clocks */
+		clk_disable(phyclk);
+		clk_disable(clk48m);
+		clk_disable(clk32k);
+		state = 0;
+	}
+	return 0;
+}
+
+int omap4430_phy_power(struct device *dev, int ID, int on)
+{
+	if (on) {
+		/* enabled the clocks */
+		omap4430_phy_set_clk(dev, 1);
+		/* power on the phy */
+		if (__raw_readl(ctrl_base + CONTROL_DEV_CONF) & PHY_PD) {
+			__raw_writel(~PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+			mdelay(200);
+		}
+		if (ID)
+			/* enable VBUS valid, IDDIG groung */
+			__raw_writel(AVALID | VBUSVALID, ctrl_base +
+							USBOTGHS_CONTROL);
+		else
+			/*
+			 * Enable VBUS Valid, AValid and IDDIG
+			 * high impedence
+			 */
+			__raw_writel(IDDIG | AVALID | VBUSVALID,
+						ctrl_base + USBOTGHS_CONTROL);
+	} else {
+		/* Enable session END and IDIG to high impedence. */
+		__raw_writel(SESSEND | IDDIG, ctrl_base +
+					USBOTGHS_CONTROL);
+		/* Disable the clocks */
+		omap4430_phy_set_clk(dev, 0);
+		/* Power down the phy */
+		__raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+	}
+
+	return 0;
+}
+
+int omap4430_phy_exit(struct device *dev)
+{
+	if (ctrl_base)
+		iounmap(ctrl_base);
+	if (phyclk)
+		clk_put(phyclk);
+	if (clk48m)
+		clk_put(clk48m);
+	if (clk32k)
+		clk_put(clk32k);
+

+ return 0;
+}
+
+

arch/arm/plat-omap/include/plat/usb.h +6 -0
Index: linux-2.6/arch/arm/plat-omap/include/plat/usb.h
===================================================================
@@ -79,6 +79,12 @@ extern void usb_ehci_init(const struct e
 
 extern void usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata);
 
+extern int omap4430_phy_power(struct device *dev, int ID, int on);
+extern int omap4430_phy_set_clk(struct device *dev, int on);
+extern int omap4430_phy_init(struct device *dev);
+extern int omap4430_phy_exit(struct device *dev);
+
+
 #endif
 
 
drivers/usb/otg/twl6030-usb.c new file +520 -0

520 lines not on this page · raw message

drivers/usb/otg/Makefile +1 -0
Index: linux-2.6/drivers/usb/otg/Makefile
===================================================================
@@ -12,6 +12,7 @@ obj-$(CONFIG_USB_OTG_UTILS)	+= otg.o
 obj-$(CONFIG_USB_GPIO_VBUS)	+= gpio_vbus.o
 obj-$(CONFIG_ISP1301_OMAP)	+= isp1301_omap.o
 obj-$(CONFIG_TWL4030_USB)	+= twl4030-usb.o
+obj-$(CONFIG_TWL6030_USB)	+= twl6030-usb.o
 obj-$(CONFIG_USB_LANGWELL_OTG)	+= langwell_otg.o
 obj-$(CONFIG_NOP_USB_XCEIV)	+= nop-usb-xceiv.o
 obj-$(CONFIG_USB_ULPI)		+= ulpi.o

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#1 lore raw
Quoted 42 lines · Hema HK

Adding the twl6030-usb transceiver support for OMAP4 musb driver.

OMAP4 supports 2 types of transceiver interface.

1. UTMI: The PHY is embedded within OMAP4. The transceiver functionality is split between the twl6030 PMIC chip and OMAP4430. The VBUS, ID pin sensing and OTG SRP generation part is integrated in TWL6030 and UTMI PHY functionality is embedded within the OMAP4430.

There is no direct interactions between the MUSB controller and TWL6030 chip to communicate the session-valid, session-end and ID-GND events. It has to be done through a software by setting/resetting bits in one of the control module register of OMAP4430 which in turn toggles the appropriate signals to MUSB controller.

The internal transceiver has functional clocks and powerdown bits to powerdown the PHY for power saving.

Since there is no option available for having 2 transceiver drivers for one USB controller, internal PHY specific APIs are passed through plaform_data function pointers to use in the twl6030-usb transceiver driver.

2. ULPI interface is provided for off-chip transceivers.

Cc Felipe Balbi <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc David Brownell <[email protected]>

---

arch/arm/mach-omap2/omap_phy_internal.c |  133 ++++++++
arch/arm/plat-omap/include/plat/usb.h   |    4
drivers/usb/otg/Makefile                |    1
drivers/usb/otg/twl6030-usb.c           |  514 ++++++++++++++++++++++++++++++++
4 files changed, 652 insertions(+)

Index: linux-2.6/arch/arm/mach-omap2/omap_phy_internal.c
===================================================================

arch/arm/mach-omap2/omap_phy_internal.c new file +1 -0
@@ -0,0 +1,148 @@
+/*

arch/arm/mach-omap2/omap_phy_internal.c line 11

Quoted 10 lines
arch/arm/mach-omap2/omap_phy_internal.c new file +10 -0
+  * This file configures the internal USB PHY in OMAP4430. Used
+  * with TWL6030 transceiver and MUSB on OMAP4430.
+  *
+  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  *Author: Hema HK <[email protected]>

^^ you need a space after *

Quoted 130 lines
arch/arm/mach-omap2/omap_phy_internal.c new file +130 -0
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/usb.h>
+
+#include <plat/usb.h>
+
+/* OMAP control module register for UTMI PHY */
+#define CONTROL_DEV_CONF		0x300
+#define PHY_PD				0x1
+
+#define USBOTGHS_CONTROL		0x33c
+#define	AVALID				BIT(0)
+#define	BVALID				BIT(1)
+#define	VBUSVALID			BIT(2)
+#define	SESSEND				BIT(3)
+#define	IDDIG				BIT(4)
+
+static struct clk *phyclk, *clk48m, *clk32k;
+static void __iomem *ctrl_base;
+
+int omap4430_phy_init(struct device *dev)
+{
+	ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K);
+	if (!ctrl_base) {
+		dev_err(dev, "control module ioremap failed\n");
+		return -ENOMEM;
+	}
+	/* Power down the phy */
+	__raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+	phyclk = clk_get(dev, "ocp2scp_usb_phy_ick");
+
+	if (IS_ERR(phyclk)) {
+		dev_err(dev, "cannot clk_get ocp2scp_usb_phy_ick\n");
+		iounmap(ctrl_base);
+		return PTR_ERR(phyclk);
+	}
+
+	clk48m = clk_get(dev, "ocp2scp_usb_phy_phy_48m");
+	if (IS_ERR(clk48m)) {
+		dev_err(dev, "cannot clk_get ocp2scp_usb_phy_phy_48m\n");
+		clk_put(phyclk);
+		iounmap(ctrl_base);
+		return PTR_ERR(clk48m);
+	}
+
+	clk32k = clk_get(dev, "usb_phy_cm_clk32k");
+	if (IS_ERR(clk32k)) {
+		dev_err(dev, "cannot clk_get usb_phy_cm_clk32k\n");
+		clk_put(phyclk);
+		clk_put(clk48m);
+		iounmap(ctrl_base);
+		return PTR_ERR(clk32k);
+	}
+	return 0;
+}
+
+int omap4430_phy_set_clk(struct device *dev, int on)
+{
+	static int state;
+
+	if (on && !state) {
+		/* Enable the phy clocks */
+		clk_enable(phyclk);
+		clk_enable(clk48m);
+		clk_enable(clk32k);
+		state = 1;
+	} else if (state) {
+		/* Disable the phy clocks */
+		clk_disable(phyclk);
+		clk_disable(clk48m);
+		clk_disable(clk32k);
+		state = 0;
+	}
+	return 0;
+}
+
+int omap4430_phy_power(struct device *dev, int ID, int on)
+{
+	if (on) {
+		/* enabled the clocks */
+		omap4430_phy_set_clk(dev, 1);
+		/* power on the phy */
+		if (__raw_readl(ctrl_base + CONTROL_DEV_CONF) & PHY_PD) {
+			__raw_writel(~PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+			mdelay(200);
+		}
+		if (ID)
+			/* enable VBUS valid, IDDIG groung */
+			__raw_writel(AVALID | VBUSVALID, ctrl_base +
+							USBOTGHS_CONTROL);
+		else
+			/*
+			 * Enable VBUS Valid, AValid and IDDIG
+			 * high impedence
+			 */
+			__raw_writel(IDDIG | AVALID | VBUSVALID,
+						ctrl_base + USBOTGHS_CONTROL);
+	} else {
+		/* Enable session END and IDIG to high impedence. */
+		__raw_writel(SESSEND | IDDIG, ctrl_base +
+					USBOTGHS_CONTROL);
+		/* Disable the clocks */
+		omap4430_phy_set_clk(dev, 0);
+		/* Power down the phy */
+		__raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+	}
+
+	return 0;
+}
+
+int omap4430_phy_exit(struct device *dev)
+{
+	if (ctrl_base)
+		iounmap(ctrl_base);
+	if (phyclk)

arch/arm/mach-omap2/omap_phy_internal.c

Quoted 10 lines
arch/arm/mach-omap2/omap_phy_internal.c new file +10 -0
+		clk_put(phyclk);
+	if (clk48m)
+		clk_put(clk48m);
+	if (clk32k)
+		clk_put(clk32k);
+
+	return 0;
+}
+
+

two blank lines at the end of file. I like to use one, but people say it should be none :-p

Anyway, can this be converted into a platform driver ? Then you could power it on/off with pm_runtime ?!? You wouldn't need to export functions either.

It could be that's not possible, but doesn't hurt asking.

Quoted 5 lines

Index: linux-2.6/arch/arm/plat-omap/include/plat/usb.h
===================================================================

arch/arm/plat-omap/include/plat/usb.h extern void usb_ehci_init(const struct e · line 87

Quoted 9 lines
arch/arm/plat-omap/include/plat/usb.h +6 -0
@@ -79,6 +79,12 @@ extern void usb_ehci_init(const struct e
 
 extern void usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata);
 
+extern int omap4430_phy_power(struct device *dev, int ID, int on);
+extern int omap4430_phy_set_clk(struct device *dev, int on);
+extern int omap4430_phy_init(struct device *dev);
+extern int omap4430_phy_exit(struct device *dev);
+
+

one blank line only.

Quoted 5 lines

Index: linux-2.6/drivers/usb/otg/twl6030-usb.c
===================================================================

drivers/usb/otg/twl6030-usb.c line 10

Quoted 10 lines
drivers/usb/otg/twl6030-usb.c new file +10 -0
@@ -0,0 +1,520 @@
+/*
+ * twl6030_usb - TWL6030 USB transceiver, talking to OMAP OTG driver.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *Author: Hema HK <[email protected]>

^^ space

Quoted 39 lines
drivers/usb/otg/twl6030-usb.c new file +39 -0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/usb/otg.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/notifier.h>
+#include <linux/slab.h>
+
+/* usb register definitions */
+#define USB_VENDOR_ID_LSB		0x00
+#define USB_VENDOR_ID_MSB		0x01
+#define USB_PRODUCT_ID_LSB		0x02
+#define USB_PRODUCT_ID_MSB		0x03
+#define USB_VBUS_CTRL_SET		0x04
+#define USB_VBUS_CTRL_CLR		0x05
+#define USB_ID_CTRL_SET			0x06
+#define USB_ID_CTRL_CLR			0x07
+#define USB_VBUS_INT_SRC		0x08
+#define USB_VBUS_INT_LATCH_SET		0x09
+#define USB_VBUS_INT_LATCH_CLR		0x0A
+#define USB_VBUS_INT_EN_LO_SET		0x0B
+#define USB_VBUS_INT_EN_LO_CLR		0x0C
+#define USB_VBUS_INT_EN_HI_SET		0x0D

drivers/usb/otg/twl6030-usb.c line 60

Quoted 10 lines
drivers/usb/otg/twl6030-usb.c new file +10 -0
+#define USB_VBUS_INT_EN_HI_CLR		0x0E
+#define USB_ID_INT_SRC			0x0F
+#define USB_ID_INT_LATCH_SET		0x10
+#define USB_ID_INT_LATCH_CLR		0x11
+
+
+#define USB_ID_INT_EN_LO_SET		0x12
+#define USB_ID_INT_EN_LO_CLR		0x13
+#define USB_ID_INT_EN_HI_SET		0x14
+#define USB_ID_INT_EN_HI_CLR		0x15

I wonder why HW people didn't follow ULPI spec here. What a mess...

drivers/usb/otg/twl6030-usb.c line 65

Quoted 5 lines
drivers/usb/otg/twl6030-usb.c new file +5 -0
+#define USB_OTG_ADP_CTRL		0x16
+#define USB_OTG_ADP_HIGH		0x17
+#define USB_OTG_ADP_LOW			0x18
+#define USB_OTG_ADP_RISE		0x19
+#define USB_OTG_REVISION		0x1A

... then these would only be a set of extended registers.

drivers/usb/otg/twl6030-usb.c line 69

Quoted 3 lines
drivers/usb/otg/twl6030-usb.c new file +3 -0
+/* to be moved to LDO */
+#define MISC2				0xE5
+#define CFG_LDO_PD2			0xF5

prepend with USB_

drivers/usb/otg/twl6030-usb.c line 75

Quoted 6 lines
drivers/usb/otg/twl6030-usb.c new file +6 -0
+#define USB_BACKUP_REG			0xFA
+
+#define STS_HW_CONDITIONS		0x21
+
+/* In module TWL6030_MODULE_PM_MASTER */
+#define PROTECT_KEY			0x0E

defined in <linux/i2c/twl.h>

Quoted 21 lines
drivers/usb/otg/twl6030-usb.c new file +21 -0
+#define STS_HW_CONDITIONS		0x21
+#define STS_USB_ID			BIT(2)
+
+/* In module TWL6030_MODULE_PM_RECEIVER */
+#define VUSB_DEDICATED1			0x7D
+#define VUSB_DEDICATED2			0x7E
+#define VUSB1V5_DEV_GRP			0x71
+#define VUSB1V5_TYPE			0x72
+#define VUSB1V5_REMAP			0x73
+#define VUSB1V8_DEV_GRP			0x74
+#define VUSB1V8_TYPE			0x75
+#define VUSB1V8_REMAP			0x76
+#define VUSB3V1_DEV_GRP			0x77
+#define VUSB3V1_TYPE			0x78
+#define VUSB3V1_REMAP			0x79
+
+/* In module TWL6030_MODULE_PM_RECEIVER */
+#define VUSB_CFG_TRANS			0x71
+#define VUSB_CFG_STATE			0x72
+#define VUSB_CFG_VOLTAGE		0x73
+

drivers/usb/otg/twl6030-usb.c line 106

Quoted 10 lines
drivers/usb/otg/twl6030-usb.c new file +10 -0
+/* in module TWL6030_MODULE_MAIN_CHARGE */
+
+#define CHARGERUSB_CTRL1		0x8
+
+#define CONTROLLER_STAT1		0x03
+#define	VBUS_DET			BIT(2)
+
+
+/* OMAP control module register for UTMI PHY */
+#define ONTROL_DEV_CONF			0x300

did you mean CONTROL ??

drivers/usb/otg/twl6030-usb.c line 112

Quoted 8 lines
drivers/usb/otg/twl6030-usb.c new file +8 -0
+#define PHY_PD				0x1
+
+#define USBOTGHS_CONTROL		0x33c
+#define	AVALID				BIT(0)
+#define	BVALID				BIT(1)
+#define	VBUSVALID			BIT(2)
+#define	SESSEND				BIT(3)
+#define	IDDIG				BIT(4)

these are likely to give namespace colision at some point, append with USB_ or better change USB_ to TWL6030_USB_

Quoted 10 lines
drivers/usb/otg/twl6030-usb.c new file +10 -0
+static int __devinit twl6030_usb_probe(struct platform_device *pdev)
+{
+	struct twl6030_usb	*twl;
+	int			status, err;
+	struct twl4030_usb_data *pdata;
+	struct device *dev = &pdev->dev;
+	pdata = dev->platform_data;
+
+	twl = kzalloc(sizeof *twl, GFP_KERNEL);
+	if (!twl)

drivers/usb/otg/twl6030-usb.c line 422

Quoted 10 lines
drivers/usb/otg/twl6030-usb.c new file +10 -0
+		return -ENOMEM;
+
+	twl->dev		= &pdev->dev;
+	twl->irq1		= platform_get_irq(pdev, 0);
+	twl->irq2		= platform_get_irq(pdev, 1);
+	twl->otg.dev		= twl->dev;
+	twl->otg.label		= "twl6030";
+	twl->otg.set_host	= twl6030_set_host;
+	twl->otg.set_peripheral	= twl6030_set_peripheral;
+	twl->asleep		= 1;

better to read this from HW and avoid problems if bootloaders wakes this one up.

Signature · 1 line
balbi

A message that is not in the archive (sent off-list or not yet received): 20101208095053.GF2891-UiBtZHVXSwEVvW8u9ZQWYwjfymiNCTlR@public.gmane.org

#3 lore raw
Quoted 49 lines · Felipe Balbi
Quoted 48 lines · Hema HK

Adding the twl6030-usb transceiver support for OMAP4 musb driver.

OMAP4 supports 2 types of transceiver interface.

1. UTMI: The PHY is embedded within OMAP4. The transceiver functionality is split between the twl6030 PMIC chip and OMAP4430. The VBUS, ID pin sensing and OTG SRP generation part is integrated in TWL6030 and UTMI PHY functionality is embedded within the OMAP4430.

There is no direct interactions between the MUSB controller and TWL6030 chip to communicate the session-valid, session-end and ID-GND events. It has to be done through a software by setting/resetting bits in one of the control module register of OMAP4430 which in turn toggles the appropriate signals to MUSB controller.

The internal transceiver has functional clocks and powerdown bits to powerdown the PHY for power saving.

Since there is no option available for having 2 transceiver drivers for one USB controller, internal PHY specific APIs are passed through plaform_data function pointers to use in the twl6030-usb transceiver driver.

2. ULPI interface is provided for off-chip transceivers.

Cc Felipe Balbi <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc David Brownell <[email protected]>

---
arch/arm/mach-omap2/omap_phy_internal.c |  133 ++++++++ arch/arm/plat-omap/include/plat/usb.h   |    4 drivers/usb/otg/Makefile                |    1 drivers/usb/otg/twl6030-usb.c           |  514
++++++++++++++++++++++++++++++++

4 files changed, 652 insertions(+)

Index: linux-2.6/arch/arm/mach-omap2/omap_phy_internal.c
===================================================================

arch/arm/mach-omap2/omap_phy_internal.c new file +5 -0
@@ -0,0 +1,148 @@
+/*
+  * This file configures the internal USB PHY in OMAP4430. Used
+  * with TWL6030 transceiver and MUSB on OMAP4430.
+  *
+  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
Quoted 8 lines

arch/arm/mach-omap2/omap_phy_internal.c line 11

Quoted 6 lines
arch/arm/mach-omap2/omap_phy_internal.c new file +6 -0
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  *Author: Hema HK <[email protected]>

   ^^ you need a space after *

OK.

Quoted 138 lines
Quoted 138 lines
arch/arm/mach-omap2/omap_phy_internal.c new file +99 -0
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/usb.h>
+
+#include <plat/usb.h>
+
+/* OMAP control module register for UTMI PHY */
+#define CONTROL_DEV_CONF               0x300
+#define PHY_PD                         0x1
+
+#define USBOTGHS_CONTROL               0x33c
+#define        AVALID                          BIT(0)
+#define        BVALID                          BIT(1)
+#define        VBUSVALID                       BIT(2)
+#define        SESSEND                         BIT(3)
+#define        IDDIG                           BIT(4)
+
+static struct clk *phyclk, *clk48m, *clk32k;
+static void __iomem *ctrl_base;
+
+int omap4430_phy_init(struct device *dev)
+{
+       ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K);
+       if (!ctrl_base) {
+               dev_err(dev, "control module ioremap failed\n");
+               return -ENOMEM;
+       }
+       /* Power down the phy */
+       __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+       phyclk = clk_get(dev, "ocp2scp_usb_phy_ick");
+
+       if (IS_ERR(phyclk)) {
+               dev_err(dev, "cannot clk_get ocp2scp_usb_phy_ick\n");
+               iounmap(ctrl_base);
+               return PTR_ERR(phyclk);
+       }
+
+       clk48m = clk_get(dev, "ocp2scp_usb_phy_phy_48m");
+       if (IS_ERR(clk48m)) {
+               dev_err(dev, "cannot clk_get ocp2scp_usb_phy_phy_48m\n");
+               clk_put(phyclk);
+               iounmap(ctrl_base);
+               return PTR_ERR(clk48m);
+       }
+
+       clk32k = clk_get(dev, "usb_phy_cm_clk32k");
+       if (IS_ERR(clk32k)) {
+               dev_err(dev, "cannot clk_get usb_phy_cm_clk32k\n");
+               clk_put(phyclk);
+               clk_put(clk48m);
+               iounmap(ctrl_base);
+               return PTR_ERR(clk32k);
+       }
+       return 0;
+}
+
+int omap4430_phy_set_clk(struct device *dev, int on)
+{
+       static int state;
+
+       if (on && !state) {
+               /* Enable the phy clocks */
+               clk_enable(phyclk);
+               clk_enable(clk48m);
+               clk_enable(clk32k);
+               state = 1;
+       } else if (state) {
+               /* Disable the phy clocks */
+               clk_disable(phyclk);
+               clk_disable(clk48m);
+               clk_disable(clk32k);
+               state = 0;
+       }
+       return 0;
+}
+
+int omap4430_phy_power(struct device *dev, int ID, int on)
+{
+       if (on) {
+               /* enabled the clocks */
+               omap4430_phy_set_clk(dev, 1);
+               /* power on the phy */
+               if (__raw_readl(ctrl_base + CONTROL_DEV_CONF) & PHY_PD) {
+                       __raw_writel(~PHY_PD, ctrl_base +

CONTROL_DEV_CONF);
+                       mdelay(200);
+               }
+               if (ID)
+                       /* enable VBUS valid, IDDIG groung */
+                       __raw_writel(AVALID | VBUSVALID, ctrl_base +
+                                                       USBOTGHS_CONTROL);
+               else
+                       /*
+                        * Enable VBUS Valid, AValid and IDDIG
+                        * high impedence
+                        */
+                       __raw_writel(IDDIG | AVALID | VBUSVALID,
+                                               ctrl_base + USBOTGHS_CONTROL);
+       } else {
+               /* Enable session END and IDIG to high impedence. */
+               __raw_writel(SESSEND | IDDIG, ctrl_base +
+                                       USBOTGHS_CONTROL);
+               /* Disable the clocks */
+               omap4430_phy_set_clk(dev, 0);
+               /* Power down the phy */
+               __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+       }

arch/arm/mach-omap2/omap_phy_internal.c new file +14 -0
+
+       return 0;
+}
+
+int omap4430_phy_exit(struct device *dev)
+{
+       if (ctrl_base)
+               iounmap(ctrl_base);
+       if (phyclk)
+               clk_put(phyclk);
+       if (clk48m)
+               clk_put(clk48m);
+       if (clk32k)
+               clk_put(clk32k);
Quoted 8 lines

arch/arm/mach-omap2/omap_phy_internal.c line 87

Quoted 5 lines
arch/arm/mach-omap2/omap_phy_internal.c new file +5 -0
+
+       return 0;
+}
+
+

two blank lines at the end of file. I like to use one, but people say it should be none :-p

Fine. I will remove the blank lines.

Quoted 6 lines

Anyway, can this be converted into a platform driver ? Then you could power it on/off with pm_runtime ?!? You wouldn't need to export functions either.

It could be that's not possible, but doesn't hurt asking.

pm_runime will take care of this as there is no device build done for PHY. This device does not have any IRQs or sysconfig registers. This device has only 2 clocks associated with it and that too these are considered as optional clocks.
So using it is decided to use the clock framework for this device.

Quoted 10 lines
Quoted 10 lines

Index: linux-2.6/arch/arm/plat-omap/include/plat/usb.h
===================================================================

arch/arm/plat-omap/include/plat/usb.h +0 -0
@@ -79,6 +79,12 @@ extern void usb_ehci_init(const struct e
 

extern void usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata);

Quoted 8 lines

arch/arm/plat-omap/include/plat/usb.h extern void usb_ehci_init(const struct e · line 87

Quoted 6 lines
arch/arm/plat-omap/include/plat/usb.h +6 -0
+extern int omap4430_phy_power(struct device *dev, int ID, int on);
+extern int omap4430_phy_set_clk(struct device *dev, int on);
+extern int omap4430_phy_init(struct device *dev);
+extern int omap4430_phy_exit(struct device *dev);
+
+

one blank line only.

OK.

Quoted 10 lines
Quoted 10 lines

Index: linux-2.6/drivers/usb/otg/twl6030-usb.c
===================================================================

drivers/usb/otg/twl6030-usb.c new file +4 -0
@@ -0,0 +1,520 @@
+/*
+ * twl6030_usb - TWL6030 USB transceiver, talking to OMAP OTG driver.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
Quoted 8 lines

drivers/usb/otg/twl6030-usb.c line 10

Quoted 6 lines
drivers/usb/otg/twl6030-usb.c new file +6 -0
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *Author: Hema HK <[email protected]>

  ^^ space

OK.

Quoted 61 lines
Quoted 40 lines
drivers/usb/otg/twl6030-usb.c new file +39 -0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/usb/otg.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/notifier.h>
+#include <linux/slab.h>
+
+/* usb register definitions */
+#define USB_VENDOR_ID_LSB              0x00
+#define USB_VENDOR_ID_MSB              0x01
+#define USB_PRODUCT_ID_LSB             0x02
+#define USB_PRODUCT_ID_MSB             0x03
+#define USB_VBUS_CTRL_SET              0x04
+#define USB_VBUS_CTRL_CLR              0x05
+#define USB_ID_CTRL_SET                        0x06
+#define USB_ID_CTRL_CLR                        0x07
+#define USB_VBUS_INT_SRC               0x08
+#define USB_VBUS_INT_LATCH_SET         0x09
+#define USB_VBUS_INT_LATCH_CLR         0x0A
+#define USB_VBUS_INT_EN_LO_SET         0x0B
+#define USB_VBUS_INT_EN_LO_CLR         0x0C
+#define USB_VBUS_INT_EN_HI_SET         0x0D

drivers/usb/otg/twl6030-usb.c line 60

Quoted 10 lines
drivers/usb/otg/twl6030-usb.c new file +10 -0
+#define USB_VBUS_INT_EN_HI_CLR         0x0E
+#define USB_ID_INT_SRC                 0x0F
+#define USB_ID_INT_LATCH_SET           0x10
+#define USB_ID_INT_LATCH_CLR           0x11
+
+
+#define USB_ID_INT_EN_LO_SET           0x12
+#define USB_ID_INT_EN_LO_CLR           0x13
+#define USB_ID_INT_EN_HI_SET           0x14
+#define USB_ID_INT_EN_HI_CLR           0x15

I wonder why HW people didn't follow ULPI spec here. What a mess...

drivers/usb/otg/twl6030-usb.c line 65

Quoted 5 lines
drivers/usb/otg/twl6030-usb.c new file +5 -0
+#define USB_OTG_ADP_CTRL               0x16
+#define USB_OTG_ADP_HIGH               0x17
+#define USB_OTG_ADP_LOW                        0x18
+#define USB_OTG_ADP_RISE               0x19
+#define USB_OTG_REVISION               0x1A

... then these would only be a set of extended registers.

Quoted 5 lines

drivers/usb/otg/twl6030-usb.c line 69

Quoted 3 lines
drivers/usb/otg/twl6030-usb.c new file +3 -0
+/* to be moved to LDO */
+#define MISC2                          0xE5
+#define CFG_LDO_PD2                    0xF5

prepend with USB_

OK.

Quoted 35 lines

drivers/usb/otg/twl6030-usb.c line 75

Quoted 7 lines
drivers/usb/otg/twl6030-usb.c new file +6 -0
+#define USB_BACKUP_REG                 0xFA
+
+#define STS_HW_CONDITIONS              0x21
+
+/* In module TWL6030_MODULE_PM_MASTER */
+#define PROTECT_KEY                    0x0E

defined in <linux/i2c/twl.h>

Quoted 25 lines
drivers/usb/otg/twl6030-usb.c new file +25 -0
+#define STS_HW_CONDITIONS              0x21
+#define STS_USB_ID                     BIT(2)
+
+/* In module TWL6030_MODULE_PM_RECEIVER */
+#define VUSB_DEDICATED1                        0x7D
+#define VUSB_DEDICATED2                        0x7E
+#define VUSB1V5_DEV_GRP                        0x71
+#define VUSB1V5_TYPE                   0x72
+#define VUSB1V5_REMAP                  0x73
+#define VUSB1V8_DEV_GRP                        0x74
+#define VUSB1V8_TYPE                   0x75
+#define VUSB1V8_REMAP                  0x76
+#define VUSB3V1_DEV_GRP                        0x77
+#define VUSB3V1_TYPE                   0x78
+#define VUSB3V1_REMAP                  0x79
+
+/* In module TWL6030_MODULE_PM_RECEIVER */
+#define VUSB_CFG_TRANS                 0x71
+#define VUSB_CFG_STATE                 0x72
+#define VUSB_CFG_VOLTAGE               0x73
+
+/* in module TWL6030_MODULE_MAIN_CHARGE */
+
+#define CHARGERUSB_CTRL1               0x8
+
Quoted 8 lines

drivers/usb/otg/twl6030-usb.c line 106

Quoted 6 lines
drivers/usb/otg/twl6030-usb.c new file +6 -0
+#define CONTROLLER_STAT1               0x03
+#define        VBUS_DET                        BIT(2)
+
+
+/* OMAP control module register for UTMI PHY */
+#define ONTROL_DEV_CONF                        0x300

did you mean CONTROL ??

I need to remove this from this file as these are not used here.

Quoted 12 lines

drivers/usb/otg/twl6030-usb.c line 112

Quoted 9 lines
drivers/usb/otg/twl6030-usb.c new file +8 -0
+#define PHY_PD                         0x1
+
+#define USBOTGHS_CONTROL               0x33c
+#define        AVALID                          BIT(0)
+#define        BVALID                          BIT(1)
+#define        VBUSVALID                       BIT(2)
+#define        SESSEND                         BIT(3)
+#define        IDDIG                           BIT(4)

these are likely to give namespace colision at some point, append with USB_ or better change USB_ to TWL6030_USB_

These are not required so i will remove them.

Quoted 16 lines
Quoted 16 lines
drivers/usb/otg/twl6030-usb.c new file +15 -0
+static int __devinit twl6030_usb_probe(struct platform_device *pdev)
+{
+       struct twl6030_usb      *twl;
+       int                     status, err;
+       struct twl4030_usb_data *pdata;
+       struct device *dev = &pdev->dev;
+       pdata = dev->platform_data;
+
+       twl = kzalloc(sizeof *twl, GFP_KERNEL);
+       if (!twl)
+               return -ENOMEM;
+
+       twl->dev                = &pdev->dev;
+       twl->irq1               = platform_get_irq(pdev, 0);
+       twl->irq2               = platform_get_irq(pdev, 1);
Quoted 8 lines

drivers/usb/otg/twl6030-usb.c line 422

Quoted 5 lines
drivers/usb/otg/twl6030-usb.c new file +5 -0
+       twl->otg.dev            = twl->dev;
+       twl->otg.label          = "twl6030";
+       twl->otg.set_host       = twl6030_set_host;
+       twl->otg.set_peripheral = twl6030_set_peripheral;
+       twl->asleep             = 1;

better to read this from HW and avoid problems if bootloaders wakes this one up.

I don'e need this anymore.

Quoted 4 lines

--
balbi

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): AANLkTimTNiry5nNb+OvegLEkq2LmBuyfQ3DjfeC-5q1E-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org

#5 lore raw
Quoted 207 lines · Hema
Quoted 49 lines · Felipe Balbi
Quoted 48 lines · Hema HK

Adding the twl6030-usb transceiver support for OMAP4 musb driver.

OMAP4 supports 2 types of transceiver interface.

1. UTMI: The PHY is embedded within OMAP4. The transceiver functionality is split between the twl6030 PMIC chip and OMAP4430. The VBUS, ID pin sensing and OTG SRP generation part is integrated in TWL6030 and UTMI PHY functionality is embedded within the OMAP4430.

There is no direct interactions between the MUSB controller and TWL6030 chip to communicate the session-valid, session-end and ID-GND events. It has to be done through a software by setting/resetting bits in one of the control module register of OMAP4430 which in turn toggles the appropriate signals to MUSB controller.

The internal transceiver has functional clocks and powerdown bits to powerdown the PHY for power saving.

Since there is no option available for having 2 transceiver drivers for one USB controller, internal PHY specific APIs are passed through plaform_data function pointers to use in the twl6030-usb transceiver driver.

2. ULPI interface is provided for off-chip transceivers.

Cc Felipe Balbi <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc David Brownell <[email protected]>

---
arch/arm/mach-omap2/omap_phy_internal.c |  133 ++++++++ arch/arm/plat-omap/include/plat/usb.h   |    4 drivers/usb/otg/Makefile                |    1 drivers/usb/otg/twl6030-usb.c           |  514
++++++++++++++++++++++++++++++++

4 files changed, 652 insertions(+)

Index: linux-2.6/arch/arm/mach-omap2/omap_phy_internal.c
===================================================================

arch/arm/mach-omap2/omap_phy_internal.c new file +5 -0
@@ -0,0 +1,148 @@
+/*
+  * This file configures the internal USB PHY in OMAP4430. Used
+  * with TWL6030 transceiver and MUSB on OMAP4430.
+  *
+  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
Quoted 8 lines

arch/arm/mach-omap2/omap_phy_internal.c line 11

Quoted 6 lines
arch/arm/mach-omap2/omap_phy_internal.c new file +6 -0
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  *Author: Hema HK <[email protected]>

   ^^ you need a space after *

OK.

Quoted 138 lines
Quoted 138 lines
arch/arm/mach-omap2/omap_phy_internal.c new file +99 -0
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/usb.h>
+
+#include <plat/usb.h>
+
+/* OMAP control module register for UTMI PHY */
+#define CONTROL_DEV_CONF               0x300
+#define PHY_PD                         0x1
+
+#define USBOTGHS_CONTROL               0x33c
+#define        AVALID                          BIT(0)
+#define        BVALID                          BIT(1)
+#define        VBUSVALID                       BIT(2)
+#define        SESSEND                         BIT(3)
+#define        IDDIG                           BIT(4)
+
+static struct clk *phyclk, *clk48m, *clk32k;
+static void __iomem *ctrl_base;
+
+int omap4430_phy_init(struct device *dev)
+{
+       ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K);
+       if (!ctrl_base) {
+               dev_err(dev, "control module ioremap failed\n");
+               return -ENOMEM;
+       }
+       /* Power down the phy */
+       __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+       phyclk = clk_get(dev, "ocp2scp_usb_phy_ick");
+
+       if (IS_ERR(phyclk)) {
+               dev_err(dev, "cannot clk_get ocp2scp_usb_phy_ick\n");
+               iounmap(ctrl_base);
+               return PTR_ERR(phyclk);
+       }
+
+       clk48m = clk_get(dev, "ocp2scp_usb_phy_phy_48m");
+       if (IS_ERR(clk48m)) {
+               dev_err(dev, "cannot clk_get ocp2scp_usb_phy_phy_48m\n");
+               clk_put(phyclk);
+               iounmap(ctrl_base);
+               return PTR_ERR(clk48m);
+       }
+
+       clk32k = clk_get(dev, "usb_phy_cm_clk32k");
+       if (IS_ERR(clk32k)) {
+               dev_err(dev, "cannot clk_get usb_phy_cm_clk32k\n");
+               clk_put(phyclk);
+               clk_put(clk48m);
+               iounmap(ctrl_base);
+               return PTR_ERR(clk32k);
+       }
+       return 0;
+}
+
+int omap4430_phy_set_clk(struct device *dev, int on)
+{
+       static int state;
+
+       if (on && !state) {
+               /* Enable the phy clocks */
+               clk_enable(phyclk);
+               clk_enable(clk48m);
+               clk_enable(clk32k);
+               state = 1;
+       } else if (state) {
+               /* Disable the phy clocks */
+               clk_disable(phyclk);
+               clk_disable(clk48m);
+               clk_disable(clk32k);
+               state = 0;
+       }
+       return 0;
+}
+
+int omap4430_phy_power(struct device *dev, int ID, int on)
+{
+       if (on) {
+               /* enabled the clocks */
+               omap4430_phy_set_clk(dev, 1);
+               /* power on the phy */
+               if (__raw_readl(ctrl_base + CONTROL_DEV_CONF) & PHY_PD) {
+                       __raw_writel(~PHY_PD, ctrl_base +

CONTROL_DEV_CONF);
+                       mdelay(200);
+               }
+               if (ID)
+                       /* enable VBUS valid, IDDIG groung */
+                       __raw_writel(AVALID | VBUSVALID, ctrl_base +
+                                                       USBOTGHS_CONTROL);
+               else
+                       /*
+                        * Enable VBUS Valid, AValid and IDDIG
+                        * high impedence
+                        */
+                       __raw_writel(IDDIG | AVALID | VBUSVALID,
+                                               ctrl_base + USBOTGHS_CONTROL);
+       } else {
+               /* Enable session END and IDIG to high impedence. */
+               __raw_writel(SESSEND | IDDIG, ctrl_base +
+                                       USBOTGHS_CONTROL);
+               /* Disable the clocks */
+               omap4430_phy_set_clk(dev, 0);
+               /* Power down the phy */
+               __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+       }

arch/arm/mach-omap2/omap_phy_internal.c new file +14 -0
+
+       return 0;
+}
+
+int omap4430_phy_exit(struct device *dev)
+{
+       if (ctrl_base)
+               iounmap(ctrl_base);
+       if (phyclk)
+               clk_put(phyclk);
+       if (clk48m)
+               clk_put(clk48m);
+       if (clk32k)
+               clk_put(clk32k);
Quoted 8 lines

arch/arm/mach-omap2/omap_phy_internal.c line 87

Quoted 5 lines
arch/arm/mach-omap2/omap_phy_internal.c new file +5 -0
+
+       return 0;
+}
+
+

two blank lines at the end of file. I like to use one, but people say it should be none :-p

Fine. I will remove the blank lines.

Quoted 1 line
Quoted 7 lines
Quoted 5 lines

Anyway, can this be converted into a platform driver ? Then you could power it on/off with pm_runtime ?!? You wouldn't need to export functions either.

It could be that's not possible, but doesn't hurt asking.

pm_runime will take care of this as there is no device build done for PHY.

I mean pm_runime will not take care of this as there is no device build done for PHY.

Quoted 42 lines

This device does not have any IRQs or sysconfig registers. This device has only 2 clocks associated with it and that too these are considered as optional clocks.
So using it is decided to use the clock framework for this device.

Quoted 10 lines
Quoted 10 lines

Index: linux-2.6/arch/arm/plat-omap/include/plat/usb.h
===================================================================

arch/arm/plat-omap/include/plat/usb.h +0 -0
@@ -79,6 +79,12 @@ extern void usb_ehci_init(const struct e
 

extern void usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata);

Quoted 8 lines

arch/arm/plat-omap/include/plat/usb.h extern void usb_ehci_init(const struct e · line 87

Quoted 6 lines
arch/arm/plat-omap/include/plat/usb.h +6 -0
+extern int omap4430_phy_power(struct device *dev, int ID, int on);
+extern int omap4430_phy_set_clk(struct device *dev, int on);
+extern int omap4430_phy_init(struct device *dev);
+extern int omap4430_phy_exit(struct device *dev);
+
+

one blank line only.

OK.

Quoted 10 lines
Quoted 10 lines

Index: linux-2.6/drivers/usb/otg/twl6030-usb.c
===================================================================

drivers/usb/otg/twl6030-usb.c new file +4 -0
@@ -0,0 +1,520 @@
+/*
+ * twl6030_usb - TWL6030 USB transceiver, talking to OMAP OTG driver.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
Quoted 8 lines

drivers/usb/otg/twl6030-usb.c line 10

Quoted 6 lines
drivers/usb/otg/twl6030-usb.c new file +6 -0
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *Author: Hema HK <[email protected]>

  ^^ space

Quoted 61 lines

OK.

Quoted 60 lines
Quoted 40 lines
drivers/usb/otg/twl6030-usb.c new file +39 -0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/usb/otg.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/notifier.h>
+#include <linux/slab.h>
+
+/* usb register definitions */
+#define USB_VENDOR_ID_LSB              0x00
+#define USB_VENDOR_ID_MSB              0x01
+#define USB_PRODUCT_ID_LSB             0x02
+#define USB_PRODUCT_ID_MSB             0x03
+#define USB_VBUS_CTRL_SET              0x04
+#define USB_VBUS_CTRL_CLR              0x05
+#define USB_ID_CTRL_SET                        0x06
+#define USB_ID_CTRL_CLR                        0x07
+#define USB_VBUS_INT_SRC               0x08
+#define USB_VBUS_INT_LATCH_SET         0x09
+#define USB_VBUS_INT_LATCH_CLR         0x0A
+#define USB_VBUS_INT_EN_LO_SET         0x0B
+#define USB_VBUS_INT_EN_LO_CLR         0x0C
+#define USB_VBUS_INT_EN_HI_SET         0x0D

drivers/usb/otg/twl6030-usb.c line 60

Quoted 10 lines
drivers/usb/otg/twl6030-usb.c new file +10 -0
+#define USB_VBUS_INT_EN_HI_CLR         0x0E
+#define USB_ID_INT_SRC                 0x0F
+#define USB_ID_INT_LATCH_SET           0x10
+#define USB_ID_INT_LATCH_CLR           0x11
+
+
+#define USB_ID_INT_EN_LO_SET           0x12
+#define USB_ID_INT_EN_LO_CLR           0x13
+#define USB_ID_INT_EN_HI_SET           0x14
+#define USB_ID_INT_EN_HI_CLR           0x15

I wonder why HW people didn't follow ULPI spec here. What a mess...

drivers/usb/otg/twl6030-usb.c line 65

Quoted 5 lines
drivers/usb/otg/twl6030-usb.c new file +5 -0
+#define USB_OTG_ADP_CTRL               0x16
+#define USB_OTG_ADP_HIGH               0x17
+#define USB_OTG_ADP_LOW                        0x18
+#define USB_OTG_ADP_RISE               0x19
+#define USB_OTG_REVISION               0x1A

... then these would only be a set of extended registers.

Yes. Some of these registers are not used now. But required when OTG2.0 support is provided.

Quoted 7 lines
Quoted 6 lines

drivers/usb/otg/twl6030-usb.c line 69

Quoted 4 lines
drivers/usb/otg/twl6030-usb.c new file +3 -0
+/* to be moved to LDO */
+#define MISC2                          0xE5
+#define CFG_LDO_PD2                    0xF5

prepend with USB_

OK.

These are not the USB_OTG registers under in TWL6030
Ideally would bedefined in twl.h. I think i will move these to twl.h file.

Quoted 9 lines
Quoted 9 lines

drivers/usb/otg/twl6030-usb.c line 75

Quoted 7 lines
drivers/usb/otg/twl6030-usb.c new file +6 -0
+#define USB_BACKUP_REG                 0xFA
+
+#define STS_HW_CONDITIONS              0x21
+
+/* In module TWL6030_MODULE_PM_MASTER */
+#define PROTECT_KEY                    0x0E

defined in <linux/i2c/twl.h>

OK. I will remove from here.

Quoted 74 lines
Quoted 26 lines
Quoted 26 lines
drivers/usb/otg/twl6030-usb.c new file +25 -0
+#define STS_HW_CONDITIONS              0x21
+#define STS_USB_ID                     BIT(2)
+
+/* In module TWL6030_MODULE_PM_RECEIVER */
+#define VUSB_DEDICATED1                        0x7D
+#define VUSB_DEDICATED2                        0x7E
+#define VUSB1V5_DEV_GRP                        0x71
+#define VUSB1V5_TYPE                   0x72
+#define VUSB1V5_REMAP                  0x73
+#define VUSB1V8_DEV_GRP                        0x74
+#define VUSB1V8_TYPE                   0x75
+#define VUSB1V8_REMAP                  0x76
+#define VUSB3V1_DEV_GRP                        0x77
+#define VUSB3V1_TYPE                   0x78
+#define VUSB3V1_REMAP                  0x79
+
+/* In module TWL6030_MODULE_PM_RECEIVER */
+#define VUSB_CFG_TRANS                 0x71
+#define VUSB_CFG_STATE                 0x72
+#define VUSB_CFG_VOLTAGE               0x73
+
+/* in module TWL6030_MODULE_MAIN_CHARGE */
+
+#define CHARGERUSB_CTRL1               0x8
+
Quoted 8 lines

drivers/usb/otg/twl6030-usb.c line 106

Quoted 6 lines
drivers/usb/otg/twl6030-usb.c new file +6 -0
+#define CONTROLLER_STAT1               0x03
+#define        VBUS_DET                        BIT(2)
+
+
+/* OMAP control module register for UTMI PHY */
+#define ONTROL_DEV_CONF                        0x300

did you mean CONTROL ??

I need to remove this from this file as these are not used here.

Quoted 12 lines

drivers/usb/otg/twl6030-usb.c line 112

Quoted 9 lines
drivers/usb/otg/twl6030-usb.c new file +8 -0
+#define PHY_PD                         0x1
+
+#define USBOTGHS_CONTROL               0x33c
+#define        AVALID                          BIT(0)
+#define        BVALID                          BIT(1)
+#define        VBUSVALID                       BIT(2)
+#define        SESSEND                         BIT(3)
+#define        IDDIG                           BIT(4)

these are likely to give namespace colision at some point, append with USB_ or better change USB_ to TWL6030_USB_

These are not required so i will remove them.

Quoted 16 lines
Quoted 16 lines
drivers/usb/otg/twl6030-usb.c new file +15 -0
+static int __devinit twl6030_usb_probe(struct platform_device *pdev)
+{
+       struct twl6030_usb      *twl;
+       int                     status, err;
+       struct twl4030_usb_data *pdata;
+       struct device *dev = &pdev->dev;
+       pdata = dev->platform_data;
+
+       twl = kzalloc(sizeof *twl, GFP_KERNEL);
+       if (!twl)
+               return -ENOMEM;
+
+       twl->dev                = &pdev->dev;
+       twl->irq1               = platform_get_irq(pdev, 0);
+       twl->irq2               = platform_get_irq(pdev, 1);
Quoted 8 lines

drivers/usb/otg/twl6030-usb.c line 422

Quoted 5 lines
drivers/usb/otg/twl6030-usb.c new file +5 -0
+       twl->otg.dev            = twl->dev;
+       twl->otg.label          = "twl6030";
+       twl->otg.set_host       = twl6030_set_host;
+       twl->otg.set_peripheral = twl6030_set_peripheral;
+       twl->asleep             = 1;

better to read this from HW and avoid problems if bootloaders wakes this one up.

Quoted 6 lines

I don'e need this anymore.

Quoted 4 lines

--
balbi

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html