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