usb_platform.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * platform.c - DesignWare HS OTG Controller platform driver
  3. *
  4. * Copyright (C) Matthijs Kooijman <matthijs@stdin.nl>
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions, and the following disclaimer,
  11. * without modification.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. The names of the above-listed copyright holders may not be used
  16. * to endorse or promote products derived from this software without
  17. * specific prior written permission.
  18. *
  19. * ALTERNATIVELY, this software may be distributed under the terms of the
  20. * GNU General Public License ("GPL") as published by the Free Software
  21. * Foundation; either version 2 of the License, or (at your option) any
  22. * later version.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  25. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  26. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  27. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  28. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  29. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  30. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  31. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  32. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  33. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  34. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. */
  36. #include "usb_os_adapter.h"
  37. #include "trace.h"
  38. #include <asm/dma-mapping.h>
  39. #include <linux/usb/ch9.h>
  40. #include <linux/usb/gadget.h>
  41. #include "core.h"
  42. #include "hcd.h"
  43. #include "chip.h"
  44. #include "board.h"
  45. int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
  46. {
  47. int ret = 0;
  48. if (ret == 0)
  49. hsotg->ll_hw_enabled = false;
  50. return ret;
  51. }
  52. int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
  53. {
  54. int ret = 0;
  55. if (ret == 0)
  56. hsotg->ll_hw_enabled = true;
  57. return ret;
  58. }
  59. static int dwc2_get_dr_mode(struct dwc2_hsotg *hsotg)
  60. {
  61. if (get_usb_mode()) {
  62. hsotg->dr_mode = USB_DR_MODE_PERIPHERAL;//usb_get_dr_mode(hsotg->dev);
  63. if (hsotg->dr_mode == USB_DR_MODE_UNKNOWN)
  64. hsotg->dr_mode = USB_DR_MODE_OTG;
  65. } else {
  66. enum usb_dr_mode mode;
  67. hsotg->dr_mode = USB_DR_MODE_HOST;//usb_get_dr_mode(hsotg->dev);
  68. if (hsotg->dr_mode == USB_DR_MODE_UNKNOWN)
  69. hsotg->dr_mode = USB_DR_MODE_OTG;
  70. mode = hsotg->dr_mode;
  71. if (dwc2_hw_is_device(hsotg)) {
  72. if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) {
  73. dev_err(hsotg->dev,
  74. "Controller does not support host mode.\n");
  75. return -EINVAL;
  76. }
  77. mode = USB_DR_MODE_PERIPHERAL;
  78. } else if (dwc2_hw_is_host(hsotg)) {
  79. if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) {
  80. dev_err(hsotg->dev,
  81. "Controller does not support device mode.\n");
  82. return -EINVAL;
  83. }
  84. mode = USB_DR_MODE_HOST;
  85. } else {
  86. if (IS_ENABLED(CONFIG_USB_DWC2_HOST))
  87. mode = USB_DR_MODE_HOST;
  88. else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL))
  89. mode = USB_DR_MODE_PERIPHERAL;
  90. }
  91. if (mode != hsotg->dr_mode) {
  92. dev_warn(hsotg->dev,
  93. "Configuration mismatch. dr_mode forced to %s\n",
  94. mode == USB_DR_MODE_HOST ? "host" : "device");
  95. hsotg->dr_mode = mode;
  96. }
  97. }
  98. return 0;
  99. }
  100. //static QueueHandle_t usb_irq_queue;
  101. //static TaskHandle_t usb_irq_task;
  102. //static char first_irq = 1;
  103. irqreturn_t dwc2_hsotg_irq(int irq, void *pw);
  104. static void ark_usb_interrupt(void *param)
  105. {
  106. struct dwc2_hsotg *hsotg = (struct dwc2_hsotg *)param;
  107. //printf("ark_usb_interrupt\r\n");
  108. dwc2_handle_common_intr(hsotg->irq, param);
  109. dwc2_hcd_irq(hsotg);
  110. dwc2_hsotg_irq(hsotg->irq, param);
  111. /*if (first_irq) {
  112. dwc2_hcd_irq(hsotg);
  113. first_irq = 0;
  114. } else {
  115. portDISABLE_INTERRUPTS();
  116. xQueueSendFromISR(usb_irq_queue, NULL, 0);
  117. }*/
  118. }
  119. #if 0
  120. static void usb_irq_task_proc(void *pvParameters)
  121. {
  122. struct dwc2_hsotg *hsotg = (struct dwc2_hsotg *)pvParameters;
  123. int ret = -1;
  124. while(1) {
  125. ret = xQueueReceive(usb_irq_queue, NULL, portMAX_DELAY);
  126. if (pdFALSE == ret) {
  127. continue;
  128. }
  129. //portENTER_CRITICAL();
  130. dwc2_hcd_irq(hsotg);
  131. portENABLE_INTERRUPTS();
  132. //portEXIT_CRITICAL();
  133. }
  134. }
  135. #endif
  136. int dwc2_driver_init(struct dwc2_hsotg **dev, struct usb_hcd *hcd)
  137. {
  138. struct dwc2_hsotg *hsotg;
  139. int retval = -1;
  140. u32 size = sizeof(struct device);
  141. hsotg = devm_kzalloc(NULL, sizeof(*hsotg), GFP_KERNEL);
  142. if (!hsotg)
  143. return -ENOMEM;
  144. hsotg->dev = (struct device *)kzalloc(size, (__GFP_ZERO | GFP_KERNEL));
  145. if (NULL == hsotg->dev)
  146. goto error;
  147. hsotg->phyif = GUSBCFG_PHYIF16;
  148. hsotg->regs = REGS_USB_BASE;
  149. spin_lock_init(&(hsotg->lock));
  150. hsotg->irq = USB_IRQn;
  151. retval = request_irq(hsotg->irq, 0, ark_usb_interrupt, (void*)hsotg);
  152. if (retval)
  153. goto error;
  154. retval = dwc2_get_dr_mode(hsotg);
  155. if (retval)
  156. goto error;
  157. /*
  158. * Reset before dwc2_get_hwparams() then it could get power-on real
  159. * reset value form registers.
  160. */
  161. dwc2_core_reset_and_force_dr_mode(hsotg);
  162. /* Detect config values from hardware */
  163. retval = dwc2_get_hwparams(hsotg);
  164. if (retval)
  165. goto error;
  166. dwc2_force_dr_mode(hsotg);
  167. retval = dwc2_init_params(hsotg);
  168. if (retval)
  169. goto error;
  170. if (hsotg->dr_mode != USB_DR_MODE_HOST) {
  171. retval = dwc2_gadget_init(hsotg, hsotg->irq);
  172. if (retval)
  173. goto error;
  174. hsotg->gadget_enabled = 1;
  175. }
  176. if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) {
  177. //usb_irq_queue = xQueueCreate(1, 0);
  178. retval = dwc2_hcd_init(hsotg, hcd);
  179. if (retval) {
  180. if (hsotg->gadget_enabled)
  181. dwc2_hsotg_remove(hsotg);
  182. goto error;
  183. }
  184. hsotg->hcd_enabled = 1;
  185. }
  186. /* Gadget code manages lowlevel hw on its own */
  187. if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
  188. dwc2_lowlevel_hw_disable(hsotg);
  189. #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
  190. IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
  191. /* Postponed adding a new gadget to the udc class driver list */
  192. if (hsotg->gadget_enabled) {
  193. retval = usb_add_gadget_udc(hsotg->dev, &hsotg->gadget);
  194. if (retval) {
  195. //hsotg->gadget.udc = NULL;
  196. dwc2_hsotg_remove(hsotg);
  197. goto error;
  198. }
  199. }
  200. #endif
  201. if (dev) {
  202. *dev = hsotg;
  203. }
  204. return 0;
  205. error:
  206. if (hsotg && hsotg->dev) {
  207. kfree(hsotg->dev);
  208. }
  209. if (hsotg) {
  210. kfree(hsotg);
  211. }
  212. return retval;
  213. }
  214. int dwc2_driver_uninit(struct dwc2_hsotg *hsotg)
  215. {
  216. if (NULL == hsotg)
  217. return 0;
  218. if (hsotg->hcd_enabled)
  219. dwc2_hcd_remove(hsotg);
  220. if (hsotg->gadget_enabled)
  221. dwc2_hsotg_remove(hsotg);
  222. if (hsotg->dev)
  223. kfree(hsotg->dev);
  224. kfree(hsotg);
  225. return 0;
  226. }