OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [wireless/] [rtl8187_rtl8225.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * Radio tuning for RTL8225 on RTL8187
3
 *
4
 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5
 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6
 *
7
 * Based on the r8187 driver, which is:
8
 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9
 *
10
 * Magic delays, register offsets, and phy value tables below are
11
 * taken from the original r8187 driver sources.  Thanks to Realtek
12
 * for their support!
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License version 2 as
16
 * published by the Free Software Foundation.
17
 */
18
 
19
#include <linux/init.h>
20
#include <linux/usb.h>
21
#include <net/mac80211.h>
22
 
23
#include "rtl8187.h"
24
#include "rtl8187_rtl8225.h"
25
 
26
static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data)
27
{
28
        struct rtl8187_priv *priv = dev->priv;
29
        u16 reg80, reg84, reg82;
30
        u32 bangdata;
31
        int i;
32
 
33
        bangdata = (data << 4) | (addr & 0xf);
34
 
35
        reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
36
        reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
37
 
38
        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
39
 
40
        reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
41
        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7);
42
        udelay(10);
43
 
44
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
45
        udelay(2);
46
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
47
        udelay(10);
48
 
49
        for (i = 15; i >= 0; i--) {
50
                u16 reg = reg80 | (bangdata & (1 << i)) >> i;
51
 
52
                if (i & 1)
53
                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
54
 
55
                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
56
                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
57
 
58
                if (!(i & 1))
59
                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
60
        }
61
 
62
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
63
        udelay(10);
64
 
65
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
66
        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
67
        msleep(2);
68
}
69
 
70
static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data)
71
{
72
        struct rtl8187_priv *priv = dev->priv;
73
        u16 reg80, reg82, reg84;
74
 
75
        reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
76
        reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
77
        reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
78
 
79
        reg80 &= ~(0x3 << 2);
80
        reg84 &= ~0xF;
81
 
82
        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x0007);
83
        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x0007);
84
        udelay(10);
85
 
86
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
87
        udelay(2);
88
 
89
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
90
        udelay(10);
91
 
92
        usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
93
                        RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
94
                        addr, 0x8225, &data, sizeof(data), HZ / 2);
95
 
96
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
97
        udelay(10);
98
 
99
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
100
        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
101
        msleep(2);
102
}
103
 
104
void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
105
{
106
        struct rtl8187_priv *priv = dev->priv;
107
 
108
        if (priv->asic_rev)
109
                rtl8225_write_8051(dev, addr, cpu_to_le16(data));
110
        else
111
                rtl8225_write_bitbang(dev, addr, data);
112
}
113
 
114
u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
115
{
116
        struct rtl8187_priv *priv = dev->priv;
117
        u16 reg80, reg82, reg84, out;
118
        int i;
119
 
120
        reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
121
        reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
122
        reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
123
 
124
        reg80 &= ~0xF;
125
 
126
        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
127
        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
128
 
129
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
130
        udelay(4);
131
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
132
        udelay(5);
133
 
134
        for (i = 4; i >= 0; i--) {
135
                u16 reg = reg80 | ((addr >> i) & 1);
136
 
137
                if (!(i & 1)) {
138
                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
139
                        udelay(1);
140
                }
141
 
142
                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
143
                                  reg | (1 << 1));
144
                udelay(2);
145
                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
146
                                  reg | (1 << 1));
147
                udelay(2);
148
 
149
                if (i & 1) {
150
                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
151
                        udelay(1);
152
                }
153
        }
154
 
155
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
156
                          reg80 | (1 << 3) | (1 << 1));
157
        udelay(2);
158
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
159
                          reg80 | (1 << 3));
160
        udelay(2);
161
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
162
                          reg80 | (1 << 3));
163
        udelay(2);
164
 
165
        out = 0;
166
        for (i = 11; i >= 0; i--) {
167
                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
168
                                  reg80 | (1 << 3));
169
                udelay(1);
170
                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
171
                                  reg80 | (1 << 3) | (1 << 1));
172
                udelay(2);
173
                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
174
                                  reg80 | (1 << 3) | (1 << 1));
175
                udelay(2);
176
                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
177
                                  reg80 | (1 << 3) | (1 << 1));
178
                udelay(2);
179
 
180
                if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
181
                        out |= 1 << i;
