root/drivers/net/wireless/realtek/rtl818x/rtl8180/max2820.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. write_max2820
  2. max2820_write_phy_antenna
  3. max2820_rf_calc_rssi
  4. max2820_rf_set_channel
  5. max2820_rf_stop
  6. max2820_rf_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Radio tuning for Maxim max2820 on RTL8180
   4  *
   5  * Copyright 2007 Andrea Merello <andrea.merello@gmail.com>
   6  *
   7  * Code from the BSD driver and the rtl8181 project have been
   8  * very useful to understand certain things
   9  *
  10  * I want to thanks the Authors of such projects and the Ndiswrapper
  11  * project Authors.
  12  *
  13  * A special Big Thanks also is for all people who donated me cards,
  14  * making possible the creation of the original rtl8180 driver
  15  * from which this code is derived!
  16  */
  17 
  18 #include <linux/pci.h>
  19 #include <linux/delay.h>
  20 #include <net/mac80211.h>
  21 
  22 #include "rtl8180.h"
  23 #include "max2820.h"
  24 
  25 static const u32 max2820_chan[] = {
  26         12, /* CH 1 */
  27         17,
  28         22,
  29         27,
  30         32,
  31         37,
  32         42,
  33         47,
  34         52,
  35         57,
  36         62,
  37         67,
  38         72,
  39         84, /* CH 14 */
  40 };
  41 
  42 static void write_max2820(struct ieee80211_hw *dev, u8 addr, u32 data)
  43 {
  44         struct rtl8180_priv *priv = dev->priv;
  45         u32 phy_config;
  46 
  47         phy_config = 0x90 + (data & 0xf);
  48         phy_config <<= 16;
  49         phy_config += addr;
  50         phy_config <<= 8;
  51         phy_config += (data >> 4) & 0xff;
  52 
  53         rtl818x_iowrite32(priv,
  54                 (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
  55 
  56         msleep(1);
  57 }
  58 
  59 static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan)
  60 {
  61         struct rtl8180_priv *priv = dev->priv;
  62         u8 ant;
  63 
  64         ant = MAXIM_ANTENNA;
  65         if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
  66                 ant |= BB_ANTENNA_B;
  67         if (chan == 14)
  68                 ant |= BB_ANTATTEN_CHAN14;
  69 
  70         rtl8180_write_phy(dev, 0x10, ant);
  71 }
  72 
  73 static u8 max2820_rf_calc_rssi(u8 agc, u8 sq)
  74 {
  75         bool odd;
  76 
  77         odd = !!(agc & 1);
  78 
  79         agc >>= 1;
  80         if (odd)
  81                 agc += 76;
  82         else
  83                 agc += 66;
  84 
  85         /* TODO: change addends above to avoid mult / div below */
  86         return 65 * agc / 100;
  87 }
  88 
  89 static void max2820_rf_set_channel(struct ieee80211_hw *dev,
  90                                    struct ieee80211_conf *conf)
  91 {
  92         struct rtl8180_priv *priv = dev->priv;
  93         int channel = conf ?
  94                 ieee80211_frequency_to_channel(conf->chandef.chan->center_freq) : 1;
  95         unsigned int chan_idx = channel - 1;
  96         u32 txpw = priv->channels[chan_idx].hw_value & 0xFF;
  97         u32 chan = max2820_chan[chan_idx];
  98 
  99         /* While philips SA2400 drive the PA bias from
 100          * sa2400, for MAXIM we do this directly from BB */
 101         rtl8180_write_phy(dev, 3, txpw);
 102 
 103         max2820_write_phy_antenna(dev, channel);
 104         write_max2820(dev, 3, chan);
 105 }
 106 
 107 static void max2820_rf_stop(struct ieee80211_hw *dev)
 108 {
 109         rtl8180_write_phy(dev, 3, 0x8);
 110         write_max2820(dev, 1, 0);
 111 }
 112 
 113 
 114 static void max2820_rf_init(struct ieee80211_hw *dev)
 115 {
 116         struct rtl8180_priv *priv = dev->priv;
 117 
 118         /* MAXIM from netbsd driver */
 119         write_max2820(dev, 0, 0x007); /* test mode as indicated in datasheet */
 120         write_max2820(dev, 1, 0x01e); /* enable register */
 121         write_max2820(dev, 2, 0x001); /* synt register */
 122 
 123         max2820_rf_set_channel(dev, NULL);
 124 
 125         write_max2820(dev, 4, 0x313); /* rx register */
 126 
 127         /* PA is driven directly by the BB, we keep the MAXIM bias
 128          * at the highest value in case that setting it to lower
 129          * values may introduce some further attenuation somewhere..
 130          */
 131         write_max2820(dev, 5, 0x00f);
 132 
 133         /* baseband configuration */
 134         rtl8180_write_phy(dev, 0, 0x88); /* sys1       */
 135         rtl8180_write_phy(dev, 3, 0x08); /* txagc      */
 136         rtl8180_write_phy(dev, 4, 0xf8); /* lnadet     */
 137         rtl8180_write_phy(dev, 5, 0x90); /* ifagcinit  */
 138         rtl8180_write_phy(dev, 6, 0x1a); /* ifagclimit */
 139         rtl8180_write_phy(dev, 7, 0x64); /* ifagcdet   */
 140 
 141         max2820_write_phy_antenna(dev, 1);
 142 
 143         rtl8180_write_phy(dev, 0x11, 0x88); /* trl */
 144 
 145         if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
 146             RTL818X_CONFIG2_ANTENNA_DIV)
 147                 rtl8180_write_phy(dev, 0x12, 0xc7);
 148         else
 149                 rtl8180_write_phy(dev, 0x12, 0x47);
 150 
 151         rtl8180_write_phy(dev, 0x13, 0x9b);
 152 
 153         rtl8180_write_phy(dev, 0x19, 0x0);  /* CHESTLIM */
 154         rtl8180_write_phy(dev, 0x1a, 0x9f); /* CHSQLIM  */
 155 
 156         max2820_rf_set_channel(dev, NULL);
 157 }
 158 
 159 const struct rtl818x_rf_ops max2820_rf_ops = {
 160         .name           = "Maxim",
 161         .init           = max2820_rf_init,
 162         .stop           = max2820_rf_stop,
 163         .set_chan       = max2820_rf_set_channel,
 164         .calc_rssi      = max2820_rf_calc_rssi,
 165 };

/* [<][>][^][v][top][bottom][index][help] */