3 Copyright (C) 2001-2011 Neil Cafferkey
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 #include "radio_protos.h"
26 #include "eeprom_protos.h"
27 #include "timer_protos.h"
28 #include "realtek8187.h"
31 static UBYTE
GetPowerPair(struct DevUnit
*unit
, UWORD index
,
32 struct DevBase
*base
);
33 static VOID
WritePHY(struct DevUnit
*unit
, UWORD index
, ULONG value
,
34 struct DevBase
*base
);
37 static const UWORD gain_table
[] =
39 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
40 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
41 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
42 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
43 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
44 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
45 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
46 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
47 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
48 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
49 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
50 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
54 static const UBYTE agc_table
[] =
56 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57,
57 0x55, 0x53, 0x51, 0x4f, 0x4d, 0x4b, 0x49, 0x47,
58 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
59 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27,
60 0x25, 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17,
61 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
62 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
63 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
64 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
65 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
66 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
67 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
68 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f,
69 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
70 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
71 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
75 static const UBYTE ofdm_table
[] =
77 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
78 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
79 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
80 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
81 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
82 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
83 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
84 0x6d, 0x3c, 0xfb, 0x07
87 #if !defined(__AROS__)
88 static const UBYTE cck_power_table1
[] =
90 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
94 static const UBYTE cck_power_table2
[] =
96 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
100 static UBYTE rtl8225_power_tables
[][8] =
102 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
103 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
104 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
105 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
106 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
107 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
108 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
109 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}
113 static UBYTE rtl8225_ch14_power_tables
[][8] =
115 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
116 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
117 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
118 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
119 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
120 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
121 {0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00},
122 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}
126 static UBYTE rtl8225_ofdm_power
[] = {0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4};
129 static const UBYTE eeprom_power_locations_l
[] =
131 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x7a, 0x7b,
132 0x7c, 0x7d, 0x36, 0x37, 0x38, 0x39
136 static const UBYTE eeprom_power_locations_b
[] =
138 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x7a, 0x7b,
139 0x7c, 0x7d, 0x36, 0x14, 0x38, 0x39
143 /****i* realtek8180.device/InitialiseRadio *********************************
149 * success = InitialiseRadio(unit, reinsertion)
151 * BOOL InitialiseRadio(struct DevUnit *, BOOL);
160 * success - Success indicator.
162 ****************************************************************************
166 BOOL
InitialiseRadio(struct DevUnit
*unit
, struct DevBase
*base
)
171 /* Get radio revision */
173 if((LEWord(ReadEEPROM(unit
, R8180ROM_RFCHIPID
, base
)) & 0xff) == 5)
175 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
, 0x80);
176 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSSELECT
, 0x80);
177 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSENABLE
, 0x80);
178 BusyMilliDelay(500, base
);
180 WriteRadio(unit
, 0x0, 0x1b7, base
);
182 if(ReadRadio(unit
, 0x8, base
) != 0x588 ||
183 ReadRadio(unit
, 0x9, base
) != 0x700)
184 unit
->radio_type
= RTL8225_RADIO
;
186 unit
->radio_type
= RTL8225V2_RADIO
;
187 WriteRadio(unit
, 0x0, 0xb7, base
);
190 unit
->radio_type
= RTL8225V2B_RADIO
;
192 /* Initialise radio */
194 WriteRadio(unit
, 0x0, 0xb7, base
);
195 WriteRadio(unit
, 0x1, 0xee0, base
);
196 WriteRadio(unit
, 0x2, 0x44d, base
);
197 WriteRadio(unit
, 0x3, 0x441, base
);
198 WriteRadio(unit
, 0x4, 0x8c3, base
);
199 WriteRadio(unit
, 0x5, 0xc72, base
);
200 WriteRadio(unit
, 0x6, 0xe6, base
);
201 WriteRadio(unit
, 0x7, 0x82a, base
);
202 WriteRadio(unit
, 0x8, 0x3f, base
);
203 WriteRadio(unit
, 0x9, 0x335, base
);
204 WriteRadio(unit
, 0xa, 0x9d4, base
);
205 WriteRadio(unit
, 0xb, 0x7bb, base
);
206 WriteRadio(unit
, 0xc, 0x850, base
);
207 WriteRadio(unit
, 0xd, 0xcdf, base
);
208 WriteRadio(unit
, 0xe, 0x2b, base
);
209 WriteRadio(unit
, 0xf, 0x114, base
);
210 WriteRadio(unit
, 0x0, 0x1b7, base
);
212 for(i
= 0; i
< sizeof(gain_table
) / sizeof(UWORD
); i
++)
214 WriteRadio(unit
, 0x1, i
+ 1, base
);
215 WriteRadio(unit
, 0x2, gain_table
[i
], base
);
218 WriteRadio(unit
, 0x3, 0x80, base
);
219 WriteRadio(unit
, 0x5, 0x4, base
);
220 WriteRadio(unit
, 0x0, 0xb7, base
);
221 BusyMilliDelay(100, base
);
223 WriteRadio(unit
, 0x2, 0xc4d, base
);
224 WriteRadio(unit
, 0x2, 0x44d, base
);
225 WriteRadio(unit
, 0x0, 0x2bf, base
);
227 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_TXGAINCCK
, 0x3);
228 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_TXGAINOFDM
, 0x7);
229 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_TXANTENNA
, 0x3);
231 WriteOFDM(unit
, 0x80, 0x12, base
);
232 for(i
= 0; i
< sizeof(agc_table
); i
++)
234 WriteOFDM(unit
, 0xf, agc_table
[i
], base
);
235 WriteOFDM(unit
, 0xe, 0x80 + i
, base
);
236 WriteOFDM(unit
, 0xe, 0, base
);
238 WriteOFDM(unit
, 0x80, 0x10, base
);
240 for(i
= 0; i
< sizeof(ofdm_table
); i
++)
241 WriteOFDM(unit
, i
, ofdm_table
[i
], base
);
243 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_ACVO
, (7 << 12) | (3 << 8) | 0x1c);
244 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_ACVI
, (7 << 12) | (3 << 8) | 0x1c);
245 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_ACBE
, (7 << 12) | (3 << 8) | 0x1c);
246 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_ACBK
, (7 << 12) | (3 << 8) | 0x1c);
248 WriteOFDM(unit
, 0x97, 0x46, base
);
249 WriteOFDM(unit
, 0xa4, 0xb6, base
);
250 WriteOFDM(unit
, 0x85, 0xfc, base
);
251 WriteCCK(unit
, 0xc1, 0x88, base
);
260 VOID
GetPower(struct DevUnit
*unit
, struct DevBase
*base
)
262 const UBYTE
*locations
;
266 if(unit
->generation
== RTL8187L_GEN
)
267 locations
= eeprom_power_locations_l
;
269 locations
= eeprom_power_locations_b
;
271 for(i
= 0; i
< 14; i
++)
273 value
= GetPowerPair(unit
, locations
[i
], base
);
274 unit
->cck_power
[i
] = value
& 0xf;
275 unit
->ofdm_power
[i
] = value
>> 4;
281 static UBYTE
GetPowerPair(struct DevUnit
*unit
, UWORD index
,
282 struct DevBase
*base
)
286 value
= LEWord(ReadEEPROM(unit
, index
>> 1, base
));
287 if((index
& 0x1) != 0)
295 VOID
SetPower(struct DevUnit
*unit
, struct DevBase
*base
)
297 UBYTE power_level
, tx_gain
, table_no
, n
;
298 const UBYTE
*power_table
;
300 ULONG tx_conf
, loop_tx_conf
, channel_code
;
302 /* Get CCK power level and gain */
304 power_level
= unit
->cck_power
[unit
->channel
];
305 if(unit
->radio_type
== RTL8225_RADIO
)
309 table_no
= power_level
% 6;
310 tx_gain
= (2 << power_level
/ 6) - 1;
316 if(unit
->generation
!= RTL8187B1_GEN
)
318 power_level
+= unit
->base_cck_power
;
323 tx_gain
= power_level
<< 1;
326 /* Adjust power table number for RTL8225v2b */
328 if(unit
->radio_type
== RTL8225V2B_RADIO
)
330 if(unit
->generation
== RTL8187B1_GEN
)
332 if(power_level
> 11 && unit
->channel
!= 14)
334 else if(power_level
> 6)
345 if(unit
->channel
!= 14)
349 else if(power_level
> 11)
355 /* Get CCK power table and write it to chip */
357 if(unit
->channel
== 14)
358 power_table
= rtl8225_ch14_power_tables
[table_no
];
360 power_table
= rtl8225_power_tables
[table_no
];
362 for(i
= 0; i
< 8; i
++)
363 WriteCCK(unit
, 0x44 + i
, power_table
[i
], base
);
367 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_TXGAINCCK
, tx_gain
);
368 BusyMilliDelay(1, base
);
370 /* Get OFDM power level */
372 power_level
= unit
->ofdm_power
[unit
->channel
];
375 if(unit
->radio_type
<= RTL8225V2_RADIO
)
381 if(unit
->generation
!= RTL8187B1_GEN
)
386 if(unit
->radio_type
>= RTL8225V2_RADIO
)
387 power_level
+= unit
->base_ofdm_power
;
391 /* Enable analogue parameter 2 */
393 if(unit
->radio_type
<= RTL8225V2_RADIO
)
395 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, R8180ECMD_CONFIG
);
396 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CONFIG3
,
397 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CONFIG3
)
398 | R8180REG_CONFIG3F_ANAPARAMWRITE
);
399 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_ANAPARAM2
, 0x860c7312);
400 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CONFIG3
,
401 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CONFIG3
)
402 & ~R8180REG_CONFIG3F_ANAPARAMWRITE
);
403 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, 0);
408 if(unit
->radio_type
== RTL8225_RADIO
)
409 tx_gain
= (2 << power_level
/ 6) - 1;
411 tx_gain
= power_level
<< 1;
413 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_TXGAINOFDM
, tx_gain
);
415 /* Set up OFDM power */
417 if(unit
->radio_type
== RTL8225V2B_RADIO
)
419 if(unit
->generation
== RTL8187B1_GEN
)
430 else if(power_level
> 11)
435 WriteOFDM(unit
, 0x87, n
, base
);
436 WriteOFDM(unit
, 0x89, n
, base
);
438 else if(unit
->radio_type
== RTL8225V2_RADIO
)
440 WriteOFDM(unit
, 0x2, 0x42, base
);
441 WriteOFDM(unit
, 0x5, 0, base
);
442 WriteOFDM(unit
, 0x6, 0x40, base
);
443 WriteOFDM(unit
, 0x7, 0, base
);
444 WriteOFDM(unit
, 0x8, 0x40, base
);
448 n
= rtl8225_ofdm_power
[power_level
% 6];
449 WriteOFDM(unit
, 0x2, 0x42, base
);
450 WriteOFDM(unit
, 0x5, n
, base
);
451 WriteOFDM(unit
, 0x6, 0, base
);
452 WriteOFDM(unit
, 0x7, n
, base
);
453 WriteOFDM(unit
, 0x8, 0, base
);
456 BusyMilliDelay(1, base
);
460 tx_conf
= unit
->LELongIn(unit
->card
, 0x100 + R8180REG_TXCONF
);
461 loop_tx_conf
= tx_conf
& ~R8180REG_TXCONFF_LOOPBACK
462 | 1 << R8180REG_TXCONFB_LOOPBACK
;
463 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_TXCONF
,
465 if(unit
->channel
== 14)
466 channel_code
= 0xf72;
468 channel_code
= 0x7dc + unit
->channel
* 0x80;
469 WriteRadio(unit
, 0x7, channel_code
, base
);
470 BusyMilliDelay(10, base
);
471 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_TXCONF
, tx_conf
);
478 /****i* realtek8180.device/WriteCCK ****************************************
481 * WriteCCK -- Write to a CCK PHY register.
484 * WriteCCK(unit, index, value)
486 * VOID WriteCCK(struct DevUnit *, UWORD, UWORD);
489 * unit - A unit of this device.
490 * index - Offset of register.
491 * value - Value to write to register.
496 ****************************************************************************
500 VOID
WriteCCK(struct DevUnit
*unit
, UWORD index
, UWORD value
,
501 struct DevBase
*base
)
503 WritePHY(unit
, index
, value
| 1 << 16, base
);
510 /****i* realtek8180.device/WriteOFDM ***************************************
513 * WriteOFDM -- Write to an OFDM PHY register.
516 * WriteOFDM(unit, index, value)
518 * VOID WriteOFDM(struct DevUnit *, UWORD, UWORD);
521 * unit - A unit of this device.
522 * index - Offset of register.
523 * value - Value to write to register.
528 ****************************************************************************
532 VOID
WriteOFDM(struct DevUnit
*unit
, UWORD index
, UWORD value
,
533 struct DevBase
*base
)
535 WritePHY(unit
, index
, value
, base
);
542 /****i* realtek8180.device/WritePHY ****************************************
545 * WritePHY -- Write to a CCK PHY register.
548 * WritePHY(unit, index, value)
550 * VOID WritePHY(struct DevUnit *, UWORD, ULONG);
553 * unit - A unit of this device.
554 * index - Offset of register.
555 * value - Value to write to register.
560 ****************************************************************************
564 static VOID
WritePHY(struct DevUnit
*unit
, UWORD index
, ULONG value
,
565 struct DevBase
*base
)
569 data
= value
<< 8 | index
| 0x80;
570 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_PHY
+ 3, data
>> 24);
571 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_PHY
+ 2, data
>> 16);
572 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_PHY
+ 1, data
>> 8);
573 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_PHY
, data
);
580 /****i* realtek8180.device/ReadRadio ***************************************
583 * ReadRadio -- Read a radio register.
586 * value = ReadRadio(unit, index)
588 * UWORD ReadRadio(struct DevUnit *, UWORD);
591 * unit - A unit of this device.
592 * index - Offset of register.
595 * value - Value read from radio register.
597 ****************************************************************************
601 UWORD
ReadRadio(struct DevUnit
*unit
, UWORD index
,
602 struct DevBase
*base
)
604 UWORD value
= 0, value2
, output_reg
, enable_reg
, select_reg
;
607 output_reg
= unit
->LEWordIn(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
)
609 enable_reg
= unit
->LEWordIn(unit
->card
, 0x100 + R8180REG_RFPINSENABLE
);
610 select_reg
= unit
->LEWordIn(unit
->card
, 0x100 + R8180REG_RFPINSSELECT
);
611 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSENABLE
,
613 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSSELECT
,
615 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
617 BusyMicroDelay(4, base
);
619 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
, output_reg
);
620 BusyMicroDelay(5, base
);
622 for(i
= 4; i
>= 0; i
--)
624 value2
= output_reg
| index
>> i
& 1;
628 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
, value2
);
629 BusyMicroDelay(1, base
);
632 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
, value2
| 0x2);
633 BusyMicroDelay(2, base
);
635 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
, value2
| 0x2);
636 BusyMicroDelay(2, base
);
640 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
, value2
);
641 BusyMicroDelay(1, base
);
645 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
647 BusyMicroDelay(2, base
);
649 for(i
= 0; i
< 2; i
++)
651 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
653 BusyMicroDelay(2, base
);
656 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSENABLE
,
657 (enable_reg
| 0xe) & ~1);
659 for(i
= 11; i
>= 0; i
--)
661 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
663 BusyMicroDelay(1, base
);
665 for(j
= 0; j
< 3; j
++)
667 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
669 BusyMicroDelay(2, base
);
672 if((unit
->LEWordIn(unit
->card
, 0x100 + R8180REG_RFPINSINPUT
) & 0x2)
676 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
678 BusyMicroDelay(2, base
);
681 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
, output_reg
| 0xc);
682 BusyMicroDelay(2, base
);
684 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSENABLE
, enable_reg
);
685 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSSELECT
, select_reg
);
686 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
, 0x3a0);
693 /****i* realtek8180.device/WriteRadio **************************************
696 * WriteRadio -- Write to a radio register.
699 * WriteRadio(unit, index, value)
701 * VOID WriteRadio(struct DevUnit *, UWORD, UWORD);
704 * unit - A unit of this device.
705 * index - Offset of register.
706 * value - Value to write to register.
711 ****************************************************************************
715 VOID
WriteRadio(struct DevUnit
*unit
, UWORD index
, UWORD value
,
716 struct DevBase
*base
)
718 UWORD output_reg
, enable_reg
, select_reg
, value2
;
722 data
= (value
<< 4) | (index
& 0xf);
724 output_reg
= unit
->LEWordIn(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
)
726 enable_reg
= unit
->LEWordIn(unit
->card
, 0x100 + R8180REG_RFPINSENABLE
);
727 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSENABLE
,
729 select_reg
= unit
->LEWordIn(unit
->card
, 0x100 + R8180REG_RFPINSSELECT
);
730 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSSELECT
,
732 BusyMicroDelay(10, base
);
734 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
736 BusyMicroDelay(2, base
);
738 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
, output_reg
);
739 BusyMicroDelay(10, base
);
741 if(unit
->bus
== USB_BUS
&& unit
->generation
>= RTL8187B0_GEN
)
742 unit
->LEWordOut(unit
->card
, 0x8225 << 16 | 0x200 + index
, value
);
745 for(i
= 15; i
>= 0; i
--)
747 value2
= output_reg
| (data
& (1 << i
)) >> i
;
750 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
752 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
754 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
757 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
762 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
764 BusyMicroDelay(10, base
);
766 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
,
768 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSSELECT
, select_reg
);