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