Skip to contentSkip to conversation

mfd: omap: control: usb-phy: introduce the ctrl-module usb driver

PATCH Superseded Konstantin Baydarov 4 participants 4 messages Jun 27, 2012 – Jul 9, 2012

Subsystems (2)

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH v3 4/7 mfd: omap: control: usb-phy: introduce the ctrl-module usb driver

Created a new platform driver for the platform device created by the control module mfd core, wrt usb. This driver has API's to power on/off the phy and the API's to write to musb mailbox.

Changes since previous version:
- Bandgap and usb phy: drivers are now independent from control module driver, they use their own functions to acess scm registers.
- Parent SCM platform device IOMEM resources is used to get the base address of SCM window.
- SCM Dependency was removed from Kconfig.
- Bandgap and usb phy: Added private spinlocks for bandgap and usb drivers.

(p.s. the mailbox for musb in omap4 is present in system control module)

[kishon at ti.com: wrote the original API's related to USB functions]
---
 drivers/usb/otg/Kconfig           |   12 +++
 drivers/usb/otg/Makefile          |    1 +
 drivers/usb/otg/omap4-usb-phy.c   |  170 +++++++++++++++++++++++++++++++++++++
 include/linux/usb/omap4_usb_phy.h |   53 ++++++++++++
 4 files changed, 236 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/otg/omap4-usb-phy.c
 create mode 100644 include/linux/usb/omap4_usb_phy.h
drivers/usb/otg/Kconfig +12 -0
index 5c87db0..0ed691b 100644
@@ -78,6 +78,18 @@ config TWL6030_USB
 	  are hooked to this driver through platform_data structure.
 	  The definition of internal PHY APIs are in the mach-omap2 layer.
 
+config OMAP4_USB_PHY
+	tristate "Texas Instruments OMAP4+ USB pin control driver"
+	help
+	  If you say yes here you get support for the Texas Instruments
+	  OMAP4+ USB pin control driver. The register set is part of system
+	  control module.
+
+	  USB phy in OMAP configures control module register for powering on
+	  the phy, configuring VBUSVALID, AVALID, IDDIG and SESSEND. For
+	  performing the above mentioned configuration, API's are added in
+	  by this children of the control module driver.
+
 config NOP_USB_XCEIV
 	tristate "NOP USB Transceiver Driver"
 	select USB_OTG_UTILS
drivers/usb/otg/Makefile +1 -0
index 41aa509..60c8c83 100644
@@ -13,6 +13,7 @@ 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_OMAP4_USB_PHY)	+= omap4-usb-phy.o
 obj-$(CONFIG_NOP_USB_XCEIV)	+= nop-usb-xceiv.o
 obj-$(CONFIG_USB_ULPI)		+= ulpi.o
 obj-$(CONFIG_USB_ULPI_VIEWPORT)	+= ulpi_viewport.o
drivers/usb/otg/omap4-usb-phy.c new file +170 -0

170 lines not on this page · raw message

include/linux/usb/omap4_usb_phy.h new file +53 -0

53 lines not on this page · raw message

Signature · 1 line
1.7.7.6
#1 lore raw

PATCH v3 4/7 mfd: omap: control: usb-phy: introduce the ctrl-module usb driver

Hello,

Quoted 106 lines · Konstantin Baydarov

Created a new platform driver for the platform device created by the control module mfd core, wrt usb. This driver has API's to power on/off the phy and the API's to write to musb mailbox.

Changes since previous version:
- Bandgap and usb phy: drivers are now independent from control module driver, they use their own functions to acess scm registers.
- Parent SCM platform device IOMEM resources is used to get the base address of SCM window.
- SCM Dependency was removed from Kconfig.
- Bandgap and usb phy: Added private spinlocks for bandgap and usb drivers.

(p.s. the mailbox for musb in omap4 is present in system control module)

[kishon at ti.com: wrote the original API's related to USB functions]
---
 drivers/usb/otg/Kconfig           |   12 +++
 drivers/usb/otg/Makefile          |    1 +
 drivers/usb/otg/omap4-usb-phy.c   |  170 +++++++++++++++++++++++++++++++++++++
 include/linux/usb/omap4_usb_phy.h |   53 ++++++++++++
 4 files changed, 236 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/otg/omap4-usb-phy.c
 create mode 100644 include/linux/usb/omap4_usb_phy.h
drivers/usb/otg/Kconfig +12 -0
index 5c87db0..0ed691b 100644
@@ -78,6 +78,18 @@ config TWL6030_USB
 	  are hooked to this driver through platform_data structure.
 	  The definition of internal PHY APIs are in the mach-omap2 layer.
 
+config OMAP4_USB_PHY
+	tristate "Texas Instruments OMAP4+ USB pin control driver"
+	help
+	  If you say yes here you get support for the Texas Instruments
+	  OMAP4+ USB pin control driver. The register set is part of system
+	  control module.
+
+	  USB phy in OMAP configures control module register for powering on
+	  the phy, configuring VBUSVALID, AVALID, IDDIG and SESSEND. For
+	  performing the above mentioned configuration, API's are added in
+	  by this children of the control module driver.
+
 config NOP_USB_XCEIV
 	tristate "NOP USB Transceiver Driver"
 	select USB_OTG_UTILS
drivers/usb/otg/Makefile +1 -0
index 41aa509..60c8c83 100644
@@ -13,6 +13,7 @@ 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_OMAP4_USB_PHY)	+= omap4-usb-phy.o
 obj-$(CONFIG_NOP_USB_XCEIV)	+= nop-usb-xceiv.o
 obj-$(CONFIG_USB_ULPI)		+= ulpi.o
 obj-$(CONFIG_USB_ULPI_VIEWPORT)	+= ulpi_viewport.o
