xref: /wlan-dirver/platform/icnss2/power.c (revision 5a888e90a2d595c929907f9f11821ed298ecde6c)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
4  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6 #include <linux/clk.h>
7 #include <linux/delay.h>
8 #include <linux/of.h>
9 #include <linux/pinctrl/consumer.h>
10 #include <linux/regulator/consumer.h>
11 #include <soc/qcom/cmd-db.h>
12 #include "main.h"
13 #include "qmi.h"
14 #include "debug.h"
15 #include "power.h"
16 #if IS_ENABLED(CONFIG_MSM_QMP)
17 #include <linux/soc/qcom/qcom_aoss.h>
18 #endif
19 
20 static struct icnss_vreg_cfg icnss_wcn6750_vreg_list[] = {
21 	{"vdd-cx-mx", 824000, 952000, 0, 0, 0, false, true},
22 	{"vdd-1.8-xo", 1872000, 1872000, 0, 0, 0, false, true},
23 	{"vdd-1.3-rfa", 1256000, 1352000, 0, 0, 0, false, true},
24 };
25 
26 static struct icnss_vreg_cfg icnss_adrestea_vreg_list[] = {
27 	{"vdd-cx-mx", 752000, 752000, 0, 0, 0, false, true},
28 	{"vdd-1.8-xo", 1800000, 1800000, 0, 0, 0, false, true},
29 	{"vdd-1.3-rfa", 1304000, 1304000, 0, 0, 0, false, true},
30 	{"vdd-3.3-ch1", 3312000, 3312000, 0, 0, 0, false, true},
31 	{"vdd-3.3-ch0", 3312000, 3312000, 0, 0, 0, false, true},
32 };
33 
34 static struct icnss_battery_level icnss_battery_level[] = {
35 	{70, 3300000},
36 	{60, 3200000},
37 	{50, 3100000},
38 	{25, 3000000},
39 	{0, 2850000},
40 };
41 
42 static struct icnss_vreg_cfg icnss_wcn6450_vreg_list[] = {
43 	{"vdd-cx-mx", 824000, 952000, 0, 0, 0, false, true},
44 	{"vdd-1.8-xo", 1872000, 1872000, 0, 0, 0, false, true},
45 	{"vdd-1.3-rfa", 1256000, 1352000, 0, 0, 0, false, true},
46 	{"vdd-aon", 1256000, 1352000, 0, 0, 0, false, true},
47 };
48 
49 static struct icnss_clk_cfg icnss_clk_list[] = {
50 	{"rf_clk", 0, 0},
51 };
52 
53 static struct icnss_clk_cfg icnss_adrestea_clk_list[] = {
54 	{"cxo_ref_clk_pin", 0, 0},
55 };
56 
57 #define ICNSS_VREG_LIST_SIZE		ARRAY_SIZE(icnss_wcn6750_vreg_list)
58 #define ICNSS_VREG_ADRESTEA_LIST_SIZE	ARRAY_SIZE(icnss_adrestea_vreg_list)
59 #define ICNSS_VREG_EVROS_LIST_SIZE	ARRAY_SIZE(icnss_wcn6450_vreg_list)
60 #define ICNSS_CLK_LIST_SIZE		ARRAY_SIZE(icnss_clk_list)
61 #define ICNSS_CLK_ADRESTEA_LIST_SIZE	ARRAY_SIZE(icnss_adrestea_clk_list)
62 
63 #define ICNSS_CHAIN1_REGULATOR                          "vdd-3.3-ch1"
64 #define MAX_PROP_SIZE					32
65 
66 #define BT_CXMX_VOLTAGE_MV		950
67 #define ICNSS_MBOX_MSG_MAX_LEN 64
68 #define ICNSS_MBOX_TIMEOUT_MS 1000
69 
70 #define ICNSS_BATTERY_LEVEL_COUNT	ARRAY_SIZE(icnss_battery_level)
71 #define ICNSS_MAX_BATTERY_LEVEL		100
72 
73 /**
74  * enum icnss_vreg_param: Voltage regulator TCS param
75  * @ICNSS_VREG_VOLTAGE: Provides voltage level to be configured in TCS
76  * @ICNSS_VREG_MODE: Regulator mode
77  * @ICNSS_VREG_ENABLE: Set Voltage regulator enable config in TCS
78  */
79 enum icnss_vreg_param {
80 	ICNSS_VREG_VOLTAGE,
81 	ICNSS_VREG_MODE,
82 	ICNSS_VREG_ENABLE,
83 };
84 
85 /**
86  * enum icnss_tcs_seq: TCS sequence ID for trigger
87  * ICNSS_TCS_UP_SEQ: TCS Sequence based on up trigger / Wake TCS
88  * ICNSS_TCS_DOWN_SEQ: TCS Sequence based on down trigger / Sleep TCS
89  * ICNSS_TCS_ALL_SEQ: Update for both up and down triggers
90  */
91 enum icnss_tcs_seq {
92 	ICNSS_TCS_UP_SEQ,
93 	ICNSS_TCS_DOWN_SEQ,
94 	ICNSS_TCS_ALL_SEQ,
95 };
96 
97 static int icnss_get_vreg_single(struct icnss_priv *priv,
98 				 struct icnss_vreg_info *vreg)
99 {
100 	int ret = 0;
101 	struct device *dev = NULL;
102 	struct regulator *reg = NULL;
103 	const __be32 *prop = NULL;
104 	char prop_name[MAX_PROP_SIZE] = {0};
105 	int len = 0;
106 	int i;
107 
108 	dev = &priv->pdev->dev;
109 
110 	reg = devm_regulator_get_optional(dev, vreg->cfg.name);
111 	if (IS_ERR(reg)) {
112 		ret = PTR_ERR(reg);
113 		if (ret == -ENODEV) {
114 			return ret;
115 		} else if (ret == -EPROBE_DEFER) {
116 			icnss_pr_info("EPROBE_DEFER for regulator: %s\n",
117 				      vreg->cfg.name);
118 			goto out;
119 		} else if (priv->device_id == ADRASTEA_DEVICE_ID) {
120 			if (vreg->cfg.required) {
121 				icnss_pr_err("Regulator %s doesn't exist: %d\n",
122 					     vreg->cfg.name, ret);
123 			goto out;
124 			} else {
125 				icnss_pr_dbg("Optional regulator %s doesn't exist: %d\n",
126 					     vreg->cfg.name, ret);
127 				goto done;
128 			}
129 		} else {
130 			icnss_pr_err("Failed to get regulator %s, err = %d\n",
131 				     vreg->cfg.name, ret);
132 			goto out;
133 		}
134 	}
135 
136 	vreg->reg = reg;
137 
138 	snprintf(prop_name, MAX_PROP_SIZE, "qcom,%s-config",
139 		 vreg->cfg.name);
140 
141 	prop = of_get_property(dev->of_node, prop_name, &len);
142 
143 	icnss_pr_dbg("Got regulator config, prop: %s, len: %d\n",
144 		     prop_name, len);
145 
146 	if (!prop || len < (2 * sizeof(__be32))) {
147 		icnss_pr_dbg("Property %s %s, use default\n", prop_name,
148 			     prop ? "invalid format" : "doesn't exist");
149 		goto done;
150 	}
151 
152 	for (i = 0; (i * sizeof(__be32)) < len; i++) {
153 		switch (i) {
154 		case 0:
155 			vreg->cfg.min_uv = be32_to_cpup(&prop[0]);
156 			break;
157 		case 1:
158 			vreg->cfg.max_uv = be32_to_cpup(&prop[1]);
159 			break;
160 		case 2:
161 			vreg->cfg.load_ua = be32_to_cpup(&prop[2]);
162 			break;
163 		case 3:
164 			vreg->cfg.delay_us = be32_to_cpup(&prop[3]);
165 			break;
166 		case 4:
167 			if (priv->device_id == WCN6750_DEVICE_ID)
168 				vreg->cfg.need_unvote = be32_to_cpup(&prop[4]);
169 			else
170 				vreg->cfg.need_unvote = 0;
171 			break;
172 		default:
173 			icnss_pr_dbg("Property %s, ignoring value at %d\n",
174 				     prop_name, i);
175 			break;
176 		}
177 	}
178 
179 done:
180 	icnss_pr_dbg("Got regulator: %s, min_uv: %u, max_uv: %u, load_ua: %u, delay_us: %u, need_unvote: %u\n",
181 		     vreg->cfg.name, vreg->cfg.min_uv,
182 		     vreg->cfg.max_uv, vreg->cfg.load_ua,
183 		     vreg->cfg.delay_us, vreg->cfg.need_unvote);
184 
185 	return 0;
186 
187 out:
188 	return ret;
189 }
190 
191 static int icnss_vreg_on_single(struct icnss_vreg_info *vreg)
192 {
193 	int ret = 0;
194 
195 	if (vreg->enabled) {
196 		icnss_pr_dbg("Regulator %s is already enabled\n",
197 			     vreg->cfg.name);
198 		return 0;
199 	}
200 
201 	icnss_pr_dbg("Regulator %s is being enabled\n", vreg->cfg.name);
202 
203 	if (vreg->cfg.min_uv != 0 && vreg->cfg.max_uv != 0) {
204 		ret = regulator_set_voltage(vreg->reg,
205 					    vreg->cfg.min_uv,
206 					    vreg->cfg.max_uv);
207 
208 		if (ret) {
209 			icnss_pr_err("Failed to set voltage for regulator %s, min_uv: %u, max_uv: %u, err = %d\n",
210 				     vreg->cfg.name, vreg->cfg.min_uv,
211 				     vreg->cfg.max_uv, ret);
212 			goto out;
213 		}
214 	}
215 
216 	if (vreg->cfg.load_ua) {
217 		ret = regulator_set_load(vreg->reg,
218 					 vreg->cfg.load_ua);
219 
220 		if (ret < 0) {
221 			icnss_pr_err("Failed to set load for regulator %s, load: %u, err = %d\n",
222 				     vreg->cfg.name, vreg->cfg.load_ua,
223 				     ret);
224 			goto out;
225 		}
226 	}
227 
228 	if (vreg->cfg.delay_us)
229 		udelay(vreg->cfg.delay_us);
230 
231 	ret = regulator_enable(vreg->reg);
232 	if (ret) {
233 		icnss_pr_err("Failed to enable regulator %s, err = %d\n",
234 			     vreg->cfg.name, ret);
235 		goto out;
236 	}
237 
238 	vreg->enabled = true;
239 
240 out:
241 	return ret;
242 }
243 
244 static int icnss_vreg_unvote_single(struct icnss_vreg_info *vreg)
245 {
246 	int ret = 0;
247 
248 	if (!vreg->enabled) {
249 		icnss_pr_dbg("Regulator %s is already disabled\n",
250 			     vreg->cfg.name);
251 		return 0;
252 	}
253 
254 	icnss_pr_dbg("Removing vote for Regulator %s\n", vreg->cfg.name);
255 
256 	if (vreg->cfg.load_ua) {
257 		ret = regulator_set_load(vreg->reg, 0);
258 		if (ret < 0)
259 			icnss_pr_err("Failed to set load for regulator %s, err = %d\n",
260 				     vreg->cfg.name, ret);
261 	}
262 
263 	if (vreg->cfg.min_uv != 0 && vreg->cfg.max_uv != 0) {
264 		ret = regulator_set_voltage(vreg->reg, 0,
265 					    vreg->cfg.max_uv);
266 		if (ret)
267 			icnss_pr_err("Failed to set voltage for regulator %s, err = %d\n",
268 				     vreg->cfg.name, ret);
269 	}
270 
271 	return ret;
272 }
273 
274 static int icnss_vreg_off_single(struct icnss_vreg_info *vreg)
275 {
276 	int ret = 0;
277 
278 	if (!vreg->enabled) {
279 		icnss_pr_dbg("Regulator %s is already disabled\n",
280 			     vreg->cfg.name);
281 		return 0;
282 	}
283 
284 	icnss_pr_dbg("Regulator %s is being disabled\n",
285 		     vreg->cfg.name);
286 
287 	ret = regulator_disable(vreg->reg);
288 	if (ret)
289 		icnss_pr_err("Failed to disable regulator %s, err = %d\n",
290 			     vreg->cfg.name, ret);
291 
292 	if (vreg->cfg.load_ua) {
293 		ret = regulator_set_load(vreg->reg, 0);
294 		if (ret < 0)
295 			icnss_pr_err("Failed to set load for regulator %s, err = %d\n",
296 				     vreg->cfg.name, ret);
297 	}
298 
299 	if (vreg->cfg.min_uv != 0 && vreg->cfg.max_uv != 0) {
300 		ret = regulator_set_voltage(vreg->reg, 0,
301 					    vreg->cfg.max_uv);
302 		if (ret)
303 			icnss_pr_err("Failed to set voltage for regulator %s, err = %d\n",
304 				     vreg->cfg.name, ret);
305 	}
306 	vreg->enabled = false;
307 
308 	return ret;
309 }
310 
311 static struct icnss_vreg_cfg *get_vreg_list(u32 *vreg_list_size,
312 					    unsigned long device_id)
313 {
314 	switch (device_id) {
315 	case WCN6750_DEVICE_ID:
316 		*vreg_list_size = ICNSS_VREG_LIST_SIZE;
317 		return icnss_wcn6750_vreg_list;
318 
319 	case ADRASTEA_DEVICE_ID:
320 		*vreg_list_size = ICNSS_VREG_ADRESTEA_LIST_SIZE;
321 		return icnss_adrestea_vreg_list;
322 
323 	case WCN6450_DEVICE_ID:
324 		*vreg_list_size = ICNSS_VREG_EVROS_LIST_SIZE;
325 		return icnss_wcn6450_vreg_list;
326 
327 	default:
328 		icnss_pr_err("Unsupported device_id 0x%x\n", device_id);
329 		*vreg_list_size = 0;
330 		return NULL;
331 	}
332 }
333 
334 int icnss_get_vreg(struct icnss_priv *priv)
335 {
336 	int ret = 0;
337 	int i;
338 	struct icnss_vreg_info *vreg;
339 	struct icnss_vreg_cfg *vreg_cfg = NULL;
340 	struct list_head *vreg_list = &priv->vreg_list;
341 	struct device *dev = &priv->pdev->dev;
342 	u32 vreg_list_size = 0;
343 
344 	vreg_cfg = get_vreg_list(&vreg_list_size, priv->device_id);
345 	if (!vreg_cfg)
346 		return -EINVAL;
347 
348 	for (i = 0; i < vreg_list_size; i++) {
349 		vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
350 		if (!vreg)
351 			return -ENOMEM;
352 
353 		memcpy(&vreg->cfg, &vreg_cfg[i], sizeof(vreg->cfg));
354 		ret = icnss_get_vreg_single(priv, vreg);
355 		if (ret != 0) {
356 			if (ret == -ENODEV)
357 				continue;
358 			else
359 				return ret;
360 		}
361 		list_add_tail(&vreg->list, vreg_list);
362 	}
363 
364 	return 0;
365 }
366 
367 void icnss_put_vreg(struct icnss_priv *priv)
368 {
369 	struct list_head *vreg_list = &priv->vreg_list;
370 	struct icnss_vreg_info *vreg = NULL;
371 
372 	while (!list_empty(vreg_list)) {
373 		vreg = list_first_entry(vreg_list,
374 					struct icnss_vreg_info, list);
375 		list_del(&vreg->list);
376 	}
377 }
378 
379 static int icnss_vreg_on(struct icnss_priv *priv)
380 {
381 	struct list_head *vreg_list = &priv->vreg_list;
382 	struct icnss_vreg_info *vreg = NULL;
383 	int ret = 0;
384 
385 	list_for_each_entry(vreg, vreg_list, list) {
386 		if (IS_ERR_OR_NULL(vreg->reg) || !vreg->cfg.is_supported)
387 			continue;
388 		if (!priv->chain_reg_info_updated &&
389 		    !strcmp(ICNSS_CHAIN1_REGULATOR, vreg->cfg.name)) {
390 			priv->chain_reg_info_updated = true;
391 			if (!priv->is_chain1_supported) {
392 				vreg->cfg.is_supported = false;
393 				continue;
394 			}
395 		}
396 
397 		ret = icnss_vreg_on_single(vreg);
398 		if (ret)
399 			break;
400 	}
401 
402 	if (!ret)
403 		return 0;
404 
405 	list_for_each_entry_continue_reverse(vreg, vreg_list, list) {
406 		if (IS_ERR_OR_NULL(vreg->reg) || !vreg->enabled)
407 			continue;
408 
409 		icnss_vreg_off_single(vreg);
410 	}
411 
412 	return ret;
413 }
414 
415 static int icnss_vreg_off(struct icnss_priv *priv)
416 {
417 	struct list_head *vreg_list = &priv->vreg_list;
418 	struct icnss_vreg_info *vreg = NULL;
419 
420 	list_for_each_entry_reverse(vreg, vreg_list, list) {
421 		if (IS_ERR_OR_NULL(vreg->reg))
422 			continue;
423 
424 		icnss_vreg_off_single(vreg);
425 	}
426 
427 	return 0;
428 }
429 
430 int icnss_vreg_unvote(struct icnss_priv *priv)
431 {
432 	struct list_head *vreg_list = &priv->vreg_list;
433 	struct icnss_vreg_info *vreg = NULL;
434 
435 	list_for_each_entry_reverse(vreg, vreg_list, list) {
436 		if (IS_ERR_OR_NULL(vreg->reg))
437 			continue;
438 
439 		if (vreg->cfg.need_unvote)
440 			icnss_vreg_unvote_single(vreg);
441 	}
442 
443 	return 0;
444 }
445 
446 int icnss_get_clk_single(struct icnss_priv *priv,
447 			 struct icnss_clk_info *clk_info)
448 {
449 	struct device *dev = &priv->pdev->dev;
450 	struct clk *clk;
451 	int ret;
452 
453 	clk = devm_clk_get(dev, clk_info->cfg.name);
454 	if (IS_ERR(clk)) {
455 		ret = PTR_ERR(clk);
456 		if (clk_info->cfg.required)
457 			icnss_pr_err("Failed to get clock %s, err = %d\n",
458 				     clk_info->cfg.name, ret);
459 		else
460 			icnss_pr_dbg("Failed to get optional clock %s, err = %d\n",
461 				     clk_info->cfg.name, ret);
462 		return ret;
463 	}
464 
465 	clk_info->clk = clk;
466 	icnss_pr_dbg("Got clock: %s, freq: %u\n",
467 		     clk_info->cfg.name, clk_info->cfg.freq);
468 
469 	return 0;
470 }
471 
472 static int icnss_clk_on_single(struct icnss_clk_info *clk_info)
473 {
474 	int ret;
475 
476 	if (clk_info->enabled) {
477 		icnss_pr_dbg("Clock %s is already enabled\n",
478 			     clk_info->cfg.name);
479 		return 0;
480 	}
481 
482 	icnss_pr_dbg("Clock %s is being enabled\n", clk_info->cfg.name);
483 
484 	if (clk_info->cfg.freq) {
485 		ret = clk_set_rate(clk_info->clk, clk_info->cfg.freq);
486 		if (ret) {
487 			icnss_pr_err("Failed to set frequency %u for clock %s, err = %d\n",
488 				     clk_info->cfg.freq, clk_info->cfg.name,
489 				     ret);
490 			return ret;
491 		}
492 	}
493 
494 	ret = clk_prepare_enable(clk_info->clk);
495 	if (ret) {
496 		icnss_pr_err("Failed to enable clock %s, err = %d\n",
497 			     clk_info->cfg.name, ret);
498 		return ret;
499 	}
500 
501 	clk_info->enabled = true;
502 
503 	return 0;
504 }
505 
506 static int icnss_clk_off_single(struct icnss_clk_info *clk_info)
507 {
508 	if (!clk_info->enabled) {
509 		icnss_pr_dbg("Clock %s is already disabled\n",
510 			     clk_info->cfg.name);
511 		return 0;
512 	}
513 
514 	icnss_pr_dbg("Clock %s is being disabled\n", clk_info->cfg.name);
515 
516 	clk_disable_unprepare(clk_info->clk);
517 	clk_info->enabled = false;
518 
519 	return 0;
520 }
521 
522 int icnss_get_clk(struct icnss_priv *priv)
523 {
524 	struct device *dev;
525 	struct list_head *clk_list;
526 	struct icnss_clk_info *clk_info;
527 	struct icnss_clk_cfg *clk_cfg;
528 	int ret, i;
529 	u32 clk_list_size = 0;
530 
531 	if (!priv)
532 		return -ENODEV;
533 
534 	dev = &priv->pdev->dev;
535 	clk_list = &priv->clk_list;
536 
537 	if (priv->device_id == ADRASTEA_DEVICE_ID) {
538 		clk_cfg = icnss_adrestea_clk_list;
539 		clk_list_size = ICNSS_CLK_ADRESTEA_LIST_SIZE;
540 	} else if (priv->device_id == WCN6750_DEVICE_ID ||
541 		   priv->device_id == WCN6450_DEVICE_ID) {
542 		clk_cfg = icnss_clk_list;
543 		clk_list_size = ICNSS_CLK_LIST_SIZE;
544 	}
545 
546 	if (!list_empty(clk_list)) {
547 		icnss_pr_dbg("Clocks have already been updated\n");
548 		return 0;
549 	}
550 
551 	for (i = 0; i < clk_list_size; i++) {
552 		clk_info = devm_kzalloc(dev, sizeof(*clk_info), GFP_KERNEL);
553 		if (!clk_info) {
554 			ret = -ENOMEM;
555 			goto cleanup;
556 		}
557 
558 		memcpy(&clk_info->cfg, &clk_cfg[i],
559 		       sizeof(clk_info->cfg));
560 		ret = icnss_get_clk_single(priv, clk_info);
561 		if (ret != 0) {
562 			if (clk_info->cfg.required)
563 				goto cleanup;
564 			else
565 				continue;
566 		}
567 		list_add_tail(&clk_info->list, clk_list);
568 	}
569 
570 	return 0;
571 
572 cleanup:
573 	while (!list_empty(clk_list)) {
574 		clk_info = list_first_entry(clk_list, struct icnss_clk_info,
575 					    list);
576 		list_del(&clk_info->list);
577 	}
578 
579 	return ret;
580 }
581 
582 void icnss_put_clk(struct icnss_priv *priv)
583 {
584 	struct device *dev;
585 	struct list_head *clk_list;
586 	struct icnss_clk_info *clk_info;
587 
588 	if (!priv)
589 		return;
590 
591 	dev = &priv->pdev->dev;
592 	clk_list = &priv->clk_list;
593 
594 	while (!list_empty(clk_list)) {
595 		clk_info = list_first_entry(clk_list, struct icnss_clk_info,
596 					    list);
597 		list_del(&clk_info->list);
598 	}
599 }
600 
601 static int icnss_clk_on(struct list_head *clk_list)
602 {
603 	struct icnss_clk_info *clk_info;
604 	int ret = 0;
605 
606 	list_for_each_entry(clk_info, clk_list, list) {
607 		if (IS_ERR_OR_NULL(clk_info->clk))
608 			continue;
609 		ret = icnss_clk_on_single(clk_info);
610 		if (ret)
611 			break;
612 	}
613 
614 	if (!ret)
615 		return 0;
616 
617 	list_for_each_entry_continue_reverse(clk_info, clk_list, list) {
618 		if (IS_ERR_OR_NULL(clk_info->clk))
619 			continue;
620 
621 		icnss_clk_off_single(clk_info);
622 	}
623 
624 	return ret;
625 }
626 
627 static int icnss_clk_off(struct list_head *clk_list)
628 {
629 	struct icnss_clk_info *clk_info;
630 
631 	list_for_each_entry_reverse(clk_info, clk_list, list) {
632 		if (IS_ERR_OR_NULL(clk_info->clk))
633 			continue;
634 
635 		icnss_clk_off_single(clk_info);
636 	}
637 
638 	return 0;
639 }
640 
641 int icnss_hw_power_on(struct icnss_priv *priv)
642 {
643 	int ret = 0;
644 
645 	icnss_pr_dbg("HW Power on: state: 0x%lx\n", priv->state);
646 
647 	spin_lock(&priv->on_off_lock);
648 	if (test_bit(ICNSS_POWER_ON, &priv->state)) {
649 		spin_unlock(&priv->on_off_lock);
650 		return ret;
651 	}
652 	set_bit(ICNSS_POWER_ON, &priv->state);
653 	spin_unlock(&priv->on_off_lock);
654 
655 	ret = icnss_vreg_on(priv);
656 	if (ret) {
657 		icnss_pr_err("Failed to turn on vreg, err = %d\n", ret);
658 		goto out;
659 	}
660 
661 	ret = icnss_clk_on(&priv->clk_list);
662 	if (ret)
663 		goto vreg_off;
664 
665 	return ret;
666 
667 vreg_off:
668 	icnss_vreg_off(priv);
669 out:
670 	clear_bit(ICNSS_POWER_ON, &priv->state);
671 	return ret;
672 }
673 
674 int icnss_hw_power_off(struct icnss_priv *priv)
675 {
676 	int ret = 0;
677 
678 	if (test_bit(HW_ALWAYS_ON, &priv->ctrl_params.quirks))
679 		return 0;
680 
681 	if (test_bit(ICNSS_FW_DOWN, &priv->state))
682 		return 0;
683 
684 	icnss_pr_dbg("HW Power off: 0x%lx\n", priv->state);
685 
686 	spin_lock(&priv->on_off_lock);
687 	if (!test_bit(ICNSS_POWER_ON, &priv->state)) {
688 		spin_unlock(&priv->on_off_lock);
689 		return ret;
690 	}
691 	clear_bit(ICNSS_POWER_ON, &priv->state);
692 	spin_unlock(&priv->on_off_lock);
693 
694 	icnss_clk_off(&priv->clk_list);
695 
696 	ret = icnss_vreg_off(priv);
697 
698 	return ret;
699 }
700 
701 int icnss_power_on(struct device *dev)
702 {
703 	struct icnss_priv *priv = dev_get_drvdata(dev);
704 
705 	if (!priv) {
706 		icnss_pr_err("Invalid drvdata: dev %pK, data %pK\n",
707 			     dev, priv);
708 		return -EINVAL;
709 	}
710 
711 	icnss_pr_dbg("Power On: 0x%lx\n", priv->state);
712 
713 	return icnss_hw_power_on(priv);
714 }
715 EXPORT_SYMBOL(icnss_power_on);
716 
717 int icnss_power_off(struct device *dev)
718 {
719 	struct icnss_priv *priv = dev_get_drvdata(dev);
720 
721 	if (!priv) {
722 		icnss_pr_err("Invalid drvdata: dev %pK, data %pK\n",
723 			     dev, priv);
724 		return -EINVAL;
725 	}
726 
727 	icnss_pr_dbg("Power Off: 0x%lx\n", priv->state);
728 
729 	return icnss_hw_power_off(priv);
730 }
731 EXPORT_SYMBOL(icnss_power_off);
732 
733 void icnss_put_resources(struct icnss_priv *priv)
734 {
735 	icnss_put_clk(priv);
736 	icnss_put_vreg(priv);
737 }
738 
739 
740 #if IS_ENABLED(CONFIG_MSM_QMP)
741 /**
742  * icnss_aop_interface_init: Initialize AOP interface: either mbox channel or direct QMP
743  * @priv: Pointer to icnss platform data
744  *
745  * Device tree file should have either mbox or qmp configured, but not both.
746  * Based on device tree configuration setup mbox channel or QMP
747  *
748  * Return: 0 for success, otherwise error code
749 */
750 int icnss_aop_interface_init(struct icnss_priv *priv)
751 {
752 	struct mbox_client *mbox = &priv->mbox_client_data;
753 	struct mbox_chan *chan;
754 	int ret = 0, ol_cpr = 0;
755 
756 	ol_cpr = of_property_read_string(priv->pdev->dev.of_node,
757 					 "qcom,vreg_ol_cpr",
758 					 &priv->cpr_info.vreg_ol_cpr);
759 
760 	if (ol_cpr && !priv->pdc_init_table) {
761 		icnss_pr_dbg("Vreg for OL CPR and pdc_init table not configured\n");
762 		return -EINVAL;
763 	}
764 
765 	mbox->dev = &priv->pdev->dev;
766 	mbox->tx_block = true;
767 	mbox->tx_tout = ICNSS_MBOX_TIMEOUT_MS;
768 	mbox->knows_txdone = false;
769 
770 	priv->mbox_chan = NULL;
771 	priv->qmp = NULL;
772 	priv->use_direct_qmp = false;
773 	/* First try to get mbox channel, if it fails then try qmp_get
774 	 * In device tree file there should be either mboxes or qmp,
775 	 * cannot have both properties at the same time.
776 	 */
777 	chan = mbox_request_channel(mbox, 0);
778 	if (IS_ERR(chan)) {
779 		ret = PTR_ERR(chan);
780 		icnss_pr_dbg("Failed to get mbox channel with err %d\n", ret);
781 		priv->qmp = qmp_get(&priv->pdev->dev);
782 		if (IS_ERR(priv->qmp)) {
783 			icnss_pr_err("Failed to get qmp\n");
784 			return PTR_ERR(priv->qmp);
785 		} else {
786 			priv->use_direct_qmp = true;
787 			icnss_pr_dbg("QMP initialized\n");
788 		}
789 	} else {
790 		priv->mbox_chan = chan;
791 		icnss_pr_dbg("Mbox channel initialized\n");
792 	}
793 	ret = icnss_aop_pdc_reconfig(priv);
794 	if (ret)
795 		icnss_pr_err("Failed to reconfig WLAN PDC, err = %d\n", ret);
796 
797 	return ret;
798 }
799 
800 /**
801  * icnss_aop_interface_deinit: Cleanup AOP interface
802  * @priv: Pointer to icnss platform data
803  *
804  * Cleanup mbox channel or QMP whichever was configured during initialization.
805  *
806  * Return: None
807  */
808 void icnss_aop_interface_deinit(struct icnss_priv *priv)
809 {
810 	if (!IS_ERR_OR_NULL(priv->mbox_chan))
811 		mbox_free_channel(priv->mbox_chan);
812 
813 	if (!IS_ERR_OR_NULL(priv->qmp)) {
814 		qmp_put(priv->qmp);
815 		priv->use_direct_qmp = false;
816 	}
817 }
818 
819 static int icnss_aop_set_vreg_param(struct icnss_priv *priv,
820 				    const char *vreg_name,
821 				    enum icnss_vreg_param param,
822 				    enum icnss_tcs_seq seq, int val)
823 {
824 	struct qmp_pkt pkt;
825 	char mbox_msg[ICNSS_MBOX_MSG_MAX_LEN];
826 	static const char * const vreg_param_str[] = {"v", "m", "e"};
827 	static const char *const tcs_seq_str[] = {"upval", "dwnval", "enable"};
828 	int ret = 0;
829 
830 	if (param > ICNSS_VREG_ENABLE || seq > ICNSS_TCS_ALL_SEQ || !vreg_name)
831 		return -EINVAL;
832 
833 	snprintf(mbox_msg, ICNSS_MBOX_MSG_MAX_LEN,
834 		 "{class: wlan_pdc, res: %s.%s, %s: %d}", vreg_name,
835 		 vreg_param_str[param], tcs_seq_str[seq], val);
836 	if (priv->use_direct_qmp) {
837 		icnss_pr_dbg("Sending AOP QMP msg: %s\n", mbox_msg);
838 		ret = qmp_send(priv->qmp, mbox_msg, ICNSS_MBOX_MSG_MAX_LEN);
839 		if (ret < 0)
840 			icnss_pr_err("Failed to send AOP QMP msg: %s\n", mbox_msg);
841 		else
842 			ret = 0;
843 	} else {
844 		icnss_pr_dbg("Sending AOP Mbox msg: %s\n", mbox_msg);
845 		pkt.size = ICNSS_MBOX_MSG_MAX_LEN;
846 		pkt.data = mbox_msg;
847 
848 		ret = mbox_send_message(priv->mbox_chan, &pkt);
849 		if (ret < 0)
850 			icnss_pr_err("Failed to send AOP mbox msg: %s,ret: %d\n",
851 				     mbox_msg, ret);
852 		else
853 			ret = 0;
854 	}
855 
856 	return ret;
857 }
858 
859 /* icnss_aop_pdc_reconfig: Send AOP msg to configure PDC table for WLAN device
860  * @priv: Pointer to icnss platform data
861  *
862  * Send AOP QMP or Mbox msg to configure PDC table for WLAN device
863  *
864  * Return: 0 for success, otherwise error code
865  */
866 int icnss_aop_pdc_reconfig(struct icnss_priv *priv)
867 {
868 	u32 i;
869 	int ret;
870 	char *mbox_msg;
871 	struct qmp_pkt pkt;
872 
873 	if (priv->pdc_init_table_len <= 0 || !priv->pdc_init_table)
874 		return 0;
875 
876 	icnss_pr_dbg("Setting PDC defaults for device ID: (0x%x)\n",
877 		     priv->device_id);
878 	for (i = 0; i < priv->pdc_init_table_len; i++) {
879 		mbox_msg = (char *)priv->pdc_init_table[i];
880 		if (priv->use_direct_qmp) {
881 			icnss_pr_dbg("Sending AOP QMP msg: %s\n", mbox_msg);
882 			ret = qmp_send(priv->qmp, mbox_msg,
883 				       ICNSS_MBOX_MSG_MAX_LEN);
884 			if (ret < 0)
885 				icnss_pr_err("Failed to send AOP QMP msg: %s\n",
886 					     mbox_msg);
887 			else
888 				ret = 0;
889 		} else {
890 			icnss_pr_dbg("Sending AOP Mbox msg: %s\n", mbox_msg);
891 			pkt.size = ICNSS_MBOX_MSG_MAX_LEN;
892 			pkt.data = mbox_msg;
893 
894 			ret = mbox_send_message(priv->mbox_chan, &pkt);
895 			if (ret < 0)
896 				icnss_pr_err("Failed to send AOP mbox msg: %s,ret: %d\n",
897 					     mbox_msg, ret);
898 			else
899 				ret = 0;
900 		}
901 	}
902 	return ret;
903 }
904 
905 #else
906 int icnss_aop_interface_init(struct icnss_priv *priv)
907 {
908 	return 0;
909 }
910 
911 void icnss_aop_interface_deinit(struct icnss_priv *priv)
912 {
913 }
914 
915 static int icnss_aop_set_vreg_param(struct icnss_priv *priv,
916 				    const char *vreg_name,
917 				    enum icnss_vreg_param param,
918 				    enum icnss_tcs_seq seq, int val)
919 {
920 	return 0;
921 }
922 
923 int icnss_aop_pdc_reconfig(struct icnss_priv *priv)
924 {
925 	return 0;
926 }
927 
928 #endif
929 
930 void icnss_power_misc_params_init(struct icnss_priv *priv)
931 {
932 	struct device *dev = &priv->pdev->dev;
933 	int ret;
934 
935 	/* common DT Entries */
936 	priv->pdc_init_table_len =
937 				of_property_count_strings(dev->of_node,
938 							  "qcom,pdc_init_table");
939 	if (priv->pdc_init_table_len > 0) {
940 		priv->pdc_init_table =
941 			kcalloc(priv->pdc_init_table_len,
942 				sizeof(char *), GFP_KERNEL);
943 		if (priv->pdc_init_table) {
944 			ret = of_property_read_string_array(dev->of_node,
945 						"qcom,pdc_init_table",
946 						priv->pdc_init_table,
947 						priv->pdc_init_table_len);
948 			if (ret < 0)
949 				icnss_pr_err("Failed to get PDC Init Table\n");
950 		} else {
951 			icnss_pr_err("Failed to alloc PDC Init Table mem\n");
952 		}
953 	} else {
954 		icnss_pr_dbg("PDC Init Table not configured\n");
955 	}
956 }
957 
958 int icnss_update_cpr_info(struct icnss_priv *priv)
959 {
960 	struct icnss_cpr_info *cpr_info = &priv->cpr_info;
961 
962 	if (!cpr_info->vreg_ol_cpr || (!priv->mbox_chan && !priv->use_direct_qmp)) {
963 		icnss_pr_dbg("Mbox channel / QMP / OL CPR Vreg not configured\n");
964 		return 0;
965 	}
966 
967 	if (cpr_info->voltage == 0) {
968 		icnss_pr_err("Voltage %dmV is not valid\n", cpr_info->voltage);
969 		return -EINVAL;
970 	}
971 
972 	cpr_info->voltage = cpr_info->voltage > BT_CXMX_VOLTAGE_MV ?
973 		cpr_info->voltage : BT_CXMX_VOLTAGE_MV;
974 
975 	return icnss_aop_set_vreg_param(priv,
976 				       cpr_info->vreg_ol_cpr,
977 				       ICNSS_VREG_VOLTAGE,
978 				       ICNSS_TCS_UP_SEQ,
979 				       cpr_info->voltage);
980 }
981 
982 static int icnss_get_battery_level(struct icnss_priv *priv)
983 {
984 	int err = 0, battery_percentage = 0;
985 	union power_supply_propval psp = {0,};
986 
987 	if (!priv->batt_psy)
988 		priv->batt_psy = power_supply_get_by_name("battery");
989 
990 	if (priv->batt_psy) {
991 		err = power_supply_get_property(priv->batt_psy,
992 						POWER_SUPPLY_PROP_CAPACITY,
993 						&psp);
994 		if (err) {
995 			icnss_pr_err("battery percentage read error:%d\n", err);
996 			goto out;
997 		}
998 		battery_percentage = psp.intval;
999 	}
1000 
1001 	icnss_pr_info("Battery Percentage: %d\n", battery_percentage);
1002 out:
1003 	return battery_percentage;
1004 }
1005 
1006 static void icnss_update_soc_level(struct work_struct *work)
1007 {
1008 	int battery_percentage = 0, current_updated_voltage = 0, err = 0;
1009 	int level_count;
1010 	struct icnss_priv *priv = container_of(work, struct icnss_priv, soc_update_work);
1011 
1012 	battery_percentage = icnss_get_battery_level(priv);
1013 	if (!battery_percentage ||
1014 	    battery_percentage > ICNSS_MAX_BATTERY_LEVEL) {
1015 		icnss_pr_err("Battery percentage read failure\n");
1016 		return;
1017 	}
1018 
1019 	for (level_count = 0; level_count < ICNSS_BATTERY_LEVEL_COUNT;
1020 	     level_count++) {
1021 		if (battery_percentage >=
1022 		    icnss_battery_level[level_count].lower_battery_threshold) {
1023 			current_updated_voltage =
1024 				icnss_battery_level[level_count].ldo_voltage;
1025 			break;
1026 		}
1027 	}
1028 
1029 	if (level_count != ICNSS_BATTERY_LEVEL_COUNT &&
1030 	    priv->last_updated_voltage != current_updated_voltage) {
1031 		err = icnss_send_vbatt_update(priv, current_updated_voltage);
1032 		if (err < 0) {
1033 			icnss_pr_err("Unable to update ldo voltage");
1034 			return;
1035 		}
1036 		priv->last_updated_voltage = current_updated_voltage;
1037 	}
1038 }
1039 
1040 static int icnss_battery_supply_callback(struct notifier_block *nb,
1041 					 unsigned long event, void *data)
1042 {
1043 	struct power_supply *psy = data;
1044 	struct icnss_priv *priv = container_of(nb, struct icnss_priv,
1045 					       psf_nb);
1046 	if (strcmp(psy->desc->name, "battery"))
1047 		return NOTIFY_OK;
1048 
1049 	if (test_bit(ICNSS_WLFW_CONNECTED, &priv->state) &&
1050 	    !test_bit(ICNSS_FW_DOWN, &priv->state))
1051 		queue_work(priv->soc_update_wq, &priv->soc_update_work);
1052 
1053 	return NOTIFY_OK;
1054 }
1055 
1056 int icnss_get_psf_info(struct icnss_priv *priv)
1057 {
1058 	int ret = 0;
1059 
1060 	priv->soc_update_wq = alloc_workqueue("icnss_soc_update",
1061 					      WQ_UNBOUND, 1);
1062 	if (!priv->soc_update_wq) {
1063 		icnss_pr_err("Workqueue creation failed for soc update\n");
1064 		ret = -EFAULT;
1065 		goto out;
1066 	}
1067 
1068 	priv->psf_nb.notifier_call = icnss_battery_supply_callback;
1069 	ret = power_supply_reg_notifier(&priv->psf_nb);
1070 	if (ret < 0) {
1071 		icnss_pr_err("Power supply framework registration err: %d\n",
1072 			     ret);
1073 		goto err_psf_registration;
1074 	}
1075 
1076 	INIT_WORK(&priv->soc_update_work, icnss_update_soc_level);
1077 
1078 	return 0;
1079 
1080 err_psf_registration:
1081 	destroy_workqueue(priv->soc_update_wq);
1082 out:
1083 	return ret;
1084 }
1085