Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / staging / rtl8723bs / hal / HalPwrSeqCmd.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 /*++
8 Copyright (c) Realtek Semiconductor Corp. All rights reserved.
9
10 Module Name:
11         HalPwrSeqCmd.c
12
13 Abstract:
14         Implement HW Power sequence configuration CMD handling routine for Realtek devices.
15
16 Major Change History:
17         When       Who               What
18         ---------- ---------------   -------------------------------
19         2011-10-26 Lucas            Modify to be compatible with SD4-CE driver.
20         2011-07-07 Roger            Create.
21
22 --*/
23 #include <drv_types.h>
24 #include <rtw_debug.h>
25 #include <HalPwrSeqCmd.h>
26
27
28 /*  */
29 /*  Description: */
30 /*  This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC. */
31 /*  */
32 /*  Assumption: */
33 /*  We should follow specific format which was released from HW SD. */
34 /*  */
35 /*  2011.07.07, added by Roger. */
36 /*  */
37 u8 HalPwrSeqCmdParsing(
38         struct adapter *padapter,
39         u8 CutVersion,
40         u8 FabVersion,
41         u8 InterfaceType,
42         WLAN_PWR_CFG PwrSeqCmd[]
43 )
44 {
45         WLAN_PWR_CFG PwrCfgCmd;
46         u8 bPollingBit = false;
47         u32 AryIdx = 0;
48         u8 value = 0;
49         u32 offset = 0;
50         u32 pollingCount = 0; /*  polling autoload done. */
51         u32 maxPollingCnt = 5000;
52
53         do {
54                 PwrCfgCmd = PwrSeqCmd[AryIdx];
55
56                 RT_TRACE(
57                         _module_hal_init_c_,
58                         _drv_info_,
59                         (
60                                 "HalPwrSeqCmdParsing: offset(%#x) cut_msk(%#x) fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x) msk(%#x) value(%#x)\n",
61                                 GET_PWR_CFG_OFFSET(PwrCfgCmd),
62                                 GET_PWR_CFG_CUT_MASK(PwrCfgCmd),
63                                 GET_PWR_CFG_FAB_MASK(PwrCfgCmd),
64                                 GET_PWR_CFG_INTF_MASK(PwrCfgCmd),
65                                 GET_PWR_CFG_BASE(PwrCfgCmd),
66                                 GET_PWR_CFG_CMD(PwrCfgCmd),
67                                 GET_PWR_CFG_MASK(PwrCfgCmd),
68                                 GET_PWR_CFG_VALUE(PwrCfgCmd)
69                         )
70                 );
71
72                 /* 2 Only Handle the command whose FAB, CUT, and Interface are matched */
73                 if (
74                         (GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) &&
75                         (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) &&
76                         (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)
77                 ) {
78                         switch (GET_PWR_CFG_CMD(PwrCfgCmd)) {
79                         case PWR_CMD_READ:
80                                 RT_TRACE(
81                                         _module_hal_init_c_,
82                                         _drv_info_,
83                                         ("HalPwrSeqCmdParsing: PWR_CMD_READ\n")
84                                 );
85                                 break;
86
87                         case PWR_CMD_WRITE:
88                                 RT_TRACE(
89                                         _module_hal_init_c_,
90                                         _drv_info_,
91                                         ("HalPwrSeqCmdParsing: PWR_CMD_WRITE\n")
92                                 );
93                                 offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
94
95                                 /*  */
96                                 /*  <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface */
97                                 /*  2011.07.07. */
98                                 /*  */
99                                 if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) {
100                                         /*  Read Back SDIO Local value */
101                                         value = SdioLocalCmd52Read1Byte(padapter, offset);
102
103                                         value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
104                                         value |= (
105                                                 GET_PWR_CFG_VALUE(PwrCfgCmd) &
106                                                 GET_PWR_CFG_MASK(PwrCfgCmd)
107                                         );
108
109                                         /*  Write Back SDIO Local value */
110                                         SdioLocalCmd52Write1Byte(padapter, offset, value);
111                                 } else {
112                                         /*  Read the value from system register */
113                                         value = rtw_read8(padapter, offset);
114
115                                         value &= (~(GET_PWR_CFG_MASK(PwrCfgCmd)));
116                                         value |= (
117                                                 GET_PWR_CFG_VALUE(PwrCfgCmd)
118                                                 &GET_PWR_CFG_MASK(PwrCfgCmd)
119                                         );
120
121                                         /*  Write the value back to sytem register */
122                                         rtw_write8(padapter, offset, value);
123                                 }
124                                 break;
125
126                         case PWR_CMD_POLLING:
127                                 RT_TRACE(
128                                         _module_hal_init_c_,
129                                         _drv_info_,
130                                         ("HalPwrSeqCmdParsing: PWR_CMD_POLLING\n")
131                                 );
132
133                                 bPollingBit = false;
134                                 offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
135                                 do {
136                                         if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
137                                                 value = SdioLocalCmd52Read1Byte(padapter, offset);
138                                         else
139                                                 value = rtw_read8(padapter, offset);
140
141                                         value = value&GET_PWR_CFG_MASK(PwrCfgCmd);
142                                         if (
143                                                 value == (GET_PWR_CFG_VALUE(PwrCfgCmd) &
144                                                 GET_PWR_CFG_MASK(PwrCfgCmd))
145                                         )
146                                                 bPollingBit = true;
147                                         else
148                                                 udelay(10);
149
150                                         if (pollingCount++ > maxPollingCnt) {
151                                                 DBG_871X(
152                                                         "Fail to polling Offset[%#x]=%02x\n",
153                                                         offset,
154                                                         value
155                                                 );
156                                                 return false;
157                                         }
158                                 } while (!bPollingBit);
159
160                                 break;
161
162                         case PWR_CMD_DELAY:
163                                 RT_TRACE(
164                                         _module_hal_init_c_,
165                                         _drv_info_,
166                                         ("HalPwrSeqCmdParsing: PWR_CMD_DELAY\n")
167                                 );
168                                 if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
169                                         udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd));
170                                 else
171                                         udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000);
172                                 break;
173
174                         case PWR_CMD_END:
175                                 /*  When this command is parsed, end the process */
176                                 RT_TRACE(
177                                         _module_hal_init_c_,
178                                         _drv_info_,
179                                         ("HalPwrSeqCmdParsing: PWR_CMD_END\n")
180                                 );
181                                 return true;
182
183                         default:
184                                 RT_TRACE(
185                                         _module_hal_init_c_,
186                                         _drv_err_,
187                                         ("HalPwrSeqCmdParsing: Unknown CMD!!\n")
188                                 );
189                                 break;
190                         }
191                 }
192
193                 AryIdx++;/* Add Array Index */
194         } while (1);
195
196         return true;
197 }