Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[linux-2.6] / drivers / staging / rtl8187se / r8180_sa2400.c
1 /*
2    This files contains PHILIPS SA2400 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    Code at http://che.ojctech.com/~dyoung/rtw/ has been useful to me to
17    understand some things.
18
19    Code from rtl8181 project has been useful to me to understand some things.
20
21    We want to tanks the Authors of such projects and the Ndiswrapper
22    project Authors.
23 */
24
25
26 #include "r8180.h"
27 #include "r8180_hw.h"
28 #include "r8180_sa2400.h"
29
30
31 //#define DEBUG_SA2400
32
33 u32 sa2400_chan[] = {
34         0x0,    //dummy channel 0
35         0x00096c, //1
36         0x080970, //2
37         0x100974, //3
38         0x180978, //4
39         0x000980, //5
40         0x080984, //6
41         0x100988, //7
42         0x18098c, //8
43         0x000994, //9
44         0x080998, //10
45         0x10099c, //11
46         0x1809a0, //12
47         0x0009a8, //13
48         0x0009b4, //14
49 };
50
51
52 void rf_stabilize(struct net_device *dev)
53 {
54         force_pci_posting(dev);
55         mdelay(3); //for now use a great value.. we may optimize in future
56 }
57
58
59 void write_sa2400(struct net_device *dev,u8 adr, u32 data)
60 {
61 //      struct r8180_priv *priv = ieee80211_priv(dev);
62         u32 phy_config;
63
64         // philips sa2400 expects 24 bits data
65
66         /*if(adr == 4 && priv->digphy){
67                 phy_config=0x60000000;
68         }else{
69                 phy_config=0xb0000000;
70         }*/
71
72         phy_config = 0xb0000000; // MAC will bang bits to the sa2400
73
74         phy_config |= (((u32)(adr&0xf))<< 24);
75         phy_config |= (data & 0xffffff);
76         write_nic_dword(dev,PHY_CONFIG,phy_config);
77 #ifdef DEBUG_SA2400
78         DMESG("Writing sa2400: %x (adr %x)",phy_config,adr);
79 #endif
80         rf_stabilize(dev);
81 }
82
83
84
85 void sa2400_write_phy_antenna(struct net_device *dev,short ch)
86 {
87         struct r8180_priv *priv = ieee80211_priv(dev);
88         u8 ant;
89
90         ant = SA2400_ANTENNA;
91         if(priv->antb) /*default antenna is antenna B */
92                 ant |= BB_ANTENNA_B;
93         if(ch == 14)
94                 ant |= BB_ANTATTEN_CHAN14;
95         write_phy(dev,0x10,ant);
96         //DMESG("BB antenna %x ",ant);
97 }
98
99
100 /* from the rtl8181 embedded driver */
101 short sa2400_rf_set_sens(struct net_device *dev, short sens)
102 {
103         u8 finetune = 0;
104         if ((sens > 85) || (sens < 54)) return -1;
105
106         write_sa2400(dev,5,0x1dfb | (sens-54) << 15 |(finetune<<20));  // AGC   0xc9dfb
107
108         return 0;
109 }
110
111
112 void sa2400_rf_set_chan(struct net_device *dev, short ch)
113 {
114         struct r8180_priv *priv = ieee80211_priv(dev);
115         u32 txpw = 0xff & priv->chtxpwr[ch];
116         u32 chan = sa2400_chan[ch];
117
118         write_sa2400(dev,7,txpw);
119         //write_phy(dev,0x10,0xd1);
120         sa2400_write_phy_antenna(dev,ch);
121         write_sa2400(dev,0,chan);
122         write_sa2400(dev,1,0xbb50);
123         write_sa2400(dev,2,0x80);
124         write_sa2400(dev,3,0);
125 }
126
127
128 void sa2400_rf_close(struct net_device *dev)
129 {
130         write_sa2400(dev, 4, 0);
131 }
132
133
134 void sa2400_rf_init(struct net_device *dev)
135 {
136         struct r8180_priv *priv = ieee80211_priv(dev);
137         u32 anaparam;
138         u8 firdac;
139
140         write_nic_byte(dev,PHY_DELAY,0x6);      //this is general
141         write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
142
143         /*these are philips sa2400 specific*/
144         anaparam = read_nic_dword(dev,ANAPARAM);
145         anaparam = anaparam &~ (1<<ANAPARAM_TXDACOFF_SHIFT);
146
147         anaparam = anaparam &~ANAPARAM_PWR1_MASK;
148         anaparam = anaparam &~ANAPARAM_PWR0_MASK;
149         if(priv->digphy){
150                 anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
151                 anaparam |= (SA2400_ANAPARAM_PWR0_ON<<ANAPARAM_PWR0_SHIFT);
152         }else{
153                 anaparam |= (SA2400_ANA_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
154         }
155
156         rtl8180_set_anaparam(dev,anaparam);
157
158         firdac = (priv->digphy) ? (1<<SA2400_REG4_FIRDAC_SHIFT) : 0;
159         write_sa2400(dev,0,sa2400_chan[priv->chan]);
160         write_sa2400(dev,1,0xbb50);
161         write_sa2400(dev,2,0x80);
162         write_sa2400(dev,3,0);
163         write_sa2400(dev,4,0x19340 | firdac);
164         write_sa2400(dev,5,0xc9dfb);  // AGC
165         write_sa2400(dev,4,0x19348 | firdac);  //calibrates VCO
166
167         if(priv->digphy)
168                 write_sa2400(dev,4,0x1938c); /*???*/
169
170         write_sa2400(dev,4,0x19340 | firdac);
171
172         write_sa2400(dev,0,sa2400_chan[priv->chan]);
173         write_sa2400(dev,1,0xbb50);
174         write_sa2400(dev,2,0x80);
175         write_sa2400(dev,3,0);
176         write_sa2400(dev,4,0x19344 | firdac); //calibrates filter
177
178         /* new from rtl8180 embedded driver (rtl8181 project) */
179         write_sa2400(dev,6,0x13ff | (1<<23)); // MANRX
180         write_sa2400(dev,8,0); //VCO
181
182         if(!priv->digphy)
183         {
184                 rtl8180_set_anaparam(dev, anaparam | \
185                                      (1<<ANAPARAM_TXDACOFF_SHIFT));
186
187                 rtl8180_conttx_enable(dev);
188
189                 write_sa2400(dev, 4, 0x19341); // calibrates DC
190
191                 /* a 5us sleep is required here,
192                    we rely on the 3ms delay introduced in write_sa2400
193                 */
194                 write_sa2400(dev, 4, 0x19345);
195                 /* a 20us sleep is required here,
196                    we rely on the 3ms delay introduced in write_sa2400
197                 */
198                 rtl8180_conttx_disable(dev);
199
200                 rtl8180_set_anaparam(dev, anaparam);
201         }
202         /* end new */
203
204         write_sa2400(dev,4,0x19341 | firdac ); //RTX MODE
205
206         // Set tx power level !?
207
208
209         /*baseband configuration*/
210         write_phy(dev,0,0x98);
211         write_phy(dev,3,0x38);
212         write_phy(dev,4,0xe0);
213         write_phy(dev,5,0x90);
214         write_phy(dev,6,0x1a);
215         write_phy(dev,7,0x64);
216
217         /*Should be done something more here??*/
218
219         sa2400_write_phy_antenna(dev,priv->chan);
220
221         write_phy(dev,0x11,0x80);
222         if(priv->diversity)
223                 write_phy(dev,0x12,0xc7);
224         else
225                 write_phy(dev,0x12,0x47);
226
227         write_phy(dev,0x13,0x90 | priv->cs_treshold );
228
229         write_phy(dev,0x19,0x0);
230         write_phy(dev,0x1a,0xa0);
231
232         sa2400_rf_set_chan(dev,priv->chan);
233 }