xref: /openbmc/linux/drivers/net/wireless/zydas/zd1211rw/zd_rf_rf2959.c (revision 58e16d792a6a8c6b750f637a4649967fcac853dc)
1*1ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
26948300cSKalle Valo /* ZD1211 USB-WLAN driver for Linux
36948300cSKalle Valo  *
46948300cSKalle Valo  * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
56948300cSKalle Valo  * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
66948300cSKalle Valo  */
76948300cSKalle Valo 
86948300cSKalle Valo #include <linux/kernel.h>
96948300cSKalle Valo 
106948300cSKalle Valo #include "zd_rf.h"
116948300cSKalle Valo #include "zd_usb.h"
126948300cSKalle Valo #include "zd_chip.h"
136948300cSKalle Valo 
146948300cSKalle Valo static const u32 rf2959_table[][2] = {
156948300cSKalle Valo 	RF_CHANNEL( 1) = { 0x181979, 0x1e6666 },
166948300cSKalle Valo 	RF_CHANNEL( 2) = { 0x181989, 0x1e6666 },
176948300cSKalle Valo 	RF_CHANNEL( 3) = { 0x181999, 0x1e6666 },
186948300cSKalle Valo 	RF_CHANNEL( 4) = { 0x1819a9, 0x1e6666 },
196948300cSKalle Valo 	RF_CHANNEL( 5) = { 0x1819b9, 0x1e6666 },
206948300cSKalle Valo 	RF_CHANNEL( 6) = { 0x1819c9, 0x1e6666 },
216948300cSKalle Valo 	RF_CHANNEL( 7) = { 0x1819d9, 0x1e6666 },
226948300cSKalle Valo 	RF_CHANNEL( 8) = { 0x1819e9, 0x1e6666 },
236948300cSKalle Valo 	RF_CHANNEL( 9) = { 0x1819f9, 0x1e6666 },
246948300cSKalle Valo 	RF_CHANNEL(10) = { 0x181a09, 0x1e6666 },
256948300cSKalle Valo 	RF_CHANNEL(11) = { 0x181a19, 0x1e6666 },
266948300cSKalle Valo 	RF_CHANNEL(12) = { 0x181a29, 0x1e6666 },
276948300cSKalle Valo 	RF_CHANNEL(13) = { 0x181a39, 0x1e6666 },
286948300cSKalle Valo 	RF_CHANNEL(14) = { 0x181a60, 0x1c0000 },
296948300cSKalle Valo };
306948300cSKalle Valo 
316948300cSKalle Valo #if 0
326948300cSKalle Valo static int bits(u32 rw, int from, int to)
336948300cSKalle Valo {
346948300cSKalle Valo 	rw &= ~(0xffffffffU << (to+1));
356948300cSKalle Valo 	rw >>= from;
366948300cSKalle Valo 	return rw;
376948300cSKalle Valo }
386948300cSKalle Valo 
396948300cSKalle Valo static int bit(u32 rw, int bit)
406948300cSKalle Valo {
416948300cSKalle Valo 	return bits(rw, bit, bit);
426948300cSKalle Valo }
436948300cSKalle Valo 
446948300cSKalle Valo static void dump_regwrite(u32 rw)
456948300cSKalle Valo {
466948300cSKalle Valo 	int reg = bits(rw, 18, 22);
476948300cSKalle Valo 	int rw_flag = bits(rw, 23, 23);
486948300cSKalle Valo 	PDEBUG("rf2959 %#010x reg %d rw %d", rw, reg, rw_flag);
496948300cSKalle Valo 
506948300cSKalle Valo 	switch (reg) {
516948300cSKalle Valo 	case 0:
52af643fe9SColin Ian King 		PDEBUG("reg0 CFG1 ref_sel %d hibernate %d rf_vco_reg_en %d"
536948300cSKalle Valo 		       " if_vco_reg_en %d if_vga_en %d",
546948300cSKalle Valo 		       bits(rw, 14, 15), bit(rw, 3), bit(rw, 2), bit(rw, 1),
556948300cSKalle Valo 		       bit(rw, 0));
566948300cSKalle Valo 		break;
576948300cSKalle Valo 	case 1:
586948300cSKalle Valo 		PDEBUG("reg1 IFPLL1 pll_en1 %d kv_en1 %d vtc_en1 %d lpf1 %d"
596948300cSKalle Valo 		       " cpl1 %d pdp1 %d autocal_en1 %d ld_en1 %d ifloopr %d"
606948300cSKalle Valo 		       " ifloopc %d dac1 %d",
616948300cSKalle Valo 		       bit(rw, 17), bit(rw, 16), bit(rw, 15), bit(rw, 14),
626948300cSKalle Valo 		       bit(rw, 13), bit(rw, 12), bit(rw, 11), bit(rw, 10),
636948300cSKalle Valo 		       bits(rw, 7, 9), bits(rw, 4, 6), bits(rw, 0, 3));
646948300cSKalle Valo 		break;
656948300cSKalle Valo 	case 2:
666948300cSKalle Valo 		PDEBUG("reg2 IFPLL2 n1 %d num1 %d",
676948300cSKalle Valo 		       bits(rw, 6, 17), bits(rw, 0, 5));
686948300cSKalle Valo 		break;
696948300cSKalle Valo 	case 3:
706948300cSKalle Valo 		PDEBUG("reg3 IFPLL3 num %d", bits(rw, 0, 17));
716948300cSKalle Valo 		break;
726948300cSKalle Valo 	case 4:
736948300cSKalle Valo 		PDEBUG("reg4 IFPLL4 dn1 %#04x ct_def1 %d kv_def1 %d",
746948300cSKalle Valo 		       bits(rw, 8, 16), bits(rw, 4, 7), bits(rw, 0, 3));
756948300cSKalle Valo 		break;
766948300cSKalle Valo 	case 5:
776948300cSKalle Valo 		PDEBUG("reg5 RFPLL1 pll_en %d kv_en %d vtc_en %d lpf %d cpl %d"
786948300cSKalle Valo 		       " pdp %d autocal_en %d ld_en %d rfloopr %d rfloopc %d"
796948300cSKalle Valo 		       " dac %d",
806948300cSKalle Valo 		       bit(rw, 17), bit(rw, 16), bit(rw, 15), bit(rw, 14),
816948300cSKalle Valo 		       bit(rw, 13), bit(rw, 12), bit(rw, 11), bit(rw, 10),
826948300cSKalle Valo 		       bits(rw, 7, 9), bits(rw, 4, 6), bits(rw, 0,3));
836948300cSKalle Valo 		break;
846948300cSKalle Valo 	case 6:
856948300cSKalle Valo 		PDEBUG("reg6 RFPLL2 n %d num %d",
866948300cSKalle Valo 		       bits(rw, 6, 17), bits(rw, 0, 5));
876948300cSKalle Valo 		break;
886948300cSKalle Valo 	case 7:
896948300cSKalle Valo 		PDEBUG("reg7 RFPLL3 num2 %d", bits(rw, 0, 17));
906948300cSKalle Valo 		break;
916948300cSKalle Valo 	case 8:
926948300cSKalle Valo 		PDEBUG("reg8 RFPLL4 dn %#06x ct_def %d kv_def %d",
936948300cSKalle Valo 		       bits(rw, 8, 16), bits(rw, 4, 7), bits(rw, 0, 3));
946948300cSKalle Valo 		break;
956948300cSKalle Valo 	case 9:
966948300cSKalle Valo 		PDEBUG("reg9 CAL1 tvco %d tlock %d m_ct_value %d ld_window %d",
976948300cSKalle Valo 		       bits(rw, 13, 17), bits(rw, 8, 12), bits(rw, 3, 7),
986948300cSKalle Valo 		       bits(rw, 0, 2));
996948300cSKalle Valo 		break;
1006948300cSKalle Valo 	case 10:
1016948300cSKalle Valo 		PDEBUG("reg10 TXRX1 rxdcfbbyps %d pcontrol %d txvgc %d"
1026948300cSKalle Valo 		       " rxlpfbw %d txlpfbw %d txdiffmode %d txenmode %d"
1036948300cSKalle Valo 		       " intbiasen %d tybypass %d",
1046948300cSKalle Valo 		       bit(rw, 17), bits(rw, 15, 16), bits(rw, 10, 14),
1056948300cSKalle Valo 		       bits(rw, 7, 9), bits(rw, 4, 6), bit(rw, 3), bit(rw, 2),
1066948300cSKalle Valo 		       bit(rw, 1), bit(rw, 0));
1076948300cSKalle Valo 		break;
1086948300cSKalle Valo 	case 11:
1096948300cSKalle Valo 		PDEBUG("reg11 PCNT1 mid_bias %d p_desired %d pc_offset %d"
1106948300cSKalle Valo 			" tx_delay %d",
1116948300cSKalle Valo 			bits(rw, 15, 17), bits(rw, 9, 14), bits(rw, 3, 8),
1126948300cSKalle Valo 			bits(rw, 0, 2));
1136948300cSKalle Valo 		break;
1146948300cSKalle Valo 	case 12:
1156948300cSKalle Valo 		PDEBUG("reg12 PCNT2 max_power %d mid_power %d min_power %d",
1166948300cSKalle Valo 		       bits(rw, 12, 17), bits(rw, 6, 11), bits(rw, 0, 5));
1176948300cSKalle Valo 		break;
1186948300cSKalle Valo 	case 13:
1196948300cSKalle Valo 		PDEBUG("reg13 VCOT1 rfpll vco comp %d ifpll vco comp %d"
1206948300cSKalle Valo 		       " lobias %d if_biasbuf %d if_biasvco %d rf_biasbuf %d"
1216948300cSKalle Valo 		       " rf_biasvco %d",
1226948300cSKalle Valo 		       bit(rw, 17), bit(rw, 16), bit(rw, 15),
1236948300cSKalle Valo 		       bits(rw, 8, 9), bits(rw, 5, 7), bits(rw, 3, 4),
1246948300cSKalle Valo 		       bits(rw, 0, 2));
1256948300cSKalle Valo 		break;
1266948300cSKalle Valo 	case 14:
1276948300cSKalle Valo 		PDEBUG("reg14 IQCAL rx_acal %d rx_pcal %d"
1286948300cSKalle Valo 		       " tx_acal %d tx_pcal %d",
1296948300cSKalle Valo 		       bits(rw, 13, 17), bits(rw, 9, 12), bits(rw, 4, 8),
1306948300cSKalle Valo 		       bits(rw, 0, 3));
1316948300cSKalle Valo 		break;
1326948300cSKalle Valo 	}
1336948300cSKalle Valo }
1346948300cSKalle Valo #endif /* 0 */
1356948300cSKalle Valo 
rf2959_init_hw(struct zd_rf * rf)1366948300cSKalle Valo static int rf2959_init_hw(struct zd_rf *rf)
1376948300cSKalle Valo {
1386948300cSKalle Valo 	int r;
1396948300cSKalle Valo 	struct zd_chip *chip = zd_rf_to_chip(rf);
1406948300cSKalle Valo 
1416948300cSKalle Valo 	static const struct zd_ioreq16 ioreqs[] = {
1426948300cSKalle Valo 		{ ZD_CR2,   0x1E }, { ZD_CR9,   0x20 }, { ZD_CR10,  0x89 },
1436948300cSKalle Valo 		{ ZD_CR11,  0x00 }, { ZD_CR15,  0xD0 }, { ZD_CR17,  0x68 },
1446948300cSKalle Valo 		{ ZD_CR19,  0x4a }, { ZD_CR20,  0x0c }, { ZD_CR21,  0x0E },
1456948300cSKalle Valo 		{ ZD_CR23,  0x48 },
1466948300cSKalle Valo 		/* normal size for cca threshold */
1476948300cSKalle Valo 		{ ZD_CR24,  0x14 },
1486948300cSKalle Valo 		/* { ZD_CR24,  0x20 }, */
1496948300cSKalle Valo 		{ ZD_CR26,  0x90 }, { ZD_CR27,  0x30 }, { ZD_CR29,  0x20 },
1506948300cSKalle Valo 		{ ZD_CR31,  0xb2 }, { ZD_CR32,  0x43 }, { ZD_CR33,  0x28 },
1516948300cSKalle Valo 		{ ZD_CR38,  0x30 }, { ZD_CR34,  0x0f }, { ZD_CR35,  0xF0 },
1526948300cSKalle Valo 		{ ZD_CR41,  0x2a }, { ZD_CR46,  0x7F }, { ZD_CR47,  0x1E },
1536948300cSKalle Valo 		{ ZD_CR51,  0xc5 }, { ZD_CR52,  0xc5 }, { ZD_CR53,  0xc5 },
1546948300cSKalle Valo 		{ ZD_CR79,  0x58 }, { ZD_CR80,  0x30 }, { ZD_CR81,  0x30 },
1556948300cSKalle Valo 		{ ZD_CR82,  0x00 }, { ZD_CR83,  0x24 }, { ZD_CR84,  0x04 },
1566948300cSKalle Valo 		{ ZD_CR85,  0x00 }, { ZD_CR86,  0x10 }, { ZD_CR87,  0x2A },
1576948300cSKalle Valo 		{ ZD_CR88,  0x10 }, { ZD_CR89,  0x24 }, { ZD_CR90,  0x18 },
1586948300cSKalle Valo 		/* { ZD_CR91,  0x18 }, */
1596948300cSKalle Valo 		/* should solve continuous CTS frame problems */
1606948300cSKalle Valo 		{ ZD_CR91,  0x00 },
1616948300cSKalle Valo 		{ ZD_CR92,  0x0a }, { ZD_CR93,  0x00 }, { ZD_CR94,  0x01 },
1626948300cSKalle Valo 		{ ZD_CR95,  0x00 }, { ZD_CR96,  0x40 }, { ZD_CR97,  0x37 },
1636948300cSKalle Valo 		{ ZD_CR98,  0x05 }, { ZD_CR99,  0x28 }, { ZD_CR100, 0x00 },
1646948300cSKalle Valo 		{ ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 },
1656948300cSKalle Valo 		{ ZD_CR104, 0x18 }, { ZD_CR105, 0x12 },
1666948300cSKalle Valo 		/* normal size */
1676948300cSKalle Valo 		{ ZD_CR106, 0x1a },
1686948300cSKalle Valo 		/* { ZD_CR106, 0x22 }, */
1696948300cSKalle Valo 		{ ZD_CR107, 0x24 }, { ZD_CR108, 0x0a }, { ZD_CR109, 0x13 },
1706948300cSKalle Valo 		{ ZD_CR110, 0x2F }, { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 },
1716948300cSKalle Valo 		{ ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x40 },
1726948300cSKalle Valo 		{ ZD_CR116, 0x40 }, { ZD_CR117, 0xF0 }, { ZD_CR118, 0xF0 },
1736948300cSKalle Valo 		{ ZD_CR119, 0x16 },
1746948300cSKalle Valo 		/* no TX continuation */
1756948300cSKalle Valo 		{ ZD_CR122, 0x00 },
1766948300cSKalle Valo 		/* { ZD_CR122, 0xff }, */
1776948300cSKalle Valo 		{ ZD_CR127, 0x03 }, { ZD_CR131, 0x08 }, { ZD_CR138, 0x28 },
1786948300cSKalle Valo 		{ ZD_CR148, 0x44 }, { ZD_CR150, 0x10 }, { ZD_CR169, 0xBB },
1796948300cSKalle Valo 		{ ZD_CR170, 0xBB },
1806948300cSKalle Valo 	};
1816948300cSKalle Valo 
1826948300cSKalle Valo 	static const u32 rv[] = {
1836948300cSKalle Valo 		0x000007,  /* REG0(CFG1) */
1846948300cSKalle Valo 		0x07dd43,  /* REG1(IFPLL1) */
1856948300cSKalle Valo 		0x080959,  /* REG2(IFPLL2) */
1866948300cSKalle Valo 		0x0e6666,
1876948300cSKalle Valo 		0x116a57,  /* REG4 */
1886948300cSKalle Valo 		0x17dd43,  /* REG5 */
1896948300cSKalle Valo 		0x1819f9,  /* REG6 */
1906948300cSKalle Valo 		0x1e6666,
1916948300cSKalle Valo 		0x214554,
1926948300cSKalle Valo 		0x25e7fa,
1936948300cSKalle Valo 		0x27fffa,
1946948300cSKalle Valo 		/* The Zydas driver somehow forgets to set this value. It's
1956948300cSKalle Valo 		 * only set for Japan. We are using internal power control
1966948300cSKalle Valo 		 * for now.
1976948300cSKalle Valo 		 */
1986948300cSKalle Valo 		0x294128, /* internal power */
1996948300cSKalle Valo 		/* 0x28252c, */ /* External control TX power */
2006948300cSKalle Valo 		/* ZD_CR31_CCK, ZD_CR51_6-36M, ZD_CR52_48M, ZD_CR53_54M */
2016948300cSKalle Valo 		0x2c0000,
2026948300cSKalle Valo 		0x300000,
2036948300cSKalle Valo 		0x340000,  /* REG13(0xD) */
2046948300cSKalle Valo 		0x381e0f,  /* REG14(0xE) */
2056948300cSKalle Valo 		/* Bogus, RF2959's data sheet doesn't know register 27, which is
2066948300cSKalle Valo 		 * actually referenced here. The commented 0x11 is 17.
2076948300cSKalle Valo 		 */
2086948300cSKalle Valo 		0x6c180f,  /* REG27(0x11) */
2096948300cSKalle Valo 	};
2106948300cSKalle Valo 
2116948300cSKalle Valo 	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
2126948300cSKalle Valo 	if (r)
2136948300cSKalle Valo 		return r;
2146948300cSKalle Valo 
2156948300cSKalle Valo 	return zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
2166948300cSKalle Valo }
2176948300cSKalle Valo 
rf2959_set_channel(struct zd_rf * rf,u8 channel)2186948300cSKalle Valo static int rf2959_set_channel(struct zd_rf *rf, u8 channel)
2196948300cSKalle Valo {
2206948300cSKalle Valo 	int i, r;
2216948300cSKalle Valo 	const u32 *rv = rf2959_table[channel-1];
2226948300cSKalle Valo 	struct zd_chip *chip = zd_rf_to_chip(rf);
2236948300cSKalle Valo 
2246948300cSKalle Valo 	for (i = 0; i < 2; i++) {
2256948300cSKalle Valo 		r = zd_rfwrite_locked(chip, rv[i], RF_RV_BITS);
2266948300cSKalle Valo 		if (r)
2276948300cSKalle Valo 			return r;
2286948300cSKalle Valo 	}
2296948300cSKalle Valo 	return 0;
2306948300cSKalle Valo }
2316948300cSKalle Valo 
rf2959_switch_radio_on(struct zd_rf * rf)2326948300cSKalle Valo static int rf2959_switch_radio_on(struct zd_rf *rf)
2336948300cSKalle Valo {
2346948300cSKalle Valo 	static const struct zd_ioreq16 ioreqs[] = {
2356948300cSKalle Valo 		{ ZD_CR10, 0x89 },
2366948300cSKalle Valo 		{ ZD_CR11, 0x00 },
2376948300cSKalle Valo 	};
2386948300cSKalle Valo 	struct zd_chip *chip = zd_rf_to_chip(rf);
2396948300cSKalle Valo 
2406948300cSKalle Valo 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
2416948300cSKalle Valo }
2426948300cSKalle Valo 
rf2959_switch_radio_off(struct zd_rf * rf)2436948300cSKalle Valo static int rf2959_switch_radio_off(struct zd_rf *rf)
2446948300cSKalle Valo {
2456948300cSKalle Valo 	static const struct zd_ioreq16 ioreqs[] = {
2466948300cSKalle Valo 		{ ZD_CR10, 0x15 },
2476948300cSKalle Valo 		{ ZD_CR11, 0x81 },
2486948300cSKalle Valo 	};
2496948300cSKalle Valo 	struct zd_chip *chip = zd_rf_to_chip(rf);
2506948300cSKalle Valo 
2516948300cSKalle Valo 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
2526948300cSKalle Valo }
2536948300cSKalle Valo 
zd_rf_init_rf2959(struct zd_rf * rf)2546948300cSKalle Valo int zd_rf_init_rf2959(struct zd_rf *rf)
2556948300cSKalle Valo {
2566948300cSKalle Valo 	struct zd_chip *chip = zd_rf_to_chip(rf);
2576948300cSKalle Valo 
2586948300cSKalle Valo 	if (zd_chip_is_zd1211b(chip)) {
2596948300cSKalle Valo 		dev_err(zd_chip_dev(chip),
2606948300cSKalle Valo 		       "RF2959 is currently not supported for ZD1211B"
2616948300cSKalle Valo 		       " devices\n");
2626948300cSKalle Valo 		return -ENODEV;
2636948300cSKalle Valo 	}
2646948300cSKalle Valo 	rf->init_hw = rf2959_init_hw;
2656948300cSKalle Valo 	rf->set_channel = rf2959_set_channel;
2666948300cSKalle Valo 	rf->switch_radio_on = rf2959_switch_radio_on;
2676948300cSKalle Valo 	rf->switch_radio_off = rf2959_switch_radio_off;
2686948300cSKalle Valo 	return 0;
2696948300cSKalle Valo }
270