wcnss_vreg.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. /* Copyright (c) 2011-2013,2015 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. #include <linux/module.h>
  13. #include <linux/slab.h>
  14. #include <linux/err.h>
  15. #include <linux/io.h>
  16. #include <linux/gpio.h>
  17. #include <linux/delay.h>
  18. #include <linux/regulator/consumer.h>
  19. #include <linux/mfd/pm8xxx/pm8921.h>
  20. #include <linux/mfd/pm8xxx/gpio.h>
  21. #include <linux/wcnss_wlan.h>
  22. #include <linux/semaphore.h>
  23. #include <linux/list.h>
  24. #include <linux/slab.h>
  25. #include <linux/clk.h>
  26. #include <mach/msm_xo.h>
  27. #include <mach/msm_iomap.h>
  28. static void __iomem *msm_wcnss_base;
  29. static LIST_HEAD(power_on_lock_list);
  30. static DEFINE_MUTEX(list_lock);
  31. static DEFINE_SEMAPHORE(wcnss_power_on_lock);
  32. static int auto_detect;
  33. #define MSM_RIVA_PHYS 0x03204000
  34. #define MSM_PRONTO_PHYS 0xfb21b000
  35. #define RIVA_PMU_OFFSET 0x28
  36. #define RIVA_SPARE_OFFSET 0x0b4
  37. #define PRONTO_SPARE_OFFSET 0x1088
  38. #define NVBIN_DLND_BIT BIT(25)
  39. #define PRONTO_IRIS_REG_READ_OFFSET 0x1134
  40. #define PRONTO_IRIS_REG_CHIP_ID 0x04
  41. /* IRIS card chip ID's */
  42. #define WCN3660 0x0200
  43. #define WCN3660A 0x0300
  44. #define WCN3660B 0x0400
  45. #define WCN3620 0x5111
  46. #define WCN3620A 0x5112
  47. #define WCN3610 0x9101
  48. #define WCN3610V1 0x9110
  49. #define WCNSS_PMU_CFG_IRIS_XO_CFG BIT(3)
  50. #define WCNSS_PMU_CFG_IRIS_XO_EN BIT(4)
  51. #define WCNSS_PMU_CFG_IRIS_XO_CFG_STS BIT(6) /* 1: in progress, 0: done */
  52. #define WCNSS_PMU_CFG_IRIS_RESET BIT(7)
  53. #define WCNSS_PMU_CFG_IRIS_RESET_STS BIT(8) /* 1: in progress, 0: done */
  54. #define WCNSS_PMU_CFG_IRIS_XO_READ BIT(9)
  55. #define WCNSS_PMU_CFG_IRIS_XO_READ_STS BIT(10)
  56. #define WCNSS_PMU_CFG_IRIS_XO_MODE 0x6
  57. #define WCNSS_PMU_CFG_IRIS_XO_MODE_48 (3 << 1)
  58. #define VREG_NULL_CONFIG 0x0000
  59. #define VREG_GET_REGULATOR_MASK 0x0001
  60. #define VREG_SET_VOLTAGE_MASK 0x0002
  61. #define VREG_OPTIMUM_MODE_MASK 0x0004
  62. #define VREG_ENABLE_MASK 0x0008
  63. #define WCNSS_INVALID_IRIS_REG 0xbaadbaad
  64. struct vregs_info {
  65. const char * const name;
  66. int state;
  67. const int nominal_min;
  68. const int low_power_min;
  69. const int max_voltage;
  70. const int uA_load;
  71. struct regulator *regulator;
  72. };
  73. /* IRIS regulators for Riva hardware */
  74. static struct vregs_info iris_vregs_riva[] = {
  75. {"iris_vddxo", VREG_NULL_CONFIG, 1800000, 0, 1800000, 10000, NULL},
  76. {"iris_vddrfa", VREG_NULL_CONFIG, 1300000, 0, 1300000, 100000, NULL},
  77. {"iris_vddpa", VREG_NULL_CONFIG, 2900000, 0, 3000000, 515000, NULL},
  78. {"iris_vdddig", VREG_NULL_CONFIG, 1200000, 0, 1225000, 10000, NULL},
  79. };
  80. /* WCNSS regulators for Riva hardware */
  81. static struct vregs_info riva_vregs[] = {
  82. /* Riva */
  83. {"riva_vddmx", VREG_NULL_CONFIG, 1050000, 0, 1150000, 0, NULL},
  84. {"riva_vddcx", VREG_NULL_CONFIG, 1050000, 0, 1150000, 0, NULL},
  85. {"riva_vddpx", VREG_NULL_CONFIG, 1800000, 0, 1800000, 0, NULL},
  86. };
  87. /* IRIS regulators for Pronto hardware */
  88. static struct vregs_info iris_vregs_pronto[] = {
  89. {"qcom,iris-vddxo", VREG_NULL_CONFIG, 1800000, 0,
  90. 1800000, 10000, NULL},
  91. {"qcom,iris-vddrfa", VREG_NULL_CONFIG, 1300000, 0,
  92. 1300000, 100000, NULL},
  93. {"qcom,iris-vddpa", VREG_NULL_CONFIG, 2900000, 0,
  94. 3350000, 515000, NULL},
  95. {"qcom,iris-vdddig", VREG_NULL_CONFIG, 1225000, 0,
  96. 1800000, 10000, NULL},
  97. };
  98. /* WCNSS regulators for Pronto hardware */
  99. static struct vregs_info pronto_vregs[] = {
  100. {"qcom,pronto-vddmx", VREG_NULL_CONFIG, 950000, 0,
  101. 1150000, 0, NULL},
  102. {"qcom,pronto-vddcx", VREG_NULL_CONFIG, 900000, 0,
  103. 1150000, 0, NULL},
  104. {"qcom,pronto-vddpx", VREG_NULL_CONFIG, 1800000, 0,
  105. 1800000, 0, NULL},
  106. };
  107. struct host_driver {
  108. char name[20];
  109. struct list_head list;
  110. };
  111. enum {
  112. IRIS_3660, /* also 3660A and 3680 */
  113. IRIS_3620
  114. };
  115. int xo_auto_detect(u32 reg)
  116. {
  117. reg >>= 30;
  118. switch (reg) {
  119. case IRIS_3660:
  120. return WCNSS_XO_48MHZ;
  121. case IRIS_3620:
  122. return WCNSS_XO_19MHZ;
  123. default:
  124. return WCNSS_XO_INVALID;
  125. }
  126. }
  127. int wcnss_get_iris_name(char *iris_name)
  128. {
  129. struct wcnss_wlan_config *cfg = NULL;
  130. int iris_id;
  131. cfg = wcnss_get_wlan_config();
  132. if (cfg) {
  133. iris_id = cfg->iris_id;
  134. iris_id = iris_id >> 16;
  135. } else {
  136. return 1;
  137. }
  138. switch (iris_id) {
  139. case WCN3660:
  140. memcpy(iris_name, "WCN3660", sizeof("WCN3660"));
  141. break;
  142. case WCN3660A:
  143. memcpy(iris_name, "WCN3660A", sizeof("WCN3660A"));
  144. break;
  145. case WCN3660B:
  146. memcpy(iris_name, "WCN3660B", sizeof("WCN3660B"));
  147. break;
  148. case WCN3620:
  149. memcpy(iris_name, "WCN3620", sizeof("WCN3620"));
  150. break;
  151. case WCN3620A:
  152. memcpy(iris_name, "WCN3620A", sizeof("WCN3620A"));
  153. break;
  154. case WCN3610:
  155. memcpy(iris_name, "WCN3610", sizeof("WCN3610"));
  156. break;
  157. case WCN3610V1:
  158. memcpy(iris_name, "WCN3610V1", sizeof("WCN3610V1"));
  159. break;
  160. default:
  161. return 1;
  162. }
  163. return 0;
  164. }
  165. EXPORT_SYMBOL(wcnss_get_iris_name);
  166. int validate_iris_chip_id(u32 reg)
  167. {
  168. int iris_id;
  169. iris_id = reg >> 16;
  170. switch (iris_id) {
  171. case WCN3660:
  172. case WCN3660A:
  173. case WCN3660B:
  174. case WCN3620:
  175. case WCN3620A:
  176. case WCN3610:
  177. case WCN3610V1:
  178. return 0;
  179. default:
  180. return 1;
  181. }
  182. }
  183. void wcnss_iris_reset(u32 reg, void __iomem *pmu_conf_reg)
  184. {
  185. /* Reset IRIS */
  186. reg |= WCNSS_PMU_CFG_IRIS_RESET;
  187. writel_relaxed(reg, pmu_conf_reg);
  188. /* Wait for PMU_CFG.iris_reg_reset_sts */
  189. while (readl_relaxed(pmu_conf_reg) &
  190. WCNSS_PMU_CFG_IRIS_RESET_STS)
  191. cpu_relax();
  192. /* Reset iris reset bit */
  193. reg &= ~WCNSS_PMU_CFG_IRIS_RESET;
  194. writel_relaxed(reg, pmu_conf_reg);
  195. }
  196. static int configure_iris_xo(struct device *dev, bool use_48mhz_xo, int on,
  197. int *iris_xo_set)
  198. {
  199. u32 reg = 0, i = 0;
  200. u32 iris_reg = WCNSS_INVALID_IRIS_REG;
  201. int rc = 0;
  202. int size = 0;
  203. int pmu_offset = 0;
  204. int spare_offset = 0;
  205. unsigned long wcnss_phys_addr;
  206. void __iomem *pmu_conf_reg;
  207. void __iomem *spare_reg;
  208. void __iomem *iris_read_reg;
  209. struct clk *clk;
  210. struct clk *clk_rf = NULL;
  211. struct wcnss_wlan_config *cfg = NULL;
  212. cfg = wcnss_get_wlan_config();
  213. if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
  214. wcnss_phys_addr = MSM_PRONTO_PHYS;
  215. pmu_offset = PRONTO_PMU_OFFSET;
  216. spare_offset = PRONTO_SPARE_OFFSET;
  217. size = 0x3000;
  218. clk = clk_get(dev, "xo");
  219. if (IS_ERR(clk)) {
  220. pr_err("Couldn't get xo clock\n");
  221. return PTR_ERR(clk);
  222. }
  223. } else {
  224. wcnss_phys_addr = MSM_RIVA_PHYS;
  225. pmu_offset = RIVA_PMU_OFFSET;
  226. spare_offset = RIVA_SPARE_OFFSET;
  227. size = SZ_256;
  228. clk = clk_get(dev, "cxo");
  229. if (IS_ERR(clk)) {
  230. pr_err("Couldn't get cxo clock\n");
  231. return PTR_ERR(clk);
  232. }
  233. }
  234. if (on) {
  235. msm_wcnss_base = ioremap(wcnss_phys_addr, size);
  236. if (!msm_wcnss_base) {
  237. pr_err("ioremap wcnss physical failed\n");
  238. goto fail;
  239. }
  240. /* Enable IRIS XO */
  241. rc = clk_prepare_enable(clk);
  242. if (rc) {
  243. pr_err("clk enable failed\n");
  244. goto fail;
  245. }
  246. /* NV bit is set to indicate that platform driver is capable
  247. * of doing NV download.
  248. */
  249. pr_debug("wcnss: Indicate NV bin download\n");
  250. spare_reg = msm_wcnss_base + spare_offset;
  251. reg = readl_relaxed(spare_reg);
  252. reg |= NVBIN_DLND_BIT;
  253. writel_relaxed(reg, spare_reg);
  254. pmu_conf_reg = msm_wcnss_base + pmu_offset;
  255. writel_relaxed(0, pmu_conf_reg);
  256. reg = readl_relaxed(pmu_conf_reg);
  257. reg |= WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP |
  258. WCNSS_PMU_CFG_IRIS_XO_EN;
  259. writel_relaxed(reg, pmu_conf_reg);
  260. if (wcnss_xo_auto_detect_enabled()) {
  261. iris_read_reg = msm_wcnss_base +
  262. PRONTO_IRIS_REG_READ_OFFSET;
  263. iris_reg = readl_relaxed(iris_read_reg);
  264. }
  265. wcnss_iris_reset(reg, pmu_conf_reg);
  266. if (iris_reg != WCNSS_INVALID_IRIS_REG) {
  267. iris_reg &= 0xffff;
  268. iris_reg |= PRONTO_IRIS_REG_CHIP_ID;
  269. writel_relaxed(iris_reg, iris_read_reg);
  270. do {
  271. /* Iris read */
  272. reg = readl_relaxed(pmu_conf_reg);
  273. reg |= WCNSS_PMU_CFG_IRIS_XO_READ;
  274. writel_relaxed(reg, pmu_conf_reg);
  275. /* Wait for PMU_CFG.iris_reg_read_sts */
  276. while (readl_relaxed(pmu_conf_reg) &
  277. WCNSS_PMU_CFG_IRIS_XO_READ_STS)
  278. cpu_relax();
  279. iris_reg = readl_relaxed(iris_read_reg);
  280. pr_info("wcnss: IRIS Reg: %08x\n", iris_reg);
  281. if (validate_iris_chip_id(iris_reg) && i >= 4) {
  282. pr_info("wcnss: IRIS Card absent/invalid\n");
  283. auto_detect = WCNSS_XO_INVALID;
  284. /* Reset iris read bit */
  285. reg &= ~WCNSS_PMU_CFG_IRIS_XO_READ;
  286. /* Clear XO_MODE[b2:b1] bits.
  287. * Clear implies 19.2 MHz TCXO
  288. */
  289. reg &= ~(WCNSS_PMU_CFG_IRIS_XO_MODE);
  290. goto xo_configure;
  291. } else if (!validate_iris_chip_id(iris_reg)) {
  292. pr_debug("wcnss: IRIS Card is present\n");
  293. break;
  294. }
  295. reg &= ~WCNSS_PMU_CFG_IRIS_XO_READ;
  296. writel_relaxed(reg, pmu_conf_reg);
  297. wcnss_iris_reset(reg, pmu_conf_reg);
  298. } while (i++ < 5);
  299. auto_detect = xo_auto_detect(iris_reg);
  300. /* Reset iris read bit */
  301. reg &= ~WCNSS_PMU_CFG_IRIS_XO_READ;
  302. } else if (wcnss_xo_auto_detect_enabled())
  303. /* Default to 48 MHZ */
  304. auto_detect = WCNSS_XO_48MHZ;
  305. else
  306. auto_detect = WCNSS_XO_INVALID;
  307. if (cfg != NULL)
  308. cfg->iris_id = iris_reg;
  309. /* Clear XO_MODE[b2:b1] bits. Clear implies 19.2 MHz TCXO */
  310. reg &= ~(WCNSS_PMU_CFG_IRIS_XO_MODE);
  311. if ((use_48mhz_xo && auto_detect == WCNSS_XO_INVALID)
  312. || auto_detect == WCNSS_XO_48MHZ) {
  313. reg |= WCNSS_PMU_CFG_IRIS_XO_MODE_48;
  314. if (iris_xo_set)
  315. *iris_xo_set = WCNSS_XO_48MHZ;
  316. }
  317. xo_configure:
  318. writel_relaxed(reg, pmu_conf_reg);
  319. wcnss_iris_reset(reg, pmu_conf_reg);
  320. /* Start IRIS XO configuration */
  321. reg |= WCNSS_PMU_CFG_IRIS_XO_CFG;
  322. writel_relaxed(reg, pmu_conf_reg);
  323. /* Wait for XO configuration to finish */
  324. while (readl_relaxed(pmu_conf_reg) &
  325. WCNSS_PMU_CFG_IRIS_XO_CFG_STS)
  326. cpu_relax();
  327. /* Stop IRIS XO configuration */
  328. reg &= ~(WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP |
  329. WCNSS_PMU_CFG_IRIS_XO_CFG);
  330. writel_relaxed(reg, pmu_conf_reg);
  331. clk_disable_unprepare(clk);
  332. if ((!use_48mhz_xo && auto_detect == WCNSS_XO_INVALID)
  333. || auto_detect == WCNSS_XO_19MHZ) {
  334. clk_rf = clk_get(dev, "rf_clk");
  335. if (IS_ERR(clk_rf)) {
  336. pr_err("Couldn't get rf_clk\n");
  337. goto fail;
  338. }
  339. rc = clk_prepare_enable(clk_rf);
  340. if (rc) {
  341. pr_err("clk_rf enable failed\n");
  342. goto fail;
  343. }
  344. if (iris_xo_set)
  345. *iris_xo_set = WCNSS_XO_19MHZ;
  346. }
  347. } else if ((!use_48mhz_xo && auto_detect == WCNSS_XO_INVALID)
  348. || auto_detect == WCNSS_XO_19MHZ) {
  349. clk_rf = clk_get(dev, "rf_clk");
  350. if (IS_ERR(clk_rf)) {
  351. pr_err("Couldn't get rf_clk\n");
  352. goto fail;
  353. }
  354. clk_disable_unprepare(clk_rf);
  355. }
  356. /* Add some delay for XO to settle */
  357. msleep(20);
  358. fail:
  359. clk_put(clk);
  360. if (clk_rf != NULL)
  361. clk_put(clk_rf);
  362. return rc;
  363. }
  364. /* Helper routine to turn off all WCNSS & IRIS vregs */
  365. static void wcnss_vregs_off(struct vregs_info regulators[], uint size)
  366. {
  367. int i, rc = 0;
  368. /* Regulators need to be turned off in the reverse order */
  369. for (i = (size-1); i >= 0; i--) {
  370. if (regulators[i].state == VREG_NULL_CONFIG)
  371. continue;
  372. /* Remove PWM mode */
  373. if (regulators[i].state & VREG_OPTIMUM_MODE_MASK) {
  374. rc = regulator_set_optimum_mode(
  375. regulators[i].regulator, 0);
  376. if (rc < 0)
  377. pr_err("regulator_set_optimum_mode(%s) failed (%d)\n",
  378. regulators[i].name, rc);
  379. }
  380. /* Set voltage to lowest level */
  381. if (regulators[i].state & VREG_SET_VOLTAGE_MASK) {
  382. rc = regulator_set_voltage(regulators[i].regulator,
  383. regulators[i].low_power_min,
  384. regulators[i].max_voltage);
  385. if (rc)
  386. pr_err("regulator_set_voltage(%s) failed (%d)\n",
  387. regulators[i].name, rc);
  388. }
  389. /* Disable regulator */
  390. if (regulators[i].state & VREG_ENABLE_MASK) {
  391. rc = regulator_disable(regulators[i].regulator);
  392. if (rc < 0)
  393. pr_err("vreg %s disable failed (%d)\n",
  394. regulators[i].name, rc);
  395. }
  396. /* Free the regulator source */
  397. if (regulators[i].state & VREG_GET_REGULATOR_MASK)
  398. regulator_put(regulators[i].regulator);
  399. regulators[i].state = VREG_NULL_CONFIG;
  400. }
  401. }
  402. /* Common helper routine to turn on all WCNSS & IRIS vregs */
  403. static int wcnss_vregs_on(struct device *dev,
  404. struct vregs_info regulators[], uint size)
  405. {
  406. int i, rc = 0, reg_cnt;
  407. for (i = 0; i < size; i++) {
  408. /* Get regulator source */
  409. regulators[i].regulator =
  410. regulator_get(dev, regulators[i].name);
  411. if (IS_ERR(regulators[i].regulator)) {
  412. rc = PTR_ERR(regulators[i].regulator);
  413. pr_err("regulator get of %s failed (%d)\n",
  414. regulators[i].name, rc);
  415. goto fail;
  416. }
  417. regulators[i].state |= VREG_GET_REGULATOR_MASK;
  418. reg_cnt = regulator_count_voltages(regulators[i].regulator);
  419. /* Set voltage to nominal. Exclude swtiches e.g. LVS */
  420. if ((regulators[i].nominal_min || regulators[i].max_voltage)
  421. && (reg_cnt > 0)) {
  422. rc = regulator_set_voltage(regulators[i].regulator,
  423. regulators[i].nominal_min,
  424. regulators[i].max_voltage);
  425. if (rc) {
  426. pr_err("regulator_set_voltage(%s) failed (%d)\n",
  427. regulators[i].name, rc);
  428. goto fail;
  429. }
  430. regulators[i].state |= VREG_SET_VOLTAGE_MASK;
  431. }
  432. /* Vote for PWM/PFM mode if needed */
  433. if (regulators[i].uA_load && (reg_cnt > 0)) {
  434. rc = regulator_set_optimum_mode(regulators[i].regulator,
  435. regulators[i].uA_load);
  436. if (rc < 0) {
  437. pr_err("regulator_set_optimum_mode(%s) failed (%d)\n",
  438. regulators[i].name, rc);
  439. goto fail;
  440. }
  441. regulators[i].state |= VREG_OPTIMUM_MODE_MASK;
  442. }
  443. /* Enable the regulator */
  444. rc = regulator_enable(regulators[i].regulator);
  445. if (rc) {
  446. pr_err("vreg %s enable failed (%d)\n",
  447. regulators[i].name, rc);
  448. goto fail;
  449. }
  450. regulators[i].state |= VREG_ENABLE_MASK;
  451. }
  452. return rc;
  453. fail:
  454. wcnss_vregs_off(regulators, size);
  455. return rc;
  456. }
  457. static void wcnss_iris_vregs_off(enum wcnss_hw_type hw_type)
  458. {
  459. switch (hw_type) {
  460. case WCNSS_RIVA_HW:
  461. wcnss_vregs_off(iris_vregs_riva, ARRAY_SIZE(iris_vregs_riva));
  462. break;
  463. case WCNSS_PRONTO_HW:
  464. wcnss_vregs_off(iris_vregs_pronto,
  465. ARRAY_SIZE(iris_vregs_pronto));
  466. break;
  467. default:
  468. pr_err("%s invalid hardware %d\n", __func__, hw_type);
  469. }
  470. }
  471. static int wcnss_iris_vregs_on(struct device *dev, enum wcnss_hw_type hw_type)
  472. {
  473. int ret = -1;
  474. switch (hw_type) {
  475. case WCNSS_RIVA_HW:
  476. ret = wcnss_vregs_on(dev, iris_vregs_riva,
  477. ARRAY_SIZE(iris_vregs_riva));
  478. break;
  479. case WCNSS_PRONTO_HW:
  480. ret = wcnss_vregs_on(dev, iris_vregs_pronto,
  481. ARRAY_SIZE(iris_vregs_pronto));
  482. break;
  483. default:
  484. pr_err("%s invalid hardware %d\n", __func__, hw_type);
  485. }
  486. return ret;
  487. }
  488. static void wcnss_core_vregs_off(enum wcnss_hw_type hw_type)
  489. {
  490. switch (hw_type) {
  491. case WCNSS_RIVA_HW:
  492. wcnss_vregs_off(riva_vregs, ARRAY_SIZE(riva_vregs));
  493. break;
  494. case WCNSS_PRONTO_HW:
  495. wcnss_vregs_off(pronto_vregs, ARRAY_SIZE(pronto_vregs));
  496. break;
  497. default:
  498. pr_err("%s invalid hardware %d\n", __func__, hw_type);
  499. }
  500. }
  501. static int wcnss_core_vregs_on(struct device *dev, enum wcnss_hw_type hw_type)
  502. {
  503. int ret = -1;
  504. switch (hw_type) {
  505. case WCNSS_RIVA_HW:
  506. ret = wcnss_vregs_on(dev, riva_vregs, ARRAY_SIZE(riva_vregs));
  507. break;
  508. case WCNSS_PRONTO_HW:
  509. ret = wcnss_vregs_on(dev, pronto_vregs,
  510. ARRAY_SIZE(pronto_vregs));
  511. break;
  512. default:
  513. pr_err("%s invalid hardware %d\n", __func__, hw_type);
  514. }
  515. return ret;
  516. }
  517. int wcnss_wlan_power(struct device *dev,
  518. struct wcnss_wlan_config *cfg,
  519. enum wcnss_opcode on, int *iris_xo_set)
  520. {
  521. int rc = 0;
  522. enum wcnss_hw_type hw_type = wcnss_hardware_type();
  523. if (on) {
  524. down(&wcnss_power_on_lock);
  525. /* RIVA regulator settings */
  526. rc = wcnss_core_vregs_on(dev, hw_type);
  527. if (rc)
  528. goto fail_wcnss_on;
  529. /* IRIS regulator settings */
  530. rc = wcnss_iris_vregs_on(dev, hw_type);
  531. if (rc)
  532. goto fail_iris_on;
  533. /* Configure IRIS XO */
  534. rc = configure_iris_xo(dev, cfg->use_48mhz_xo,
  535. WCNSS_WLAN_SWITCH_ON, iris_xo_set);
  536. if (rc)
  537. goto fail_iris_xo;
  538. up(&wcnss_power_on_lock);
  539. } else {
  540. configure_iris_xo(dev, cfg->use_48mhz_xo,
  541. WCNSS_WLAN_SWITCH_OFF, NULL);
  542. wcnss_iris_vregs_off(hw_type);
  543. wcnss_core_vregs_off(hw_type);
  544. }
  545. return rc;
  546. fail_iris_xo:
  547. wcnss_iris_vregs_off(hw_type);
  548. fail_iris_on:
  549. wcnss_core_vregs_off(hw_type);
  550. fail_wcnss_on:
  551. up(&wcnss_power_on_lock);
  552. return rc;
  553. }
  554. EXPORT_SYMBOL(wcnss_wlan_power);
  555. /*
  556. * During SSR WCNSS should not be 'powered on' until all the host drivers
  557. * finish their shutdown routines. Host drivers use below APIs to
  558. * synchronize power-on. WCNSS will not be 'powered on' until all the
  559. * requests(to lock power-on) are freed.
  560. */
  561. int wcnss_req_power_on_lock(char *driver_name)
  562. {
  563. struct host_driver *node;
  564. if (!driver_name)
  565. goto err;
  566. node = kmalloc(sizeof(struct host_driver), GFP_KERNEL);
  567. if (!node)
  568. goto err;
  569. strlcpy(node->name, driver_name, sizeof(node->name));
  570. mutex_lock(&list_lock);
  571. /* Lock when the first request is added */
  572. if (list_empty(&power_on_lock_list))
  573. down(&wcnss_power_on_lock);
  574. list_add(&node->list, &power_on_lock_list);
  575. mutex_unlock(&list_lock);
  576. return 0;
  577. err:
  578. return -EINVAL;
  579. }
  580. EXPORT_SYMBOL(wcnss_req_power_on_lock);
  581. int wcnss_free_power_on_lock(char *driver_name)
  582. {
  583. int ret = -1;
  584. struct host_driver *node;
  585. mutex_lock(&list_lock);
  586. list_for_each_entry(node, &power_on_lock_list, list) {
  587. if (!strncmp(node->name, driver_name, sizeof(node->name))) {
  588. list_del(&node->list);
  589. kfree(node);
  590. ret = 0;
  591. break;
  592. }
  593. }
  594. /* unlock when the last host driver frees the lock */
  595. if (list_empty(&power_on_lock_list))
  596. up(&wcnss_power_on_lock);
  597. mutex_unlock(&list_lock);
  598. return ret;
  599. }
  600. EXPORT_SYMBOL(wcnss_free_power_on_lock);