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