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