0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #define _RTL871X_EEPROM_C_
0018
0019 #include "osdep_service.h"
0020 #include "drv_types.h"
0021
0022 static void up_clk(struct _adapter *padapter, u16 *x)
0023 {
0024 *x = *x | _EESK;
0025 r8712_write8(padapter, EE_9346CR, (u8)*x);
0026 udelay(CLOCK_RATE);
0027 }
0028
0029 static void down_clk(struct _adapter *padapter, u16 *x)
0030 {
0031 *x = *x & ~_EESK;
0032 r8712_write8(padapter, EE_9346CR, (u8)*x);
0033 udelay(CLOCK_RATE);
0034 }
0035
0036 static void shift_out_bits(struct _adapter *padapter, u16 data, u16 count)
0037 {
0038 u16 x, mask;
0039
0040 if (padapter->surprise_removed)
0041 goto out;
0042 mask = 0x01 << (count - 1);
0043 x = r8712_read8(padapter, EE_9346CR);
0044 x &= ~(_EEDO | _EEDI);
0045 do {
0046 x &= ~_EEDI;
0047 if (data & mask)
0048 x |= _EEDI;
0049 if (padapter->surprise_removed)
0050 goto out;
0051 r8712_write8(padapter, EE_9346CR, (u8)x);
0052 udelay(CLOCK_RATE);
0053 up_clk(padapter, &x);
0054 down_clk(padapter, &x);
0055 mask >>= 1;
0056 } while (mask);
0057 if (padapter->surprise_removed)
0058 goto out;
0059 x &= ~_EEDI;
0060 r8712_write8(padapter, EE_9346CR, (u8)x);
0061 out:;
0062 }
0063
0064 static u16 shift_in_bits(struct _adapter *padapter)
0065 {
0066 u16 x, d = 0, i;
0067
0068 if (padapter->surprise_removed)
0069 goto out;
0070 x = r8712_read8(padapter, EE_9346CR);
0071 x &= ~(_EEDO | _EEDI);
0072 d = 0;
0073 for (i = 0; i < 16; i++) {
0074 d <<= 1;
0075 up_clk(padapter, &x);
0076 if (padapter->surprise_removed)
0077 goto out;
0078 x = r8712_read8(padapter, EE_9346CR);
0079 x &= ~(_EEDI);
0080 if (x & _EEDO)
0081 d |= 1;
0082 down_clk(padapter, &x);
0083 }
0084 out:
0085 return d;
0086 }
0087
0088 static void standby(struct _adapter *padapter)
0089 {
0090 u8 x;
0091
0092 x = r8712_read8(padapter, EE_9346CR);
0093 x &= ~(_EECS | _EESK);
0094 r8712_write8(padapter, EE_9346CR, x);
0095 udelay(CLOCK_RATE);
0096 x |= _EECS;
0097 r8712_write8(padapter, EE_9346CR, x);
0098 udelay(CLOCK_RATE);
0099 }
0100
0101 static u16 wait_eeprom_cmd_done(struct _adapter *padapter)
0102 {
0103 u8 x;
0104 u16 i;
0105
0106 standby(padapter);
0107 for (i = 0; i < 200; i++) {
0108 x = r8712_read8(padapter, EE_9346CR);
0109 if (x & _EEDO)
0110 return true;
0111 udelay(CLOCK_RATE);
0112 }
0113 return false;
0114 }
0115
0116 static void eeprom_clean(struct _adapter *padapter)
0117 {
0118 u16 x;
0119
0120 if (padapter->surprise_removed)
0121 return;
0122 x = r8712_read8(padapter, EE_9346CR);
0123 if (padapter->surprise_removed)
0124 return;
0125 x &= ~(_EECS | _EEDI);
0126 r8712_write8(padapter, EE_9346CR, (u8)x);
0127 if (padapter->surprise_removed)
0128 return;
0129 up_clk(padapter, &x);
0130 if (padapter->surprise_removed)
0131 return;
0132 down_clk(padapter, &x);
0133 }
0134
0135 void r8712_eeprom_write16(struct _adapter *padapter, u16 reg, u16 data)
0136 {
0137 u8 x;
0138 u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new;
0139
0140 tmp8_ori = r8712_read8(padapter, 0x102502f1);
0141 tmp8_new = tmp8_ori & 0xf7;
0142 if (tmp8_ori != tmp8_new)
0143 r8712_write8(padapter, 0x102502f1, tmp8_new);
0144 tmp8_clk_ori = r8712_read8(padapter, 0x10250003);
0145 tmp8_clk_new = tmp8_clk_ori | 0x20;
0146 if (tmp8_clk_new != tmp8_clk_ori)
0147 r8712_write8(padapter, 0x10250003, tmp8_clk_new);
0148 x = r8712_read8(padapter, EE_9346CR);
0149 x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
0150 x |= _EEM1 | _EECS;
0151 r8712_write8(padapter, EE_9346CR, x);
0152 shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5);
0153 if (padapter->eeprom_address_size == 8)
0154 shift_out_bits(padapter, 0, 6);
0155 else
0156 shift_out_bits(padapter, 0, 4);
0157 standby(padapter);
0158
0159
0160
0161
0162 standby(padapter);
0163
0164
0165
0166 shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3);
0167
0168 shift_out_bits(padapter, reg, padapter->eeprom_address_size);
0169
0170 shift_out_bits(padapter, data, 16);
0171 if (wait_eeprom_cmd_done(padapter)) {
0172 standby(padapter);
0173 shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5);
0174 shift_out_bits(padapter, reg, 4);
0175 eeprom_clean(padapter);
0176 }
0177 if (tmp8_clk_new != tmp8_clk_ori)
0178 r8712_write8(padapter, 0x10250003, tmp8_clk_ori);
0179 if (tmp8_new != tmp8_ori)
0180 r8712_write8(padapter, 0x102502f1, tmp8_ori);
0181 }
0182
0183 u16 r8712_eeprom_read16(struct _adapter *padapter, u16 reg)
0184 {
0185 u16 x;
0186 u16 data = 0;
0187 u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new;
0188
0189 tmp8_ori = r8712_read8(padapter, 0x102502f1);
0190 tmp8_new = tmp8_ori & 0xf7;
0191 if (tmp8_ori != tmp8_new)
0192 r8712_write8(padapter, 0x102502f1, tmp8_new);
0193 tmp8_clk_ori = r8712_read8(padapter, 0x10250003);
0194 tmp8_clk_new = tmp8_clk_ori | 0x20;
0195 if (tmp8_clk_new != tmp8_clk_ori)
0196 r8712_write8(padapter, 0x10250003, tmp8_clk_new);
0197 if (padapter->surprise_removed)
0198 goto out;
0199
0200 x = r8712_read8(padapter, EE_9346CR);
0201 if (padapter->surprise_removed)
0202 goto out;
0203 x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
0204 x |= _EEM1 | _EECS;
0205 r8712_write8(padapter, EE_9346CR, (unsigned char)x);
0206
0207
0208
0209 shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
0210 shift_out_bits(padapter, reg, padapter->eeprom_address_size);
0211
0212 data = shift_in_bits(padapter);
0213 eeprom_clean(padapter);
0214 out:
0215 if (tmp8_clk_new != tmp8_clk_ori)
0216 r8712_write8(padapter, 0x10250003, tmp8_clk_ori);
0217 if (tmp8_new != tmp8_ori)
0218 r8712_write8(padapter, 0x102502f1, tmp8_ori);
0219 return data;
0220 }