1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2f1d2b4d3SLarry Finger 
3f1d2b4d3SLarry Finger /*
4f1d2b4d3SLarry Finger  * Radio tuning for RTL8225 on RTL8180
5f1d2b4d3SLarry Finger  *
6f1d2b4d3SLarry Finger  * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
7f1d2b4d3SLarry Finger  * Copyright 2007 Andrea Merello <andrea.merello@gmail.com>
8f1d2b4d3SLarry Finger  *
9f1d2b4d3SLarry Finger  * Based on the r8180 driver, which is:
10f1d2b4d3SLarry Finger  * Copyright 2005 Andrea Merello <andrea.merello@gmail.com>, et al.
11f1d2b4d3SLarry Finger  *
12f1d2b4d3SLarry Finger  * Thanks to Realtek for their support!
13f1d2b4d3SLarry Finger  */
14f1d2b4d3SLarry Finger 
15f1d2b4d3SLarry Finger #include <linux/pci.h>
16f1d2b4d3SLarry Finger #include <linux/delay.h>
17f1d2b4d3SLarry Finger #include <net/mac80211.h>
18f1d2b4d3SLarry Finger 
19f1d2b4d3SLarry Finger #include "rtl8180.h"
20f1d2b4d3SLarry Finger #include "rtl8225.h"
21f1d2b4d3SLarry Finger 
rtl8225_write(struct ieee80211_hw * dev,u8 addr,u16 data)22f1d2b4d3SLarry Finger static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
23f1d2b4d3SLarry Finger {
24f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
25f1d2b4d3SLarry Finger 	u16 reg80, reg84, reg82;
26f1d2b4d3SLarry Finger 	u32 bangdata;
27f1d2b4d3SLarry Finger 	int i;
28f1d2b4d3SLarry Finger 
29f1d2b4d3SLarry Finger 	bangdata = (data << 4) | (addr & 0xf);
30f1d2b4d3SLarry Finger 
31f1d2b4d3SLarry Finger 	reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
32f1d2b4d3SLarry Finger 	reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
33f1d2b4d3SLarry Finger 
34f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
35f1d2b4d3SLarry Finger 
36f1d2b4d3SLarry Finger 	reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
37f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400);
38f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
39f1d2b4d3SLarry Finger 	udelay(10);
40f1d2b4d3SLarry Finger 
41f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
42f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
43f1d2b4d3SLarry Finger 	udelay(2);
44f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
45f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
46f1d2b4d3SLarry Finger 	udelay(10);
47f1d2b4d3SLarry Finger 
48f1d2b4d3SLarry Finger 	for (i = 15; i >= 0; i--) {
49f1d2b4d3SLarry Finger 		u16 reg = reg80;
50f1d2b4d3SLarry Finger 
51f1d2b4d3SLarry Finger 		if (bangdata & (1 << i))
52f1d2b4d3SLarry Finger 			reg |= 1;
53f1d2b4d3SLarry Finger 
54f1d2b4d3SLarry Finger 		if (i & 1)
55f1d2b4d3SLarry Finger 			rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
56f1d2b4d3SLarry Finger 
57f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
58f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
59f1d2b4d3SLarry Finger 
60f1d2b4d3SLarry Finger 		if (!(i & 1))
61f1d2b4d3SLarry Finger 			rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
62f1d2b4d3SLarry Finger 	}
63f1d2b4d3SLarry Finger 
64f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
65f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
66f1d2b4d3SLarry Finger 	udelay(10);
67f1d2b4d3SLarry Finger 
68f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
69f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400);
70f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
71f1d2b4d3SLarry Finger }
72f1d2b4d3SLarry Finger 
rtl8225_read(struct ieee80211_hw * dev,u8 addr)73f1d2b4d3SLarry Finger static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
74f1d2b4d3SLarry Finger {
75f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
76f1d2b4d3SLarry Finger 	u16 reg80, reg82, reg84, out;
77f1d2b4d3SLarry Finger 	int i;
78f1d2b4d3SLarry Finger 
79f1d2b4d3SLarry Finger 	reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
80f1d2b4d3SLarry Finger 	reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
81f1d2b4d3SLarry Finger 	reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400;
82f1d2b4d3SLarry Finger 
83f1d2b4d3SLarry Finger 	reg80 &= ~0xF;
84f1d2b4d3SLarry Finger 
85f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
86f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
87f1d2b4d3SLarry Finger 
88f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
89f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
90f1d2b4d3SLarry Finger 	udelay(4);
91f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
92f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
93f1d2b4d3SLarry Finger 	udelay(5);
94f1d2b4d3SLarry Finger 
95f1d2b4d3SLarry Finger 	for (i = 4; i >= 0; i--) {
96f1d2b4d3SLarry Finger 		u16 reg = reg80 | ((addr >> i) & 1);
97f1d2b4d3SLarry Finger 
98f1d2b4d3SLarry Finger 		if (!(i & 1)) {
99f1d2b4d3SLarry Finger 			rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
100f1d2b4d3SLarry Finger 			rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
101f1d2b4d3SLarry Finger 			udelay(1);
102f1d2b4d3SLarry Finger 		}
103f1d2b4d3SLarry Finger 
104f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
105f1d2b4d3SLarry Finger 				  reg | (1 << 1));
106f1d2b4d3SLarry Finger 		rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
107f1d2b4d3SLarry Finger 		udelay(2);
108f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
109f1d2b4d3SLarry Finger 				  reg | (1 << 1));
110f1d2b4d3SLarry Finger 		rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
111f1d2b4d3SLarry Finger 		udelay(2);
112f1d2b4d3SLarry Finger 
113f1d2b4d3SLarry Finger 		if (i & 1) {
114f1d2b4d3SLarry Finger 			rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
115f1d2b4d3SLarry Finger 			rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
116f1d2b4d3SLarry Finger 			udelay(1);
117f1d2b4d3SLarry Finger 		}
118f1d2b4d3SLarry Finger 	}
119f1d2b4d3SLarry Finger 
120f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E);
121f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E);
122f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
123f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
124f1d2b4d3SLarry Finger 			  reg80 | (1 << 3) | (1 << 1));
125f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
126f1d2b4d3SLarry Finger 	udelay(2);
127f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
128f1d2b4d3SLarry Finger 			  reg80 | (1 << 3));
129f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
130f1d2b4d3SLarry Finger 	udelay(2);
131f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
132f1d2b4d3SLarry Finger 			  reg80 | (1 << 3));
133f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
134f1d2b4d3SLarry Finger 	udelay(2);
135f1d2b4d3SLarry Finger 
136f1d2b4d3SLarry Finger 	out = 0;
137f1d2b4d3SLarry Finger 	for (i = 11; i >= 0; i--) {
138f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
139f1d2b4d3SLarry Finger 				  reg80 | (1 << 3));
140f1d2b4d3SLarry Finger 		rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
141f1d2b4d3SLarry Finger 		udelay(1);
142f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
143f1d2b4d3SLarry Finger 				  reg80 | (1 << 3) | (1 << 1));
144f1d2b4d3SLarry Finger 		rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
145f1d2b4d3SLarry Finger 		udelay(2);
146f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
147f1d2b4d3SLarry Finger 				  reg80 | (1 << 3) | (1 << 1));
148f1d2b4d3SLarry Finger 		rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
149f1d2b4d3SLarry Finger 		udelay(2);
150f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
151f1d2b4d3SLarry Finger 				  reg80 | (1 << 3) | (1 << 1));
152f1d2b4d3SLarry Finger 		rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
153f1d2b4d3SLarry Finger 		udelay(2);
154f1d2b4d3SLarry Finger 
155f1d2b4d3SLarry Finger 		if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
156f1d2b4d3SLarry Finger 			out |= 1 << i;
157f1d2b4d3SLarry Finger 
158f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
159f1d2b4d3SLarry Finger 				  reg80 | (1 << 3));
160f1d2b4d3SLarry Finger 		rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
161f1d2b4d3SLarry Finger 		udelay(2);
162f1d2b4d3SLarry Finger 	}
163f1d2b4d3SLarry Finger 
164f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
165f1d2b4d3SLarry Finger 			  reg80 | (1 << 3) | (1 << 2));
166f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
167f1d2b4d3SLarry Finger 	udelay(2);
168f1d2b4d3SLarry Finger 
169f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
170f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
171f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
172f1d2b4d3SLarry Finger 
173f1d2b4d3SLarry Finger 	return out;
174f1d2b4d3SLarry Finger }
175f1d2b4d3SLarry Finger 
176f1d2b4d3SLarry Finger static const u16 rtl8225bcd_rxgain[] = {
177f1d2b4d3SLarry Finger 	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
178f1d2b4d3SLarry Finger 	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
179f1d2b4d3SLarry Finger 	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
180f1d2b4d3SLarry Finger 	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
181f1d2b4d3SLarry Finger 	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
182f1d2b4d3SLarry Finger 	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
183f1d2b4d3SLarry Finger 	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
184f1d2b4d3SLarry Finger 	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
185f1d2b4d3SLarry Finger 	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
186f1d2b4d3SLarry Finger 	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
187f1d2b4d3SLarry Finger 	0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
188f1d2b4d3SLarry Finger 	0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
189f1d2b4d3SLarry Finger };
190f1d2b4d3SLarry Finger 
191f1d2b4d3SLarry Finger static const u8 rtl8225_agc[] = {
192f1d2b4d3SLarry Finger 	0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
193f1d2b4d3SLarry Finger 	0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
194f1d2b4d3SLarry Finger 	0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
195f1d2b4d3SLarry Finger 	0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
196f1d2b4d3SLarry Finger 	0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
197f1d2b4d3SLarry Finger 	0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
198f1d2b4d3SLarry Finger 	0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
199f1d2b4d3SLarry Finger 	0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
200f1d2b4d3SLarry Finger 	0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
201f1d2b4d3SLarry Finger 	0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
202f1d2b4d3SLarry Finger 	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
203f1d2b4d3SLarry Finger 	0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
204f1d2b4d3SLarry Finger 	0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
205f1d2b4d3SLarry Finger 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
206f1d2b4d3SLarry Finger 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
207f1d2b4d3SLarry Finger 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
208f1d2b4d3SLarry Finger };
209f1d2b4d3SLarry Finger 
210f1d2b4d3SLarry Finger static const u8 rtl8225_gain[] = {
211f1d2b4d3SLarry Finger 	0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
212f1d2b4d3SLarry Finger 	0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
213f1d2b4d3SLarry Finger 	0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
214f1d2b4d3SLarry Finger 	0x33, 0x80, 0x79, 0xc5, /* -78dbm */
215f1d2b4d3SLarry Finger 	0x43, 0x78, 0x76, 0xc5, /* -74dbm */
216f1d2b4d3SLarry Finger 	0x53, 0x60, 0x73, 0xc5, /* -70dbm */
217f1d2b4d3SLarry Finger 	0x63, 0x58, 0x70, 0xc5, /* -66dbm */
218f1d2b4d3SLarry Finger };
219f1d2b4d3SLarry Finger 
220f1d2b4d3SLarry Finger static const u8 rtl8225_threshold[] = {
221f1d2b4d3SLarry Finger 	0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
222f1d2b4d3SLarry Finger };
223f1d2b4d3SLarry Finger 
224f1d2b4d3SLarry Finger static const u8 rtl8225_tx_gain_cck_ofdm[] = {
225f1d2b4d3SLarry Finger 	0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
226f1d2b4d3SLarry Finger };
227f1d2b4d3SLarry Finger 
228f1d2b4d3SLarry Finger static const u8 rtl8225_tx_power_cck[] = {
229f1d2b4d3SLarry Finger 	0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
230f1d2b4d3SLarry Finger 	0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
231f1d2b4d3SLarry Finger 	0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
232f1d2b4d3SLarry Finger 	0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
233f1d2b4d3SLarry Finger 	0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
234f1d2b4d3SLarry Finger 	0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
235f1d2b4d3SLarry Finger };
236f1d2b4d3SLarry Finger 
237f1d2b4d3SLarry Finger static const u8 rtl8225_tx_power_cck_ch14[] = {
238f1d2b4d3SLarry Finger 	0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
239f1d2b4d3SLarry Finger 	0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
240f1d2b4d3SLarry Finger 	0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
241f1d2b4d3SLarry Finger 	0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
242f1d2b4d3SLarry Finger 	0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
243f1d2b4d3SLarry Finger 	0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
244f1d2b4d3SLarry Finger };
245f1d2b4d3SLarry Finger 
246f1d2b4d3SLarry Finger static const u8 rtl8225_tx_power_ofdm[] = {
247f1d2b4d3SLarry Finger 	0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
248f1d2b4d3SLarry Finger };
249f1d2b4d3SLarry Finger 
250f1d2b4d3SLarry Finger static const u32 rtl8225_chan[] = {
251f1d2b4d3SLarry Finger 	0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
252f1d2b4d3SLarry Finger 	0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
253f1d2b4d3SLarry Finger };
254f1d2b4d3SLarry Finger 
rtl8225_rf_set_tx_power(struct ieee80211_hw * dev,int channel)255f1d2b4d3SLarry Finger static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
256f1d2b4d3SLarry Finger {
257f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
258f1d2b4d3SLarry Finger 	u8 cck_power, ofdm_power;
259f1d2b4d3SLarry Finger 	const u8 *tmp;
260f1d2b4d3SLarry Finger 	u32 reg;
261f1d2b4d3SLarry Finger 	int i;
262f1d2b4d3SLarry Finger 
263f1d2b4d3SLarry Finger 	cck_power = priv->channels[channel - 1].hw_value & 0xFF;
264f1d2b4d3SLarry Finger 	ofdm_power = priv->channels[channel - 1].hw_value >> 8;
265f1d2b4d3SLarry Finger 
266f1d2b4d3SLarry Finger 	cck_power = min(cck_power, (u8)35);
267f1d2b4d3SLarry Finger 	ofdm_power = min(ofdm_power, (u8)35);
268f1d2b4d3SLarry Finger 
269f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
270f1d2b4d3SLarry Finger 			 rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
271f1d2b4d3SLarry Finger 
272f1d2b4d3SLarry Finger 	if (channel == 14)
273f1d2b4d3SLarry Finger 		tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
274f1d2b4d3SLarry Finger 	else
275f1d2b4d3SLarry Finger 		tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
276f1d2b4d3SLarry Finger 
277f1d2b4d3SLarry Finger 	for (i = 0; i < 8; i++)
278f1d2b4d3SLarry Finger 		rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
279f1d2b4d3SLarry Finger 
280f1d2b4d3SLarry Finger 	msleep(1); /* FIXME: optional? */
281f1d2b4d3SLarry Finger 
282f1d2b4d3SLarry Finger 	/* TODO: use set_anaparam2 dev.c_func*/
283f1d2b4d3SLarry Finger 	/* anaparam2 on */
284f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
285f1d2b4d3SLarry Finger 	reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
286f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
287f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
288f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
289f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
290f1d2b4d3SLarry Finger 
291f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
292f1d2b4d3SLarry Finger 			 rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1);
293f1d2b4d3SLarry Finger 
294f1d2b4d3SLarry Finger 	tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
295f1d2b4d3SLarry Finger 
296f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 5, *tmp);
297f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 7, *tmp);
298f1d2b4d3SLarry Finger 
299f1d2b4d3SLarry Finger 	msleep(1);
300f1d2b4d3SLarry Finger }
301f1d2b4d3SLarry Finger 
rtl8225_rf_init(struct ieee80211_hw * dev)302f1d2b4d3SLarry Finger static void rtl8225_rf_init(struct ieee80211_hw *dev)
303f1d2b4d3SLarry Finger {
304f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
305f1d2b4d3SLarry Finger 	int i;
306f1d2b4d3SLarry Finger 
307f1d2b4d3SLarry Finger 	rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);
308f1d2b4d3SLarry Finger 
309f1d2b4d3SLarry Finger 	/* host_pci_init */
310f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
311f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
312f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
313f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
314f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
315f1d2b4d3SLarry Finger 	msleep(200);	/* FIXME: ehh?? */
316f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
317f1d2b4d3SLarry Finger 
318f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
319f1d2b4d3SLarry Finger 
320f1d2b4d3SLarry Finger 	/* TODO: check if we need really to change BRSR to do RF config */
321f1d2b4d3SLarry Finger 	rtl818x_ioread16(priv, &priv->map->BRSR);
322f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
323f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
324f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
325f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
326f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
327f1d2b4d3SLarry Finger 
328f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x0, 0x067);
329f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x1, 0xFE0);
330f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x2, 0x44D);
331f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x3, 0x441);
332f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x4, 0x8BE);
333f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x5, 0xBF0);		/* TODO: minipci */
334f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x6, 0xAE6);
335f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x7, rtl8225_chan[0]);
336f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x8, 0x01F);
337f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x9, 0x334);
338f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xA, 0xFD4);
339f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xB, 0x391);
340f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xC, 0x050);
341f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xD, 0x6DB);
342f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xE, 0x029);
343f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xF, 0x914); msleep(1);
344f1d2b4d3SLarry Finger 
345f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x2, 0xC4D); msleep(100);
346f1d2b4d3SLarry Finger 
347f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x0, 0x127);
348f1d2b4d3SLarry Finger 
349f1d2b4d3SLarry Finger 	for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
350f1d2b4d3SLarry Finger 		rtl8225_write(dev, 0x1, i + 1);
351f1d2b4d3SLarry Finger 		rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
352f1d2b4d3SLarry Finger 	}
353f1d2b4d3SLarry Finger 
354f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x0, 0x027);
355f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x0, 0x22F);
356f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
357f1d2b4d3SLarry Finger 
358f1d2b4d3SLarry Finger 	for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
359f1d2b4d3SLarry Finger 		rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
360f1d2b4d3SLarry Finger 		msleep(1);
361f1d2b4d3SLarry Finger 		rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
362f1d2b4d3SLarry Finger 		msleep(1);
363f1d2b4d3SLarry Finger 	}
364f1d2b4d3SLarry Finger 
365f1d2b4d3SLarry Finger 	msleep(1);
366f1d2b4d3SLarry Finger 
367f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
368f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
369f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1);
370f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
371f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
372f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
373f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x06, 0x00); msleep(1);
374f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
375f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x08, 0x00); msleep(1);
376f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
377f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
378f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
379f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
380f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
381f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
382f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
383f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x11, 0x03); msleep(1);
384f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
385f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
386f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
387f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
388f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
389f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
390f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
391f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
392f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
393f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1);
394f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
395f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
396f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
397f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
398f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
399f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
400f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
401f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
402f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
403f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
404f1d2b4d3SLarry Finger 
405f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
406f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
407f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
408f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
409f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
410f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
411f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
412f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1);
413f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
414f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
415f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x13, 0xd0);
416f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x19, 0x00);
417f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
418f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x1b, 0x08);
419f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x40, 0x86);
420f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
421f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
422f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
423f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1);
424f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1);
425f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1);
426f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1);
427f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1);
428f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1);
429f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1);
430f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1);
431f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
432f1d2b4d3SLarry Finger 
433f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); msleep(1);
434f1d2b4d3SLarry Finger 
435f1d2b4d3SLarry Finger 	rtl8225_rf_set_tx_power(dev, 1);
436f1d2b4d3SLarry Finger 
437f1d2b4d3SLarry Finger 	/* RX antenna default to A */
438f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);	/* B: 0xDB */
439f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);	/* B: 0x10 */
440f1d2b4d3SLarry Finger 
441f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);	/* B: 0x00 */
442f1d2b4d3SLarry Finger 	msleep(1);
443f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002);
444f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
445f1d2b4d3SLarry Finger 
446f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x0c, 0x50);
447f1d2b4d3SLarry Finger 	/* set OFDM initial gain */
448f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]);
449f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]);
450f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]);
451f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]);
452f1d2b4d3SLarry Finger 	/* set CCK threshold */
453f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]);
454f1d2b4d3SLarry Finger }
455f1d2b4d3SLarry Finger 
456f1d2b4d3SLarry Finger static const u8 rtl8225z2_tx_power_cck_ch14[] = {
457f1d2b4d3SLarry Finger 	0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
458f1d2b4d3SLarry Finger };
459f1d2b4d3SLarry Finger 
460f1d2b4d3SLarry Finger static const u8 rtl8225z2_tx_power_cck_B[] = {
461f1d2b4d3SLarry Finger 	0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04
462f1d2b4d3SLarry Finger };
463f1d2b4d3SLarry Finger 
464f1d2b4d3SLarry Finger static const u8 rtl8225z2_tx_power_cck_A[] = {
465f1d2b4d3SLarry Finger 	0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04
466f1d2b4d3SLarry Finger };
467f1d2b4d3SLarry Finger 
468f1d2b4d3SLarry Finger static const u8 rtl8225z2_tx_power_cck[] = {
469f1d2b4d3SLarry Finger 	0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
470f1d2b4d3SLarry Finger };
471f1d2b4d3SLarry Finger 
rtl8225z2_rf_set_tx_power(struct ieee80211_hw * dev,int channel)472f1d2b4d3SLarry Finger static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
473f1d2b4d3SLarry Finger {
474f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
475f1d2b4d3SLarry Finger 	u8 cck_power, ofdm_power;
476f1d2b4d3SLarry Finger 	const u8 *tmp;
477f1d2b4d3SLarry Finger 	int i;
478f1d2b4d3SLarry Finger 
479f1d2b4d3SLarry Finger 	cck_power = priv->channels[channel - 1].hw_value & 0xFF;
480f1d2b4d3SLarry Finger 	ofdm_power = priv->channels[channel - 1].hw_value >> 8;
481f1d2b4d3SLarry Finger 
482f1d2b4d3SLarry Finger 	if (channel == 14)
483f1d2b4d3SLarry Finger 		tmp = rtl8225z2_tx_power_cck_ch14;
484f1d2b4d3SLarry Finger 	else if (cck_power == 12)
485f1d2b4d3SLarry Finger 		tmp = rtl8225z2_tx_power_cck_B;
486f1d2b4d3SLarry Finger 	else if (cck_power == 13)
487f1d2b4d3SLarry Finger 		tmp = rtl8225z2_tx_power_cck_A;
488f1d2b4d3SLarry Finger 	else
489f1d2b4d3SLarry Finger 		tmp = rtl8225z2_tx_power_cck;
490f1d2b4d3SLarry Finger 
491f1d2b4d3SLarry Finger 	for (i = 0; i < 8; i++)
492f1d2b4d3SLarry Finger 		rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
493f1d2b4d3SLarry Finger 
494f1d2b4d3SLarry Finger 	cck_power = min(cck_power, (u8)35);
495f1d2b4d3SLarry Finger 	if (cck_power == 13 || cck_power == 14)
496f1d2b4d3SLarry Finger 		cck_power = 12;
497f1d2b4d3SLarry Finger 	if (cck_power >= 15)
498f1d2b4d3SLarry Finger 		cck_power -= 2;
499f1d2b4d3SLarry Finger 
500f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, cck_power);
501f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->TX_GAIN_CCK);
502f1d2b4d3SLarry Finger 	msleep(1);
503f1d2b4d3SLarry Finger 
504f1d2b4d3SLarry Finger 	ofdm_power = min(ofdm_power, (u8)35);
505f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, ofdm_power);
506f1d2b4d3SLarry Finger 
507f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 2, 0x62);
508f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 5, 0x00);
509f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 6, 0x40);
510f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 7, 0x00);
511f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 8, 0x40);
512f1d2b4d3SLarry Finger 
513f1d2b4d3SLarry Finger 	msleep(1);
514f1d2b4d3SLarry Finger }
515f1d2b4d3SLarry Finger 
516f1d2b4d3SLarry Finger static const u16 rtl8225z2_rxgain[] = {
517f1d2b4d3SLarry Finger 	0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
518f1d2b4d3SLarry Finger 	0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
519f1d2b4d3SLarry Finger 	0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
520f1d2b4d3SLarry Finger 	0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
521f1d2b4d3SLarry Finger 	0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
522f1d2b4d3SLarry Finger 	0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
523f1d2b4d3SLarry Finger 	0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
524f1d2b4d3SLarry Finger 	0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
525f1d2b4d3SLarry Finger 	0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
526f1d2b4d3SLarry Finger 	0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
527f1d2b4d3SLarry Finger 	0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
528f1d2b4d3SLarry Finger 	0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
529f1d2b4d3SLarry Finger };
530f1d2b4d3SLarry Finger 
rtl8225z2_rf_init(struct ieee80211_hw * dev)531f1d2b4d3SLarry Finger static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
532f1d2b4d3SLarry Finger {
533f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
534f1d2b4d3SLarry Finger 	int i;
535f1d2b4d3SLarry Finger 
536f1d2b4d3SLarry Finger 	rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);
537f1d2b4d3SLarry Finger 
538f1d2b4d3SLarry Finger 	/* host_pci_init */
539f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
540f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
541f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
542f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
543f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
544f1d2b4d3SLarry Finger 	msleep(200);	/* FIXME: ehh?? */
545f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
546f1d2b4d3SLarry Finger 
547f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00088008);
548f1d2b4d3SLarry Finger 
549f1d2b4d3SLarry Finger 	/* TODO: check if we need really to change BRSR to do RF config */
550f1d2b4d3SLarry Finger 	rtl818x_ioread16(priv, &priv->map->BRSR);
551f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
552f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
553f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
554f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
555f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
556f1d2b4d3SLarry Finger 
557f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
558f1d2b4d3SLarry Finger 
559f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
560f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
561f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x2, 0x44D); msleep(1);
562f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x3, 0x441); msleep(1);
563f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
564f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x5, 0xC72); msleep(1);
565f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
566f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x7, 0x82A); msleep(1);
567f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x8, 0x03F); msleep(1);
568f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x9, 0x335); msleep(1);
569f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
570f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
571f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xc, 0x850); msleep(1);
572f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
573f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xe, 0x02B); msleep(1);
574f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xf, 0x114); msleep(100);
575f1d2b4d3SLarry Finger 
576f1d2b4d3SLarry Finger 	if (!(rtl8225_read(dev, 6) & (1 << 7))) {
577f1d2b4d3SLarry Finger 		rtl8225_write(dev, 0x02, 0x0C4D);
578f1d2b4d3SLarry Finger 		msleep(200);
579f1d2b4d3SLarry Finger 		rtl8225_write(dev, 0x02, 0x044D);
580f1d2b4d3SLarry Finger 		msleep(100);
581f1d2b4d3SLarry Finger 		/* TODO: readd calibration failure message when the calibration
582f1d2b4d3SLarry Finger 		   check works */
583f1d2b4d3SLarry Finger 	}
584f1d2b4d3SLarry Finger 
585f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x0, 0x1B7);
586f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x3, 0x002);
587f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x5, 0x004);
588f1d2b4d3SLarry Finger 
589f1d2b4d3SLarry Finger 	for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
590f1d2b4d3SLarry Finger 		rtl8225_write(dev, 0x1, i + 1);
591f1d2b4d3SLarry Finger 		rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
592f1d2b4d3SLarry Finger 	}
593f1d2b4d3SLarry Finger 
594f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x0, 0x0B7); msleep(100);
595f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x2, 0xC4D);
596f1d2b4d3SLarry Finger 
597f1d2b4d3SLarry Finger 	msleep(200);
598f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x2, 0x44D);
599f1d2b4d3SLarry Finger 	msleep(100);
600f1d2b4d3SLarry Finger 
601f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x00, 0x2BF);
602f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0xFF, 0xFFFF);
603f1d2b4d3SLarry Finger 
604f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
605f1d2b4d3SLarry Finger 
606f1d2b4d3SLarry Finger 	for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
607f1d2b4d3SLarry Finger 		rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
608f1d2b4d3SLarry Finger 		msleep(1);
609f1d2b4d3SLarry Finger 		rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
610f1d2b4d3SLarry Finger 		msleep(1);
611f1d2b4d3SLarry Finger 	}
612f1d2b4d3SLarry Finger 
613f1d2b4d3SLarry Finger 	msleep(1);
614f1d2b4d3SLarry Finger 
615f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
616f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
617f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1);
618f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
619f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
620f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
621f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
622f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
623f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
624f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
625f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
626f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
627f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
628f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
629f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
630f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
631f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
632f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
633f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1);
634f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
635f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
636f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
637f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
638f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
639f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
640f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
641f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
642f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
643f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1b, 0x11); msleep(1);
644f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
645f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1);
646f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1e, 0xb3); msleep(1);
647f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
648f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
649f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
650f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
651f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); /* FIXME: not needed? */
652f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
653f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
654f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
655f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
656f1d2b4d3SLarry Finger 
657f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
658f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
659f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
660f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
661f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
662f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
663f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
664f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1);
665f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
666f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
667f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x13, 0xd0);
668f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x19, 0x00);
669f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
670f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x1b, 0x08);
671f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x40, 0x86);
672f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x41, 0x8a); msleep(1);
673f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
674f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
675f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1);
676f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1);
677f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1);
678f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1);
679f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1);
680f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1);
681f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1);
682f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1);
683f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
684f1d2b4d3SLarry Finger 
685f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, (u8 __iomem *)((void __iomem *)priv->map + 0x5B), 0x0D); msleep(1);
686f1d2b4d3SLarry Finger 
687f1d2b4d3SLarry Finger 	rtl8225z2_rf_set_tx_power(dev, 1);
688f1d2b4d3SLarry Finger 
689f1d2b4d3SLarry Finger 	/* RX antenna default to A */
690f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);	/* B: 0xDB */
691f1d2b4d3SLarry Finger 	rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);	/* B: 0x10 */
692f1d2b4d3SLarry Finger 
693f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);	/* B: 0x00 */
694f1d2b4d3SLarry Finger 	msleep(1);
695f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002);
696f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
697f1d2b4d3SLarry Finger }
698f1d2b4d3SLarry Finger 
rtl8225_rf_stop(struct ieee80211_hw * dev)699f1d2b4d3SLarry Finger static void rtl8225_rf_stop(struct ieee80211_hw *dev)
700f1d2b4d3SLarry Finger {
701f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
702f1d2b4d3SLarry Finger 	u8 reg;
703f1d2b4d3SLarry Finger 
704f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x4, 0x1f); msleep(1);
705f1d2b4d3SLarry Finger 
706f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
707f1d2b4d3SLarry Finger 	reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
708f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
709f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF);
710f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF);
711f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
712f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
713f1d2b4d3SLarry Finger }
714f1d2b4d3SLarry Finger 
rtl8225_rf_set_channel(struct ieee80211_hw * dev,struct ieee80211_conf * conf)715f1d2b4d3SLarry Finger static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
716f1d2b4d3SLarry Finger 				   struct ieee80211_conf *conf)
717f1d2b4d3SLarry Finger {
718f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
719f1d2b4d3SLarry Finger 	int chan =
720f1d2b4d3SLarry Finger 		ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
721f1d2b4d3SLarry Finger 
722f1d2b4d3SLarry Finger 	if (priv->rf->init == rtl8225_rf_init)
723f1d2b4d3SLarry Finger 		rtl8225_rf_set_tx_power(dev, chan);
724f1d2b4d3SLarry Finger 	else
725f1d2b4d3SLarry Finger 		rtl8225z2_rf_set_tx_power(dev, chan);
726f1d2b4d3SLarry Finger 
727f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
728f1d2b4d3SLarry Finger 	msleep(10);
729f1d2b4d3SLarry Finger }
730f1d2b4d3SLarry Finger 
731f1d2b4d3SLarry Finger static const struct rtl818x_rf_ops rtl8225_ops = {
732f1d2b4d3SLarry Finger 	.name		= "rtl8225",
733f1d2b4d3SLarry Finger 	.init		= rtl8225_rf_init,
734f1d2b4d3SLarry Finger 	.stop		= rtl8225_rf_stop,
735f1d2b4d3SLarry Finger 	.set_chan	= rtl8225_rf_set_channel,
736f1d2b4d3SLarry Finger };
737f1d2b4d3SLarry Finger 
738f1d2b4d3SLarry Finger static const struct rtl818x_rf_ops rtl8225z2_ops = {
739f1d2b4d3SLarry Finger 	.name		= "rtl8225z2",
740f1d2b4d3SLarry Finger 	.init		= rtl8225z2_rf_init,
741f1d2b4d3SLarry Finger 	.stop		= rtl8225_rf_stop,
742f1d2b4d3SLarry Finger 	.set_chan	= rtl8225_rf_set_channel,
743f1d2b4d3SLarry Finger };
744f1d2b4d3SLarry Finger 
rtl8180_detect_rf(struct ieee80211_hw * dev)745f1d2b4d3SLarry Finger const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
746f1d2b4d3SLarry Finger {
747f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
748f1d2b4d3SLarry Finger 	u16 reg8, reg9;
749f1d2b4d3SLarry Finger 
750f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
751f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
752f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
753f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
754f1d2b4d3SLarry Finger 	msleep(100);
755f1d2b4d3SLarry Finger 
756f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0, 0x1B7);
757f1d2b4d3SLarry Finger 
758f1d2b4d3SLarry Finger 	reg8 = rtl8225_read(dev, 8);
759f1d2b4d3SLarry Finger 	reg9 = rtl8225_read(dev, 9);
760f1d2b4d3SLarry Finger 
761f1d2b4d3SLarry Finger 	rtl8225_write(dev, 0, 0x0B7);
762f1d2b4d3SLarry Finger 
763f1d2b4d3SLarry Finger 	if (reg8 != 0x588 || reg9 != 0x700)
764f1d2b4d3SLarry Finger 		return &rtl8225_ops;
765f1d2b4d3SLarry Finger 
766f1d2b4d3SLarry Finger 	return &rtl8225z2_ops;
767f1d2b4d3SLarry Finger }
768