Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
omap2430.c
Go to the documentation of this file.
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 <[email protected]>
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-omap.h>
40 
41 #include "musb_core.h"
42 #include "omap2430.h"
43 
44 struct omap2430_glue {
45  struct device *dev;
50 };
51 #define glue_to_musb(g) platform_get_drvdata(g->musb)
52 
54 
55 static struct timer_list musb_idle_timer;
56 
71 static void omap4_usb_phy_mailbox(struct omap2430_glue *glue, u32 val)
72 {
73  if (glue->control_otghs)
74  writel(val, glue->control_otghs);
75 }
76 
77 static void musb_do_idle(unsigned long _musb)
78 {
79  struct musb *musb = (void *)_musb;
80  unsigned long flags;
81  u8 power;
82  u8 devctl;
83 
84  spin_lock_irqsave(&musb->lock, flags);
85 
86  switch (musb->xceiv->state) {
88 
89  devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
90  if (devctl & MUSB_DEVCTL_BDEVICE) {
91  musb->xceiv->state = OTG_STATE_B_IDLE;
92  MUSB_DEV_MODE(musb);
93  } else {
94  musb->xceiv->state = OTG_STATE_A_IDLE;
95  MUSB_HST_MODE(musb);
96  }
97  break;
99  /* finish RESUME signaling? */
100  if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
101  power = musb_readb(musb->mregs, MUSB_POWER);
102  power &= ~MUSB_POWER_RESUME;
103  dev_dbg(musb->controller, "root port resume stopped, power %02x\n", power);
104  musb_writeb(musb->mregs, MUSB_POWER, power);
105  musb->is_active = 1;
108  musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
109  usb_hcd_poll_rh_status(musb_to_hcd(musb));
110  /* NOTE: it might really be A_WAIT_BCON ... */
111  musb->xceiv->state = OTG_STATE_A_HOST;
112  }
113  break;
114  case OTG_STATE_A_HOST:
115  devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
116  if (devctl & MUSB_DEVCTL_BDEVICE)
117  musb->xceiv->state = OTG_STATE_B_IDLE;
118  else
119  musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
120  default:
121  break;
122  }
123  spin_unlock_irqrestore(&musb->lock, flags);
124 }
125 
126 
127 static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout)
128 {
129  unsigned long default_timeout = jiffies + msecs_to_jiffies(3);
130  static unsigned long last_timer;
131 
132  if (timeout == 0)
133  timeout = default_timeout;
134 
135  /* Never idle if active, or when VBUS timeout is not set as host */
136  if (musb->is_active || ((musb->a_wait_bcon == 0)
137  && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
138  dev_dbg(musb->controller, "%s active, deleting timer\n",
139  otg_state_string(musb->xceiv->state));
140  del_timer(&musb_idle_timer);
141  last_timer = jiffies;
142  return;
143  }
144 
145  if (time_after(last_timer, timeout)) {
146  if (!timer_pending(&musb_idle_timer))
147  last_timer = timeout;
148  else {
149  dev_dbg(musb->controller, "Longer idle timer already pending, ignoring\n");
150  return;
151  }
152  }
153  last_timer = timeout;
154 
155  dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n",
156  otg_state_string(musb->xceiv->state),
157  (unsigned long)jiffies_to_msecs(timeout - jiffies));
158  mod_timer(&musb_idle_timer, timeout);
159 }
160 
161 static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
162 {
163  struct usb_otg *otg = musb->xceiv->otg;
164  u8 devctl;
165  unsigned long timeout = jiffies + msecs_to_jiffies(1000);
166  /* HDRC controls CPEN, but beware current surges during device
167  * connect. They can trigger transient overcurrent conditions
168  * that must be ignored.
169  */
170 
171  devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
172 
173  if (is_on) {
174  if (musb->xceiv->state == OTG_STATE_A_IDLE) {
175  int loops = 100;
176  /* start the session */
177  devctl |= MUSB_DEVCTL_SESSION;
178  musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
179  /*
180  * Wait for the musb to set as A device to enable the
181  * VBUS
182  */
183  while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
184 
185  mdelay(5);
186  cpu_relax();
187 
188  if (time_after(jiffies, timeout)
189  || loops-- <= 0) {
190  dev_err(musb->controller,
191  "configured as A device timeout");
192  break;
193  }
194  }
195 
196  if (otg->set_vbus)
197  otg_set_vbus(otg, 1);
198  } else {
199  musb->is_active = 1;
200  otg->default_a = 1;
201  musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
202  devctl |= MUSB_DEVCTL_SESSION;
203  MUSB_HST_MODE(musb);
204  }
205  } else {
206  musb->is_active = 0;
207 
208  /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and
209  * jumping right to B_IDLE...
210  */
211 
212  otg->default_a = 0;
213  musb->xceiv->state = OTG_STATE_B_IDLE;
214  devctl &= ~MUSB_DEVCTL_SESSION;
215 
216  MUSB_DEV_MODE(musb);
217  }
218  musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
219 
220  dev_dbg(musb->controller, "VBUS %s, devctl %02x "
221  /* otg %3x conf %08x prcm %08x */ "\n",
222  otg_state_string(musb->xceiv->state),
223  musb_readb(musb->mregs, MUSB_DEVCTL));
224 }
225 
226 static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
227 {
228  u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
229 
230  devctl |= MUSB_DEVCTL_SESSION;
231  musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
232 
233  return 0;
234 }
235 
236 static inline void omap2430_low_level_exit(struct musb *musb)
237 {
238  u32 l;
239 
240  /* in any role */
241  l = musb_readl(musb->mregs, OTG_FORCESTDBY);
242  l |= ENABLEFORCE; /* enable MSTANDBY */
243  musb_writel(musb->mregs, OTG_FORCESTDBY, l);
244 }
245 
246 static inline void omap2430_low_level_init(struct musb *musb)
247 {
248  u32 l;
249 
250  l = musb_readl(musb->mregs, OTG_FORCESTDBY);
251  l &= ~ENABLEFORCE; /* disable MSTANDBY */
252  musb_writel(musb->mregs, OTG_FORCESTDBY, l);
253 }
254 
256 {
257  struct omap2430_glue *glue = _glue;
258  struct musb *musb = glue_to_musb(glue);
259 
260  glue->status = status;
261  if (!musb) {
262  dev_err(glue->dev, "musb core is not yet ready\n");
263  return;
264  }
265 
267 }
269 
270 static void omap_musb_set_mailbox(struct omap2430_glue *glue)
271 {
272  u32 val;
273  struct musb *musb = glue_to_musb(glue);
274  struct device *dev = musb->controller;
276  struct omap_musb_board_data *data = pdata->board_data;
277  struct usb_otg *otg = musb->xceiv->otg;
278 
279  switch (glue->status) {
280  case OMAP_MUSB_ID_GROUND:
281  dev_dbg(dev, "ID GND\n");
282 
283  otg->default_a = true;
284  musb->xceiv->state = OTG_STATE_A_IDLE;
285  musb->xceiv->last_event = USB_EVENT_ID;
286  if (musb->gadget_driver) {
287  pm_runtime_get_sync(dev);
288  val = AVALID | VBUSVALID;
289  omap4_usb_phy_mailbox(glue, val);
290  omap2430_musb_set_vbus(musb, 1);
291  }
292  break;
293 
295  dev_dbg(dev, "VBUS Connect\n");
296 
297  otg->default_a = false;
298  musb->xceiv->state = OTG_STATE_B_IDLE;
299  musb->xceiv->last_event = USB_EVENT_VBUS;
300  if (musb->gadget_driver)
301  pm_runtime_get_sync(dev);
302  val = IDDIG | AVALID | VBUSVALID;
303  omap4_usb_phy_mailbox(glue, val);
304  break;
305 
306  case OMAP_MUSB_ID_FLOAT:
307  case OMAP_MUSB_VBUS_OFF:
308  dev_dbg(dev, "VBUS Disconnect\n");
309 
310  musb->xceiv->last_event = USB_EVENT_NONE;
311  if (musb->gadget_driver) {
312  pm_runtime_mark_last_busy(dev);
313  pm_runtime_put_autosuspend(dev);
314  }
315 
316  if (data->interface_type == MUSB_INTERFACE_UTMI) {
317  if (musb->xceiv->otg->set_vbus)
318  otg_set_vbus(musb->xceiv->otg, 0);
319  }
320  val = SESSEND | IDDIG;
321  omap4_usb_phy_mailbox(glue, val);
322  break;
323  default:
324  dev_dbg(dev, "ID float\n");
325  }
326 }
327 
328 
329 static void omap_musb_mailbox_work(struct work_struct *mailbox_work)
330 {
331  struct omap2430_glue *glue = container_of(mailbox_work,
333  omap_musb_set_mailbox(glue);
334 }
335 
336 static int omap2430_musb_init(struct musb *musb)
337 {
338  u32 l;
339  int status = 0;
340  struct device *dev = musb->controller;
341  struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
342  struct musb_hdrc_platform_data *plat = dev->platform_data;
343  struct omap_musb_board_data *data = plat->board_data;
344 
345  /* We require some kind of external transceiver, hooked
346  * up through ULPI. TWL4030-family PMICs include one,
347  * which needs a driver, drivers aren't always needed.
348  */
350  if (IS_ERR_OR_NULL(musb->xceiv)) {
351  pr_err("HS USB OTG: no transceiver configured\n");
352  return -ENODEV;
353  }
354 
355  status = pm_runtime_get_sync(dev);
356  if (status < 0) {
357  dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
358  goto err1;
359  }
360 
361  l = musb_readl(musb->mregs, OTG_INTERFSEL);
362 
363  if (data->interface_type == MUSB_INTERFACE_UTMI) {
364  /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
365  l &= ~ULPI_12PIN; /* Disable ULPI */
366  l |= UTMI_8BIT; /* Enable UTMI */
367  } else {
368  l |= ULPI_12PIN;
369  }
370 
371  musb_writel(musb->mregs, OTG_INTERFSEL, l);
372 
373  pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
374  "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n",
375  musb_readl(musb->mregs, OTG_REVISION),
376  musb_readl(musb->mregs, OTG_SYSCONFIG),
377  musb_readl(musb->mregs, OTG_SYSSTATUS),
378  musb_readl(musb->mregs, OTG_INTERFSEL),
379  musb_readl(musb->mregs, OTG_SIMENABLE));
380 
381  setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
382 
383  if (glue->status != OMAP_MUSB_UNKNOWN)
384  omap_musb_set_mailbox(glue);
385 
386  pm_runtime_put_noidle(musb->controller);
387  return 0;
388 
389 err1:
390  return status;
391 }
392 
393 static void omap2430_musb_enable(struct musb *musb)
394 {
395  u8 devctl;
396  u32 val;
397  unsigned long timeout = jiffies + msecs_to_jiffies(1000);
398  struct device *dev = musb->controller;
399  struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
400  struct musb_hdrc_platform_data *pdata = dev->platform_data;
401  struct omap_musb_board_data *data = pdata->board_data;
402 
403  switch (glue->status) {
404 
405  case OMAP_MUSB_ID_GROUND:
406  val = AVALID | VBUSVALID;
407  omap4_usb_phy_mailbox(glue, val);
408  if (data->interface_type != MUSB_INTERFACE_UTMI)
409  break;
410  devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
411  /* start the session */
412  devctl |= MUSB_DEVCTL_SESSION;
413  musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
414  while (musb_readb(musb->mregs, MUSB_DEVCTL) &
415  MUSB_DEVCTL_BDEVICE) {
416  cpu_relax();
417 
418  if (time_after(jiffies, timeout)) {
419  dev_err(dev, "configured as A device timeout");
420  break;
421  }
422  }
423  break;
424 
426  val = IDDIG | AVALID | VBUSVALID;
427  omap4_usb_phy_mailbox(glue, val);
428  break;
429 
430  default:
431  break;
432  }
433 }
434 
435 static void omap2430_musb_disable(struct musb *musb)
436 {
437  u32 val;
438  struct device *dev = musb->controller;
439  struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
440 
441  if (glue->status != OMAP_MUSB_UNKNOWN) {
442  val = SESSEND | IDDIG;
443  omap4_usb_phy_mailbox(glue, val);
444  }
445 }
446 
447 static int omap2430_musb_exit(struct musb *musb)
448 {
449  del_timer_sync(&musb_idle_timer);
450 
451  omap2430_low_level_exit(musb);
452 
453  return 0;
454 }
455 
456 static const struct musb_platform_ops omap2430_ops = {
457  .init = omap2430_musb_init,
458  .exit = omap2430_musb_exit,
459 
460  .set_mode = omap2430_musb_set_mode,
461  .try_idle = omap2430_musb_try_idle,
462 
463  .set_vbus = omap2430_musb_set_vbus,
464 
465  .enable = omap2430_musb_enable,
466  .disable = omap2430_musb_disable,
467 };
468 
469 static u64 omap2430_dmamask = DMA_BIT_MASK(32);
470 
471 static int __devinit omap2430_probe(struct platform_device *pdev)
472 {
473  struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
474  struct omap_musb_board_data *data;
475  struct platform_device *musb;
476  struct omap2430_glue *glue;
477  struct device_node *np = pdev->dev.of_node;
478  struct musb_hdrc_config *config;
479  struct resource *res;
480  int ret = -ENOMEM;
481  int musbid;
482 
483  glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
484  if (!glue) {
485  dev_err(&pdev->dev, "failed to allocate glue context\n");
486  goto err0;
487  }
488 
489  /* get the musb id */
490  musbid = musb_get_id(&pdev->dev, GFP_KERNEL);
491  if (musbid < 0) {
492  dev_err(&pdev->dev, "failed to allocate musb id\n");
493  ret = -ENOMEM;
494  goto err0;
495  }
496 
497  musb = platform_device_alloc("musb-hdrc", musbid);
498  if (!musb) {
499  dev_err(&pdev->dev, "failed to allocate musb device\n");
500  goto err1;
501  }
502 
503  musb->id = musbid;
504  musb->dev.parent = &pdev->dev;
505  musb->dev.dma_mask = &omap2430_dmamask;
506  musb->dev.coherent_dma_mask = omap2430_dmamask;
507 
508  glue->dev = &pdev->dev;
509  glue->musb = musb;
510  glue->status = OMAP_MUSB_UNKNOWN;
511 
512  res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
513 
514  glue->control_otghs = devm_request_and_ioremap(&pdev->dev, res);
515  if (glue->control_otghs == NULL)
516  dev_dbg(&pdev->dev, "Failed to obtain control memory\n");
517 
518  if (np) {
519  pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
520  if (!pdata) {
521  dev_err(&pdev->dev,
522  "failed to allocate musb platfrom data\n");
523  ret = -ENOMEM;
524  goto err1;
525  }
526 
527  data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
528  if (!data) {
529  dev_err(&pdev->dev,
530  "failed to allocate musb board data\n");
531  ret = -ENOMEM;
532  goto err1;
533  }
534 
535  config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
536  if (!data) {
537  dev_err(&pdev->dev,
538  "failed to allocate musb hdrc config\n");
539  goto err1;
540  }
541 
542  of_property_read_u32(np, "mode", (u32 *)&pdata->mode);
543  of_property_read_u32(np, "interface_type",
544  (u32 *)&data->interface_type);
545  of_property_read_u32(np, "num_eps", (u32 *)&config->num_eps);
546  of_property_read_u32(np, "ram_bits", (u32 *)&config->ram_bits);
547  of_property_read_u32(np, "power", (u32 *)&pdata->power);
548  config->multipoint = of_property_read_bool(np, "multipoint");
549 
550  pdata->board_data = data;
551  pdata->config = config;
552  }
553 
554  pdata->platform_ops = &omap2430_ops;
555 
556  platform_set_drvdata(pdev, glue);
557 
558  /*
559  * REVISIT if we ever have two instances of the wrapper, we will be
560  * in big trouble
561  */
562  _glue = glue;
563 
564  INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work);
565 
566  ret = platform_device_add_resources(musb, pdev->resource,
567  pdev->num_resources);
568  if (ret) {
569  dev_err(&pdev->dev, "failed to add resources\n");
570  goto err2;
571  }
572 
573  ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
574  if (ret) {
575  dev_err(&pdev->dev, "failed to add platform_data\n");
576  goto err2;
577  }
578 
579  pm_runtime_enable(&pdev->dev);
580 
581  ret = platform_device_add(musb);
582  if (ret) {
583  dev_err(&pdev->dev, "failed to register musb device\n");
584  goto err2;
585  }
586 
587  return 0;
588 
589 err2:
590  platform_device_put(musb);
591 
592 err1:
593  musb_put_id(&pdev->dev, musbid);
594 
595 err0:
596  return ret;
597 }
598 
599 static int __devexit omap2430_remove(struct platform_device *pdev)
600 {
601  struct omap2430_glue *glue = platform_get_drvdata(pdev);
602 
604  musb_put_id(&pdev->dev, glue->musb->id);
606 
607  return 0;
608 }
609 
610 #ifdef CONFIG_PM
611 
612 static int omap2430_runtime_suspend(struct device *dev)
613 {
614  struct omap2430_glue *glue = dev_get_drvdata(dev);
615  struct musb *musb = glue_to_musb(glue);
616 
617  if (musb) {
618  musb->context.otg_interfsel = musb_readl(musb->mregs,
619  OTG_INTERFSEL);
620 
621  omap2430_low_level_exit(musb);
622  usb_phy_set_suspend(musb->xceiv, 1);
623  }
624 
625  return 0;
626 }
627 
628 static int omap2430_runtime_resume(struct device *dev)
629 {
630  struct omap2430_glue *glue = dev_get_drvdata(dev);
631  struct musb *musb = glue_to_musb(glue);
632 
633  if (musb) {
634  omap2430_low_level_init(musb);
635  musb_writel(musb->mregs, OTG_INTERFSEL,
636  musb->context.otg_interfsel);
637 
638  usb_phy_set_suspend(musb->xceiv, 0);
639  }
640 
641  return 0;
642 }
643 
644 static struct dev_pm_ops omap2430_pm_ops = {
645  .runtime_suspend = omap2430_runtime_suspend,
646  .runtime_resume = omap2430_runtime_resume,
647 };
648 
649 #define DEV_PM_OPS (&omap2430_pm_ops)
650 #else
651 #define DEV_PM_OPS NULL
652 #endif
653 
654 #ifdef CONFIG_OF
655 static const struct of_device_id omap2430_id_table[] = {
656  {
657  .compatible = "ti,omap4-musb"
658  },
659  {
660  .compatible = "ti,omap3-musb"
661  },
662  {},
663 };
664 MODULE_DEVICE_TABLE(of, omap2430_id_table);
665 #endif
666 
667 static struct platform_driver omap2430_driver = {
668  .probe = omap2430_probe,
669  .remove = __devexit_p(omap2430_remove),
670  .driver = {
671  .name = "musb-omap2430",
672  .pm = DEV_PM_OPS,
673  .of_match_table = of_match_ptr(omap2430_id_table),
674  },
675 };
676 
677 MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer");
678 MODULE_AUTHOR("Felipe Balbi <[email protected]>");
679 MODULE_LICENSE("GPL v2");
680 
681 static int __init omap2430_init(void)
682 {
683  return platform_driver_register(&omap2430_driver);
684 }
685 subsys_initcall(omap2430_init);
686 
687 static void __exit omap2430_exit(void)
688 {
689  platform_driver_unregister(&omap2430_driver);
690 }
691 module_exit(omap2430_exit);