/*
* RF Buffer handling functions
*
* Copyright (c) 2009 Nick Kossifidis <mickflemm@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
/*
* There are some special registers on the RF chip
* that control various operation settings related mostly to
* the analog parts (channel, gain adjustment etc).
*
* We don't write on those registers directly but
* we send a data packet on the chip, using a special register,
* that holds all the settings we need. After we 've sent the
* data packet, we write on another special register to notify hw
* to apply the settings. This is done so that control registers
* can be dynamicaly programmed during operation and the settings
* are applied faster on the hw.
*
* We call each data packet an "RF Bank" and all the data we write
* (all RF Banks) "RF Buffer". This file holds initial RF Buffer
* data for the different RF chips, and various info to match RF
* Buffer offsets with specific RF registers so that we can access
* them. We tweak these settings on rfregs_init function.
*
* Also check out reg.h and U.S. Patent 6677779 B1 (about buffer
* registers and control registers):
*
* http://www.google.com/patents?id=qNURAAAAEBAJ
*/
/*
* Struct to hold default mode specific RF
* register values (RF Banks)
*/
struct ath5k_ini_rfbuffer {
u8 rfb_bank; /* RF Bank number */
u16 rfb_ctrl_register; /* RF Buffer control register */
u32 rfb_mode_data[5]; /* RF Buffer data for each mode */
};
/*
* Struct to hold RF Buffer field
* infos used to access certain RF
* analog registers
*/
struct ath5k_rfb_field {
u8 len; /* Field length */
u16 pos; /* Offset on the raw packet */
u8 col; /* Column -used for shifting */
};
/*
* RF analog register definition
*/
struct ath5k_rf_reg {
u8 bank; /* RF Buffer Bank number */
u8 index; /* Register's index on rf_regs_idx */
struct ath5k_rfb_field field; /* RF Buffer field for this register */
};
/* Map RF registers to indexes
* We do this to handle common bits and make our
* life easier by using an index for each register
* instead of a full rfb_field */
enum ath5k_rf_regs_idx {
/* BANK 6 */
AR5K_RF_OB_2GHZ = 0,
AR5K_RF_OB_5GHZ,
AR5K_RF_DB_2GHZ,
AR5K_RF_DB_5GHZ,
AR5K_RF_FIXED_BIAS_A,
AR5K_RF_FIXED_BIAS_B,
AR5K_RF_PWD_XPD,
AR5K_RF_XPD_SEL,
AR5K_RF_XPD_GAIN,
AR5K_RF_PD_GAIN_LO,
AR5K_RF_PD_GAIN_HI,
AR5K_RF_HIGH_VC_CP,
AR5K_RF_MID_VC_CP,
AR5K_RF_LOW_VC_CP,
AR5K_RF_PUSH_UP,
AR5K_RF_PAD2GND,
AR5K_RF_XB2_LVL,
AR5K_RF_XB5_LVL,
AR5K_RF_PWD_ICLOBUF_2G,
AR5K_RF_PWD_84,
AR5K_RF_PWD_90,
AR5K_RF_PWD_130,
AR5K_RF_PWD_131,
AR5K_RF_PWD_132,
AR5K_RF_PWD_136,
AR5K_RF_PWD_137,
AR5K_RF_PWD_138,
AR5K_RF_PWD_166,
AR5K_RF_PWD_167,
AR5K_RF_DERBY_CHAN_SEL_MODE,
/* BANK 7 */
AR5K_RF_GAIN_I,
AR5K_RF_PLO_SEL,
AR5K_RF_RFGAIN_SEL,
AR5K_RF_RFGAIN_STEP,
AR5K_RF_WAIT_S,
AR5K_RF_WAIT_I,
AR5K_RF_MAX_TIME,
AR5K_RF_MIXVGA_OVR,
AR5K_RF_MIXGAIN_OVR,
AR5K_RF_MIXGAIN_STEP,
AR5K_RF_PD_DELAY_A,
AR5K_RF_PD_DELAY_B,
AR5K_RF_PD_DELAY_XR,
AR5K_RF_PD_PERIOD_A,
AR5K_RF_PD_PERIOD_B,
AR5K_RF_PD_PERIOD_XR,
};
/*******************\
* RF5111 (Sombrero) *
\*******************/
/* BANK 6 len pos col */
#define AR5K_RF5111_OB_2GHZ { 3, 119, 0 }
#define AR5K_RF5111_DB_2GHZ { 3, 122, 0 }
#define AR5K_RF5111_OB_5GHZ { 3, 104, 0 }
#define AR5K_RF5111_DB_5GHZ { 3, 107, 0 }
#define AR5K_RF5111_PWD_XPD { 1, 95, 0 }
#define AR5K_RF5111_XPD_GAIN { 4, 96, 0 }
/* Access to PWD registers */
#define AR5K_RF5111_PWD(_n) { 1, (135 - _n), 3 }
/* BANK 7 len pos col */
#define AR5K_RF5111_GAIN_I { 6, 29, 0 }
#define AR5K_RF5111_PLO_SEL { 1, 4, 0 }
#define AR5K_RF5111_RFGAIN_SEL { 1, 36, 0 }
#define AR5K_RF5111_RFGAIN_STEP { 6, 37, 0 }
/* Only on AR5212 BaseBand and up */
#define AR5K_RF5111_WAIT_S { 5, 19, 0 }
#define AR5K_RF5111_WAIT_I { 5, 24, 0 }
#define AR5K_RF5111_MAX_TIME { 2, 49, 0 }
static const struct ath5k_rf_reg rf_regs_5111[] = {
{6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ},
{6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ},
{6, AR5K_RF_DB_5GHZ, AR5K_RF5111_DB_5GHZ},
{6, AR5K_RF_PWD_XPD, AR5K_RF5111_PWD_XPD},
{6, AR5K_RF_XPD_GAIN, AR5K_RF5111_XPD_GAIN},
{6, AR5K_RF_PWD_84, AR5K_RF5111_PWD(84)},
{6, AR5K_RF_PWD_90, AR5K_RF5111_PWD(90)},
{7, AR5K_RF_GAIN_I, AR5K_RF5111_GAIN_I},
{7, AR5K_RF_PLO_SEL, AR5K_RF5111_PLO_SEL},
{7, AR5K_RF_RFGAIN_SEL, AR5K_RF5111_RFGAIN_SEL},
{7, AR5K_RF_RFGAIN_STEP, AR5K_RF5111_RFGAIN_STEP},
{7, AR5K_RF_WAIT_S, AR5K_RF5111_WAIT_S},
{7, <