• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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