1 // SPDX-License-Identifier: GPL-2.0-only
4 * Radio tuning for GCT GRF5101 on RTL8180
6 * Copyright 2007 Andrea Merello <andrea.merello@gmail.com>
8 * Code from the BSD driver and the rtl8181 project have been
9 * very useful to understand certain things
11 * I want to thanks the Authors of such projects and the Ndiswrapper
14 * A special Big Thanks also is for all people who donated me cards,
15 * making possible the creation of the original rtl8180 driver
16 * from which this code is derived!
19 #include <linux/pci.h>
20 #include <linux/delay.h>
21 #include <net/mac80211.h>
26 static const int grf5101_encode
[] = {
33 static void write_grf5101(struct ieee80211_hw
*dev
, u8 addr
, u32 data
)
35 struct rtl8180_priv
*priv
= dev
->priv
;
38 phy_config
= grf5101_encode
[(data
>> 8) & 0xF];
39 phy_config
|= grf5101_encode
[(data
>> 4) & 0xF] << 4;
40 phy_config
|= grf5101_encode
[data
& 0xF] << 8;
41 phy_config
|= grf5101_encode
[(addr
>> 1) & 0xF] << 12;
42 phy_config
|= (addr
& 1) << 16;
43 phy_config
|= grf5101_encode
[(data
& 0xf000) >> 12] << 24;
45 /* MAC will bang bits to the chip */
46 phy_config
|= 0x90000000;
48 rtl818x_iowrite32(priv
,
49 (__le32 __iomem
*) &priv
->map
->RFPinsOutput
, phy_config
);
54 static void grf5101_write_phy_antenna(struct ieee80211_hw
*dev
, short chan
)
56 struct rtl8180_priv
*priv
= dev
->priv
;
57 u8 ant
= GRF5101_ANTENNA
;
59 if (priv
->rfparam
& RF_PARAM_ANTBDEFAULT
)
63 ant
|= BB_ANTATTEN_CHAN14
;
65 rtl8180_write_phy(dev
, 0x10, ant
);
68 static u8
grf5101_rf_calc_rssi(u8 agc
, u8 sq
)
73 /* TODO(?): just return agc (or agc + 5) to avoid mult / div */
77 static void grf5101_rf_set_channel(struct ieee80211_hw
*dev
,
78 struct ieee80211_conf
*conf
)
80 struct rtl8180_priv
*priv
= dev
->priv
;
82 ieee80211_frequency_to_channel(conf
->chandef
.chan
->center_freq
);
83 u32 txpw
= priv
->channels
[channel
- 1].hw_value
& 0xFF;
84 u32 chan
= channel
- 1;
87 write_grf5101(dev
, 0x15, 0x0);
88 write_grf5101(dev
, 0x06, txpw
);
89 write_grf5101(dev
, 0x15, 0x10);
90 write_grf5101(dev
, 0x15, 0x0);
93 write_grf5101(dev
, 0x07, 0x0);
94 write_grf5101(dev
, 0x0B, chan
);
95 write_grf5101(dev
, 0x07, 0x1000);
97 grf5101_write_phy_antenna(dev
, channel
);
100 static void grf5101_rf_stop(struct ieee80211_hw
*dev
)
102 struct rtl8180_priv
*priv
= dev
->priv
;
105 anaparam
= priv
->anaparam
;
106 anaparam
&= 0x000fffff;
107 anaparam
|= 0x3f900000;
108 rtl8180_set_anaparam(priv
, anaparam
);
110 write_grf5101(dev
, 0x07, 0x0);
111 write_grf5101(dev
, 0x1f, 0x45);
112 write_grf5101(dev
, 0x1f, 0x5);
113 write_grf5101(dev
, 0x00, 0x8e4);
116 static void grf5101_rf_init(struct ieee80211_hw
*dev
)
118 struct rtl8180_priv
*priv
= dev
->priv
;
120 rtl8180_set_anaparam(priv
, priv
->anaparam
);
122 write_grf5101(dev
, 0x1f, 0x0);
123 write_grf5101(dev
, 0x1f, 0x0);
124 write_grf5101(dev
, 0x1f, 0x40);
125 write_grf5101(dev
, 0x1f, 0x60);
126 write_grf5101(dev
, 0x1f, 0x61);
127 write_grf5101(dev
, 0x1f, 0x61);
128 write_grf5101(dev
, 0x00, 0xae4);
129 write_grf5101(dev
, 0x1f, 0x1);
130 write_grf5101(dev
, 0x1f, 0x41);
131 write_grf5101(dev
, 0x1f, 0x61);
133 write_grf5101(dev
, 0x01, 0x1a23);
134 write_grf5101(dev
, 0x02, 0x4971);
135 write_grf5101(dev
, 0x03, 0x41de);
136 write_grf5101(dev
, 0x04, 0x2d80);
137 write_grf5101(dev
, 0x05, 0x68ff); /* 0x61ff original value */
138 write_grf5101(dev
, 0x06, 0x0);
139 write_grf5101(dev
, 0x07, 0x0);
140 write_grf5101(dev
, 0x08, 0x7533);
141 write_grf5101(dev
, 0x09, 0xc401);
142 write_grf5101(dev
, 0x0a, 0x0);
143 write_grf5101(dev
, 0x0c, 0x1c7);
144 write_grf5101(dev
, 0x0d, 0x29d3);
145 write_grf5101(dev
, 0x0e, 0x2e8);
146 write_grf5101(dev
, 0x10, 0x192);
147 write_grf5101(dev
, 0x11, 0x248);
148 write_grf5101(dev
, 0x12, 0x0);
149 write_grf5101(dev
, 0x13, 0x20c4);
150 write_grf5101(dev
, 0x14, 0xf4fc);
151 write_grf5101(dev
, 0x15, 0x0);
152 write_grf5101(dev
, 0x16, 0x1500);
154 write_grf5101(dev
, 0x07, 0x1000);
156 /* baseband configuration */
157 rtl8180_write_phy(dev
, 0, 0xa8);
158 rtl8180_write_phy(dev
, 3, 0x0);
159 rtl8180_write_phy(dev
, 4, 0xc0);
160 rtl8180_write_phy(dev
, 5, 0x90);
161 rtl8180_write_phy(dev
, 6, 0x1e);
162 rtl8180_write_phy(dev
, 7, 0x64);
164 grf5101_write_phy_antenna(dev
, 1);
166 rtl8180_write_phy(dev
, 0x11, 0x88);
168 if (rtl818x_ioread8(priv
, &priv
->map
->CONFIG2
) &
169 RTL818X_CONFIG2_ANTENNA_DIV
)
170 rtl8180_write_phy(dev
, 0x12, 0xc0); /* enable ant diversity */
172 rtl8180_write_phy(dev
, 0x12, 0x40); /* disable ant diversity */
174 rtl8180_write_phy(dev
, 0x13, 0x90 | priv
->csthreshold
);
176 rtl8180_write_phy(dev
, 0x19, 0x0);
177 rtl8180_write_phy(dev
, 0x1a, 0xa0);
178 rtl8180_write_phy(dev
, 0x1b, 0x44);
181 const struct rtl818x_rf_ops grf5101_rf_ops
= {
183 .init
= grf5101_rf_init
,
184 .stop
= grf5101_rf_stop
,
185 .set_chan
= grf5101_rf_set_channel
,
186 .calc_rssi
= grf5101_rf_calc_rssi
,