#include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/usb/musb-omap.h>
+#include <linux/usb/omap_control_usb.h>
 
 #include "musb_core.h"
 #include "omap2430.h"
        struct platform_device  *musb;
        enum omap_musb_vbus_id_status status;
        struct work_struct      omap_musb_mailbox_work;
-       u32 __iomem             *control_otghs;
+       struct device           *control_otghs;
 };
 #define glue_to_musb(g)                platform_get_drvdata(g->musb)
 
 
 static struct timer_list musb_idle_timer;
 
-/**
- * omap4_usb_phy_mailbox - write to usb otg mailbox
- * @glue: struct omap2430_glue *
- * @val: the value to be written to the mailbox
- *
- * On detection of a device (ID pin is grounded), this API should be called
- * to set AVALID, VBUSVALID and ID pin is grounded.
- *
- * When OMAP is connected to a host (OMAP in device mode), this API
- * is called to set AVALID, VBUSVALID and ID pin in high impedance.
- *
- * XXX: This function will be removed once we have a seperate driver for
- * control module
- */
-static void omap4_usb_phy_mailbox(struct omap2430_glue *glue, u32 val)
-{
-       if (glue->control_otghs)
-               writel(val, glue->control_otghs);
-}
-
 static void musb_do_idle(unsigned long _musb)
 {
        struct musb     *musb = (void *)_musb;
 
 static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 {
-       u32 val;
        struct musb *musb = glue_to_musb(glue);
        struct device *dev = musb->controller;
        struct musb_hdrc_platform_data *pdata = dev->platform_data;
                musb->xceiv->last_event = USB_EVENT_ID;
                if (musb->gadget_driver) {
                        pm_runtime_get_sync(dev);
-                       val = AVALID | VBUSVALID;
-                       omap4_usb_phy_mailbox(glue, val);
+                       omap_control_usb_set_mode(glue->control_otghs,
+                               USB_MODE_HOST);
                        omap2430_musb_set_vbus(musb, 1);
                }
                break;
                musb->xceiv->last_event = USB_EVENT_VBUS;
                if (musb->gadget_driver)
                        pm_runtime_get_sync(dev);
-               val = IDDIG | AVALID | VBUSVALID;
-               omap4_usb_phy_mailbox(glue, val);
+               omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
                break;
 
        case OMAP_MUSB_ID_FLOAT:
                        if (musb->xceiv->otg->set_vbus)
                                otg_set_vbus(musb->xceiv->otg, 0);
                }
-               val = SESSEND | IDDIG;
-               omap4_usb_phy_mailbox(glue, val);
+               omap_control_usb_set_mode(glue->control_otghs,
+                       USB_MODE_DISCONNECT);
                break;
        default:
                dev_dbg(dev, "ID float\n");
 static void omap2430_musb_enable(struct musb *musb)
 {
        u8              devctl;
-       u32             val;
        unsigned long timeout = jiffies + msecs_to_jiffies(1000);
        struct device *dev = musb->controller;
        struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
        switch (glue->status) {
 
        case OMAP_MUSB_ID_GROUND:
-               val = AVALID | VBUSVALID;
-               omap4_usb_phy_mailbox(glue, val);
+               omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST);
                if (data->interface_type != MUSB_INTERFACE_UTMI)
                        break;
                devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
                break;
 
        case OMAP_MUSB_VBUS_VALID:
-               val = IDDIG | AVALID | VBUSVALID;
-               omap4_usb_phy_mailbox(glue, val);
+               omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
                break;
 
        default:
 
 static void omap2430_musb_disable(struct musb *musb)
 {
-       u32 val;
        struct device *dev = musb->controller;
        struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
 
-       if (glue->status != OMAP_MUSB_UNKNOWN) {
-               val = SESSEND | IDDIG;
-               omap4_usb_phy_mailbox(glue, val);
-       }
+       if (glue->status != OMAP_MUSB_UNKNOWN)
+               omap_control_usb_set_mode(glue->control_otghs,
+                       USB_MODE_DISCONNECT);
 }
 
 static int omap2430_musb_exit(struct musb *musb)
        struct omap2430_glue            *glue;
        struct device_node              *np = pdev->dev.of_node;
        struct musb_hdrc_config         *config;
-       struct resource                 *res;
        int                             ret = -ENOMEM;
 
        glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
        glue->musb                      = musb;
        glue->status                    = OMAP_MUSB_UNKNOWN;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-
-       glue->control_otghs = devm_request_and_ioremap(&pdev->dev, res);
-       if (glue->control_otghs == NULL)
-               dev_dbg(&pdev->dev, "Failed to obtain control memory\n");
-
        if (np) {
                pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
                if (!pdata) {
                of_property_read_u32(np, "ram_bits", (u32 *)&config->ram_bits);
                of_property_read_u32(np, "power", (u32 *)&pdata->power);
                config->multipoint = of_property_read_bool(np, "multipoint");
+               pdata->has_mailbox = of_property_read_bool(np,
+                   "ti,has-mailbox");
 
                pdata->board_data       = data;
                pdata->config           = config;
        }
 
+       if (pdata->has_mailbox) {
+               glue->control_otghs = omap_get_control_dev();
+               if (IS_ERR(glue->control_otghs)) {
+                       dev_vdbg(&pdev->dev, "Failed to get control device\n");
+                       return -ENODEV;
+               }
+       } else {
+               glue->control_otghs = ERR_PTR(-ENODEV);
+       }
        pdata->platform_ops             = &omap2430_ops;
 
        platform_set_drvdata(pdev, glue);
 
 #include <linux/err.h>
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
+#include <linux/usb/omap_control_usb.h>
 
 /**
  * omap_usb2_set_comparator - links the comparator present in the sytem with
 }
 EXPORT_SYMBOL_GPL(omap_usb2_set_comparator);
 
-/**
- * omap_usb_phy_power - power on/off the phy using control module reg
- * @phy: struct omap_usb *
- * @on: 0 or 1, based on powering on or off the PHY
- *
- * XXX: Remove this function once control module driver gets merged
- */
-static void omap_usb_phy_power(struct omap_usb *phy, int on)
-{
-       u32 val;
-
-       if (on) {
-               val = readl(phy->control_dev);
-               if (val & PHY_PD) {
-                       writel(~PHY_PD, phy->control_dev);
-                       /* XXX: add proper documentation for this delay */
-                       mdelay(200);
-               }
-       } else {
-               writel(PHY_PD, phy->control_dev);
-       }
-}
-
 static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled)
 {
        struct omap_usb *phy = phy_to_omapusb(otg->phy);
        struct omap_usb *phy = phy_to_omapusb(x);
 
        if (suspend && !phy->is_suspended) {
-               omap_usb_phy_power(phy, 0);
+               omap_control_usb_phy_power(phy->control_dev, 0);
                pm_runtime_put_sync(phy->dev);
                phy->is_suspended = 1;
        } else if (!suspend && phy->is_suspended) {
                                                                        ret);
                        return ret;
                }
-               omap_usb_phy_power(phy, 1);
+               omap_control_usb_phy_power(phy->control_dev, 1);
                phy->is_suspended = 0;
        }
 
 {
        struct omap_usb                 *phy;
        struct usb_otg                  *otg;
-       struct resource                 *res;
 
        phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
        if (!phy) {
        phy->phy.set_suspend    = omap_usb2_suspend;
        phy->phy.otg            = otg;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-
-       phy->control_dev = devm_request_and_ioremap(&pdev->dev, res);
-       if (phy->control_dev == NULL) {
-               dev_err(&pdev->dev, "Failed to obtain io memory\n");
-               return -ENXIO;
+       phy->control_dev = omap_get_control_dev();
+       if (IS_ERR(phy->control_dev)) {
+               dev_dbg(&pdev->dev, "Failed to get control device\n");
+               return -ENODEV;
        }
 
        phy->is_suspended       = 1;
-       omap_usb_phy_power(phy, 0);
+       omap_control_usb_phy_power(phy->control_dev, 0);
 
        otg->set_host           = omap_usb_set_host;
        otg->set_peripheral     = omap_usb_set_peripheral;