1 /*
2 This files contains MAXIM MAX2820 radio frontend programming routines.
3
4 This is part of rtl8180 OpenSource driver
5 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
6 Released under the terms of GPL (General Public Licence)
7
8 Parts of this driver are based on the GPL part of the
9 official realtek driver
10
11 Parts of this driver are based on the rtl8180 driver skeleton
12 from Patric Schenke & Andres Salomon
13
14 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15
16 NetBSD rtl8180 driver from Dave Young has been really useful to
17 understand how to program the MAXIM radio. Thanks a lot!!!
18
19 'The Deuce' tested this and fixed some bugs.
20
21 Code from rtl8181 project has been useful to me to understand some things.
22
23 We want to tanks the Authors of such projects and the Ndiswrapper
24 project Authors.
25 */
26
27
28 #include "r8180.h"
29 #include "r8180_hw.h"
30 #include "r8180_max2820.h"
31
32
33 //#define DEBUG_MAXIM
34
35 u32 maxim_chan[] = {
36 0, //dummy channel 0
37 12, //1
38 17, //2
39 22, //3
40 27, //4
41 32, //5
42 37, //6
43 42, //7
44 47, //8
45 52, //9
46 57, //10
47 62, //11
48 67, //12
49 72, //13
50 84, //14
51 };
52
53 #if 0
54 /* maxim expects 4 bit address MSF, then 12 bit data MSF*/
55 void write_maxim(struct net_device *dev,u8 adr, u32 data)
56 {
57
58 int shift;
59 short bit;
60 u16 word;
61
62 adr = adr &0xf;
63 word = (u16)data & 0xfff;
64 word |= (adr<<12);
65 /*write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | BB_HOST_BANG_EN);
66 read_nic_dword(dev,PHY_CONFIG);
67 mdelay(1);
68
69 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | BB_HOST_BANG_EN | BB_HOST_BANG_CLK);
70 read_nic_dword(dev,PHY_CONFIG);
71 mdelay(1);
72 */
73
74 /* MAX2820 will sample data on rising edge of clock */
75 for(shift = 15;shift >=0; shift--){
76 bit = word>>shift & 1;
77
78 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA));
79
80 read_nic_dword(dev,PHY_CONFIG);
81 mdelay(2);
82
83 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
84 (bit<<BB_HOST_BANG_DATA) | BB_HOST_BANG_CLK); /* sample data */
85
86 read_nic_dword(dev,PHY_CONFIG);
87 mdelay(1);
88
89 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
90 (bit<<BB_HOST_BANG_DATA));
91
92 read_nic_dword(dev,PHY_CONFIG);
93 mdelay(2);
94
95 }
96 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
97 BB_HOST_BANG_EN);
98 read_nic_dword(dev,PHY_CONFIG);
99 mdelay(2);
100
101 /* The shift register fill flush to the requested register the
102 * last 12 bits data shifted in
103 */
104 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
105 BB_HOST_BANG_EN | BB_HOST_BANG_CLK);
106 read_nic_dword(dev,PHY_CONFIG);
107 mdelay(2);
108
109 write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
110 BB_HOST_BANG_EN);
111 read_nic_dword(dev,PHY_CONFIG);
112 mdelay(2);
113
114
115 #ifdef DEBUG_MAXIM
116 DMESG("Writing maxim: %x (adr %x)",phy_config,adr);
117 #endif
118
119 }
120 #endif
121
write_maxim(struct net_device * dev,u8 adr,u32 data)122 void write_maxim(struct net_device *dev,u8 adr, u32 data) {
123 u32 temp;
124 temp = 0x90 + (data & 0xf);
125 temp <<= 16;
126 temp += adr;
127 temp <<= 8;
128 temp += (data >> 4) & 0xff;
129 #ifdef DEBUG_MAXIM
130 DMESG("write_maxim: %08x", temp);
131 #endif
132 write_nic_dword(dev, PHY_CONFIG, temp);
133 force_pci_posting(dev);
134 mdelay(1);
135 }
136
137
maxim_write_phy_antenna(struct net_device * dev,short ch)138 void maxim_write_phy_antenna(struct net_device *dev,short ch)
139 {
140 struct r8180_priv *priv = ieee80211_priv(dev);
141 u8 ant;
142
143 ant = MAXIM_ANTENNA;
144 if(priv->antb) /*default antenna is antenna B */
145 ant |= BB_ANTENNA_B;
146 if(ch == 14)
147 ant |= BB_ANTATTEN_CHAN14;
148 write_phy(dev,0x10,ant);
149 //DMESG("BB antenna %x ",ant);
150 }
151
152
maxim_rf_set_chan(struct net_device * dev,short ch)153 void maxim_rf_set_chan(struct net_device *dev, short ch)
154 {
155 struct r8180_priv *priv = ieee80211_priv(dev);
156 u32 txpw = 0xff & priv->chtxpwr[ch];
157 u32 chan = maxim_chan[ch];
158
159 /*While philips SA2400 drive the PA bias
160 *seems that for MAXIM we delegate this
161 *to the BB
162 */
163
164 //write_maxim(dev,5,txpw);
165 write_phy(dev,3,txpw);
166
167 maxim_write_phy_antenna(dev,ch);
168 write_maxim(dev,3,chan);
169 }
170
171
maxim_rf_close(struct net_device * dev)172 void maxim_rf_close(struct net_device *dev)
173 {
174 write_phy(dev, 3, 0x8);
175 write_maxim(dev, 1, 0);
176 }
177
178
maxim_rf_init(struct net_device * dev)179 void maxim_rf_init(struct net_device *dev)
180 {
181 struct r8180_priv *priv = ieee80211_priv(dev);
182 u32 anaparam;
183
184 write_nic_byte(dev,PHY_DELAY,0x6); //this is general
185 write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
186
187 /*these are maxim specific*/
188 anaparam = read_nic_dword(dev,ANAPARAM);
189 anaparam = anaparam &~ (ANAPARAM_TXDACOFF_SHIFT);
190 anaparam = anaparam &~ANAPARAM_PWR1_MASK;
191 anaparam = anaparam &~ANAPARAM_PWR0_MASK;
192 anaparam |= (MAXIM_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
193 anaparam |= (MAXIM_ANAPARAM_PWR0_ON<<ANAPARAM_PWR0_SHIFT);
194
195 //rtl8180_set_anaparam(dev,anaparam);
196
197 /* MAXIM from netbsd driver */
198
199 write_maxim(dev,0, 7); /* test mode as indicated in datasheet*/
200 write_maxim(dev,1, 0x1e); /* enable register*/
201 write_maxim(dev,2, 1); /* synt register */
202
203
204 maxim_rf_set_chan(dev,priv->chan);
205
206 write_maxim(dev,4, 0x313); /* rx register*/
207
208 /* PA is driven directly by the BB, we keep the MAXIM bias
209 * at the highest value in the boubt tha pleacing it to lower
210 * values may introduce some further attenuation somewhere..
211 */
212
213 write_maxim(dev,5, 0xf);
214
215
216 /*baseband configuration*/
217 write_phy(dev,0,0x88); //sys1
218 write_phy(dev,3,0x8); //txagc
219 write_phy(dev,4,0xf8); // lnadet
220 write_phy(dev,5,0x90); // ifagcinit
221 write_phy(dev,6,0x1a); // ifagclimit
222 write_phy(dev,7,0x64); // ifagcdet
223
224 /*Should be done something more here??*/
225
226 maxim_write_phy_antenna(dev,priv->chan);
227
228 write_phy(dev,0x11,0x88); //trl
229 if(priv->diversity)
230 write_phy(dev,0x12,0xc7);
231 else
232 write_phy(dev,0x12,0x47);
233
234 write_phy(dev,0x13,0x9b);
235
236 write_phy(dev,0x19,0x0); //CHESTLIM
237 write_phy(dev,0x1a,0x9f); //CHSQLIM
238
239 maxim_rf_set_chan(dev,priv->chan);
240 }
241