241 lines
5.5 KiB
C
241 lines
5.5 KiB
C
/*
|
|
This files contains MAXIM MAX2820 radio frontend programming routines.
|
|
|
|
This is part of rtl8180 OpenSource driver
|
|
Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
|
|
Released under the terms of GPL (General Public Licence)
|
|
|
|
Parts of this driver are based on the GPL part of the
|
|
official realtek driver
|
|
|
|
Parts of this driver are based on the rtl8180 driver skeleton
|
|
from Patric Schenke & Andres Salomon
|
|
|
|
Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
|
|
|
|
NetBSD rtl8180 driver from Dave Young has been really useful to
|
|
understand how to program the MAXIM radio. Thanks a lot!!!
|
|
|
|
'The Deuce' tested this and fixed some bugs.
|
|
|
|
Code from rtl8181 project has been useful to me to understand some things.
|
|
|
|
We want to tanks the Authors of such projects and the Ndiswrapper
|
|
project Authors.
|
|
*/
|
|
|
|
|
|
#include "r8180.h"
|
|
#include "r8180_hw.h"
|
|
#include "r8180_max2820.h"
|
|
|
|
|
|
//#define DEBUG_MAXIM
|
|
|
|
u32 maxim_chan[] = {
|
|
0, //dummy channel 0
|
|
12, //1
|
|
17, //2
|
|
22, //3
|
|
27, //4
|
|
32, //5
|
|
37, //6
|
|
42, //7
|
|
47, //8
|
|
52, //9
|
|
57, //10
|
|
62, //11
|
|
67, //12
|
|
72, //13
|
|
84, //14
|
|
};
|
|
|
|
#if 0
|
|
/* maxim expects 4 bit address MSF, then 12 bit data MSF*/
|
|
void write_maxim(struct net_device *dev,u8 adr, u32 data)
|
|
{
|
|
|
|
int shift;
|
|
short bit;
|
|
u16 word;
|
|
|
|
adr = adr &0xf;
|
|
word = (u16)data & 0xfff;
|
|
word |= (adr<<12);
|
|
/*write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | BB_HOST_BANG_EN);
|
|
read_nic_dword(dev,PHY_CONFIG);
|
|
mdelay(1);
|
|
|
|
write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | BB_HOST_BANG_EN | BB_HOST_BANG_CLK);
|
|
read_nic_dword(dev,PHY_CONFIG);
|
|
mdelay(1);
|
|
*/
|
|
|
|
/* MAX2820 will sample data on rising edge of clock */
|
|
for(shift = 15;shift >=0; shift--){
|
|
bit = word>>shift & 1;
|
|
|
|
write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA));
|
|
|
|
read_nic_dword(dev,PHY_CONFIG);
|
|
mdelay(2);
|
|
|
|
write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
|
|
(bit<<BB_HOST_BANG_DATA) | BB_HOST_BANG_CLK); /* sample data */
|
|
|
|
read_nic_dword(dev,PHY_CONFIG);
|
|
mdelay(1);
|
|
|
|
write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
|
|
(bit<<BB_HOST_BANG_DATA));
|
|
|
|
read_nic_dword(dev,PHY_CONFIG);
|
|
mdelay(2);
|
|
|
|
}
|
|
write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
|
|
BB_HOST_BANG_EN);
|
|
read_nic_dword(dev,PHY_CONFIG);
|
|
mdelay(2);
|
|
|
|
/* The shift register fill flush to the requested register the
|
|
* last 12 bits data shifted in
|
|
*/
|
|
write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
|
|
BB_HOST_BANG_EN | BB_HOST_BANG_CLK);
|
|
read_nic_dword(dev,PHY_CONFIG);
|
|
mdelay(2);
|
|
|
|
write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
|
|
BB_HOST_BANG_EN);
|
|
read_nic_dword(dev,PHY_CONFIG);
|
|
mdelay(2);
|
|
|
|
|
|
#ifdef DEBUG_MAXIM
|
|
DMESG("Writing maxim: %x (adr %x)",phy_config,adr);
|
|
#endif
|
|
|
|
}
|
|
#endif
|
|
|
|
void write_maxim(struct net_device *dev,u8 adr, u32 data) {
|
|
u32 temp;
|
|
temp = 0x90 + (data & 0xf);
|
|
temp <<= 16;
|
|
temp += adr;
|
|
temp <<= 8;
|
|
temp += (data >> 4) & 0xff;
|
|
#ifdef DEBUG_MAXIM
|
|
DMESG("write_maxim: %08x", temp);
|
|
#endif
|
|
write_nic_dword(dev, PHY_CONFIG, temp);
|
|
force_pci_posting(dev);
|
|
mdelay(1);
|
|
}
|
|
|
|
|
|
void maxim_write_phy_antenna(struct net_device *dev,short ch)
|
|
{
|
|
struct r8180_priv *priv = ieee80211_priv(dev);
|
|
u8 ant;
|
|
|
|
ant = MAXIM_ANTENNA;
|
|
if(priv->antb) /*default antenna is antenna B */
|
|
ant |= BB_ANTENNA_B;
|
|
if(ch == 14)
|
|
ant |= BB_ANTATTEN_CHAN14;
|
|
write_phy(dev,0x10,ant);
|
|
//DMESG("BB antenna %x ",ant);
|
|
}
|
|
|
|
|
|
void maxim_rf_set_chan(struct net_device *dev, short ch)
|
|
{
|
|
struct r8180_priv *priv = ieee80211_priv(dev);
|
|
u32 txpw = 0xff & priv->chtxpwr[ch];
|
|
u32 chan = maxim_chan[ch];
|
|
|
|
/*While philips SA2400 drive the PA bias
|
|
*seems that for MAXIM we delegate this
|
|
*to the BB
|
|
*/
|
|
|
|
//write_maxim(dev,5,txpw);
|
|
write_phy(dev,3,txpw);
|
|
|
|
maxim_write_phy_antenna(dev,ch);
|
|
write_maxim(dev,3,chan);
|
|
}
|
|
|
|
|
|
void maxim_rf_close(struct net_device *dev)
|
|
{
|
|
write_phy(dev, 3, 0x8);
|
|
write_maxim(dev, 1, 0);
|
|
}
|
|
|
|
|
|
void maxim_rf_init(struct net_device *dev)
|
|
{
|
|
struct r8180_priv *priv = ieee80211_priv(dev);
|
|
u32 anaparam;
|
|
|
|
write_nic_byte(dev,PHY_DELAY,0x6); //this is general
|
|
write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
|
|
|
|
/*these are maxim specific*/
|
|
anaparam = read_nic_dword(dev,ANAPARAM);
|
|
anaparam = anaparam &~ (ANAPARAM_TXDACOFF_SHIFT);
|
|
anaparam = anaparam &~ANAPARAM_PWR1_MASK;
|
|
anaparam = anaparam &~ANAPARAM_PWR0_MASK;
|
|
anaparam |= (MAXIM_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
|
|
anaparam |= (MAXIM_ANAPARAM_PWR0_ON<<ANAPARAM_PWR0_SHIFT);
|
|
|
|
//rtl8180_set_anaparam(dev,anaparam);
|
|
|
|
/* MAXIM from netbsd driver */
|
|
|
|
write_maxim(dev,0, 7); /* test mode as indicated in datasheet*/
|
|
write_maxim(dev,1, 0x1e); /* enable register*/
|
|
write_maxim(dev,2, 1); /* synt register */
|
|
|
|
|
|
maxim_rf_set_chan(dev,priv->chan);
|
|
|
|
write_maxim(dev,4, 0x313); /* rx register*/
|
|
|
|
/* PA is driven directly by the BB, we keep the MAXIM bias
|
|
* at the highest value in the boubt tha pleacing it to lower
|
|
* values may introduce some further attenuation somewhere..
|
|
*/
|
|
|
|
write_maxim(dev,5, 0xf);
|
|
|
|
|
|
/*baseband configuration*/
|
|
write_phy(dev,0,0x88); //sys1
|
|
write_phy(dev,3,0x8); //txagc
|
|
write_phy(dev,4,0xf8); // lnadet
|
|
write_phy(dev,5,0x90); // ifagcinit
|
|
write_phy(dev,6,0x1a); // ifagclimit
|
|
write_phy(dev,7,0x64); // ifagcdet
|
|
|
|
/*Should be done something more here??*/
|
|
|
|
maxim_write_phy_antenna(dev,priv->chan);
|
|
|
|
write_phy(dev,0x11,0x88); //trl
|
|
if(priv->diversity)
|
|
write_phy(dev,0x12,0xc7);
|
|
else
|
|
write_phy(dev,0x12,0x47);
|
|
|
|
write_phy(dev,0x13,0x9b);
|
|
|
|
write_phy(dev,0x19,0x0); //CHESTLIM
|
|
write_phy(dev,0x1a,0x9f); //CHSQLIM
|
|
|
|
maxim_rf_set_chan(dev,priv->chan);
|
|
}
|