2008-07-24 17:27:36 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2005-2007 by Texas Instruments
|
|
|
|
* Some code has been taken from tusb6010.c
|
|
|
|
* Copyrights for that are attributable to:
|
|
|
|
* Copyright (C) 2006 Nokia Corporation
|
|
|
|
* Tony Lindgren <tony@atomide.com>
|
|
|
|
*
|
|
|
|
* This file is part of the Inventra Controller Driver for Linux.
|
|
|
|
*
|
|
|
|
* The Inventra Controller Driver for Linux 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.
|
|
|
|
*
|
|
|
|
* The Inventra Controller Driver for Linux 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 The Inventra Controller Driver for Linux ; if not,
|
|
|
|
* write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
|
|
* Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/sched.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/list.h>
|
|
|
|
#include <linux/io.h>
|
2012-09-11 17:09:40 +08:00
|
|
|
#include <linux/of.h>
|
2010-12-01 21:01:11 +08:00
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <linux/dma-mapping.h>
|
2011-02-17 14:37:22 +08:00
|
|
|
#include <linux/pm_runtime.h>
|
|
|
|
#include <linux/err.h>
|
2012-08-13 10:32:58 +08:00
|
|
|
#include <linux/delay.h>
|
2012-06-22 20:10:52 +08:00
|
|
|
#include <linux/usb/musb-omap.h>
|
2014-03-06 22:38:37 +08:00
|
|
|
#include <linux/phy/omap_control_phy.h>
|
2013-10-03 23:12:34 +08:00
|
|
|
#include <linux/of_platform.h>
|
2008-07-24 17:27:36 +08:00
|
|
|
|
|
|
|
#include "musb_core.h"
|
|
|
|
#include "omap2430.h"
|
|
|
|
|
2010-12-02 15:27:29 +08:00
|
|
|
struct omap2430_glue {
|
|
|
|
struct device *dev;
|
|
|
|
struct platform_device *musb;
|
2012-06-22 20:10:52 +08:00
|
|
|
enum omap_musb_vbus_id_status status;
|
2012-06-22 20:10:51 +08:00
|
|
|
struct work_struct omap_musb_mailbox_work;
|
2013-01-25 18:24:00 +08:00
|
|
|
struct device *control_otghs;
|
2010-12-02 15:27:29 +08:00
|
|
|
};
|
2010-12-02 18:44:40 +08:00
|
|
|
#define glue_to_musb(g) platform_get_drvdata(g->musb)
|
2010-12-02 15:27:29 +08:00
|
|
|
|
2013-03-05 19:04:24 +08:00
|
|
|
static struct omap2430_glue *_glue;
|
2012-06-22 20:10:52 +08:00
|
|
|
|
2008-07-24 17:27:36 +08:00
|
|
|
static struct timer_list musb_idle_timer;
|
|
|
|
|
|
|
|
static void musb_do_idle(unsigned long _musb)
|
|
|
|
{
|
|
|
|
struct musb *musb = (void *)_musb;
|
|
|
|
unsigned long flags;
|
|
|
|
u8 power;
|
|
|
|
u8 devctl;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&musb->lock, flags);
|
|
|
|
|
2014-10-31 01:41:13 +08:00
|
|
|
switch (musb->xceiv->otg->state) {
|
2008-07-24 17:27:36 +08:00
|
|
|
case OTG_STATE_A_WAIT_BCON:
|
|
|
|
|
|
|
|
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
|
|
|
|
if (devctl & MUSB_DEVCTL_BDEVICE) {
|
2014-10-31 01:41:13 +08:00
|
|
|
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
|
2008-07-24 17:27:36 +08:00
|
|
|
MUSB_DEV_MODE(musb);
|
|
|
|
} else {
|
2014-10-31 01:41:13 +08:00
|
|
|
musb->xceiv->otg->state = OTG_STATE_A_IDLE;
|
2008-07-24 17:27:36 +08:00
|
|
|
MUSB_HST_MODE(musb);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case OTG_STATE_A_SUSPEND:
|
|
|
|
/* finish RESUME signaling? */
|
|
|
|
if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
|
|
|
|
power = musb_readb(musb->mregs, MUSB_POWER);
|
|
|
|
power &= ~MUSB_POWER_RESUME;
|
2011-05-11 17:44:08 +08:00
|
|
|
dev_dbg(musb->controller, "root port resume stopped, power %02x\n", power);
|
2008-07-24 17:27:36 +08:00
|
|
|
musb_writeb(musb->mregs, MUSB_POWER, power);
|
|
|
|
musb->is_active = 1;
|
|
|
|
musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
|
|
|
|
| MUSB_PORT_STAT_RESUME);
|
|
|
|
musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
|
2013-04-11 03:55:50 +08:00
|
|
|
usb_hcd_poll_rh_status(musb->hcd);
|
2008-07-24 17:27:36 +08:00
|
|
|
/* NOTE: it might really be A_WAIT_BCON ... */
|
2014-10-31 01:41:13 +08:00
|
|
|
musb->xceiv->otg->state = OTG_STATE_A_HOST;
|
2008-07-24 17:27:36 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case OTG_STATE_A_HOST:
|
|
|
|
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
|
|
|
|
if (devctl & MUSB_DEVCTL_BDEVICE)
|
2014-10-31 01:41:13 +08:00
|
|
|
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
|
2008-07-24 17:27:36 +08:00
|
|
|
else
|
2014-10-31 01:41:13 +08:00
|
|
|
musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON;
|
2008-07-24 17:27:36 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(&musb->lock, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-01 19:22:05 +08:00
|
|
|
static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout)
|
2008-07-24 17:27:36 +08:00
|
|
|
{
|
|
|
|
unsigned long default_timeout = jiffies + msecs_to_jiffies(3);
|
|
|
|
static unsigned long last_timer;
|
|
|
|
|
|
|
|
if (timeout == 0)
|
|
|
|
timeout = default_timeout;
|
|
|
|
|
|
|
|
/* Never idle if active, or when VBUS timeout is not set as host */
|
|
|
|
if (musb->is_active || ((musb->a_wait_bcon == 0)
|
2014-10-31 01:41:13 +08:00
|
|
|
&& (musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON))) {
|
2011-05-11 17:44:08 +08:00
|
|
|
dev_dbg(musb->controller, "%s active, deleting timer\n",
|
2014-10-31 01:41:13 +08:00
|
|
|
usb_otg_state_string(musb->xceiv->otg->state));
|
2008-07-24 17:27:36 +08:00
|
|
|
del_timer(&musb_idle_timer);
|
|
|
|
last_timer = jiffies;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (time_after(last_timer, timeout)) {
|
|
|
|
if (!timer_pending(&musb_idle_timer))
|
|
|
|
last_timer = timeout;
|
|
|
|
else {
|
2011-05-11 17:44:08 +08:00
|
|
|
dev_dbg(musb->controller, "Longer idle timer already pending, ignoring\n");
|
2008-07-24 17:27:36 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
last_timer = timeout;
|
|
|
|
|
2011-05-11 17:44:08 +08:00
|
|
|
dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n",
|
2014-10-31 01:41:13 +08:00
|
|
|
usb_otg_state_string(musb->xceiv->otg->state),
|
2008-07-24 17:27:36 +08:00
|
|
|
(unsigned long)jiffies_to_msecs(timeout - jiffies));
|
|
|
|
mod_timer(&musb_idle_timer, timeout);
|
|
|
|
}
|
|
|
|
|
2010-12-01 19:22:05 +08:00
|
|
|
static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
|
2008-07-24 17:27:36 +08:00
|
|
|
{
|
2012-02-13 19:24:15 +08:00
|
|
|
struct usb_otg *otg = musb->xceiv->otg;
|
2008-07-24 17:27:36 +08:00
|
|
|
u8 devctl;
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
|
2008-07-24 17:27:36 +08:00
|
|
|
/* HDRC controls CPEN, but beware current surges during device
|
|
|
|
* connect. They can trigger transient overcurrent conditions
|
|
|
|
* that must be ignored.
|
|
|
|
*/
|
|
|
|
|
|
|
|
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
|
|
|
|
|
|
|
|
if (is_on) {
|
2014-10-31 01:41:13 +08:00
|
|
|
if (musb->xceiv->otg->state == OTG_STATE_A_IDLE) {
|
2012-08-13 10:32:58 +08:00
|
|
|
int loops = 100;
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
/* start the session */
|
|
|
|
devctl |= MUSB_DEVCTL_SESSION;
|
|
|
|
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
|
|
|
|
/*
|
|
|
|
* Wait for the musb to set as A device to enable the
|
|
|
|
* VBUS
|
|
|
|
*/
|
2014-10-24 04:34:12 +08:00
|
|
|
while (musb_readb(musb->mregs, MUSB_DEVCTL) &
|
|
|
|
MUSB_DEVCTL_BDEVICE) {
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
|
2012-08-13 10:32:58 +08:00
|
|
|
mdelay(5);
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
cpu_relax();
|
|
|
|
|
2012-08-13 10:32:58 +08:00
|
|
|
if (time_after(jiffies, timeout)
|
|
|
|
|| loops-- <= 0) {
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
dev_err(musb->controller,
|
|
|
|
"configured as A device timeout");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-14 14:23:56 +08:00
|
|
|
otg_set_vbus(otg, 1);
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
} else {
|
|
|
|
musb->is_active = 1;
|
2012-02-13 19:24:15 +08:00
|
|
|
otg->default_a = 1;
|
2014-10-31 01:41:13 +08:00
|
|
|
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
devctl |= MUSB_DEVCTL_SESSION;
|
|
|
|
MUSB_HST_MODE(musb);
|
|
|
|
}
|
2008-07-24 17:27:36 +08:00
|
|
|
} else {
|
|
|
|
musb->is_active = 0;
|
|
|
|
|
|
|
|
/* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and
|
|
|
|
* jumping right to B_IDLE...
|
|
|
|
*/
|
|
|
|
|
2012-02-13 19:24:15 +08:00
|
|
|
otg->default_a = 0;
|
2014-10-31 01:41:13 +08:00
|
|
|
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
|
2008-07-24 17:27:36 +08:00
|
|
|
devctl &= ~MUSB_DEVCTL_SESSION;
|
|
|
|
|
|
|
|
MUSB_DEV_MODE(musb);
|
|
|
|
}
|
|
|
|
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
|
|
|
|
|
2011-05-11 17:44:08 +08:00
|
|
|
dev_dbg(musb->controller, "VBUS %s, devctl %02x "
|
2008-07-24 17:27:36 +08:00
|
|
|
/* otg %3x conf %08x prcm %08x */ "\n",
|
2014-10-31 01:41:13 +08:00
|
|
|
usb_otg_state_string(musb->xceiv->otg->state),
|
2008-07-24 17:27:36 +08:00
|
|
|
musb_readb(musb->mregs, MUSB_DEVCTL));
|
|
|
|
}
|
|
|
|
|
2010-12-01 19:22:05 +08:00
|
|
|
static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
|
2008-07-24 17:27:36 +08:00
|
|
|
{
|
|
|
|
u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
|
|
|
|
|
|
|
|
devctl |= MUSB_DEVCTL_SESSION;
|
|
|
|
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
|
|
|
|
|
2008-11-24 19:06:47 +08:00
|
|
|
return 0;
|
2008-07-24 17:27:36 +08:00
|
|
|
}
|
|
|
|
|
2010-12-02 18:44:40 +08:00
|
|
|
static inline void omap2430_low_level_exit(struct musb *musb)
|
|
|
|
{
|
|
|
|
u32 l;
|
|
|
|
|
|
|
|
/* in any role */
|
|
|
|
l = musb_readl(musb->mregs, OTG_FORCESTDBY);
|
|
|
|
l |= ENABLEFORCE; /* enable MSTANDBY */
|
|
|
|
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void omap2430_low_level_init(struct musb *musb)
|
|
|
|
{
|
|
|
|
u32 l;
|
|
|
|
|
|
|
|
l = musb_readl(musb->mregs, OTG_FORCESTDBY);
|
|
|
|
l &= ~ENABLEFORCE; /* disable MSTANDBY */
|
|
|
|
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
|
|
|
|
}
|
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
{
|
2012-06-22 20:10:52 +08:00
|
|
|
struct omap2430_glue *glue = _glue;
|
2011-08-12 22:38:51 +08:00
|
|
|
|
2013-03-05 19:04:23 +08:00
|
|
|
if (!glue) {
|
|
|
|
pr_err("%s: musb core is not yet initialized\n", __func__);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
glue->status = status;
|
|
|
|
|
|
|
|
if (!glue_to_musb(glue)) {
|
2012-12-23 07:24:51 +08:00
|
|
|
pr_err("%s: musb core is not yet ready\n", __func__);
|
2012-06-22 20:10:52 +08:00
|
|
|
return;
|
|
|
|
}
|
2011-08-12 22:38:51 +08:00
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
schedule_work(&glue->omap_musb_mailbox_work);
|
2011-08-12 22:38:51 +08:00
|
|
|
}
|
2012-06-22 20:10:52 +08:00
|
|
|
EXPORT_SYMBOL_GPL(omap_musb_mailbox);
|
2011-08-12 22:38:51 +08:00
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
static void omap_musb_set_mailbox(struct omap2430_glue *glue)
|
2011-08-12 22:38:51 +08:00
|
|
|
{
|
2012-06-22 20:10:51 +08:00
|
|
|
struct musb *musb = glue_to_musb(glue);
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
struct device *dev = musb->controller;
|
2013-07-30 16:03:12 +08:00
|
|
|
struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev);
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
struct omap_musb_board_data *data = pdata->board_data;
|
2012-06-22 20:10:53 +08:00
|
|
|
struct usb_otg *otg = musb->xceiv->otg;
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
switch (glue->status) {
|
|
|
|
case OMAP_MUSB_ID_GROUND:
|
|
|
|
dev_dbg(dev, "ID GND\n");
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
|
2012-06-22 20:10:53 +08:00
|
|
|
otg->default_a = true;
|
2014-10-31 01:41:13 +08:00
|
|
|
musb->xceiv->otg->state = OTG_STATE_A_IDLE;
|
2012-06-22 20:10:52 +08:00
|
|
|
musb->xceiv->last_event = USB_EVENT_ID;
|
2011-11-24 21:46:26 +08:00
|
|
|
if (musb->gadget_driver) {
|
2012-06-22 20:10:52 +08:00
|
|
|
pm_runtime_get_sync(dev);
|
2013-01-25 18:24:00 +08:00
|
|
|
omap_control_usb_set_mode(glue->control_otghs,
|
|
|
|
USB_MODE_HOST);
|
2011-02-28 17:35:29 +08:00
|
|
|
omap2430_musb_set_vbus(musb, 1);
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
case OMAP_MUSB_VBUS_VALID:
|
|
|
|
dev_dbg(dev, "VBUS Connect\n");
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
|
2012-06-22 20:10:53 +08:00
|
|
|
otg->default_a = false;
|
2014-10-31 01:41:13 +08:00
|
|
|
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
|
2012-06-22 20:10:52 +08:00
|
|
|
musb->xceiv->last_event = USB_EVENT_VBUS;
|
usb: musb: Idle path retention and offmode support for OMAP3
This patch supports the retention and offmode support in the idle path for
musb driver using runtime pm APIs.
This is restricted to support offmode and retention only when device not
connected.When device/cable connected with gadget driver loaded,configured
to no idle/standby which will not allow the core transition to retention
or off.
There is no context save/restore done by hardware for musb in OMAP3
and OMAP4,driver has to take care of saving and restoring the context
during offmode.
Musb has a requirement of configuring sysconfig register to force
idle/standby mode and set the ENFORCE bit in module STANDBY register
for retention and offmode support.
Runtime pm and hwmod frameworks will take care of configuring to force
idle/standby when pm_runtime_put_sync is called and back to no
idle/standby when pm_runeime_get_sync is called.
Compile, boot tested and also tested the retention in the idle path on
OMAP3630Zoom3. And tested the global suspend/resume with offmode enabled.
Usb basic functionality tested on OMAP4430SDP.
There is some problem with idle path offmode in mainline, I could not test
with offmode. But I have tested this patch with resetting the controller
in the idle path when wakeup from retention just to make sure that the
context is lost, and restore path is working fine.
Removed .suspend/.resume fnction pointers and functions because there
is no need of having these functions as all required work is done
at runtime in the driver.
There is no need to call the runtime pm api with glue driver device
as glue layer device is the parent of musb core device, when runtime apis
are called for the child, parent device runtime functionality
will be invoked.
Design overview:
pm_runtime_get_sync: When called with musb core device takes care of
enabling the clock, calling runtime callback function of omap2430 glue
layer, runtime call back of musb driver and configure the musb sysconfig
to no idle/standby
pm_runtime_put: Takes care of calling runtime callback function of omap2430
glue layer, runtime call back of musb driver, Configure the musb sysconfig
to force idle/standby and disable the clock.
During musb driver load: Call pm_runtime_get_sync.
End of musb driver load: Call pm_runtime_put
During gadget driver load: Call pm_runtime_get_sync,
End of gadget driver load: Call pm_runtime_put if there is no device
or cable is connected.
During unload of the gadget driver:Call pm_runtime_get_sync if cable/device
is not connected.
End of the gadget driver unload : pm_runtime_put
During unload of musb driver : Call pm_runtime_get_sync
End of unload: Call pm_runtime_put
On connect of usb cable/device -> transceiver notification(VBUS and ID-GND):
pm_runtime_get_sync only if the gadget driver loaded.
On disconnect of the cable/device -> Disconnect Notification:
pm_runtime_put if the gadget driver is loaded.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2011-02-28 16:49:34 +08:00
|
|
|
if (musb->gadget_driver)
|
2012-06-22 20:10:52 +08:00
|
|
|
pm_runtime_get_sync(dev);
|
2013-01-25 18:24:00 +08:00
|
|
|
omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
break;
|
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
case OMAP_MUSB_ID_FLOAT:
|
|
|
|
case OMAP_MUSB_VBUS_OFF:
|
|
|
|
dev_dbg(dev, "VBUS Disconnect\n");
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
musb->xceiv->last_event = USB_EVENT_NONE;
|
2011-11-24 21:46:26 +08:00
|
|
|
if (musb->gadget_driver) {
|
2013-03-24 23:36:54 +08:00
|
|
|
omap2430_musb_set_vbus(musb, 0);
|
2011-11-24 21:46:26 +08:00
|
|
|
pm_runtime_mark_last_busy(dev);
|
|
|
|
pm_runtime_put_autosuspend(dev);
|
|
|
|
}
|
usb: musb: Idle path retention and offmode support for OMAP3
This patch supports the retention and offmode support in the idle path for
musb driver using runtime pm APIs.
This is restricted to support offmode and retention only when device not
connected.When device/cable connected with gadget driver loaded,configured
to no idle/standby which will not allow the core transition to retention
or off.
There is no context save/restore done by hardware for musb in OMAP3
and OMAP4,driver has to take care of saving and restoring the context
during offmode.
Musb has a requirement of configuring sysconfig register to force
idle/standby mode and set the ENFORCE bit in module STANDBY register
for retention and offmode support.
Runtime pm and hwmod frameworks will take care of configuring to force
idle/standby when pm_runtime_put_sync is called and back to no
idle/standby when pm_runeime_get_sync is called.
Compile, boot tested and also tested the retention in the idle path on
OMAP3630Zoom3. And tested the global suspend/resume with offmode enabled.
Usb basic functionality tested on OMAP4430SDP.
There is some problem with idle path offmode in mainline, I could not test
with offmode. But I have tested this patch with resetting the controller
in the idle path when wakeup from retention just to make sure that the
context is lost, and restore path is working fine.
Removed .suspend/.resume fnction pointers and functions because there
is no need of having these functions as all required work is done
at runtime in the driver.
There is no need to call the runtime pm api with glue driver device
as glue layer device is the parent of musb core device, when runtime apis
are called for the child, parent device runtime functionality
will be invoked.
Design overview:
pm_runtime_get_sync: When called with musb core device takes care of
enabling the clock, calling runtime callback function of omap2430 glue
layer, runtime call back of musb driver and configure the musb sysconfig
to no idle/standby
pm_runtime_put: Takes care of calling runtime callback function of omap2430
glue layer, runtime call back of musb driver, Configure the musb sysconfig
to force idle/standby and disable the clock.
During musb driver load: Call pm_runtime_get_sync.
End of musb driver load: Call pm_runtime_put
During gadget driver load: Call pm_runtime_get_sync,
End of gadget driver load: Call pm_runtime_put if there is no device
or cable is connected.
During unload of the gadget driver:Call pm_runtime_get_sync if cable/device
is not connected.
End of the gadget driver unload : pm_runtime_put
During unload of musb driver : Call pm_runtime_get_sync
End of unload: Call pm_runtime_put
On connect of usb cable/device -> transceiver notification(VBUS and ID-GND):
pm_runtime_get_sync only if the gadget driver loaded.
On disconnect of the cable/device -> Disconnect Notification:
pm_runtime_put if the gadget driver is loaded.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2011-02-28 16:49:34 +08:00
|
|
|
|
2013-03-14 14:23:56 +08:00
|
|
|
if (data->interface_type == MUSB_INTERFACE_UTMI)
|
|
|
|
otg_set_vbus(musb->xceiv->otg, 0);
|
|
|
|
|
2013-01-25 18:24:00 +08:00
|
|
|
omap_control_usb_set_mode(glue->control_otghs,
|
|
|
|
USB_MODE_DISCONNECT);
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
break;
|
|
|
|
default:
|
2012-06-22 20:10:52 +08:00
|
|
|
dev_dbg(dev, "ID float\n");
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
}
|
2013-09-19 01:03:34 +08:00
|
|
|
|
|
|
|
atomic_notifier_call_chain(&musb->xceiv->notifier,
|
|
|
|
musb->xceiv->last_event, NULL);
|
usb: musb: Adding musb support for OMAP4430
OMAP4430 supports UTMI and ULPI types of transceiver interface.
In UTMI mode: The PHY is embedded within OMAP4430. 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.
musb driver is register for blocking notifications from the transceiver
driver to get the event notifications for connect/disconnect and ID-GND.
Based on these events call the transceiver init/shutdown function to
configure the transceiver to toggle the VBUS valid, session end and ID_GND
signals to musb and power on/off the internal PHY.
For ID_GND event notifications, toggle the ID_GND signal and then wait for
musb to be configured as "A" device, and then call the transceiver function
to set the VBUS.
In OTG mode and musb as a host, When the Micro A connector used, VBUS is turned on
and session bit set. When the device is connected, enumeration goes through.
When the device disconnected from the other end of the connector(ID is still grounded),
link will detect the disconnect and end the session. When the device is connected back,
there are no events generated in the TWL6030-usb, and link is already down.
So the device is not detected. Removed the session bit disable code which
will recognize the connect of the device.
Limitation: In OTG host mode, if device is connected during boot, it does not get
detected. If disconnect and connect it back or connect after boot only it works.
Fix for this, I will submit seperate patch later.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2010-12-10 20:40:51 +08:00
|
|
|
}
|
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
|
|
|
|
static void omap_musb_mailbox_work(struct work_struct *mailbox_work)
|
|
|
|
{
|
|
|
|
struct omap2430_glue *glue = container_of(mailbox_work,
|
|
|
|
struct omap2430_glue, omap_musb_mailbox_work);
|
2014-04-07 23:58:01 +08:00
|
|
|
struct musb *musb = glue_to_musb(glue);
|
|
|
|
struct device *dev = musb->controller;
|
|
|
|
|
|
|
|
pm_runtime_get_sync(dev);
|
2012-06-22 20:10:52 +08:00
|
|
|
omap_musb_set_mailbox(glue);
|
2014-04-07 23:58:01 +08:00
|
|
|
pm_runtime_mark_last_busy(dev);
|
|
|
|
pm_runtime_put_autosuspend(dev);
|
2012-06-22 20:10:52 +08:00
|
|
|
}
|
|
|
|
|
2012-11-06 21:32:13 +08:00
|
|
|
static irqreturn_t omap2430_musb_interrupt(int irq, void *__hci)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
irqreturn_t retval = IRQ_NONE;
|
|
|
|
struct musb *musb = __hci;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&musb->lock, flags);
|
|
|
|
|
|
|
|
musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
|
|
|
|
musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
|
|
|
|
musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
|
|
|
|
|
|
|
|
if (musb->int_usb || musb->int_tx || musb->int_rx)
|
|
|
|
retval = musb_interrupt(musb);
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&musb->lock, flags);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2010-12-01 19:22:05 +08:00
|
|
|
static int omap2430_musb_init(struct musb *musb)
|
2008-07-24 17:27:36 +08:00
|
|
|
{
|
2012-03-22 15:18:06 +08:00
|
|
|
u32 l;
|
|
|
|
int status = 0;
|
2010-09-23 08:27:40 +08:00
|
|
|
struct device *dev = musb->controller;
|
2012-06-22 20:10:52 +08:00
|
|
|
struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
|
2013-07-30 16:03:12 +08:00
|
|
|
struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
|
2010-09-23 08:27:40 +08:00
|
|
|
struct omap_musb_board_data *data = plat->board_data;
|
2008-07-24 17:27:36 +08:00
|
|
|
|
2009-04-01 03:30:04 +08:00
|
|
|
/* We require some kind of external transceiver, hooked
|
|
|
|
* up through ULPI. TWL4030-family PMICs include one,
|
|
|
|
* which needs a driver, drivers aren't always needed.
|
|
|
|
*/
|
2013-09-27 14:23:30 +08:00
|
|
|
if (dev->parent->of_node) {
|
|
|
|
musb->phy = devm_phy_get(dev->parent, "usb2-phy");
|
|
|
|
|
|
|
|
/* We can't totally remove musb->xceiv as of now because
|
|
|
|
* musb core uses xceiv.state and xceiv.otg. Once we have
|
|
|
|
* a separate state machine to handle otg, these can be moved
|
|
|
|
* out of xceiv and then we can start using the generic PHY
|
|
|
|
* framework
|
|
|
|
*/
|
2013-01-25 10:33:26 +08:00
|
|
|
musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent,
|
|
|
|
"usb-phy", 0);
|
2013-09-27 14:23:30 +08:00
|
|
|
} else {
|
2013-01-25 10:33:26 +08:00
|
|
|
musb->xceiv = devm_usb_get_phy_dev(dev, 0);
|
2013-09-27 14:23:30 +08:00
|
|
|
musb->phy = devm_phy_get(dev, "usb");
|
|
|
|
}
|
2013-01-25 10:33:26 +08:00
|
|
|
|
2013-03-15 16:57:40 +08:00
|
|
|
if (IS_ERR(musb->xceiv)) {
|
|
|
|
status = PTR_ERR(musb->xceiv);
|
|
|
|
|
|
|
|
if (status == -ENXIO)
|
|
|
|
return status;
|
|
|
|
|
2009-04-01 03:30:04 +08:00
|
|
|
pr_err("HS USB OTG: no transceiver configured\n");
|
2013-01-04 23:13:58 +08:00
|
|
|
return -EPROBE_DEFER;
|
2009-04-01 03:30:04 +08:00
|
|
|
}
|
|
|
|
|
2013-09-27 14:23:30 +08:00
|
|
|
if (IS_ERR(musb->phy)) {
|
|
|
|
pr_err("HS USB OTG: no PHY configured\n");
|
|
|
|
return PTR_ERR(musb->phy);
|
|
|
|
}
|
2012-11-06 21:32:13 +08:00
|
|
|
musb->isr = omap2430_musb_interrupt;
|
|
|
|
|
usb: musb: Idle path retention and offmode support for OMAP3
This patch supports the retention and offmode support in the idle path for
musb driver using runtime pm APIs.
This is restricted to support offmode and retention only when device not
connected.When device/cable connected with gadget driver loaded,configured
to no idle/standby which will not allow the core transition to retention
or off.
There is no context save/restore done by hardware for musb in OMAP3
and OMAP4,driver has to take care of saving and restoring the context
during offmode.
Musb has a requirement of configuring sysconfig register to force
idle/standby mode and set the ENFORCE bit in module STANDBY register
for retention and offmode support.
Runtime pm and hwmod frameworks will take care of configuring to force
idle/standby when pm_runtime_put_sync is called and back to no
idle/standby when pm_runeime_get_sync is called.
Compile, boot tested and also tested the retention in the idle path on
OMAP3630Zoom3. And tested the global suspend/resume with offmode enabled.
Usb basic functionality tested on OMAP4430SDP.
There is some problem with idle path offmode in mainline, I could not test
with offmode. But I have tested this patch with resetting the controller
in the idle path when wakeup from retention just to make sure that the
context is lost, and restore path is working fine.
Removed .suspend/.resume fnction pointers and functions because there
is no need of having these functions as all required work is done
at runtime in the driver.
There is no need to call the runtime pm api with glue driver device
as glue layer device is the parent of musb core device, when runtime apis
are called for the child, parent device runtime functionality
will be invoked.
Design overview:
pm_runtime_get_sync: When called with musb core device takes care of
enabling the clock, calling runtime callback function of omap2430 glue
layer, runtime call back of musb driver and configure the musb sysconfig
to no idle/standby
pm_runtime_put: Takes care of calling runtime callback function of omap2430
glue layer, runtime call back of musb driver, Configure the musb sysconfig
to force idle/standby and disable the clock.
During musb driver load: Call pm_runtime_get_sync.
End of musb driver load: Call pm_runtime_put
During gadget driver load: Call pm_runtime_get_sync,
End of gadget driver load: Call pm_runtime_put if there is no device
or cable is connected.
During unload of the gadget driver:Call pm_runtime_get_sync if cable/device
is not connected.
End of the gadget driver unload : pm_runtime_put
During unload of musb driver : Call pm_runtime_get_sync
End of unload: Call pm_runtime_put
On connect of usb cable/device -> transceiver notification(VBUS and ID-GND):
pm_runtime_get_sync only if the gadget driver loaded.
On disconnect of the cable/device -> Disconnect Notification:
pm_runtime_put if the gadget driver is loaded.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2011-02-28 16:49:34 +08:00
|
|
|
status = pm_runtime_get_sync(dev);
|
|
|
|
if (status < 0) {
|
2012-03-22 15:18:06 +08:00
|
|
|
dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
|
usb: musb: Idle path retention and offmode support for OMAP3
This patch supports the retention and offmode support in the idle path for
musb driver using runtime pm APIs.
This is restricted to support offmode and retention only when device not
connected.When device/cable connected with gadget driver loaded,configured
to no idle/standby which will not allow the core transition to retention
or off.
There is no context save/restore done by hardware for musb in OMAP3
and OMAP4,driver has to take care of saving and restoring the context
during offmode.
Musb has a requirement of configuring sysconfig register to force
idle/standby mode and set the ENFORCE bit in module STANDBY register
for retention and offmode support.
Runtime pm and hwmod frameworks will take care of configuring to force
idle/standby when pm_runtime_put_sync is called and back to no
idle/standby when pm_runeime_get_sync is called.
Compile, boot tested and also tested the retention in the idle path on
OMAP3630Zoom3. And tested the global suspend/resume with offmode enabled.
Usb basic functionality tested on OMAP4430SDP.
There is some problem with idle path offmode in mainline, I could not test
with offmode. But I have tested this patch with resetting the controller
in the idle path when wakeup from retention just to make sure that the
context is lost, and restore path is working fine.
Removed .suspend/.resume fnction pointers and functions because there
is no need of having these functions as all required work is done
at runtime in the driver.
There is no need to call the runtime pm api with glue driver device
as glue layer device is the parent of musb core device, when runtime apis
are called for the child, parent device runtime functionality
will be invoked.
Design overview:
pm_runtime_get_sync: When called with musb core device takes care of
enabling the clock, calling runtime callback function of omap2430 glue
layer, runtime call back of musb driver and configure the musb sysconfig
to no idle/standby
pm_runtime_put: Takes care of calling runtime callback function of omap2430
glue layer, runtime call back of musb driver, Configure the musb sysconfig
to force idle/standby and disable the clock.
During musb driver load: Call pm_runtime_get_sync.
End of musb driver load: Call pm_runtime_put
During gadget driver load: Call pm_runtime_get_sync,
End of gadget driver load: Call pm_runtime_put if there is no device
or cable is connected.
During unload of the gadget driver:Call pm_runtime_get_sync if cable/device
is not connected.
End of the gadget driver unload : pm_runtime_put
During unload of musb driver : Call pm_runtime_get_sync
End of unload: Call pm_runtime_put
On connect of usb cable/device -> transceiver notification(VBUS and ID-GND):
pm_runtime_get_sync only if the gadget driver loaded.
On disconnect of the cable/device -> Disconnect Notification:
pm_runtime_put if the gadget driver is loaded.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2011-02-28 16:49:34 +08:00
|
|
|
goto err1;
|
|
|
|
}
|
2008-07-24 17:27:36 +08:00
|
|
|
|
2010-01-21 21:33:53 +08:00
|
|
|
l = musb_readl(musb->mregs, OTG_INTERFSEL);
|
2010-03-12 16:29:07 +08:00
|
|
|
|
|
|
|
if (data->interface_type == MUSB_INTERFACE_UTMI) {
|
|
|
|
/* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
|
|
|
|
l &= ~ULPI_12PIN; /* Disable ULPI */
|
|
|
|
l |= UTMI_8BIT; /* Enable UTMI */
|
|
|
|
} else {
|
|
|
|
l |= ULPI_12PIN;
|
|
|
|
}
|
|
|
|
|
2010-01-21 21:33:53 +08:00
|
|
|
musb_writel(musb->mregs, OTG_INTERFSEL, l);
|
2008-07-24 17:27:36 +08:00
|
|
|
|
|
|
|
pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
|
|
|
|
"sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n",
|
2010-01-21 21:33:53 +08:00
|
|
|
musb_readl(musb->mregs, OTG_REVISION),
|
|
|
|
musb_readl(musb->mregs, OTG_SYSCONFIG),
|
|
|
|
musb_readl(musb->mregs, OTG_SYSSTATUS),
|
|
|
|
musb_readl(musb->mregs, OTG_INTERFSEL),
|
|
|
|
musb_readl(musb->mregs, OTG_SIMENABLE));
|
2008-07-24 17:27:36 +08:00
|
|
|
|
|
|
|
setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
|
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
if (glue->status != OMAP_MUSB_UNKNOWN)
|
|
|
|
omap_musb_set_mailbox(glue);
|
|
|
|
|
2013-09-27 14:23:30 +08:00
|
|
|
phy_init(musb->phy);
|
2014-03-29 03:31:47 +08:00
|
|
|
phy_power_on(musb->phy);
|
2013-03-14 14:23:58 +08:00
|
|
|
|
2012-02-05 01:43:51 +08:00
|
|
|
pm_runtime_put_noidle(musb->controller);
|
2008-07-24 17:27:36 +08:00
|
|
|
return 0;
|
usb: musb: Idle path retention and offmode support for OMAP3
This patch supports the retention and offmode support in the idle path for
musb driver using runtime pm APIs.
This is restricted to support offmode and retention only when device not
connected.When device/cable connected with gadget driver loaded,configured
to no idle/standby which will not allow the core transition to retention
or off.
There is no context save/restore done by hardware for musb in OMAP3
and OMAP4,driver has to take care of saving and restoring the context
during offmode.
Musb has a requirement of configuring sysconfig register to force
idle/standby mode and set the ENFORCE bit in module STANDBY register
for retention and offmode support.
Runtime pm and hwmod frameworks will take care of configuring to force
idle/standby when pm_runtime_put_sync is called and back to no
idle/standby when pm_runeime_get_sync is called.
Compile, boot tested and also tested the retention in the idle path on
OMAP3630Zoom3. And tested the global suspend/resume with offmode enabled.
Usb basic functionality tested on OMAP4430SDP.
There is some problem with idle path offmode in mainline, I could not test
with offmode. But I have tested this patch with resetting the controller
in the idle path when wakeup from retention just to make sure that the
context is lost, and restore path is working fine.
Removed .suspend/.resume fnction pointers and functions because there
is no need of having these functions as all required work is done
at runtime in the driver.
There is no need to call the runtime pm api with glue driver device
as glue layer device is the parent of musb core device, when runtime apis
are called for the child, parent device runtime functionality
will be invoked.
Design overview:
pm_runtime_get_sync: When called with musb core device takes care of
enabling the clock, calling runtime callback function of omap2430 glue
layer, runtime call back of musb driver and configure the musb sysconfig
to no idle/standby
pm_runtime_put: Takes care of calling runtime callback function of omap2430
glue layer, runtime call back of musb driver, Configure the musb sysconfig
to force idle/standby and disable the clock.
During musb driver load: Call pm_runtime_get_sync.
End of musb driver load: Call pm_runtime_put
During gadget driver load: Call pm_runtime_get_sync,
End of gadget driver load: Call pm_runtime_put if there is no device
or cable is connected.
During unload of the gadget driver:Call pm_runtime_get_sync if cable/device
is not connected.
End of the gadget driver unload : pm_runtime_put
During unload of musb driver : Call pm_runtime_get_sync
End of unload: Call pm_runtime_put
On connect of usb cable/device -> transceiver notification(VBUS and ID-GND):
pm_runtime_get_sync only if the gadget driver loaded.
On disconnect of the cable/device -> Disconnect Notification:
pm_runtime_put if the gadget driver is loaded.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2011-02-28 16:49:34 +08:00
|
|
|
|
|
|
|
err1:
|
|
|
|
return status;
|
2008-07-24 17:27:36 +08:00
|
|
|
}
|
|
|
|
|
2011-02-17 14:36:10 +08:00
|
|
|
static void omap2430_musb_enable(struct musb *musb)
|
|
|
|
{
|
|
|
|
u8 devctl;
|
|
|
|
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
|
|
|
|
struct device *dev = musb->controller;
|
2012-06-22 20:10:52 +08:00
|
|
|
struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
|
2013-07-30 16:03:12 +08:00
|
|
|
struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev);
|
2011-02-17 14:36:10 +08:00
|
|
|
struct omap_musb_board_data *data = pdata->board_data;
|
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
switch (glue->status) {
|
2011-02-17 14:36:10 +08:00
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
case OMAP_MUSB_ID_GROUND:
|
2013-01-25 18:24:00 +08:00
|
|
|
omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST);
|
2011-12-20 04:17:50 +08:00
|
|
|
if (data->interface_type != MUSB_INTERFACE_UTMI)
|
|
|
|
break;
|
|
|
|
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
|
|
|
|
/* start the session */
|
|
|
|
devctl |= MUSB_DEVCTL_SESSION;
|
|
|
|
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
|
|
|
|
while (musb_readb(musb->mregs, MUSB_DEVCTL) &
|
|
|
|
MUSB_DEVCTL_BDEVICE) {
|
|
|
|
cpu_relax();
|
|
|
|
|
|
|
|
if (time_after(jiffies, timeout)) {
|
|
|
|
dev_err(dev, "configured as A device timeout");
|
|
|
|
break;
|
2011-02-17 14:36:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
case OMAP_MUSB_VBUS_VALID:
|
2013-01-25 18:24:00 +08:00
|
|
|
omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
|
2011-02-17 14:36:10 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void omap2430_musb_disable(struct musb *musb)
|
|
|
|
{
|
2012-06-22 20:10:52 +08:00
|
|
|
struct device *dev = musb->controller;
|
|
|
|
struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
|
|
|
|
|
2013-01-25 18:24:00 +08:00
|
|
|
if (glue->status != OMAP_MUSB_UNKNOWN)
|
|
|
|
omap_control_usb_set_mode(glue->control_otghs,
|
|
|
|
USB_MODE_DISCONNECT);
|
2008-07-24 17:27:36 +08:00
|
|
|
}
|
|
|
|
|
2010-12-01 19:22:05 +08:00
|
|
|
static int omap2430_musb_exit(struct musb *musb)
|
2008-07-24 17:27:36 +08:00
|
|
|
{
|
2011-02-11 23:57:08 +08:00
|
|
|
del_timer_sync(&musb_idle_timer);
|
2008-07-24 17:27:36 +08:00
|
|
|
|
2010-12-02 18:44:40 +08:00
|
|
|
omap2430_low_level_exit(musb);
|
2014-03-29 03:31:47 +08:00
|
|
|
phy_power_off(musb->phy);
|
2013-09-27 14:23:30 +08:00
|
|
|
phy_exit(musb->phy);
|
2010-12-02 18:44:40 +08:00
|
|
|
|
2008-07-24 17:27:36 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2010-12-01 19:22:05 +08:00
|
|
|
|
2010-12-02 15:48:58 +08:00
|
|
|
static const struct musb_platform_ops omap2430_ops = {
|
2010-12-01 19:22:05 +08:00
|
|
|
.init = omap2430_musb_init,
|
|
|
|
.exit = omap2430_musb_exit,
|
|
|
|
|
|
|
|
.set_mode = omap2430_musb_set_mode,
|
|
|
|
.try_idle = omap2430_musb_try_idle,
|
|
|
|
|
|
|
|
.set_vbus = omap2430_musb_set_vbus,
|
2011-02-17 14:36:10 +08:00
|
|
|
|
|
|
|
.enable = omap2430_musb_enable,
|
|
|
|
.disable = omap2430_musb_disable,
|
2010-12-01 19:22:05 +08:00
|
|
|
};
|
2010-12-01 21:01:11 +08:00
|
|
|
|
|
|
|
static u64 omap2430_dmamask = DMA_BIT_MASK(32);
|
|
|
|
|
2012-11-20 02:21:48 +08:00
|
|
|
static int omap2430_probe(struct platform_device *pdev)
|
2010-12-01 21:01:11 +08:00
|
|
|
{
|
2013-07-17 15:51:22 +08:00
|
|
|
struct resource musb_resources[3];
|
2013-07-30 16:03:12 +08:00
|
|
|
struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
2012-09-11 17:09:40 +08:00
|
|
|
struct omap_musb_board_data *data;
|
2010-12-01 21:01:11 +08:00
|
|
|
struct platform_device *musb;
|
2010-12-02 15:27:29 +08:00
|
|
|
struct omap2430_glue *glue;
|
2012-09-11 17:09:40 +08:00
|
|
|
struct device_node *np = pdev->dev.of_node;
|
|
|
|
struct musb_hdrc_config *config;
|
2015-02-04 22:28:49 +08:00
|
|
|
int ret = -ENOMEM, val;
|
2010-12-01 21:01:11 +08:00
|
|
|
|
2012-06-22 20:10:54 +08:00
|
|
|
glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
|
2014-10-14 15:56:08 +08:00
|
|
|
if (!glue)
|
2010-12-02 15:27:29 +08:00
|
|
|
goto err0;
|
|
|
|
|
2012-10-31 23:12:43 +08:00
|
|
|
musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
|
2010-12-01 21:01:11 +08:00
|
|
|
if (!musb) {
|
|
|
|
dev_err(&pdev->dev, "failed to allocate musb device\n");
|
2012-10-31 23:12:43 +08:00
|
|
|
goto err0;
|
2010-12-01 21:01:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
musb->dev.parent = &pdev->dev;
|
|
|
|
musb->dev.dma_mask = &omap2430_dmamask;
|
|
|
|
musb->dev.coherent_dma_mask = omap2430_dmamask;
|
|
|
|
|
2010-12-02 15:27:29 +08:00
|
|
|
glue->dev = &pdev->dev;
|
|
|
|
glue->musb = musb;
|
2012-06-22 20:10:52 +08:00
|
|
|
glue->status = OMAP_MUSB_UNKNOWN;
|
2013-10-03 23:12:34 +08:00
|
|
|
glue->control_otghs = ERR_PTR(-ENODEV);
|
2010-12-02 15:27:29 +08:00
|
|
|
|
2012-09-11 17:09:40 +08:00
|
|
|
if (np) {
|
2013-10-03 23:12:34 +08:00
|
|
|
struct device_node *control_node;
|
|
|
|
struct platform_device *control_pdev;
|
|
|
|
|
2012-09-11 17:09:40 +08:00
|
|
|
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
|
2014-10-14 15:56:08 +08:00
|
|
|
if (!pdata)
|
2012-10-31 23:12:43 +08:00
|
|
|
goto err2;
|
2012-09-11 17:09:40 +08:00
|
|
|
|
|
|
|
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
2014-10-14 15:56:08 +08:00
|
|
|
if (!data)
|
2012-10-31 23:12:43 +08:00
|
|
|
goto err2;
|
2012-09-11 17:09:40 +08:00
|
|
|
|
|
|
|
config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
|
2014-10-14 15:56:08 +08:00
|
|
|
if (!config)
|
2012-10-31 23:12:43 +08:00
|
|
|
goto err2;
|
2012-09-11 17:09:40 +08:00
|
|
|
|
|
|
|
of_property_read_u32(np, "mode", (u32 *)&pdata->mode);
|
2013-03-07 21:21:46 +08:00
|
|
|
of_property_read_u32(np, "interface-type",
|
2012-09-11 17:09:40 +08:00
|
|
|
(u32 *)&data->interface_type);
|
2013-03-07 21:21:46 +08:00
|
|
|
of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
|
|
|
|
of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
|
2012-09-11 17:09:40 +08:00
|
|
|
of_property_read_u32(np, "power", (u32 *)&pdata->power);
|
2015-02-04 22:28:49 +08:00
|
|
|
|
|
|
|
ret = of_property_read_u32(np, "multipoint", &val);
|
|
|
|
if (!ret && val)
|
|
|
|
config->multipoint = true;
|
2012-09-11 17:09:40 +08:00
|
|
|
|
|
|
|
pdata->board_data = data;
|
|
|
|
pdata->config = config;
|
|
|
|
|
2013-10-03 23:12:34 +08:00
|
|
|
control_node = of_parse_phandle(np, "ctrl-module", 0);
|
|
|
|
if (control_node) {
|
|
|
|
control_pdev = of_find_device_by_node(control_node);
|
|
|
|
if (!control_pdev) {
|
|
|
|
dev_err(&pdev->dev, "Failed to get control device\n");
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto err2;
|
|
|
|
}
|
|
|
|
glue->control_otghs = &control_pdev->dev;
|
2013-01-25 18:24:00 +08:00
|
|
|
}
|
|
|
|
}
|
2010-12-02 15:48:58 +08:00
|
|
|
pdata->platform_ops = &omap2430_ops;
|
|
|
|
|
2010-12-02 15:27:29 +08:00
|
|
|
platform_set_drvdata(pdev, glue);
|
2010-12-01 21:01:11 +08:00
|
|
|
|
2012-06-22 20:10:52 +08:00
|
|
|
/*
|
|
|
|
* REVISIT if we ever have two instances of the wrapper, we will be
|
|
|
|
* in big trouble
|
|
|
|
*/
|
|
|
|
_glue = glue;
|
|
|
|
|
2012-06-22 20:10:51 +08:00
|
|
|
INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work);
|
|
|
|
|
2013-06-25 15:41:02 +08:00
|
|
|
memset(musb_resources, 0x00, sizeof(*musb_resources) *
|
2013-04-24 22:21:42 +08:00
|
|
|
ARRAY_SIZE(musb_resources));
|
|
|
|
|
|
|
|
musb_resources[0].name = pdev->resource[0].name;
|
|
|
|
musb_resources[0].start = pdev->resource[0].start;
|
|
|
|
musb_resources[0].end = pdev->resource[0].end;
|
|
|
|
musb_resources[0].flags = pdev->resource[0].flags;
|
|
|
|
|
|
|
|
musb_resources[1].name = pdev->resource[1].name;
|
|
|
|
musb_resources[1].start = pdev->resource[1].start;
|
|
|
|
musb_resources[1].end = pdev->resource[1].end;
|
|
|
|
musb_resources[1].flags = pdev->resource[1].flags;
|
|
|
|
|
2013-07-17 15:51:22 +08:00
|
|
|
musb_resources[2].name = pdev->resource[2].name;
|
|
|
|
musb_resources[2].start = pdev->resource[2].start;
|
|
|
|
musb_resources[2].end = pdev->resource[2].end;
|
|
|
|
musb_resources[2].flags = pdev->resource[2].flags;
|
|
|
|
|
2013-04-24 22:21:42 +08:00
|
|
|
ret = platform_device_add_resources(musb, musb_resources,
|
|
|
|
ARRAY_SIZE(musb_resources));
|
2010-12-01 21:01:11 +08:00
|
|
|
if (ret) {
|
|
|
|
dev_err(&pdev->dev, "failed to add resources\n");
|
2012-08-31 19:09:49 +08:00
|
|
|
goto err2;
|
2010-12-01 21:01:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
|
|
|
|
if (ret) {
|
|
|
|
dev_err(&pdev->dev, "failed to add platform_data\n");
|
2012-08-31 19:09:49 +08:00
|
|
|
goto err2;
|
2010-12-01 21:01:11 +08:00
|
|
|
}
|
|
|
|
|
2012-03-22 00:00:20 +08:00
|
|
|
pm_runtime_enable(&pdev->dev);
|
|
|
|
|
2010-12-01 21:01:11 +08:00
|
|
|
ret = platform_device_add(musb);
|
|
|
|
if (ret) {
|
|
|
|
dev_err(&pdev->dev, "failed to register musb device\n");
|
2012-08-31 19:09:49 +08:00
|
|
|
goto err2;
|
2010-12-01 21:01:11 +08:00
|
|
|
}
|
|
|
|
|
2011-02-17 14:37:22 +08:00
|
|
|
return 0;
|
2010-12-02 15:57:08 +08:00
|
|
|
|
2012-08-31 19:09:49 +08:00
|
|
|
err2:
|
2012-06-22 20:10:54 +08:00
|
|
|
platform_device_put(musb);
|
2010-12-02 15:27:29 +08:00
|
|
|
|
2010-12-01 21:01:11 +08:00
|
|
|
err0:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-11-20 02:26:20 +08:00
|
|
|
static int omap2430_remove(struct platform_device *pdev)
|
2010-12-01 21:01:11 +08:00
|
|
|
{
|
2010-12-02 15:27:29 +08:00
|
|
|
struct omap2430_glue *glue = platform_get_drvdata(pdev);
|
2010-12-01 21:01:11 +08:00
|
|
|
|
2012-06-22 20:10:51 +08:00
|
|
|
cancel_work_sync(&glue->omap_musb_mailbox_work);
|
2012-08-02 18:00:07 +08:00
|
|
|
platform_device_unregister(glue->musb);
|
2010-12-01 21:01:11 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-12-02 18:44:40 +08:00
|
|
|
#ifdef CONFIG_PM
|
|
|
|
|
usb: musb: Idle path retention and offmode support for OMAP3
This patch supports the retention and offmode support in the idle path for
musb driver using runtime pm APIs.
This is restricted to support offmode and retention only when device not
connected.When device/cable connected with gadget driver loaded,configured
to no idle/standby which will not allow the core transition to retention
or off.
There is no context save/restore done by hardware for musb in OMAP3
and OMAP4,driver has to take care of saving and restoring the context
during offmode.
Musb has a requirement of configuring sysconfig register to force
idle/standby mode and set the ENFORCE bit in module STANDBY register
for retention and offmode support.
Runtime pm and hwmod frameworks will take care of configuring to force
idle/standby when pm_runtime_put_sync is called and back to no
idle/standby when pm_runeime_get_sync is called.
Compile, boot tested and also tested the retention in the idle path on
OMAP3630Zoom3. And tested the global suspend/resume with offmode enabled.
Usb basic functionality tested on OMAP4430SDP.
There is some problem with idle path offmode in mainline, I could not test
with offmode. But I have tested this patch with resetting the controller
in the idle path when wakeup from retention just to make sure that the
context is lost, and restore path is working fine.
Removed .suspend/.resume fnction pointers and functions because there
is no need of having these functions as all required work is done
at runtime in the driver.
There is no need to call the runtime pm api with glue driver device
as glue layer device is the parent of musb core device, when runtime apis
are called for the child, parent device runtime functionality
will be invoked.
Design overview:
pm_runtime_get_sync: When called with musb core device takes care of
enabling the clock, calling runtime callback function of omap2430 glue
layer, runtime call back of musb driver and configure the musb sysconfig
to no idle/standby
pm_runtime_put: Takes care of calling runtime callback function of omap2430
glue layer, runtime call back of musb driver, Configure the musb sysconfig
to force idle/standby and disable the clock.
During musb driver load: Call pm_runtime_get_sync.
End of musb driver load: Call pm_runtime_put
During gadget driver load: Call pm_runtime_get_sync,
End of gadget driver load: Call pm_runtime_put if there is no device
or cable is connected.
During unload of the gadget driver:Call pm_runtime_get_sync if cable/device
is not connected.
End of the gadget driver unload : pm_runtime_put
During unload of musb driver : Call pm_runtime_get_sync
End of unload: Call pm_runtime_put
On connect of usb cable/device -> transceiver notification(VBUS and ID-GND):
pm_runtime_get_sync only if the gadget driver loaded.
On disconnect of the cable/device -> Disconnect Notification:
pm_runtime_put if the gadget driver is loaded.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2011-02-28 16:49:34 +08:00
|
|
|
static int omap2430_runtime_suspend(struct device *dev)
|
2010-12-02 18:44:40 +08:00
|
|
|
{
|
|
|
|
struct omap2430_glue *glue = dev_get_drvdata(dev);
|
|
|
|
struct musb *musb = glue_to_musb(glue);
|
|
|
|
|
2011-12-24 00:37:18 +08:00
|
|
|
if (musb) {
|
|
|
|
musb->context.otg_interfsel = musb_readl(musb->mregs,
|
|
|
|
OTG_INTERFSEL);
|
2011-09-08 00:19:24 +08:00
|
|
|
|
2011-12-24 00:37:18 +08:00
|
|
|
omap2430_low_level_exit(musb);
|
|
|
|
}
|
2010-12-02 18:44:40 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
usb: musb: Idle path retention and offmode support for OMAP3
This patch supports the retention and offmode support in the idle path for
musb driver using runtime pm APIs.
This is restricted to support offmode and retention only when device not
connected.When device/cable connected with gadget driver loaded,configured
to no idle/standby which will not allow the core transition to retention
or off.
There is no context save/restore done by hardware for musb in OMAP3
and OMAP4,driver has to take care of saving and restoring the context
during offmode.
Musb has a requirement of configuring sysconfig register to force
idle/standby mode and set the ENFORCE bit in module STANDBY register
for retention and offmode support.
Runtime pm and hwmod frameworks will take care of configuring to force
idle/standby when pm_runtime_put_sync is called and back to no
idle/standby when pm_runeime_get_sync is called.
Compile, boot tested and also tested the retention in the idle path on
OMAP3630Zoom3. And tested the global suspend/resume with offmode enabled.
Usb basic functionality tested on OMAP4430SDP.
There is some problem with idle path offmode in mainline, I could not test
with offmode. But I have tested this patch with resetting the controller
in the idle path when wakeup from retention just to make sure that the
context is lost, and restore path is working fine.
Removed .suspend/.resume fnction pointers and functions because there
is no need of having these functions as all required work is done
at runtime in the driver.
There is no need to call the runtime pm api with glue driver device
as glue layer device is the parent of musb core device, when runtime apis
are called for the child, parent device runtime functionality
will be invoked.
Design overview:
pm_runtime_get_sync: When called with musb core device takes care of
enabling the clock, calling runtime callback function of omap2430 glue
layer, runtime call back of musb driver and configure the musb sysconfig
to no idle/standby
pm_runtime_put: Takes care of calling runtime callback function of omap2430
glue layer, runtime call back of musb driver, Configure the musb sysconfig
to force idle/standby and disable the clock.
During musb driver load: Call pm_runtime_get_sync.
End of musb driver load: Call pm_runtime_put
During gadget driver load: Call pm_runtime_get_sync,
End of gadget driver load: Call pm_runtime_put if there is no device
or cable is connected.
During unload of the gadget driver:Call pm_runtime_get_sync if cable/device
is not connected.
End of the gadget driver unload : pm_runtime_put
During unload of musb driver : Call pm_runtime_get_sync
End of unload: Call pm_runtime_put
On connect of usb cable/device -> transceiver notification(VBUS and ID-GND):
pm_runtime_get_sync only if the gadget driver loaded.
On disconnect of the cable/device -> Disconnect Notification:
pm_runtime_put if the gadget driver is loaded.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2011-02-28 16:49:34 +08:00
|
|
|
static int omap2430_runtime_resume(struct device *dev)
|
2010-12-02 18:44:40 +08:00
|
|
|
{
|
|
|
|
struct omap2430_glue *glue = dev_get_drvdata(dev);
|
|
|
|
struct musb *musb = glue_to_musb(glue);
|
|
|
|
|
2011-12-24 00:37:18 +08:00
|
|
|
if (musb) {
|
|
|
|
omap2430_low_level_init(musb);
|
|
|
|
musb_writel(musb->mregs, OTG_INTERFSEL,
|
|
|
|
musb->context.otg_interfsel);
|
|
|
|
}
|
2010-12-02 18:44:40 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct dev_pm_ops omap2430_pm_ops = {
|
usb: musb: Idle path retention and offmode support for OMAP3
This patch supports the retention and offmode support in the idle path for
musb driver using runtime pm APIs.
This is restricted to support offmode and retention only when device not
connected.When device/cable connected with gadget driver loaded,configured
to no idle/standby which will not allow the core transition to retention
or off.
There is no context save/restore done by hardware for musb in OMAP3
and OMAP4,driver has to take care of saving and restoring the context
during offmode.
Musb has a requirement of configuring sysconfig register to force
idle/standby mode and set the ENFORCE bit in module STANDBY register
for retention and offmode support.
Runtime pm and hwmod frameworks will take care of configuring to force
idle/standby when pm_runtime_put_sync is called and back to no
idle/standby when pm_runeime_get_sync is called.
Compile, boot tested and also tested the retention in the idle path on
OMAP3630Zoom3. And tested the global suspend/resume with offmode enabled.
Usb basic functionality tested on OMAP4430SDP.
There is some problem with idle path offmode in mainline, I could not test
with offmode. But I have tested this patch with resetting the controller
in the idle path when wakeup from retention just to make sure that the
context is lost, and restore path is working fine.
Removed .suspend/.resume fnction pointers and functions because there
is no need of having these functions as all required work is done
at runtime in the driver.
There is no need to call the runtime pm api with glue driver device
as glue layer device is the parent of musb core device, when runtime apis
are called for the child, parent device runtime functionality
will be invoked.
Design overview:
pm_runtime_get_sync: When called with musb core device takes care of
enabling the clock, calling runtime callback function of omap2430 glue
layer, runtime call back of musb driver and configure the musb sysconfig
to no idle/standby
pm_runtime_put: Takes care of calling runtime callback function of omap2430
glue layer, runtime call back of musb driver, Configure the musb sysconfig
to force idle/standby and disable the clock.
During musb driver load: Call pm_runtime_get_sync.
End of musb driver load: Call pm_runtime_put
During gadget driver load: Call pm_runtime_get_sync,
End of gadget driver load: Call pm_runtime_put if there is no device
or cable is connected.
During unload of the gadget driver:Call pm_runtime_get_sync if cable/device
is not connected.
End of the gadget driver unload : pm_runtime_put
During unload of musb driver : Call pm_runtime_get_sync
End of unload: Call pm_runtime_put
On connect of usb cable/device -> transceiver notification(VBUS and ID-GND):
pm_runtime_get_sync only if the gadget driver loaded.
On disconnect of the cable/device -> Disconnect Notification:
pm_runtime_put if the gadget driver is loaded.
Signed-off-by: Hema HK <hemahk@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2011-02-28 16:49:34 +08:00
|
|
|
.runtime_suspend = omap2430_runtime_suspend,
|
|
|
|
.runtime_resume = omap2430_runtime_resume,
|
2010-12-02 18:44:40 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#define DEV_PM_OPS (&omap2430_pm_ops)
|
|
|
|
#else
|
|
|
|
#define DEV_PM_OPS NULL
|
|
|
|
#endif
|
|
|
|
|
2012-09-11 17:09:40 +08:00
|
|
|
#ifdef CONFIG_OF
|
|
|
|
static const struct of_device_id omap2430_id_table[] = {
|
|
|
|
{
|
|
|
|
.compatible = "ti,omap4-musb"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.compatible = "ti,omap3-musb"
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
};
|
|
|
|
MODULE_DEVICE_TABLE(of, omap2430_id_table);
|
|
|
|
#endif
|
|
|
|
|
2010-12-01 21:01:11 +08:00
|
|
|
static struct platform_driver omap2430_driver = {
|
2012-01-26 18:40:23 +08:00
|
|
|
.probe = omap2430_probe,
|
2012-11-20 02:21:08 +08:00
|
|
|
.remove = omap2430_remove,
|
2010-12-01 21:01:11 +08:00
|
|
|
.driver = {
|
|
|
|
.name = "musb-omap2430",
|
2010-12-02 18:44:40 +08:00
|
|
|
.pm = DEV_PM_OPS,
|
2012-09-11 17:09:40 +08:00
|
|
|
.of_match_table = of_match_ptr(omap2430_id_table),
|
2010-12-01 21:01:11 +08:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer");
|
|
|
|
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
|
|
|
|
MODULE_LICENSE("GPL v2");
|
|
|
|
|
|
|
|
static int __init omap2430_init(void)
|
|
|
|
{
|
2012-01-26 18:40:23 +08:00
|
|
|
return platform_driver_register(&omap2430_driver);
|
2010-12-01 21:01:11 +08:00
|
|
|
}
|
2012-06-22 20:10:52 +08:00
|
|
|
subsys_initcall(omap2430_init);
|
2010-12-01 21:01:11 +08:00
|
|
|
|
|
|
|
static void __exit omap2430_exit(void)
|
|
|
|
{
|
|
|
|
platform_driver_unregister(&omap2430_driver);
|
|
|
|
}
|
|
|
|
module_exit(omap2430_exit);
|