2
* Copyright (C) 2005-2007 by Texas Instruments
3
* Some code has been taken from tusb6010.c
4
* Copyrights for that are attributable to:
5
* Copyright (C) 2006 Nokia Corporation
6
* Tony Lindgren <tony@atomide.com>
8
* This file is part of the Inventra Controller Driver for Linux.
10
* The Inventra Controller Driver for Linux is free software; you
11
* can redistribute it and/or modify it under the terms of the GNU
12
* General Public License version 2 as published by the Free Software
15
* The Inventra Controller Driver for Linux is distributed in
16
* the hope that it will be useful, but WITHOUT ANY WARRANTY;
17
* without even the implied warranty of MERCHANTABILITY or
18
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
19
* License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with The Inventra Controller Driver for Linux ; if not,
23
* write to the Free Software Foundation, Inc., 59 Temple Place,
24
* Suite 330, Boston, MA 02111-1307 USA
29
#include <linux/module.h>
30
#include <linux/kernel.h>
31
#include <linux/sched.h>
32
#include <linux/init.h>
33
#include <linux/list.h>
35
#include <linux/platform_device.h>
36
#include <linux/dma-mapping.h>
37
#include <linux/pm_runtime.h>
38
#include <linux/err.h>
39
#include <linux/usb/musb-omap.h>
42
#include <asm/omap_musb.h>
44
#include "linux-compat.h"
47
#include "musb_core.h"
51
struct omap2430_glue {
53
struct platform_device *musb;
54
enum omap_musb_vbus_id_status status;
55
struct work_struct omap_musb_mailbox_work;
57
#define glue_to_musb(g) platform_get_drvdata(g->musb)
59
struct omap2430_glue *_glue;
61
static struct timer_list musb_idle_timer;
63
static void musb_do_idle(unsigned long _musb)
65
struct musb *musb = (void *)_musb;
70
spin_lock_irqsave(&musb->lock, flags);
72
switch (musb->xceiv->state) {
73
case OTG_STATE_A_WAIT_BCON:
75
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
76
if (devctl & MUSB_DEVCTL_BDEVICE) {
77
musb->xceiv->state = OTG_STATE_B_IDLE;
80
musb->xceiv->state = OTG_STATE_A_IDLE;
84
case OTG_STATE_A_SUSPEND:
85
/* finish RESUME signaling? */
86
if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
87
power = musb_readb(musb->mregs, MUSB_POWER);
88
power &= ~MUSB_POWER_RESUME;
89
dev_dbg(musb->controller, "root port resume stopped, power %02x\n", power);
90
musb_writeb(musb->mregs, MUSB_POWER, power);
92
musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
93
| MUSB_PORT_STAT_RESUME);
94
musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
95
usb_hcd_poll_rh_status(musb_to_hcd(musb));
96
/* NOTE: it might really be A_WAIT_BCON ... */
97
musb->xceiv->state = OTG_STATE_A_HOST;
100
case OTG_STATE_A_HOST:
101
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
102
if (devctl & MUSB_DEVCTL_BDEVICE)
103
musb->xceiv->state = OTG_STATE_B_IDLE;
105
musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
109
spin_unlock_irqrestore(&musb->lock, flags);
113
static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout)
115
unsigned long default_timeout = jiffies + msecs_to_jiffies(3);
116
static unsigned long last_timer;
119
timeout = default_timeout;
121
/* Never idle if active, or when VBUS timeout is not set as host */
122
if (musb->is_active || ((musb->a_wait_bcon == 0)
123
&& (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
124
dev_dbg(musb->controller, "%s active, deleting timer\n",
125
otg_state_string(musb->xceiv->state));
126
del_timer(&musb_idle_timer);
127
last_timer = jiffies;
131
if (time_after(last_timer, timeout)) {
132
if (!timer_pending(&musb_idle_timer))
133
last_timer = timeout;
135
dev_dbg(musb->controller, "Longer idle timer already pending, ignoring\n");
139
last_timer = timeout;
141
dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n",
142
otg_state_string(musb->xceiv->state),
143
(unsigned long)jiffies_to_msecs(timeout - jiffies));
144
mod_timer(&musb_idle_timer, timeout);
147
static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
149
struct usb_otg *otg = musb->xceiv->otg;
151
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
153
/* HDRC controls CPEN, but beware current surges during device
154
* connect. They can trigger transient overcurrent conditions
155
* that must be ignored.
158
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
161
if (musb->xceiv->state == OTG_STATE_A_IDLE) {
162
/* start the session */
163
devctl |= MUSB_DEVCTL_SESSION;
164
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
166
* Wait for the musb to set as A device to enable the
169
while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
173
if (time_after(jiffies, timeout)) {
174
dev_err(musb->controller,
175
"configured as A device timeout");
181
if (ret && otg->set_vbus)
182
otg_set_vbus(otg, 1);
186
musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
187
devctl |= MUSB_DEVCTL_SESSION;
193
/* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and
194
* jumping right to B_IDLE...
198
musb->xceiv->state = OTG_STATE_B_IDLE;
199
devctl &= ~MUSB_DEVCTL_SESSION;
203
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
205
dev_dbg(musb->controller, "VBUS %s, devctl %02x "
206
/* otg %3x conf %08x prcm %08x */ "\n",
207
otg_state_string(musb->xceiv->state),
208
musb_readb(musb->mregs, MUSB_DEVCTL));
211
static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
213
u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
215
devctl |= MUSB_DEVCTL_SESSION;
216
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
222
static inline void omap2430_low_level_exit(struct musb *musb)
227
l = musb_readl(musb->mregs, OTG_FORCESTDBY);
228
l |= ENABLEFORCE; /* enable MSTANDBY */
229
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
232
static inline void omap2430_low_level_init(struct musb *musb)
236
l = musb_readl(musb->mregs, OTG_FORCESTDBY);
237
l &= ~ENABLEFORCE; /* disable MSTANDBY */
238
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
242
void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
244
struct omap2430_glue *glue = _glue;
245
struct musb *musb = glue_to_musb(glue);
247
glue->status = status;
249
dev_err(glue->dev, "musb core is not yet ready\n");
253
schedule_work(&glue->omap_musb_mailbox_work);
255
EXPORT_SYMBOL_GPL(omap_musb_mailbox);
257
static void omap_musb_set_mailbox(struct omap2430_glue *glue)
259
struct musb *musb = glue_to_musb(glue);
260
struct device *dev = musb->controller;
261
struct musb_hdrc_platform_data *pdata = dev->platform_data;
262
struct omap_musb_board_data *data = pdata->board_data;
263
struct usb_otg *otg = musb->xceiv->otg;
265
switch (glue->status) {
266
case OMAP_MUSB_ID_GROUND:
267
dev_dbg(dev, "ID GND\n");
269
otg->default_a = true;
270
musb->xceiv->state = OTG_STATE_A_IDLE;
271
musb->xceiv->last_event = USB_EVENT_ID;
272
if (!is_otg_enabled(musb) || musb->gadget_driver) {
273
pm_runtime_get_sync(dev);
274
usb_phy_init(musb->xceiv);
275
omap2430_musb_set_vbus(musb, 1);
279
case OMAP_MUSB_VBUS_VALID:
280
dev_dbg(dev, "VBUS Connect\n");
282
otg->default_a = false;
283
musb->xceiv->state = OTG_STATE_B_IDLE;
284
musb->xceiv->last_event = USB_EVENT_VBUS;
285
if (musb->gadget_driver)
286
pm_runtime_get_sync(dev);
287
usb_phy_init(musb->xceiv);
290
case OMAP_MUSB_ID_FLOAT:
291
case OMAP_MUSB_VBUS_OFF:
292
dev_dbg(dev, "VBUS Disconnect\n");
294
musb->xceiv->last_event = USB_EVENT_NONE;
295
if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
296
if (musb->gadget_driver) {
297
pm_runtime_mark_last_busy(dev);
298
pm_runtime_put_autosuspend(dev);
301
if (data->interface_type == MUSB_INTERFACE_UTMI) {
302
if (musb->xceiv->otg->set_vbus)
303
otg_set_vbus(musb->xceiv->otg, 0);
305
usb_phy_shutdown(musb->xceiv);
308
dev_dbg(dev, "ID float\n");
313
static void omap_musb_mailbox_work(struct work_struct *mailbox_work)
315
struct omap2430_glue *glue = container_of(mailbox_work,
316
struct omap2430_glue, omap_musb_mailbox_work);
317
omap_musb_set_mailbox(glue);
321
static int omap2430_musb_init(struct musb *musb)
326
struct device *dev = musb->controller;
327
struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
328
struct musb_hdrc_platform_data *plat = dev->platform_data;
329
struct omap_musb_board_data *data = plat->board_data;
331
struct omap_musb_board_data *data =
332
(struct omap_musb_board_data *)musb->controller;
337
/* We require some kind of external transceiver, hooked
338
* up through ULPI. TWL4030-family PMICs include one,
339
* which needs a driver, drivers aren't always needed.
341
musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
342
if (IS_ERR_OR_NULL(musb->xceiv)) {
343
pr_err("HS USB OTG: no transceiver configured\n");
347
status = pm_runtime_get_sync(dev);
349
dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
354
l = musb_readl(musb->mregs, OTG_INTERFSEL);
356
if (data->interface_type == MUSB_INTERFACE_UTMI) {
357
/* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
358
l &= ~ULPI_12PIN; /* Disable ULPI */
359
l |= UTMI_8BIT; /* Enable UTMI */
364
musb_writel(musb->mregs, OTG_INTERFSEL, l);
366
pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
367
"sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n",
368
musb_readl(musb->mregs, OTG_REVISION),
369
musb_readl(musb->mregs, OTG_SYSCONFIG),
370
musb_readl(musb->mregs, OTG_SYSSTATUS),
371
musb_readl(musb->mregs, OTG_INTERFSEL),
372
musb_readl(musb->mregs, OTG_SIMENABLE));
375
setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
377
if (glue->status != OMAP_MUSB_UNKNOWN)
378
omap_musb_set_mailbox(glue);
380
pm_runtime_put_noidle(musb->controller);
388
static void omap2430_musb_enable(struct musb *musb)
392
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
393
struct device *dev = musb->controller;
394
struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
395
struct musb_hdrc_platform_data *pdata = dev->platform_data;
396
struct omap_musb_board_data *data = pdata->board_data;
398
switch (glue->status) {
400
case OMAP_MUSB_ID_GROUND:
401
usb_phy_init(musb->xceiv);
402
if (data->interface_type != MUSB_INTERFACE_UTMI)
404
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
405
/* start the session */
406
devctl |= MUSB_DEVCTL_SESSION;
407
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
408
while (musb_readb(musb->mregs, MUSB_DEVCTL) &
409
MUSB_DEVCTL_BDEVICE) {
412
if (time_after(jiffies, timeout)) {
413
dev_err(dev, "configured as A device timeout");
419
case OMAP_MUSB_VBUS_VALID:
420
usb_phy_init(musb->xceiv);
427
#ifdef CONFIG_TWL4030_USB
428
if (twl4030_usb_ulpi_init()) {
429
serial_printf("ERROR: %s Could not initialize PHY\n",
430
__PRETTY_FUNCTION__);
436
static void omap2430_musb_disable(struct musb *musb)
439
struct device *dev = musb->controller;
440
struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
442
if (glue->status != OMAP_MUSB_UNKNOWN)
443
usb_phy_shutdown(musb->xceiv);
447
static int omap2430_musb_exit(struct musb *musb)
449
del_timer_sync(&musb_idle_timer);
451
omap2430_low_level_exit(musb);
457
static const struct musb_platform_ops omap2430_ops = {
459
const struct musb_platform_ops omap2430_ops = {
461
.init = omap2430_musb_init,
462
.exit = omap2430_musb_exit,
465
.set_mode = omap2430_musb_set_mode,
466
.try_idle = omap2430_musb_try_idle,
468
.set_vbus = omap2430_musb_set_vbus,
471
.enable = omap2430_musb_enable,
472
.disable = omap2430_musb_disable,
476
static u64 omap2430_dmamask = DMA_BIT_MASK(32);
478
static int __devinit omap2430_probe(struct platform_device *pdev)
480
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
481
struct platform_device *musb;
482
struct omap2430_glue *glue;
485
glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
487
dev_err(&pdev->dev, "failed to allocate glue context\n");
491
musb = platform_device_alloc("musb-hdrc", -1);
493
dev_err(&pdev->dev, "failed to allocate musb device\n");
497
musb->dev.parent = &pdev->dev;
498
musb->dev.dma_mask = &omap2430_dmamask;
499
musb->dev.coherent_dma_mask = omap2430_dmamask;
501
glue->dev = &pdev->dev;
503
glue->status = OMAP_MUSB_UNKNOWN;
505
pdata->platform_ops = &omap2430_ops;
507
platform_set_drvdata(pdev, glue);
510
* REVISIT if we ever have two instances of the wrapper, we will be
515
INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work);
517
ret = platform_device_add_resources(musb, pdev->resource,
518
pdev->num_resources);
520
dev_err(&pdev->dev, "failed to add resources\n");
524
ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
526
dev_err(&pdev->dev, "failed to add platform_data\n");
530
pm_runtime_enable(&pdev->dev);
532
ret = platform_device_add(musb);
534
dev_err(&pdev->dev, "failed to register musb device\n");
541
platform_device_put(musb);
547
static int __devexit omap2430_remove(struct platform_device *pdev)
549
struct omap2430_glue *glue = platform_get_drvdata(pdev);
551
cancel_work_sync(&glue->omap_musb_mailbox_work);
552
platform_device_del(glue->musb);
553
platform_device_put(glue->musb);
560
static int omap2430_runtime_suspend(struct device *dev)
562
struct omap2430_glue *glue = dev_get_drvdata(dev);
563
struct musb *musb = glue_to_musb(glue);
566
musb->context.otg_interfsel = musb_readl(musb->mregs,
569
omap2430_low_level_exit(musb);
570
usb_phy_set_suspend(musb->xceiv, 1);
576
static int omap2430_runtime_resume(struct device *dev)
578
struct omap2430_glue *glue = dev_get_drvdata(dev);
579
struct musb *musb = glue_to_musb(glue);
582
omap2430_low_level_init(musb);
583
musb_writel(musb->mregs, OTG_INTERFSEL,
584
musb->context.otg_interfsel);
586
usb_phy_set_suspend(musb->xceiv, 0);
592
static struct dev_pm_ops omap2430_pm_ops = {
593
.runtime_suspend = omap2430_runtime_suspend,
594
.runtime_resume = omap2430_runtime_resume,
597
#define DEV_PM_OPS (&omap2430_pm_ops)
599
#define DEV_PM_OPS NULL
602
static struct platform_driver omap2430_driver = {
603
.probe = omap2430_probe,
604
.remove = __devexit_p(omap2430_remove),
606
.name = "musb-omap2430",
611
MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer");
612
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
613
MODULE_LICENSE("GPL v2");
615
static int __init omap2430_init(void)
617
return platform_driver_register(&omap2430_driver);
619
subsys_initcall(omap2430_init);
621
static void __exit omap2430_exit(void)
623
platform_driver_unregister(&omap2430_driver);
625
module_exit(omap2430_exit);