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
16static 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
33static 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
50static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = {
51	{ ZD_CR240, 0x57 }, { ZD_CR9,   0xe0 },
52};
53
54static 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
66static 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
92static 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
205static 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
347static 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
363static 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
381static 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
392static 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
403static 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
414int 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