drivers/usb/otg/omap4-usb-phy.c new file +38 -0
new file mode 100644
index 0000000..cbea2ea
@@ -0,0 +1,170 @@
+/*
+ * OMAP4 system control module driver, USB control children
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Contact:
+ *    Kishon Vijay Abraham I <[email protected]>
+ *    Eduardo Valentin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/usb/omap4_usb_phy.h>
+
+void __iomem *omap_usb_phy_base;
+spinlock_t omap_usb_phy_lock;
+
+static int omap_usb_phy_readl(u32 reg, u32 *val)
+{

drivers/usb/otg/omap4-usb-phy.c line 48

Quoted 10 lines
drivers/usb/otg/omap4-usb-phy.c new file +10 -0
+	if (!omap_usb_phy_base)
+		return -EINVAL;
+
+	*val = __raw_readl(omap_usb_phy_base + reg);
+	return 0;
+}
+
+/*
+ * TODO: Get rid from omap_usb_phy_writel() return value -
+ * It's useless.

if you do that remember to keep a WARN_ON in case the base address is not set.

drivers/usb/otg/omap4-usb-phy.c line 59

Quoted 11 lines
drivers/usb/otg/omap4-usb-phy.c new file +11 -0
+ */
+static int omap_usb_phy_writel(u32 val, u32 reg)
+{
+	unsigned long flags;
+
+	if (!omap_usb_phy_base)
+		return -EINVAL;
+
+	spin_lock_irqsave(&omap_usb_phy_lock, flags);
+	__raw_writel(val, omap_usb_phy_base + reg);
+	spin_unlock_irqrestore(&omap_usb_phy_lock, flags);

I think it is better to lock per operation than per write.

Quoted 52 lines
drivers/usb/otg/omap4-usb-phy.c new file +52 -0
+	return 0;
+}
+
+/**
+ * omap4_usb_phy_power - power on/off the phy using control module reg
+ * @dev: struct device *
+ * @on: 0 or 1, based on powering on or off the PHY
+ *
+ * omap_usb2 can call this API to power on or off the PHY.
+ */
+int omap4_usb_phy_power(struct device *dev, int on)
+{
+	u32 val;
+	int ret;
+
+	if (on) {
+		ret = omap_usb_phy_readl(CONTROL_DEV_CONF, &val);
+		if (!ret && (val & PHY_PD)) {
+			ret = omap_usb_phy_writel(~PHY_PD,
+						  CONTROL_DEV_CONF);
+			/* XXX: add proper documentation for this delay */
+			mdelay(200);
+		}
+	} else
+		ret = omap_usb_phy_writel(PHY_PD, CONTROL_DEV_CONF);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(omap4_usb_phy_power);
+
+/**
+ * omap4_usb_phy_mailbox - write to usb otg mailbox
+ * @dev: struct device *
+ * @val: the value to be written to the mailbox
+ *
+ * On detection of a device (ID pin is grounded), the phy should call this API
+ * to set AVALID, VBUSVALID and ID pin is grounded.
+ *
+ * When OMAP is connected to a host (OMAP in device mode), the phy should call
+ * this API to set AVALID, VBUSVALID and ID pin in high impedance.
+ *
+ * The phy should call this API, if OMAP is disconnected from host or device.
+ */
+int omap4_usb_phy_mailbox(struct device *dev, u32 val)
+{
+	return omap_usb_phy_writel(val, CONTROL_USBOTGHS_CONTROL);
+}
+EXPORT_SYMBOL_GPL(omap4_usb_phy_mailbox);
+
+static int __devinit omap_usb_phy_probe(struct platform_device *pdev)
+{
+	struct resource *io_res;

drivers/usb/otg/omap4-usb-phy.c line 121

Quoted 10 lines
drivers/usb/otg/omap4-usb-phy.c new file +10 -0
+	struct platform_device *pparent;
+
+	if (!pdev->dev.parent) {
+		dev_err(&pdev->dev, "No parent device!\n");
+		return -ENOMEM;
+	}
+
+	pparent = to_platform_device(pdev->dev.parent);
+
+	io_res = platform_get_resource(pparent, IORESOURCE_MEM, 0);

Can someone please explain me what do we gain by doing this at children code?

Quoted 112 lines
drivers/usb/otg/omap4-usb-phy.c new file +49 -0
+	if (!io_res)
+		return -ENOENT;
+
+	omap_usb_phy_base = ioremap(io_res->start, resource_size(io_res));
+	if (!omap_usb_phy_base)
+		return -ENOMEM;
+
+	/* Initialize register lock */
+	spin_lock_init(&omap_usb_phy_lock);
+
+	return 0;
+}
+
+static int __devexit omap_usb_phy_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static const struct of_device_id of_omap_usb_phy_match[] = {
+	{ .compatible = "ti,omap4-usb-phy", },
+	{ },
+};
+
+static struct platform_driver omap_usb_phy_driver = {
+	.probe = omap_usb_phy_probe,
+	.remove = __devexit_p(omap_usb_phy_remove),
+	.driver = {
+			.name	= "omap4-usb-phy",
+			.owner	= THIS_MODULE,
+			.of_match_table	= of_omap_usb_phy_match,
+	},
+};
+
+static int __init omap_usb_phy_init(void)
+{
+	return platform_driver_register(&omap_usb_phy_driver);
+}
+postcore_initcall(omap_usb_phy_init);
+
+static void __exit omap_usb_phy_exit(void)
+{
+	platform_driver_unregister(&omap_usb_phy_driver);
+}
+module_exit(omap_usb_phy_exit);
+
+MODULE_DESCRIPTION("OMAP4+ USB-phy driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform: omap4-usb-phy");
+MODULE_AUTHOR("Texas Instrument Inc.");
include/linux/usb/omap4_usb_phy.h new file +53 -0
new file mode 100644
index 0000000..b6a4701
@@ -0,0 +1,53 @@
+/*
+ * OMAP4 USB-phy
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Contact:
+ *    Kishon Vijay Abraham I <[email protected]>
+ *    Eduardo Valentin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __OMAP4_USB_PHY_H
+#define __OMAP4_USB_PHY_H
+
+#define	PHY_PD				0x1
+#define	AVALID				BIT(0)
+#define	BVALID				BIT(1)
+#define	VBUSVALID			BIT(2)
+#define	SESSEND				BIT(3)
+#define	IDDIG				BIT(4)
+#define	CONTROL_DEV_CONF		0x00000300
+#define	CONTROL_USBOTGHS_CONTROL	0x0000033C
+
+/* USB-PHY helpers */
+#if (defined(CONFIG_OMAP4_USB_PHY)) || (defined(CONFIG_OMAP4_USB_PHY_MODULE))
+extern int omap4_usb_phy_mailbox(struct device *dev, u32 val);
+extern int omap4_usb_phy_power(struct device *dev, int on);
+#else
+static inline int omap4_usb_phy_mailbox(struct device *dev, u32 val)
+{
+	return 0;
+}
+static inline int omap4_usb_phy_power(struct device *dev, int on)
+{
+	return 0;
+}
+#endif
+
+#endif
Signature · 1 line
1.7.7.6
#2 lore raw

PATCH v3 4/7 mfd: omap: control: usb-phy: introduce the ctrl-module usb driver

+Ajay

Quoted 313 lines · Eduardo Valentin

Hello,

Quoted 106 lines · Konstantin Baydarov

Created a new platform driver for the platform device created by the control module mfd core, wrt usb. This driver has API's to power on/off the phy and the API's to write to musb mailbox.

Changes since previous version:
- Bandgap and usb phy: drivers are now independent from control module driver, they use their own functions to acess scm registers.
- Parent SCM platform device IOMEM resources is used to get the base address of SCM window.
- SCM Dependency was removed from Kconfig.
- Bandgap and usb phy: Added private spinlocks for bandgap and usb drivers.

(p.s. the mailbox for musb in omap4 is present in system control module)

[kishon at ti.com: wrote the original API's related to USB functions]

---

?drivers/usb/otg/Kconfig ? ? ? ? ? | ? 12 +++
?drivers/usb/otg/Makefile ? ? ? ? ?| ? ?1 +
?drivers/usb/otg/omap4-usb-phy.c ? | ?170 +++++++++++++++++++++++++++++++++++++
?include/linux/usb/omap4_usb_phy.h | ? 53 ++++++++++++

?4 files changed, 236 insertions(+), 0 deletions(-) ?create mode 100644 drivers/usb/otg/omap4-usb-phy.c ?create mode 100644 include/linux/usb/omap4_usb_phy.h

drivers/usb/otg/Kconfig +0 -0
index 5c87db0..0ed691b 100644
@@ -78,6 +78,18 @@ config TWL6030_USB

? ? ? ? are hooked to this driver through platform_data structure. ? ? ? ? The definition of internal PHY APIs are in the mach-omap2 layer.

drivers/usb/otg/Kconfig +12 -0
+config OMAP4_USB_PHY
+ ? ? tristate "Texas Instruments OMAP4+ USB pin control driver"
+ ? ? help
+ ? ? ? If you say yes here you get support for the Texas Instruments
+ ? ? ? OMAP4+ USB pin control driver. The register set is part of system
+ ? ? ? control module.
+
+ ? ? ? USB phy in OMAP configures control module register for powering on
+ ? ? ? the phy, configuring VBUSVALID, AVALID, IDDIG and SESSEND. For
+ ? ? ? performing the above mentioned configuration, API's are added in
+ ? ? ? by this children of the control module driver.
+

?config NOP_USB_XCEIV
? ? ? tristate "NOP USB Transceiver Driver"
? ? ? select USB_OTG_UTILS

drivers/usb/otg/Makefile +0 -0
index 41aa509..60c8c83 100644
@@ -13,6 +13,7 @@ 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_OMAP4_USB_PHY) ?+= omap4-usb-phy.o ?obj-$(CONFIG_NOP_USB_XCEIV) ?+= nop-usb-xceiv.o ?obj-$(CONFIG_USB_ULPI) ? ? ? ? ? ? ? += ulpi.o ?obj-$(CONFIG_USB_ULPI_VIEWPORT) ? ? ?+= ulpi_viewport.o

drivers/usb/otg/omap4-usb-phy.c new file +38 -0
new file mode 100644
index 0000000..cbea2ea
@@ -0,0 +1,170 @@
+/*
+ * OMAP4 system control module driver, USB control children
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Contact:
+ * ? ?Kishon Vijay Abraham I <[email protected]>
+ * ? ?Eduardo Valentin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/usb/omap4_usb_phy.h>
+
+void __iomem *omap_usb_phy_base;
+spinlock_t omap_usb_phy_lock;
+
+static int omap_usb_phy_readl(u32 reg, u32 *val)
+{

drivers/usb/otg/omap4-usb-phy.c line 48

Quoted 10 lines
drivers/usb/otg/omap4-usb-phy.c new file +10 -0
+ ? ? if (!omap_usb_phy_base)
+ ? ? ? ? ? ? return -EINVAL;
+
+ ? ? *val = __raw_readl(omap_usb_phy_base + reg);
+ ? ? return 0;
+}
+
+/*
+ * TODO: Get rid from omap_usb_phy_writel() return value -
+ * It's useless.

if you do that remember to keep a WARN_ON in case the base address is not set.

drivers/usb/otg/omap4-usb-phy.c line 59

Quoted 11 lines
drivers/usb/otg/omap4-usb-phy.c new file +11 -0
+ */
+static int omap_usb_phy_writel(u32 val, u32 reg)
+{
+ ? ? unsigned long flags;
+
+ ? ? if (!omap_usb_phy_base)
+ ? ? ? ? ? ? return -EINVAL;
+
+ ? ? spin_lock_irqsave(&omap_usb_phy_lock, flags);
+ ? ? __raw_writel(val, omap_usb_phy_base + reg);
+ ? ? spin_unlock_irqrestore(&omap_usb_phy_lock, flags);

I think it is better to lock per operation than per write.

Quoted 52 lines
drivers/usb/otg/omap4-usb-phy.c new file +52 -0
+ ? ? return 0;
+}
+
+/**
+ * omap4_usb_phy_power - power on/off the phy using control module reg
+ * @dev: struct device *
+ * @on: 0 or 1, based on powering on or off the PHY
+ *
+ * omap_usb2 can call this API to power on or off the PHY.
+ */
+int omap4_usb_phy_power(struct device *dev, int on)
+{
+ ? ? u32 val;
+ ? ? int ret;
+
+ ? ? if (on) {
+ ? ? ? ? ? ? ret = omap_usb_phy_readl(CONTROL_DEV_CONF, &val);
+ ? ? ? ? ? ? if (!ret && (val & PHY_PD)) {
+ ? ? ? ? ? ? ? ? ? ? ret = omap_usb_phy_writel(~PHY_PD,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CONTROL_DEV_CONF);
+ ? ? ? ? ? ? ? ? ? ? /* XXX: add proper documentation for this delay */
+ ? ? ? ? ? ? ? ? ? ? mdelay(200);
+ ? ? ? ? ? ? }
+ ? ? } else
+ ? ? ? ? ? ? ret = omap_usb_phy_writel(PHY_PD, CONTROL_DEV_CONF);
+
+ ? ? return ret;
+}
+EXPORT_SYMBOL_GPL(omap4_usb_phy_power);
+
+/**
+ * omap4_usb_phy_mailbox - write to usb otg mailbox
+ * @dev: struct device *
+ * @val: the value to be written to the mailbox
+ *
+ * On detection of a device (ID pin is grounded), the phy should call this API
+ * to set AVALID, VBUSVALID and ID pin is grounded.
+ *
+ * When OMAP is connected to a host (OMAP in device mode), the phy should call
+ * this API to set AVALID, VBUSVALID and ID pin in high impedance.
+ *
+ * The phy should call this API, if OMAP is disconnected from host or device.
+ */
+int omap4_usb_phy_mailbox(struct device *dev, u32 val)
+{
+ ? ? return omap_usb_phy_writel(val, CONTROL_USBOTGHS_CONTROL);
+}
+EXPORT_SYMBOL_GPL(omap4_usb_phy_mailbox);
+
+static int __devinit omap_usb_phy_probe(struct platform_device *pdev)
+{
+ ? ? struct resource *io_res;

drivers/usb/otg/omap4-usb-phy.c

Quoted 10 lines
drivers/usb/otg/omap4-usb-phy.c new file +10 -0
+ ? ? struct platform_device *pparent;
+
+ ? ? if (!pdev->dev.parent) {
+ ? ? ? ? ? ? dev_err(&pdev->dev, "No parent device!\n");
+ ? ? ? ? ? ? return -ENOMEM;
+ ? ? }
+
+ ? ? pparent = to_platform_device(pdev->dev.parent);
+
+ ? ? io_res = platform_get_resource(pparent, IORESOURCE_MEM, 0);

Can someone please explain me what do we gain by doing this at children code?

Quoted 112 lines
drivers/usb/otg/omap4-usb-phy.c new file +49 -0
+ ? ? if (!io_res)
+ ? ? ? ? ? ? return -ENOENT;
+
+ ? ? omap_usb_phy_base = ioremap(io_res->start, resource_size(io_res));
+ ? ? if (!omap_usb_phy_base)
+ ? ? ? ? ? ? return -ENOMEM;
+
+ ? ? /* Initialize register lock */
+ ? ? spin_lock_init(&omap_usb_phy_lock);
+
+ ? ? return 0;
+}
+
+static int __devexit omap_usb_phy_remove(struct platform_device *pdev)
+{
+ ? ? return 0;
+}
+
+static const struct of_device_id of_omap_usb_phy_match[] = {
+ ? ? { .compatible = "ti,omap4-usb-phy", },
+ ? ? { },
+};
+
+static struct platform_driver omap_usb_phy_driver = {
+ ? ? .probe = omap_usb_phy_probe,
+ ? ? .remove = __devexit_p(omap_usb_phy_remove),
+ ? ? .driver = {
+ ? ? ? ? ? ? ? ? ? ? .name ? = "omap4-usb-phy",
+ ? ? ? ? ? ? ? ? ? ? .owner ?= THIS_MODULE,
+ ? ? ? ? ? ? ? ? ? ? .of_match_table = of_omap_usb_phy_match,
+ ? ? },
+};
+
+static int __init omap_usb_phy_init(void)
+{
+ ? ? return platform_driver_register(&omap_usb_phy_driver);
+}
+postcore_initcall(omap_usb_phy_init);
+
+static void __exit omap_usb_phy_exit(void)
+{
+ ? ? platform_driver_unregister(&omap_usb_phy_driver);
+}
+module_exit(omap_usb_phy_exit);
+
+MODULE_DESCRIPTION("OMAP4+ USB-phy driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform: omap4-usb-phy");
+MODULE_AUTHOR("Texas Instrument Inc.");
include/linux/usb/omap4_usb_phy.h new file +53 -1
new file mode 100644
index 0000000..b6a4701
@@ -0,0 +1,53 @@
+/*
+ * OMAP4 USB-phy
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Contact:
+ * ? ?Kishon Vijay Abraham I <[email protected]>
+ * ? ?Eduardo Valentin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __OMAP4_USB_PHY_H
+#define __OMAP4_USB_PHY_H
+
+#define ? ? ?PHY_PD ? ? ? ? ? ? ? ? ? ? ? ? ?0x1
+#define ? ? ?AVALID ? ? ? ? ? ? ? ? ? ? ? ? ?BIT(0)
+#define ? ? ?BVALID ? ? ? ? ? ? ? ? ? ? ? ? ?BIT(1)
+#define ? ? ?VBUSVALID ? ? ? ? ? ? ? ? ? ? ? BIT(2)
+#define ? ? ?SESSEND ? ? ? ? ? ? ? ? ? ? ? ? BIT(3)
+#define ? ? ?IDDIG ? ? ? ? ? ? ? ? ? ? ? ? ? BIT(4)
+#define ? ? ?CONTROL_DEV_CONF ? ? ? ? ? ? ? ?0x00000300
+#define ? ? ?CONTROL_USBOTGHS_CONTROL ? ? ? ?0x0000033C
+
+/* USB-PHY helpers */
+#if (defined(CONFIG_OMAP4_USB_PHY)) || (defined(CONFIG_OMAP4_USB_PHY_MODULE))
+extern int omap4_usb_phy_mailbox(struct device *dev, u32 val);
+extern int omap4_usb_phy_power(struct device *dev, int on);
+#else
+static inline int omap4_usb_phy_mailbox(struct device *dev, u32 val)
+{
+ ? ? return 0;
+}
+static inline int omap4_usb_phy_power(struct device *dev, int on)
+{
+ ? ? return 0;
+}
+#endif
+
+#endif
--

1.7.7.6

#3 lore raw

PATCH v3 4/7 mfd: omap: control: usb-phy: introduce the ctrl-module usb driver

Hi,

Quoted 8 lines
Quoted 5 lines · Eduardo Valentin

Hello,

Quoted 2 lines · Konstantin Baydarov

Created a new platform driver for the platform device created by the control module mfd core, wrt usb. This driver has API's to power

on/off the phy and the API's to write to musb mailbox.

USB PHY on am335x platform also need to be enabled using phy control register in system control module register space.

I think we should make this driver generic enough so that it can be used by am335x like platforms also to avoid duplication of such drivers.

Ajay

Quoted 339 lines
Quoted 3 lines
Quoted 3 lines

Changes since previous version:
- Bandgap and usb phy: drivers are now independent from control

module driver, they use

Quoted 2 lines
Quoted 2 lines

their own functions to acess scm registers.
- Parent SCM platform device IOMEM resources is used to get the base

address of SCM window.

Quoted 2 lines
Quoted 2 lines

- SCM Dependency was removed from Kconfig.
- Bandgap and usb phy: Added private spinlocks for bandgap and usb

drivers.

Quoted 4 lines
Quoted 4 lines

(p.s. the mailbox for musb in omap4 is present in system control module)

Quoted 8 lines
Quoted 8 lines
[kishon at ti.com: wrote the original API's related to USB functions]

---

?drivers/usb/otg/Kconfig ? ? ? ? ? | ? 12 +++
?drivers/usb/otg/Makefile ? ? ? ? ?| ? ?1 +
?drivers/usb/otg/omap4-usb-phy.c ? | ?170

+++++++++++++++++++++++++++++++++++++

Quoted 5 lines
Quoted 5 lines

?include/linux/usb/omap4_usb_phy.h | ? 53 ++++++++++++ ?4 files changed, 236 insertions(+), 0 deletions(-) ?create mode 100644 drivers/usb/otg/omap4-usb-phy.c ?create mode 100644 include/linux/usb/omap4_usb_phy.h

Quoted 7 lines
Quoted 7 lines
drivers/usb/otg/Kconfig +0 -0
index 5c87db0..0ed691b 100644
@@ -78,6 +78,18 @@ config TWL6030_USB

? ? ? ? are hooked to this driver through platform_data structure. ? ? ? ? The definition of internal PHY APIs are in the mach-omap2

layer.

Quoted 5 lines
Quoted 5 lines

+config OMAP4_USB_PHY
+ ? ? tristate "Texas Instruments OMAP4+ USB pin control driver"
+ ? ? help
+ ? ? ? If you say yes here you get support for the Texas

Instruments

Quoted 1 line
Quoted 1 line

+ ? ? ? OMAP4+ USB pin control driver. The register set is part of

system

Quoted 3 lines
Quoted 3 lines

+ ? ? ? control module.
+
+ ? ? ? USB phy in OMAP configures control module register for

powering on

Quoted 1 line
Quoted 1 line

+ ? ? ? the phy, configuring VBUSVALID, AVALID, IDDIG and SESSEND.

For

Quoted 1 line
Quoted 1 line

+ ? ? ? performing the above mentioned configuration, API's are

added in

Quoted 10 lines
Quoted 10 lines

+ ? ? ? by this children of the control module driver. +
?config NOP_USB_XCEIV
? ? ? tristate "NOP USB Transceiver Driver"
? ? ? select USB_OTG_UTILS

drivers/usb/otg/Makefile +0 -0
index 41aa509..60c8c83 100644
@@ -13,6 +13,7 @@ obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o
Quoted 8 lines

Review

Quoted 8 lines

?obj-$(CONFIG_ISP1301_OMAP) ? += isp1301_omap.o ?obj-$(CONFIG_TWL4030_USB) ? ?+= twl4030-usb.o ?obj-$(CONFIG_TWL6030_USB) ? ?+= twl6030-usb.o +obj-$(CONFIG_OMAP4_USB_PHY) ?+= omap4-usb-phy.o ?obj-$(CONFIG_NOP_USB_XCEIV) ?+= nop-usb-xceiv.o ?obj-$(CONFIG_USB_ULPI) ? ? ? ? ? ? ? += ulpi.o ?obj-$(CONFIG_USB_ULPI_VIEWPORT) ? ? ?+= ulpi_viewport.o

(quoted diff) +0 -0

b/drivers/usb/otg/omap4-usb-phy.c

Quoted 9 lines

drivers/usb/otg/omap4-usb-phy.c line 4

Quoted 9 lines

new file mode 100644
index 0000000..cbea2ea

drivers/usb/otg/omap4-usb-phy.c new file +4 -0
@@ -0,0 +1,170 @@
+/*
+ * OMAP4 system control module driver, USB control children
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated -

http://www.ti.com/

Quoted 10 lines

drivers/usb/otg/omap4-usb-phy.c

Quoted 10 lines
drivers/usb/otg/omap4-usb-phy.c new file +10 -0
+ *
+ * Contact:
+ * ? ?Kishon Vijay Abraham I <[email protected]>
+ * ? ?Eduardo Valentin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,

but

Quoted 2 lines

drivers/usb/otg/omap4-usb-phy.c line 16

Quoted 2 lines
drivers/usb/otg/omap4-usb-phy.c new file +2 -0
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the

GNU

Quoted 3 lines

drivers/usb/otg/omap4-usb-phy.c

Quoted 3 lines
drivers/usb/otg/omap4-usb-phy.c new file +3 -0
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public

License

Quoted 23 lines
Quoted 23 lines
drivers/usb/otg/omap4-usb-phy.c new file +23 -0
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/usb/omap4_usb_phy.h>
+
+void __iomem *omap_usb_phy_base;
+spinlock_t omap_usb_phy_lock;
+
+static int omap_usb_phy_readl(u32 reg, u32 *val)
+{
+ ? ? if (!omap_usb_phy_base)
+ ? ? ? ? ? ? return -EINVAL;
+
+ ? ? *val = __raw_readl(omap_usb_phy_base + reg);
Quoted 8 lines

drivers/usb/otg/omap4-usb-phy.c line 48

Quoted 6 lines
drivers/usb/otg/omap4-usb-phy.c new file +6 -0
+ ? ? return 0;
+}
+
+/*
+ * TODO: Get rid from omap_usb_phy_writel() return value -
+ * It's useless.

if you do that remember to keep a WARN_ON in case the base address is

not set.

Quoted 15 lines

drivers/usb/otg/omap4-usb-phy.c line 59

Quoted 12 lines
drivers/usb/otg/omap4-usb-phy.c new file +11 -0
+ */
+static int omap_usb_phy_writel(u32 val, u32 reg)
+{
+ ? ? unsigned long flags;
+
+ ? ? if (!omap_usb_phy_base)
+ ? ? ? ? ? ? return -EINVAL;
+
+ ? ? spin_lock_irqsave(&omap_usb_phy_lock, flags);
+ ? ? __raw_writel(val, omap_usb_phy_base + reg);
+ ? ? spin_unlock_irqrestore(&omap_usb_phy_lock, flags);

I think it is better to lock per operation than per write.

Quoted 5 lines

drivers/usb/otg/omap4-usb-phy.c

Quoted 5 lines
drivers/usb/otg/omap4-usb-phy.c new file +5 -0
+ ? ? return 0;
+}
+
+/**
+ * omap4_usb_phy_power - power on/off the phy using control module

reg

Quoted 8 lines
Quoted 8 lines
drivers/usb/otg/omap4-usb-phy.c new file +8 -0
+ * @dev: struct device *
+ * @on: 0 or 1, based on powering on or off the PHY
+ *
+ * omap_usb2 can call this API to power on or off the PHY.
+ */
+int omap4_usb_phy_power(struct device *dev, int on)
+{
+ ? ? u32 val;
Quoted 8 lines

drivers/usb/otg/omap4-usb-phy.c line 80

Quoted 8 lines
drivers/usb/otg/omap4-usb-phy.c new file +8 -0
+ ? ? int ret;
+
+ ? ? if (on) {
+ ? ? ? ? ? ? ret = omap_usb_phy_readl(CONTROL_DEV_CONF, &val);
+ ? ? ? ? ? ? if (!ret && (val & PHY_PD)) {
+ ? ? ? ? ? ? ? ? ? ? ret = omap_usb_phy_writel(~PHY_PD,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CONTROL_DEV_CONF);
+ ? ? ? ? ? ? ? ? ? ? /* XXX: add proper documentation for this

delay */

Quoted 7 lines
Quoted 7 lines
drivers/usb/otg/omap4-usb-phy.c new file +7 -0
+ ? ? ? ? ? ? ? ? ? ? mdelay(200);
+ ? ? ? ? ? ? }
+ ? ? } else
+ ? ? ? ? ? ? ret = omap_usb_phy_writel(PHY_PD, CONTROL_DEV_CONF);
+
+ ? ? return ret;
+}
Quoted 8 lines

drivers/usb/otg/omap4-usb-phy.c

Quoted 8 lines
drivers/usb/otg/omap4-usb-phy.c new file +8 -0
+EXPORT_SYMBOL_GPL(omap4_usb_phy_power);
+
+/**
+ * omap4_usb_phy_mailbox - write to usb otg mailbox
+ * @dev: struct device *
+ * @val: the value to be written to the mailbox
+ *
+ * On detection of a device (ID pin is grounded), the phy should

call this API

Quoted 3 lines

drivers/usb/otg/omap4-usb-phy.c

Quoted 3 lines
drivers/usb/otg/omap4-usb-phy.c new file +3 -0
+ * to set AVALID, VBUSVALID and ID pin is grounded.
+ *
+ * When OMAP is connected to a host (OMAP in device mode), the phy

should call

Quoted 3 lines

drivers/usb/otg/omap4-usb-phy.c

Quoted 3 lines
drivers/usb/otg/omap4-usb-phy.c new file +3 -0
+ * this API to set AVALID, VBUSVALID and ID pin in high impedance.
+ *
+ * The phy should call this API, if OMAP is disconnected from host

or device.

Quoted 8 lines

drivers/usb/otg/omap4-usb-phy.c

Quoted 8 lines
drivers/usb/otg/omap4-usb-phy.c new file +8 -0
+ */
+int omap4_usb_phy_mailbox(struct device *dev, u32 val)
+{
+ ? ? return omap_usb_phy_writel(val, CONTROL_USBOTGHS_CONTROL);
+}
+EXPORT_SYMBOL_GPL(omap4_usb_phy_mailbox);
+
+static int __devinit omap_usb_phy_probe(struct platform_device

*pdev)

Quoted 6 lines
Quoted 6 lines
drivers/usb/otg/omap4-usb-phy.c new file +6 -0
+{
+ ? ? struct resource *io_res;
+ ? ? struct platform_device *pparent;
+
+ ? ? if (!pdev->dev.parent) {
+ ? ? ? ? ? ? dev_err(&pdev->dev, "No parent device!\n");
Quoted 8 lines

drivers/usb/otg/omap4-usb-phy.c line 121

Quoted 6 lines
drivers/usb/otg/omap4-usb-phy.c new file +6 -0
+ ? ? ? ? ? ? return -ENOMEM;
+ ? ? }
+
+ ? ? pparent = to_platform_device(pdev->dev.parent);
+
+ ? ? io_res = platform_get_resource(pparent, IORESOURCE_MEM, 0);

Can someone please explain me what do we gain by doing this at

children code?

Quoted 5 lines

drivers/usb/otg/omap4-usb-phy.c line 125

Quoted 5 lines
drivers/usb/otg/omap4-usb-phy.c new file +4 -0
+ ? ? if (!io_res)
+ ? ? ? ? ? ? return -ENOENT;
+
+ ? ? omap_usb_phy_base = ioremap(io_res->start,

resource_size(io_res));

Quoted 10 lines

drivers/usb/otg/omap4-usb-phy.c line 135

Quoted 10 lines
drivers/usb/otg/omap4-usb-phy.c new file +10 -0
+ ? ? if (!omap_usb_phy_base)
+ ? ? ? ? ? ? return -ENOMEM;
+
+ ? ? /* Initialize register lock */
+ ? ? spin_lock_init(&omap_usb_phy_lock);
+
+ ? ? return 0;
+}
+
+static int __devexit omap_usb_phy_remove(struct platform_device

*pdev)

Quoted 28 lines
Quoted 28 lines
drivers/usb/otg/omap4-usb-phy.c new file +28 -0
+{
+ ? ? return 0;
+}
+
+static const struct of_device_id of_omap_usb_phy_match[] = {
+ ? ? { .compatible = "ti,omap4-usb-phy", },
+ ? ? { },
+};
+
+static struct platform_driver omap_usb_phy_driver = {
+ ? ? .probe = omap_usb_phy_probe,
+ ? ? .remove = __devexit_p(omap_usb_phy_remove),
+ ? ? .driver = {
+ ? ? ? ? ? ? ? ? ? ? .name ? = "omap4-usb-phy",
+ ? ? ? ? ? ? ? ? ? ? .owner ?= THIS_MODULE,
+ ? ? ? ? ? ? ? ? ? ? .of_match_table = of_omap_usb_phy_match,
+ ? ? },
+};
+
+static int __init omap_usb_phy_init(void)
+{
+ ? ? return platform_driver_register(&omap_usb_phy_driver);
+}
+postcore_initcall(omap_usb_phy_init);
+
+static void __exit omap_usb_phy_exit(void)
+{
+ ? ? platform_driver_unregister(&omap_usb_phy_driver);
Quoted 8 lines

Review

Quoted 8 lines
drivers/usb/otg/omap4-usb-phy.c new file +7 -0
+}
+module_exit(omap_usb_phy_exit);
+
+MODULE_DESCRIPTION("OMAP4+ USB-phy driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform: omap4-usb-phy");
+MODULE_AUTHOR("Texas Instrument Inc.");
(quoted diff) +0 -0

b/include/linux/usb/omap4_usb_phy.h

Quoted 9 lines

include/linux/usb/omap4_usb_phy.h line 4

Quoted 9 lines

new file mode 100644
index 0000000..b6a4701

include/linux/usb/omap4_usb_phy.h new file +4 -0
@@ -0,0 +1,53 @@
+/*
+ * OMAP4 USB-phy
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated -

http://www.ti.com/

Quoted 10 lines

include/linux/usb/omap4_usb_phy.h line 14

Quoted 10 lines
include/linux/usb/omap4_usb_phy.h new file +10 -0
+ *
+ * Contact:
+ * ? ?Kishon Vijay Abraham I <[email protected]>
+ * ? ?Eduardo Valentin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,

but

Quoted 2 lines

include/linux/usb/omap4_usb_phy.h line 16

Quoted 2 lines
include/linux/usb/omap4_usb_phy.h new file +2 -0
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the

GNU

Quoted 3 lines

include/linux/usb/omap4_usb_phy.h line 19

Quoted 3 lines
include/linux/usb/omap4_usb_phy.h new file +3 -0
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public

License

Quoted 12 lines
Quoted 12 lines
include/linux/usb/omap4_usb_phy.h new file +12 -0
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __OMAP4_USB_PHY_H
+#define __OMAP4_USB_PHY_H
+
+#define ? ? ?PHY_PD ? ? ? ? ? ? ? ? ? ? ? ? ?0x1
+#define ? ? ?AVALID ? ? ? ? ? ? ? ? ? ? ? ? ?BIT(0)
+#define ? ? ?BVALID ? ? ? ? ? ? ? ? ? ? ? ? ?BIT(1)
Quoted 8 lines

include/linux/usb/omap4_usb_phy.h line 39

Quoted 8 lines
include/linux/usb/omap4_usb_phy.h new file +8 -0
+#define ? ? ?VBUSVALID ? ? ? ? ? ? ? ? ? ? ? BIT(2)
+#define ? ? ?SESSEND ? ? ? ? ? ? ? ? ? ? ? ? BIT(3)
+#define ? ? ?IDDIG ? ? ? ? ? ? ? ? ? ? ? ? ? BIT(4)
+#define ? ? ?CONTROL_DEV_CONF ? ? ? ? ? ? ? ?0x00000300
+#define ? ? ?CONTROL_USBOTGHS_CONTROL ? ? ? ?0x0000033C
+
+/* USB-PHY helpers */
+#if (defined(CONFIG_OMAP4_USB_PHY)) ||

(defined(CONFIG_OMAP4_USB_PHY_MODULE))

Quoted 4 lines

include/linux/usb/omap4_usb_phy.h

Quoted 4 lines
include/linux/usb/omap4_usb_phy.h new file +4 -0
+extern int omap4_usb_phy_mailbox(struct device *dev, u32 val);
+extern int omap4_usb_phy_power(struct device *dev, int on);
+#else
+static inline int omap4_usb_phy_mailbox(struct device *dev, u32

val)

Quoted 14 lines
Quoted 14 lines
include/linux/usb/omap4_usb_phy.h new file +10 -1
+{
+ ? ? return 0;
+}
+static inline int omap4_usb_phy_power(struct device *dev, int on)
+{
+ ? ? return 0;
+}
+#endif
+
+#endif
--

1.7.7.6