Thread (4 messages) 4 messages, 4 authors, 2012-07-09
DORMANTno replies

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

From: Gupta, Ajay Kumar <hidden>
Date: 2012-07-09 09:29:19
Also in: linux-omap, linux-pm

Hi,
On Thu, Jun 28, 2012 at 10:28 AM, Eduardo Valentin
[off-list ref] wrote:
quoted
Hello,

On Wed, Jun 27, 2012 at 10:05:00PM +0400, Konstantin Baydarov wrote:
quoted
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
quoted
Changes since previous version:
- Bandgap and usb phy: drivers are now independent from control
module driver, they use
quoted
quoted
their own functions to acess scm registers.
- Parent SCM platform device IOMEM resources is used to get the base
address of SCM window.
quoted
quoted
- SCM Dependency was removed from Kconfig.
- Bandgap and usb phy: Added private spinlocks for bandgap and usb
drivers.
quoted
quoted
(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]
Signed-off-by: Konstantin Baydarov <redacted>
Signed-off-by: Kishon Vijay Abraham I <redacted>
Signed-off-by: Eduardo Valentin <redacted>
---
?drivers/usb/otg/Kconfig ? ? ? ? ? | ? 12 +++
?drivers/usb/otg/Makefile ? ? ? ? ?| ? ?1 +
?drivers/usb/otg/omap4-usb-phy.c ? | ?170
+++++++++++++++++++++++++++++++++++++
quoted
quoted
?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
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index 5c87db0..0ed691b 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -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
quoted
+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
quoted
+ ? ? ? OMAP4+ USB pin control driver. The register set is part of
system
quoted
quoted
+ ? ? ? control module.
+
+ ? ? ? USB phy in OMAP configures control module register for
powering on
quoted
quoted
+ ? ? ? the phy, configuring VBUSVALID, AVALID, IDDIG and SESSEND.
For
quoted
quoted
+ ? ? ? performing the above mentioned configuration, API's are
added in
quoted
quoted
+ ? ? ? by this children of the control module driver.
+
?config NOP_USB_XCEIV
? ? ? tristate "NOP USB Transceiver Driver"
? ? ? select USB_OTG_UTILS
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile
index 41aa509..60c8c83 100644
--- a/drivers/usb/otg/Makefile
+++ b/drivers/usb/otg/Makefile
@@ -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
diff --git a/drivers/usb/otg/omap4-usb-phy.c
b/drivers/usb/otg/omap4-usb-phy.c
quoted
quoted
new file mode 100644
index 0000000..cbea2ea
--- /dev/null
+++ b/drivers/usb/otg/omap4-usb-phy.c
@@ -0,0 +1,170 @@
+/*
+ * OMAP4 system control module driver, USB control children
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated -
http://www.ti.com/
quoted
quoted
+ *
+ * Contact:
+ * ? ?Kishon Vijay Abraham I [off-list ref]
+ * ? ?Eduardo Valentin [off-list ref]
+ *
+ * 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
quoted
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
GNU
quoted
quoted
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
License
quoted
quoted
+ * 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);
+ ? ? 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
quoted
+ */
+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
+ ? ? return 0;
+}
+
+/**
+ * omap4_usb_phy_power - power on/off the phy using control module
reg
quoted
quoted
+ * @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 */
quoted
quoted
+ ? ? ? ? ? ? ? ? ? ? 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
quoted
quoted
+ * 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
quoted
+ * 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
quoted
+ */
+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
quoted
+{
+ ? ? struct resource *io_res;
+ ? ? 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
quoted
+ ? ? if (!io_res)
+ ? ? ? ? ? ? return -ENOENT;
+
+ ? ? omap_usb_phy_base = ioremap(io_res->start,
resource_size(io_res));
quoted
quoted
+ ? ? 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
quoted
+{
+ ? ? 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.");
diff --git a/include/linux/usb/omap4_usb_phy.h
b/include/linux/usb/omap4_usb_phy.h
quoted
quoted
new file mode 100644
index 0000000..b6a4701
--- /dev/null
+++ b/include/linux/usb/omap4_usb_phy.h
@@ -0,0 +1,53 @@
+/*
+ * OMAP4 USB-phy
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated -
http://www.ti.com/
quoted
quoted
+ *
+ * Contact:
+ * ? ?Kishon Vijay Abraham I [off-list ref]
+ * ? ?Eduardo Valentin [off-list ref]
+ *
+ * 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
quoted
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
GNU
quoted
quoted
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
License
quoted
quoted
+ * 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))
quoted
quoted
+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
quoted
+{
+ ? ? return 0;
+}
+static inline int omap4_usb_phy_power(struct device *dev, int on)
+{
+ ? ? return 0;
+}
+#endif
+
+#endif
--
1.7.7.6
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help