Commit | Line | Data |
---|---|---|
5e93f352 LF |
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 | #define _RTW_EFUSE_C_ | |
16 | ||
17 | #include <osdep_service.h> | |
18 | #include <drv_types.h> | |
19 | ||
20 | #include <rtw_efuse.h> | |
b2e68046 | 21 | #include <rtl8723a_hal.h> |
050abc45 | 22 | #include <usb_ops_linux.h> |
5e93f352 | 23 | |
5e93f352 | 24 | #define REG_EFUSE_CTRL 0x0030 |
159b023d | 25 | #define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control */ |
5e93f352 | 26 | |
b2e68046 JS |
27 | #define VOLTAGE_V25 0x03 |
28 | #define LDOE25_SHIFT 28 | |
29 | ||
159b023d AS |
30 | /* |
31 | * When we want to enable write operation, we should change to | |
32 | * pwr on state. When we stop write, we should switch to 500k mode | |
33 | * and disable LDO 2.5V. | |
34 | */ | |
b2e68046 JS |
35 | static void Efuse_PowerSwitch(struct rtw_adapter *padapter, |
36 | u8 bWrite, u8 PwrState) | |
5e93f352 | 37 | { |
b2e68046 JS |
38 | u8 tempval; |
39 | u16 tmpV16; | |
40 | ||
41 | if (PwrState == true) { | |
edbfd672 | 42 | rtl8723au_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); |
b2e68046 | 43 | |
159b023d AS |
44 | /* |
45 | * 1.2V Power: From VDDON with Power | |
46 | * Cut(0x0000h[15]), default valid | |
47 | */ | |
050abc45 | 48 | tmpV16 = rtl8723au_read16(padapter, REG_SYS_ISO_CTRL); |
b2e68046 JS |
49 | if (!(tmpV16 & PWC_EV12V)) { |
50 | tmpV16 |= PWC_EV12V; | |
edbfd672 | 51 | rtl8723au_write16(padapter, REG_SYS_ISO_CTRL, tmpV16); |
b2e68046 | 52 | } |
159b023d | 53 | /* Reset: 0x0000h[28], default valid */ |
050abc45 | 54 | tmpV16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN); |
b2e68046 JS |
55 | if (!(tmpV16 & FEN_ELDR)) { |
56 | tmpV16 |= FEN_ELDR; | |
edbfd672 | 57 | rtl8723au_write16(padapter, REG_SYS_FUNC_EN, tmpV16); |
b2e68046 JS |
58 | } |
59 | ||
159b023d AS |
60 | /* |
61 | * Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) | |
62 | * clock from ANA, default valid | |
63 | */ | |
050abc45 | 64 | tmpV16 = rtl8723au_read16(padapter, REG_SYS_CLKR); |
b2e68046 JS |
65 | if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) { |
66 | tmpV16 |= (LOADER_CLK_EN | ANA8M); | |
edbfd672 | 67 | rtl8723au_write16(padapter, REG_SYS_CLKR, tmpV16); |
b2e68046 JS |
68 | } |
69 | ||
70 | if (bWrite == true) { | |
71 | /* Enable LDO 2.5V before read/write action */ | |
050abc45 | 72 | tempval = rtl8723au_read8(padapter, EFUSE_TEST + 3); |
b2e68046 JS |
73 | tempval &= 0x0F; |
74 | tempval |= (VOLTAGE_V25 << 4); | |
edbfd672 JS |
75 | rtl8723au_write8(padapter, EFUSE_TEST + 3, |
76 | tempval | 0x80); | |
b2e68046 JS |
77 | } |
78 | } else { | |
edbfd672 | 79 | rtl8723au_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); |
b2e68046 JS |
80 | |
81 | if (bWrite == true) { | |
82 | /* Disable LDO 2.5V after read/write action */ | |
050abc45 | 83 | tempval = rtl8723au_read8(padapter, EFUSE_TEST + 3); |
edbfd672 JS |
84 | rtl8723au_write8(padapter, EFUSE_TEST + 3, |
85 | tempval & 0x7F); | |
b2e68046 JS |
86 | } |
87 | } | |
5e93f352 LF |
88 | } |
89 | ||
0e4427f4 | 90 | u16 Efuse_GetCurrentSize23a(struct rtw_adapter *pAdapter, u8 efuseType) |
5e93f352 LF |
91 | { |
92 | u16 ret = 0; | |
93 | ||
b2e68046 JS |
94 | if (efuseType == EFUSE_WIFI) |
95 | ret = rtl8723a_EfuseGetCurrentSize_WiFi(pAdapter); | |
96 | else | |
97 | ret = rtl8723a_EfuseGetCurrentSize_BT(pAdapter); | |
5e93f352 LF |
98 | |
99 | return ret; | |
100 | } | |
101 | ||
159b023d | 102 | /* Get current efuse area enabled word */ |
0e4427f4 | 103 | u8 Efuse_CalculateWordCnts23a(u8 word_en) |
5e93f352 | 104 | { |
4ecdc381 | 105 | return hweight8((~word_en) & 0xf); |
5e93f352 LF |
106 | } |
107 | ||
159b023d AS |
108 | /* |
109 | * Description: Execute E-Fuse read byte operation. | |
110 | * | |
111 | * Assumptions: 1. Boot from E-Fuse and successfully auto-load. | |
112 | * 2. PASSIVE_LEVEL (USB interface) | |
113 | */ | |
0e4427f4 | 114 | void ReadEFuseByte23a(struct rtw_adapter *Adapter, u16 _offset, u8 *pbuf) |
5e93f352 LF |
115 | { |
116 | u32 value32; | |
117 | u8 readbyte; | |
118 | u16 retry; | |
5e93f352 LF |
119 | |
120 | /* Write Address */ | |
edbfd672 | 121 | rtl8723au_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff)); |
050abc45 | 122 | readbyte = rtl8723au_read8(Adapter, EFUSE_CTRL+2); |
edbfd672 JS |
123 | rtl8723au_write8(Adapter, EFUSE_CTRL+2, |
124 | ((_offset >> 8) & 0x03) | (readbyte & 0xfc)); | |
5e93f352 LF |
125 | |
126 | /* Write bit 32 0 */ | |
050abc45 | 127 | readbyte = rtl8723au_read8(Adapter, EFUSE_CTRL+3); |
edbfd672 | 128 | rtl8723au_write8(Adapter, EFUSE_CTRL+3, readbyte & 0x7f); |
5e93f352 LF |
129 | |
130 | /* Check bit 32 read-ready */ | |
131 | retry = 0; | |
050abc45 | 132 | value32 = rtl8723au_read32(Adapter, EFUSE_CTRL); |
2892d397 | 133 | while (!((value32 >> 24) & 0x80) && retry < 10000) { |
050abc45 | 134 | value32 = rtl8723au_read32(Adapter, EFUSE_CTRL); |
5e93f352 LF |
135 | retry++; |
136 | } | |
137 | ||
159b023d AS |
138 | /* |
139 | * Added suggested delay. This fixes the problem that | |
140 | * Efuse read error in high temperature condition. | |
141 | * Designer says that there shall be some delay after | |
142 | * ready bit is set, or the result will always stay | |
143 | * on last data we read. | |
144 | */ | |
5e93f352 | 145 | udelay(50); |
050abc45 | 146 | value32 = rtl8723au_read32(Adapter, EFUSE_CTRL); |
5e93f352 LF |
147 | |
148 | *pbuf = (u8)(value32 & 0xff); | |
5e93f352 LF |
149 | } |
150 | ||
0e4427f4 AS |
151 | void EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, |
152 | u8 type, void *pOut) | |
5e93f352 | 153 | { |
b2e68046 JS |
154 | u8 *pu1Tmp; |
155 | u16 *pu2Tmp; | |
156 | u8 *pMax_section; | |
157 | ||
158 | switch (type) { | |
159 | case TYPE_EFUSE_MAX_SECTION: | |
ad6128a3 | 160 | pMax_section = pOut; |
b2e68046 JS |
161 | |
162 | if (efuseType == EFUSE_WIFI) | |
163 | *pMax_section = EFUSE_MAX_SECTION_8723A; | |
164 | else | |
165 | *pMax_section = EFUSE_BT_MAX_SECTION; | |
166 | break; | |
167 | ||
168 | case TYPE_EFUSE_REAL_CONTENT_LEN: | |
ad6128a3 | 169 | pu2Tmp = pOut; |
b2e68046 JS |
170 | |
171 | if (efuseType == EFUSE_WIFI) | |
172 | *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A; | |
173 | else | |
174 | *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN; | |
175 | break; | |
176 | ||
177 | case TYPE_AVAILABLE_EFUSE_BYTES_BANK: | |
ad6128a3 | 178 | pu2Tmp = pOut; |
b2e68046 JS |
179 | |
180 | if (efuseType == EFUSE_WIFI) | |
181 | *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A - | |
182 | EFUSE_OOB_PROTECT_BYTES); | |
183 | else | |
184 | *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN - | |
185 | EFUSE_PROTECT_BYTES_BANK); | |
186 | break; | |
187 | ||
188 | case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: | |
ad6128a3 | 189 | pu2Tmp = pOut; |
b2e68046 JS |
190 | |
191 | if (efuseType == EFUSE_WIFI) | |
192 | *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A - | |
193 | EFUSE_OOB_PROTECT_BYTES); | |
194 | else | |
195 | *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN - | |
196 | (EFUSE_PROTECT_BYTES_BANK * 3)); | |
197 | break; | |
198 | ||
199 | case TYPE_EFUSE_MAP_LEN: | |
ad6128a3 | 200 | pu2Tmp = pOut; |
b2e68046 JS |
201 | |
202 | if (efuseType == EFUSE_WIFI) | |
203 | *pu2Tmp = EFUSE_MAP_LEN_8723A; | |
204 | else | |
205 | *pu2Tmp = EFUSE_BT_MAP_LEN; | |
206 | break; | |
207 | ||
208 | case TYPE_EFUSE_PROTECT_BYTES_BANK: | |
ad6128a3 | 209 | pu1Tmp = pOut; |
b2e68046 JS |
210 | |
211 | if (efuseType == EFUSE_WIFI) | |
212 | *pu1Tmp = EFUSE_OOB_PROTECT_BYTES; | |
213 | else | |
214 | *pu1Tmp = EFUSE_PROTECT_BYTES_BANK; | |
215 | break; | |
216 | ||
217 | case TYPE_EFUSE_CONTENT_LEN_BANK: | |
ad6128a3 | 218 | pu2Tmp = pOut; |
b2e68046 JS |
219 | |
220 | if (efuseType == EFUSE_WIFI) | |
221 | *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A; | |
222 | else | |
223 | *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN; | |
224 | break; | |
225 | ||
226 | default: | |
ad6128a3 | 227 | pu1Tmp = pOut; |
b2e68046 JS |
228 | *pu1Tmp = 0; |
229 | break; | |
230 | } | |
5e93f352 LF |
231 | } |
232 | ||
159b023d | 233 | /* Copy from WMAC for EFUSE read 1 byte. */ |
0e4427f4 | 234 | u8 EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address) |
5e93f352 LF |
235 | { |
236 | u8 data; | |
237 | u8 Bytetemp = {0x00}; | |
238 | u8 temp = {0x00}; | |
239 | u32 k = 0; | |
240 | u16 contentLen = 0; | |
241 | ||
242 | EFUSE_GetEfuseDefinition23a(Adapter, EFUSE_WIFI, | |
243 | TYPE_EFUSE_REAL_CONTENT_LEN, | |
244 | (void *)&contentLen); | |
245 | ||
c5081c54 | 246 | if (Address < contentLen) { /* E-fuse 512Byte */ |
5e93f352 LF |
247 | /* Write E-fuse Register address bit0~7 */ |
248 | temp = Address & 0xFF; | |
edbfd672 | 249 | rtl8723au_write8(Adapter, EFUSE_CTRL+1, temp); |
050abc45 | 250 | Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+2); |
5e93f352 LF |
251 | /* Write E-fuse Register address bit8~9 */ |
252 | temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC); | |
edbfd672 | 253 | rtl8723au_write8(Adapter, EFUSE_CTRL+2, temp); |
5e93f352 LF |
254 | |
255 | /* Write 0x30[31]= 0 */ | |
050abc45 | 256 | Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3); |
5e93f352 | 257 | temp = Bytetemp & 0x7F; |
edbfd672 | 258 | rtl8723au_write8(Adapter, EFUSE_CTRL+3, temp); |
5e93f352 LF |
259 | |
260 | /* Wait Write-ready (0x30[31]= 1) */ | |
050abc45 | 261 | Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3); |
c5081c54 | 262 | while (!(Bytetemp & 0x80)) { |
050abc45 | 263 | Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3); |
5e93f352 | 264 | k++; |
c5081c54 | 265 | if (k == 1000) { |
5e93f352 LF |
266 | k = 0; |
267 | break; | |
268 | } | |
269 | } | |
050abc45 | 270 | data = rtl8723au_read8(Adapter, EFUSE_CTRL); |
5e93f352 | 271 | return data; |
67d095a0 | 272 | } else |
5e93f352 | 273 | return 0xFF; |
159b023d | 274 | } |
5e93f352 | 275 | |
159b023d | 276 | /* Read one byte from real Efuse. */ |
0e4427f4 | 277 | int efuse_OneByteRead23a(struct rtw_adapter *pAdapter, u16 addr, u8 *data) |
5e93f352 LF |
278 | { |
279 | u8 tmpidx = 0; | |
44f3f16d | 280 | int bResult; |
5e93f352 | 281 | |
159b023d | 282 | /* -----------------e-fuse reg ctrl ---------------------------- */ |
5e93f352 | 283 | /* address */ |
5e3144c1 AS |
284 | rtl8723au_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff)); |
285 | rtl8723au_write8(pAdapter, EFUSE_CTRL + 2, | |
286 | ((u8)((addr >> 8) & 0x03)) | | |
287 | (rtl8723au_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC)); | |
5e93f352 | 288 | |
5e3144c1 | 289 | rtl8723au_write8(pAdapter, EFUSE_CTRL + 3, 0x72); /* read cmd */ |
5e93f352 | 290 | |
5e3144c1 AS |
291 | while (!(0x80 & rtl8723au_read8(pAdapter, EFUSE_CTRL + 3)) && |
292 | (tmpidx < 100)) | |
5e93f352 LF |
293 | tmpidx++; |
294 | if (tmpidx < 100) { | |
050abc45 | 295 | *data = rtl8723au_read8(pAdapter, EFUSE_CTRL); |
44f3f16d | 296 | bResult = _SUCCESS; |
5e93f352 LF |
297 | } else { |
298 | *data = 0xff; | |
44f3f16d | 299 | bResult = _FAIL; |
5e93f352 LF |
300 | } |
301 | return bResult; | |
302 | } | |
303 | ||
159b023d | 304 | /* Write one byte to reald Efuse. */ |
0e4427f4 | 305 | int efuse_OneByteWrite23a(struct rtw_adapter *pAdapter, u16 addr, u8 data) |
5e93f352 LF |
306 | { |
307 | u8 tmpidx = 0; | |
44f3f16d | 308 | int bResult; |
5e93f352 | 309 | |
5e93f352 LF |
310 | /* return 0; */ |
311 | ||
159b023d | 312 | /* -----------------e-fuse reg ctrl ------------------------- */ |
5e93f352 | 313 | /* address */ |
5e3144c1 AS |
314 | rtl8723au_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff)); |
315 | rtl8723au_write8(pAdapter, EFUSE_CTRL + 2, | |
316 | (rtl8723au_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC) | | |
317 | (u8)((addr >> 8) & 0x03)); | |
159b023d | 318 | rtl8723au_write8(pAdapter, EFUSE_CTRL, data); /* data */ |
5e93f352 | 319 | |
5e3144c1 | 320 | rtl8723au_write8(pAdapter, EFUSE_CTRL + 3, 0xF2); /* write cmd */ |
5e93f352 | 321 | |
5e3144c1 AS |
322 | while ((0x80 & rtl8723au_read8(pAdapter, EFUSE_CTRL + 3)) && |
323 | (tmpidx < 100)) { | |
5e93f352 LF |
324 | tmpidx++; |
325 | } | |
326 | ||
44f3f16d JS |
327 | if (tmpidx < 100) |
328 | bResult = _SUCCESS; | |
5e93f352 | 329 | else |
44f3f16d | 330 | bResult = _FAIL; |
5e93f352 LF |
331 | |
332 | return bResult; | |
333 | } | |
334 | ||
159b023d | 335 | /* Read allowed word in current efuse section data. */ |
0e4427f4 | 336 | void efuse_WordEnableDataRead23a(u8 word_en, u8 *sourdata, u8 *targetdata) |
5e93f352 | 337 | { |
c5081c54 | 338 | if (!(word_en&BIT(0))) { |
5e93f352 LF |
339 | targetdata[0] = sourdata[0]; |
340 | targetdata[1] = sourdata[1]; | |
341 | } | |
c5081c54 | 342 | if (!(word_en&BIT(1))) { |
5e93f352 LF |
343 | targetdata[2] = sourdata[2]; |
344 | targetdata[3] = sourdata[3]; | |
345 | } | |
c5081c54 | 346 | if (!(word_en&BIT(2))) { |
5e93f352 LF |
347 | targetdata[4] = sourdata[4]; |
348 | targetdata[5] = sourdata[5]; | |
349 | } | |
c5081c54 | 350 | if (!(word_en&BIT(3))) { |
5e93f352 LF |
351 | targetdata[6] = sourdata[6]; |
352 | targetdata[7] = sourdata[7]; | |
353 | } | |
354 | } | |
355 | ||
44f3f16d | 356 | static int efuse_read8(struct rtw_adapter *padapter, u16 address, u8 *value) |
5e93f352 LF |
357 | { |
358 | return efuse_OneByteRead23a(padapter, address, value); | |
359 | } | |
360 | ||
44f3f16d | 361 | static int efuse_write8(struct rtw_adapter *padapter, u16 address, u8 *value) |
5e93f352 LF |
362 | { |
363 | return efuse_OneByteWrite23a(padapter, address, *value); | |
364 | } | |
365 | ||
159b023d | 366 | /* read/write raw efuse data */ |
44f3f16d JS |
367 | int rtw_efuse_access23a(struct rtw_adapter *padapter, u8 bWrite, u16 start_addr, |
368 | u16 cnts, u8 *data) | |
5e93f352 LF |
369 | { |
370 | int i = 0; | |
44f3f16d | 371 | u16 real_content_len = 0, max_available_size = 0; |
5e3144c1 | 372 | int res = _FAIL; |
44f3f16d | 373 | int (*rw8)(struct rtw_adapter *, u16, u8*); |
5e93f352 LF |
374 | |
375 | EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI, | |
376 | TYPE_EFUSE_REAL_CONTENT_LEN, | |
377 | (void *)&real_content_len); | |
378 | EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI, | |
379 | TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, | |
380 | (void *)&max_available_size); | |
381 | ||
382 | if (start_addr > real_content_len) | |
383 | return _FAIL; | |
384 | ||
385 | if (true == bWrite) { | |
386 | if ((start_addr + cnts) > max_available_size) | |
387 | return _FAIL; | |
388 | rw8 = &efuse_write8; | |
389 | } else | |
390 | rw8 = &efuse_read8; | |
391 | ||
b2e68046 | 392 | Efuse_PowerSwitch(padapter, bWrite, true); |
5e93f352 | 393 | |
159b023d | 394 | /* e-fuse one byte read/write */ |
5e93f352 LF |
395 | for (i = 0; i < cnts; i++) { |
396 | if (start_addr >= real_content_len) { | |
397 | res = _FAIL; | |
398 | break; | |
399 | } | |
400 | ||
401 | res = rw8(padapter, start_addr++, data++); | |
44f3f16d JS |
402 | if (res == _FAIL) |
403 | break; | |
5e93f352 LF |
404 | } |
405 | ||
b2e68046 | 406 | Efuse_PowerSwitch(padapter, bWrite, false); |
5e93f352 LF |
407 | |
408 | return res; | |
409 | } | |
159b023d | 410 | |
5e93f352 LF |
411 | u16 efuse_GetMaxSize23a(struct rtw_adapter *padapter) |
412 | { | |
44f3f16d | 413 | u16 max_size; |
5e3144c1 | 414 | |
5e93f352 LF |
415 | EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI, |
416 | TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, | |
417 | (void *)&max_size); | |
418 | return max_size; | |
419 | } | |
159b023d | 420 | |
44f3f16d JS |
421 | int rtw_efuse_map_read23a(struct rtw_adapter *padapter, |
422 | u16 addr, u16 cnts, u8 *data) | |
5e93f352 | 423 | { |
44f3f16d | 424 | u16 mapLen = 0; |
5e93f352 LF |
425 | |
426 | EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI, | |
427 | TYPE_EFUSE_MAP_LEN, (void *)&mapLen); | |
428 | ||
429 | if ((addr + cnts) > mapLen) | |
430 | return _FAIL; | |
431 | ||
b2e68046 | 432 | Efuse_PowerSwitch(padapter, false, true); |
5e93f352 | 433 | |
b2e68046 | 434 | rtl8723a_readefuse(padapter, EFUSE_WIFI, addr, cnts, data); |
5e93f352 | 435 | |
b2e68046 | 436 | Efuse_PowerSwitch(padapter, false, false); |
5e93f352 LF |
437 | |
438 | return _SUCCESS; | |
439 | } | |
440 | ||
44f3f16d JS |
441 | int rtw_BT_efuse_map_read23a(struct rtw_adapter *padapter, |
442 | u16 addr, u16 cnts, u8 *data) | |
5e93f352 | 443 | { |
44f3f16d | 444 | u16 mapLen = 0; |
5e93f352 LF |
445 | |
446 | EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT, | |
447 | TYPE_EFUSE_MAP_LEN, (void *)&mapLen); | |
448 | ||
449 | if ((addr + cnts) > mapLen) | |
450 | return _FAIL; | |
451 | ||
b2e68046 | 452 | Efuse_PowerSwitch(padapter, false, true); |
5e93f352 | 453 | |
b2e68046 | 454 | rtl8723a_readefuse(padapter, EFUSE_BT, addr, cnts, data); |
5e93f352 | 455 | |
b2e68046 | 456 | Efuse_PowerSwitch(padapter, false, false); |
5e93f352 LF |
457 | |
458 | return _SUCCESS; | |
459 | } | |
460 | ||
159b023d | 461 | /* Read All Efuse content */ |
84295526 KS |
462 | static void Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType, |
463 | u8 *Efuse) | |
5e93f352 LF |
464 | { |
465 | u16 mapLen = 0; | |
466 | ||
b2e68046 | 467 | Efuse_PowerSwitch(pAdapter, false, true); |
5e93f352 LF |
468 | |
469 | EFUSE_GetEfuseDefinition23a(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, | |
470 | (void *)&mapLen); | |
471 | ||
b2e68046 | 472 | rtl8723a_readefuse(pAdapter, efuseType, 0, mapLen, Efuse); |
5e93f352 | 473 | |
b2e68046 | 474 | Efuse_PowerSwitch(pAdapter, false, false); |
5e93f352 LF |
475 | } |
476 | ||
159b023d AS |
477 | /* |
478 | * Functions: efuse_ShadowRead1Byte | |
479 | * efuse_ShadowRead2Byte | |
480 | * efuse_ShadowRead4Byte | |
5e93f352 | 481 | * |
159b023d AS |
482 | * Read from efuse init map by one/two/four bytes |
483 | */ | |
0e4427f4 AS |
484 | static void efuse_ShadowRead1Byte(struct rtw_adapter *pAdapter, u16 Offset, |
485 | u8 *Value) | |
5e93f352 LF |
486 | { |
487 | struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); | |
488 | ||
489 | *Value = pEEPROM->efuse_eeprom_data[Offset]; | |
159b023d | 490 | } |
5e93f352 | 491 | |
0e4427f4 AS |
492 | static void efuse_ShadowRead2Byte(struct rtw_adapter *pAdapter, u16 Offset, |
493 | u16 *Value) | |
5e93f352 LF |
494 | { |
495 | struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); | |
496 | ||
497 | *Value = pEEPROM->efuse_eeprom_data[Offset]; | |
498 | *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8; | |
159b023d | 499 | } |
5e93f352 | 500 | |
0e4427f4 AS |
501 | static void efuse_ShadowRead4Byte(struct rtw_adapter *pAdapter, u16 Offset, |
502 | u32 *Value) | |
5e93f352 LF |
503 | { |
504 | struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); | |
505 | ||
506 | *Value = pEEPROM->efuse_eeprom_data[Offset]; | |
507 | *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8; | |
508 | *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16; | |
509 | *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24; | |
159b023d AS |
510 | } |
511 | ||
512 | /* Transfer current EFUSE content to shadow init and modify map. */ | |
5e93f352 LF |
513 | void EFUSE_ShadowMapUpdate23a(struct rtw_adapter *pAdapter, u8 efuseType) |
514 | { | |
515 | struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); | |
516 | u16 mapLen = 0; | |
517 | ||
518 | EFUSE_GetEfuseDefinition23a(pAdapter, efuseType, | |
519 | TYPE_EFUSE_MAP_LEN, (void *)&mapLen); | |
520 | ||
521 | if (pEEPROM->bautoload_fail_flag == true) | |
522 | memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen); | |
523 | else | |
524 | Efuse_ReadAllMap(pAdapter, efuseType, | |
525 | pEEPROM->efuse_eeprom_data); | |
159b023d | 526 | } |
5e93f352 | 527 | |
159b023d | 528 | /* Read from efuse init map */ |
0e4427f4 AS |
529 | void EFUSE_ShadowRead23a(struct rtw_adapter *pAdapter, u8 Type, |
530 | u16 Offset, u32 *Value) | |
5e93f352 LF |
531 | { |
532 | if (Type == 1) | |
533 | efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value); | |
534 | else if (Type == 2) | |
535 | efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value); | |
536 | else if (Type == 4) | |
537 | efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value); | |
159b023d | 538 | } |