182
 
183
                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
184
                                  reg80 | (1 << 3));
185
                udelay(2);
186
        }
187
 
188
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
189
                          reg80 | (1 << 3) | (1 << 2));
190
        udelay(2);
191
 
192
        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
193
        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
194
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
195
 
196
        return out;
197
}
198
 
199
static const u16 rtl8225bcd_rxgain[] = {
200
        0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
201
        0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
202
        0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
203
        0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
204
        0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
205
        0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
206
        0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
207
        0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
208
        0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
209
        0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
210
        0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
211
        0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
212
};
213
 
214
static const u8 rtl8225_agc[] = {
215
        0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
216
        0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
217
        0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
218
        0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
219
        0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
220
        0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
221
        0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
222
        0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
223
        0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
224
        0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
225
        0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
226
        0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
227
        0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
228
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
229
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
230
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
231
};
232
 
233
static const u8 rtl8225_gain[] = {
234
        0x23, 0x88, 0x7c, 0xa5, /* -82dBm */
235
        0x23, 0x88, 0x7c, 0xb5, /* -82dBm */
236
        0x23, 0x88, 0x7c, 0xc5, /* -82dBm */
237
        0x33, 0x80, 0x79, 0xc5, /* -78dBm */
238
        0x43, 0x78, 0x76, 0xc5, /* -74dBm */
239
        0x53, 0x60, 0x73, 0xc5, /* -70dBm */
240
        0x63, 0x58, 0x70, 0xc5, /* -66dBm */
241
};
242
 
243
static const u8 rtl8225_threshold[] = {
244
        0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
245
};
246
 
247
static const u8 rtl8225_tx_gain_cck_ofdm[] = {
248
        0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
249
};
250
 
251
static const u8 rtl8225_tx_power_cck[] = {
252
        0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
253
        0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
254
        0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
255
        0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
256
        0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
257
        0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
258
};
259
 
260
static const u8 rtl8225_tx_power_cck_ch14[] = {
261
        0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
262
        0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
263
        0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
264
        0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
265
        0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
266
        0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
267
};
268
 
269
static const u8 rtl8225_tx_power_ofdm[] = {
270
        0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
271
};
272
 
273
static const u32 rtl8225_chan[] = {
274
        0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
275
        0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
276
};
277
 
278
static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
279
{
280
        struct rtl8187_priv *priv = dev->priv;
281
        u8 cck_power, ofdm_power;
282
        const u8 *tmp;
283
        u32 reg;
284
        int i;
285
 
286
        cck_power = priv->channels[channel - 1].val & 0xF;
287
        ofdm_power = priv->channels[channel - 1].val >> 4;
288
 
289
        cck_power = min(cck_power, (u8)11);
290
        ofdm_power = min(ofdm_power, (u8)35);
291
 
292
        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
293
                         rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
294
 
295
        if (channel == 14)
296
                tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
297
        else
298
                tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
299
 
300
        for (i = 0; i < 8; i++)
301
                rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
302
 
303
        msleep(1); // FIXME: optional?
304
 
305
        /* anaparam2 on */
306
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
307
        reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
308
        rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
309
        rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
310
        rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
311
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
312
 
313
        rtl8225_write_phy_ofdm(dev, 2, 0x42);
314
        rtl8225_write_phy_ofdm(dev, 6, 0x00);
315
        rtl8225_write_phy_ofdm(dev, 8, 0x00);
316
 
317
        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
318
                         rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1);
319
 
320
        tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
321
 
322
        rtl8225_write_phy_ofdm(dev, 5, *tmp);
323
        rtl8225_write_phy_ofdm(dev, 7, *tmp);
324
 
325
        msleep(1);
326
}
327
 
