1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#define _RTW_EFUSE_C_
16
17#include <osdep_service.h>
18#include <drv_types.h>
19
20#include <rtw_efuse.h>
21#include <rtl8723a_hal.h>
22#include <usb_ops_linux.h>
23
24#define REG_EFUSE_CTRL 0x0030
25#define EFUSE_CTRL REG_EFUSE_CTRL
26
27#define VOLTAGE_V25 0x03
28#define LDOE25_SHIFT 28
29
30
31
32
33
34
35static void Efuse_PowerSwitch(struct rtw_adapter *padapter,
36 u8 bWrite, u8 PwrState)
37{
38 u8 tempval;
39 u16 tmpV16;
40
41 if (PwrState == true) {
42 rtl8723au_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
43
44
45
46
47
48 tmpV16 = rtl8723au_read16(padapter, REG_SYS_ISO_CTRL);
49 if (!(tmpV16 & PWC_EV12V)) {
50 tmpV16 |= PWC_EV12V;
51 rtl8723au_write16(padapter, REG_SYS_ISO_CTRL, tmpV16);
52 }
53
54 tmpV16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN);
55 if (!(tmpV16 & FEN_ELDR)) {
56 tmpV16 |= FEN_ELDR;
57 rtl8723au_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
58 }
59
60
61
62
63
64 tmpV16 = rtl8723au_read16(padapter, REG_SYS_CLKR);
65 if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
66 tmpV16 |= (LOADER_CLK_EN | ANA8M);
67 rtl8723au_write16(padapter, REG_SYS_CLKR, tmpV16);
68 }
69
70 if (bWrite == true) {
71
72 tempval = rtl8723au_read8(padapter, EFUSE_TEST + 3);
73 tempval &= 0x0F;
74 tempval |= (VOLTAGE_V25 << 4);
75 rtl8723au_write8(padapter, EFUSE_TEST + 3,
76 tempval | 0x80);
77 }
78 } else {
79 rtl8723au_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
80
81 if (bWrite == true) {
82
83 tempval = rtl8723au_read8(padapter, EFUSE_TEST + 3);
84 rtl8723au_write8(padapter, EFUSE_TEST + 3,
85 tempval & 0x7F);
86 }
87 }
88}
89
90u16 Efuse_GetCurrentSize23a(struct rtw_adapter *pAdapter, u8 efuseType)
91{
92 u16 ret = 0;
93
94 if (efuseType == EFUSE_WIFI)
95 ret = rtl8723a_EfuseGetCurrentSize_WiFi(pAdapter);
96 else
97 ret = rtl8723a_EfuseGetCurrentSize_BT(pAdapter);
98
99 return ret;
100}
101
102
103u8 Efuse_CalculateWordCnts23a(u8 word_en)
104{
105 return hweight8((~word_en) & 0xf);
106}
107
108
109
110
111
112
113
114void ReadEFuseByte23a(struct rtw_adapter *Adapter, u16 _offset, u8 *pbuf)
115{
116 u32 value32;
117 u8 readbyte;
118 u16 retry;
119
120
121 rtl8723au_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff));
122 readbyte = rtl8723au_read8(Adapter, EFUSE_CTRL+2);
123 rtl8723au_write8(Adapter, EFUSE_CTRL+2,
124 ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
125
126
127 readbyte = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
128 rtl8723au_write8(Adapter, EFUSE_CTRL+3, readbyte & 0x7f);
129
130
131 retry = 0;
132 value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
133 while (!((value32 >> 24) & 0x80) && retry < 10000) {
134 value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
135 retry++;
136 }
137
138
139
140
141
142
143
144
145 udelay(50);
146 value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
147
148 *pbuf = (u8)(value32 & 0xff);
149}
150
151void EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType,
152 u8 type, void *pOut)
153{
154 u8 *pu1Tmp;
155 u16 *pu2Tmp;
156 u8 *pMax_section;
157
158 switch (type) {
159 case TYPE_EFUSE_MAX_SECTION:
160 pMax_section = pOut;
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:
169 pu2Tmp = pOut;
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:
178 pu2Tmp = pOut;
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:
189 pu2Tmp = pOut;
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:
200 pu2Tmp = pOut;
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:
209 pu1Tmp = pOut;
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:
218 pu2Tmp = pOut;
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:
227 pu1Tmp = pOut;
228 *pu1Tmp = 0;
229 break;
230 }
231}
232
233
234u8 EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address)
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
246 if (Address < contentLen) {
247
248 temp = Address & 0xFF;
249 rtl8723au_write8(Adapter, EFUSE_CTRL+1, temp);
250 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+2);
251
252 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
253 rtl8723au_write8(Adapter, EFUSE_CTRL+2, temp);
254
255
256 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
257 temp = Bytetemp & 0x7F;
258 rtl8723au_write8(Adapter, EFUSE_CTRL+3, temp);
259
260
261 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
262 while (!(Bytetemp & 0x80)) {
263 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
264 k++;
265 if (k == 1000) {
266 k = 0;
267 break;
268 }
269 }
270 data = rtl8723au_read8(Adapter, EFUSE_CTRL);
271 return data;
272 }
273 return 0xFF;
274}
275
276
277int efuse_OneByteRead23a(struct rtw_adapter *pAdapter, u16 addr, u8 *data)
278{
279 u8 tmpidx = 0;
280 int bResult;
281
282
283
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));
288
289 rtl8723au_write8(pAdapter, EFUSE_CTRL + 3, 0x72);
290
291 while (!(0x80 & rtl8723au_read8(pAdapter, EFUSE_CTRL + 3)) &&
292 (tmpidx < 100))
293 tmpidx++;
294 if (tmpidx < 100) {
295 *data = rtl8723au_read8(pAdapter, EFUSE_CTRL);
296 bResult = _SUCCESS;
297 } else {
298 *data = 0xff;
299 bResult = _FAIL;
300 }
301 return bResult;
302}
303
304
305int efuse_OneByteWrite23a(struct rtw_adapter *pAdapter, u16 addr, u8 data)
306{
307 u8 tmpidx = 0;
308 int bResult;
309
310
311
312
313
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));
318 rtl8723au_write8(pAdapter, EFUSE_CTRL, data);
319
320 rtl8723au_write8(pAdapter, EFUSE_CTRL + 3, 0xF2);
321
322 while ((0x80 & rtl8723au_read8(pAdapter, EFUSE_CTRL + 3)) &&
323 (tmpidx < 100)) {
324 tmpidx++;
325 }
326
327 if (tmpidx < 100)
328 bResult = _SUCCESS;
329 else
330 bResult = _FAIL;
331
332 return bResult;
333}
334
335
336void efuse_WordEnableDataRead23a(u8 word_en, u8 *sourdata, u8 *targetdata)
337{
338 if (!(word_en&BIT(0))) {
339 targetdata[0] = sourdata[0];
340 targetdata[1] = sourdata[1];
341 }
342 if (!(word_en&BIT(1))) {
343 targetdata[2] = sourdata[2];
344 targetdata[3] = sourdata[3];
345 }
346 if (!(word_en&BIT(2))) {
347 targetdata[4] = sourdata[4];
348 targetdata[5] = sourdata[5];
349 }
350 if (!(word_en&BIT(3))) {
351 targetdata[6] = sourdata[6];
352 targetdata[7] = sourdata[7];
353 }
354}
355
356static int efuse_read8(struct rtw_adapter *padapter, u16 address, u8 *value)
357{
358 return efuse_OneByteRead23a(padapter, address, value);
359}
360
361static int efuse_write8(struct rtw_adapter *padapter, u16 address, u8 *value)
362{
363 return efuse_OneByteWrite23a(padapter, address, *value);
364}
365
366
367int rtw_efuse_access23a(struct rtw_adapter *padapter, u8 bWrite, u16 start_addr,
368 u16 cnts, u8 *data)
369{
370 int i = 0;
371 u16 real_content_len = 0, max_available_size = 0;
372 int res = _FAIL;
373 int (*rw8)(struct rtw_adapter *, u16, u8*);
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
392 Efuse_PowerSwitch(padapter, bWrite, true);
393
394
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++);
402 if (res == _FAIL)
403 break;
404 }
405
406 Efuse_PowerSwitch(padapter, bWrite, false);
407
408 return res;
409}
410
411u16 efuse_GetMaxSize23a(struct rtw_adapter *padapter)
412{
413 u16 max_size;
414
415 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
416 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL,
417 (void *)&max_size);
418 return max_size;
419}
420
421int rtw_efuse_map_read23a(struct rtw_adapter *padapter,
422 u16 addr, u16 cnts, u8 *data)
423{
424 u16 mapLen = 0;
425
426 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
427 TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
428
429 if ((addr + cnts) > mapLen)
430 return _FAIL;
431
432 Efuse_PowerSwitch(padapter, false, true);
433
434 rtl8723a_readefuse(padapter, EFUSE_WIFI, addr, cnts, data);
435
436 Efuse_PowerSwitch(padapter, false, false);
437
438 return _SUCCESS;
439}
440
441int rtw_BT_efuse_map_read23a(struct rtw_adapter *padapter,
442 u16 addr, u16 cnts, u8 *data)
443{
444 u16 mapLen = 0;
445
446 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
447 TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
448
449 if ((addr + cnts) > mapLen)
450 return _FAIL;
451
452 Efuse_PowerSwitch(padapter, false, true);
453
454 rtl8723a_readefuse(padapter, EFUSE_BT, addr, cnts, data);
455
456 Efuse_PowerSwitch(padapter, false, false);
457
458 return _SUCCESS;
459}
460
461
462static void Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType,
463 u8 *Efuse)
464{
465 u16 mapLen = 0;
466
467 Efuse_PowerSwitch(pAdapter, false, true);
468
469 EFUSE_GetEfuseDefinition23a(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN,
470 (void *)&mapLen);
471
472 rtl8723a_readefuse(pAdapter, efuseType, 0, mapLen, Efuse);
473
474 Efuse_PowerSwitch(pAdapter, false, false);
475}
476
477
478
479
480
481
482
483
484static void efuse_ShadowRead1Byte(struct rtw_adapter *pAdapter, u16 Offset,
485 u8 *Value)
486{
487 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
488
489 *Value = pEEPROM->efuse_eeprom_data[Offset];
490}
491
492static void efuse_ShadowRead2Byte(struct rtw_adapter *pAdapter, u16 Offset,
493 u16 *Value)
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;
499}
500
501static void efuse_ShadowRead4Byte(struct rtw_adapter *pAdapter, u16 Offset,
502 u32 *Value)
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;
510}
511
512
513void 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);
526}
527
528
529void EFUSE_ShadowRead23a(struct rtw_adapter *pAdapter, u8 Type,
530 u16 Offset, u32 *Value)
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);
538}
539