aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl8180_sa2400.c
diff options
context:
space:
mode:
authorMichael Wu <flamingice@sourmilk.net>2007-10-14 14:43:16 -0400
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:09:35 -0500
commitf653211197f3841f383fa9757ef8ce182c6cf627 (patch)
treeba56e1fa09924d1ffab4f825044175291786b58e /drivers/net/wireless/rtl8180_sa2400.c
parentfa1c114fdaa605496045e56c42d0c8aa4c139e57 (diff)
Add rtl8180 wireless driver
This patch adds a mac80211 based wireless driver for the rtl8180 and rtl8185 PCI wireless cards. Also included are some rtl8187 changes required due to the relationship between that driver and this one. Michael Wu is primarily responsible for the initial driver and rtl8185 support. Andreas Merello provided the additional rtl8180 support. Thanks to Jukka Ruohonen for the donating a rtl8185 card! It was very helpful for the rtl8225z2 code. The Signed-off-by information below is collected from the individual patches submitted to wireless-2.6 before merging this driver upstream. Signed-off-by: Andrea Merello <andreamrl@tiscali.it> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Pavel Roskin <proski@gnu.org> Signed-off-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtl8180_sa2400.c')
-rw-r--r--drivers/net/wireless/rtl8180_sa2400.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c
new file mode 100644
index 000000000000..e08ace7b1cb7
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_sa2400.c
@@ -0,0 +1,201 @@
1
2/*
3 * Radio tuning for Philips SA2400 on RTL8180
4 *
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Code from the BSD driver and the rtl8181 project have been
8 * very useful to understand certain things
9 *
10 * I want to thanks the Authors of such projects and the Ndiswrapper
11 * project Authors.
12 *
13 * A special Big Thanks also is for all people who donated me cards,
14 * making possible the creation of the original rtl8180 driver
15 * from which this code is derived!
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
20 */
21
22#include <linux/init.h>
23#include <linux/pci.h>
24#include <linux/delay.h>
25#include <net/mac80211.h>
26
27#include "rtl8180.h"
28#include "rtl8180_sa2400.h"
29
30static const u32 sa2400_chan[] = {
31 0x00096c, /* ch1 */
32 0x080970,
33 0x100974,
34 0x180978,
35 0x000980,
36 0x080984,
37 0x100988,
38 0x18098c,
39 0x000994,
40 0x080998,
41 0x10099c,
42 0x1809a0,
43 0x0009a8,
44 0x0009b4, /* ch 14 */
45};
46
47static void write_sa2400(struct ieee80211_hw *dev, u8 addr, u32 data)
48{
49 struct rtl8180_priv *priv = dev->priv;
50 u32 phy_config;
51
52 /* MAC will bang bits to the sa2400. sw 3-wire is NOT used */
53 phy_config = 0xb0000000;
54
55 phy_config |= ((u32)(addr & 0xf)) << 24;
56 phy_config |= data & 0xffffff;
57
58 rtl818x_iowrite32(priv,
59 (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
60
61 msleep(3);
62}
63
64static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan)
65{
66 struct rtl8180_priv *priv = dev->priv;
67 u8 ant = SA2400_ANTENNA;
68
69 if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
70 ant |= BB_ANTENNA_B;
71
72 if (chan == 14)
73 ant |= BB_ANTATTEN_CHAN14;
74
75 rtl8180_write_phy(dev, 0x10, ant);
76
77}
78
79static void sa2400_rf_set_channel(struct ieee80211_hw *dev,
80 struct ieee80211_conf *conf)
81{
82 struct rtl8180_priv *priv = dev->priv;
83 u32 txpw = priv->channels[conf->channel - 1].val & 0xFF;
84 u32 chan = sa2400_chan[conf->channel - 1];
85
86 write_sa2400(dev, 7, txpw);
87
88 sa2400_write_phy_antenna(dev, chan);
89
90 write_sa2400(dev, 0, chan);
91 write_sa2400(dev, 1, 0xbb50);
92 write_sa2400(dev, 2, 0x80);
93 write_sa2400(dev, 3, 0);
94}
95
96static void sa2400_rf_stop(struct ieee80211_hw *dev)
97{
98 write_sa2400(dev, 4, 0);
99}
100
101static void sa2400_rf_init(struct ieee80211_hw *dev)
102{
103 struct rtl8180_priv *priv = dev->priv;
104 u32 anaparam, txconf;
105 u8 firdac;
106 int analogphy = priv->rfparam & RF_PARAM_ANALOGPHY;
107
108 anaparam = priv->anaparam;
109 anaparam &= ~(1 << ANAPARAM_TXDACOFF_SHIFT);
110 anaparam &= ~ANAPARAM_PWR1_MASK;
111 anaparam &= ~ANAPARAM_PWR0_MASK;
112
113 if (analogphy) {
114 anaparam |= SA2400_ANA_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT;
115 firdac = 0;
116 } else {
117 anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT);
118 anaparam |= (SA2400_ANAPARAM_PWR0_ON << ANAPARAM_PWR0_SHIFT);
119 firdac = 1 << SA2400_REG4_FIRDAC_SHIFT;
120 }
121
122 rtl8180_set_anaparam(priv, anaparam);
123
124 write_sa2400(dev, 0, sa2400_chan[0]);
125 write_sa2400(dev, 1, 0xbb50);
126 write_sa2400(dev, 2, 0x80);
127 write_sa2400(dev, 3, 0);
128 write_sa2400(dev, 4, 0x19340 | firdac);
129 write_sa2400(dev, 5, 0x1dfb | (SA2400_MAX_SENS - 54) << 15);
130 write_sa2400(dev, 4, 0x19348 | firdac); /* calibrate VCO */
131
132 if (!analogphy)
133 write_sa2400(dev, 4, 0x1938c); /*???*/
134
135 write_sa2400(dev, 4, 0x19340 | firdac);
136
137 write_sa2400(dev, 0, sa2400_chan[0]);
138 write_sa2400(dev, 1, 0xbb50);
139 write_sa2400(dev, 2, 0x80);
140 write_sa2400(dev, 3, 0);
141 write_sa2400(dev, 4, 0x19344 | firdac); /* calibrate filter */
142
143 /* new from rtl8180 embedded driver (rtl8181 project) */
144 write_sa2400(dev, 6, 0x13ff | (1 << 23)); /* MANRX */
145 write_sa2400(dev, 8, 0); /* VCO */
146
147 if (analogphy) {
148 rtl8180_set_anaparam(priv, anaparam |
149 (1 << ANAPARAM_TXDACOFF_SHIFT));
150
151 txconf = rtl818x_ioread32(priv, &priv->map->TX_CONF);
152 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
153 txconf | RTL818X_TX_CONF_LOOPBACK_CONT);
154
155 write_sa2400(dev, 4, 0x19341); /* calibrates DC */
156
157 /* a 5us sleep is required here,
158 * we rely on the 3ms delay introduced in write_sa2400 */
159 write_sa2400(dev, 4, 0x19345);
160
161 /* a 20us sleep is required here,
162 * we rely on the 3ms delay introduced in write_sa2400 */
163
164 rtl818x_iowrite32(priv, &priv->map->TX_CONF, txconf);
165
166 rtl8180_set_anaparam(priv, anaparam);
167 }
168 /* end new code */
169
170 write_sa2400(dev, 4, 0x19341 | firdac); /* RTX MODE */
171
172 /* baseband configuration */
173 rtl8180_write_phy(dev, 0, 0x98);
174 rtl8180_write_phy(dev, 3, 0x38);
175 rtl8180_write_phy(dev, 4, 0xe0);
176 rtl8180_write_phy(dev, 5, 0x90);
177 rtl8180_write_phy(dev, 6, 0x1a);
178 rtl8180_write_phy(dev, 7, 0x64);
179
180 sa2400_write_phy_antenna(dev, 1);
181
182 rtl8180_write_phy(dev, 0x11, 0x80);
183
184 if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
185 RTL818X_CONFIG2_ANTENNA_DIV)
186 rtl8180_write_phy(dev, 0x12, 0xc7); /* enable ant diversity */
187 else
188 rtl8180_write_phy(dev, 0x12, 0x47); /* disable ant diversity */
189
190 rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
191
192 rtl8180_write_phy(dev, 0x19, 0x0);
193 rtl8180_write_phy(dev, 0x1a, 0xa0);
194}
195
196const struct rtl818x_rf_ops sa2400_rf_ops = {
197 .name = "Philips",
198 .init = sa2400_rf_init,
199 .stop = sa2400_rf_stop,
200 .set_chan = sa2400_rf_set_channel
201};