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