Blame view
drivers/staging/rtl8712/rtl871x_eeprom.c
5.68 KB
e24c1f865 staging: rtl8712:... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
2865d42c7 staging: r8712u: ... |
2 3 4 5 6 7 |
/****************************************************************************** * rtl871x_eeprom.c * * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. * Linux device driver for RTL8192SU * |
2865d42c7 staging: r8712u: ... |
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
* Modifications for inclusion into the Linux staging tree are * Copyright(c) 2010 Larry Finger. All rights reserved. * * Contact information: * WLAN FAE <wlanfae@realtek.com> * Larry Finger <Larry.Finger@lwfinger.net> * ******************************************************************************/ #define _RTL871X_EEPROM_C_ #include "osdep_service.h" #include "drv_types.h" static void up_clk(struct _adapter *padapter, u16 *x) { *x = *x | _EESK; r8712_write8(padapter, EE_9346CR, (u8)*x); udelay(CLOCK_RATE); } static void down_clk(struct _adapter *padapter, u16 *x) { *x = *x & ~_EESK; r8712_write8(padapter, EE_9346CR, (u8)*x); udelay(CLOCK_RATE); } static void shift_out_bits(struct _adapter *padapter, u16 data, u16 count) { u16 x, mask; |
5b8d98f17 staging: rtl8712:... |
39 |
if (padapter->surprise_removed) |
2865d42c7 staging: r8712u: ... |
40 41 42 43 44 45 46 47 |
goto out; mask = 0x01 << (count - 1); x = r8712_read8(padapter, EE_9346CR); x &= ~(_EEDO | _EEDI); do { x &= ~_EEDI; if (data & mask) x |= _EEDI; |
5b8d98f17 staging: rtl8712:... |
48 |
if (padapter->surprise_removed) |
2865d42c7 staging: r8712u: ... |
49 50 51 52 53 |
goto out; r8712_write8(padapter, EE_9346CR, (u8)x); udelay(CLOCK_RATE); up_clk(padapter, &x); down_clk(padapter, &x); |
bc5b749a4 staging: rtl8712:... |
54 |
mask >>= 1; |
2865d42c7 staging: r8712u: ... |
55 |
} while (mask); |
5b8d98f17 staging: rtl8712:... |
56 |
if (padapter->surprise_removed) |
2865d42c7 staging: r8712u: ... |
57 58 59 60 61 62 63 64 65 |
goto out; x &= ~_EEDI; r8712_write8(padapter, EE_9346CR, (u8)x); out:; } static u16 shift_in_bits(struct _adapter *padapter) { u16 x, d = 0, i; |
5b8d98f17 staging: rtl8712:... |
66 |
if (padapter->surprise_removed) |
2865d42c7 staging: r8712u: ... |
67 68 69 70 71 |
goto out; x = r8712_read8(padapter, EE_9346CR); x &= ~(_EEDO | _EEDI); d = 0; for (i = 0; i < 16; i++) { |
bc5b749a4 staging: rtl8712:... |
72 |
d <<= 1; |
2865d42c7 staging: r8712u: ... |
73 |
up_clk(padapter, &x); |
5b8d98f17 staging: rtl8712:... |
74 |
if (padapter->surprise_removed) |
2865d42c7 staging: r8712u: ... |
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
goto out; x = r8712_read8(padapter, EE_9346CR); x &= ~(_EEDI); if (x & _EEDO) d |= 1; down_clk(padapter, &x); } out: return d; } static void standby(struct _adapter *padapter) { u8 x; x = r8712_read8(padapter, EE_9346CR); x &= ~(_EECS | _EESK); r8712_write8(padapter, EE_9346CR, x); udelay(CLOCK_RATE); x |= _EECS; r8712_write8(padapter, EE_9346CR, x); udelay(CLOCK_RATE); } static u16 wait_eeprom_cmd_done(struct _adapter *padapter) { u8 x; u16 i; standby(padapter); for (i = 0; i < 200; i++) { x = r8712_read8(padapter, EE_9346CR); if (x & _EEDO) return true; udelay(CLOCK_RATE); } return false; } static void eeprom_clean(struct _adapter *padapter) { u16 x; |
5b8d98f17 staging: rtl8712:... |
117 |
if (padapter->surprise_removed) |
2865d42c7 staging: r8712u: ... |
118 119 |
return; x = r8712_read8(padapter, EE_9346CR); |
5b8d98f17 staging: rtl8712:... |
120 |
if (padapter->surprise_removed) |
2865d42c7 staging: r8712u: ... |
121 122 123 |
return; x &= ~(_EECS | _EEDI); r8712_write8(padapter, EE_9346CR, (u8)x); |
5b8d98f17 staging: rtl8712:... |
124 |
if (padapter->surprise_removed) |
2865d42c7 staging: r8712u: ... |
125 126 |
return; up_clk(padapter, &x); |
5b8d98f17 staging: rtl8712:... |
127 |
if (padapter->surprise_removed) |
2865d42c7 staging: r8712u: ... |
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
return; down_clk(padapter, &x); } void r8712_eeprom_write16(struct _adapter *padapter, u16 reg, u16 data) { u8 x; u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new; tmp8_ori = r8712_read8(padapter, 0x102502f1); tmp8_new = tmp8_ori & 0xf7; if (tmp8_ori != tmp8_new) r8712_write8(padapter, 0x102502f1, tmp8_new); tmp8_clk_ori = r8712_read8(padapter, 0x10250003); tmp8_clk_new = tmp8_clk_ori | 0x20; if (tmp8_clk_new != tmp8_clk_ori) r8712_write8(padapter, 0x10250003, tmp8_clk_new); x = r8712_read8(padapter, EE_9346CR); x &= ~(_EEDI | _EEDO | _EESK | _EEM0); x |= _EEM1 | _EECS; r8712_write8(padapter, EE_9346CR, x); shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5); |
906ad742f staging: rtl8712:... |
150 |
if (padapter->eeprom_address_size == 8) /*CF+ and SDIO*/ |
2865d42c7 staging: r8712u: ... |
151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
shift_out_bits(padapter, 0, 6); else /* USB */ shift_out_bits(padapter, 0, 4); standby(padapter); /* Erase this particular word. Write the erase opcode and register * number in that order. The opcode is 3bits in length; reg is 6 * bits long. */ standby(padapter); /* write the new word to the EEPROM * send the write opcode the EEPORM */ shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3); /* select which word in the EEPROM that we are writing to. */ |
906ad742f staging: rtl8712:... |
165 |
shift_out_bits(padapter, reg, padapter->eeprom_address_size); |
2865d42c7 staging: r8712u: ... |
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
/* write the data to the selected EEPROM word. */ shift_out_bits(padapter, data, 16); if (wait_eeprom_cmd_done(padapter)) { standby(padapter); shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5); shift_out_bits(padapter, reg, 4); eeprom_clean(padapter); } if (tmp8_clk_new != tmp8_clk_ori) r8712_write8(padapter, 0x10250003, tmp8_clk_ori); if (tmp8_new != tmp8_ori) r8712_write8(padapter, 0x102502f1, tmp8_ori); } u16 r8712_eeprom_read16(struct _adapter *padapter, u16 reg) /*ReadEEprom*/ { u16 x; u16 data = 0; u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new; tmp8_ori = r8712_read8(padapter, 0x102502f1); tmp8_new = tmp8_ori & 0xf7; if (tmp8_ori != tmp8_new) r8712_write8(padapter, 0x102502f1, tmp8_new); tmp8_clk_ori = r8712_read8(padapter, 0x10250003); tmp8_clk_new = tmp8_clk_ori | 0x20; if (tmp8_clk_new != tmp8_clk_ori) r8712_write8(padapter, 0x10250003, tmp8_clk_new); |
5b8d98f17 staging: rtl8712:... |
194 |
if (padapter->surprise_removed) |
2865d42c7 staging: r8712u: ... |
195 196 197 |
goto out; /* select EEPROM, reset bits, set _EECS */ x = r8712_read8(padapter, EE_9346CR); |
5b8d98f17 staging: rtl8712:... |
198 |
if (padapter->surprise_removed) |
2865d42c7 staging: r8712u: ... |
199 200 201 202 203 204 205 206 |
goto out; x &= ~(_EEDI | _EEDO | _EESK | _EEM0); x |= _EEM1 | _EECS; r8712_write8(padapter, EE_9346CR, (unsigned char)x); /* write the read opcode and register number in that order * The opcode is 3bits in length, reg is 6 bits long */ shift_out_bits(padapter, EEPROM_READ_OPCODE, 3); |
906ad742f staging: rtl8712:... |
207 |
shift_out_bits(padapter, reg, padapter->eeprom_address_size); |
2865d42c7 staging: r8712u: ... |
208 209 210 211 212 213 214 215 216 217 |
/* Now read the data (16 bits) in from the selected EEPROM word */ data = shift_in_bits(padapter); eeprom_clean(padapter); out: if (tmp8_clk_new != tmp8_clk_ori) r8712_write8(padapter, 0x10250003, tmp8_clk_ori); if (tmp8_new != tmp8_ori) r8712_write8(padapter, 0x102502f1, tmp8_ori); return data; } |