File Index
Files and directories
Sign in
FILE

zd_rf_al7230b.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/zydas/zd1211rw/zd_rf_al7230b.c C
  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
 14static const u32 chan_rv[][2] = {
 15	RF_CHANNEL( 1) = { 0x09ec00, 0x8cccc8 },
 16	RF_CHANNEL( 2) = { 0x09ec00, 0x8cccd8 },
 17	RF_CHANNEL( 3) = { 0x09ec00, 0x8cccc0 },
 18	RF_CHANNEL( 4) = { 0x09ec00, 0x8cccd0 },
 19	RF_CHANNEL( 5) = { 0x05ec00, 0x8cccc8 },
 20	RF_CHANNEL( 6) = { 0x05ec00, 0x8cccd8 },
 21	RF_CHANNEL( 7) = { 0x05ec00, 0x8cccc0 },
 22	RF_CHANNEL( 8) = { 0x05ec00, 0x8cccd0 },
 23	RF_CHANNEL( 9) = { 0x0dec00, 0x8cccc8 },
 24	RF_CHANNEL(10) = { 0x0dec00, 0x8cccd8 },
 25	RF_CHANNEL(11) = { 0x0dec00, 0x8cccc0 },
 26	RF_CHANNEL(12) = { 0x0dec00, 0x8cccd0 },
 27	RF_CHANNEL(13) = { 0x03ec00, 0x8cccc8 },
 28	RF_CHANNEL(14) = { 0x03ec00, 0x866660 },
 29};
 30
 31static const u32 std_rv[] = {
 32	0x4ff821,
 33	0xc5fbfc,
 34	0x21ebfe,
 35	0xafd401, /* freq shift 0xaad401 */
 36	0x6cf56a,
 37	0xe04073,
 38	0x193d76,
 39	0x9dd844,
 40	0x500007,
 41	0xd8c010,
 42};
 43
 44static const u32 rv_init1[] = {
 45	0x3c9000,
 46	0xbfffff,
 47	0x700000,
 48	0xf15d58,
 49};
 50
 51static const u32 rv_init2[] = {
 52	0xf15d59,
 53	0xf15d5c,
 54	0xf15d58,
 55};
 56
 57static const struct zd_ioreq16 ioreqs_sw[] = {
 58	{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
 59	{ ZD_CR38,  0x38 }, { ZD_CR136, 0xdf },
 60};
 61
 62static int zd1211b_al7230b_finalize(struct zd_chip *chip)
 63{
 64	int r;
 65	static const struct zd_ioreq16 ioreqs[] = {
 66		{ ZD_CR80,  0x30 }, { ZD_CR81,  0x30 }, { ZD_CR79,  0x58 },
 67		{ ZD_CR12,  0xf0 }, { ZD_CR77,  0x1b }, { ZD_CR78,  0x58 },
 68		{ ZD_CR203, 0x04 },
 69		{ },
 70		{ ZD_CR240, 0x80 },
 71	};
 72
 73	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
 74	if (r)
 75		return r;
 76
 77	if (chip->new_phy_layout) {
 78		/* antenna selection? */
 79		r = zd_iowrite16_locked(chip, 0xe5, ZD_CR9);
 80		if (r)
 81			return r;
 82	}
 83
 84	return zd_iowrite16_locked(chip, 0x04, ZD_CR203);
 85}
 86
 87static int zd1211_al7230b_init_hw(struct zd_rf *rf)
 88{
 89	int r;
 90	struct zd_chip *chip = zd_rf_to_chip(rf);
 91
 92	/* All of these writes are identical to AL2230 unless otherwise
 93	 * specified */
 94	static const struct zd_ioreq16 ioreqs_1[] = {
 95		/* This one is 7230-specific, and happens before the rest */
 96		{ ZD_CR240,  0x57 },
 97		{ },
 98
 99		{ ZD_CR15,   0x20 }, { ZD_CR23,   0x40 }, { ZD_CR24,  0x20 },
100		{ ZD_CR26,   0x11 }, { ZD_CR28,   0x3e }, { ZD_CR29,  0x00 },
101		{ ZD_CR44,   0x33 },
102		/* This value is different for 7230 (was: 0x2a) */
103		{ ZD_CR106,  0x22 },
104		{ ZD_CR107,  0x1a }, { ZD_CR109,  0x09 }, { ZD_CR110,  0x27 },
105		{ ZD_CR111,  0x2b }, { ZD_CR112,  0x2b }, { ZD_CR119,  0x0a },
106		/* This happened further down in AL2230,
107		 * and the value changed (was: 0xe0) */
108		{ ZD_CR122,  0xfc },
109		{ ZD_CR10,   0x89 },
110		/* for newest (3rd cut) AL2300 */
111		{ ZD_CR17,   0x28 },
112		{ ZD_CR26,   0x93 }, { ZD_CR34,   0x30 },
113		/* for newest (3rd cut) AL2300 */
114		{ ZD_CR35,   0x3e },
115		{ ZD_CR41,   0x24 }, { ZD_CR44,   0x32 },
116		/* for newest (3rd cut) AL2300 */
117		{ ZD_CR46,   0x96 },
118		{ ZD_CR47,   0x1e }, { ZD_CR79,   0x58 }, { ZD_CR80,  0x30 },
119		{ ZD_CR81,   0x30 }, { ZD_CR87,   0x0a }, { ZD_CR89,  0x04 },
120		{ ZD_CR92,   0x0a }, { ZD_CR99,   0x28 },
121		/* This value is different for 7230 (was: 0x00) */
122		{ ZD_CR100,  0x02 },
123		{ ZD_CR101,  0x13 }, { ZD_CR102,  0x27 },
124		/* This value is different for 7230 (was: 0x24) */
125		{ ZD_CR106,  0x22 },
126		/* This value is different for 7230 (was: 0x2a) */
127		{ ZD_CR107,  0x3f },
128		{ ZD_CR109,  0x09 },
129		/* This value is different for 7230 (was: 0x13) */
130		{ ZD_CR110,  0x1f },
131		{ ZD_CR111,  0x1f }, { ZD_CR112,  0x1f }, { ZD_CR113, 0x27 },
132		{ ZD_CR114,  0x27 },
133		/* for newest (3rd cut) AL2300 */
134		{ ZD_CR115,  0x24 },
135		/* This value is different for 7230 (was: 0x24) */
136		{ ZD_CR116,  0x3f },
137		/* This value is different for 7230 (was: 0xf4) */
138		{ ZD_CR117,  0xfa },
139		{ ZD_CR118,  0xfc }, { ZD_CR119,  0x10 }, { ZD_CR120, 0x4f },
140		{ ZD_CR121,  0x77 }, { ZD_CR137,  0x88 },
141		/* This one is 7230-specific */
142		{ ZD_CR138,  0xa8 },
143		/* This value is different for 7230 (was: 0xff) */
144		{ ZD_CR252,  0x34 },
145		/* This value is different for 7230 (was: 0xff) */
146		{ ZD_CR253,  0x34 },
147
148		/* PLL_OFF */
149		{ ZD_CR251, 0x2f },
150	};
151
152	static const struct zd_ioreq16 ioreqs_2[] = {
153		{ ZD_CR251, 0x3f }, /* PLL_ON */
154		{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
155		{ ZD_CR38,  0x38 }, { ZD_CR136, 0xdf },
156	};
157
158	r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
159	if (r)
160		return r;
161
162	r = zd_rfwritev_cr_locked(chip, chan_rv[0], ARRAY_SIZE(chan_rv[0]));
163	if (r)
164		return r;
165
166	r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
167	if (r)
168		return r;
169
170	r = zd_rfwritev_cr_locked(chip, rv_init1, ARRAY_SIZE(rv_init1));
171	if (r)
172		return r;
173
174	r = zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2));
175	if (r)
176		return r;
177
178	r = zd_rfwritev_cr_locked(chip, rv_init2, ARRAY_SIZE(rv_init2));
179	if (r)
180		return r;
181
182	r = zd_iowrite16_locked(chip, 0x06, ZD_CR203);
183	if (r)
184		return r;
185	r = zd_iowrite16_locked(chip, 0x80, ZD_CR240);
186	if (r)
187		return r;
188
189	return 0;
190}
191
192static int zd1211b_al7230b_init_hw(struct zd_rf *rf)
193{
194	int r;
195	struct zd_chip *chip = zd_rf_to_chip(rf);
196
197	static const struct zd_ioreq16 ioreqs_1[] = {
198		{ ZD_CR240, 0x57 }, { ZD_CR9,   0x9 },
199		{ },
200		{ ZD_CR10,  0x8b }, { ZD_CR15,  0x20 },
201		{ ZD_CR17,  0x2B }, /* for newest (3rd cut) AL2230 */
202		{ ZD_CR20,  0x10 }, /* 4N25->Stone Request */
203		{ ZD_CR23,  0x40 }, { ZD_CR24,  0x20 }, { ZD_CR26,  0x93 },
204		{ ZD_CR28,  0x3e }, { ZD_CR29,  0x00 },
205		{ ZD_CR33,  0x28 }, /* 5613 */
206		{ ZD_CR34,  0x30 },
207		{ ZD_CR35,  0x3e }, /* for newest (3rd cut) AL2230 */
208		{ ZD_CR41,  0x24 }, { ZD_CR44,  0x32 },
209		{ ZD_CR46,  0x99 }, /* for newest (3rd cut) AL2230 */
210		{ ZD_CR47,  0x1e },
211
212		/* ZD1215 5610 */
213		{ ZD_CR48,  0x00 }, { ZD_CR49,  0x00 }, { ZD_CR51,  0x01 },
214		{ ZD_CR52,  0x80 }, { ZD_CR53,  0x7e }, { ZD_CR65,  0x00 },
215		{ ZD_CR66,  0x00 }, { ZD_CR67,  0x00 }, { ZD_CR68,  0x00 },
216		{ ZD_CR69,  0x28 },
217
218		{ ZD_CR79,  0x58 }, { ZD_CR80,  0x30 }, { ZD_CR81,  0x30 },
219		{ ZD_CR87,  0x0A }, { ZD_CR89,  0x04 },
220		{ ZD_CR90,  0x58 }, /* 5112 */
221		{ ZD_CR91,  0x00 }, /* 5613 */
222		{ ZD_CR92,  0x0a },
223		{ ZD_CR98,  0x8d }, /* 4804, for 1212 new algorithm */
224		{ ZD_CR99,  0x00 }, { ZD_CR100, 0x02 }, { ZD_CR101, 0x13 },
225		{ ZD_CR102, 0x27 },
226		{ ZD_CR106, 0x20 }, /* change to 0x24 for AL7230B */
227		{ ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */
228		{ ZD_CR112, 0x1f },
229	};
230
231	static const struct zd_ioreq16 ioreqs_new_phy[] = {
232		{ ZD_CR107, 0x28 },
233		{ ZD_CR110, 0x1f }, /* 5127, 0x13->0x1f */
234		{ ZD_CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */
235		{ ZD_CR116, 0x2a }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x12 },
236		{ ZD_CR121, 0x6c }, /* 5613 */
237	};
238
239	static const struct zd_ioreq16 ioreqs_old_phy[] = {
240		{ ZD_CR107, 0x24 },
241		{ ZD_CR110, 0x13 }, /* 5127, 0x13->0x1f */
242		{ ZD_CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */
243		{ ZD_CR116, 0x24 }, { ZD_CR118, 0xfc }, { ZD_CR119, 0x11 },
244		{ ZD_CR121, 0x6a }, /* 5613 */
245	};
246
247	static const struct zd_ioreq16 ioreqs_2[] = {
248		{ ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x24 },
249		{ ZD_CR117, 0xfa }, { ZD_CR120, 0x4f },
250		{ ZD_CR122, 0xfc }, /* E0->FCh at 4901 */
251		{ ZD_CR123, 0x57 }, /* 5613 */
252		{ ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */
253		{ ZD_CR126, 0x6c }, /* 5613 */
254		{ ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */
255		{ ZD_CR130, 0x10 },
256		{ ZD_CR131, 0x00 }, /* 5112 */
257		{ ZD_CR137, 0x50 }, /* 5613 */
258		{ ZD_CR138, 0xa8 }, /* 5112 */
259		{ ZD_CR144, 0xac }, /* 5613 */
260		{ ZD_CR148, 0x40 }, /* 5112 */
261		{ ZD_CR149, 0x40 }, /* 4O07, 50->40 */
262		{ ZD_CR150, 0x1a }, /* 5112, 0C->1A */
263		{ ZD_CR252, 0x34 }, { ZD_CR253, 0x34 },
264		{ ZD_CR251, 0x2f }, /* PLL_OFF */
265	};
266
267	static const struct zd_ioreq16 ioreqs_3[] = {
268		{ ZD_CR251, 0x7f }, /* PLL_ON */
269		{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
270		{ ZD_CR38,  0x38 }, { ZD_CR136, 0xdf },
271	};
272
273	r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
274	if (r)
275		return r;
276
277	if (chip->new_phy_layout)
278		r = zd_iowrite16a_locked(chip, ioreqs_new_phy,
279			ARRAY_SIZE(ioreqs_new_phy));
280	else
281		r = zd_iowrite16a_locked(chip, ioreqs_old_phy,
282			ARRAY_SIZE(ioreqs_old_phy));
283	if (r)
284		return r;
285
286	r = zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2));
287	if (r)
288		return r;
289
290	r = zd_rfwritev_cr_locked(chip, chan_rv[0], ARRAY_SIZE(chan_rv[0]));
291	if (r)
292		return r;
293
294	r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
295	if (r)
296		return r;
297
298	r = zd_rfwritev_cr_locked(chip, rv_init1, ARRAY_SIZE(rv_init1));
299	if (r)
300		return r;
301
302	r = zd_iowrite16a_locked(chip, ioreqs_3, ARRAY_SIZE(ioreqs_3));
303	if (r)
304		return r;
305
306	r = zd_rfwritev_cr_locked(chip, rv_init2, ARRAY_SIZE(rv_init2));
307	if (r)
308		return r;
309
310	return zd1211b_al7230b_finalize(chip);
311}
312
313static int zd1211_al7230b_set_channel(struct zd_rf *rf, u8 channel)
314{
315	int r;
316	const u32 *rv = chan_rv[channel-1];
317	struct zd_chip *chip = zd_rf_to_chip(rf);
318
319	static const struct zd_ioreq16 ioreqs[] = {
320		/* PLL_ON */
321		{ ZD_CR251, 0x3f },
322		{ ZD_CR203, 0x06 }, { ZD_CR240, 0x08 },
323	};
324
325	r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
326	if (r)
327		return r;
328
329	/* PLL_OFF */
330	r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
331	if (r)
332		return r;
333
334	r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
335	if (r)
336		return r;
337
338	r = zd_rfwrite_cr_locked(chip, 0x3c9000);
339	if (r)
340		return r;
341	r = zd_rfwrite_cr_locked(chip, 0xf15d58);
342	if (r)
343		return r;
344
345	r = zd_iowrite16a_locked(chip, ioreqs_sw, ARRAY_SIZE(ioreqs_sw));
346	if (r)
347		return r;
348
349	r = zd_rfwritev_cr_locked(chip, rv, 2);
350	if (r)
351		return r;
352
353	r = zd_rfwrite_cr_locked(chip, 0x3c9000);
354	if (r)
355		return r;
356
357	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
358}
359
360static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel)
361{
362	int r;
363	const u32 *rv = chan_rv[channel-1];
364	struct zd_chip *chip = zd_rf_to_chip(rf);
365
366	r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
367	if (r)
368		return r;
369	r = zd_iowrite16_locked(chip, 0xe4, ZD_CR9);
370	if (r)
371		return r;
372
373	/* PLL_OFF */
374	r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
375	if (r)
376		return r;
377	r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
378	if (r)
379		return r;
380
381	r = zd_rfwrite_cr_locked(chip, 0x3c9000);
382	if (r)
383		return r;
384	r = zd_rfwrite_cr_locked(chip, 0xf15d58);
385	if (r)
386		return r;
387
388	r = zd_iowrite16a_locked(chip, ioreqs_sw, ARRAY_SIZE(ioreqs_sw));
389	if (r)
390		return r;
391
392	r = zd_rfwritev_cr_locked(chip, rv, 2);
393	if (r)
394		return r;
395
396	r = zd_rfwrite_cr_locked(chip, 0x3c9000);
397	if (r)
398		return r;
399
400	r = zd_iowrite16_locked(chip, 0x7f, ZD_CR251);
401	if (r)
402		return r;
403
404	return zd1211b_al7230b_finalize(chip);
405}
406
407static int zd1211_al7230b_switch_radio_on(struct zd_rf *rf)
408{
409	struct zd_chip *chip = zd_rf_to_chip(rf);
410	static const struct zd_ioreq16 ioreqs[] = {
411		{ ZD_CR11,  0x00 },
412		{ ZD_CR251, 0x3f },
413	};
414
415	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
416}
417
418static int zd1211b_al7230b_switch_radio_on(struct zd_rf *rf)
419{
420	struct zd_chip *chip = zd_rf_to_chip(rf);
421	static const struct zd_ioreq16 ioreqs[] = {
422		{ ZD_CR11,  0x00 },
423		{ ZD_CR251, 0x7f },
424	};
425
426	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
427}
428
429static int al7230b_switch_radio_off(struct zd_rf *rf)
430{
431	struct zd_chip *chip = zd_rf_to_chip(rf);
432	static const struct zd_ioreq16 ioreqs[] = {
433		{ ZD_CR11,  0x04 },
434		{ ZD_CR251, 0x2f },
435	};
436
437	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
438}
439
440/* ZD1211B+AL7230B 6m band edge patching differs slightly from other
441 * configurations */
442static int zd1211b_al7230b_patch_6m(struct zd_rf *rf, u8 channel)
443{
444	struct zd_chip *chip = zd_rf_to_chip(rf);
445	struct zd_ioreq16 ioreqs[] = {
446		{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 },
447	};
448
449	/* FIXME: Channel 11 is not the edge for all regulatory domains. */
450	if (channel == 1) {
451		ioreqs[0].value = 0x0e;
452		ioreqs[1].value = 0x10;
453	} else if (channel == 11) {
454		ioreqs[0].value = 0x10;
455		ioreqs[1].value = 0x10;
456	}
457
458	dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel);
459	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
460}
461
462int zd_rf_init_al7230b(struct zd_rf *rf)
463{
464	struct zd_chip *chip = zd_rf_to_chip(rf);
465
466	if (zd_chip_is_zd1211b(chip)) {
467		rf->init_hw = zd1211b_al7230b_init_hw;
468		rf->switch_radio_on = zd1211b_al7230b_switch_radio_on;
469		rf->set_channel = zd1211b_al7230b_set_channel;
470		rf->patch_6m_band_edge = zd1211b_al7230b_patch_6m;
471	} else {
472		rf->init_hw = zd1211_al7230b_init_hw;
473		rf->switch_radio_on = zd1211_al7230b_switch_radio_on;
474		rf->set_channel = zd1211_al7230b_set_channel;
475		rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
476		rf->patch_cck_gain = 1;
477	}
478
479	rf->switch_radio_off = al7230b_switch_radio_off;
480
481	return 0;
482}
~/ Read-only file preview.