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 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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
988 static void rtl8225_rf_stop(struct ieee80211_hw *dev)
989 {
990 	rtl8225_write(dev, 0x4, 0x1f);
991 }
992 
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 
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