GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / net / wireless / realtek / rtl818x / rtl8187 / rtl8225.c
1 /*
2  * Radio tuning for RTL8225 on RTL8187
3  *
4  * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5  * Copyright 2007 Andrea Merello <andrea.merello@gmail.com>
6  *
7  * Based on the r8187 driver, which is:
8  * Copyright 2005 Andrea Merello <andrea.merello@gmail.com>, 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/usb.h>
20 #include <net/mac80211.h>
21
22 #include "rtl8187.h"
23 #include "rtl8225.h"
24
25 u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv,
26                                 u8 *addr, u8 idx)
27 {
28         u8 val;
29
30         mutex_lock(&priv->io_mutex);
31         usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
32                         RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
33                         (unsigned long)addr, idx & 0x03,
34                         &priv->io_dmabuf->bits8, sizeof(val), 500);
35
36         val = priv->io_dmabuf->bits8;
37         mutex_unlock(&priv->io_mutex);
38
39         return val;
40 }
41
42 u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv,
43                                 __le16 *addr, u8 idx)
44 {
45         __le16 val;
46
47         mutex_lock(&priv->io_mutex);
48         usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
49                         RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
50                         (unsigned long)addr, idx & 0x03,
51                         &priv->io_dmabuf->bits16, sizeof(val), 500);
52
53         val = priv->io_dmabuf->bits16;
54         mutex_unlock(&priv->io_mutex);
55
56         return le16_to_cpu(val);
57 }
58
59 u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv,
60                                 __le32 *addr, u8 idx)
61 {
62         __le32 val;
63
64         mutex_lock(&priv->io_mutex);
65         usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
66                         RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
67                         (unsigned long)addr, idx & 0x03,
68                         &priv->io_dmabuf->bits32, sizeof(val), 500);
69
70         val = priv->io_dmabuf->bits32;
71         mutex_unlock(&priv->io_mutex);
72
73         return le32_to_cpu(val);
74 }
75
76 void rtl818x_iowrite8_idx(struct rtl8187_priv *priv,
77                                 u8 *addr, u8 val, u8 idx)
78 {
79         mutex_lock(&priv->io_mutex);
80
81         priv->io_dmabuf->bits8 = val;
82         usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
83                         RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
84                         (unsigned long)addr, idx & 0x03,
85                         &priv->io_dmabuf->bits8, sizeof(val), 500);
86
87         mutex_unlock(&priv->io_mutex);
88 }
89
90 void rtl818x_iowrite16_idx(struct rtl8187_priv *priv,
91                                 __le16 *addr, u16 val, u8 idx)
92 {
93         mutex_lock(&priv->io_mutex);
94
95         priv->io_dmabuf->bits16 = cpu_to_le16(val);
96         usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
97                         RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
98                         (unsigned long)addr, idx & 0x03,
99                         &priv->io_dmabuf->bits16, sizeof(val), 500);
100
101         mutex_unlock(&priv->io_mutex);
102 }
103
104 void rtl818x_iowrite32_idx(struct rtl8187_priv *priv,
105                                 __le32 *addr, u32 val, u8 idx)
106 {
107         mutex_lock(&priv->io_mutex);
108
109         priv->io_dmabuf->bits32 = cpu_to_le32(val);
110         usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
111                         RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
112                         (unsigned long)addr, idx & 0x03,
113                         &priv->io_dmabuf->bits32, sizeof(val), 500);
114
115         mutex_unlock(&priv->io_mutex);
116 }
117
118 static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data)
119 {
120         struct rtl8187_priv *priv = dev->priv;
121         u16 reg80, reg84, reg82;
122         u32 bangdata;
123         int i;
124
125         bangdata = (data << 4) | (addr & 0xf);
126
127         reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
128         reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
129
130         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
131
132         reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
133         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7);
134         udelay(10);
135
136         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
137         udelay(2);
138         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
139         udelay(10);
140
141         for (i = 15; i >= 0; i--) {
142                 u16 reg = reg80 | (bangdata & (1 << i)) >> i;
143
144                 if (i & 1)
145                         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
146
147                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
148                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
149
150                 if (!(i & 1))
151                         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
152         }
153
154         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
155         udelay(10);
156
157         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
158         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
159 }
160
161 static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data)
162 {
163         struct rtl8187_priv *priv = dev->priv;
164         u16 reg80, reg82, reg84;
165
166         reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
167         reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
168         reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
169
170         reg80 &= ~(0x3 << 2);
171         reg84 &= ~0xF;
172
173         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x0007);
174         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x0007);
175         udelay(10);
176
177         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
178         udelay(2);
179
180         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
181         udelay(10);
182
183         mutex_lock(&priv->io_mutex);
184
185         priv->io_dmabuf->bits16 = data;
186         usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
187                         RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
188                         addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data),
189                         500);
190
191         mutex_unlock(&priv->io_mutex);
192
193         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
194         udelay(10);
195
196         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
197         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
198 }
199
200 static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
201 {
202         struct rtl8187_priv *priv = dev->priv;
203
204         if (priv->asic_rev)
205                 rtl8225_write_8051(dev, addr, cpu_to_le16(data));
206         else
207                 rtl8225_write_bitbang(dev, addr, data);
208 }
209
210 static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
211 {
212         struct rtl8187_priv *priv = dev->priv;
213         u16 reg80, reg82, reg84, out;
214         int i;
215
216         reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
217         reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
218         reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
219
220         reg80 &= ~0xF;
221
222         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
223         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
224
225         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
226         udelay(4);
227         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
228         udelay(5);
229
230         for (i = 4; i >= 0; i--) {
231                 u16 reg = reg80 | ((addr >> i) & 1);
232
233                 if (!(i & 1)) {
234                         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
235                         udelay(1);
236                 }
237
238                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
239                                   reg | (1 << 1));
240                 udelay(2);
241                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
242                                   reg | (1 << 1));
243                 udelay(2);
244
245                 if (i & 1) {
246                         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
247                         udelay(1);
248                 }
249         }
250
251         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
252                           reg80 | (1 << 3) | (1 << 1));
253         udelay(2);
254         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
255                           reg80 | (1 << 3));
256         udelay(2);
257         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
258                           reg80 | (1 << 3));
259         udelay(2);
260
261         out = 0;
262         for (i = 11; i >= 0; i--) {
263                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
264                                   reg80 | (1 << 3));
265                 udelay(1);
266                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
267                                   reg80 | (1 << 3) | (1 << 1));
268                 udelay(2);
269                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
270                                   reg80 | (1 << 3) | (1 << 1));
271                 udelay(2);
272                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
273                                   reg80 | (1 << 3) | (1 << 1));
274                 udelay(2);
275
276                 if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
277                         out |= 1 << i;
278
279                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
280                                   reg80 | (1 << 3));
281                 udelay(2);
282         }
283
284         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
285                           reg80 | (1 << 3) | (1 << 2));
286         udelay(2);
287
288         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
289         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
290         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
291
292         return out;
293 }
294
295 static const u16 rtl8225bcd_rxgain[] = {
296         0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
297         0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
298         0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
299         0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
300         0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
301         0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
302         0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
303         0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
304         0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
305         0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
306         0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
307         0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
308 };
309
310 static const u8 rtl8225_agc[] = {
311         0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
312         0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
313         0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
314         0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
315         0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
316         0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
317         0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
318         0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
319         0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
320         0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
321         0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
322         0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
323         0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
324         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
325         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
326         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
327 };
328
329 static const u8 rtl8225_gain[] = {
330         0x23, 0x88, 0x7c, 0xa5, /* -82dBm */
331         0x23, 0x88, 0x7c, 0xb5, /* -82dBm */
332         0x23, 0x88, 0x7c, 0xc5, /* -82dBm */
333         0x33, 0x80, 0x79, 0xc5, /* -78dBm */
334         0x43, 0x78, 0x76, 0xc5, /* -74dBm */
335         0x53, 0x60, 0x73, 0xc5, /* -70dBm */
336         0x63, 0x58, 0x70, 0xc5, /* -66dBm */
337 };
338
339 static const u8 rtl8225_threshold[] = {
340         0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
341 };
342
343 static const u8 rtl8225_tx_gain_cck_ofdm[] = {
344         0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
345 };
346
347 static const u8 rtl8225_tx_power_cck[] = {
348         0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
349         0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
350         0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
351         0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
352         0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
353         0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
354 };
355
356 static const u8 rtl8225_tx_power_cck_ch14[] = {
357         0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
358         0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
359         0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
360         0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
361         0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
362         0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
363 };
364
365 static const u8 rtl8225_tx_power_ofdm[] = {
366         0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
367 };
368
369 static const u32 rtl8225_chan[] = {
370         0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
371         0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
372 };
373
374 static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
375 {
376         struct rtl8187_priv *priv = dev->priv;
377         u8 cck_power, ofdm_power;
378         const u8 *tmp;
379         u32 reg;
380         int i;
381
382         cck_power = priv->channels[channel - 1].hw_value & 0xF;
383         ofdm_power = priv->channels[channel - 1].hw_value >> 4;
384
385         cck_power = min(cck_power, (u8)11);
386         if (ofdm_power > (u8)15)
387                 ofdm_power = 25;
388         else
389                 ofdm_power += 10;
390
391         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
392                          rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
393
394         if (channel == 14)
395                 tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
396         else
397                 tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
398
399         for (i = 0; i < 8; i++)
400                 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
401
402         msleep(1); // FIXME: optional?
403
404         /* anaparam2 on */
405         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
406         reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
407         rtl818x_iowrite8(priv, &priv->map->CONFIG3,
408                         reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
409         rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
410                           RTL8187_RTL8225_ANAPARAM2_ON);
411         rtl818x_iowrite8(priv, &priv->map->CONFIG3,
412                         reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
413         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
414
415         rtl8225_write_phy_ofdm(dev, 2, 0x42);
416         rtl8225_write_phy_ofdm(dev, 6, 0x00);
417         rtl8225_write_phy_ofdm(dev, 8, 0x00);
418
419         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
420                          rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1);
421
422         tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
423
424         rtl8225_write_phy_ofdm(dev, 5, *tmp);
425         rtl8225_write_phy_ofdm(dev, 7, *tmp);
426
427         msleep(1);
428 }
429
430 static void rtl8225_rf_init(struct ieee80211_hw *dev)
431 {
432         struct rtl8187_priv *priv = dev->priv;
433         int i;
434
435         rtl8225_write(dev, 0x0, 0x067);
436         rtl8225_write(dev, 0x1, 0xFE0);
437         rtl8225_write(dev, 0x2, 0x44D);
438         rtl8225_write(dev, 0x3, 0x441);
439         rtl8225_write(dev, 0x4, 0x486);
440         rtl8225_write(dev, 0x5, 0xBC0);
441         rtl8225_write(dev, 0x6, 0xAE6);
442         rtl8225_write(dev, 0x7, 0x82A);
443         rtl8225_write(dev, 0x8, 0x01F);
444         rtl8225_write(dev, 0x9, 0x334);
445         rtl8225_write(dev, 0xA, 0xFD4);
446         rtl8225_write(dev, 0xB, 0x391);
447         rtl8225_write(dev, 0xC, 0x050);
448         rtl8225_write(dev, 0xD, 0x6DB);
449         rtl8225_write(dev, 0xE, 0x029);
450         rtl8225_write(dev, 0xF, 0x914); msleep(100);
451
452         rtl8225_write(dev, 0x2, 0xC4D); msleep(200);
453         rtl8225_write(dev, 0x2, 0x44D); msleep(200);
454
455         if (!(rtl8225_read(dev, 6) & (1 << 7))) {
456                 rtl8225_write(dev, 0x02, 0x0c4d);
457                 msleep(200);
458                 rtl8225_write(dev, 0x02, 0x044d);
459                 msleep(100);
460                 if (!(rtl8225_read(dev, 6) & (1 << 7)))
461                         wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n",
462                                    rtl8225_read(dev, 6));
463         }
464
465         rtl8225_write(dev, 0x0, 0x127);
466
467         for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
468                 rtl8225_write(dev, 0x1, i + 1);
469                 rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
470         }
471
472         rtl8225_write(dev, 0x0, 0x027);
473         rtl8225_write(dev, 0x0, 0x22F);
474
475         for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
476                 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
477                 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
478         }
479
480         msleep(1);
481
482         rtl8225_write_phy_ofdm(dev, 0x00, 0x01);
483         rtl8225_write_phy_ofdm(dev, 0x01, 0x02);
484         rtl8225_write_phy_ofdm(dev, 0x02, 0x42);
485         rtl8225_write_phy_ofdm(dev, 0x03, 0x00);
486         rtl8225_write_phy_ofdm(dev, 0x04, 0x00);
487         rtl8225_write_phy_ofdm(dev, 0x05, 0x00);
488         rtl8225_write_phy_ofdm(dev, 0x06, 0x40);
489         rtl8225_write_phy_ofdm(dev, 0x07, 0x00);
490         rtl8225_write_phy_ofdm(dev, 0x08, 0x40);
491         rtl8225_write_phy_ofdm(dev, 0x09, 0xfe);
492         rtl8225_write_phy_ofdm(dev, 0x0a, 0x09);
493         rtl8225_write_phy_ofdm(dev, 0x0b, 0x80);
494         rtl8225_write_phy_ofdm(dev, 0x0c, 0x01);
495         rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3);
496         rtl8225_write_phy_ofdm(dev, 0x0f, 0x38);
497         rtl8225_write_phy_ofdm(dev, 0x10, 0x84);
498         rtl8225_write_phy_ofdm(dev, 0x11, 0x06);
499         rtl8225_write_phy_ofdm(dev, 0x12, 0x20);
500         rtl8225_write_phy_ofdm(dev, 0x13, 0x20);
501         rtl8225_write_phy_ofdm(dev, 0x14, 0x00);
502         rtl8225_write_phy_ofdm(dev, 0x15, 0x40);
503         rtl8225_write_phy_ofdm(dev, 0x16, 0x00);
504         rtl8225_write_phy_ofdm(dev, 0x17, 0x40);
505         rtl8225_write_phy_ofdm(dev, 0x18, 0xef);
506         rtl8225_write_phy_ofdm(dev, 0x19, 0x19);
507         rtl8225_write_phy_ofdm(dev, 0x1a, 0x20);
508         rtl8225_write_phy_ofdm(dev, 0x1b, 0x76);
509         rtl8225_write_phy_ofdm(dev, 0x1c, 0x04);
510         rtl8225_write_phy_ofdm(dev, 0x1e, 0x95);
511         rtl8225_write_phy_ofdm(dev, 0x1f, 0x75);
512         rtl8225_write_phy_ofdm(dev, 0x20, 0x1f);
513         rtl8225_write_phy_ofdm(dev, 0x21, 0x27);
514         rtl8225_write_phy_ofdm(dev, 0x22, 0x16);
515         rtl8225_write_phy_ofdm(dev, 0x24, 0x46);
516         rtl8225_write_phy_ofdm(dev, 0x25, 0x20);
517         rtl8225_write_phy_ofdm(dev, 0x26, 0x90);
518         rtl8225_write_phy_ofdm(dev, 0x27, 0x88);
519
520         rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
521         rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
522         rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
523         rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
524
525         rtl8225_write_phy_cck(dev, 0x00, 0x98);
526         rtl8225_write_phy_cck(dev, 0x03, 0x20);
527         rtl8225_write_phy_cck(dev, 0x04, 0x7e);
528         rtl8225_write_phy_cck(dev, 0x05, 0x12);
529         rtl8225_write_phy_cck(dev, 0x06, 0xfc);
530         rtl8225_write_phy_cck(dev, 0x07, 0x78);
531         rtl8225_write_phy_cck(dev, 0x08, 0x2e);
532         rtl8225_write_phy_cck(dev, 0x10, 0x9b);
533         rtl8225_write_phy_cck(dev, 0x11, 0x88);
534         rtl8225_write_phy_cck(dev, 0x12, 0x47);
535         rtl8225_write_phy_cck(dev, 0x13, 0xd0);
536         rtl8225_write_phy_cck(dev, 0x19, 0x00);
537         rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
538         rtl8225_write_phy_cck(dev, 0x1b, 0x08);
539         rtl8225_write_phy_cck(dev, 0x40, 0x86);
540         rtl8225_write_phy_cck(dev, 0x41, 0x8d);
541         rtl8225_write_phy_cck(dev, 0x42, 0x15);
542         rtl8225_write_phy_cck(dev, 0x43, 0x18);
543         rtl8225_write_phy_cck(dev, 0x44, 0x1f);
544         rtl8225_write_phy_cck(dev, 0x45, 0x1e);
545         rtl8225_write_phy_cck(dev, 0x46, 0x1a);
546         rtl8225_write_phy_cck(dev, 0x47, 0x15);
547         rtl8225_write_phy_cck(dev, 0x48, 0x10);
548         rtl8225_write_phy_cck(dev, 0x49, 0x0a);
549         rtl8225_write_phy_cck(dev, 0x4a, 0x05);
550         rtl8225_write_phy_cck(dev, 0x4b, 0x02);
551         rtl8225_write_phy_cck(dev, 0x4c, 0x05);
552
553         rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D);
554
555         rtl8225_rf_set_tx_power(dev, 1);
556
557         /* RX antenna default to A */
558         rtl8225_write_phy_cck(dev, 0x10, 0x9b);                 /* B: 0xDB */
559         rtl8225_write_phy_ofdm(dev, 0x26, 0x90);                /* B: 0x10 */
560
561         rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
562         msleep(1);
563         rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
564
565         /* set sensitivity */
566         rtl8225_write(dev, 0x0c, 0x50);
567         rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
568         rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
569         rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
570         rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
571         rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]);
572 }
573
574 static const u8 rtl8225z2_agc[] = {
575         0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51, 0x4f,
576         0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
577         0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f,
578         0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
579         0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
580         0x01, 0x01, 0x01, 0x01, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
581         0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28,
582         0x28, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
583         0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30,
584         0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
585         0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
586 };
587 static const u8 rtl8225z2_ofdm[] = {
588         0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
589         0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
590         0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
591         0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
592         0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
593         0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
594         0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
595         0x6d, 0x3c, 0xfb, 0x07
596 };
597
598 static const u8 rtl8225z2_tx_power_cck_ch14[] = {
599         0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
600         0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
601         0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
602         0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
603 };
604
605 static const u8 rtl8225z2_tx_power_cck[] = {
606         0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
607         0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
608         0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
609         0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
610 };
611
612 static const u8 rtl8225z2_tx_power_ofdm[] = {
613         0x42, 0x00, 0x40, 0x00, 0x40
614 };
615
616 static const u8 rtl8225z2_tx_gain_cck_ofdm[] = {
617         0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
618         0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
619         0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
620         0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
621         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
622         0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
623 };
624
625 static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
626 {
627         struct rtl8187_priv *priv = dev->priv;
628         u8 cck_power, ofdm_power;
629         const u8 *tmp;
630         u32 reg;
631         int i;
632
633         cck_power = priv->channels[channel - 1].hw_value & 0xF;
634         ofdm_power = priv->channels[channel - 1].hw_value >> 4;
635
636         cck_power = min(cck_power, (u8)15);
637         cck_power += priv->txpwr_base & 0xF;
638         cck_power = min(cck_power, (u8)35);
639
640         if (ofdm_power > (u8)15)
641                 ofdm_power = 25;
642         else
643                 ofdm_power += 10;
644         ofdm_power += priv->txpwr_base >> 4;
645         ofdm_power = min(ofdm_power, (u8)35);
646
647         if (channel == 14)
648                 tmp = rtl8225z2_tx_power_cck_ch14;
649         else
650                 tmp = rtl8225z2_tx_power_cck;
651
652         for (i = 0; i < 8; i++)
653                 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
654
655         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
656                          rtl8225z2_tx_gain_cck_ofdm[cck_power]);
657         msleep(1);
658
659         /* anaparam2 on */
660         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
661         reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
662         rtl818x_iowrite8(priv, &priv->map->CONFIG3,
663                         reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
664         rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
665                           RTL8187_RTL8225_ANAPARAM2_ON);
666         rtl818x_iowrite8(priv, &priv->map->CONFIG3,
667                         reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
668         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
669
670         rtl8225_write_phy_ofdm(dev, 2, 0x42);
671         rtl8225_write_phy_ofdm(dev, 5, 0x00);
672         rtl8225_write_phy_ofdm(dev, 6, 0x40);
673         rtl8225_write_phy_ofdm(dev, 7, 0x00);
674         rtl8225_write_phy_ofdm(dev, 8, 0x40);
675
676         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
677                          rtl8225z2_tx_gain_cck_ofdm[ofdm_power]);
678         msleep(1);
679 }
680
681 static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
682 {
683         struct rtl8187_priv *priv = dev->priv;
684         u8 cck_power, ofdm_power;
685         const u8 *tmp;
686         int i;
687
688         cck_power = priv->channels[channel - 1].hw_value & 0xF;
689         ofdm_power = priv->channels[channel - 1].hw_value >> 4;
690
691         if (cck_power > 15)
692                 cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22;
693         else
694                 cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7;
695         cck_power += priv->txpwr_base & 0xF;
696         cck_power = min(cck_power, (u8)35);
697
698         if (ofdm_power > 15)
699                 ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25;
700         else
701                 ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10;
702         ofdm_power += (priv->txpwr_base >> 4) & 0xF;
703         ofdm_power = min(ofdm_power, (u8)35);
704
705         if (channel == 14)
706                 tmp = rtl8225z2_tx_power_cck_ch14;
707         else
708                 tmp = rtl8225z2_tx_power_cck;
709
710         if (priv->hw_rev == RTL8187BvB) {
711                 if (cck_power <= 6)
712                         ; /* do nothing */
713                 else if (cck_power <= 11)
714                         tmp += 8;
715                 else
716                         tmp += 16;
717         } else {
718                 if (cck_power <= 5)
719                         ; /* do nothing */
720                 else if (cck_power <= 11)
721                         tmp += 8;
722                 else if (cck_power <= 17)
723                         tmp += 16;
724                 else
725                         tmp += 24;
726         }
727
728         for (i = 0; i < 8; i++)
729                 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
730
731         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
732                          rtl8225z2_tx_gain_cck_ofdm[cck_power] << 1);
733         msleep(1);
734
735         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
736                          rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1);
737         if (priv->hw_rev == RTL8187BvB) {
738                 if (ofdm_power <= 11) {
739                         rtl8225_write_phy_ofdm(dev, 0x87, 0x60);
740                         rtl8225_write_phy_ofdm(dev, 0x89, 0x60);
741                 } else {
742                         rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
743                         rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
744                 }
745         } else {
746                 if (ofdm_power <= 11) {
747                         rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
748                         rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
749                 } else if (ofdm_power <= 17) {
750                         rtl8225_write_phy_ofdm(dev, 0x87, 0x54);
751                         rtl8225_write_phy_ofdm(dev, 0x89, 0x54);
752                 } else {
753                         rtl8225_write_phy_ofdm(dev, 0x87, 0x50);
754                         rtl8225_write_phy_ofdm(dev, 0x89, 0x50);
755                 }
756         }
757         msleep(1);
758 }
759
760 static const u16 rtl8225z2_rxgain[] = {
761         0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
762         0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
763         0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
764         0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
765         0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
766         0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
767         0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
768         0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
769         0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
770         0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
771         0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
772         0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
773 };
774
775 static const u8 rtl8225z2_gain_bg[] = {
776         0x23, 0x15, 0xa5, /* -82-1dBm */
777         0x23, 0x15, 0xb5, /* -82-2dBm */
778         0x23, 0x15, 0xc5, /* -82-3dBm */
779         0x33, 0x15, 0xc5, /* -78dBm */
780         0x43, 0x15, 0xc5, /* -74dBm */
781         0x53, 0x15, 0xc5, /* -70dBm */
782         0x63, 0x15, 0xc5  /* -66dBm */
783 };
784
785 static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
786 {
787         struct rtl8187_priv *priv = dev->priv;
788         int i;
789
790         rtl8225_write(dev, 0x0, 0x2BF);
791         rtl8225_write(dev, 0x1, 0xEE0);
792         rtl8225_write(dev, 0x2, 0x44D);
793         rtl8225_write(dev, 0x3, 0x441);
794         rtl8225_write(dev, 0x4, 0x8C3);
795         rtl8225_write(dev, 0x5, 0xC72);
796         rtl8225_write(dev, 0x6, 0x0E6);
797         rtl8225_write(dev, 0x7, 0x82A);
798         rtl8225_write(dev, 0x8, 0x03F);
799         rtl8225_write(dev, 0x9, 0x335);
800         rtl8225_write(dev, 0xa, 0x9D4);
801         rtl8225_write(dev, 0xb, 0x7BB);
802         rtl8225_write(dev, 0xc, 0x850);
803         rtl8225_write(dev, 0xd, 0xCDF);
804         rtl8225_write(dev, 0xe, 0x02B);
805         rtl8225_write(dev, 0xf, 0x114);
806         msleep(100);
807
808         rtl8225_write(dev, 0x0, 0x1B7);
809
810         for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
811                 rtl8225_write(dev, 0x1, i + 1);
812                 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
813         }
814
815         rtl8225_write(dev, 0x3, 0x080);
816         rtl8225_write(dev, 0x5, 0x004);
817         rtl8225_write(dev, 0x0, 0x0B7);
818         rtl8225_write(dev, 0x2, 0xc4D);
819
820         msleep(200);
821         rtl8225_write(dev, 0x2, 0x44D);
822         msleep(100);
823
824         if (!(rtl8225_read(dev, 6) & (1 << 7))) {
825                 rtl8225_write(dev, 0x02, 0x0C4D);
826                 msleep(200);
827                 rtl8225_write(dev, 0x02, 0x044D);
828                 msleep(100);
829                 if (!(rtl8225_read(dev, 6) & (1 << 7)))
830                         wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n",
831                                    rtl8225_read(dev, 6));
832         }
833
834         msleep(200);
835
836         rtl8225_write(dev, 0x0, 0x2BF);
837
838         for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
839                 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
840                 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
841         }
842
843         msleep(1);
844
845         rtl8225_write_phy_ofdm(dev, 0x00, 0x01);
846         rtl8225_write_phy_ofdm(dev, 0x01, 0x02);
847         rtl8225_write_phy_ofdm(dev, 0x02, 0x42);
848         rtl8225_write_phy_ofdm(dev, 0x03, 0x00);
849         rtl8225_write_phy_ofdm(dev, 0x04, 0x00);
850         rtl8225_write_phy_ofdm(dev, 0x05, 0x00);
851         rtl8225_write_phy_ofdm(dev, 0x06, 0x40);
852         rtl8225_write_phy_ofdm(dev, 0x07, 0x00);
853         rtl8225_write_phy_ofdm(dev, 0x08, 0x40);
854         rtl8225_write_phy_ofdm(dev, 0x09, 0xfe);
855         rtl8225_write_phy_ofdm(dev, 0x0a, 0x08);
856         rtl8225_write_phy_ofdm(dev, 0x0b, 0x80);
857         rtl8225_write_phy_ofdm(dev, 0x0c, 0x01);
858         rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
859         rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3);
860         rtl8225_write_phy_ofdm(dev, 0x0f, 0x38);
861         rtl8225_write_phy_ofdm(dev, 0x10, 0x84);
862         rtl8225_write_phy_ofdm(dev, 0x11, 0x07);
863         rtl8225_write_phy_ofdm(dev, 0x12, 0x20);
864         rtl8225_write_phy_ofdm(dev, 0x13, 0x20);
865         rtl8225_write_phy_ofdm(dev, 0x14, 0x00);
866         rtl8225_write_phy_ofdm(dev, 0x15, 0x40);
867         rtl8225_write_phy_ofdm(dev, 0x16, 0x00);
868         rtl8225_write_phy_ofdm(dev, 0x17, 0x40);
869         rtl8225_write_phy_ofdm(dev, 0x18, 0xef);
870         rtl8225_write_phy_ofdm(dev, 0x19, 0x19);
871         rtl8225_write_phy_ofdm(dev, 0x1a, 0x20);
872         rtl8225_write_phy_ofdm(dev, 0x1b, 0x15);
873         rtl8225_write_phy_ofdm(dev, 0x1c, 0x04);
874         rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5);
875         rtl8225_write_phy_ofdm(dev, 0x1e, 0x95);
876         rtl8225_write_phy_ofdm(dev, 0x1f, 0x75);
877         rtl8225_write_phy_ofdm(dev, 0x20, 0x1f);
878         rtl8225_write_phy_ofdm(dev, 0x21, 0x17);
879         rtl8225_write_phy_ofdm(dev, 0x22, 0x16);
880         rtl8225_write_phy_ofdm(dev, 0x23, 0x80);
881         rtl8225_write_phy_ofdm(dev, 0x24, 0x46);
882         rtl8225_write_phy_ofdm(dev, 0x25, 0x00);
883         rtl8225_write_phy_ofdm(dev, 0x26, 0x90);
884         rtl8225_write_phy_ofdm(dev, 0x27, 0x88);
885
886         rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]);
887         rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]);
888         rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]);
889         rtl8225_write_phy_ofdm(dev, 0x21, 0x37);
890
891         rtl8225_write_phy_cck(dev, 0x00, 0x98);
892         rtl8225_write_phy_cck(dev, 0x03, 0x20);
893         rtl8225_write_phy_cck(dev, 0x04, 0x7e);
894         rtl8225_write_phy_cck(dev, 0x05, 0x12);
895         rtl8225_write_phy_cck(dev, 0x06, 0xfc);
896         rtl8225_write_phy_cck(dev, 0x07, 0x78);
897         rtl8225_write_phy_cck(dev, 0x08, 0x2e);
898         rtl8225_write_phy_cck(dev, 0x10, 0x9b);
899         rtl8225_write_phy_cck(dev, 0x11, 0x88);
900         rtl8225_write_phy_cck(dev, 0x12, 0x47);
901         rtl8225_write_phy_cck(dev, 0x13, 0xd0);
902         rtl8225_write_phy_cck(dev, 0x19, 0x00);
903         rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
904         rtl8225_write_phy_cck(dev, 0x1b, 0x08);
905         rtl8225_write_phy_cck(dev, 0x40, 0x86);
906         rtl8225_write_phy_cck(dev, 0x41, 0x8d);
907         rtl8225_write_phy_cck(dev, 0x42, 0x15);
908         rtl8225_write_phy_cck(dev, 0x43, 0x18);
909         rtl8225_write_phy_cck(dev, 0x44, 0x36);
910         rtl8225_write_phy_cck(dev, 0x45, 0x35);
911         rtl8225_write_phy_cck(dev, 0x46, 0x2e);
912         rtl8225_write_phy_cck(dev, 0x47, 0x25);
913         rtl8225_write_phy_cck(dev, 0x48, 0x1c);
914         rtl8225_write_phy_cck(dev, 0x49, 0x12);
915         rtl8225_write_phy_cck(dev, 0x4a, 0x09);
916         rtl8225_write_phy_cck(dev, 0x4b, 0x04);
917         rtl8225_write_phy_cck(dev, 0x4c, 0x05);
918
919         rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1);
920
921         rtl8225z2_rf_set_tx_power(dev, 1);
922
923         /* RX antenna default to A */
924         rtl8225_write_phy_cck(dev, 0x10, 0x9b);                 /* B: 0xDB */
925         rtl8225_write_phy_ofdm(dev, 0x26, 0x90);                /* B: 0x10 */
926
927         rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
928         msleep(1);
929         rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
930 }
931
932 static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
933 {
934         struct rtl8187_priv *priv = dev->priv;
935         int i;
936
937         rtl8225_write(dev, 0x0, 0x0B7);
938         rtl8225_write(dev, 0x1, 0xEE0);
939         rtl8225_write(dev, 0x2, 0x44D);
940         rtl8225_write(dev, 0x3, 0x441);
941         rtl8225_write(dev, 0x4, 0x8C3);
942         rtl8225_write(dev, 0x5, 0xC72);
943         rtl8225_write(dev, 0x6, 0x0E6);
944         rtl8225_write(dev, 0x7, 0x82A);
945         rtl8225_write(dev, 0x8, 0x03F);
946         rtl8225_write(dev, 0x9, 0x335);
947         rtl8225_write(dev, 0xa, 0x9D4);
948         rtl8225_write(dev, 0xb, 0x7BB);
949         rtl8225_write(dev, 0xc, 0x850);
950         rtl8225_write(dev, 0xd, 0xCDF);
951         rtl8225_write(dev, 0xe, 0x02B);
952         rtl8225_write(dev, 0xf, 0x114);
953
954         rtl8225_write(dev, 0x0, 0x1B7);
955
956         for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
957                 rtl8225_write(dev, 0x1, i + 1);
958                 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
959         }
960
961         rtl8225_write(dev, 0x3, 0x080);
962         rtl8225_write(dev, 0x5, 0x004);
963         rtl8225_write(dev, 0x0, 0x0B7);
964
965         rtl8225_write(dev, 0x2, 0xC4D);
966
967         rtl8225_write(dev, 0x2, 0x44D);
968         rtl8225_write(dev, 0x0, 0x2BF);
969
970         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03);
971         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07);
972         rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
973
974         rtl8225_write_phy_ofdm(dev, 0x80, 0x12);
975         for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) {
976                 rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]);
977                 rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i);
978                 rtl8225_write_phy_ofdm(dev, 0xE, 0);
979         }
980         rtl8225_write_phy_ofdm(dev, 0x80, 0x10);
981
982         for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++)
983                 rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]);
984
985         rtl8225_write_phy_ofdm(dev, 0x97, 0x46);
986         rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6);
987         rtl8225_write_phy_ofdm(dev, 0x85, 0xfc);
988         rtl8225_write_phy_cck(dev, 0xc1, 0x88);
989 }
990
991 static void rtl8225_rf_stop(struct ieee80211_hw *dev)
992 {
993         rtl8225_write(dev, 0x4, 0x1f);
994 }
995
996 static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
997                                    struct ieee80211_conf *conf)
998 {
999         struct rtl8187_priv *priv = dev->priv;
1000         int chan =
1001                 ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
1002
1003         if (priv->rf->init == rtl8225_rf_init)
1004                 rtl8225_rf_set_tx_power(dev, chan);
1005         else if (priv->rf->init == rtl8225z2_rf_init)
1006                 rtl8225z2_rf_set_tx_power(dev, chan);
1007         else
1008                 rtl8225z2_b_rf_set_tx_power(dev, chan);
1009
1010         rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
1011         msleep(10);
1012 }
1013
1014 static const struct rtl818x_rf_ops rtl8225_ops = {
1015         .name           = "rtl8225",
1016         .init           = rtl8225_rf_init,
1017         .stop           = rtl8225_rf_stop,
1018         .set_chan       = rtl8225_rf_set_channel
1019 };
1020
1021 static const struct rtl818x_rf_ops rtl8225z2_ops = {
1022         .name           = "rtl8225z2",
1023         .init           = rtl8225z2_rf_init,
1024         .stop           = rtl8225_rf_stop,
1025         .set_chan       = rtl8225_rf_set_channel
1026 };
1027
1028 static const struct rtl818x_rf_ops rtl8225z2_b_ops = {
1029         .name           = "rtl8225z2",
1030         .init           = rtl8225z2_b_rf_init,
1031         .stop           = rtl8225_rf_stop,
1032         .set_chan       = rtl8225_rf_set_channel
1033 };
1034
1035 const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev)
1036 {
1037         u16 reg8, reg9;
1038         struct rtl8187_priv *priv = dev->priv;
1039
1040         if (!priv->is_rtl8187b) {
1041                 rtl8225_write(dev, 0, 0x1B7);
1042
1043                 reg8 = rtl8225_read(dev, 8);
1044                 reg9 = rtl8225_read(dev, 9);
1045
1046                 rtl8225_write(dev, 0, 0x0B7);
1047
1048                 if (reg8 != 0x588 || reg9 != 0x700)
1049                         return &rtl8225_ops;
1050
1051                 return &rtl8225z2_ops;
1052         } else
1053                 return &rtl8225z2_b_ops;
1054 }