mt_usb.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * MUSB OTG controller driver for Blackfin Processors
  3. *
  4. * Copyright 2006-2008 Analog Devices Inc.
  5. *
  6. * Enter bugs at http://blackfin.uclinux.org/
  7. *
  8. * Licensed under the GPL-2 or later.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/kernel.h>
  12. #include <linux/sched.h>
  13. #include <linux/init.h>
  14. #include <linux/list.h>
  15. #include <linux/gpio.h>
  16. #include <linux/io.h>
  17. #include <linux/workqueue.h>
  18. #include <linux/usb/gadget.h>
  19. #include <mt-plat/upmu_common.h>
  20. #include "musb_core.h"
  21. enum mu3d_status {
  22. MU3D_INIT,
  23. MU3D_ON,
  24. MU3D_OFF,
  25. };
  26. /* ================================ */
  27. /* connect and disconnect functions */
  28. /* ================================ */
  29. bool mt_usb_is_device(void)
  30. {
  31. bool tmp = mtk_is_host_mode();
  32. mu3d_dbg(K_DEBUG, "%s(%s)\n", __func__, tmp ? "host" : "device");
  33. return !tmp;
  34. /* return true; */
  35. }
  36. void connection_work(struct work_struct *data)
  37. {
  38. struct musb *musb = container_of(to_delayed_work(data), struct musb, connection_work);
  39. static enum mu3d_status is_on = MU3D_INIT;
  40. bool is_usb_cable = usb_cable_connected();
  41. if (is_otg_enabled(musb) && !mt_usb_is_device()) {
  42. #ifdef CONFIG_SSUSB_PROJECT_PHY
  43. /* usb_fake_powerdown(musb->is_clk_on); */
  44. #endif
  45. musb->is_clk_on = 0;
  46. is_on = MU3D_OFF;
  47. mu3d_dbg(K_INFO, "%s, Host mode. directly return\n", __func__);
  48. return;
  49. }
  50. mu3d_dbg(K_INFO, "%s musb %s, cable %s\n", __func__,
  51. (is_on == MU3D_INIT ? "INIT" : (is_on == MU3D_ON ? "ON" : "OFF")),
  52. (is_usb_cable ? "IN" : "OUT"));
  53. if ((is_usb_cable == true) && (is_on != MU3D_ON) && (musb->usb_mode == CABLE_MODE_NORMAL)) {
  54. is_on = MU3D_ON;
  55. if (!wake_lock_active(&musb->usb_wakelock))
  56. wake_lock(&musb->usb_wakelock);
  57. /* FIXME: Should use usb_udc_start() & usb_gadget_connect(), like usb_udc_softconn_store().
  58. * But have no time to think how to handle. However i think it is the correct way.*/
  59. musb_start(musb);
  60. mu3d_dbg(K_INFO, "%s ----Connect----\n", __func__);
  61. } else if (((is_usb_cable == false) && (is_on != MU3D_OFF))
  62. || (musb->usb_mode != CABLE_MODE_NORMAL)) {
  63. is_on = MU3D_OFF;
  64. if (wake_lock_active(&musb->usb_wakelock))
  65. wake_unlock(&musb->usb_wakelock);
  66. /*FIXME: we should use usb_gadget_disconnect() & usb_udc_stop(). like usb_udc_softconn_store().
  67. * But have no time to think how to handle. However i think it is the correct way.*/
  68. musb_stop(musb);
  69. mu3d_dbg(K_INFO, "%s ----Disconnect----\n", __func__);
  70. } else {
  71. /* This if-elseif is to set wakelock when booting with USB cable.
  72. * Because battery driver does _NOT_ notify at this codition.*/
  73. #if 0
  74. if ((is_usb_cable == true) && !wake_lock_active(&musb->usb_wakelock)) {
  75. mu3d_dbg(K_INFO, "%s Boot wakelock\n", __func__);
  76. wake_lock(&musb->usb_wakelock);
  77. } else if ((is_usb_cable == false) && wake_lock_active(&musb->usb_wakelock)) {
  78. mu3d_dbg(K_INFO, "%s Boot unwakelock\n", __func__);
  79. wake_unlock(&musb->usb_wakelock);
  80. }
  81. #endif
  82. mu3d_dbg(K_INFO, "%s directly return\n", __func__);
  83. }
  84. }
  85. bool mt_usb_is_ready(void)
  86. {
  87. mu3d_dbg(K_INFO, "USB is ready or not\n");
  88. #ifdef NEVER
  89. if (!mtk_musb || !mtk_musb->is_ready)
  90. return false;
  91. else
  92. return true;
  93. #endif /* NEVER */
  94. return true;
  95. }
  96. void mt_usb_connect(void)
  97. {
  98. struct delayed_work *work;
  99. mu3d_dbg(K_INFO, "%s+\n", __func__);
  100. if (_mu3d_musb) {
  101. work = &_mu3d_musb->connection_work;
  102. /* if(!cancel_delayed_work(work)) */
  103. /* flush_workqueue(_mu3d_musb->wq); */
  104. queue_delayed_work(_mu3d_musb->wq, work, 0);
  105. } else {
  106. mu3d_dbg(K_INFO, "%s musb_musb not ready\n", __func__);
  107. }
  108. mu3d_dbg(K_INFO, "%s-\n", __func__);
  109. }
  110. EXPORT_SYMBOL_GPL(mt_usb_connect);
  111. void mt_usb_disconnect(void)
  112. {
  113. struct delayed_work *work;
  114. mu3d_dbg(K_INFO, "%s+\n", __func__);
  115. if (_mu3d_musb) {
  116. work = &_mu3d_musb->connection_work;
  117. /* if(!cancel_delayed_work(work)) */
  118. /* flush_workqueue(_mu3d_musb->wq); */
  119. queue_delayed_work(_mu3d_musb->wq, work, 0);
  120. } else {
  121. mu3d_dbg(K_INFO, "%s musb_musb not ready\n", __func__);
  122. }
  123. mu3d_dbg(K_INFO, "%s-\n", __func__);
  124. }
  125. EXPORT_SYMBOL_GPL(mt_usb_disconnect);
  126. bool usb_cable_connected(void)
  127. {
  128. u32 ret = false;
  129. #ifndef CONFIG_MTK_FPGA
  130. u32 chrdet = 0;
  131. #ifdef CONFIG_POWER_EXT
  132. chrdet = upmu_get_rgs_chrdet();
  133. #else
  134. chrdet = upmu_is_chr_det();
  135. #endif
  136. if (chrdet && ((bat_charger_type_detection() == 1) || (bat_charger_type_detection() == 2))) {
  137. ret = true;
  138. } else {
  139. if (_mu3d_musb && need_vbus_chg_int(_mu3d_musb)
  140. && is_ssusb_connected_to_pc(_mu3d_musb->ssusb))
  141. ret = true;
  142. else
  143. ret = false;
  144. }
  145. #endif
  146. return ret;
  147. }
  148. EXPORT_SYMBOL_GPL(usb_cable_connected);
  149. #ifdef NEVER
  150. void musb_platform_reset(struct musb *musb)
  151. {
  152. u16 swrst = 0;
  153. void __iomem *mbase = musb->mregs;
  154. swrst = musb_readw(mbase, MUSB_SWRST);
  155. swrst |= (MUSB_SWRST_DISUSBRESET | MUSB_SWRST_SWRST);
  156. musb_writew(mbase, MUSB_SWRST, swrst);
  157. }
  158. #endif /* NEVER */
  159. void usb_check_connect(void)
  160. {
  161. mu3d_dbg(K_INFO, "usb_check_connect\n");
  162. #ifndef CONFIG_MTK_FPGA
  163. if (usb_cable_connected())
  164. mt_usb_connect();
  165. #endif
  166. }
  167. void musb_sync_with_bat(struct musb *musb, int usb_state)
  168. {
  169. bat_charger_update_usb_state(usb_state);
  170. #if 0
  171. mu3d_dbg(K_INFO, "musb_sync_with_bat\n");
  172. #ifndef CONFIG_MTK_FPGA
  173. BATTERY_SetUSBState(usb_state);
  174. wake_up_bat();
  175. #endif
  176. #endif
  177. }