注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

BCB-DG's Blog

...

 
 
 

日志

 
 

Linux/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c  

2014-04-23 15:04:54|  分类: Linux |  标签: |举报 |字号 订阅

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

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017