1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 
8 #include <pwrseqcmd.h>
9 #include <usb_ops_linux.h>
10 
11 /* This routine deals with the Power Configuration CMDs parsing
12  * for RTL8723/RTL8188E Series IC.
13  */
rtl88eu_pwrseqcmdparsing(struct adapter * padapter,u8 cut_vers,struct wl_pwr_cfg pwrseqcmd[])14 u8 rtl88eu_pwrseqcmdparsing(struct adapter *padapter, u8 cut_vers,
15 			    struct wl_pwr_cfg pwrseqcmd[])
16 {
17 	struct wl_pwr_cfg pwrcfgcmd;
18 	u8 poll_bit = false;
19 	u32 aryidx = 0;
20 	u8 value = 0;
21 	u32 offset = 0;
22 	u32 poll_count = 0; /*  polling autoload done. */
23 	u32 max_poll_count = 5000;
24 
25 	do {
26 		pwrcfgcmd = pwrseqcmd[aryidx];
27 
28 		RT_TRACE(_module_hal_init_c_, _drv_info_,
29 			 ("%s: offset(%#x) cut_msk(%#x)"
30 			  " cmd(%#x)"
31 			  "msk(%#x) value(%#x)\n",
32 			  __func__,
33 			  GET_PWR_CFG_OFFSET(pwrcfgcmd),
34 			  GET_PWR_CFG_CUT_MASK(pwrcfgcmd),
35 			  GET_PWR_CFG_CMD(pwrcfgcmd),
36 			  GET_PWR_CFG_MASK(pwrcfgcmd),
37 			  GET_PWR_CFG_VALUE(pwrcfgcmd)));
38 
39 		/* Only Handle the command whose CUT is matched */
40 		if (GET_PWR_CFG_CUT_MASK(pwrcfgcmd) & cut_vers) {
41 			switch (GET_PWR_CFG_CMD(pwrcfgcmd)) {
42 			case PWR_CMD_READ:
43 				RT_TRACE(_module_hal_init_c_, _drv_info_,
44 					 ("%s: PWR_CMD_READ\n", __func__));
45 				break;
46 			case PWR_CMD_WRITE:
47 				RT_TRACE(_module_hal_init_c_, _drv_info_,
48 					 ("%s: PWR_CMD_WRITE\n", __func__));
49 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
50 
51 				/*  Read the value from system register */
52 				value = usb_read8(padapter, offset);
53 
54 				value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
55 				value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) &
56 					  GET_PWR_CFG_MASK(pwrcfgcmd));
57 
58 				/*  Write the value back to system register */
59 				usb_write8(padapter, offset, value);
60 				break;
61 			case PWR_CMD_POLLING:
62 				RT_TRACE(_module_hal_init_c_, _drv_info_,
63 					 ("%s: PWR_CMD_POLLING\n", __func__));
64 
65 				poll_bit = false;
66 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
67 				do {
68 					value = usb_read8(padapter, offset);
69 					value &= GET_PWR_CFG_MASK(pwrcfgcmd);
70 
71 					if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) &
72 						      GET_PWR_CFG_MASK(pwrcfgcmd)))
73 						poll_bit = true;
74 					else
75 						udelay(10);
76 
77 					if (poll_count++ > max_poll_count) {
78 						DBG_88E("Fail to polling Offset[%#x]\n", offset);
79 						return false;
80 					}
81 				} while (!poll_bit);
82 				break;
83 			case PWR_CMD_DELAY:
84 				RT_TRACE(_module_hal_init_c_, _drv_info_,
85 					 ("%s: PWR_CMD_DELAY\n", __func__));
86 				if (GET_PWR_CFG_VALUE(pwrcfgcmd) == PWRSEQ_DELAY_US)
87 					udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd));
88 				else
89 					udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd) * 1000);
90 				break;
91 			case PWR_CMD_END:
92 				/* When this command is parsed, end the process */
93 				RT_TRACE(_module_hal_init_c_, _drv_info_,
94 					 ("%s: PWR_CMD_END\n", __func__));
95 				return true;
96 			default:
97 				RT_TRACE(_module_hal_init_c_, _drv_err_,
98 					 ("%s: Unknown CMD!!\n", __func__));
99 				break;
100 			}
101 		}
102 
103 		aryidx++;/* Add Array Index */
104 	} while (1);
105 	return true;
106 }
107