328
void rtl8225_rf_init(struct ieee80211_hw *dev)
329
{
330
        struct rtl8187_priv *priv = dev->priv;
331
        int i;
332
 
333
        rtl8225_write(dev, 0x0, 0x067); msleep(1);
334
        rtl8225_write(dev, 0x1, 0xFE0); msleep(1);
335
        rtl8225_write(dev, 0x2, 0x44D); msleep(1);
336
        rtl8225_write(dev, 0x3, 0x441); msleep(1);
337
        rtl8225_write(dev, 0x4, 0x486); msleep(1);
338
        rtl8225_write(dev, 0x5, 0xBC0); msleep(1);
339
        rtl8225_write(dev, 0x6, 0xAE6); msleep(1);
340
        rtl8225_write(dev, 0x7, 0x82A); msleep(1);
341
        rtl8225_write(dev, 0x8, 0x01F); msleep(1);
342
        rtl8225_write(dev, 0x9, 0x334); msleep(1);
343
        rtl8225_write(dev, 0xA, 0xFD4); msleep(1);
344
        rtl8225_write(dev, 0xB, 0x391); msleep(1);
345
        rtl8225_write(dev, 0xC, 0x050); msleep(1);
346
        rtl8225_write(dev, 0xD, 0x6DB); msleep(1);
347
        rtl8225_write(dev, 0xE, 0x029); msleep(1);
348
        rtl8225_write(dev, 0xF, 0x914); msleep(100);
349
 
350
        rtl8225_write(dev, 0x2, 0xC4D); msleep(200);
351
        rtl8225_write(dev, 0x2, 0x44D); msleep(200);
352
 
353
        if (!(rtl8225_read(dev, 6) & (1 << 7))) {
354
                rtl8225_write(dev, 0x02, 0x0c4d);
355
                msleep(200);
356
                rtl8225_write(dev, 0x02, 0x044d);
357
                msleep(100);
358
                if (!(rtl8225_read(dev, 6) & (1 << 7)))
359
                        printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
360
                               wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
361
        }
362
 
363
        rtl8225_write(dev, 0x0, 0x127);
364
 
365
        for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
366
                rtl8225_write(dev, 0x1, i + 1);
367
                rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
368
        }
369
 
370
        rtl8225_write(dev, 0x0, 0x027);
371
        rtl8225_write(dev, 0x0, 0x22F);
372
 
373
        for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
374
                rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
375
                msleep(1);
376
                rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
377
                msleep(1);
378
        }
379
 
380
        msleep(1);
381
 
382
        rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
383
        rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
384
        rtl8225_write_phy_ofdm(dev, 0x02, 0x42); msleep(1);
385
        rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
386
        rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
387
        rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
388
        rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
389
        rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
390
        rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
391
        rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
392
        rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
393
        rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
394
        rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
395
        rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
396
        rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
397
        rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
398
        rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1);
399
        rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
400
        rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
401
        rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
402
        rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
403
        rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
404
        rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
405
        rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
406
        rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
407
        rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
408
        rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1);
409
        rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
410
        rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
411
        rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
412
        rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
413
        rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
414
        rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
415
        rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
416
        rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
417
        rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
418
        rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
419
 
420
        rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
421
        rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
422
        rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
423
        rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
424
 
425
        rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
426
        rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
427
        rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
428
        rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
429
        rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
430
        rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
431
        rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
432
        rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);
433
        rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
434
        rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
435
        rtl8225_write_phy_cck(dev, 0x13, 0xd0);
436
        rtl8225_write_phy_cck(dev, 0x19, 0x00);
437
        rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
438
        rtl8225_write_phy_cck(dev, 0x1b, 0x08);
439
        rtl8225_write_phy_cck(dev, 0x40, 0x86);
440
        rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
441
        rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
442
        rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
443
        rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1);
444
        rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1);
445
        rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1);
446
        rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1);
447
        rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1);
448
        rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1);
449
        rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1);
450
        rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1);
451
        rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
452
 
453
        rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D);
454
 
455
        rtl8225_rf_set_tx_power(dev, 1);
456
 
457
        /* RX antenna default to A */
458
        rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);      /* B: 0xDB */
459
        rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);     /* B: 0x10 */
460
 
461
        rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
462
        msleep(1);
463
        rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
464
 
465
        /* set sensitivity */
466
        rtl8225_write(dev, 0x0c, 0x50);
467
        rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
468
        rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
469
        rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
470
        rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
471
        rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]);
472
}
473
 
474
static const u8 rtl8225z2_tx_power_cck_ch14[] = {
475
        0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
476
};
477
 
478
static const u8 rtl8225z2_tx_power_cck[] = {
479
        0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
480
};
481
 
482
static const u8 rtl8225z2_tx_power_ofdm[] = {
483
        0x42, 0x00, 0x40, 0x00, 0x40
484
};
485
 
