GNU Linux-libre 5.19-rc6-gnu
[releases.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), 500);
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), 500);
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), 500);
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), 500);
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), 500);
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), 500);
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                         500);
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_gain_cck_ofdm[] = {
610         0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
611         0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
612         0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
613         0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
614         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
615         0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
616 };
617
618 static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
619 {
620         struct rtl8187_priv *priv = dev->priv;
621         u8 cck_power, ofdm_power;
622         const u8 *tmp;
623         u32 reg;
624         int i;
625
626         cck_power = priv->channels[channel - 1].hw_value & 0xF;
627         ofdm_power = priv->channels[channel - 1].hw_value >> 4;
628
629         cck_power = min(cck_power, (u8)15);
630         cck_power += priv->txpwr_base & 0xF;
631         cck_power = min(cck_power, (u8)35);
632
633         if (ofdm_power > (u8)15)
634                 ofdm_power = 25;
635         else
636                 ofdm_power += 10;
637         ofdm_power += priv->txpwr_base >> 4;
638         ofdm_power = min(ofdm_power, (u8)35);
639
640         if (channel == 14)
641                 tmp = rtl8225z2_tx_power_cck_ch14;
642         else
643                 tmp = rtl8225z2_tx_power_cck;
644
645         for (i = 0; i < 8; i++)
646                 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
647
648         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
649                          rtl8225z2_tx_gain_cck_ofdm[cck_power]);
650         msleep(1);
651
652         /* anaparam2 on */
653         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
654         reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
655         rtl818x_iowrite8(priv, &priv->map->CONFIG3,
656                         reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
657         rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
658                           RTL8187_RTL8225_ANAPARAM2_ON);
659         rtl818x_iowrite8(priv, &priv->map->CONFIG3,
660                         reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
661         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
662
663         rtl8225_write_phy_ofdm(dev, 2, 0x42);
664         rtl8225_write_phy_ofdm(dev, 5, 0x00);
665         rtl8225_write_phy_ofdm(dev, 6, 0x40);
666         rtl8225_write_phy_ofdm(dev, 7, 0x00);
667         rtl8225_write_phy_ofdm(dev, 8, 0x40);
668
669         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
670                          rtl8225z2_tx_gain_cck_ofdm[ofdm_power]);
671         msleep(1);
672 }
673
674 static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
675 {
676         struct rtl8187_priv *priv = dev->priv;
677         u8 cck_power, ofdm_power;
678         const u8 *tmp;
679         int i;
680
681         cck_power = priv->channels[channel - 1].hw_value & 0xF;
682         ofdm_power = priv->channels[channel - 1].hw_value >> 4;
683
684         cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7;
685         cck_power += priv->txpwr_base & 0xF;
686         cck_power = min(cck_power, (u8)35);
687
688         if (ofdm_power > 15)
689                 ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25;
690         else
691                 ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10;
692         ofdm_power += (priv->txpwr_base >> 4) & 0xF;
693         ofdm_power = min(ofdm_power, (u8)35);
694
695         if (channel == 14)
696                 tmp = rtl8225z2_tx_power_cck_ch14;
697         else
698                 tmp = rtl8225z2_tx_power_cck;
699
700         if (priv->hw_rev == RTL8187BvB) {
701                 if (cck_power <= 6)
702                         ; /* do nothing */
703                 else if (cck_power <= 11)
704                         tmp += 8;
705                 else
706                         tmp += 16;
707         } else {
708                 if (cck_power <= 5)
709                         ; /* do nothing */
710                 else if (cck_power <= 11)
711                         tmp += 8;
712                 else if (cck_power <= 17)
713                         tmp += 16;
714                 else
715                         tmp += 24;
716         }
717
718         for (i = 0; i < 8; i++)
719                 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
720
721         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
722                          rtl8225z2_tx_gain_cck_ofdm[cck_power] << 1);
723         msleep(1);
724
725         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
726                          rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1);
727         if (priv->hw_rev == RTL8187BvB) {
728                 if (ofdm_power <= 11) {
729                         rtl8225_write_phy_ofdm(dev, 0x87, 0x60);
730                         rtl8225_write_phy_ofdm(dev, 0x89, 0x60);
731                 } else {
732                         rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
733                         rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
734                 }
735         } else {
736                 if (ofdm_power <= 11) {
737                         rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
738                         rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
739                 } else if (ofdm_power <= 17) {
740                         rtl8225_write_phy_ofdm(dev, 0x87, 0x54);
741                         rtl8225_write_phy_ofdm(dev, 0x89, 0x54);
742                 } else {
743                         rtl8225_write_phy_ofdm(dev, 0x87, 0x50);
744                         rtl8225_write_phy_ofdm(dev, 0x89, 0x50);
745                 }
746         }
747         msleep(1);
748 }
749
750 static const u16 rtl8225z2_rxgain[] = {
751         0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
752         0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
753         0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
754         0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
755         0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
756         0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
757         0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
758         0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
759         0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
760         0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
761         0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
762         0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
763 };
764
765 static const u8 rtl8225z2_gain_bg[] = {
766         0x23, 0x15, 0xa5, /* -82-1dBm */
767         0x23, 0x15, 0xb5, /* -82-2dBm */
768         0x23, 0x15, 0xc5, /* -82-3dBm */
769         0x33, 0x15, 0xc5, /* -78dBm */
770         0x43, 0x15, 0xc5, /* -74dBm */
771         0x53, 0x15, 0xc5, /* -70dBm */
772         0x63, 0x15, 0xc5  /* -66dBm */
773 };
774
775 static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
776 {
777         struct rtl8187_priv *priv = dev->priv;
778         int i;
779
780         rtl8225_write(dev, 0x0, 0x2BF);
781         rtl8225_write(dev, 0x1, 0xEE0);
782         rtl8225_write(dev, 0x2, 0x44D);
783         rtl8225_write(dev, 0x3, 0x441);
784         rtl8225_write(dev, 0x4, 0x8C3);
785         rtl8225_write(dev, 0x5, 0xC72);
786         rtl8225_write(dev, 0x6, 0x0E6);
787         rtl8225_write(dev, 0x7, 0x82A);
788         rtl8225_write(dev, 0x8, 0x03F);
789         rtl8225_write(dev, 0x9, 0x335);
790         rtl8225_write(dev, 0xa, 0x9D4);
791         rtl8225_write(dev, 0xb, 0x7BB);
792         rtl8225_write(dev, 0xc, 0x850);
793         rtl8225_write(dev, 0xd, 0xCDF);
794         rtl8225_write(dev, 0xe, 0x02B);
795         rtl8225_write(dev, 0xf, 0x114);
796         msleep(100);
797
798         rtl8225_write(dev, 0x0, 0x1B7);
799
800         for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
801                 rtl8225_write(dev, 0x1, i + 1);
802                 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
803         }
804
805         rtl8225_write(dev, 0x3, 0x080);
806         rtl8225_write(dev, 0x5, 0x004);
807         rtl8225_write(dev, 0x0, 0x0B7);
808         rtl8225_write(dev, 0x2, 0xc4D);
809
810         msleep(200);
811         rtl8225_write(dev, 0x2, 0x44D);
812         msleep(100);
813
814         if (!(rtl8225_read(dev, 6) & (1 << 7))) {
815                 rtl8225_write(dev, 0x02, 0x0C4D);
816                 msleep(200);
817                 rtl8225_write(dev, 0x02, 0x044D);
818                 msleep(100);
819                 if (!(rtl8225_read(dev, 6) & (1 << 7)))
820                         wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n",
821                                    rtl8225_read(dev, 6));
822         }
823
824         msleep(200);
825
826         rtl8225_write(dev, 0x0, 0x2BF);
827
828         for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
829                 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
830                 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
831         }
832
833         msleep(1);
834
835         rtl8225_write_phy_ofdm(dev, 0x00, 0x01);
836         rtl8225_write_phy_ofdm(dev, 0x01, 0x02);
837         rtl8225_write_phy_ofdm(dev, 0x02, 0x42);
838         rtl8225_write_phy_ofdm(dev, 0x03, 0x00);
839         rtl8225_write_phy_ofdm(dev, 0x04, 0x00);
840         rtl8225_write_phy_ofdm(dev, 0x05, 0x00);
841         rtl8225_write_phy_ofdm(dev, 0x06, 0x40);
842         rtl8225_write_phy_ofdm(dev, 0x07, 0x00);
843         rtl8225_write_phy_ofdm(dev, 0x08, 0x40);
844         rtl8225_write_phy_ofdm(dev, 0x09, 0xfe);
845         rtl8225_write_phy_ofdm(dev, 0x0a, 0x08);
846         rtl8225_write_phy_ofdm(dev, 0x0b, 0x80);
847         rtl8225_write_phy_ofdm(dev, 0x0c, 0x01);
848         rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
849         rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3);
850         rtl8225_write_phy_ofdm(dev, 0x0f, 0x38);
851         rtl8225_write_phy_ofdm(dev, 0x10, 0x84);
852         rtl8225_write_phy_ofdm(dev, 0x11, 0x07);
853         rtl8225_write_phy_ofdm(dev, 0x12, 0x20);
854         rtl8225_write_phy_ofdm(dev, 0x13, 0x20);
855         rtl8225_write_phy_ofdm(dev, 0x14, 0x00);
856         rtl8225_write_phy_ofdm(dev, 0x15, 0x40);
857         rtl8225_write_phy_ofdm(dev, 0x16, 0x00);
858         rtl8225_write_phy_ofdm(dev, 0x17, 0x40);
859         rtl8225_write_phy_ofdm(dev, 0x18, 0xef);
860         rtl8225_write_phy_ofdm(dev, 0x19, 0x19);
861         rtl8225_write_phy_ofdm(dev, 0x1a, 0x20);
862         rtl8225_write_phy_ofdm(dev, 0x1b, 0x15);
863         rtl8225_write_phy_ofdm(dev, 0x1c, 0x04);
864         rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5);
865         rtl8225_write_phy_ofdm(dev, 0x1e, 0x95);
866         rtl8225_write_phy_ofdm(dev, 0x1f, 0x75);
867         rtl8225_write_phy_ofdm(dev, 0x20, 0x1f);
868         rtl8225_write_phy_ofdm(dev, 0x21, 0x17);
869         rtl8225_write_phy_ofdm(dev, 0x22, 0x16);
870         rtl8225_write_phy_ofdm(dev, 0x23, 0x80);
871         rtl8225_write_phy_ofdm(dev, 0x24, 0x46);
872         rtl8225_write_phy_ofdm(dev, 0x25, 0x00);
873         rtl8225_write_phy_ofdm(dev, 0x26, 0x90);
874         rtl8225_write_phy_ofdm(dev, 0x27, 0x88);
875
876         rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]);
877         rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]);
878         rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]);
879         rtl8225_write_phy_ofdm(dev, 0x21, 0x37);
880
881         rtl8225_write_phy_cck(dev, 0x00, 0x98);
882         rtl8225_write_phy_cck(dev, 0x03, 0x20);
883         rtl8225_write_phy_cck(dev, 0x04, 0x7e);
884         rtl8225_write_phy_cck(dev, 0x05, 0x12);
885         rtl8225_write_phy_cck(dev, 0x06, 0xfc);
886         rtl8225_write_phy_cck(dev, 0x07, 0x78);
887         rtl8225_write_phy_cck(dev, 0x08, 0x2e);
888         rtl8225_write_phy_cck(dev, 0x10, 0x9b);
889         rtl8225_write_phy_cck(dev, 0x11, 0x88);
890         rtl8225_write_phy_cck(dev, 0x12, 0x47);
891         rtl8225_write_phy_cck(dev, 0x13, 0xd0);
892         rtl8225_write_phy_cck(dev, 0x19, 0x00);
893         rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
894         rtl8225_write_phy_cck(dev, 0x1b, 0x08);
895         rtl8225_write_phy_cck(dev, 0x40, 0x86);
896         rtl8225_write_phy_cck(dev, 0x41, 0x8d);
897         rtl8225_write_phy_cck(dev, 0x42, 0x15);
898         rtl8225_write_phy_cck(dev, 0x43, 0x18);
899         rtl8225_write_phy_cck(dev, 0x44, 0x36);
900         rtl8225_write_phy_cck(dev, 0x45, 0x35);
901         rtl8225_write_phy_cck(dev, 0x46, 0x2e);
902         rtl8225_write_phy_cck(dev, 0x47, 0x25);
903         rtl8225_write_phy_cck(dev, 0x48, 0x1c);
904         rtl8225_write_phy_cck(dev, 0x49, 0x12);
905         rtl8225_write_phy_cck(dev, 0x4a, 0x09);
906         rtl8225_write_phy_cck(dev, 0x4b, 0x04);
907         rtl8225_write_phy_cck(dev, 0x4c, 0x05);
908
909         rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1);
910
911         rtl8225z2_rf_set_tx_power(dev, 1);
912
913         /* RX antenna default to A */
914         rtl8225_write_phy_cck(dev, 0x10, 0x9b);                 /* B: 0xDB */
915         rtl8225_write_phy_ofdm(dev, 0x26, 0x90);                /* B: 0x10 */
916
917         rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
918         msleep(1);
919         rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
920 }
921
922 static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
923 {
924         struct rtl8187_priv *priv = dev->priv;
925         int i;
926
927         rtl8225_write(dev, 0x0, 0x0B7);
928         rtl8225_write(dev, 0x1, 0xEE0);
929         rtl8225_write(dev, 0x2, 0x44D);
930         rtl8225_write(dev, 0x3, 0x441);
931         rtl8225_write(dev, 0x4, 0x8C3);
932         rtl8225_write(dev, 0x5, 0xC72);
933         rtl8225_write(dev, 0x6, 0x0E6);
934         rtl8225_write(dev, 0x7, 0x82A);
935         rtl8225_write(dev, 0x8, 0x03F);
936         rtl8225_write(dev, 0x9, 0x335);
937         rtl8225_write(dev, 0xa, 0x9D4);
938         rtl8225_write(dev, 0xb, 0x7BB);
939         rtl8225_write(dev, 0xc, 0x850);
940         rtl8225_write(dev, 0xd, 0xCDF);
941         rtl8225_write(dev, 0xe, 0x02B);
942         rtl8225_write(dev, 0xf, 0x114);
943
944         rtl8225_write(dev, 0x0, 0x1B7);
945
946         for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
947                 rtl8225_write(dev, 0x1, i + 1);
948                 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
949         }
950
951         rtl8225_write(dev, 0x3, 0x080);
952         rtl8225_write(dev, 0x5, 0x004);
953         rtl8225_write(dev, 0x0, 0x0B7);
954
955         rtl8225_write(dev, 0x2, 0xC4D);
956
957         rtl8225_write(dev, 0x2, 0x44D);
958         rtl8225_write(dev, 0x0, 0x2BF);
959
960         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03);
961         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07);
962         rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
963
964         rtl8225_write_phy_ofdm(dev, 0x80, 0x12);
965         for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) {
966                 rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]);
967                 rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i);
968                 rtl8225_write_phy_ofdm(dev, 0xE, 0);
969         }
970         rtl8225_write_phy_ofdm(dev, 0x80, 0x10);
971
972         for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++)
973                 rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]);
974
975         rtl8225_write_phy_ofdm(dev, 0x97, 0x46);
976         rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6);
977         rtl8225_write_phy_ofdm(dev, 0x85, 0xfc);
978         rtl8225_write_phy_cck(dev, 0xc1, 0x88);
979 }
980
981 static void rtl8225_rf_stop(struct ieee80211_hw *dev)
982 {
983         rtl8225_write(dev, 0x4, 0x1f);
984 }
985
986 static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
987                                    struct ieee80211_conf *conf)
988 {
989         struct rtl8187_priv *priv = dev->priv;
990         int chan =
991                 ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
992
993         if (priv->rf->init == rtl8225_rf_init)
994                 rtl8225_rf_set_tx_power(dev, chan);
995         else if (priv->rf->init == rtl8225z2_rf_init)
996                 rtl8225z2_rf_set_tx_power(dev, chan);
997         else
998                 rtl8225z2_b_rf_set_tx_power(dev, chan);
999
1000         rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
1001         msleep(10);
1002 }
1003
1004 static const struct rtl818x_rf_ops rtl8225_ops = {
1005         .name           = "rtl8225",
1006         .init           = rtl8225_rf_init,
1007         .stop           = rtl8225_rf_stop,
1008         .set_chan       = rtl8225_rf_set_channel
1009 };
1010
1011 static const struct rtl818x_rf_ops rtl8225z2_ops = {
1012         .name           = "rtl8225z2",
1013         .init           = rtl8225z2_rf_init,
1014         .stop           = rtl8225_rf_stop,
1015         .set_chan       = rtl8225_rf_set_channel
1016 };
1017
1018 static const struct rtl818x_rf_ops rtl8225z2_b_ops = {
1019         .name           = "rtl8225z2",
1020         .init           = rtl8225z2_b_rf_init,
1021         .stop           = rtl8225_rf_stop,
1022         .set_chan       = rtl8225_rf_set_channel
1023 };
1024
1025 const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev)
1026 {
1027         u16 reg8, reg9;
1028         struct rtl8187_priv *priv = dev->priv;
1029
1030         if (!priv->is_rtl8187b) {
1031                 rtl8225_write(dev, 0, 0x1B7);
1032
1033                 reg8 = rtl8225_read(dev, 8);
1034                 reg9 = rtl8225_read(dev, 9);
1035
1036                 rtl8225_write(dev, 0, 0x0B7);
1037
1038                 if (reg8 != 0x588 || reg9 != 0x700)
1039                         return &rtl8225_ops;
1040
1041                 return &rtl8225z2_ops;
1042         } else
1043                 return &rtl8225z2_b_ops;
1044 }