qcomwlan_pwrif.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include <linux/qcomwlan_pwrif.h>
  14. #include <linux/export.h>
  15. #define GPIO_WLAN_DEEP_SLEEP_N 230
  16. #define GPIO_WLAN_DEEP_SLEEP_N_DRAGON 82
  17. #define WLAN_RESET_OUT 1
  18. #define WLAN_RESET 0
  19. static const char *id = "WLAN";
  20. /**
  21. * vos_chip_power_qrf8615() - WLAN Power Up Seq for WCN1314 rev 2.0 on QRF 8615
  22. * @on - Turn WLAN ON/OFF (1 or 0)
  23. *
  24. * Power up/down WLAN by turning on/off various regs and asserting/deasserting
  25. * Power-on-reset pin. Also, put XO A0 buffer as slave to wlan_clk_pwr_req while
  26. * turning ON WLAN and vice-versa.
  27. *
  28. * This function returns 0 on success or a non-zero value on failure.
  29. */
  30. int vos_chip_power_qrf8615(int on)
  31. {
  32. static char wlan_on;
  33. static const char *vregs_qwlan_name[] = {
  34. "8058_l20",
  35. "8058_l8",
  36. "8901_s4",
  37. "8901_lvs1",
  38. "8901_l0",
  39. "8058_s2",
  40. "8058_s1",
  41. };
  42. static const char *vregs_qwlan_pc_name[] = {
  43. "8058_l20_pc",
  44. "8058_l8_pc",
  45. NULL,
  46. NULL,
  47. "8901_l0_pc",
  48. "8058_s2_pc",
  49. NULL,
  50. };
  51. static const int vregs_qwlan_val_min[] = {
  52. 1800000,
  53. 3050000,
  54. 1225000,
  55. 0,
  56. 1200000,
  57. 1300000,
  58. 500000,
  59. };
  60. static const int vregs_qwlan_val_max[] = {
  61. 1800000,
  62. 3050000,
  63. 1225000,
  64. 0,
  65. 1200000,
  66. 1300000,
  67. 1250000,
  68. };
  69. static const int vregs_qwlan_peek_current[] = {
  70. 4000,
  71. 150000,
  72. 60000,
  73. 0,
  74. 32000,
  75. 130000,
  76. 0,
  77. };
  78. static const bool vregs_is_pin_controlled_default[] = {
  79. 1,
  80. 1,
  81. 0,
  82. 0,
  83. 1,
  84. 1,
  85. 0,
  86. };
  87. static const bool vregs_is_pin_controlled_dragon[] = {
  88. 0,
  89. 0,
  90. 0,
  91. 0,
  92. 0,
  93. 1,
  94. 0,
  95. };
  96. bool const *vregs_is_pin_controlled;
  97. static struct regulator *vregs_qwlan[ARRAY_SIZE(vregs_qwlan_name)];
  98. static struct regulator *vregs_pc_qwlan[ARRAY_SIZE(vregs_qwlan_name)];
  99. static struct msm_xo_voter *wlan_clock;
  100. int ret, i, rc = 0;
  101. unsigned wlan_gpio_deep_sleep = GPIO_WLAN_DEEP_SLEEP_N;
  102. vregs_is_pin_controlled = vregs_is_pin_controlled_default;
  103. if (machine_is_msm8x60_dragon()) {
  104. wlan_gpio_deep_sleep = GPIO_WLAN_DEEP_SLEEP_N_DRAGON;
  105. vregs_is_pin_controlled = vregs_is_pin_controlled_dragon;
  106. }
  107. /* WLAN RESET and CLK settings */
  108. if (on && !wlan_on) {
  109. /*
  110. * Program U12 GPIO expander pin IO1 to de-assert (drive 0)
  111. * WLAN_EXT_POR_N to put WLAN in reset
  112. */
  113. rc = gpio_request(wlan_gpio_deep_sleep, "WLAN_DEEP_SLEEP_N");
  114. if (rc) {
  115. pr_err("WLAN reset GPIO %d request failed\n",
  116. wlan_gpio_deep_sleep);
  117. goto fail;
  118. }
  119. rc = gpio_direction_output(wlan_gpio_deep_sleep,
  120. WLAN_RESET);
  121. if (rc < 0) {
  122. pr_err("WLAN reset GPIO %d set output direction failed",
  123. wlan_gpio_deep_sleep);
  124. goto fail_gpio_dir_out;
  125. }
  126. /* Configure TCXO to be slave to WLAN_CLK_PWR_REQ */
  127. if (wlan_clock == NULL) {
  128. wlan_clock = msm_xo_get(MSM_XO_TCXO_A0, id);
  129. if (IS_ERR(wlan_clock)) {
  130. pr_err("Failed to get TCXO_A0 voter (%ld)\n",
  131. PTR_ERR(wlan_clock));
  132. goto fail_gpio_dir_out;
  133. }
  134. }
  135. rc = msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_PIN_CTRL);
  136. if (rc < 0) {
  137. pr_err("Configuring TCXO to Pin controllable failed"
  138. "(%d)\n", rc);
  139. goto fail_xo_mode_vote;
  140. }
  141. } else if (!on && wlan_on) {
  142. if (wlan_clock != NULL)
  143. msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_OFF);
  144. gpio_set_value_cansleep(wlan_gpio_deep_sleep, WLAN_RESET);
  145. gpio_free(wlan_gpio_deep_sleep);
  146. }
  147. /* WLAN VREG settings */
  148. for (i = 0; i < ARRAY_SIZE(vregs_qwlan_name); i++) {
  149. if (on && !wlan_on) {
  150. vregs_qwlan[i] = regulator_get(NULL,
  151. vregs_qwlan_name[i]);
  152. if (IS_ERR(vregs_qwlan[i])) {
  153. pr_err("regulator get of %s failed (%ld)\n",
  154. vregs_qwlan_name[i],
  155. PTR_ERR(vregs_qwlan[i]));
  156. rc = PTR_ERR(vregs_qwlan[i]);
  157. goto vreg_get_fail;
  158. }
  159. if (vregs_qwlan_val_min[i] || vregs_qwlan_val_max[i]) {
  160. rc = regulator_set_voltage(vregs_qwlan[i],
  161. vregs_qwlan_val_min[i],
  162. vregs_qwlan_val_max[i]);
  163. if (rc) {
  164. pr_err("regulator_set_voltage(%s) failed\n",
  165. vregs_qwlan_name[i]);
  166. goto vreg_fail;
  167. }
  168. }
  169. /* vote for pin control (if needed) */
  170. if (vregs_is_pin_controlled[i]) {
  171. vregs_pc_qwlan[i] = regulator_get(NULL,
  172. vregs_qwlan_pc_name[i]);
  173. if (IS_ERR(vregs_pc_qwlan[i])) {
  174. pr_err("regulator get of %s failed "
  175. "(%ld)\n",
  176. vregs_qwlan_pc_name[i],
  177. PTR_ERR(vregs_pc_qwlan[i]));
  178. rc = PTR_ERR(vregs_pc_qwlan[i]);
  179. goto vreg_fail;
  180. }
  181. }
  182. if (vregs_qwlan_peek_current[i]) {
  183. rc = regulator_set_optimum_mode(vregs_qwlan[i],
  184. vregs_qwlan_peek_current[i]);
  185. if (rc < 0)
  186. pr_err("vreg %s set optimum mode"
  187. " failed to %d (%d)\n",
  188. vregs_qwlan_name[i], rc,
  189. vregs_qwlan_peek_current[i]);
  190. }
  191. rc = regulator_enable(vregs_qwlan[i]);
  192. if (rc < 0) {
  193. pr_err("vreg %s enable failed (%d)\n",
  194. vregs_qwlan_name[i], rc);
  195. goto vreg_fail;
  196. }
  197. if (vregs_is_pin_controlled[i]) {
  198. rc = regulator_enable(vregs_pc_qwlan[i]);
  199. if (rc < 0) {
  200. pr_err("vreg %s enable failed (%d)\n",
  201. vregs_qwlan_pc_name[i], rc);
  202. goto vreg_fail;
  203. }
  204. }
  205. } else if (!on && wlan_on) {
  206. if (vregs_qwlan_peek_current[i]) {
  207. /* For legacy reasons we pass 1mA current to
  208. * put regulator in LPM mode.
  209. */
  210. rc = regulator_set_optimum_mode(vregs_qwlan[i],
  211. 1000);
  212. if (rc < 0)
  213. pr_info("vreg %s set optimum mode"
  214. "failed (%d)\n",
  215. vregs_qwlan_name[i], rc);
  216. rc = regulator_set_voltage(vregs_qwlan[i], 0 ,
  217. vregs_qwlan_val_max[i]);
  218. if (rc)
  219. pr_err("regulator_set_voltage(%s)"
  220. "failed (%d)\n",
  221. vregs_qwlan_name[i], rc);
  222. }
  223. if (vregs_is_pin_controlled[i]) {
  224. rc = regulator_disable(vregs_pc_qwlan[i]);
  225. if (rc < 0) {
  226. pr_err("vreg %s disable failed (%d)\n",
  227. vregs_qwlan_pc_name[i], rc);
  228. goto vreg_fail;
  229. }
  230. regulator_put(vregs_pc_qwlan[i]);
  231. }
  232. rc = regulator_disable(vregs_qwlan[i]);
  233. if (rc < 0) {
  234. pr_err("vreg %s disable failed (%d)\n",
  235. vregs_qwlan_name[i], rc);
  236. goto vreg_fail;
  237. }
  238. regulator_put(vregs_qwlan[i]);
  239. }
  240. }
  241. if (on) {
  242. gpio_set_value_cansleep(wlan_gpio_deep_sleep, WLAN_RESET_OUT);
  243. wlan_on = true;
  244. }
  245. else
  246. wlan_on = false;
  247. return 0;
  248. vreg_fail:
  249. regulator_put(vregs_qwlan[i]);
  250. if (vregs_is_pin_controlled[i])
  251. regulator_put(vregs_pc_qwlan[i]);
  252. vreg_get_fail:
  253. i--;
  254. while (i >= 0) {
  255. ret = !on ? regulator_enable(vregs_qwlan[i]) :
  256. regulator_disable(vregs_qwlan[i]);
  257. if (ret < 0) {
  258. pr_err("vreg %s %s failed (%d) in err path\n",
  259. vregs_qwlan_name[i],
  260. !on ? "enable" : "disable", ret);
  261. }
  262. if (vregs_is_pin_controlled[i]) {
  263. ret = !on ? regulator_enable(vregs_pc_qwlan[i]) :
  264. regulator_disable(vregs_pc_qwlan[i]);
  265. if (ret < 0) {
  266. pr_err("vreg %s %s failed (%d) in err path\n",
  267. vregs_qwlan_pc_name[i],
  268. !on ? "enable" : "disable", ret);
  269. }
  270. }
  271. regulator_put(vregs_qwlan[i]);
  272. if (vregs_is_pin_controlled[i])
  273. regulator_put(vregs_pc_qwlan[i]);
  274. i--;
  275. }
  276. if (!on)
  277. goto fail;
  278. fail_xo_mode_vote:
  279. msm_xo_put(wlan_clock);
  280. fail_gpio_dir_out:
  281. gpio_free(wlan_gpio_deep_sleep);
  282. fail:
  283. return rc;
  284. }
  285. EXPORT_SYMBOL(vos_chip_power_qrf8615);
  286. /**
  287. * qcomwlan_pmic_xo_core_force_enable() - Force XO Core of PMIC to be ALWAYS ON
  288. * @on - Force XO Core ON/OFF (1 or 0)
  289. *
  290. * The XO_CORE controls the XO feeding the TCXO buffers (A0, A1, etc.). WLAN
  291. * wants to keep the XO core on even though our buffer A0 is in pin control
  292. * because it can take a long time turn the XO back on and warm up the buffers.
  293. * This helps in optimizing power in BMPS (power save) mode of WLAN.
  294. * The WLAN driver wrapper function takes care that this API is not called
  295. * consecutively.
  296. *
  297. * This function returns 0 on success or a non-zero value on failure.
  298. */
  299. int qcomwlan_pmic_xo_core_force_enable(int on)
  300. {
  301. static struct msm_xo_voter *wlan_ps;
  302. int rc = 0;
  303. if (wlan_ps == NULL) {
  304. wlan_ps = msm_xo_get(MSM_XO_CORE, id);
  305. if (IS_ERR(wlan_ps)) {
  306. pr_err("Failed to get XO CORE voter (%ld)\n",
  307. PTR_ERR(wlan_ps));
  308. goto fail;
  309. }
  310. }
  311. if (on)
  312. rc = msm_xo_mode_vote(wlan_ps, MSM_XO_MODE_ON);
  313. else
  314. rc = msm_xo_mode_vote(wlan_ps, MSM_XO_MODE_OFF);
  315. if (rc < 0) {
  316. pr_err("XO Core %s failed (%d)\n",
  317. on ? "enable" : "disable", rc);
  318. goto fail_xo_mode_vote;
  319. }
  320. return 0;
  321. fail_xo_mode_vote:
  322. msm_xo_put(wlan_ps);
  323. fail:
  324. return rc;
  325. }
  326. EXPORT_SYMBOL(qcomwlan_pmic_xo_core_force_enable);
  327. /**
  328. * qcomwlan_freq_change_1p3v_supply() - function to change the freq for 1.3V RF supply.
  329. * @freq - freq of the 1.3V Supply
  330. *
  331. * This function returns 0 on success or a non-zero value on failure.
  332. */
  333. int qcomwlan_freq_change_1p3v_supply(enum rpm_vreg_freq freq)
  334. {
  335. return rpm_vreg_set_frequency(RPM_VREG_ID_PM8058_S2, freq);
  336. }
  337. EXPORT_SYMBOL(qcomwlan_freq_change_1p3v_supply);