xref: /linux/drivers/net/wireless/zydas/zd1211rw/zd_rf_al2230.c (revision 24bce201d79807b668bf9d9e0aca801c5c0d5f78)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* ZD1211 USB-WLAN driver for Linux
3  *
4  * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
5  * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
6  */
7 
8 #include <linux/kernel.h>
9 
10 #include "zd_rf.h"
11 #include "zd_usb.h"
12 #include "zd_chip.h"
13 
14 #define IS_AL2230S(chip) ((chip)->al2230s_bit || (chip)->rf.type == AL2230S_RF)
15 
16 static const u32 zd1211_al2230_table[][3] = {
17 	RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, },
18 	RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, },
19 	RF_CHANNEL( 3) = { 0x03e790, 0x033331, 0x00000d, },
20 	RF_CHANNEL( 4) = { 0x03e790, 0x0b3331, 0x00000d, },
21 	RF_CHANNEL( 5) = { 0x03f7a0, 0x033331, 0x00000d, },
22 	RF_CHANNEL( 6) = { 0x03f7a0, 0x0b3331, 0x00000d, },
23 	RF_CHANNEL( 7) = { 0x03e7a0, 0x033331, 0x00000d, },
24 	RF_CHANNEL( 8) = { 0x03e7a0, 0x0b3331, 0x00000d, },
25 	RF_CHANNEL( 9) = { 0x03f7b0, 0x033331, 0x00000d, },
26 	RF_CHANNEL(10) = { 0x03f7b0, 0x0b3331, 0x00000d, },
27 	RF_CHANNEL(11) = { 0x03e7b0, 0x033331, 0x00000d, },
28 	RF_CHANNEL(12) = { 0x03e7b0, 0x0b3331, 0x00000d, },
29 	RF_CHANNEL(13) = { 0x03f7c0, 0x033331, 0x00000d, },
30 	RF_CHANNEL(14) = { 0x03e7c0, 0x066661, 0x00000d, },
31 };
32 
33 static const u32 zd1211b_al2230_table[][3] = {
34 	RF_CHANNEL( 1) = { 0x09efc0, 0x8cccc0, 0xb00000, },
35 	RF_CHANNEL( 2) = { 0x09efc0, 0x8cccd0, 0xb00000, },
36 	RF_CHANNEL( 3) = { 0x09e7c0, 0x8cccc0, 0xb00000, },
37 	RF_CHANNEL( 4) = { 0x09e7c0, 0x8cccd0, 0xb00000, },
38 	RF_CHANNEL( 5) = { 0x05efc0, 0x8cccc0, 0xb00000, },
39 	RF_CHANNEL( 6) = { 0x05efc0, 0x8cccd0, 0xb00000, },
40 	RF_CHANNEL( 7) = { 0x05e7c0, 0x8cccc0, 0xb00000, },
41 	RF_CHANNEL( 8) = { 0x05e7c0, 0x8cccd0, 0xb00000, },
42 	RF_CHANNEL( 9) = { 0x0defc0, 0x8cccc0, 0xb00000, },
43 	RF_CHANNEL(10) = { 0x0defc0, 0x8cccd0, 0xb00000, },
44 	RF_CHANNEL(11) = { 0x0de7c0, 0x8cccc0, 0xb00000, },
45 	RF_CHANNEL(12) = { 0x0de7c0, 0x8cccd0, 0xb00000, },
46 	RF_CHANNEL(13) = { 0x03efc0, 0x8cccc0, 0xb00000, },
47 	RF_CHANNEL(14) = { 0x03e7c0, 0x866660, 0xb00000, },
48 };
49 
50 static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = {
51 	{ ZD_CR240, 0x57 }, { ZD_CR9,   0xe0 },
52 };
53 
54 static const struct zd_ioreq16 ioreqs_init_al2230s[] = {
55 	{ ZD_CR47,   0x1e }, /* MARK_002 */
56 	{ ZD_CR106,  0x22 },
57 	{ ZD_CR107,  0x2a }, /* MARK_002 */
58 	{ ZD_CR109,  0x13 }, /* MARK_002 */
59 	{ ZD_CR118,  0xf8 }, /* MARK_002 */
60 	{ ZD_CR119,  0x12 }, { ZD_CR122,  0xe0 },
61 	{ ZD_CR128,  0x10 }, /* MARK_001 from 0xe->0x10 */
62 	{ ZD_CR129,  0x0e }, /* MARK_001 from 0xd->0x0e */
63 	{ ZD_CR130,  0x10 }, /* MARK_001 from 0xb->0x0d */
64 };
65 
66 static int zd1211b_al2230_finalize_rf(struct zd_chip *chip)
67 {
68 	int r;
69 	static const struct zd_ioreq16 ioreqs[] = {
70 		{ ZD_CR80,  0x30 }, { ZD_CR81,  0x30 }, { ZD_CR79,  0x58 },
71 		{ ZD_CR12,  0xf0 }, { ZD_CR77,  0x1b }, { ZD_CR78,  0x58 },
72 		{ ZD_CR203, 0x06 },
73 		{ },
74 
75 		{ ZD_CR240, 0x80 },
76 	};
77 
78 	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
79 	if (r)
80 		return r;
81 
82 	/* related to antenna selection? */
83 	if (chip->new_phy_layout) {
84 		r = zd_iowrite16_locked(chip, 0xe1, ZD_CR9);
85 		if (r)
86 			return r;
87 	}
88 
89 	return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
90 }
91 
92 static int zd1211_al2230_init_hw(struct zd_rf *rf)
93 {
94 	int r;
95 	struct zd_chip *chip = zd_rf_to_chip(rf);
96 
97 	static const struct zd_ioreq16 ioreqs_init[] = {
98 		{ ZD_CR15,   0x20 }, { ZD_CR23,   0x40 }, { ZD_CR24,  0x20 },
99 		{ ZD_CR26,   0x11 }, { ZD_CR28,   0x3e }, { ZD_CR29,  0x00 },
100 		{ ZD_CR44,   0x33 }, { ZD_CR106,  0x2a }, { ZD_CR107, 0x1a },
101 		{ ZD_CR109,  0x09 }, { ZD_CR110,  0x27 }, { ZD_CR111, 0x2b },
102 		{ ZD_CR112,  0x2b }, { ZD_CR119,  0x0a }, { ZD_CR10,  0x89 },
103 		/* for newest (3rd cut) AL2300 */
104 		{ ZD_CR17,   0x28 },
105 		{ ZD_CR26,   0x93 }, { ZD_CR34,   0x30 },
106 		/* for newest (3rd cut) AL2300 */
107 		{ ZD_CR35,   0x3e },
108 		{ ZD_CR41,   0x24 }, { ZD_CR44,   0x32 },
109 		/* for newest (3rd cut) AL2300 */
110 		{ ZD_CR46,   0x96 },
111 		{ ZD_CR47,   0x1e }, { ZD_CR79,   0x58 }, { ZD_CR80,  0x30 },
112 		{ ZD_CR81,   0x30 }, { ZD_CR87,   0x0a }, { ZD_CR89,  0x04 },
113 		{ ZD_CR92,   0x0a }, { ZD_CR99,   0x28 }, { ZD_CR100, 0x00 },
114 		{ ZD_CR101,  0x13 }, { ZD_CR102,  0x27 }, { ZD_CR106, 0x24 },
115 		{ ZD_CR107,  0x2a }, { ZD_CR109,  0x09 }, { ZD_CR110, 0x13 },
116 		{ ZD_CR111,  0x1f }, { ZD_CR112,  0x1f }, { ZD_CR113, 0x27 },
117 		{ ZD_CR114,  0x27 },
118 		/* for newest (3rd cut) AL2300 */
119 		{ ZD_CR115,  0x24 },
120 		{ ZD_CR116,  0x24 }, { ZD_CR117,  0xf4 }, { ZD_CR118, 0xfc },
121 		{ ZD_CR119,  0x10 }, { ZD_CR120,  0x4f }, { ZD_CR121, 0x77 },
122 		{ ZD_CR122,  0xe0 }, { ZD_CR137,  0x88 }, { ZD_CR252, 0xff },
123 		{ ZD_CR253,  0xff },
124 	};
125 
126 	static const struct zd_ioreq16 ioreqs_pll[] = {
127 		/* shdnb(PLL_ON)=0 */
128 		{ ZD_CR251,  0x2f },
129 		/* shdnb(PLL_ON)=1 */
130 		{ ZD_CR251,  0x3f },
131 		{ ZD_CR138,  0x28 }, { ZD_CR203,  0x06 },
132 	};
133 
134 	static const u32 rv1[] = {
135 		/* Channel 1 */
136 		0x03f790,
137 		0x033331,
138 		0x00000d,
139 
140 		0x0b3331,
141 		0x03b812,
142 		0x00fff3,
143 	};
144 
145 	static const u32 rv2[] = {
146 		0x000da4,
147 		0x0f4dc5, /* fix freq shift, 0x04edc5 */
148 		0x0805b6,
149 		0x011687,
150 		0x000688,
151 		0x0403b9, /* external control TX power (ZD_CR31) */
152 		0x00dbba,
153 		0x00099b,
154 		0x0bdffc,
155 		0x00000d,
156 		0x00500f,
157 	};
158 
159 	static const u32 rv3[] = {
160 		0x00d00f,
161 		0x004c0f,
162 		0x00540f,
163 		0x00700f,
164 		0x00500f,
165 	};
166 
167 	r = zd_iowrite16a_locked(chip, ioreqs_init, ARRAY_SIZE(ioreqs_init));
168 	if (r)
169 		return r;
170 
171 	if (IS_AL2230S(chip)) {
172 		r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
173 			ARRAY_SIZE(ioreqs_init_al2230s));
174 		if (r)
175 			return r;
176 	}
177 
178 	r = zd_rfwritev_locked(chip, rv1, ARRAY_SIZE(rv1), RF_RV_BITS);
179 	if (r)
180 		return r;
181 
182 	/* improve band edge for AL2230S */
183 	if (IS_AL2230S(chip))
184 		r = zd_rfwrite_locked(chip, 0x000824, RF_RV_BITS);
185 	else
186 		r = zd_rfwrite_locked(chip, 0x0005a4, RF_RV_BITS);
187 	if (r)
188 		return r;
189 
190 	r = zd_rfwritev_locked(chip, rv2, ARRAY_SIZE(rv2), RF_RV_BITS);
191 	if (r)
192 		return r;
193 
194 	r = zd_iowrite16a_locked(chip, ioreqs_pll, ARRAY_SIZE(ioreqs_pll));
195 	if (r)
196 		return r;
197 
198 	r = zd_rfwritev_locked(chip, rv3, ARRAY_SIZE(rv3), RF_RV_BITS);
199 	if (r)
200 		return r;
201 
202 	return 0;
203 }
204 
205 static int zd1211b_al2230_init_hw(struct zd_rf *rf)
206 {
207 	int r;
208 	struct zd_chip *chip = zd_rf_to_chip(rf);
209 
210 	static const struct zd_ioreq16 ioreqs1[] = {
211 		{ ZD_CR10,  0x89 }, { ZD_CR15,  0x20 },
212 		{ ZD_CR17,  0x2B }, /* for newest(3rd cut) AL2230 */
213 		{ ZD_CR23,  0x40 }, { ZD_CR24,  0x20 }, { ZD_CR26,  0x93 },
214 		{ ZD_CR28,  0x3e }, { ZD_CR29,  0x00 },
215 		{ ZD_CR33,  0x28 }, /* 5621 */
216 		{ ZD_CR34,  0x30 },
217 		{ ZD_CR35,  0x3e }, /* for newest(3rd cut) AL2230 */
218 		{ ZD_CR41,  0x24 }, { ZD_CR44,  0x32 },
219 		{ ZD_CR46,  0x99 }, /* for newest(3rd cut) AL2230 */
220 		{ ZD_CR47,  0x1e },
221 
222 		/* ZD1211B 05.06.10 */
223 		{ ZD_CR48,  0x06 }, { ZD_CR49,  0xf9 }, { ZD_CR51,  0x01 },
224 		{ ZD_CR52,  0x80 }, { ZD_CR53,  0x7e }, { ZD_CR65,  0x00 },
225 		{ ZD_CR66,  0x00 }, { ZD_CR67,  0x00 }, { ZD_CR68,  0x00 },
226 		{ ZD_CR69,  0x28 },
227 
228 		{ ZD_CR79,  0x58 }, { ZD_CR80,  0x30 }, { ZD_CR81,  0x30 },
229 		{ ZD_CR87,  0x0a }, { ZD_CR89,  0x04 },
230 		{ ZD_CR91,  0x00 }, /* 5621 */
231 		{ ZD_CR92,  0x0a },
232 		{ ZD_CR98,  0x8d }, /* 4804,  for 1212 new algorithm */
233 		{ ZD_CR99,  0x00 }, /* 5621 */
234 		{ ZD_CR101, 0x13 }, { ZD_CR102, 0x27 },
235 		{ ZD_CR106, 0x24 }, /* for newest(3rd cut) AL2230 */
236 		{ ZD_CR107, 0x2a },
237 		{ ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */
238 		{ ZD_CR110, 0x1f }, /* 4804, for 1212 new algorithm */
239 		{ ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
240 		{ ZD_CR114, 0x27 },
241 		{ ZD_CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut)
242 				     * AL2230
243 				     */
244 		{ ZD_CR116, 0x24 },
245 		{ ZD_CR117, 0xfa }, /* for 1211b */
246 		{ ZD_CR118, 0xfa }, /* for 1211b */
247 		{ ZD_CR119, 0x10 },
248 		{ ZD_CR120, 0x4f },
249 		{ ZD_CR121, 0x6c }, /* for 1211b */
250 		{ ZD_CR122, 0xfc }, /* E0->FC at 4902 */
251 		{ ZD_CR123, 0x57 }, /* 5623 */
252 		{ ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */
253 		{ ZD_CR126, 0x6c }, /* 5614 */
254 		{ ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */
255 		{ ZD_CR137, 0x50 }, /* 5614 */
256 		{ ZD_CR138, 0xa8 },
257 		{ ZD_CR144, 0xac }, /* 5621 */
258 		{ ZD_CR150, 0x0d }, { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 },
259 	};
260 
261 	static const u32 rv1[] = {
262 		0x8cccd0,
263 		0x481dc0,
264 		0xcfff00,
265 		0x25a000,
266 	};
267 
268 	static const u32 rv2[] = {
269 		/* To improve AL2230 yield, improve phase noise, 4713 */
270 		0x25a000,
271 		0xa3b2f0,
272 
273 		0x6da010, /* Reg6 update for MP versio */
274 		0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */
275 		0x116000,
276 		0x9dc020, /* External control TX power (ZD_CR31) */
277 		0x5ddb00, /* RegA update for MP version */
278 		0xd99000, /* RegB update for MP version */
279 		0x3ffbd0, /* RegC update for MP version */
280 		0xb00000, /* RegD update for MP version */
281 
282 		/* improve phase noise and remove phase calibration,4713 */
283 		0xf01a00,
284 	};
285 
286 	static const struct zd_ioreq16 ioreqs2[] = {
287 		{ ZD_CR251, 0x2f }, /* shdnb(PLL_ON)=0 */
288 		{ ZD_CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
289 	};
290 
291 	static const u32 rv3[] = {
292 		/* To improve AL2230 yield, 4713 */
293 		0xf01b00,
294 		0xf01e00,
295 		0xf01a00,
296 	};
297 
298 	static const struct zd_ioreq16 ioreqs3[] = {
299 		/* related to 6M band edge patching, happens unconditionally */
300 		{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
301 	};
302 
303 	r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1,
304 		ARRAY_SIZE(zd1211b_ioreqs_shared_1));
305 	if (r)
306 		return r;
307 	r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1));
308 	if (r)
309 		return r;
310 
311 	if (IS_AL2230S(chip)) {
312 		r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
313 			ARRAY_SIZE(ioreqs_init_al2230s));
314 		if (r)
315 			return r;
316 	}
317 
318 	r = zd_rfwritev_cr_locked(chip, zd1211b_al2230_table[0], 3);
319 	if (r)
320 		return r;
321 	r = zd_rfwritev_cr_locked(chip, rv1, ARRAY_SIZE(rv1));
322 	if (r)
323 		return r;
324 
325 	if (IS_AL2230S(chip))
326 		r = zd_rfwrite_locked(chip, 0x241000, RF_RV_BITS);
327 	else
328 		r = zd_rfwrite_locked(chip, 0x25a000, RF_RV_BITS);
329 	if (r)
330 		return r;
331 
332 	r = zd_rfwritev_cr_locked(chip, rv2, ARRAY_SIZE(rv2));
333 	if (r)
334 		return r;
335 	r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2));
336 	if (r)
337 		return r;
338 	r = zd_rfwritev_cr_locked(chip, rv3, ARRAY_SIZE(rv3));
339 	if (r)
340 		return r;
341 	r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3));
342 	if (r)
343 		return r;
344 	return zd1211b_al2230_finalize_rf(chip);
345 }
346 
347 static int zd1211_al2230_set_channel(struct zd_rf *rf, u8 channel)
348 {
349 	int r;
350 	const u32 *rv = zd1211_al2230_table[channel-1];
351 	struct zd_chip *chip = zd_rf_to_chip(rf);
352 	static const struct zd_ioreq16 ioreqs[] = {
353 		{ ZD_CR138, 0x28 },
354 		{ ZD_CR203, 0x06 },
355 	};
356 
357 	r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS);
358 	if (r)
359 		return r;
360 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
361 }
362 
363 static int zd1211b_al2230_set_channel(struct zd_rf *rf, u8 channel)
364 {
365 	int r;
366 	const u32 *rv = zd1211b_al2230_table[channel-1];
367 	struct zd_chip *chip = zd_rf_to_chip(rf);
368 
369 	r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1,
370 		ARRAY_SIZE(zd1211b_ioreqs_shared_1));
371 	if (r)
372 		return r;
373 
374 	r = zd_rfwritev_cr_locked(chip, rv, 3);
375 	if (r)
376 		return r;
377 
378 	return zd1211b_al2230_finalize_rf(chip);
379 }
380 
381 static int zd1211_al2230_switch_radio_on(struct zd_rf *rf)
382 {
383 	struct zd_chip *chip = zd_rf_to_chip(rf);
384 	static const struct zd_ioreq16 ioreqs[] = {
385 		{ ZD_CR11,  0x00 },
386 		{ ZD_CR251, 0x3f },
387 	};
388 
389 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
390 }
391 
392 static int zd1211b_al2230_switch_radio_on(struct zd_rf *rf)
393 {
394 	struct zd_chip *chip = zd_rf_to_chip(rf);
395 	static const struct zd_ioreq16 ioreqs[] = {
396 		{ ZD_CR11,  0x00 },
397 		{ ZD_CR251, 0x7f },
398 	};
399 
400 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
401 }
402 
403 static int al2230_switch_radio_off(struct zd_rf *rf)
404 {
405 	struct zd_chip *chip = zd_rf_to_chip(rf);
406 	static const struct zd_ioreq16 ioreqs[] = {
407 		{ ZD_CR11,  0x04 },
408 		{ ZD_CR251, 0x2f },
409 	};
410 
411 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
412 }
413 
414 int zd_rf_init_al2230(struct zd_rf *rf)
415 {
416 	struct zd_chip *chip = zd_rf_to_chip(rf);
417 
418 	rf->switch_radio_off = al2230_switch_radio_off;
419 	if (zd_chip_is_zd1211b(chip)) {
420 		rf->init_hw = zd1211b_al2230_init_hw;
421 		rf->set_channel = zd1211b_al2230_set_channel;
422 		rf->switch_radio_on = zd1211b_al2230_switch_radio_on;
423 	} else {
424 		rf->init_hw = zd1211_al2230_init_hw;
425 		rf->set_channel = zd1211_al2230_set_channel;
426 		rf->switch_radio_on = zd1211_al2230_switch_radio_on;
427 	}
428 	rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
429 	rf->patch_cck_gain = 1;
430 	return 0;
431 }
432