Thread (9 messages) 9 messages, 4 authors, 2012-06-20

[RFC PATCH 1/3] drivers: usb: otg: add a new driver for omap usb2 phy

From: Shilimkar, Santosh <hidden>
Date: 2012-05-30 15:05:25
Also in: linux-omap, lkml

On Wed, May 30, 2012 at 8:04 PM, Kishon Vijay Abraham I [off-list ref] wrote:
All phy related programming like enabling/disabling the clocks, powering
on/off the phy is taken care of by this driver. It is also used for OTG
related functionality like srp.

Cc: Felipe Balbi <redacted>
Signed-off-by: Kishon Vijay Abraham I <redacted>
---
?drivers/usb/otg/Kconfig ? ? ? ? ? | ? 17 ++-
?drivers/usb/otg/Makefile ? ? ? ? ?| ? ?1 +
?drivers/usb/otg/omap-usb2.c ? ? ? | ?232 +++++++++++++++++++++++++++++++++++++
?include/linux/usb/omap_usb.h ? ? ?| ? 47 ++++++++
?include/linux/usb/phy_companion.h | ? 34 ++++++
?5 files changed, 327 insertions(+), 4 deletions(-)
?create mode 100644 drivers/usb/otg/omap-usb2.c
?create mode 100644 include/linux/usb/omap_usb.h
?create mode 100644 include/linux/usb/phy_companion.h
[...]
quoted hunk ↗ jump to hunk
diff --git a/drivers/usb/otg/omap-usb2.c b/drivers/usb/otg/omap-usb2.c
new file mode 100644
index 0000000..ccd74b6
--- /dev/null
+++ b/drivers/usb/otg/omap-usb2.c
@@ -0,0 +1,232 @@
+/*
+ * omap-usb2.c - USB PHY, talking to musb controller in OMAP.
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com
s/2011/2012
+ * 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: Kishon Vijay Abraham I [off-list ref]
+ *
+ * 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/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/usb/omap_usb.h>
+#include <linux/usb/phy_companion.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+#include <linux/delay.h>
Do you need it ?
+#include <linux/mfd/omap_control.h>
+#include <linux/usb/omap4_usb_phy.h>
+
+/**
+ * omap_usb2_set_comparator - links the comparator present in the sytem with
+ * ? ? this phy
+ * @comparator - the companion phy(comparator) for this phy
+ *
+ * The phy companion driver should call this API passing the phy_companion
+ * filled with set_vbus and start_srp to be used by usb phy.
+ *
+ * For use by phy companion driver
+ */
+void omap_usb2_set_comparator(struct phy_companion *comparator)
+{
+ ? ? ? struct usb_phy ?*x = usb_get_phy(USB_PHY_TYPE_USB2);
+ ? ? ? struct omap_usb *phy = phy_to_omapusb(x);
+
+ ? ? ? phy->comparator = comparator;
+}
+EXPORT_SYMBOL_GPL(omap_usb2_set_comparator);
+
+static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled)
+{
+ ? ? ? struct omap_usb *phy = phy_to_omapusb(otg->phy);
+
+ ? ? ? if (!phy->comparator)
+ ? ? ? ? ? ? ? return -ENODEV;
+
+ ? ? ? return phy->comparator->set_vbus(phy->comparator, enabled);
+}
+
+static int omap_usb_start_srp(struct usb_otg *otg)
+{
+ ? ? ? struct omap_usb *phy = phy_to_omapusb(otg->phy);
+
+ ? ? ? if (!phy->comparator)
+ ? ? ? ? ? ? ? return -ENODEV;
+
+ ? ? ? return phy->comparator->start_srp(phy->comparator);
+}
+
+static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host)
+{
+ ? ? ? struct usb_phy ?*phy = otg->phy;
+
+ ? ? ? otg->host = host;
+ ? ? ? if (!host)
+ ? ? ? ? ? ? ? phy->state = OTG_STATE_UNDEFINED;
+
+ ? ? ? return 0;
+}
+
+static int omap_usb_set_peripheral(struct usb_otg *otg,
+ ? ? ? ? ? ? ? struct usb_gadget *gadget)
+{
+ ? ? ? struct usb_phy ?*phy = otg->phy;
+
+ ? ? ? otg->gadget = gadget;
+ ? ? ? if (!gadget)
+ ? ? ? ? ? ? ? phy->state = OTG_STATE_UNDEFINED;
+
+ ? ? ? return 0;
+}
+
+static int omap_usb2_suspend(struct usb_phy *x, int suspend)
+{
+ ? ? ? struct omap_usb *phy = phy_to_omapusb(x);
+
+ ? ? ? if (suspend && !phy->is_suspended) {
+ ? ? ? ? ? ? ? pm_runtime_put_sync(phy->dev);
+ ? ? ? ? ? ? ? phy->is_suspended = 1;
+ ? ? ? } else if (!suspend && phy->is_suspended) {
+ ? ? ? ? ? ? ? pm_runtime_get_sync(phy->dev);
+ ? ? ? ? ? ? ? phy->is_suspended = 0;
+ ? ? ? }
+
+ ? ? ? return 0;
+}
+
+static int __devinit omap_usb2_probe(struct platform_device *pdev)
+{
+ ? ? ? struct omap_usb ? ? ? ? ? ? ? ? *phy;
+ ? ? ? struct usb_otg ? ? ? ? ? ? ? ? ?*otg;
+
+ ? ? ? phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
+ ? ? ? if (!phy) {
+ ? ? ? ? ? ? ? dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n");
+ ? ? ? ? ? ? ? return -ENOMEM;
+ ? ? ? }
+
+ ? ? ? otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
+ ? ? ? if (!otg) {
+ ? ? ? ? ? ? ? dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n");
+ ? ? ? ? ? ? ? return -ENOMEM;
+ ? ? ? }
+
+ ? ? ? phy->dev ? ? ? ? ? ? ? ?= &pdev->dev;
+
+ ? ? ? phy->phy.dev ? ? ? ? ? ?= phy->dev;
+ ? ? ? phy->phy.label ? ? ? ? ?= "omap-usb2";
+ ? ? ? phy->phy.set_suspend ? ?= omap_usb2_suspend;
+ ? ? ? phy->phy.otg ? ? ? ? ? ?= otg;
+
+ ? ? ? phy->control_dev ? ? ? ?= omap_control_get();
+ ? ? ? if (IS_ERR(phy->control_dev)) {
+ ? ? ? ? ? ? ? dev_err(&pdev->dev, "no control device present in system\n");
+ ? ? ? ? ? ? ? return PTR_ERR(phy->control_dev);
+ ? ? ? }
+
+ ? ? ? phy->is_suspended ? ? ? = 1;
+ ? ? ? omap4_usb_phy_power(phy->control_dev, 0);
+
+ ? ? ? otg->set_host ? ? ? ? ? = omap_usb_set_host;
+ ? ? ? otg->set_peripheral ? ? = omap_usb_set_peripheral;
+ ? ? ? otg->set_vbus ? ? ? ? ? = omap_usb_set_vbus;
+ ? ? ? otg->start_srp ? ? ? ? ?= omap_usb_start_srp;
+ ? ? ? otg->phy ? ? ? ? ? ? ? ?= &phy->phy;
+
+ ? ? ? phy->wkupclk = clk_get(phy->dev, "usb_phy_cm_clk32k");
Error check missing here.
+
+ ? ? ? usb_add_phy(&phy->phy, USB_PHY_TYPE_USB2);
+
unnecessary extra line
+ ? ? ? platform_set_drvdata(pdev, phy);
+
this one too
+ ? ? ? pm_runtime_enable(phy->dev);
+
+ ? ? ? return 0;
+}
+
+static int __devexit omap_usb2_remove(struct platform_device *pdev)
+{
+ ? ? ? struct omap_usb *phy = platform_get_drvdata(pdev);
+
+ ? ? ? usb_remove_phy(&phy->phy);
+ ? ? ? platform_set_drvdata(pdev, NULL);
+
+ ? ? ? return 0;
+}
+
+#ifdef CONFIG_PM
s/ CONFIG_PM/CONFIG_SUSPEND
otherwise you will get build warning with !CONFIG_SUSPEND
quoted hunk ↗ jump to hunk
+
+static int omap_usb2_runtime_suspend(struct device *dev)
+{
+ ? ? ? struct platform_device ?*pdev = to_platform_device(dev);
+ ? ? ? struct omap_usb *phy = platform_get_drvdata(pdev);
+
+ ? ? ? clk_disable(phy->wkupclk);
+ ? ? ? omap4_usb_phy_power(phy->control_dev, 0);
+
+ ? ? ? return 0;
+}
+
+static int omap_usb2_runtime_resume(struct device *dev)
+{
+ ? ? ? struct platform_device ?*pdev = to_platform_device(dev);
+ ? ? ? struct omap_usb *phy = platform_get_drvdata(pdev);
+
+ ? ? ? omap4_usb_phy_power(phy->control_dev, 1);
+ ? ? ? clk_enable(phy->wkupclk);
+
+ ? ? ? return 0;
+}
+
+static const struct dev_pm_ops omap_usb2_pm_ops = {
+ ? ? ? SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume,
+ ? ? ? ? ? ? ? NULL)
+};
+
+#define DEV_PM_OPS ? ? (&omap_usb2_pm_ops)
+#else
+#define DEV_PM_OPS ? ? NULL
+#endif
+
+static struct platform_driver omap_usb2_driver = {
+ ? ? ? .probe ? ? ? ? ?= omap_usb2_probe,
+ ? ? ? .remove ? ? ? ? = __devexit_p(omap_usb2_remove),
+ ? ? ? .driver ? ? ? ? = {
+ ? ? ? ? ? ? ? .name ? = "omap-usb2",
+ ? ? ? ? ? ? ? .owner ?= THIS_MODULE,
+ ? ? ? ? ? ? ? .pm ? ? = DEV_PM_OPS,
+ ? ? ? },
+};
+
+static int __init usb2_omap_init(void)
+{
+ ? ? ? return platform_driver_register(&omap_usb2_driver);
+}
+arch_initcall(usb2_omap_init);
+
+static void __exit usb2_omap_exit(void)
+{
+ ? ? ? platform_driver_unregister(&omap_usb2_driver);
+}
+module_exit(usb2_omap_exit);
+
+MODULE_ALIAS("platform: omap_usb2");
+MODULE_AUTHOR("Kishon Vijay Abraham I [off-list ref]");
+MODULE_DESCRIPTION("OMAP USB2 PHY DRIVER");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/usb/omap_usb.h b/include/linux/usb/omap_usb.h
new file mode 100644
index 0000000..8d781df
--- /dev/null
+++ b/include/linux/usb/omap_usb.h
@@ -0,0 +1,47 @@
+/*
+ * omap_usb.h -- omap usb2 phy header file
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com
s/2011/2012
quoted hunk ↗ jump to hunk
+ * 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: Kishon Vijay Abraham I [off-list ref]
+ *
+ * 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.
+ *
+ */
+
+#ifndef __DRIVERS_OMAP_USB2_H
+#define __DRIVERS_OMAP_USB2_H
+
+#include <linux/usb/otg.h>
+
+struct omap_usb {
+ ? ? ? struct usb_phy ? ? ? ? ?phy;
+ ? ? ? struct phy_companion ? ?*comparator;
+ ? ? ? struct device ? ? ? ? ? *dev;
+ ? ? ? struct device ? ? ? ? ? *control_dev;
+ ? ? ? struct clk ? ? ? ? ? ? ?*wkupclk;
+ ? ? ? u8 ? ? ? ? ? ? ? ? ? ? ?is_suspended:1;
+};
+
+#define ? ? ? ?phy_to_omapusb(x) ? ? ? container_of((x), struct omap_usb, phy)
+
+#if defined(CONFIG_OMAP_USB2) || defined(CONFIG_OMAP_USB2_MODULE)
+void omap_usb2_set_comparator(struct phy_companion *comparator);
+#else
+static inline void omap_usb2_set_comparator(struct phy_companion *comparator)
+{
+}
+#endif
+
+#endif /* __DRIVERS_OMAP_USB_H */
diff --git a/include/linux/usb/phy_companion.h b/include/linux/usb/phy_companion.h
new file mode 100644
index 0000000..321290f
--- /dev/null
+++ b/include/linux/usb/phy_companion.h
@@ -0,0 +1,34 @@
+/*
+ * phy-companion.h -- phy companion to indicate the comparator part of PHY
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com
Here too..

Regards
Santosh
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help