486
static const u8 rtl8225z2_tx_gain_cck_ofdm[] = {
487
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
488
        0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
489
        0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
490
        0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
491
        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
492
        0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
493
};
494
 
495
static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
496
{
497
        struct rtl8187_priv *priv = dev->priv;
498
        u8 cck_power, ofdm_power;
499
        const u8 *tmp;
500
        u32 reg;
501
        int i;
502
 
503
        cck_power = priv->channels[channel - 1].val & 0xF;
504
        ofdm_power = priv->channels[channel - 1].val >> 4;
505
 
506
        cck_power = min(cck_power, (u8)15);
507
        cck_power += priv->txpwr_base & 0xF;
508
        cck_power = min(cck_power, (u8)35);
509
 
510
        ofdm_power = min(ofdm_power, (u8)15);
511
        ofdm_power += priv->txpwr_base >> 4;
512
        ofdm_power = min(ofdm_power, (u8)35);
513
 
514
        if (channel == 14)
515
                tmp = rtl8225z2_tx_power_cck_ch14;
516
        else
517
                tmp = rtl8225z2_tx_power_cck;
518
 
519
        for (i = 0; i < 8; i++)
520
                rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
521
 
522
        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
523
                         rtl8225z2_tx_gain_cck_ofdm[cck_power]);
524
        msleep(1);
525
 
526
        /* anaparam2 on */
527
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
528
        reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
529
        rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
530
        rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
531
        rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
532
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
533
 
534
        rtl8225_write_phy_ofdm(dev, 2, 0x42);
535
        rtl8225_write_phy_ofdm(dev, 5, 0x00);
536
        rtl8225_write_phy_ofdm(dev, 6, 0x40);
537
        rtl8225_write_phy_ofdm(dev, 7, 0x00);
538
        rtl8225_write_phy_ofdm(dev, 8, 0x40);
539
 
540
        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
541
                         rtl8225z2_tx_gain_cck_ofdm[ofdm_power]);
542
        msleep(1);
543
}
544
 
545
static const u16 rtl8225z2_rxgain[] = {
546
        0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
547
        0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
548
        0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
549
        0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
550
        0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
551
        0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
552
        0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
553
        0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
554
        0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
555
        0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
556
        0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
557
        0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
558
};
559
 
560
static const u8 rtl8225z2_gain_bg[] = {
561
        0x23, 0x15, 0xa5, /* -82-1dBm */
562
        0x23, 0x15, 0xb5, /* -82-2dBm */
563
        0x23, 0x15, 0xc5, /* -82-3dBm */
564
        0x33, 0x15, 0xc5, /* -78dBm */
565
        0x43, 0x15, 0xc5, /* -74dBm */
566
        0x53, 0x15, 0xc5, /* -70dBm */
567
        0x63, 0x15, 0xc5  /* -66dBm */
568
};
569
 
570
void rtl8225z2_rf_init(struct ieee80211_hw *dev)
571
{
572
        struct rtl8187_priv *priv = dev->priv;
573
        int i;
574
 
575
        rtl8225_write(dev, 0x0, 0x2BF); msleep(1);
576
        rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
577
        rtl8225_write(dev, 0x2, 0x44D); msleep(1);
578
        rtl8225_write(dev, 0x3, 0x441); msleep(1);
579
        rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
580
        rtl8225_write(dev, 0x5, 0xC72); msleep(1);
581
        rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
582
        rtl8225_write(dev, 0x7, 0x82A); msleep(1);
583
        rtl8225_write(dev, 0x8, 0x03F); msleep(1);
584
        rtl8225_write(dev, 0x9, 0x335); msleep(1);
585
        rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
586
        rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
587
        rtl8225_write(dev, 0xc, 0x850); msleep(1);
588
        rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
589
        rtl8225_write(dev, 0xe, 0x02B); msleep(1);
590
        rtl8225_write(dev, 0xf, 0x114); msleep(100);
591
 
592
        rtl8225_write(dev, 0x0, 0x1B7);
593
 
594
        for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
595
                rtl8225_write(dev, 0x1, i + 1);
596
                rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
597
        }
598
 
599
        rtl8225_write(dev, 0x3, 0x080);
