1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3 
4 #define _RTW_EFUSE_C_
5 
6 #include "../include/osdep_service.h"
7 #include "../include/drv_types.h"
8 #include "../include/rtw_efuse.h"
9 #include "../include/rtl8188e_hal.h"
10 
11 /*  */
12 /* 	Description: */
13 /* 		Execute E-Fuse read byte operation. */
14 /* 		Referred from SD1 Richard. */
15 /*  */
16 /* 	Assumption: */
17 /* 		1. Boot from E-Fuse and successfully auto-load. */
18 /* 		2. PASSIVE_LEVEL (USB interface) */
19 /*  */
20 /* 	Created by Roger, 2008.10.21. */
21 /*  */
22 void
ReadEFuseByte(struct adapter * Adapter,u16 _offset,u8 * pbuf)23 ReadEFuseByte(
24 		struct adapter *Adapter,
25 		u16 _offset,
26 		u8 *pbuf)
27 {
28 	u32 value32;
29 	u8 readbyte;
30 	u16 retry;
31 	int res;
32 
33 	/* Write Address */
34 	rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
35 	res = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte);
36 	if (res)
37 		return;
38 
39 	rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
40 
41 	/* Write bit 32 0 */
42 	res = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte);
43 	if (res)
44 		return;
45 
46 	rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
47 
48 	/* Check bit 32 read-ready */
49 	res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
50 	if (res)
51 		return;
52 
53 	for (retry = 0; retry < 10000; retry++) {
54 		res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
55 		if (res)
56 			continue;
57 
58 		if (((value32 >> 24) & 0xff) & 0x80)
59 			break;
60 	}
61 
62 	/*  20100205 Joseph: Add delay suggested by SD1 Victor. */
63 	/*  This fix the problem that Efuse read error in high temperature condition. */
64 	/*  Designer says that there shall be some delay after ready bit is set, or the */
65 	/*  result will always stay on last data we read. */
66 	udelay(50);
67 	res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
68 	if (res)
69 		return;
70 
71 	*pbuf = (u8)(value32 & 0xff);
72 
73 	/* FIXME: return an error to caller */
74 }
75