⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adm8211.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_WRITE_SYNDATA_0);     \		ADM8211_CSR_READ(SYNRF);				     \	}								     \									     \	for (i = 0; i <= bits; i++) {					     \		if (bitbuf & (1 << (bits - i)))				     \			reg = ADM8211_SYNRF_WRITE_SYNDATA_1;		     \		else							     \			reg = ADM8211_SYNRF_WRITE_SYNDATA_0;		     \									     \		ADM8211_CSR_WRITE(SYNRF, reg);				     \		ADM8211_CSR_READ(SYNRF);				     \									     \		ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_WRITE_CLOCK_1); \		ADM8211_CSR_READ(SYNRF);				     \		ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_WRITE_CLOCK_0); \		ADM8211_CSR_READ(SYNRF);				     \	}								     \									     \	if (postwrite == 1) {						     \		ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_IF_SELECT_0);   \		ADM8211_CSR_READ(SYNRF);				     \	}								     \	if (postwrite == 2) {						     \		ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_IF_SELECT_1);   \		ADM8211_CSR_READ(SYNRF);				     \	}								     \									     \	ADM8211_CSR_WRITE(SYNRF, 0);					     \	ADM8211_CSR_READ(SYNRF);					     \}WRITE_SYN(max2820,  0x00FFF, 0, 0x0F, 12, 15, 1, 1)WRITE_SYN(al2210l,  0xFFFFF, 4, 0x0F,  0, 23, 1, 1)WRITE_SYN(rfmd2958, 0x3FFFF, 0, 0x1F, 18, 23, 0, 1)WRITE_SYN(rfmd2948, 0x0FFFF, 4, 0x0F,  0, 21, 0, 2)#undef WRITE_SYNstatic int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data){	struct adm8211_priv *priv = dev->priv;	unsigned int timeout;	u32 reg;	timeout = 10;	while (timeout > 0) {		reg = ADM8211_CSR_READ(BBPCTL);		if (!(reg & (ADM8211_BBPCTL_WR | ADM8211_BBPCTL_RD)))			break;		timeout--;		msleep(2);	}	if (timeout == 0) {		printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed"		       " prewrite (reg=0x%08x)\n",		       wiphy_name(dev->wiphy), addr, data, reg);		return -ETIMEDOUT;	}	switch (priv->bbp_type) {	case ADM8211_TYPE_INTERSIL:		reg = ADM8211_BBPCTL_MMISEL;	/* three wire interface */		break;	case ADM8211_TYPE_RFMD:		reg = (0x20 << 24) | ADM8211_BBPCTL_TXCE | ADM8211_BBPCTL_CCAP |		      (0x01 << 18);		break;	case ADM8211_TYPE_ADMTEK:		reg = (0x20 << 24) | ADM8211_BBPCTL_TXCE | ADM8211_BBPCTL_CCAP |		      (0x05 << 18);		break;	}	reg |= ADM8211_BBPCTL_WR | (addr << 8) | data;	ADM8211_CSR_WRITE(BBPCTL, reg);	timeout = 10;	while (timeout > 0) {		reg = ADM8211_CSR_READ(BBPCTL);		if (!(reg & ADM8211_BBPCTL_WR))			break;		timeout--;		msleep(2);	}	if (timeout == 0) {		ADM8211_CSR_WRITE(BBPCTL, ADM8211_CSR_READ(BBPCTL) &				  ~ADM8211_BBPCTL_WR);		printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed"		       " postwrite (reg=0x%08x)\n",		       wiphy_name(dev->wiphy), addr, data, reg);		return -ETIMEDOUT;	}	return 0;}static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan){	static const u32 adm8211_rfmd2958_reg5[] =		{0x22BD, 0x22D2, 0x22E8, 0x22FE, 0x2314, 0x232A, 0x2340,		 0x2355, 0x236B, 0x2381, 0x2397, 0x23AD, 0x23C2, 0x23F7};	static const u32 adm8211_rfmd2958_reg6[] =		{0x05D17, 0x3A2E8, 0x2E8BA, 0x22E8B, 0x1745D, 0x0BA2E, 0x00000,		 0x345D1, 0x28BA2, 0x1D174, 0x11745, 0x05D17, 0x3A2E8, 0x11745};	struct adm8211_priv *priv = dev->priv;	u8 ant_power = priv->ant_power > 0x3F ?		priv->eeprom->antenna_power[chan - 1] : priv->ant_power;	u8 tx_power = priv->tx_power > 0x3F ?		priv->eeprom->tx_power[chan - 1] : priv->tx_power;	u8 lpf_cutoff = priv->lpf_cutoff == 0xFF ?		priv->eeprom->lpf_cutoff[chan - 1] : priv->lpf_cutoff;	u8 lnags_thresh = priv->lnags_threshold == 0xFF ?		priv->eeprom->lnags_threshold[chan - 1] : priv->lnags_threshold;	u32 reg;	ADM8211_IDLE();	/* Program synthesizer to new channel */	switch (priv->transceiver_type) {	case ADM8211_RFMD2958:	case ADM8211_RFMD2958_RF3000_CONTROL_POWER:		adm8211_rf_write_syn_rfmd2958(dev, 0x00, 0x04007);		adm8211_rf_write_syn_rfmd2958(dev, 0x02, 0x00033);		adm8211_rf_write_syn_rfmd2958(dev, 0x05,			adm8211_rfmd2958_reg5[chan - 1]);		adm8211_rf_write_syn_rfmd2958(dev, 0x06,			adm8211_rfmd2958_reg6[chan - 1]);		break;	case ADM8211_RFMD2948:		adm8211_rf_write_syn_rfmd2948(dev, SI4126_MAIN_CONF,					      SI4126_MAIN_XINDIV2);		adm8211_rf_write_syn_rfmd2948(dev, SI4126_POWERDOWN,					      SI4126_POWERDOWN_PDIB |					      SI4126_POWERDOWN_PDRB);		adm8211_rf_write_syn_rfmd2948(dev, SI4126_PHASE_DET_GAIN, 0);		adm8211_rf_write_syn_rfmd2948(dev, SI4126_RF2_N_DIV,					      (chan == 14 ?					       2110 : (2033 + (chan * 5))));		adm8211_rf_write_syn_rfmd2948(dev, SI4126_IF_N_DIV, 1496);		adm8211_rf_write_syn_rfmd2948(dev, SI4126_RF2_R_DIV, 44);		adm8211_rf_write_syn_rfmd2948(dev, SI4126_IF_R_DIV, 44);		break;	case ADM8211_MAX2820:		adm8211_rf_write_syn_max2820(dev, 0x3,			(chan == 14 ? 0x054 : (0x7 + (chan * 5))));		break;	case ADM8211_AL2210L:		adm8211_rf_write_syn_al2210l(dev, 0x0,			(chan == 14 ? 0x229B4 : (0x22967 + (chan * 5))));		break;	default:		printk(KERN_DEBUG "%s: unsupported transceiver type %d\n",		       wiphy_name(dev->wiphy), priv->transceiver_type);		break;	}	/* write BBP regs */	if (priv->bbp_type == ADM8211_TYPE_RFMD) {	/* SMC 2635W specific? adm8211b doesn't use the 2948 though.. */	/* TODO: remove if SMC 2635W doesn't need this */	if (priv->transceiver_type == ADM8211_RFMD2948) {		reg = ADM8211_CSR_READ(GPIO);		reg &= 0xfffc0000;		reg |= ADM8211_CSR_GPIO_EN0;		if (chan != 14)			reg |= ADM8211_CSR_GPIO_O0;		ADM8211_CSR_WRITE(GPIO, reg);	}	if (priv->transceiver_type == ADM8211_RFMD2958) {		/* set PCNT2 */		adm8211_rf_write_syn_rfmd2958(dev, 0x0B, 0x07100);		/* set PCNT1 P_DESIRED/MID_BIAS */		reg = le16_to_cpu(priv->eeprom->cr49);		reg >>= 13;		reg <<= 15;		reg |= ant_power << 9;		adm8211_rf_write_syn_rfmd2958(dev, 0x0A, reg);		/* set TXRX TX_GAIN */		adm8211_rf_write_syn_rfmd2958(dev, 0x09, 0x00050 |			(priv->pdev->revision < ADM8211_REV_CA ? tx_power : 0));	} else {		reg = ADM8211_CSR_READ(PLCPHD);		reg &= 0xff00ffff;		reg |= tx_power << 18;		ADM8211_CSR_WRITE(PLCPHD, reg);	}	ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_SELRF |			  ADM8211_SYNRF_PE1 | ADM8211_SYNRF_PHYRST);	ADM8211_CSR_READ(SYNRF);	msleep(30);	/* RF3000 BBP */	if (priv->transceiver_type != ADM8211_RFMD2958)		adm8211_write_bbp(dev, RF3000_TX_VAR_GAIN__TX_LEN_EXT,				  tx_power<<2);	adm8211_write_bbp(dev, RF3000_LOW_GAIN_CALIB, lpf_cutoff);	adm8211_write_bbp(dev, RF3000_HIGH_GAIN_CALIB, lnags_thresh);	adm8211_write_bbp(dev, 0x1c, priv->pdev->revision == ADM8211_REV_BA ?				     priv->eeprom->cr28 : 0);	adm8211_write_bbp(dev, 0x1d, priv->eeprom->cr29);	ADM8211_CSR_WRITE(SYNRF, 0);	/* Nothing to do for ADMtek BBP */	} else if (priv->bbp_type != ADM8211_TYPE_ADMTEK)		printk(KERN_DEBUG "%s: unsupported BBP type %d\n",		       wiphy_name(dev->wiphy), priv->bbp_type);	ADM8211_RESTORE();	/* update current channel for adhoc (and maybe AP mode) */	reg = ADM8211_CSR_READ(CAP0);	reg &= ~0xF;	reg |= chan;	ADM8211_CSR_WRITE(CAP0, reg);	return 0;}static void adm8211_update_mode(struct ieee80211_hw *dev){	struct adm8211_priv *priv = dev->priv;	ADM8211_IDLE();	priv->soft_rx_crc = 0;	switch (priv->mode) {	case IEEE80211_IF_TYPE_STA:		priv->nar &= ~(ADM8211_NAR_PR | ADM8211_NAR_EA);		priv->nar |= ADM8211_NAR_ST | ADM8211_NAR_SR;		break;	case IEEE80211_IF_TYPE_IBSS:		priv->nar &= ~ADM8211_NAR_PR;		priv->nar |= ADM8211_NAR_EA | ADM8211_NAR_ST | ADM8211_NAR_SR;		/* don't trust the error bits on rev 0x20 and up in adhoc */		if (priv->pdev->revision >= ADM8211_REV_BA)			priv->soft_rx_crc = 1;		break;	case IEEE80211_IF_TYPE_MNTR:		priv->nar &= ~(ADM8211_NAR_EA | ADM8211_NAR_ST);		priv->nar |= ADM8211_NAR_PR | ADM8211_NAR_SR;		break;	}	ADM8211_RESTORE();}static void adm8211_hw_init_syn(struct ieee80211_hw *dev){	struct adm8211_priv *priv = dev->priv;	switch (priv->transceiver_type) {	case ADM8211_RFMD2958:	case ADM8211_RFMD2958_RF3000_CONTROL_POWER:		/* comments taken from ADMtek vendor driver */		/* Reset RF2958 after power on */		adm8211_rf_write_syn_rfmd2958(dev, 0x1F, 0x00000);		/* Initialize RF VCO Core Bias to maximum */		adm8211_rf_write_syn_rfmd2958(dev, 0x0C, 0x3001F);		/* Initialize IF PLL */		adm8211_rf_write_syn_rfmd2958(dev, 0x01, 0x29C03);		/* Initialize IF PLL Coarse Tuning */		adm8211_rf_write_syn_rfmd2958(dev, 0x03, 0x1FF6F);		/* Initialize RF PLL */		adm8211_rf_write_syn_rfmd2958(dev, 0x04, 0x29403);		/* Initialize RF PLL Coarse Tuning */		adm8211_rf_write_syn_rfmd2958(dev, 0x07, 0x1456F);		/* Initialize TX gain and filter BW (R9) */		adm8211_rf_write_syn_rfmd2958(dev, 0x09,			(priv->transceiver_type == ADM8211_RFMD2958 ?			 0x10050 : 0x00050));		/* Initialize CAL register */		adm8211_rf_write_syn_rfmd2958(dev, 0x08, 0x3FFF8);		break;	case ADM8211_MAX2820:		adm8211_rf_write_syn_max2820(dev, 0x1, 0x01E);		adm8211_rf_write_syn_max2820(dev, 0x2, 0x001);		adm8211_rf_write_syn_max2820(dev, 0x3, 0x054);		adm8211_rf_write_syn_max2820(dev, 0x4, 0x310);		adm8211_rf_write_syn_max2820(dev, 0x5, 0x000);		break;	case ADM8211_AL2210L:		adm8211_rf_write_syn_al2210l(dev, 0x0, 0x0196C);		adm8211_rf_write_syn_al2210l(dev, 0x1, 0x007CB);		adm8211_rf_write_syn_al2210l(dev, 0x2, 0x3582F);		adm8211_rf_write_syn_al2210l(dev, 0x3, 0x010A9);		adm8211_rf_write_syn_al2210l(dev, 0x4, 0x77280);		adm8211_rf_write_syn_al2210l(dev, 0x5, 0x45641);		adm8211_rf_write_syn_al2210l(dev, 0x6, 0xEA130);		adm8211_rf_write_syn_al2210l(dev, 0x7, 0x80000);		adm8211_rf_write_syn_al2210l(dev, 0x8, 0x7850F);		adm8211_rf_write_syn_al2210l(dev, 0x9, 0xF900C);		adm8211_rf_write_syn_al2210l(dev, 0xA, 0x00000);		adm8211_rf_write_syn_al2210l(dev, 0xB, 0x00000);		break;	case ADM8211_RFMD2948:	default:		break;	}}static int adm8211_hw_init_bbp(struct ieee80211_hw *dev){	struct adm8211_priv *priv = dev->priv;	u32 reg;	/* write addresses */	if (priv->bbp_type == ADM8211_TYPE_INTERSIL) {		ADM8211_CSR_WRITE(MMIWA,  0x100E0C0A);		ADM8211_CSR_WRITE(MMIRD0, 0x00007C7E);		ADM8211_CSR_WRITE(MMIRD1, 0x00100000);	} else if (priv->bbp_type == ADM8211_TYPE_RFMD ||		   priv->bbp_type == ADM8211_TYPE_ADMTEK) {		/* check specific BBP type */		switch (priv->specific_bbptype) {		case ADM8211_BBP_RFMD3000:		case ADM8211_BBP_RFMD3002:			ADM8211_CSR_WRITE(MMIWA,  0x00009101);			ADM8211_CSR_WRITE(MMIRD0, 0x00000301);			break;		case ADM8211_BBP_ADM8011:			ADM8211_CSR_WRITE(MMIWA,  0x00008903);			ADM8211_CSR_WRITE(MMIRD0, 0x00001716);			reg = ADM8211_CSR_READ(BBPCTL);			reg &= ~ADM8211_BBPCTL_TYPE;			reg |= 0x5 << 18;			ADM8211_CSR_WRITE(BBPCTL, reg);			break;		}		switch (priv->pdev->revision) {		case ADM8211_REV_CA:			if (priv->transceiver_type == ADM8211_RFMD2958 ||			    priv->transceiver_type == ADM8211_RFMD2958_RF3000_CONTROL_POWER ||			    priv->transceiver_type == ADM8211_RFMD2948)				ADM8211_CSR_WRITE(SYNCTL, 0x1 << 22);			else if (priv->transceiver_type == ADM8211_MAX2820 ||				 priv->transceiver_type == ADM8211_AL2210L)				ADM8211_CSR_WRITE(SYNCTL, 0x3 << 22);			break;		case ADM8211_REV_BA:			reg  = ADM8211_CSR_READ(MMIRD1);			reg &= 0x0000FFFF;			reg |= 0x7e100000;			ADM8211_CSR_WRITE(MMIRD1, reg);			break;		case ADM8211_REV_AB:		case ADM8211_REV_AF:		default:			ADM8211_CSR_WRITE(MMIRD1, 0x7e100000);			break;		}		/* For RFMD */		ADM8211_CSR_WRITE(MACTEST, 0x800);	}	adm8211_hw_init_syn(dev);	/* Set RF Power control IF pin to PE1+PHYRST# */	ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_SELRF |			  ADM8211_SYNRF_PE1 | ADM8211_SYNRF_PHYRST);	ADM8211_CSR_READ(SYNRF);	msleep(20);	/* write BBP regs */	if (priv->bbp_type == ADM8211_TYPE_RFMD) {		/* RF3000 BBP */		/* another set:		 * 11: c8		 * 14: 14		 * 15: 50 (chan 1..13; chan 14: d0)		 * 1c: 00		 * 1d: 84		 */		adm8211_write_bbp(dev, RF3000_CCA_CTRL, 0x80);		/* antenna selection: diversity */		adm8211_write_bbp(dev, RF3000_DIVERSITY__RSSI, 0x80);		adm8211_write_bbp(dev, RF3000_TX_VAR_GAIN__TX_LEN_EXT, 0x74);		adm8211_write_bbp(dev, RF3000_LOW_GAIN_CALIB, 0x38);		adm8211_write_bbp(dev, RF3000_HIGH_GAIN_CALIB, 0x40);		if (priv->eeprom->major_version < 2) {			adm8211_write_bbp(dev, 0x1c, 0x00);			adm8211_write_bbp(dev, 0x1d, 0x80);		} else {			if (priv->pdev->revision == ADM8211_REV_BA)				adm8211_write_bbp(dev, 0x1c, priv->eeprom->cr28);			else				adm8211_write_bbp(dev, 0x1c, 0x00);			adm8211_write_bbp(dev, 0x1d, priv->eeprom->cr29);		}	} else if (priv->bbp_type == ADM8211_TYPE_ADMTEK) {		/* reset baseband */		adm8211_write_bbp(dev, 0x00, 0xFF);		/* antenna selection: diversity */		adm8211_write_bbp(dev, 0x07, 0x0A);		/* TODO: find documentation for this */		switch (priv->transceiver_type) {		case ADM8211_RFMD2958:		case ADM8211_RFMD2958_RF3000_CONTROL_POWER:			adm8211_write_bbp(dev, 0x00, 0x00);			adm8211_write_bbp(dev, 0x01, 0x00);			adm8211_write_bbp(dev, 0x02, 0x00);			adm8211_write_bbp(dev, 0x03, 0x00);			adm8211_write_bbp(dev, 0x06, 0x0f);			adm8211_write_bbp(dev, 0x09, 0x00);			adm8211_write_bbp(dev, 0x0a, 0x00);			adm8211_write_bbp(dev, 0x0b, 0x00);			adm8211_write_bbp(dev, 0x0c, 0x00);			adm8211_write_bbp(dev, 0x0f, 0xAA);			adm8211_write_bbp(dev, 0x10, 0x8c);			adm8211_write_bbp(dev, 0x11, 0x43);			adm8211_write_bbp(dev, 0x18, 0x40);			adm8211_write_bbp(dev, 0x20, 0x23);			adm8211_write_bbp(dev, 0x21, 0x02);			adm8211_write_bbp(dev, 0x22, 0x28);			adm8211_write_bbp(dev, 0x23, 0x30);			adm8211_write_bbp(dev, 0x24, 0x2d);			adm8211_write_bbp(dev, 0x28, 0x35);			adm8211_write_bbp(dev, 0x2a, 0x8c);			adm8211_write_bbp(dev, 0x2b, 0x81);			adm8211_write_bbp(dev, 0x2c, 0x44);			adm8211_write_bbp(dev, 0x2d, 0x0A);			adm8211_write_bbp(dev, 0x29, 0x40);			adm8211_write_bbp(dev, 0x60, 0x08);			adm8211_write_bbp(dev, 0x64, 0x01);			break;		case ADM8211_MAX2820:			adm8211_write_bbp(dev, 0x00, 0x00);			adm8211_write_bbp(dev, 0x01, 0x00);			adm8211_write_bbp(dev, 0x02, 0x00);			adm8211_write_bbp(dev, 0x03, 0x00);			adm8211_write_bbp(dev, 0x06, 0x0f);			adm8211_write_bbp(dev, 0x09, 0x05);			adm8211_write_bbp(dev, 0x0a, 0x02);			adm8211_write_bbp(dev, 0x0b, 0x00);			adm8211_write_bbp(dev, 0x0c, 0x0f);			adm8211_write_bbp(dev, 0x0f, 0x55);			adm8211_write_bbp(dev, 0x10, 0x8d);			adm8211_write_bbp(dev, 0x11, 0x43);			adm8211_write_bbp(dev, 0x18, 0x4a);			adm8211_write_bbp(dev, 0x20, 0x20);			adm8211_write_bbp(dev, 0x21, 0x02);			adm8211_write_bbp(dev, 0x22, 0x23);			adm8211_write_bbp(dev, 0x23, 0x30);			adm8211_write_bbp(dev, 0x24, 0x2d);			adm8211_write_bbp(dev, 0x2a, 0x8c);			adm8211_write_bbp(dev, 0x2b, 0x81);			adm8211_write_bbp(dev, 0x2c, 0x44);			adm8211_write_bbp(dev, 0x29, 0x4a);			adm8211_write_bbp(dev, 0x60, 0x2b);			adm8211_write_bbp(dev, 0x64, 0x01);			break;		case ADM8211_AL2210L:			adm8211_write_bbp(dev, 0x00, 0x00);			adm8211_write_bbp(dev, 0x01, 0x00);			adm8211_write_bbp(dev, 0x02, 0x00);			adm8211_write_bbp(dev, 0x03, 0x00);			adm8211_write_bbp(dev, 0x06, 0x0f);			adm8211_write_bbp(dev, 0x07, 0x05);			adm8211_write_bbp(dev, 0x08, 0x03);			adm8211_write_bbp(dev, 0x09, 0x00);			adm8211_write_bbp(dev, 0x0a, 0x00);			adm8211_write_bbp(dev, 0x0b, 0x00);			adm8211_write_bbp(dev, 0x0c, 0x10);			adm8211_write_bbp(dev, 0x0f, 0x55);			adm8211_write_bbp(dev, 0x10, 0x8d);			adm8211_write_bbp(dev, 0x11, 0x43);			adm8211_write_bbp(dev, 0x18, 0x4a);			adm8211_write_bbp(dev, 0x20, 0x20);			adm8211_write_bbp(dev, 0x21, 0x02);			adm8211_write_bbp(dev, 0x22, 0x23);			adm8211_write_bbp(dev, 0x23, 0x30);			adm8211_write_bbp(dev, 0x24, 0x2d);			adm8211_write_bbp(dev, 0x2a, 0xaa);			adm8211_write_bbp(dev, 0x2b, 0x81);			adm8211_write_bbp(dev, 0x2c, 0x44);			adm8211_write_bbp(dev, 0x29, 0xfa);			adm8211_write_bbp(dev, 0x60, 0x2d);			adm8211_write_bbp(dev, 0x64, 0x01);			break;		case ADM8211_RFMD2948:			break;		default:			printk(KERN_DEBUG "%s: unsupported transceiver %d\n",			       wiphy_name(dev->wiphy), priv->transceiver_type);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -