xref: /linux/drivers/staging/vt6656/rf.c (revision a13d7201d7deedcbb6ac6efa94a1a7d34d3d79ec)
1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
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.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  *
20  * File: rf.c
21  *
22  * Purpose: rf function code
23  *
24  * Author: Jerry Chen
25  *
26  * Date: Feb. 19, 2004
27  *
28  * Functions:
29  *	vnt_rf_write_embedded	- Embedded write RF register via MAC
30  *
31  * Revision History:
32  *	RF_VT3226: RobertYu:20051111, VT3226C0 and before
33  *	RF_VT3226D0: RobertYu:20051228
34  *	RF_VT3342A0: RobertYu:20060609
35  *
36  */
37 
38 #include "mac.h"
39 #include "rf.h"
40 #include "baseband.h"
41 #include "usbpipe.h"
42 
43 #define CB_AL2230_INIT_SEQ    15
44 #define AL2230_PWR_IDX_LEN    64
45 
46 #define CB_AL7230_INIT_SEQ    16
47 #define AL7230_PWR_IDX_LEN    64
48 
49 #define CB_VT3226_INIT_SEQ    11
50 #define VT3226_PWR_IDX_LEN    64
51 
52 #define CB_VT3342_INIT_SEQ    13
53 #define VT3342_PWR_IDX_LEN    64
54 
55 static u8 al2230_init_table[CB_AL2230_INIT_SEQ][3] = {
56 	{0x03, 0xf7, 0x90},
57 	{0x03, 0x33, 0x31},
58 	{0x01, 0xb8, 0x02},
59 	{0x00, 0xff, 0xf3},
60 	{0x00, 0x05, 0xa4},
61 	{0x0f, 0x4d, 0xc5},
62 	{0x08, 0x05, 0xb6},
63 	{0x01, 0x47, 0xc7},
64 	{0x00, 0x06, 0x88},
65 	{0x04, 0x03, 0xb9},
66 	{0x00, 0xdb, 0xba},
67 	{0x00, 0x09, 0x9b},
68 	{0x0b, 0xdf, 0xfc},
69 	{0x00, 0x00, 0x0d},
70 	{0x00, 0x58, 0x0f}
71 };
72 
73 static u8 al2230_channel_table0[CB_MAX_CHANNEL_24G][3] = {
74 	{0x03, 0xf7, 0x90},
75 	{0x03, 0xf7, 0x90},
76 	{0x03, 0xe7, 0x90},
77 	{0x03, 0xe7, 0x90},
78 	{0x03, 0xf7, 0xa0},
79 	{0x03, 0xf7, 0xa0},
80 	{0x03, 0xe7, 0xa0},
81 	{0x03, 0xe7, 0xa0},
82 	{0x03, 0xf7, 0xb0},
83 	{0x03, 0xf7, 0xb0},
84 	{0x03, 0xe7, 0xb0},
85 	{0x03, 0xe7, 0xb0},
86 	{0x03, 0xf7, 0xc0},
87 	{0x03, 0xe7, 0xc0}
88 };
89 
90 static u8 al2230_channel_table1[CB_MAX_CHANNEL_24G][3] = {
91 	{0x03, 0x33, 0x31},
92 	{0x0b, 0x33, 0x31},
93 	{0x03, 0x33, 0x31},
94 	{0x0b, 0x33, 0x31},
95 	{0x03, 0x33, 0x31},
96 	{0x0b, 0x33, 0x31},
97 	{0x03, 0x33, 0x31},
98 	{0x0b, 0x33, 0x31},
99 	{0x03, 0x33, 0x31},
100 	{0x0b, 0x33, 0x31},
101 	{0x03, 0x33, 0x31},
102 	{0x0b, 0x33, 0x31},
103 	{0x03, 0x33, 0x31},
104 	{0x06, 0x66, 0x61}
105 };
106 
107 static u8 al7230_init_table[CB_AL7230_INIT_SEQ][3] = {
108 	{0x20, 0x37, 0x90},
109 	{0x13, 0x33, 0x31},
110 	{0x84, 0x1f, 0xf2},
111 	{0x3f, 0xdf, 0xa3},
112 	{0x7f, 0xd7, 0x84},
113 	{0x80, 0x2b, 0x55},
114 	{0x56, 0xaf, 0x36},
115 	{0xce, 0x02, 0x07},
116 	{0x6e, 0xbc, 0x98},
117 	{0x22, 0x1b, 0xb9},
118 	{0xe0, 0x00, 0x0a},
119 	{0x08, 0x03, 0x1b},
120 	{0x00, 0x0a, 0x3c},
121 	{0xff, 0xff, 0xfd},
122 	{0x00, 0x00, 0x0e},
123 	{0x1a, 0xba, 0x8f}
124 };
125 
126 static u8 al7230_init_table_amode[CB_AL7230_INIT_SEQ][3] = {
127 	{0x2f, 0xf5, 0x20},
128 	{0x00, 0x00, 0x01},
129 	{0x45, 0x1f, 0xe2},
130 	{0x5f, 0xdf, 0xa3},
131 	{0x6f, 0xd7, 0x84},
132 	{0x85, 0x3f, 0x55},
133 	{0x56, 0xaf, 0x36},
134 	{0xce, 0x02, 0x07},
135 	{0x6e, 0xbc, 0x98},
136 	{0x22, 0x1b, 0xb9},
137 	{0xe0, 0x60, 0x0a},
138 	{0x08, 0x03, 0x1b},
139 	{0x00, 0x14, 0x7c},
140 	{0xff, 0xff, 0xfd},
141 	{0x00, 0x00, 0x0e},
142 	{0x12, 0xba, 0xcf}
143 };
144 
145 static u8 al7230_channel_table0[CB_MAX_CHANNEL][3] = {
146 	{0x20, 0x37, 0x90},
147 	{0x20, 0x37, 0x90},
148 	{0x20, 0x37, 0x90},
149 	{0x20, 0x37, 0x90},
150 	{0x20, 0x37, 0xa0},
151 	{0x20, 0x37, 0xa0},
152 	{0x20, 0x37, 0xa0},
153 	{0x20, 0x37, 0xa0},
154 	{0x20, 0x37, 0xb0},
155 	{0x20, 0x37, 0xb0},
156 	{0x20, 0x37, 0xb0},
157 	{0x20, 0x37, 0xb0},
158 	{0x20, 0x37, 0xc0},
159 	{0x20, 0x37, 0xc0},
160 	{0x0f, 0xf5, 0x20}, /* channel 15 Tf = 4915MHz */
161 	{0x2f, 0xf5, 0x20},
162 	{0x0f, 0xf5, 0x20},
163 	{0x0f, 0xf5, 0x20},
164 	{0x2f, 0xf5, 0x20},
165 	{0x0f, 0xf5, 0x20},
166 	{0x2f, 0xf5, 0x30},
167 	{0x2f, 0xf5, 0x30},
168 	{0x0f, 0xf5, 0x40},
169 	{0x2f, 0xf5, 0x40},
170 	{0x0f, 0xf5, 0x40},
171 	{0x0f, 0xf5, 0x40},
172 	{0x2f, 0xf5, 0x40},
173 	{0x2f, 0xf5, 0x50},
174 	{0x2f, 0xf5, 0x60},
175 	{0x2f, 0xf5, 0x60},
176 	{0x2f, 0xf5, 0x70},
177 	{0x2f, 0xf5, 0x70},
178 	{0x2f, 0xf5, 0x70},
179 	{0x2f, 0xf5, 0x70},
180 	{0x2f, 0xf5, 0x70},
181 	{0x2f, 0xf5, 0x70},
182 	{0x2f, 0xf5, 0x80},
183 	{0x2f, 0xf5, 0x80},
184 	{0x2f, 0xf5, 0x80},
185 	{0x2f, 0xf5, 0x90},
186 	{0x2f, 0xf5, 0xc0},
187 	{0x2f, 0xf5, 0xc0},
188 	{0x2f, 0xf5, 0xc0},
189 	{0x2f, 0xf5, 0xd0},
190 	{0x2f, 0xf5, 0xd0},
191 	{0x2f, 0xf5, 0xd0},
192 	{0x2f, 0xf5, 0xe0},
193 	{0x2f, 0xf5, 0xe0},
194 	{0x2f, 0xf5, 0xe0},
195 	{0x2f, 0xf5, 0xf0},
196 	{0x2f, 0xf5, 0xf0},
197 	{0x2f, 0xf6, 0x00},
198 	{0x2f, 0xf6, 0x00},
199 	{0x2f, 0xf6, 0x00},
200 	{0x2f, 0xf6, 0x10},
201 	{0x2f, 0xf6, 0x10}
202 };
203 
204 static u8 al7230_channel_table1[CB_MAX_CHANNEL][3] = {
205 	{0x13, 0x33, 0x31},
206 	{0x1b, 0x33, 0x31},
207 	{0x03, 0x33, 0x31},
208 	{0x0b, 0x33, 0x31},
209 	{0x13, 0x33, 0x31},
210 	{0x1b, 0x33, 0x31},
211 	{0x03, 0x33, 0x31},
212 	{0x0b, 0x33, 0x31},
213 	{0x13, 0x33, 0x31},
214 	{0x1b, 0x33, 0x31},
215 	{0x03, 0x33, 0x31},
216 	{0x0b, 0x33, 0x31},
217 	{0x13, 0x33, 0x31},
218 	{0x06, 0x66, 0x61},
219 	{0x1d, 0x55, 0x51}, /* channel = 15, Tf = 4915MHz */
220 	{0x00, 0x00, 0x01},
221 	{0x02, 0xaa, 0xa1},
222 	{0x08, 0x00, 0x01},
223 	{0x0a, 0xaa, 0xa1},
224 	{0x0d, 0x55, 0x51},
225 	{0x15, 0x55, 0x51},
226 	{0x00, 0x00, 0x01},
227 	{0x1d, 0x55, 0x51},
228 	{0x00, 0x00, 0x01},
229 	{0x02, 0xaa, 0xa1},
230 	{0x08, 0x00, 0x01},
231 	{0x0a, 0xaa, 0xa1},
232 	{0x15, 0x55, 0x51},
233 	{0x05, 0x55, 0x51},
234 	{0x0a, 0xaa, 0xa1},
235 	{0x10, 0x00, 0x01},
236 	{0x15, 0x55, 0x51},
237 	{0x1a, 0xaa, 0xa1},
238 	{0x00, 0x00, 0x01},
239 	{0x05, 0x55, 0x51},
240 	{0x0a, 0xaa, 0xa1},
241 	{0x15, 0x55, 0x51},
242 	{0x00, 0x00, 0x01},
243 	{0x0a, 0xaa, 0xa1},
244 	{0x15, 0x55, 0x51},
245 	{0x15, 0x55, 0x51},
246 	{0x00, 0x00, 0x01},
247 	{0x0a, 0xaa, 0xa1},
248 	{0x15, 0x55, 0x51},
249 	{0x00, 0x00, 0x01},
250 	{0x0a, 0xaa, 0xa1},
251 	{0x15, 0x55, 0x51},
252 	{0x00, 0x00, 0x01},
253 	{0x0a, 0xaa, 0xa1},
254 	{0x15, 0x55, 0x51},
255 	{0x00, 0x00, 0x01},
256 	{0x18, 0x00, 0x01},
257 	{0x02, 0xaa, 0xa1},
258 	{0x0d, 0x55, 0x51},
259 	{0x18, 0x00, 0x01},
260 	{0x02, 0xaa, 0xb1}
261 };
262 
263 static u8 al7230_channel_table2[CB_MAX_CHANNEL][3] = {
264 	{0x7f, 0xd7, 0x84},
265 	{0x7f, 0xd7, 0x84},
266 	{0x7f, 0xd7, 0x84},
267 	{0x7f, 0xd7, 0x84},
268 	{0x7f, 0xd7, 0x84},
269 	{0x7f, 0xd7, 0x84},
270 	{0x7f, 0xd7, 0x84},
271 	{0x7f, 0xd7, 0x84},
272 	{0x7f, 0xd7, 0x84},
273 	{0x7f, 0xd7, 0x84},
274 	{0x7f, 0xd7, 0x84},
275 	{0x7f, 0xd7, 0x84},
276 	{0x7f, 0xd7, 0x84},
277 	{0x7f, 0xd7, 0x84},
278 	{0x7f, 0xd7, 0x84}, /* channel = 15 Tf = 4915MHz */
279 	{0x6f, 0xd7, 0x84},
280 	{0x7f, 0xd7, 0x84},
281 	{0x7f, 0xd7, 0x84},
282 	{0x7f, 0xd7, 0x84},
283 	{0x7f, 0xd7, 0x84},
284 	{0x7f, 0xd7, 0x84},
285 	{0x6f, 0xd7, 0x84},
286 	{0x7f, 0xd7, 0x84},
287 	{0x6f, 0xd7, 0x84},
288 	{0x7f, 0xd7, 0x84},
289 	{0x7f, 0xd7, 0x84},
290 	{0x7f, 0xd7, 0x84},
291 	{0x7f, 0xd7, 0x84},
292 	{0x7f, 0xd7, 0x84},
293 	{0x7f, 0xd7, 0x84},
294 	{0x7f, 0xd7, 0x84},
295 	{0x7f, 0xd7, 0x84},
296 	{0x7f, 0xd7, 0x84},
297 	{0x6f, 0xd7, 0x84},
298 	{0x7f, 0xd7, 0x84},
299 	{0x7f, 0xd7, 0x84},
300 	{0x7f, 0xd7, 0x84},
301 	{0x6f, 0xd7, 0x84},
302 	{0x7f, 0xd7, 0x84},
303 	{0x7f, 0xd7, 0x84},
304 	{0x7f, 0xd7, 0x84},
305 	{0x6f, 0xd7, 0x84},
306 	{0x7f, 0xd7, 0x84},
307 	{0x7f, 0xd7, 0x84},
308 	{0x6f, 0xd7, 0x84},
309 	{0x7f, 0xd7, 0x84},
310 	{0x7f, 0xd7, 0x84},
311 	{0x6f, 0xd7, 0x84},
312 	{0x7f, 0xd7, 0x84},
313 	{0x7f, 0xd7, 0x84},
314 	{0x6f, 0xd7, 0x84},
315 	{0x7f, 0xd7, 0x84},
316 	{0x7f, 0xd7, 0x84},
317 	{0x7f, 0xd7, 0x84},
318 	{0x7f, 0xd7, 0x84},
319 	{0x7f, 0xd7, 0x84}
320 };
321 
322 static u8 vt3226_init_table[CB_VT3226_INIT_SEQ][3] = {
323 	{0x03, 0xff, 0x80},
324 	{0x02, 0x82, 0xa1},
325 	{0x03, 0xc6, 0xa2},
326 	{0x01, 0x97, 0x93},
327 	{0x03, 0x66, 0x64},
328 	{0x00, 0x61, 0xa5},
329 	{0x01, 0x7b, 0xd6},
330 	{0x00, 0x80, 0x17},
331 	{0x03, 0xf8, 0x08},
332 	{0x00, 0x02, 0x39},
333 	{0x02, 0x00, 0x2a}
334 };
335 
336 static u8 vt3226d0_init_table[CB_VT3226_INIT_SEQ][3] = {
337 	{0x03, 0xff, 0x80},
338 	{0x03, 0x02, 0x21},
339 	{0x03, 0xc6, 0xa2},
340 	{0x01, 0x97, 0x93},
341 	{0x03, 0x66, 0x64},
342 	{0x00, 0x71, 0xa5},
343 	{0x01, 0x15, 0xc6},
344 	{0x01, 0x2e, 0x07},
345 	{0x00, 0x58, 0x08},
346 	{0x00, 0x02, 0x79},
347 	{0x02, 0x01, 0xaa}
348 };
349 
350 static u8 vt3226_channel_table0[CB_MAX_CHANNEL_24G][3] = {
351 	{0x01, 0x97, 0x83},
352 	{0x01, 0x97, 0x83},
353 	{0x01, 0x97, 0x93},
354 	{0x01, 0x97, 0x93},
355 	{0x01, 0x97, 0x93},
356 	{0x01, 0x97, 0x93},
357 	{0x01, 0x97, 0xa3},
358 	{0x01, 0x97, 0xa3},
359 	{0x01, 0x97, 0xa3},
360 	{0x01, 0x97, 0xa3},
361 	{0x01, 0x97, 0xb3},
362 	{0x01, 0x97, 0xb3},
363 	{0x01, 0x97, 0xb3},
364 	{0x03, 0x37, 0xc3}
365 };
366 
367 static u8 vt3226_channel_table1[CB_MAX_CHANNEL_24G][3] = {
368 	{0x02, 0x66, 0x64},
369 	{0x03, 0x66, 0x64},
370 	{0x00, 0x66, 0x64},
371 	{0x01, 0x66, 0x64},
372 	{0x02, 0x66, 0x64},
373 	{0x03, 0x66, 0x64},
374 	{0x00, 0x66, 0x64},
375 	{0x01, 0x66, 0x64},
376 	{0x02, 0x66, 0x64},
377 	{0x03, 0x66, 0x64},
378 	{0x00, 0x66, 0x64},
379 	{0x01, 0x66, 0x64},
380 	{0x02, 0x66, 0x64},
381 	{0x00, 0xcc, 0xc4}
382 };
383 
384 static const u32 vt3226d0_lo_current_table[CB_MAX_CHANNEL_24G] = {
385 	0x0135c600,
386 	0x0135c600,
387 	0x0235c600,
388 	0x0235c600,
389 	0x0235c600,
390 	0x0335c600,
391 	0x0335c600,
392 	0x0335c600,
393 	0x0335c600,
394 	0x0335c600,
395 	0x0335c600,
396 	0x0335c600,
397 	0x0335c600,
398 	0x0135c600
399 };
400 
401 static u8 vt3342a0_init_table[CB_VT3342_INIT_SEQ][3] = { /* 11b/g mode */
402 	{0x03, 0xff, 0x80},
403 	{0x02, 0x08, 0x81},
404 	{0x00, 0xc6, 0x02},
405 	{0x03, 0xc5, 0x13},
406 	{0x00, 0xee, 0xe4},
407 	{0x00, 0x71, 0xa5},
408 	{0x01, 0x75, 0x46},
409 	{0x01, 0x40, 0x27},
410 	{0x01, 0x54, 0x08},
411 	{0x00, 0x01, 0x69},
412 	{0x02, 0x00, 0xaa},
413 	{0x00, 0x08, 0xcb},
414 	{0x01, 0x70, 0x0c}
415 };
416 
417 static u8 vt3342_channel_table0[CB_MAX_CHANNEL][3] = {
418 	{0x02, 0x05, 0x03},
419 	{0x01, 0x15, 0x03},
420 	{0x03, 0xc5, 0x03},
421 	{0x02, 0x65, 0x03},
422 	{0x01, 0x15, 0x13},
423 	{0x03, 0xc5, 0x13},
424 	{0x02, 0x05, 0x13},
425 	{0x01, 0x15, 0x13},
426 	{0x03, 0xc5, 0x13},
427 	{0x02, 0x65, 0x13},
428 	{0x01, 0x15, 0x23},
429 	{0x03, 0xc5, 0x23},
430 	{0x02, 0x05, 0x23},
431 	{0x00, 0xd5, 0x23},
432 	{0x01, 0x15, 0x13}, /* channel = 15 Tf = 4915MHz */
433 	{0x01, 0x15, 0x13},
434 	{0x01, 0x15, 0x13},
435 	{0x01, 0x15, 0x13},
436 	{0x01, 0x15, 0x13},
437 	{0x01, 0x15, 0x13},
438 	{0x01, 0x15, 0x13},
439 	{0x01, 0x15, 0x13},
440 	{0x01, 0x15, 0x13},
441 	{0x01, 0x15, 0x13},
442 	{0x01, 0x15, 0x13},
443 	{0x01, 0x15, 0x13},
444 	{0x01, 0x15, 0x13},
445 	{0x01, 0x15, 0x13},
446 	{0x01, 0x15, 0x13},
447 	{0x01, 0x55, 0x63},
448 	{0x01, 0x55, 0x63},
449 	{0x02, 0xa5, 0x63},
450 	{0x02, 0xa5, 0x63},
451 	{0x00, 0x05, 0x73},
452 	{0x00, 0x05, 0x73},
453 	{0x01, 0x55, 0x73},
454 	{0x02, 0xa5, 0x73},
455 	{0x00, 0x05, 0x83},
456 	{0x01, 0x55, 0x83},
457 	{0x02, 0xa5, 0x83},
458 	{0x02, 0xa5, 0x83},
459 	{0x02, 0xa5, 0x83},
460 	{0x02, 0xa5, 0x83},
461 	{0x02, 0xa5, 0x83},
462 	{0x02, 0xa5, 0x83},
463 	{0x02, 0xa5, 0x83},
464 	{0x02, 0xa5, 0x83},
465 	{0x02, 0xa5, 0x83},
466 	{0x02, 0xa5, 0x83},
467 	{0x02, 0xa5, 0x83},
468 	{0x02, 0xa5, 0x83},
469 	{0x00, 0x05, 0xF3},
470 	{0x01, 0x56, 0x03},
471 	{0x02, 0xa6, 0x03},
472 	{0x00, 0x06, 0x03},
473 	{0x00, 0x06, 0x03}
474 };
475 
476 static u8 vt3342_channel_table1[CB_MAX_CHANNEL][3] = {
477 	{0x01, 0x99, 0x94},
478 	{0x02, 0x44, 0x44},
479 	{0x02, 0xee, 0xe4},
480 	{0x03, 0x99, 0x94},
481 	{0x00, 0x44, 0x44},
482 	{0x00, 0xee, 0xe4},
483 	{0x01, 0x99, 0x94},
484 	{0x02, 0x44, 0x44},
485 	{0x02, 0xee, 0xe4},
486 	{0x03, 0x99, 0x94},
487 	{0x00, 0x44, 0x44},
488 	{0x00, 0xee, 0xe4},
489 	{0x01, 0x99, 0x94},
490 	{0x03, 0x33, 0x34},
491 	{0x00, 0x44, 0x44}, /* channel = 15 Tf = 4915MHz */
492 	{0x00, 0x44, 0x44},
493 	{0x00, 0x44, 0x44},
494 	{0x00, 0x44, 0x44},
495 	{0x00, 0x44, 0x44},
496 	{0x00, 0x44, 0x44},
497 	{0x00, 0x44, 0x44},
498 	{0x00, 0x44, 0x44},
499 	{0x00, 0x44, 0x44},
500 	{0x00, 0x44, 0x44},
501 	{0x00, 0x44, 0x44},
502 	{0x00, 0x44, 0x44},
503 	{0x00, 0x44, 0x44},
504 	{0x00, 0x44, 0x44},
505 	{0x00, 0x44, 0x44},
506 	{0x01, 0x55, 0x54},
507 	{0x01, 0x55, 0x54},
508 	{0x02, 0xaa, 0xa4},
509 	{0x02, 0xaa, 0xa4},
510 	{0x00, 0x00, 0x04},
511 	{0x00, 0x00, 0x04},
512 	{0x01, 0x55, 0x54},
513 	{0x02, 0xaa, 0xa4},
514 	{0x00, 0x00, 0x04},
515 	{0x01, 0x55, 0x54},
516 	{0x02, 0xaa, 0xa4},
517 	{0x02, 0xaa, 0xa4},
518 	{0x02, 0xaa, 0xa4},
519 	{0x02, 0xaa, 0xa4},
520 	{0x02, 0xaa, 0xa4},
521 	{0x02, 0xaa, 0xa4},
522 	{0x02, 0xaa, 0xa4},
523 	{0x02, 0xaa, 0xa4},
524 	{0x02, 0xaa, 0xa4},
525 	{0x02, 0xaa, 0xa4},
526 	{0x02, 0xaa, 0xa4},
527 	{0x02, 0xaa, 0xa4},
528 	{0x03, 0x00, 0x04},
529 	{0x00, 0x55, 0x54},
530 	{0x01, 0xaa, 0xa4},
531 	{0x03, 0x00, 0x04},
532 	{0x03, 0x00, 0x04}
533 };
534 
535 /* Power Table */
536 static const u32 al2230_power_table[AL2230_PWR_IDX_LEN] = {
537 	0x04040900,
538 	0x04041900,
539 	0x04042900,
540 	0x04043900,
541 	0x04044900,
542 	0x04045900,
543 	0x04046900,
544 	0x04047900,
545 	0x04048900,
546 	0x04049900,
547 	0x0404a900,
548 	0x0404b900,
549 	0x0404c900,
550 	0x0404d900,
551 	0x0404e900,
552 	0x0404f900,
553 	0x04050900,
554 	0x04051900,
555 	0x04052900,
556 	0x04053900,
557 	0x04054900,
558 	0x04055900,
559 	0x04056900,
560 	0x04057900,
561 	0x04058900,
562 	0x04059900,
563 	0x0405a900,
564 	0x0405b900,
565 	0x0405c900,
566 	0x0405d900,
567 	0x0405e900,
568 	0x0405f900,
569 	0x04060900,
570 	0x04061900,
571 	0x04062900,
572 	0x04063900,
573 	0x04064900,
574 	0x04065900,
575 	0x04066900,
576 	0x04067900,
577 	0x04068900,
578 	0x04069900,
579 	0x0406a900,
580 	0x0406b900,
581 	0x0406c900,
582 	0x0406d900,
583 	0x0406e900,
584 	0x0406f900,
585 	0x04070900,
586 	0x04071900,
587 	0x04072900,
588 	0x04073900,
589 	0x04074900,
590 	0x04075900,
591 	0x04076900,
592 	0x04077900,
593 	0x04078900,
594 	0x04079900,
595 	0x0407a900,
596 	0x0407b900,
597 	0x0407c900,
598 	0x0407d900,
599 	0x0407e900,
600 	0x0407f900
601 };
602 
603 /*
604  * Description: Write to IF/RF, by embedded programming
605  */
606 int vnt_rf_write_embedded(struct vnt_private *priv, u32 data)
607 {
608 	u8 reg_data[4];
609 
610 	data |= (VNT_RF_REG_LEN << 3) | IFREGCTL_REGW;
611 
612 	reg_data[0] = (u8)data;
613 	reg_data[1] = (u8)(data >> 8);
614 	reg_data[2] = (u8)(data >> 16);
615 	reg_data[3] = (u8)(data >> 24);
616 
617 	vnt_control_out(priv, MESSAGE_TYPE_WRITE_IFRF,
618 				0, 0, ARRAY_SIZE(reg_data), reg_data);
619 
620 	return true;
621 }
622 
623 /* Set Tx power by rate and channel number */
624 int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel)
625 {
626 	u8 power = priv->cck_pwr;
627 
628 	if (channel == 0)
629 		return -EINVAL;
630 
631 	switch (rate) {
632 	case RATE_1M:
633 	case RATE_2M:
634 	case RATE_5M:
635 	case RATE_11M:
636 		channel--;
637 
638 		if (channel < sizeof(priv->cck_pwr_tbl))
639 			power = priv->cck_pwr_tbl[channel];
640 		break;
641 	case RATE_6M:
642 	case RATE_9M:
643 	case RATE_12M:
644 	case RATE_18M:
645 	case RATE_24M:
646 	case RATE_36M:
647 	case RATE_48M:
648 	case RATE_54M:
649 		if (channel > CB_MAX_CHANNEL_24G)
650 			power = priv->ofdm_a_pwr_tbl[channel-15];
651 		else
652 			power = priv->ofdm_pwr_tbl[channel-1];
653 		break;
654 	}
655 
656 	return vnt_rf_set_txpower(priv, power, rate);
657 }
658 
659 static u8 vnt_rf_addpower(struct vnt_private *priv)
660 {
661 	s32 rssi = -priv->current_rssi;
662 
663 	if (!rssi)
664 		return 7;
665 
666 	if (priv->rf_type == RF_VT3226D0) {
667 		if (rssi < -70)
668 			return 9;
669 		else if (rssi < -65)
670 			return 7;
671 		else if (rssi < -60)
672 			return 5;
673 	} else {
674 		if (rssi < -80)
675 			return 9;
676 		else if (rssi < -75)
677 			return 7;
678 		else if (rssi < -70)
679 			return 5;
680 	}
681 
682 	return 0;
683 }
684 
685 /* Set Tx power by power level and rate */
686 int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
687 {
688 	u32 power_setting = 0;
689 	int ret = true;
690 
691 	power += vnt_rf_addpower(priv);
692 	if (power > VNT_RF_MAX_POWER)
693 		power = VNT_RF_MAX_POWER;
694 
695 	if (priv->power == power)
696 		return true;
697 
698 	priv->power = power;
699 
700 	switch (priv->rf_type) {
701 	case RF_AL2230:
702 		if (power >= AL2230_PWR_IDX_LEN)
703 			return false;
704 
705 		ret &= vnt_rf_write_embedded(priv, al2230_power_table[power]);
706 
707 		if (rate <= RATE_11M)
708 			ret &= vnt_rf_write_embedded(priv, 0x0001b400);
709 		else
710 			ret &= vnt_rf_write_embedded(priv, 0x0005a400);
711 		break;
712 	case RF_AL2230S:
713 		if (power >= AL2230_PWR_IDX_LEN)
714 			return false;
715 
716 		ret &= vnt_rf_write_embedded(priv, al2230_power_table[power]);
717 
718 		if (rate <= RATE_11M) {
719 			ret &= vnt_rf_write_embedded(priv, 0x040c1400);
720 			ret &= vnt_rf_write_embedded(priv, 0x00299b00);
721 		} else {
722 			ret &= vnt_rf_write_embedded(priv, 0x0005a400);
723 			ret &= vnt_rf_write_embedded(priv, 0x00099b00);
724 		}
725 		break;
726 
727 	case RF_AIROHA7230:
728 		if (rate <= RATE_11M)
729 			ret &= vnt_rf_write_embedded(priv, 0x111bb900);
730 		else
731 			ret &= vnt_rf_write_embedded(priv, 0x221bb900);
732 
733 		if (power >= AL7230_PWR_IDX_LEN)
734 			return false;
735 
736 		/*
737 		* 0x080F1B00 for 3 wire control TxGain(D10)
738 		* and 0x31 as TX Gain value
739 		*/
740 		power_setting = 0x080c0b00 | (power << 12);
741 
742 		ret &= vnt_rf_write_embedded(priv, power_setting);
743 
744 		break;
745 
746 	case RF_VT3226:
747 		if (power >= VT3226_PWR_IDX_LEN)
748 			return false;
749 		power_setting = ((0x3f - power) << 20) | (0x17 << 8);
750 
751 		ret &= vnt_rf_write_embedded(priv, power_setting);
752 
753 		break;
754 	case RF_VT3226D0:
755 		if (power >= VT3226_PWR_IDX_LEN)
756 			return false;
757 
758 		if (rate <= RATE_11M) {
759 			u16 hw_value = priv->hw->conf.chandef.chan->hw_value;
760 
761 			power_setting = ((0x3f - power) << 20) | (0xe07 << 8);
762 
763 			ret &= vnt_rf_write_embedded(priv, power_setting);
764 			ret &= vnt_rf_write_embedded(priv, 0x03c6a200);
765 
766 			dev_dbg(&priv->usb->dev,
767 				"%s 11b channel [%d]\n", __func__, hw_value);
768 
769 			hw_value--;
770 
771 			if (hw_value < ARRAY_SIZE(vt3226d0_lo_current_table))
772 				ret &= vnt_rf_write_embedded(priv,
773 					vt3226d0_lo_current_table[hw_value]);
774 
775 			ret &= vnt_rf_write_embedded(priv, 0x015C0800);
776 		} else {
777 			dev_dbg(&priv->usb->dev,
778 					"@@@@ vnt_rf_set_txpower> 11G mode\n");
779 
780 			power_setting = ((0x3f - power) << 20) | (0x7 << 8);
781 
782 			ret &= vnt_rf_write_embedded(priv, power_setting);
783 			ret &= vnt_rf_write_embedded(priv, 0x00C6A200);
784 			ret &= vnt_rf_write_embedded(priv, 0x016BC600);
785 			ret &= vnt_rf_write_embedded(priv, 0x00900800);
786 		}
787 		break;
788 
789 	case RF_VT3342A0:
790 		if (power >= VT3342_PWR_IDX_LEN)
791 			return false;
792 
793 		power_setting =  ((0x3f - power) << 20) | (0x27 << 8);
794 
795 		ret &= vnt_rf_write_embedded(priv, power_setting);
796 
797 		break;
798 	default:
799 		break;
800 	}
801 	return ret;
802 }
803 
804 /* Convert rssi to dbm */
805 void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm)
806 {
807 	u8 idx = (((rssi & 0xc0) >> 6) & 0x03);
808 	long b = (rssi & 0x3f);
809 	long a = 0;
810 	u8 airoharf[4] = {0, 18, 0, 40};
811 
812 	switch (priv->rf_type) {
813 	case RF_AL2230:
814 	case RF_AL2230S:
815 	case RF_AIROHA7230:
816 	case RF_VT3226:
817 	case RF_VT3226D0:
818 	case RF_VT3342A0:
819 		a = airoharf[idx];
820 		break;
821 	default:
822 		break;
823 	}
824 
825 	*dbm = -1 * (a + b * 2);
826 }
827 
828 void vnt_rf_table_download(struct vnt_private *priv)
829 {
830 	u16 length1 = 0, length2 = 0, length3 = 0;
831 	u8 *addr1 = NULL, *addr2 = NULL, *addr3 = NULL;
832 	u16 length, value;
833 	u8 array[256];
834 
835 	switch (priv->rf_type) {
836 	case RF_AL2230:
837 	case RF_AL2230S:
838 		length1 = CB_AL2230_INIT_SEQ * 3;
839 		length2 = CB_MAX_CHANNEL_24G * 3;
840 		length3 = CB_MAX_CHANNEL_24G * 3;
841 		addr1 = &al2230_init_table[0][0];
842 		addr2 = &al2230_channel_table0[0][0];
843 		addr3 = &al2230_channel_table1[0][0];
844 		break;
845 	case RF_AIROHA7230:
846 		length1 = CB_AL7230_INIT_SEQ * 3;
847 		length2 = CB_MAX_CHANNEL * 3;
848 		length3 = CB_MAX_CHANNEL * 3;
849 		addr1 = &al7230_init_table[0][0];
850 		addr2 = &al7230_channel_table0[0][0];
851 		addr3 = &al7230_channel_table1[0][0];
852 		break;
853 	case RF_VT3226:
854 		length1 = CB_VT3226_INIT_SEQ * 3;
855 		length2 = CB_MAX_CHANNEL_24G * 3;
856 		length3 = CB_MAX_CHANNEL_24G * 3;
857 		addr1 = &vt3226_init_table[0][0];
858 		addr2 = &vt3226_channel_table0[0][0];
859 		addr3 = &vt3226_channel_table1[0][0];
860 		break;
861 	case RF_VT3226D0:
862 		length1 = CB_VT3226_INIT_SEQ * 3;
863 		length2 = CB_MAX_CHANNEL_24G * 3;
864 		length3 = CB_MAX_CHANNEL_24G * 3;
865 		addr1 = &vt3226d0_init_table[0][0];
866 		addr2 = &vt3226_channel_table0[0][0];
867 		addr3 = &vt3226_channel_table1[0][0];
868 		break;
869 	case RF_VT3342A0:
870 		length1 = CB_VT3342_INIT_SEQ * 3;
871 		length2 = CB_MAX_CHANNEL * 3;
872 		length3 = CB_MAX_CHANNEL * 3;
873 		addr1 = &vt3342a0_init_table[0][0];
874 		addr2 = &vt3342_channel_table0[0][0];
875 		addr3 = &vt3342_channel_table1[0][0];
876 		break;
877 	}
878 
879 	/* Init Table */
880 	memcpy(array, addr1, length1);
881 
882 	vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0,
883 		MESSAGE_REQUEST_RF_INIT, length1, array);
884 
885 	/* Channel Table 0 */
886 	value = 0;
887 	while (length2 > 0) {
888 		if (length2 >= 64)
889 			length = 64;
890 		else
891 			length = length2;
892 
893 		memcpy(array, addr2, length);
894 
895 		vnt_control_out(priv, MESSAGE_TYPE_WRITE,
896 			value, MESSAGE_REQUEST_RF_CH0, length, array);
897 
898 		length2 -= length;
899 		value += length;
900 		addr2 += length;
901 	}
902 
903 	/* Channel table 1 */
904 	value = 0;
905 	while (length3 > 0) {
906 		if (length3 >= 64)
907 			length = 64;
908 		else
909 			length = length3;
910 
911 		memcpy(array, addr3, length);
912 
913 		vnt_control_out(priv, MESSAGE_TYPE_WRITE,
914 			value, MESSAGE_REQUEST_RF_CH1, length, array);
915 
916 		length3 -= length;
917 		value += length;
918 		addr3 += length;
919 	}
920 
921 	if (priv->rf_type == RF_AIROHA7230) {
922 		length1 = CB_AL7230_INIT_SEQ * 3;
923 		length2 = CB_MAX_CHANNEL * 3;
924 		addr1 = &(al7230_init_table_amode[0][0]);
925 		addr2 = &(al7230_channel_table2[0][0]);
926 
927 		memcpy(array, addr1, length1);
928 
929 		/* Init Table 2 */
930 		vnt_control_out(priv, MESSAGE_TYPE_WRITE,
931 			0, MESSAGE_REQUEST_RF_INIT2, length1, array);
932 
933 		/* Channel Table 0 */
934 		value = 0;
935 		while (length2 > 0) {
936 			if (length2 >= 64)
937 				length = 64;
938 			else
939 				length = length2;
940 
941 			memcpy(array, addr2, length);
942 
943 			vnt_control_out(priv, MESSAGE_TYPE_WRITE,
944 				value, MESSAGE_REQUEST_RF_CH2, length, array);
945 
946 			length2 -= length;
947 			value += length;
948 			addr2 += length;
949 		}
950 	}
951 }
952