blob: 81960e788f8932c3b08d133aef32f8638ac514d3 [file] [log] [blame]
Larry Finger5e93f352014-03-28 21:37:38 -05001/******************************************************************************
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>
Jes Sorensenb2e68042014-05-16 10:04:14 +020021#include <rtl8723a_hal.h>
Jes Sorensen050abc42014-05-16 10:05:08 +020022#include <usb_ops_linux.h>
Larry Finger5e93f352014-03-28 21:37:38 -050023
24/*------------------------Define local variable------------------------------*/
25
26/* */
27#define REG_EFUSE_CTRL 0x0030
28#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */
29/* */
30
Jes Sorensenb2e68042014-05-16 10:04:14 +020031#define VOLTAGE_V25 0x03
32#define LDOE25_SHIFT 28
33
Larry Finger5e93f352014-03-28 21:37:38 -050034/*-----------------------------------------------------------------------------
Jes Sorensenb2e68042014-05-16 10:04:14 +020035 * Function: Efuse_PowerSwitch
Larry Finger5e93f352014-03-28 21:37:38 -050036 *
37 * Overview: When we want to enable write operation, we should change to
38 * pwr on state. When we stop write, we should switch to 500k mode
39 * and disable LDO 2.5V.
40 *
41 * Input: NONE
42 *
43 * Output: NONE
44 *
45 * Return: NONE
46 *
47 * Revised History:
48 * When Who Remark
49 * 11/17/2008 MHC Create Version 0.
50 *
51 *---------------------------------------------------------------------------*/
Jes Sorensenb2e68042014-05-16 10:04:14 +020052static void Efuse_PowerSwitch(struct rtw_adapter *padapter,
53 u8 bWrite, u8 PwrState)
Larry Finger5e93f352014-03-28 21:37:38 -050054{
Jes Sorensenb2e68042014-05-16 10:04:14 +020055 u8 tempval;
56 u16 tmpV16;
57
58 if (PwrState == true) {
Jes Sorensenedbfd672014-05-16 10:05:09 +020059 rtl8723au_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
Jes Sorensenb2e68042014-05-16 10:04:14 +020060
61 /* 1.2V Power: From VDDON with Power
Masanari Iida808bcb42014-07-22 23:42:53 +090062 Cut(0x0000h[15]), default valid */
Jes Sorensen050abc42014-05-16 10:05:08 +020063 tmpV16 = rtl8723au_read16(padapter, REG_SYS_ISO_CTRL);
Jes Sorensenb2e68042014-05-16 10:04:14 +020064 if (!(tmpV16 & PWC_EV12V)) {
65 tmpV16 |= PWC_EV12V;
Jes Sorensenedbfd672014-05-16 10:05:09 +020066 rtl8723au_write16(padapter, REG_SYS_ISO_CTRL, tmpV16);
Jes Sorensenb2e68042014-05-16 10:04:14 +020067 }
68 /* Reset: 0x0000h[28], default valid */
Jes Sorensen050abc42014-05-16 10:05:08 +020069 tmpV16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN);
Jes Sorensenb2e68042014-05-16 10:04:14 +020070 if (!(tmpV16 & FEN_ELDR)) {
71 tmpV16 |= FEN_ELDR;
Jes Sorensenedbfd672014-05-16 10:05:09 +020072 rtl8723au_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
Jes Sorensenb2e68042014-05-16 10:04:14 +020073 }
74
75 /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock
76 from ANA, default valid */
Jes Sorensen050abc42014-05-16 10:05:08 +020077 tmpV16 = rtl8723au_read16(padapter, REG_SYS_CLKR);
Jes Sorensenb2e68042014-05-16 10:04:14 +020078 if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
79 tmpV16 |= (LOADER_CLK_EN | ANA8M);
Jes Sorensenedbfd672014-05-16 10:05:09 +020080 rtl8723au_write16(padapter, REG_SYS_CLKR, tmpV16);
Jes Sorensenb2e68042014-05-16 10:04:14 +020081 }
82
83 if (bWrite == true) {
84 /* Enable LDO 2.5V before read/write action */
Jes Sorensen050abc42014-05-16 10:05:08 +020085 tempval = rtl8723au_read8(padapter, EFUSE_TEST + 3);
Jes Sorensenb2e68042014-05-16 10:04:14 +020086 tempval &= 0x0F;
87 tempval |= (VOLTAGE_V25 << 4);
Jes Sorensenedbfd672014-05-16 10:05:09 +020088 rtl8723au_write8(padapter, EFUSE_TEST + 3,
89 tempval | 0x80);
Jes Sorensenb2e68042014-05-16 10:04:14 +020090 }
91 } else {
Jes Sorensenedbfd672014-05-16 10:05:09 +020092 rtl8723au_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
Jes Sorensenb2e68042014-05-16 10:04:14 +020093
94 if (bWrite == true) {
95 /* Disable LDO 2.5V after read/write action */
Jes Sorensen050abc42014-05-16 10:05:08 +020096 tempval = rtl8723au_read8(padapter, EFUSE_TEST + 3);
Jes Sorensenedbfd672014-05-16 10:05:09 +020097 rtl8723au_write8(padapter, EFUSE_TEST + 3,
98 tempval & 0x7F);
Jes Sorensenb2e68042014-05-16 10:04:14 +020099 }
100 }
Larry Finger5e93f352014-03-28 21:37:38 -0500101}
102
Larry Finger5e93f352014-03-28 21:37:38 -0500103u16
104Efuse_GetCurrentSize23a(struct rtw_adapter *pAdapter, u8 efuseType)
105{
106 u16 ret = 0;
107
Jes Sorensenb2e68042014-05-16 10:04:14 +0200108 if (efuseType == EFUSE_WIFI)
109 ret = rtl8723a_EfuseGetCurrentSize_WiFi(pAdapter);
110 else
111 ret = rtl8723a_EfuseGetCurrentSize_BT(pAdapter);
Larry Finger5e93f352014-03-28 21:37:38 -0500112
113 return ret;
114}
115
116/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
117u8
118Efuse_CalculateWordCnts23a(u8 word_en)
119{
Tapasweni Pathak4ecdc382014-10-08 10:15:42 +0530120 return hweight8((~word_en) & 0xf);
Larry Finger5e93f352014-03-28 21:37:38 -0500121}
122
123/* */
124/* Description: */
125/* Execute E-Fuse read byte operation. */
Masanari Iida808bcb42014-07-22 23:42:53 +0900126/* Referred from SD1 Richard. */
Larry Finger5e93f352014-03-28 21:37:38 -0500127/* */
128/* Assumption: */
129/* 1. Boot from E-Fuse and successfully auto-load. */
130/* 2. PASSIVE_LEVEL (USB interface) */
131/* */
132/* Created by Roger, 2008.10.21. */
133/* */
134void
135ReadEFuseByte23a(struct rtw_adapter *Adapter, u16 _offset, u8 *pbuf)
136{
137 u32 value32;
138 u8 readbyte;
139 u16 retry;
Larry Finger5e93f352014-03-28 21:37:38 -0500140
141 /* Write Address */
Jes Sorensenedbfd672014-05-16 10:05:09 +0200142 rtl8723au_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff));
Jes Sorensen050abc42014-05-16 10:05:08 +0200143 readbyte = rtl8723au_read8(Adapter, EFUSE_CTRL+2);
Jes Sorensenedbfd672014-05-16 10:05:09 +0200144 rtl8723au_write8(Adapter, EFUSE_CTRL+2,
145 ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
Larry Finger5e93f352014-03-28 21:37:38 -0500146
147 /* Write bit 32 0 */
Jes Sorensen050abc42014-05-16 10:05:08 +0200148 readbyte = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
Jes Sorensenedbfd672014-05-16 10:05:09 +0200149 rtl8723au_write8(Adapter, EFUSE_CTRL+3, readbyte & 0x7f);
Larry Finger5e93f352014-03-28 21:37:38 -0500150
151 /* Check bit 32 read-ready */
152 retry = 0;
Jes Sorensen050abc42014-05-16 10:05:08 +0200153 value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
Andreas Schlick2892d392014-08-07 19:20:50 +0200154 while (!((value32 >> 24) & 0x80) && retry < 10000) {
Jes Sorensen050abc42014-05-16 10:05:08 +0200155 value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
Larry Finger5e93f352014-03-28 21:37:38 -0500156 retry++;
157 }
158
159 /* 20100205 Joseph: Add delay suggested by SD1 Victor. */
160 /* This fix the problem that Efuse read error in high temperature condition. */
161 /* Designer says that there shall be some delay after ready bit is set, or the */
162 /* result will always stay on last data we read. */
163 udelay(50);
Jes Sorensen050abc42014-05-16 10:05:08 +0200164 value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
Larry Finger5e93f352014-03-28 21:37:38 -0500165
166 *pbuf = (u8)(value32 & 0xff);
Larry Finger5e93f352014-03-28 21:37:38 -0500167}
168
Larry Finger5e93f352014-03-28 21:37:38 -0500169void
170EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType,
Jes Sorensenb2e68042014-05-16 10:04:14 +0200171 u8 type, void *pOut)
Larry Finger5e93f352014-03-28 21:37:38 -0500172{
Jes Sorensenb2e68042014-05-16 10:04:14 +0200173 u8 *pu1Tmp;
174 u16 *pu2Tmp;
175 u8 *pMax_section;
176
177 switch (type) {
178 case TYPE_EFUSE_MAX_SECTION:
Tapasweni Pathakad6128a2014-10-30 17:03:55 +0530179 pMax_section = pOut;
Jes Sorensenb2e68042014-05-16 10:04:14 +0200180
181 if (efuseType == EFUSE_WIFI)
182 *pMax_section = EFUSE_MAX_SECTION_8723A;
183 else
184 *pMax_section = EFUSE_BT_MAX_SECTION;
185 break;
186
187 case TYPE_EFUSE_REAL_CONTENT_LEN:
Tapasweni Pathakad6128a2014-10-30 17:03:55 +0530188 pu2Tmp = pOut;
Jes Sorensenb2e68042014-05-16 10:04:14 +0200189
190 if (efuseType == EFUSE_WIFI)
191 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
192 else
193 *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
194 break;
195
196 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
Tapasweni Pathakad6128a2014-10-30 17:03:55 +0530197 pu2Tmp = pOut;
Jes Sorensenb2e68042014-05-16 10:04:14 +0200198
199 if (efuseType == EFUSE_WIFI)
200 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A -
201 EFUSE_OOB_PROTECT_BYTES);
202 else
203 *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN -
204 EFUSE_PROTECT_BYTES_BANK);
205 break;
206
207 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
Tapasweni Pathakad6128a2014-10-30 17:03:55 +0530208 pu2Tmp = pOut;
Jes Sorensenb2e68042014-05-16 10:04:14 +0200209
210 if (efuseType == EFUSE_WIFI)
211 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A -
212 EFUSE_OOB_PROTECT_BYTES);
213 else
214 *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN -
215 (EFUSE_PROTECT_BYTES_BANK * 3));
216 break;
217
218 case TYPE_EFUSE_MAP_LEN:
Tapasweni Pathakad6128a2014-10-30 17:03:55 +0530219 pu2Tmp = pOut;
Jes Sorensenb2e68042014-05-16 10:04:14 +0200220
221 if (efuseType == EFUSE_WIFI)
222 *pu2Tmp = EFUSE_MAP_LEN_8723A;
223 else
224 *pu2Tmp = EFUSE_BT_MAP_LEN;
225 break;
226
227 case TYPE_EFUSE_PROTECT_BYTES_BANK:
Tapasweni Pathakad6128a2014-10-30 17:03:55 +0530228 pu1Tmp = pOut;
Jes Sorensenb2e68042014-05-16 10:04:14 +0200229
230 if (efuseType == EFUSE_WIFI)
231 *pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
232 else
233 *pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
234 break;
235
236 case TYPE_EFUSE_CONTENT_LEN_BANK:
Tapasweni Pathakad6128a2014-10-30 17:03:55 +0530237 pu2Tmp = pOut;
Jes Sorensenb2e68042014-05-16 10:04:14 +0200238
239 if (efuseType == EFUSE_WIFI)
240 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
241 else
242 *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
243 break;
244
245 default:
Tapasweni Pathakad6128a2014-10-30 17:03:55 +0530246 pu1Tmp = pOut;
Jes Sorensenb2e68042014-05-16 10:04:14 +0200247 *pu1Tmp = 0;
248 break;
249 }
Larry Finger5e93f352014-03-28 21:37:38 -0500250}
251
252/*-----------------------------------------------------------------------------
253 * Function: EFUSE_Read1Byte23a
254 *
255 * Overview: Copy from WMAC fot EFUSE read 1 byte.
256 *
257 * Input: NONE
258 *
259 * Output: NONE
260 *
261 * Return: NONE
262 *
263 * Revised History:
264 * When Who Remark
265 * 09/23/2008 MHC Copy from WMAC.
266 *
267 *---------------------------------------------------------------------------*/
268u8
269EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address)
270{
271 u8 data;
272 u8 Bytetemp = {0x00};
273 u8 temp = {0x00};
274 u32 k = 0;
275 u16 contentLen = 0;
276
277 EFUSE_GetEfuseDefinition23a(Adapter, EFUSE_WIFI,
278 TYPE_EFUSE_REAL_CONTENT_LEN,
279 (void *)&contentLen);
280
Andreas Schlickc5081c52014-08-07 19:20:49 +0200281 if (Address < contentLen) { /* E-fuse 512Byte */
Larry Finger5e93f352014-03-28 21:37:38 -0500282 /* Write E-fuse Register address bit0~7 */
283 temp = Address & 0xFF;
Jes Sorensenedbfd672014-05-16 10:05:09 +0200284 rtl8723au_write8(Adapter, EFUSE_CTRL+1, temp);
Jes Sorensen050abc42014-05-16 10:05:08 +0200285 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+2);
Larry Finger5e93f352014-03-28 21:37:38 -0500286 /* Write E-fuse Register address bit8~9 */
287 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
Jes Sorensenedbfd672014-05-16 10:05:09 +0200288 rtl8723au_write8(Adapter, EFUSE_CTRL+2, temp);
Larry Finger5e93f352014-03-28 21:37:38 -0500289
290 /* Write 0x30[31]= 0 */
Jes Sorensen050abc42014-05-16 10:05:08 +0200291 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
Larry Finger5e93f352014-03-28 21:37:38 -0500292 temp = Bytetemp & 0x7F;
Jes Sorensenedbfd672014-05-16 10:05:09 +0200293 rtl8723au_write8(Adapter, EFUSE_CTRL+3, temp);
Larry Finger5e93f352014-03-28 21:37:38 -0500294
295 /* Wait Write-ready (0x30[31]= 1) */
Jes Sorensen050abc42014-05-16 10:05:08 +0200296 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
Andreas Schlickc5081c52014-08-07 19:20:49 +0200297 while (!(Bytetemp & 0x80)) {
Jes Sorensen050abc42014-05-16 10:05:08 +0200298 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
Larry Finger5e93f352014-03-28 21:37:38 -0500299 k++;
Andreas Schlickc5081c52014-08-07 19:20:49 +0200300 if (k == 1000) {
Larry Finger5e93f352014-03-28 21:37:38 -0500301 k = 0;
302 break;
303 }
304 }
Jes Sorensen050abc42014-05-16 10:05:08 +0200305 data = rtl8723au_read8(Adapter, EFUSE_CTRL);
Larry Finger5e93f352014-03-28 21:37:38 -0500306 return data;
307 }
308 else
309 return 0xFF;
310}/* EFUSE_Read1Byte23a */
311
312/*-----------------------------------------------------------------------------
313 * Function: EFUSE_Write1Byte
314 *
315 * Overview: Copy from WMAC fot EFUSE write 1 byte.
316 *
317 * Input: NONE
318 *
319 * Output: NONE
320 *
321 * Return: NONE
322 *
323 * Revised History:
324 * When Who Remark
325 * 09/23/2008 MHC Copy from WMAC.
326 *
327 *---------------------------------------------------------------------------*/
328
329void
330EFUSE_Write1Byte(
331 struct rtw_adapter * Adapter,
332 u16 Address,
333 u8 Value);
334void
335EFUSE_Write1Byte(
336 struct rtw_adapter * Adapter,
337 u16 Address,
338 u8 Value)
339{
340 u8 Bytetemp = {0x00};
341 u8 temp = {0x00};
342 u32 k = 0;
343 u16 contentLen = 0;
344
345 /* RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr =%x Data =%x\n", Address, Value)); */
346 EFUSE_GetEfuseDefinition23a(Adapter, EFUSE_WIFI,
347 TYPE_EFUSE_REAL_CONTENT_LEN,
348 (void *)&contentLen);
349
Andreas Schlickc5081c52014-08-07 19:20:49 +0200350 if (Address < contentLen) { /* E-fuse 512Byte */
Jes Sorensenedbfd672014-05-16 10:05:09 +0200351 rtl8723au_write8(Adapter, EFUSE_CTRL, Value);
Larry Finger5e93f352014-03-28 21:37:38 -0500352
353 /* Write E-fuse Register address bit0~7 */
354 temp = Address & 0xFF;
Jes Sorensenedbfd672014-05-16 10:05:09 +0200355 rtl8723au_write8(Adapter, EFUSE_CTRL+1, temp);
Jes Sorensen050abc42014-05-16 10:05:08 +0200356 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+2);
Larry Finger5e93f352014-03-28 21:37:38 -0500357
358 /* Write E-fuse Register address bit8~9 */
359 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
Jes Sorensenedbfd672014-05-16 10:05:09 +0200360 rtl8723au_write8(Adapter, EFUSE_CTRL+2, temp);
Larry Finger5e93f352014-03-28 21:37:38 -0500361
362 /* Write 0x30[31]= 1 */
Jes Sorensen050abc42014-05-16 10:05:08 +0200363 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
Larry Finger5e93f352014-03-28 21:37:38 -0500364 temp = Bytetemp | 0x80;
Jes Sorensenedbfd672014-05-16 10:05:09 +0200365 rtl8723au_write8(Adapter, EFUSE_CTRL+3, temp);
Larry Finger5e93f352014-03-28 21:37:38 -0500366
367 /* Wait Write-ready (0x30[31]= 0) */
Jes Sorensen050abc42014-05-16 10:05:08 +0200368 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
Andreas Schlickc5081c52014-08-07 19:20:49 +0200369 while (Bytetemp & 0x80) {
Jes Sorensen050abc42014-05-16 10:05:08 +0200370 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
Larry Finger5e93f352014-03-28 21:37:38 -0500371 k++;
Andreas Schlickc5081c52014-08-07 19:20:49 +0200372 if (k == 100) {
Larry Finger5e93f352014-03-28 21:37:38 -0500373 k = 0;
374 break;
375 }
376 }
377 }
378}/* EFUSE_Write1Byte */
379
380/* 11/16/2008 MH Read one byte from real Efuse. */
Jes Sorensen44f3f162014-05-16 10:04:29 +0200381int
Larry Finger5e93f352014-03-28 21:37:38 -0500382efuse_OneByteRead23a(struct rtw_adapter *pAdapter, u16 addr, u8 *data)
383{
384 u8 tmpidx = 0;
Jes Sorensen44f3f162014-05-16 10:04:29 +0200385 int bResult;
Larry Finger5e93f352014-03-28 21:37:38 -0500386
387 /* -----------------e-fuse reg ctrl --------------------------------- */
388 /* address */
Jes Sorensenedbfd672014-05-16 10:05:09 +0200389 rtl8723au_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
390 rtl8723au_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) &0x03)) |
Jes Sorensen050abc42014-05-16 10:05:08 +0200391 (rtl8723au_read8(pAdapter, EFUSE_CTRL+2)&0xFC));
Larry Finger5e93f352014-03-28 21:37:38 -0500392
Jes Sorensenedbfd672014-05-16 10:05:09 +0200393 rtl8723au_write8(pAdapter, EFUSE_CTRL+3, 0x72);/* read cmd */
Larry Finger5e93f352014-03-28 21:37:38 -0500394
Jes Sorensen050abc42014-05-16 10:05:08 +0200395 while(!(0x80 &rtl8723au_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx<100))
Larry Finger5e93f352014-03-28 21:37:38 -0500396 tmpidx++;
397 if (tmpidx < 100) {
Jes Sorensen050abc42014-05-16 10:05:08 +0200398 *data = rtl8723au_read8(pAdapter, EFUSE_CTRL);
Jes Sorensen44f3f162014-05-16 10:04:29 +0200399 bResult = _SUCCESS;
Larry Finger5e93f352014-03-28 21:37:38 -0500400 } else {
401 *data = 0xff;
Jes Sorensen44f3f162014-05-16 10:04:29 +0200402 bResult = _FAIL;
Larry Finger5e93f352014-03-28 21:37:38 -0500403 }
404 return bResult;
405}
406
407/* 11/16/2008 MH Write one byte to reald Efuse. */
Jes Sorensen44f3f162014-05-16 10:04:29 +0200408int
Larry Finger5e93f352014-03-28 21:37:38 -0500409efuse_OneByteWrite23a(struct rtw_adapter *pAdapter, u16 addr, u8 data)
410{
411 u8 tmpidx = 0;
Jes Sorensen44f3f162014-05-16 10:04:29 +0200412 int bResult;
Larry Finger5e93f352014-03-28 21:37:38 -0500413
414 /* RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr = %x Data =%x\n", addr, data)); */
415
416 /* return 0; */
417
418 /* -----------------e-fuse reg ctrl --------------------------------- */
419 /* address */
Jes Sorensenedbfd672014-05-16 10:05:09 +0200420 rtl8723au_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
421 rtl8723au_write8(pAdapter, EFUSE_CTRL+2,
Jes Sorensen050abc42014-05-16 10:05:08 +0200422 (rtl8723au_read8(pAdapter, EFUSE_CTRL+2)&0xFC)|(u8)((addr>>8)&0x03));
Jes Sorensenedbfd672014-05-16 10:05:09 +0200423 rtl8723au_write8(pAdapter, EFUSE_CTRL, data);/* data */
Larry Finger5e93f352014-03-28 21:37:38 -0500424
Jes Sorensenedbfd672014-05-16 10:05:09 +0200425 rtl8723au_write8(pAdapter, EFUSE_CTRL+3, 0xF2);/* write cmd */
Larry Finger5e93f352014-03-28 21:37:38 -0500426
Jes Sorensen050abc42014-05-16 10:05:08 +0200427 while((0x80 & rtl8723au_read8(pAdapter, EFUSE_CTRL+3)) &&
428 (tmpidx<100)) {
Larry Finger5e93f352014-03-28 21:37:38 -0500429 tmpidx++;
430 }
431
Jes Sorensen44f3f162014-05-16 10:04:29 +0200432 if (tmpidx < 100)
433 bResult = _SUCCESS;
Larry Finger5e93f352014-03-28 21:37:38 -0500434 else
Jes Sorensen44f3f162014-05-16 10:04:29 +0200435 bResult = _FAIL;
Larry Finger5e93f352014-03-28 21:37:38 -0500436
437 return bResult;
438}
439
Larry Finger5e93f352014-03-28 21:37:38 -0500440/*-----------------------------------------------------------------------------
441 * Function: efuse_WordEnableDataRead23a
442 *
443 * Overview: Read allowed word in current efuse section data.
444 *
445 * Input: NONE
446 *
447 * Output: NONE
448 *
449 * Return: NONE
450 *
451 * Revised History:
452 * When Who Remark
453 * 11/16/2008 MHC Create Version 0.
454 * 11/21/2008 MHC Fix Write bug when we only enable late word.
455 *
456 *---------------------------------------------------------------------------*/
457void
458efuse_WordEnableDataRead23a(u8 word_en,
459 u8 *sourdata,
460 u8 *targetdata)
461{
Andreas Schlickc5081c52014-08-07 19:20:49 +0200462 if (!(word_en&BIT(0))) {
Larry Finger5e93f352014-03-28 21:37:38 -0500463 targetdata[0] = sourdata[0];
464 targetdata[1] = sourdata[1];
465 }
Andreas Schlickc5081c52014-08-07 19:20:49 +0200466 if (!(word_en&BIT(1))) {
Larry Finger5e93f352014-03-28 21:37:38 -0500467 targetdata[2] = sourdata[2];
468 targetdata[3] = sourdata[3];
469 }
Andreas Schlickc5081c52014-08-07 19:20:49 +0200470 if (!(word_en&BIT(2))) {
Larry Finger5e93f352014-03-28 21:37:38 -0500471 targetdata[4] = sourdata[4];
472 targetdata[5] = sourdata[5];
473 }
Andreas Schlickc5081c52014-08-07 19:20:49 +0200474 if (!(word_en&BIT(3))) {
Larry Finger5e93f352014-03-28 21:37:38 -0500475 targetdata[6] = sourdata[6];
476 targetdata[7] = sourdata[7];
477 }
478}
479
Jes Sorensen44f3f162014-05-16 10:04:29 +0200480static int efuse_read8(struct rtw_adapter *padapter, u16 address, u8 *value)
Larry Finger5e93f352014-03-28 21:37:38 -0500481{
482 return efuse_OneByteRead23a(padapter, address, value);
483}
484
Jes Sorensen44f3f162014-05-16 10:04:29 +0200485static int efuse_write8(struct rtw_adapter *padapter, u16 address, u8 *value)
Larry Finger5e93f352014-03-28 21:37:38 -0500486{
487 return efuse_OneByteWrite23a(padapter, address, *value);
488}
489
490/*
Masanari Iida808bcb42014-07-22 23:42:53 +0900491 * read/write raw efuse data
Larry Finger5e93f352014-03-28 21:37:38 -0500492 */
Jes Sorensen44f3f162014-05-16 10:04:29 +0200493int rtw_efuse_access23a(struct rtw_adapter *padapter, u8 bWrite, u16 start_addr,
494 u16 cnts, u8 *data)
Larry Finger5e93f352014-03-28 21:37:38 -0500495{
496 int i = 0;
Jes Sorensen44f3f162014-05-16 10:04:29 +0200497 u16 real_content_len = 0, max_available_size = 0;
498 int res = _FAIL ;
499 int (*rw8)(struct rtw_adapter *, u16, u8*);
Larry Finger5e93f352014-03-28 21:37:38 -0500500
501 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
502 TYPE_EFUSE_REAL_CONTENT_LEN,
503 (void *)&real_content_len);
504 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
505 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL,
506 (void *)&max_available_size);
507
508 if (start_addr > real_content_len)
509 return _FAIL;
510
511 if (true == bWrite) {
512 if ((start_addr + cnts) > max_available_size)
513 return _FAIL;
514 rw8 = &efuse_write8;
515 } else
516 rw8 = &efuse_read8;
517
Jes Sorensenb2e68042014-05-16 10:04:14 +0200518 Efuse_PowerSwitch(padapter, bWrite, true);
Larry Finger5e93f352014-03-28 21:37:38 -0500519
520 /* e-fuse one byte read / write */
521 for (i = 0; i < cnts; i++) {
522 if (start_addr >= real_content_len) {
523 res = _FAIL;
524 break;
525 }
526
527 res = rw8(padapter, start_addr++, data++);
Jes Sorensen44f3f162014-05-16 10:04:29 +0200528 if (res == _FAIL)
529 break;
Larry Finger5e93f352014-03-28 21:37:38 -0500530 }
531
Jes Sorensenb2e68042014-05-16 10:04:14 +0200532 Efuse_PowerSwitch(padapter, bWrite, false);
Larry Finger5e93f352014-03-28 21:37:38 -0500533
534 return res;
535}
536/* */
537u16 efuse_GetMaxSize23a(struct rtw_adapter *padapter)
538{
Jes Sorensen44f3f162014-05-16 10:04:29 +0200539 u16 max_size;
Larry Finger5e93f352014-03-28 21:37:38 -0500540 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
541 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL,
542 (void *)&max_size);
543 return max_size;
544}
545/* */
Jes Sorensen44f3f162014-05-16 10:04:29 +0200546int rtw_efuse_map_read23a(struct rtw_adapter *padapter,
547 u16 addr, u16 cnts, u8 *data)
Larry Finger5e93f352014-03-28 21:37:38 -0500548{
Jes Sorensen44f3f162014-05-16 10:04:29 +0200549 u16 mapLen = 0;
Larry Finger5e93f352014-03-28 21:37:38 -0500550
551 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
552 TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
553
554 if ((addr + cnts) > mapLen)
555 return _FAIL;
556
Jes Sorensenb2e68042014-05-16 10:04:14 +0200557 Efuse_PowerSwitch(padapter, false, true);
Larry Finger5e93f352014-03-28 21:37:38 -0500558
Jes Sorensenb2e68042014-05-16 10:04:14 +0200559 rtl8723a_readefuse(padapter, EFUSE_WIFI, addr, cnts, data);
Larry Finger5e93f352014-03-28 21:37:38 -0500560
Jes Sorensenb2e68042014-05-16 10:04:14 +0200561 Efuse_PowerSwitch(padapter, false, false);
Larry Finger5e93f352014-03-28 21:37:38 -0500562
563 return _SUCCESS;
564}
565
Jes Sorensen44f3f162014-05-16 10:04:29 +0200566int rtw_BT_efuse_map_read23a(struct rtw_adapter *padapter,
567 u16 addr, u16 cnts, u8 *data)
Larry Finger5e93f352014-03-28 21:37:38 -0500568{
Jes Sorensen44f3f162014-05-16 10:04:29 +0200569 u16 mapLen = 0;
Larry Finger5e93f352014-03-28 21:37:38 -0500570
571 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
572 TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
573
574 if ((addr + cnts) > mapLen)
575 return _FAIL;
576
Jes Sorensenb2e68042014-05-16 10:04:14 +0200577 Efuse_PowerSwitch(padapter, false, true);
Larry Finger5e93f352014-03-28 21:37:38 -0500578
Jes Sorensenb2e68042014-05-16 10:04:14 +0200579 rtl8723a_readefuse(padapter, EFUSE_BT, addr, cnts, data);
Larry Finger5e93f352014-03-28 21:37:38 -0500580
Jes Sorensenb2e68042014-05-16 10:04:14 +0200581 Efuse_PowerSwitch(padapter, false, false);
Larry Finger5e93f352014-03-28 21:37:38 -0500582
583 return _SUCCESS;
584}
585
586/*-----------------------------------------------------------------------------
587 * Function: Efuse_ReadAllMap
588 *
589 * Overview: Read All Efuse content
590 *
591 * Input: NONE
592 *
593 * Output: NONE
594 *
595 * Return: NONE
596 *
597 * Revised History:
598 * When Who Remark
599 * 11/11/2008 MHC Create Version 0.
600 *
601 *---------------------------------------------------------------------------*/
602void
603Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType, u8 *Efuse);
604void
605Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType, u8 *Efuse)
606{
607 u16 mapLen = 0;
608
Jes Sorensenb2e68042014-05-16 10:04:14 +0200609 Efuse_PowerSwitch(pAdapter, false, true);
Larry Finger5e93f352014-03-28 21:37:38 -0500610
611 EFUSE_GetEfuseDefinition23a(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN,
612 (void *)&mapLen);
613
Jes Sorensenb2e68042014-05-16 10:04:14 +0200614 rtl8723a_readefuse(pAdapter, efuseType, 0, mapLen, Efuse);
Larry Finger5e93f352014-03-28 21:37:38 -0500615
Jes Sorensenb2e68042014-05-16 10:04:14 +0200616 Efuse_PowerSwitch(pAdapter, false, false);
Larry Finger5e93f352014-03-28 21:37:38 -0500617}
618
619/*-----------------------------------------------------------------------------
620 * Function: efuse_ShadowRead1Byte
621 * efuse_ShadowRead2Byte
622 * efuse_ShadowRead4Byte
623 *
624 * Overview: Read from efuse init map by one/two/four bytes !!!!!
625 *
626 * Input: NONE
627 *
628 * Output: NONE
629 *
630 * Return: NONE
631 *
632 * Revised History:
633 * When Who Remark
634 * 11/12/2008 MHC Create Version 0.
635 *
636 *---------------------------------------------------------------------------*/
637static void
638efuse_ShadowRead1Byte(
639 struct rtw_adapter * pAdapter,
640 u16 Offset,
641 u8 *Value)
642{
643 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
644
645 *Value = pEEPROM->efuse_eeprom_data[Offset];
646} /* EFUSE_ShadowRead23a1Byte */
647
648/* Read Two Bytes */
649static void
650efuse_ShadowRead2Byte(
651 struct rtw_adapter * pAdapter,
652 u16 Offset,
653 u16 *Value)
654{
655 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
656
657 *Value = pEEPROM->efuse_eeprom_data[Offset];
658 *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
659} /* EFUSE_ShadowRead23a2Byte */
660
661/* Read Four Bytes */
662static void
663efuse_ShadowRead4Byte(
664 struct rtw_adapter * pAdapter,
665 u16 Offset,
666 u32 *Value)
667{
668 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
669
670 *Value = pEEPROM->efuse_eeprom_data[Offset];
671 *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
672 *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
673 *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
674} /* efuse_ShadowRead4Byte */
675
676/*-----------------------------------------------------------------------------
677 * Function: EFUSE_ShadowMapUpdate23a
678 *
679 * Overview: Transfer current EFUSE content to shadow init and modify map.
680 *
681 * Input: NONE
682 *
683 * Output: NONE
684 *
685 * Return: NONE
686 *
687 * Revised History:
688 * When Who Remark
689 * 11/13/2008 MHC Create Version 0.
690 *
691 *---------------------------------------------------------------------------*/
692void EFUSE_ShadowMapUpdate23a(struct rtw_adapter *pAdapter, u8 efuseType)
693{
694 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
695 u16 mapLen = 0;
696
697 EFUSE_GetEfuseDefinition23a(pAdapter, efuseType,
698 TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
699
700 if (pEEPROM->bautoload_fail_flag == true)
701 memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
702 else
703 Efuse_ReadAllMap(pAdapter, efuseType,
704 pEEPROM->efuse_eeprom_data);
705
706}/* EFUSE_ShadowMapUpdate23a */
707
708/*-----------------------------------------------------------------------------
709 * Function: EFUSE_ShadowRead23a
710 *
711 * Overview: Read from efuse init map !!!!!
712 *
713 * Input: NONE
714 *
715 * Output: NONE
716 *
717 * Return: NONE
718 *
719 * Revised History:
720 * When Who Remark
721 * 11/12/2008 MHC Create Version 0.
722 *
723 *---------------------------------------------------------------------------*/
724void
725EFUSE_ShadowRead23a(
726 struct rtw_adapter * pAdapter,
727 u8 Type,
728 u16 Offset,
Greg Donald1beda8d2014-08-22 12:58:13 -0500729 u32 *Value)
Larry Finger5e93f352014-03-28 21:37:38 -0500730{
731 if (Type == 1)
732 efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
733 else if (Type == 2)
734 efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);
735 else if (Type == 4)
736 efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);
737} /* EFUSE_ShadowRead23a */