1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
6 ******************************************************************************/
10 #include <osdep_service.h>
11 #include <drv_types.h>
13 void up_clk(_adapter *padapter, u16 *x)
17 rtw_write8(padapter, EE_9346CR, (u8)*x);
24 void down_clk(_adapter *padapter, u16 *x)
28 rtw_write8(padapter, EE_9346CR, (u8)*x);
33 void shift_out_bits(_adapter *padapter, u16 data, u16 count)
38 if (padapter->bSurpriseRemoved == true) {
39 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
42 mask = 0x01 << (count - 1);
43 x = rtw_read8(padapter, EE_9346CR);
45 x &= ~(_EEDO | _EEDI);
51 if (padapter->bSurpriseRemoved == true) {
52 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
55 rtw_write8(padapter, EE_9346CR, (u8)x);
58 down_clk(padapter, &x);
61 if (padapter->bSurpriseRemoved == true) {
62 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
66 rtw_write8(padapter, EE_9346CR, (u8)x);
71 u16 shift_in_bits(_adapter *padapter)
75 if (padapter->bSurpriseRemoved == true) {
76 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
79 x = rtw_read8(padapter, EE_9346CR);
81 x &= ~(_EEDO | _EEDI);
84 for (i = 0; i < 16; i++) {
87 if (padapter->bSurpriseRemoved == true) {
88 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
91 x = rtw_read8(padapter, EE_9346CR);
97 down_clk(padapter, &x);
105 void standby(_adapter *padapter)
109 x = rtw_read8(padapter, EE_9346CR);
111 x &= ~(_EECS | _EESK);
112 rtw_write8(padapter, EE_9346CR, x);
116 rtw_write8(padapter, EE_9346CR, x);
121 u16 wait_eeprom_cmd_done(_adapter *padapter)
127 for (i = 0; i < 200; i++) {
128 x = rtw_read8(padapter, EE_9346CR);
140 void eeprom_clean(_adapter *padapter)
144 if (padapter->bSurpriseRemoved == true) {
145 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
148 x = rtw_read8(padapter, EE_9346CR);
149 if (padapter->bSurpriseRemoved == true) {
150 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
153 x &= ~(_EECS | _EEDI);
154 rtw_write8(padapter, EE_9346CR, (u8)x);
155 if (padapter->bSurpriseRemoved == true) {
156 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
159 up_clk(padapter, &x);
160 if (padapter->bSurpriseRemoved == true) {
161 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
164 down_clk(padapter, &x);
169 void eeprom_write16(_adapter *padapter, u16 reg, u16 data)
175 x = rtw_read8(padapter, EE_9346CR);
177 x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
179 rtw_write8(padapter, EE_9346CR, x);
181 shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5);
183 if (padapter->EepromAddressSize == 8) /*CF+ and SDIO*/
184 shift_out_bits(padapter, 0, 6);
186 shift_out_bits(padapter, 0, 4);
190 /* Commented out by rcnjko, 2004.0
191 * Erase this particular word. Write the erase opcode and register
192 * number in that order. The opcode is 3bits in length; reg is 6 bits long.
193 * shift_out_bits(Adapter, EEPROM_ERASE_OPCODE, 3);
194 * shift_out_bits(Adapter, reg, Adapter->EepromAddressSize);
196 * if (wait_eeprom_cmd_done(Adapter ) == false)
204 /* write the new word to the EEPROM*/
206 /* send the write opcode the EEPORM*/
207 shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3);
209 /* select which word in the EEPROM that we are writing to.*/
210 shift_out_bits(padapter, reg, padapter->EepromAddressSize);
212 /* write the data to the selected EEPROM word.*/
213 shift_out_bits(padapter, data, 16);
215 if (wait_eeprom_cmd_done(padapter) == false) {
222 shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5);
223 shift_out_bits(padapter, reg, 4);
225 eeprom_clean(padapter);
231 u16 eeprom_read16(_adapter *padapter, u16 reg) /*ReadEEprom*/
239 if (padapter->bSurpriseRemoved == true) {
240 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
243 /* select EEPROM, reset bits, set _EECS*/
244 x = rtw_read8(padapter, EE_9346CR);
246 if (padapter->bSurpriseRemoved == true) {
247 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
251 x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
253 rtw_write8(padapter, EE_9346CR, (unsigned char)x);
255 /* write the read opcode and register number in that order*/
256 /* The opcode is 3bits in length, reg is 6 bits long*/
257 shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
258 shift_out_bits(padapter, reg, padapter->EepromAddressSize);
260 /* Now read the data (16 bits) in from the selected EEPROM word*/
261 data = shift_in_bits(padapter);
263 eeprom_clean(padapter);
275 void eeprom_read_sz(_adapter *padapter, u16 reg, u8 *data, u32 sz)
281 if (padapter->bSurpriseRemoved == true) {
282 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
285 /* select EEPROM, reset bits, set _EECS*/
286 x = rtw_read8(padapter, EE_9346CR);
288 if (padapter->bSurpriseRemoved == true) {
289 RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
293 x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
295 rtw_write8(padapter, EE_9346CR, (unsigned char)x);
297 /* write the read opcode and register number in that order*/
298 /* The opcode is 3bits in length, reg is 6 bits long*/
299 shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
300 shift_out_bits(padapter, reg, padapter->EepromAddressSize);
303 for (i = 0; i < sz; i += 2) {
304 data16 = shift_in_bits(padapter);
305 data[i] = data16 & 0xff;
306 data[i+1] = data16 >> 8;
309 eeprom_clean(padapter);
318 /*addr_off : address offset of the entry in eeprom (not the tuple number of eeprom (reg); that is addr_off !=reg)*/
319 u8 eeprom_read(_adapter *padapter, u32 addr_off, u8 sz, u8 *rbuf)
321 u8 quotient, remainder, addr_2align_odd;
322 u16 reg, stmp, i = 0, idx = 0;
324 reg = (u16)(addr_off >> 1);
325 addr_2align_odd = (u8)(addr_off & 0x1);
327 /*read that start at high part: e.g 1,3,5,7,9,...*/
328 if (addr_2align_odd) {
329 stmp = eeprom_read16(padapter, reg);
330 rbuf[idx++] = (u8) ((stmp>>8)&0xff); /*return hogh-part of the short*/
335 remainder = sz & 0x1;
337 for (i = 0; i < quotient; i++) {
338 stmp = eeprom_read16(padapter, reg+i);
339 rbuf[idx++] = (u8) (stmp&0xff);
340 rbuf[idx++] = (u8) ((stmp>>8)&0xff);
344 if (remainder) { /*end of read at lower part of short : 0,2,4,6,...*/
345 stmp = eeprom_read16(padapter, reg);
346 rbuf[idx] = (u8)(stmp & 0xff);
354 void read_eeprom_content(_adapter *padapter)