wmt_detect_pwr.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. * Copyright (C) 2011-2014 MediaTek Inc.
  3. *
  4. * This program is free software: you can redistribute it and/or modify it under the terms of the
  5. * GNU General Public License version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  8. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. * See the GNU General Public License for more details.
  10. *
  11. * You should have received a copy of the GNU General Public License along with this program.
  12. * If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include <mtk_rtc.h>
  15. #ifdef DFT_TAG
  16. #undef DFT_TAG
  17. #endif
  18. #define DFT_TAG "[WMT-DETECT]"
  19. #include "wmt_detect.h"
  20. #include "wmt_gpio.h"
  21. #define INVALID_PIN_ID (0xFFFFFFFF)
  22. /*copied form WMT module*/
  23. static int wmt_detect_dump_pin_conf(void)
  24. {
  25. WMT_DETECT_INFO_FUNC("[WMT-DETECT]=>dump wmt pin configuration start<=\n");
  26. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) {
  27. WMT_DETECT_INFO_FUNC("LDO(GPIO%d)\n",
  28. gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num);
  29. } else
  30. WMT_DETECT_INFO_FUNC("LDO(not defined)\n");
  31. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) {
  32. WMT_DETECT_INFO_FUNC("PMU(GPIO%d)\n",
  33. gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num);
  34. } else
  35. WMT_DETECT_INFO_FUNC("PMU(not defined)\n");
  36. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num) {
  37. WMT_DETECT_INFO_FUNC("PMUV28(GPIO%d)\n",
  38. gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num);
  39. } else
  40. WMT_DETECT_INFO_FUNC("PMUV28(not defined)\n");
  41. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) {
  42. WMT_DETECT_INFO_FUNC("RST(GPIO%d)\n",
  43. gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num);
  44. } else
  45. WMT_DETECT_INFO_FUNC("RST(not defined)\n");
  46. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num) {
  47. WMT_DETECT_INFO_FUNC("BGF_EINT(GPIO%d)\n",
  48. gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num);
  49. } else
  50. WMT_DETECT_INFO_FUNC("BGF_EINT(not defined)\n");
  51. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num) {
  52. WMT_DETECT_INFO_FUNC("BGF_EINT_NUM(%d)\n",
  53. gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num));
  54. } else
  55. WMT_DETECT_INFO_FUNC("BGF_EINT_NUM(not defined)\n");
  56. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) {
  57. WMT_DETECT_INFO_FUNC("WIFI_EINT(GPIO%d)\n",
  58. gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num);
  59. } else
  60. WMT_DETECT_INFO_FUNC("WIFI_EINT(not defined)\n");
  61. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) {
  62. WMT_DETECT_INFO_FUNC("WIFI_EINT_NUM(%d)\n",
  63. gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num));
  64. } else
  65. WMT_DETECT_INFO_FUNC("WIFI_EINT_NUM(not defined)\n");
  66. WMT_DETECT_INFO_FUNC("[WMT-PLAT]=>dump wmt pin configuration emds<=\n");
  67. return 0;
  68. }
  69. int _wmt_detect_output_low(unsigned int id)
  70. {
  71. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) {
  72. gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 0);
  73. WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n",
  74. gpio_ctrl_info.gpio_ctrl_state[id].gpio_num,
  75. gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num));
  76. }
  77. return 0;
  78. }
  79. int _wmt_detect_output_high(unsigned int id)
  80. {
  81. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) {
  82. gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 1);
  83. WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n",
  84. gpio_ctrl_info.gpio_ctrl_state[id].gpio_num,
  85. gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num));
  86. }
  87. return 0;
  88. }
  89. int _wmt_detect_read_gpio_input(unsigned int id)
  90. {
  91. int retval = 0;
  92. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) {
  93. retval = gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num);
  94. WMT_DETECT_DBG_FUNC("WMT-DETECT: get GPIO%d val%d\n",
  95. gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, retval);
  96. }
  97. return retval;
  98. }
  99. /*This power on sequence must support all combo chip's basic power on sequence
  100. * 1. LDO control is a must, if external LDO exist
  101. * 2. PMU control is a must
  102. * 3. RST control is a must
  103. * 4. WIFI_EINT pin control is a must, used for GPIO mode for EINT status checkup
  104. * 5. RTC32k clock control is a must
  105. * */
  106. static int wmt_detect_chip_pwr_on(void)
  107. {
  108. int retval = -1;
  109. /*setting validiation check*/
  110. if ((INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) ||
  111. (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) ||
  112. (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)) {
  113. WMT_DETECT_ERR_FUNC("WMT-DETECT: either PMU(%d) or RST(%d) or WIFI_EINT(%d) is not set\n",
  114. gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num,
  115. gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num,
  116. gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num);
  117. return retval;
  118. }
  119. /*set LDO/PMU/RST to output 0, no pull*/
  120. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num)
  121. _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN);
  122. if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) {
  123. pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
  124. gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]);
  125. WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n");
  126. } else
  127. WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n");
  128. _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN);
  129. if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) {
  130. pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
  131. gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]);
  132. WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n");
  133. } else
  134. WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n");
  135. _wmt_detect_output_low(GPIO_COMBO_RST_PIN);
  136. #if 0
  137. _wmt_detect_output_high(GPIO_WIFI_EINT_PIN);
  138. #endif
  139. /*pull high LDO*/
  140. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num)
  141. _wmt_detect_output_high(GPIO_COMBO_LDO_EN_PIN);
  142. /*sleep for LDO stable time*/
  143. msleep(MAX_LDO_STABLE_TIME);
  144. /*export RTC clock, sleep for RTC stable time*/
  145. rtc_gpio_enable_32k(RTC_GPIO_USER_GPS);
  146. msleep(MAX_RTC_STABLE_TIME);
  147. /*PMU output low, RST output low, to make chip power off completely*/
  148. /*always done*/
  149. /*sleep for power off stable time*/
  150. msleep(MAX_OFF_STABLE_TIME);
  151. /*PMU output high, and sleep for reset stable time*/
  152. _wmt_detect_output_high(GPIO_COMBO_PMU_EN_PIN);
  153. #ifdef CONFIG_MTK_COMBO_COMM_NPWR
  154. if ((gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num != INVALID_PIN_ID) &&
  155. (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num != INVALID_PIN_ID)) {
  156. msleep(20);
  157. _wmt_detect_output_high(GPIO_PCM_DAISYNC_PIN);
  158. msleep(20);
  159. _wmt_detect_output_high(GPIO_COMBO_I2S_DAT_PIN);
  160. msleep(20);
  161. _wmt_detect_output_low(GPIO_COMBO_I2S_DAT_PIN);
  162. msleep(20);
  163. _wmt_detect_output_low(GPIO_PCM_DAISYNC_PIN);
  164. msleep(20);
  165. }
  166. #endif
  167. msleep(MAX_RST_STABLE_TIME);
  168. /*RST output high, and sleep for power on stable time */
  169. _wmt_detect_output_high(GPIO_COMBO_RST_PIN);
  170. msleep(MAX_ON_STABLE_TIME);
  171. retval = 0;
  172. return retval;
  173. }
  174. static int wmt_detect_chip_pwr_off(void)
  175. {
  176. /*set RST pin to input low status*/
  177. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num)
  178. _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN);
  179. /*set RST pin to input low status*/
  180. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)
  181. _wmt_detect_output_low(GPIO_COMBO_RST_PIN);
  182. /*set PMU pin to input low status*/
  183. if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)
  184. _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN);
  185. return 0;
  186. }
  187. int wmt_detect_read_ext_cmb_status(void)
  188. {
  189. int retval = 0;
  190. /*read WIFI_EINT pin status*/
  191. if (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) {
  192. retval = 0;
  193. WMT_DETECT_ERR_FUNC("WMT-DETECT: no WIFI_EINT pin set\n");
  194. } else {
  195. retval = _wmt_detect_read_gpio_input(GPIO_WIFI_EINT_PIN);
  196. WMT_DETECT_ERR_FUNC("WMT-DETECT: WIFI_EINT input status:%d\n", retval);
  197. }
  198. return retval;
  199. }
  200. int wmt_detect_chip_pwr_ctrl(int on)
  201. {
  202. int retval = -1;
  203. if (0 == on) {
  204. /*power off combo chip */
  205. retval = wmt_detect_chip_pwr_off();
  206. } else {
  207. wmt_detect_dump_pin_conf();
  208. /*power on combo chip */
  209. retval = wmt_detect_chip_pwr_on();
  210. }
  211. return retval;
  212. }
  213. int wmt_detect_sdio_pwr_ctrl(int on)
  214. {
  215. int retval = -1;
  216. #ifdef MTK_WCN_COMBO_CHIP_SUPPORT
  217. if (0 == on) {
  218. /*power off SDIO slot */
  219. retval = board_sdio_ctrl(1, 0);
  220. } else {
  221. /*power on SDIO slot */
  222. retval = board_sdio_ctrl(1, 1);
  223. }
  224. #else
  225. WMT_DETECT_WARN_FUNC("WMT-DETECT: MTK_WCN_COMBO_CHIP_SUPPORT is not set\n");
  226. #endif
  227. return retval;
  228. }