600
        rtl8225_write(dev, 0x5, 0x004);
601
        rtl8225_write(dev, 0x0, 0x0B7);
602
        rtl8225_write(dev, 0x2, 0xc4D);
603
 
604
        msleep(200);
605
        rtl8225_write(dev, 0x2, 0x44D);
606
        msleep(100);
607
 
608
        if (!(rtl8225_read(dev, 6) & (1 << 7))) {
609
                rtl8225_write(dev, 0x02, 0x0C4D);
610
                msleep(200);
611
                rtl8225_write(dev, 0x02, 0x044D);
612
                msleep(100);
613
                if (!(rtl8225_read(dev, 6) & (1 << 7)))
614
                        printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
615
                               wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
616
        }
617
 
618
        msleep(200);
619
 
620
        rtl8225_write(dev, 0x0, 0x2BF);
621
 
622
        for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
623
                rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
624
                msleep(1);
625
                rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
626
                msleep(1);
627
        }
628
 
629
        msleep(1);
630
 
631
        rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
632
        rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
633
        rtl8225_write_phy_ofdm(dev, 0x02, 0x42); msleep(1);
634
        rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
635
        rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
636
        rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
637
        rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
638
        rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
639
        rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
640
        rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
641
        rtl8225_write_phy_ofdm(dev, 0x0a, 0x08); msleep(1);
642
        rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
643
        rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
644
        rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
645
        rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
646
        rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
647
        rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
648
        rtl8225_write_phy_ofdm(dev, 0x11, 0x07); msleep(1);
649
        rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
650
        rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
651
        rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
652
        rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
653
        rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
654
        rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
655
        rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
656
        rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
657
        rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
658
        rtl8225_write_phy_ofdm(dev, 0x1b, 0x15); msleep(1);
659
        rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
660
        rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1);
661
        rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
662
        rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
663
        rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
664
        rtl8225_write_phy_ofdm(dev, 0x21, 0x17); msleep(1);
665
        rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
666
        rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); //FIXME: not needed?
667
        rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
668
        rtl8225_write_phy_ofdm(dev, 0x25, 0x00); msleep(1);
669
        rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
670
        rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
671
 
672
        rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]);
673
        rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]);
674
        rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]);
675
        rtl8225_write_phy_ofdm(dev, 0x21, 0x37);
676
 
677
        rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
678
        rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
679
        rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
680
        rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
681
        rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
682
        rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
683
        rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
684
        rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);
685
        rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
686
        rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
687
        rtl8225_write_phy_cck(dev, 0x13, 0xd0);
688
        rtl8225_write_phy_cck(dev, 0x19, 0x00);
689
        rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
690
        rtl8225_write_phy_cck(dev, 0x1b, 0x08);
691
        rtl8225_write_phy_cck(dev, 0x40, 0x86);
692
        rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
693
        rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
694
        rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
695
        rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1);
696
        rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1);
697
        rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1);
698
        rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1);
699
        rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1);
700
        rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1);
701
        rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1);
702
        rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1);
703
        rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
704
 
705
        rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1);
706
 
707
        rtl8225z2_rf_set_tx_power(dev, 1);
708
 
709
        /* RX antenna default to A */
710
        rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);      /* B: 0xDB */
711
        rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);     /* B: 0x10 */
712
 
713
        rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
714
        msleep(1);
715
        rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
716
}
717
 
718
void rtl8225_rf_stop(struct ieee80211_hw *dev)
719
{
720
        u8 reg;
721
        struct rtl8187_priv *priv = dev->priv;
722
 
723
        rtl8225_write(dev, 0x4, 0x1f); msleep(1);
724
 
725
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
726
        reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
727
        rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
728
        rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF);
729
        rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF);
730
        rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
731
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
732
}
733
 
734
void rtl8225_rf_set_channel(struct ieee80211_hw *dev, int channel)
735
{
736
        struct rtl8187_priv *priv = dev->priv;
737
 
738
        if (priv->rf_init == rtl8225_rf_init)
739
                rtl8225_rf_set_tx_power(dev, channel);
740
        else
741
                rtl8225z2_rf_set_tx_power(dev, channel);
742
 
743
        rtl8225_write(dev, 0x7, rtl8225_chan[channel - 1]);
744
        msleep(10);
745
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.