[PATCH] ZyDAS ZD1211 USB-WLAN driver
[linux-2.6.git] / drivers / net / wireless / zd1211rw / zd_rf_al2230.c
1 /* zd_rf_al2230.c: Functions for the AL2230 RF controller
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  */
17
18 #include <linux/kernel.h>
19
20 #include "zd_rf.h"
21 #include "zd_usb.h"
22 #include "zd_chip.h"
23
24 static const u32 al2230_table[][3] = {
25         RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, },
26         RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, },
27         RF_CHANNEL( 3) = { 0x03e790, 0x033331, 0x00000d, },
28         RF_CHANNEL( 4) = { 0x03e790, 0x0b3331, 0x00000d, },
29         RF_CHANNEL( 5) = { 0x03f7a0, 0x033331, 0x00000d, },
30         RF_CHANNEL( 6) = { 0x03f7a0, 0x0b3331, 0x00000d, },
31         RF_CHANNEL( 7) = { 0x03e7a0, 0x033331, 0x00000d, },
32         RF_CHANNEL( 8) = { 0x03e7a0, 0x0b3331, 0x00000d, },
33         RF_CHANNEL( 9) = { 0x03f7b0, 0x033331, 0x00000d, },
34         RF_CHANNEL(10) = { 0x03f7b0, 0x0b3331, 0x00000d, },
35         RF_CHANNEL(11) = { 0x03e7b0, 0x033331, 0x00000d, },
36         RF_CHANNEL(12) = { 0x03e7b0, 0x0b3331, 0x00000d, },
37         RF_CHANNEL(13) = { 0x03f7c0, 0x033331, 0x00000d, },
38         RF_CHANNEL(14) = { 0x03e7c0, 0x066661, 0x00000d, },
39 };
40
41 static int zd1211_al2230_init_hw(struct zd_rf *rf)
42 {
43         int r;
44         struct zd_chip *chip = zd_rf_to_chip(rf);
45
46         static const struct zd_ioreq16 ioreqs[] = {
47                 { CR15,   0x20 }, { CR23,   0x40 }, { CR24,  0x20 },
48                 { CR26,   0x11 }, { CR28,   0x3e }, { CR29,  0x00 },
49                 { CR44,   0x33 }, { CR106,  0x2a }, { CR107, 0x1a },
50                 { CR109,  0x09 }, { CR110,  0x27 }, { CR111, 0x2b },
51                 { CR112,  0x2b }, { CR119,  0x0a }, { CR10,  0x89 },
52                 /* for newest (3rd cut) AL2300 */
53                 { CR17,   0x28 },
54                 { CR26,   0x93 }, { CR34,   0x30 },
55                 /* for newest (3rd cut) AL2300 */
56                 { CR35,   0x3e },
57                 { CR41,   0x24 }, { CR44,   0x32 },
58                 /* for newest (3rd cut) AL2300 */
59                 { CR46,   0x96 },
60                 { CR47,   0x1e }, { CR79,   0x58 }, { CR80,  0x30 },
61                 { CR81,   0x30 }, { CR87,   0x0a }, { CR89,  0x04 },
62                 { CR92,   0x0a }, { CR99,   0x28 }, { CR100, 0x00 },
63                 { CR101,  0x13 }, { CR102,  0x27 }, { CR106, 0x24 },
64                 { CR107,  0x2a }, { CR109,  0x09 }, { CR110, 0x13 },
65                 { CR111,  0x1f }, { CR112,  0x1f }, { CR113, 0x27 },
66                 { CR114,  0x27 },
67                 /* for newest (3rd cut) AL2300 */
68                 { CR115,  0x24 },
69                 { CR116,  0x24 }, { CR117,  0xf4 }, { CR118, 0xfc },
70                 { CR119,  0x10 }, { CR120,  0x4f }, { CR121, 0x77 },
71                 { CR122,  0xe0 }, { CR137,  0x88 }, { CR252, 0xff },
72                 { CR253,  0xff },
73
74                 /* These following happen separately in the vendor driver */
75                 { },
76
77                 /* shdnb(PLL_ON)=0 */
78                 { CR251,  0x2f },
79                 /* shdnb(PLL_ON)=1 */
80                 { CR251,  0x3f },
81                 { CR138,  0x28 }, { CR203,  0x06 },
82         };
83
84         static const u32 rv[] = {
85                 /* Channel 1 */
86                 0x03f790,
87                 0x033331,
88                 0x00000d,
89
90                 0x0b3331,
91                 0x03b812,
92                 0x00fff3,
93                 0x000da4,
94                 0x0f4dc5, /* fix freq shift, 0x04edc5 */
95                 0x0805b6,
96                 0x011687,
97                 0x000688,
98                 0x0403b9, /* external control TX power (CR31) */
99                 0x00dbba,
100                 0x00099b,
101                 0x0bdffc,
102                 0x00000d,
103                 0x00500f,
104
105                 /* These writes happen separately in the vendor driver */
106                 0x00d00f,
107                 0x004c0f,
108                 0x00540f,
109                 0x00700f,
110                 0x00500f,
111         };
112
113         r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
114         if (r)
115                 return r;
116
117         r = zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
118         if (r)
119                 return r;
120
121         return 0;
122 }
123
124 static int zd1211b_al2230_init_hw(struct zd_rf *rf)
125 {
126         int r;
127         struct zd_chip *chip = zd_rf_to_chip(rf);
128
129         static const struct zd_ioreq16 ioreqs1[] = {
130                 { CR10,  0x89 }, { CR15,  0x20 },
131                 { CR17,  0x2B }, /* for newest(3rd cut) AL2230 */
132                 { CR23,  0x40 }, { CR24,  0x20 }, { CR26,  0x93 },
133                 { CR28,  0x3e }, { CR29,  0x00 },
134                 { CR33,  0x28 }, /* 5621 */
135                 { CR34,  0x30 },
136                 { CR35,  0x3e }, /* for newest(3rd cut) AL2230 */
137                 { CR41,  0x24 }, { CR44,  0x32 },
138                 { CR46,  0x99 }, /* for newest(3rd cut) AL2230 */
139                 { CR47,  0x1e },
140
141                 /* ZD1211B 05.06.10 */
142                 { CR48,  0x00 }, { CR49,  0x00 }, { CR51,  0x01 },
143                 { CR52,  0x80 }, { CR53,  0x7e }, { CR65,  0x00 },
144                 { CR66,  0x00 }, { CR67,  0x00 }, { CR68,  0x00 },
145                 { CR69,  0x28 },
146
147                 { CR79,  0x58 }, { CR80,  0x30 }, { CR81,  0x30 },
148                 { CR87,  0x0a }, { CR89,  0x04 },
149                 { CR91,  0x00 }, /* 5621 */
150                 { CR92,  0x0a },
151                 { CR98,  0x8d }, /* 4804,  for 1212 new algorithm */
152                 { CR99,  0x00 }, /* 5621 */
153                 { CR101, 0x13 }, { CR102, 0x27 },
154                 { CR106, 0x24 }, /* for newest(3rd cut) AL2230 */
155                 { CR107, 0x2a },
156                 { CR109, 0x13 }, /* 4804, for 1212 new algorithm */
157                 { CR110, 0x1f }, /* 4804, for 1212 new algorithm */
158                 { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 },
159                 { CR114, 0x27 },
160                 { CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut) AL2230 */
161                 { CR116, 0x24 },
162                 { CR117, 0xfa }, /* for 1211b */
163                 { CR118, 0xfa }, /* for 1211b */
164                 { CR119, 0x10 },
165                 { CR120, 0x4f },
166                 { CR121, 0x6c }, /* for 1211b */
167                 { CR122, 0xfc }, /* E0->FC at 4902 */
168                 { CR123, 0x57 }, /* 5623 */
169                 { CR125, 0xad }, /* 4804, for 1212 new algorithm */
170                 { CR126, 0x6c }, /* 5614 */
171                 { CR127, 0x03 }, /* 4804, for 1212 new algorithm */
172                 { CR137, 0x50 }, /* 5614 */
173                 { CR138, 0xa8 },
174                 { CR144, 0xac }, /* 5621 */
175                 { CR150, 0x0d }, { CR252, 0x00 }, { CR253, 0x00 },
176         };
177
178         static const u32 rv1[] = {
179                 /* channel 1 */
180                 0x03f790,
181                 0x033331,
182                 0x00000d,
183
184                 0x0b3331,
185                 0x03b812,
186                 0x00fff3,
187                 0x0005a4,
188                 0x0f4dc5, /* fix freq shift 0x044dc5 */
189                 0x0805b6,
190                 0x0146c7,
191                 0x000688,
192                 0x0403b9, /* External control TX power (CR31) */
193                 0x00dbba,
194                 0x00099b,
195                 0x0bdffc,
196                 0x00000d,
197                 0x00580f,
198         };
199
200         static const struct zd_ioreq16 ioreqs2[] = {
201                 { CR47,  0x1e }, { CR_RFCFG, 0x03 },
202         };
203
204         static const u32 rv2[] = {
205                 0x00880f,
206                 0x00080f,
207         };
208
209         static const struct zd_ioreq16 ioreqs3[] = {
210                 { CR_RFCFG, 0x00 }, { CR47, 0x1e }, { CR251, 0x7f },
211         };
212
213         static const u32 rv3[] = {
214                 0x00d80f,
215                 0x00780f,
216                 0x00580f,
217         };
218
219         static const struct zd_ioreq16 ioreqs4[] = {
220                 { CR138, 0x28 }, { CR203, 0x06 },
221         };
222
223         r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1));
224         if (r)
225                 return r;
226         r = zd_rfwritev_locked(chip, rv1, ARRAY_SIZE(rv1), RF_RV_BITS);
227         if (r)
228                 return r;
229         r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2));
230         if (r)
231                 return r;
232         r = zd_rfwritev_locked(chip, rv2, ARRAY_SIZE(rv2), RF_RV_BITS);
233         if (r)
234                 return r;
235         r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3));
236         if (r)
237                 return r;
238         r = zd_rfwritev_locked(chip, rv3, ARRAY_SIZE(rv3), RF_RV_BITS);
239         if (r)
240                 return r;
241         return zd_iowrite16a_locked(chip, ioreqs4, ARRAY_SIZE(ioreqs4));
242 }
243
244 static int al2230_set_channel(struct zd_rf *rf, u8 channel)
245 {
246         int r;
247         const u32 *rv = al2230_table[channel-1];
248         struct zd_chip *chip = zd_rf_to_chip(rf);
249         static const struct zd_ioreq16 ioreqs[] = {
250                 { CR138, 0x28 },
251                 { CR203, 0x06 },
252         };
253
254         r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS);
255         if (r)
256                 return r;
257         return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
258 }
259
260 static int zd1211_al2230_switch_radio_on(struct zd_rf *rf)
261 {
262         struct zd_chip *chip = zd_rf_to_chip(rf);
263         static const struct zd_ioreq16 ioreqs[] = {
264                 { CR11,  0x00 },
265                 { CR251, 0x3f },
266         };
267
268         return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
269 }
270
271 static int zd1211b_al2230_switch_radio_on(struct zd_rf *rf)
272 {
273         struct zd_chip *chip = zd_rf_to_chip(rf);
274         static const struct zd_ioreq16 ioreqs[] = {
275                 { CR11,  0x00 },
276                 { CR251, 0x7f },
277         };
278
279         return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
280 }
281
282 static int al2230_switch_radio_off(struct zd_rf *rf)
283 {
284         struct zd_chip *chip = zd_rf_to_chip(rf);
285         static const struct zd_ioreq16 ioreqs[] = {
286                 { CR11,  0x04 },
287                 { CR251, 0x2f },
288         };
289
290         return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
291 }
292
293 int zd_rf_init_al2230(struct zd_rf *rf)
294 {
295         struct zd_chip *chip = zd_rf_to_chip(rf);
296
297         rf->set_channel = al2230_set_channel;
298         rf->switch_radio_off = al2230_switch_radio_off;
299         if (chip->is_zd1211b) {
300                 rf->init_hw = zd1211b_al2230_init_hw;
301                 rf->switch_radio_on = zd1211b_al2230_switch_radio_on;
302         } else {
303                 rf->init_hw = zd1211_al2230_init_hw;
304                 rf->switch_radio_on = zd1211_al2230_switch_radio_on;
305         }
306         rf->patch_6m_band_edge = 1;
307         return 0;
308 }