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 			 ("rtl88eu_pwrseqcmdparsing: offset(%#x) cut_msk(%#x)"
30 			  " cmd(%#x)"
31 			  "msk(%#x) value(%#x)\n",
32 			 GET_PWR_CFG_OFFSET(pwrcfgcmd),
33 			 GET_PWR_CFG_CUT_MASK(pwrcfgcmd),
34 			 GET_PWR_CFG_CMD(pwrcfgcmd),
35 			 GET_PWR_CFG_MASK(pwrcfgcmd),
36 			 GET_PWR_CFG_VALUE(pwrcfgcmd)));
37 
38 		/* Only Handle the command whose CUT is matched */
39 		if (GET_PWR_CFG_CUT_MASK(pwrcfgcmd) & cut_vers) {
40 			switch (GET_PWR_CFG_CMD(pwrcfgcmd)) {
41 			case PWR_CMD_READ:
42 				RT_TRACE(_module_hal_init_c_, _drv_info_,
43 					 ("rtl88eu_pwrseqcmdparsing: PWR_CMD_READ\n"));
44 				break;
45 			case PWR_CMD_WRITE:
46 				RT_TRACE(_module_hal_init_c_, _drv_info_,
47 					 ("rtl88eu_pwrseqcmdparsing: PWR_CMD_WRITE\n"));
48 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
49 
50 				/*  Read the value from system register */
51 				value = usb_read8(padapter, offset);
52 
53 				value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
54 				value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) &
55 					  GET_PWR_CFG_MASK(pwrcfgcmd));
56 
57 				/*  Write the value back to system register */
58 				usb_write8(padapter, offset, value);
59 				break;
60 			case PWR_CMD_POLLING:
61 				RT_TRACE(_module_hal_init_c_, _drv_info_,
62 					 ("rtl88eu_pwrseqcmdparsing: PWR_CMD_POLLING\n"));
63 
64 				poll_bit = false;
65 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
66 				do {
67 					value = usb_read8(padapter, offset);
68 					value &= GET_PWR_CFG_MASK(pwrcfgcmd);
69 
70 					if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) &
71 						      GET_PWR_CFG_MASK(pwrcfgcmd)))
72 						poll_bit = true;
73 					else
74 						udelay(10);
75 
76 					if (poll_count++ > max_poll_count) {
77 						DBG_88E("Fail to polling Offset[%#x]\n", offset);
78 						return false;
79 					}
80 				} while (!poll_bit);
81 				break;
82 			case PWR_CMD_DELAY:
83 				RT_TRACE(_module_hal_init_c_, _drv_info_,
84 					 ("rtl88eu_pwrseqcmdparsing: PWR_CMD_DELAY\n"));
85 				if (GET_PWR_CFG_VALUE(pwrcfgcmd) == PWRSEQ_DELAY_US)
86 					udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd));
87 				else
88 					udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd)*1000);
89 				break;
90 			case PWR_CMD_END:
91 				/* When this command is parsed, end the process */
92 				RT_TRACE(_module_hal_init_c_, _drv_info_,
93 					 ("rtl88eu_pwrseqcmdparsing: PWR_CMD_END\n"));
94 				return true;
95 			default:
96 				RT_TRACE(_module_hal_init_c_, _drv_err_,
97 					 ("rtl88eu_pwrseqcmdparsing: Unknown CMD!!\n"));
98 				break;
99 			}
100 		}
101 
102 		aryidx++;/* Add Array Index */
103 	} while (1);
104 	return true;
105 }
106