isp1760-core.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Driver for the NXP ISP1760 chip
  3. *
  4. * Copyright 2014 Laurent Pinchart
  5. * Copyright 2007 Sebastian Siewior
  6. *
  7. * Contacts:
  8. * Sebastian Siewior <bigeasy@linutronix.de>
  9. * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License
  13. * version 2 as published by the Free Software Foundation.
  14. */
  15. #include <linux/delay.h>
  16. #include <linux/gpio/consumer.h>
  17. #include <linux/io.h>
  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/slab.h>
  21. #include <linux/usb.h>
  22. #include "isp1760-core.h"
  23. #include "isp1760-hcd.h"
  24. #include "isp1760-regs.h"
  25. #include "isp1760-udc.h"
  26. static void isp1760_init_core(struct isp1760_device *isp)
  27. {
  28. u32 otgctrl;
  29. u32 hwmode;
  30. /* Low-level chip reset */
  31. if (isp->rst_gpio) {
  32. gpiod_set_value_cansleep(isp->rst_gpio, 1);
  33. mdelay(50);
  34. gpiod_set_value_cansleep(isp->rst_gpio, 0);
  35. }
  36. /*
  37. * Reset the host controller, including the CPU interface
  38. * configuration.
  39. */
  40. isp1760_write32(isp->regs, HC_RESET_REG, SW_RESET_RESET_ALL);
  41. msleep(100);
  42. /* Setup HW Mode Control: This assumes a level active-low interrupt */
  43. hwmode = HW_DATA_BUS_32BIT;
  44. if (isp->devflags & ISP1760_FLAG_BUS_WIDTH_16)
  45. hwmode &= ~HW_DATA_BUS_32BIT;
  46. if (isp->devflags & ISP1760_FLAG_ANALOG_OC)
  47. hwmode |= HW_ANA_DIGI_OC;
  48. if (isp->devflags & ISP1760_FLAG_DACK_POL_HIGH)
  49. hwmode |= HW_DACK_POL_HIGH;
  50. if (isp->devflags & ISP1760_FLAG_DREQ_POL_HIGH)
  51. hwmode |= HW_DREQ_POL_HIGH;
  52. if (isp->devflags & ISP1760_FLAG_INTR_POL_HIGH)
  53. hwmode |= HW_INTR_HIGH_ACT;
  54. if (isp->devflags & ISP1760_FLAG_INTR_EDGE_TRIG)
  55. hwmode |= HW_INTR_EDGE_TRIG;
  56. /*
  57. * The ISP1761 has a dedicated DC IRQ line but supports sharing the HC
  58. * IRQ line for both the host and device controllers. Hardcode IRQ
  59. * sharing for now and disable the DC interrupts globally to avoid
  60. * spurious interrupts during HCD registration.
  61. */
  62. if (isp->devflags & ISP1760_FLAG_ISP1761) {
  63. isp1760_write32(isp->regs, DC_MODE, 0);
  64. hwmode |= HW_COMN_IRQ;
  65. }
  66. /*
  67. * We have to set this first in case we're in 16-bit mode.
  68. * Write it twice to ensure correct upper bits if switching
  69. * to 16-bit mode.
  70. */
  71. isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode);
  72. isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode);
  73. /*
  74. * PORT 1 Control register of the ISP1760 is the OTG control register
  75. * on ISP1761.
  76. *
  77. * TODO: Really support OTG. For now we configure port 1 in device mode
  78. * when OTG is requested.
  79. */
  80. if ((isp->devflags & ISP1760_FLAG_ISP1761) &&
  81. (isp->devflags & ISP1760_FLAG_OTG_EN))
  82. otgctrl = ((HW_DM_PULLDOWN | HW_DP_PULLDOWN) << 16)
  83. | HW_OTG_DISABLE;
  84. else
  85. otgctrl = (HW_SW_SEL_HC_DC << 16)
  86. | (HW_VBUS_DRV | HW_SEL_CP_EXT);
  87. isp1760_write32(isp->regs, HC_PORT1_CTRL, otgctrl);
  88. dev_info(isp->dev, "bus width: %u, oc: %s\n",
  89. isp->devflags & ISP1760_FLAG_BUS_WIDTH_16 ? 16 : 32,
  90. isp->devflags & ISP1760_FLAG_ANALOG_OC ? "analog" : "digital");
  91. }
  92. void isp1760_set_pullup(struct isp1760_device *isp, bool enable)
  93. {
  94. isp1760_write32(isp->regs, HW_OTG_CTRL_SET,
  95. enable ? HW_DP_PULLUP : HW_DP_PULLUP << 16);
  96. }
  97. int isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
  98. struct device *dev, unsigned int devflags)
  99. {
  100. struct isp1760_device *isp;
  101. bool udc_disabled = !(devflags & ISP1760_FLAG_ISP1761);
  102. int ret;
  103. /*
  104. * If neither the HCD not the UDC is enabled return an error, as no
  105. * device would be registered.
  106. */
  107. if ((!IS_ENABLED(CONFIG_USB_ISP1760_HCD) || usb_disabled()) &&
  108. (!IS_ENABLED(CONFIG_USB_ISP1761_UDC) || udc_disabled))
  109. return -ENODEV;
  110. /* prevent usb-core allocating DMA pages */
  111. dev->dma_mask = NULL;
  112. isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL);
  113. if (!isp)
  114. return -ENOMEM;
  115. isp->dev = dev;
  116. isp->devflags = devflags;
  117. isp->rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
  118. if (IS_ERR(isp->rst_gpio))
  119. return PTR_ERR(isp->rst_gpio);
  120. isp->regs = devm_ioremap_resource(dev, mem);
  121. if (IS_ERR(isp->regs))
  122. return PTR_ERR(isp->regs);
  123. isp1760_init_core(isp);
  124. if (IS_ENABLED(CONFIG_USB_ISP1760_HCD) && !usb_disabled()) {
  125. ret = isp1760_hcd_register(&isp->hcd, isp->regs, mem, irq,
  126. irqflags | IRQF_SHARED, dev);
  127. if (ret < 0)
  128. return ret;
  129. }
  130. if (IS_ENABLED(CONFIG_USB_ISP1761_UDC) && !udc_disabled) {
  131. ret = isp1760_udc_register(isp, irq, irqflags);
  132. if (ret < 0) {
  133. isp1760_hcd_unregister(&isp->hcd);
  134. return ret;
  135. }
  136. }
  137. dev_set_drvdata(dev, isp);
  138. return 0;
  139. }
  140. void isp1760_unregister(struct device *dev)
  141. {
  142. struct isp1760_device *isp = dev_get_drvdata(dev);
  143. isp1760_udc_unregister(isp);
  144. isp1760_hcd_unregister(&isp->hcd);
  145. }
  146. MODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP");
  147. MODULE_AUTHOR("Sebastian Siewior <bigeasy@linuxtronix.de>");
  148. MODULE_LICENSE("GPL v2");