1 /* 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> 7 * 8 * This file is part of the Inventra Controller Driver for Linux. 9 * 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 13 * Foundation. 14 * 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. 20 * 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 25 * 26 */ 27 #include <linux/module.h> 28 #include <linux/kernel.h> 29 #include <linux/sched.h> 30 #include <linux/init.h> 31 #include <linux/list.h> 32 #include <linux/io.h> 33 #include <linux/of.h> 34 #include <linux/platform_device.h> 35 #include <linux/dma-mapping.h> 36 #include <linux/pm_runtime.h> 37 #include <linux/err.h> 38 #include <linux/delay.h> 39 #include <linux/usb/musb.h> 40 #include <linux/phy/omap_control_phy.h> 41 #include <linux/of_platform.h> 42 43 #include "musb_core.h" 44 #include "omap2430.h" 45 46 struct omap2430_glue { 47 struct device *dev; 48 struct platform_device *musb; 49 enum musb_vbus_id_status status; 50 struct work_struct omap_musb_mailbox_work; 51 struct device *control_otghs; 52 bool cable_connected; 53 bool enabled; 54 bool powered; 55 }; 56 #define glue_to_musb(g) platform_get_drvdata(g->musb) 57 58 static struct omap2430_glue *_glue; 59 60 static void omap2430_musb_set_vbus(struct musb *musb, int is_on) 61 { 62 struct usb_otg *otg = musb->xceiv->otg; 63 u8 devctl; 64 unsigned long timeout = jiffies + msecs_to_jiffies(1000); 65 /* HDRC controls CPEN, but beware current surges during device 66 * connect. They can trigger transient overcurrent conditions 67 * that must be ignored. 68 */ 69 70 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 71 72 if (is_on) { 73 if (musb->xceiv->otg->state == OTG_STATE_A_IDLE) { 74 int loops = 100; 75 /* start the session */ 76 devctl |= MUSB_DEVCTL_SESSION; 77 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); 78 /* 79 * Wait for the musb to set as A device to enable the 80 * VBUS 81 */ 82 while (musb_readb(musb->mregs, MUSB_DEVCTL) & 83 MUSB_DEVCTL_BDEVICE) { 84 85 mdelay(5); 86 cpu_relax(); 87 88 if (time_after(jiffies, timeout) 89 || loops-- <= 0) { 90 dev_err(musb->controller, 91 "configured as A device timeout"); 92 break; 93 } 94 } 95 96 otg_set_vbus(otg, 1); 97 } else { 98 musb->is_active = 1; 99 otg->default_a = 1; 100 musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; 101 devctl |= MUSB_DEVCTL_SESSION; 102 MUSB_HST_MODE(musb); 103 } 104 } else { 105 musb->is_active = 0; 106 107 /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and 108 * jumping right to B_IDLE... 109 */ 110 111 otg->default_a = 0; 112 musb->xceiv->otg->state = OTG_STATE_B_IDLE; 113 devctl &= ~MUSB_DEVCTL_SESSION; 114 115 MUSB_DEV_MODE(musb); 116 } 117 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); 118 119 dev_dbg(musb->controller, "VBUS %s, devctl %02x " 120 /* otg %3x conf %08x prcm %08x */ "\n", 121 usb_otg_state_string(musb->xceiv->otg->state), 122 musb_readb(musb->mregs, MUSB_DEVCTL)); 123 } 124 125 static inline void omap2430_low_level_exit(struct musb *musb) 126 { 127 u32 l; 128 129 /* in any role */ 130 l = musb_readl(musb->mregs, OTG_FORCESTDBY); 131 l |= ENABLEFORCE; /* enable MSTANDBY */ 132 musb_writel(musb->mregs, OTG_FORCESTDBY, l); 133 } 134 135 static inline void omap2430_low_level_init(struct musb *musb) 136 { 137 u32 l; 138 139 l = musb_readl(musb->mregs, OTG_FORCESTDBY); 140 l &= ~ENABLEFORCE; /* disable MSTANDBY */ 141 musb_writel(musb->mregs, OTG_FORCESTDBY, l); 142 } 143 144 /* 145 * We can get multiple cable events so we need to keep track 146 * of the power state. Only keep power enabled if USB cable is 147 * connected and a gadget is started. 148 */ 149 static void omap2430_set_power(struct musb *musb, bool enabled, bool cable) 150 { 151 struct device *dev = musb->controller; 152 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); 153 bool power_up; 154 int res; 155 156 if (glue->enabled != enabled) 157 glue->enabled = enabled; 158 159 if (glue->cable_connected != cable) 160 glue->cable_connected = cable; 161 162 power_up = glue->enabled && glue->cable_connected; 163 if (power_up == glue->powered) { 164 dev_warn(musb->controller, "power state already %i\n", 165 power_up); 166 return; 167 } 168 169 glue->powered = power_up; 170 171 if (power_up) { 172 res = pm_runtime_get_sync(musb->controller); 173 if (res < 0) { 174 dev_err(musb->controller, "could not enable: %i", res); 175 glue->powered = false; 176 } 177 } else { 178 pm_runtime_mark_last_busy(musb->controller); 179 pm_runtime_put_autosuspend(musb->controller); 180 } 181 } 182 183 static int omap2430_musb_mailbox(enum musb_vbus_id_status status) 184 { 185 struct omap2430_glue *glue = _glue; 186 187 if (!glue) { 188 pr_err("%s: musb core is not yet initialized\n", __func__); 189 return -EPROBE_DEFER; 190 } 191 glue->status = status; 192 193 if (!glue_to_musb(glue)) { 194 pr_err("%s: musb core is not yet ready\n", __func__); 195 return -EPROBE_DEFER; 196 } 197 198 schedule_work(&glue->omap_musb_mailbox_work); 199 200 return 0; 201 } 202 203 static void omap_musb_set_mailbox(struct omap2430_glue *glue) 204 { 205 struct musb *musb = glue_to_musb(glue); 206 struct device *dev = musb->controller; 207 struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev); 208 struct omap_musb_board_data *data = pdata->board_data; 209 struct usb_otg *otg = musb->xceiv->otg; 210 bool cable_connected; 211 212 cable_connected = ((glue->status == MUSB_ID_GROUND) || 213 (glue->status == MUSB_VBUS_VALID)); 214 215 if (cable_connected) 216 omap2430_set_power(musb, glue->enabled, cable_connected); 217 218 switch (glue->status) { 219 case MUSB_ID_GROUND: 220 dev_dbg(dev, "ID GND\n"); 221 222 otg->default_a = true; 223 musb->xceiv->otg->state = OTG_STATE_A_IDLE; 224 musb->xceiv->last_event = USB_EVENT_ID; 225 if (musb->gadget_driver) { 226 omap_control_usb_set_mode(glue->control_otghs, 227 USB_MODE_HOST); 228 omap2430_musb_set_vbus(musb, 1); 229 } 230 break; 231 232 case MUSB_VBUS_VALID: 233 dev_dbg(dev, "VBUS Connect\n"); 234 235 otg->default_a = false; 236 musb->xceiv->otg->state = OTG_STATE_B_IDLE; 237 musb->xceiv->last_event = USB_EVENT_VBUS; 238 omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE); 239 break; 240 241 case MUSB_ID_FLOAT: 242 case MUSB_VBUS_OFF: 243 dev_dbg(dev, "VBUS Disconnect\n"); 244 245 musb->xceiv->last_event = USB_EVENT_NONE; 246 if (musb->gadget_driver) 247 omap2430_musb_set_vbus(musb, 0); 248 249 if (data->interface_type == MUSB_INTERFACE_UTMI) 250 otg_set_vbus(musb->xceiv->otg, 0); 251 252 omap_control_usb_set_mode(glue->control_otghs, 253 USB_MODE_DISCONNECT); 254 break; 255 default: 256 dev_dbg(dev, "ID float\n"); 257 } 258 259 if (!cable_connected) 260 omap2430_set_power(musb, glue->enabled, cable_connected); 261 262 atomic_notifier_call_chain(&musb->xceiv->notifier, 263 musb->xceiv->last_event, NULL); 264 } 265 266 267 static void omap_musb_mailbox_work(struct work_struct *mailbox_work) 268 { 269 struct omap2430_glue *glue = container_of(mailbox_work, 270 struct omap2430_glue, omap_musb_mailbox_work); 271 272 omap_musb_set_mailbox(glue); 273 } 274 275 static irqreturn_t omap2430_musb_interrupt(int irq, void *__hci) 276 { 277 unsigned long flags; 278 irqreturn_t retval = IRQ_NONE; 279 struct musb *musb = __hci; 280 281 spin_lock_irqsave(&musb->lock, flags); 282 283 musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); 284 musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); 285 musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); 286 287 if (musb->int_usb || musb->int_tx || musb->int_rx) 288 retval = musb_interrupt(musb); 289 290 spin_unlock_irqrestore(&musb->lock, flags); 291 292 return retval; 293 } 294 295 static int omap2430_musb_init(struct musb *musb) 296 { 297 u32 l; 298 int status = 0; 299 struct device *dev = musb->controller; 300 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); 301 struct musb_hdrc_platform_data *plat = dev_get_platdata(dev); 302 struct omap_musb_board_data *data = plat->board_data; 303 304 /* We require some kind of external transceiver, hooked 305 * up through ULPI. TWL4030-family PMICs include one, 306 * which needs a driver, drivers aren't always needed. 307 */ 308 if (dev->parent->of_node) { 309 musb->phy = devm_phy_get(dev->parent, "usb2-phy"); 310 311 /* We can't totally remove musb->xceiv as of now because 312 * musb core uses xceiv.state and xceiv.otg. Once we have 313 * a separate state machine to handle otg, these can be moved 314 * out of xceiv and then we can start using the generic PHY 315 * framework 316 */ 317 musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, 318 "usb-phy", 0); 319 } else { 320 musb->xceiv = devm_usb_get_phy_dev(dev, 0); 321 musb->phy = devm_phy_get(dev, "usb"); 322 } 323 324 if (IS_ERR(musb->xceiv)) { 325 status = PTR_ERR(musb->xceiv); 326 327 if (status == -ENXIO) 328 return status; 329 330 pr_err("HS USB OTG: no transceiver configured\n"); 331 return -EPROBE_DEFER; 332 } 333 334 if (IS_ERR(musb->phy)) { 335 pr_err("HS USB OTG: no PHY configured\n"); 336 return PTR_ERR(musb->phy); 337 } 338 musb->isr = omap2430_musb_interrupt; 339 phy_init(musb->phy); 340 341 l = musb_readl(musb->mregs, OTG_INTERFSEL); 342 343 if (data->interface_type == MUSB_INTERFACE_UTMI) { 344 /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */ 345 l &= ~ULPI_12PIN; /* Disable ULPI */ 346 l |= UTMI_8BIT; /* Enable UTMI */ 347 } else { 348 l |= ULPI_12PIN; 349 } 350 351 musb_writel(musb->mregs, OTG_INTERFSEL, l); 352 353 pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " 354 "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", 355 musb_readl(musb->mregs, OTG_REVISION), 356 musb_readl(musb->mregs, OTG_SYSCONFIG), 357 musb_readl(musb->mregs, OTG_SYSSTATUS), 358 musb_readl(musb->mregs, OTG_INTERFSEL), 359 musb_readl(musb->mregs, OTG_SIMENABLE)); 360 361 if (glue->status != MUSB_UNKNOWN) 362 omap_musb_set_mailbox(glue); 363 364 return 0; 365 } 366 367 static void omap2430_musb_enable(struct musb *musb) 368 { 369 u8 devctl; 370 unsigned long timeout = jiffies + msecs_to_jiffies(1000); 371 struct device *dev = musb->controller; 372 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); 373 struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev); 374 struct omap_musb_board_data *data = pdata->board_data; 375 376 if (!WARN_ON(!musb->phy)) 377 phy_power_on(musb->phy); 378 379 omap2430_set_power(musb, true, glue->cable_connected); 380 381 switch (glue->status) { 382 383 case MUSB_ID_GROUND: 384 omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST); 385 if (data->interface_type != MUSB_INTERFACE_UTMI) 386 break; 387 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 388 /* start the session */ 389 devctl |= MUSB_DEVCTL_SESSION; 390 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); 391 while (musb_readb(musb->mregs, MUSB_DEVCTL) & 392 MUSB_DEVCTL_BDEVICE) { 393 cpu_relax(); 394 395 if (time_after(jiffies, timeout)) { 396 dev_err(dev, "configured as A device timeout"); 397 break; 398 } 399 } 400 break; 401 402 case MUSB_VBUS_VALID: 403 omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE); 404 break; 405 406 default: 407 break; 408 } 409 } 410 411 static void omap2430_musb_disable(struct musb *musb) 412 { 413 struct device *dev = musb->controller; 414 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); 415 416 if (!WARN_ON(!musb->phy)) 417 phy_power_off(musb->phy); 418 419 if (glue->status != MUSB_UNKNOWN) 420 omap_control_usb_set_mode(glue->control_otghs, 421 USB_MODE_DISCONNECT); 422 423 omap2430_set_power(musb, false, glue->cable_connected); 424 } 425 426 static int omap2430_musb_exit(struct musb *musb) 427 { 428 struct device *dev = musb->controller; 429 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); 430 431 omap2430_low_level_exit(musb); 432 phy_exit(musb->phy); 433 musb->phy = NULL; 434 cancel_work_sync(&glue->omap_musb_mailbox_work); 435 436 return 0; 437 } 438 439 static const struct musb_platform_ops omap2430_ops = { 440 .quirks = MUSB_DMA_INVENTRA, 441 #ifdef CONFIG_USB_INVENTRA_DMA 442 .dma_init = musbhs_dma_controller_create, 443 .dma_exit = musbhs_dma_controller_destroy, 444 #endif 445 .init = omap2430_musb_init, 446 .exit = omap2430_musb_exit, 447 448 .set_vbus = omap2430_musb_set_vbus, 449 450 .enable = omap2430_musb_enable, 451 .disable = omap2430_musb_disable, 452 453 .phy_callback = omap2430_musb_mailbox, 454 }; 455 456 static u64 omap2430_dmamask = DMA_BIT_MASK(32); 457 458 static int omap2430_probe(struct platform_device *pdev) 459 { 460 struct resource musb_resources[3]; 461 struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); 462 struct omap_musb_board_data *data; 463 struct platform_device *musb; 464 struct omap2430_glue *glue; 465 struct device_node *np = pdev->dev.of_node; 466 struct musb_hdrc_config *config; 467 int ret = -ENOMEM, val; 468 469 glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); 470 if (!glue) 471 goto err0; 472 473 musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); 474 if (!musb) { 475 dev_err(&pdev->dev, "failed to allocate musb device\n"); 476 goto err0; 477 } 478 479 musb->dev.parent = &pdev->dev; 480 musb->dev.dma_mask = &omap2430_dmamask; 481 musb->dev.coherent_dma_mask = omap2430_dmamask; 482 483 glue->dev = &pdev->dev; 484 glue->musb = musb; 485 glue->status = MUSB_UNKNOWN; 486 glue->control_otghs = ERR_PTR(-ENODEV); 487 488 if (np) { 489 struct device_node *control_node; 490 struct platform_device *control_pdev; 491 492 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 493 if (!pdata) 494 goto err2; 495 496 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 497 if (!data) 498 goto err2; 499 500 config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); 501 if (!config) 502 goto err2; 503 504 of_property_read_u32(np, "mode", (u32 *)&pdata->mode); 505 of_property_read_u32(np, "interface-type", 506 (u32 *)&data->interface_type); 507 of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps); 508 of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits); 509 of_property_read_u32(np, "power", (u32 *)&pdata->power); 510 511 ret = of_property_read_u32(np, "multipoint", &val); 512 if (!ret && val) 513 config->multipoint = true; 514 515 pdata->board_data = data; 516 pdata->config = config; 517 518 control_node = of_parse_phandle(np, "ctrl-module", 0); 519 if (control_node) { 520 control_pdev = of_find_device_by_node(control_node); 521 if (!control_pdev) { 522 dev_err(&pdev->dev, "Failed to get control device\n"); 523 ret = -EINVAL; 524 goto err2; 525 } 526 glue->control_otghs = &control_pdev->dev; 527 } 528 } 529 pdata->platform_ops = &omap2430_ops; 530 531 platform_set_drvdata(pdev, glue); 532 533 /* 534 * REVISIT if we ever have two instances of the wrapper, we will be 535 * in big trouble 536 */ 537 _glue = glue; 538 539 INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work); 540 541 memset(musb_resources, 0x00, sizeof(*musb_resources) * 542 ARRAY_SIZE(musb_resources)); 543 544 musb_resources[0].name = pdev->resource[0].name; 545 musb_resources[0].start = pdev->resource[0].start; 546 musb_resources[0].end = pdev->resource[0].end; 547 musb_resources[0].flags = pdev->resource[0].flags; 548 549 musb_resources[1].name = pdev->resource[1].name; 550 musb_resources[1].start = pdev->resource[1].start; 551 musb_resources[1].end = pdev->resource[1].end; 552 musb_resources[1].flags = pdev->resource[1].flags; 553 554 musb_resources[2].name = pdev->resource[2].name; 555 musb_resources[2].start = pdev->resource[2].start; 556 musb_resources[2].end = pdev->resource[2].end; 557 musb_resources[2].flags = pdev->resource[2].flags; 558 559 ret = platform_device_add_resources(musb, musb_resources, 560 ARRAY_SIZE(musb_resources)); 561 if (ret) { 562 dev_err(&pdev->dev, "failed to add resources\n"); 563 goto err2; 564 } 565 566 ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); 567 if (ret) { 568 dev_err(&pdev->dev, "failed to add platform_data\n"); 569 goto err2; 570 } 571 572 pm_runtime_enable(glue->dev); 573 pm_runtime_use_autosuspend(glue->dev); 574 pm_runtime_set_autosuspend_delay(glue->dev, 500); 575 576 ret = platform_device_add(musb); 577 if (ret) { 578 dev_err(&pdev->dev, "failed to register musb device\n"); 579 goto err2; 580 } 581 582 return 0; 583 584 err2: 585 platform_device_put(musb); 586 587 err0: 588 return ret; 589 } 590 591 static int omap2430_remove(struct platform_device *pdev) 592 { 593 struct omap2430_glue *glue = platform_get_drvdata(pdev); 594 struct musb *musb = glue_to_musb(glue); 595 596 pm_runtime_get_sync(glue->dev); 597 platform_device_unregister(glue->musb); 598 omap2430_set_power(musb, false, false); 599 pm_runtime_put_sync(glue->dev); 600 pm_runtime_dont_use_autosuspend(glue->dev); 601 pm_runtime_disable(glue->dev); 602 603 return 0; 604 } 605 606 #ifdef CONFIG_PM 607 608 static int omap2430_runtime_suspend(struct device *dev) 609 { 610 struct omap2430_glue *glue = dev_get_drvdata(dev); 611 struct musb *musb = glue_to_musb(glue); 612 613 if (!musb) 614 return 0; 615 616 musb->context.otg_interfsel = musb_readl(musb->mregs, 617 OTG_INTERFSEL); 618 619 omap2430_low_level_exit(musb); 620 621 return 0; 622 } 623 624 static int omap2430_runtime_resume(struct device *dev) 625 { 626 struct omap2430_glue *glue = dev_get_drvdata(dev); 627 struct musb *musb = glue_to_musb(glue); 628 629 if (!musb) 630 return 0; 631 632 omap2430_low_level_init(musb); 633 musb_writel(musb->mregs, OTG_INTERFSEL, 634 musb->context.otg_interfsel); 635 636 return 0; 637 } 638 639 static struct dev_pm_ops omap2430_pm_ops = { 640 .runtime_suspend = omap2430_runtime_suspend, 641 .runtime_resume = omap2430_runtime_resume, 642 }; 643 644 #define DEV_PM_OPS (&omap2430_pm_ops) 645 #else 646 #define DEV_PM_OPS NULL 647 #endif 648 649 #ifdef CONFIG_OF 650 static const struct of_device_id omap2430_id_table[] = { 651 { 652 .compatible = "ti,omap4-musb" 653 }, 654 { 655 .compatible = "ti,omap3-musb" 656 }, 657 {}, 658 }; 659 MODULE_DEVICE_TABLE(of, omap2430_id_table); 660 #endif 661 662 static struct platform_driver omap2430_driver = { 663 .probe = omap2430_probe, 664 .remove = omap2430_remove, 665 .driver = { 666 .name = "musb-omap2430", 667 .pm = DEV_PM_OPS, 668 .of_match_table = of_match_ptr(omap2430_id_table), 669 }, 670 }; 671 672 module_platform_driver(omap2430_driver); 673 674 MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer"); 675 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); 676 MODULE_LICENSE("GPL v2"); 677