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

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

DEFINITIONS

This source file includes following definitions.
  1. write_grf5101
  2. grf5101_write_phy_antenna
  3. grf5101_rf_calc_rssi
  4. grf5101_rf_set_channel
  5. grf5101_rf_stop
  6. grf5101_rf_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 
   3 /*
   4  * Radio tuning for GCT GRF5101 on RTL8180
   5  *
   6  * Copyright 2007 Andrea Merello <andrea.merello@gmail.com>
   7  *
   8  * Code from the BSD driver and the rtl8181 project have been
   9  * very useful to understand certain things
  10  *
  11  * I want to thanks the Authors of such projects and the Ndiswrapper
  12  * project Authors.
  13  *
  14  * A special Big Thanks also is for all people who donated me cards,
  15  * making possible the creation of the original rtl8180 driver
  16  * from which this code is derived!
  17  */
  18 
  19 #include <linux/pci.h>
  20 #include <linux/delay.h>
  21 #include <net/mac80211.h>
  22 
  23 #include "rtl8180.h"
  24 #include "grf5101.h"
  25 
  26 static const int grf5101_encode[] = {
  27         0x0, 0x8, 0x4, 0xC,
  28         0x2, 0xA, 0x6, 0xE,
  29         0x1, 0x9, 0x5, 0xD,
  30         0x3, 0xB, 0x7, 0xF
  31 };
  32 
  33 static void write_grf5101(struct ieee80211_hw *dev, u8 addr, u32 data)
  34 {
  35         struct rtl8180_priv *priv = dev->priv;
  36         u32 phy_config;
  37 
  38         phy_config =  grf5101_encode[(data >> 8) & 0xF];
  39         phy_config |= grf5101_encode[(data >> 4) & 0xF] << 4;
  40         phy_config |= grf5101_encode[data & 0xF] << 8;
  41         phy_config |= grf5101_encode[(addr >> 1) & 0xF] << 12;
  42         phy_config |= (addr & 1) << 16;
  43         phy_config |= grf5101_encode[(data & 0xf000) >> 12] << 24;
  44 
  45         /* MAC will bang bits to the chip */
  46         phy_config |= 0x90000000;
  47 
  48         rtl818x_iowrite32(priv,
  49                 (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
  50 
  51         msleep(3);
  52 }
  53 
  54 static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan)
  55 {
  56         struct rtl8180_priv *priv = dev->priv;
  57         u8 ant = GRF5101_ANTENNA;
  58 
  59         if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
  60                 ant |= BB_ANTENNA_B;
  61 
  62         if (chan == 14)
  63                 ant |= BB_ANTATTEN_CHAN14;
  64 
  65         rtl8180_write_phy(dev, 0x10, ant);
  66 }
  67 
  68 static u8 grf5101_rf_calc_rssi(u8 agc, u8 sq)
  69 {
  70         if (agc > 60)
  71                 return 65;
  72 
  73         /* TODO(?): just return agc (or agc + 5) to avoid mult / div */
  74         return 65 * agc / 60;
  75 }
  76 
  77 static void grf5101_rf_set_channel(struct ieee80211_hw *dev,
  78                                    struct ieee80211_conf *conf)
  79 {
  80         struct rtl8180_priv *priv = dev->priv;
  81         int channel =
  82                 ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
  83         u32 txpw = priv->channels[channel - 1].hw_value & 0xFF;
  84         u32 chan = channel - 1;
  85 
  86         /* set TX power */
  87         write_grf5101(dev, 0x15, 0x0);
  88         write_grf5101(dev, 0x06, txpw);
  89         write_grf5101(dev, 0x15, 0x10);
  90         write_grf5101(dev, 0x15, 0x0);
  91 
  92         /* set frequency */
  93         write_grf5101(dev, 0x07, 0x0);
  94         write_grf5101(dev, 0x0B, chan);
  95         write_grf5101(dev, 0x07, 0x1000);
  96 
  97         grf5101_write_phy_antenna(dev, channel);
  98 }
  99 
 100 static void grf5101_rf_stop(struct ieee80211_hw *dev)
 101 {
 102         struct rtl8180_priv *priv = dev->priv;
 103         u32 anaparam;
 104 
 105         anaparam = priv->anaparam;
 106         anaparam &= 0x000fffff;
 107         anaparam |= 0x3f900000;
 108         rtl8180_set_anaparam(priv, anaparam);
 109 
 110         write_grf5101(dev, 0x07, 0x0);
 111         write_grf5101(dev, 0x1f, 0x45);
 112         write_grf5101(dev, 0x1f, 0x5);
 113         write_grf5101(dev, 0x00, 0x8e4);
 114 }
 115 
 116 static void grf5101_rf_init(struct ieee80211_hw *dev)
 117 {
 118         struct rtl8180_priv *priv = dev->priv;
 119 
 120         rtl8180_set_anaparam(priv, priv->anaparam);
 121 
 122         write_grf5101(dev, 0x1f, 0x0);
 123         write_grf5101(dev, 0x1f, 0x0);
 124         write_grf5101(dev, 0x1f, 0x40);
 125         write_grf5101(dev, 0x1f, 0x60);
 126         write_grf5101(dev, 0x1f, 0x61);
 127         write_grf5101(dev, 0x1f, 0x61);
 128         write_grf5101(dev, 0x00, 0xae4);
 129         write_grf5101(dev, 0x1f, 0x1);
 130         write_grf5101(dev, 0x1f, 0x41);
 131         write_grf5101(dev, 0x1f, 0x61);
 132 
 133         write_grf5101(dev, 0x01, 0x1a23);
 134         write_grf5101(dev, 0x02, 0x4971);
 135         write_grf5101(dev, 0x03, 0x41de);
 136         write_grf5101(dev, 0x04, 0x2d80);
 137         write_grf5101(dev, 0x05, 0x68ff);       /* 0x61ff original value */
 138         write_grf5101(dev, 0x06, 0x0);
 139         write_grf5101(dev, 0x07, 0x0);
 140         write_grf5101(dev, 0x08, 0x7533);
 141         write_grf5101(dev, 0x09, 0xc401);
 142         write_grf5101(dev, 0x0a, 0x0);
 143         write_grf5101(dev, 0x0c, 0x1c7);
 144         write_grf5101(dev, 0x0d, 0x29d3);
 145         write_grf5101(dev, 0x0e, 0x2e8);
 146         write_grf5101(dev, 0x10, 0x192);
 147         write_grf5101(dev, 0x11, 0x248);
 148         write_grf5101(dev, 0x12, 0x0);
 149         write_grf5101(dev, 0x13, 0x20c4);
 150         write_grf5101(dev, 0x14, 0xf4fc);
 151         write_grf5101(dev, 0x15, 0x0);
 152         write_grf5101(dev, 0x16, 0x1500);
 153 
 154         write_grf5101(dev, 0x07, 0x1000);
 155 
 156         /* baseband configuration */
 157         rtl8180_write_phy(dev, 0, 0xa8);
 158         rtl8180_write_phy(dev, 3, 0x0);
 159         rtl8180_write_phy(dev, 4, 0xc0);
 160         rtl8180_write_phy(dev, 5, 0x90);
 161         rtl8180_write_phy(dev, 6, 0x1e);
 162         rtl8180_write_phy(dev, 7, 0x64);
 163 
 164         grf5101_write_phy_antenna(dev, 1);
 165 
 166         rtl8180_write_phy(dev, 0x11, 0x88);
 167 
 168         if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
 169             RTL818X_CONFIG2_ANTENNA_DIV)
 170                 rtl8180_write_phy(dev, 0x12, 0xc0); /* enable ant diversity */
 171         else
 172                 rtl8180_write_phy(dev, 0x12, 0x40); /* disable ant diversity */
 173 
 174         rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
 175 
 176         rtl8180_write_phy(dev, 0x19, 0x0);
 177         rtl8180_write_phy(dev, 0x1a, 0xa0);
 178         rtl8180_write_phy(dev, 0x1b, 0x44);
 179 }
 180 
 181 const struct rtl818x_rf_ops grf5101_rf_ops = {
 182         .name           = "GCT",
 183         .init           = grf5101_rf_init,
 184         .stop           = grf5101_rf_stop,
 185         .set_chan       = grf5101_rf_set_channel,
 186         .calc_rssi      = grf5101_rf_calc_rssi,
 187 };

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