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