linux/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2
   3/*
   4 * Radio tuning for RTL8225 on RTL8180
   5 *
   6 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
   7 * Copyright 2007 Andrea Merello <andrea.merello@gmail.com>
   8 *
   9 * Based on the r8180 driver, which is:
  10 * Copyright 2005 Andrea Merello <andrea.merello@gmail.com>, et al.
  11 *
  12 * Thanks to Realtek for their support!
  13 */
  14
  15#include <linux/pci.h>
  16#include <linux/delay.h>
  17#include <net/mac80211.h>
  18
  19#include "rtl8180.h"
  20#include "rtl8225.h"
  21
  22static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
  23{
  24        struct rtl8180_priv *priv = dev->priv;
  25        u16 reg80, reg84, reg82;
  26        u32 bangdata;
  27        int i;
  28
  29        bangdata = (data << 4) | (addr & 0xf);
  30
  31        reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
  32        reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
  33
  34        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
  35
  36        reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
  37        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400);
  38        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  39        udelay(10);
  40
  41        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
  42        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  43        udelay(2);
  44        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
  45        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  46        udelay(10);
  47
  48        for (i = 15; i >= 0; i--) {
  49                u16 reg = reg80;
  50
  51                if (bangdata & (1 << i))
  52                        reg |= 1;
  53
  54                if (i & 1)
  55                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
  56
  57                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
  58                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
  59
  60                if (!(i & 1))
  61                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
  62        }
  63
  64        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
  65        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  66        udelay(10);
  67
  68        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
  69        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400);
  70        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
  71}
  72
  73static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
  74{
  75        struct rtl8180_priv *priv = dev->priv;
  76        u16 reg80, reg82, reg84, out;
  77        int i;
  78
  79        reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
  80        reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
  81        reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400;
  82
  83        reg80 &= ~0xF;
  84
  85        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
  86        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
  87
  88        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
  89        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  90        udelay(4);
  91        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
  92        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  93        udelay(5);
  94
  95        for (i = 4; i >= 0; i--) {
  96                u16 reg = reg80 | ((addr >> i) & 1);
  97
  98                if (!(i & 1)) {
  99                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
 100                        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 101                        udelay(1);
 102                }
 103
 104                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 105                                  reg | (1 << 1));
 106                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 107                udelay(2);
 108                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 109                                  reg | (1 << 1));
 110                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 111                udelay(2);
 112
 113                if (i & 1) {
 114                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
 115                        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 116                        udelay(1);
 117                }
 118        }
 119
 120        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E);
 121        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E);
 122        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 123        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 124                          reg80 | (1 << 3) | (1 << 1));
 125        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 126        udelay(2);
 127        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 128                          reg80 | (1 << 3));
 129        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 130        udelay(2);
 131        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 132                          reg80 | (1 << 3));
 133        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 134        udelay(2);
 135
 136        out = 0;
 137        for (i = 11; i >= 0; i--) {
 138                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 139                                  reg80 | (1 << 3));
 140                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 141                udelay(1);
 142                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 143                                  reg80 | (1 << 3) | (1 << 1));
 144                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 145                udelay(2);
 146                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 147                                  reg80 | (1 << 3) | (1 << 1));
 148                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 149                udelay(2);
 150                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 151                                  reg80 | (1 << 3) | (1 << 1));
 152                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 153                udelay(2);
 154
 155                if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
 156                        out |= 1 << i;
 157
 158                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 159                                  reg80 | (1 << 3));
 160                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 161                udelay(2);
 162        }
 163
 164        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 165                          reg80 | (1 << 3) | (1 << 2));
 166        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 167        udelay(2);
 168
 169        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
 170        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
 171        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
 172
 173        return out;
 174}
 175
 176static const u16 rtl8225bcd_rxgain[] = {
 177        0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
 178        0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
 179        0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
 180        0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
 181        0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
 182        0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
 183        0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
 184        0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
 185        0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
 186        0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
 187        0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
 188        0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
 189};
 190
 191static const u8 rtl8225_agc[] = {
 192        0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 193        0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
 194        0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
 195        0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
 196        0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
 197        0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
 198        0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
 199        0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
 200        0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
 201        0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
 202        0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
 203        0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
 204        0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
 205        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 206        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 207        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
 208};
 209
 210static const u8 rtl8225_gain[] = {
 211        0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
 212        0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
 213        0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
 214        0x33, 0x80, 0x79, 0xc5, /* -78dbm */
 215        0x43, 0x78, 0x76, 0xc5, /* -74dbm */
 216        0x53, 0x60, 0x73, 0xc5, /* -70dbm */
 217        0x63, 0x58, 0x70, 0xc5, /* -66dbm */
 218};
 219
 220static const u8 rtl8225_threshold[] = {
 221        0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
 222};
 223
 224static const u8 rtl8225_tx_gain_cck_ofdm[] = {
 225        0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
 226};
 227
 228static const u8 rtl8225_tx_power_cck[] = {
 229        0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
 230        0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
 231        0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
 232        0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
 233        0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
 234        0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
 235};
 236
 237static const u8 rtl8225_tx_power_cck_ch14[] = {
 238        0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
 239        0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
 240        0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
 241        0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
 242        0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
 243        0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
 244};
 245
 246static const u8 rtl8225_tx_power_ofdm[] = {
 247        0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
 248};
 249
 250static const u32 rtl8225_chan[] = {
 251        0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
 252        0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
 253};
 254
 255static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
 256{
 257        struct rtl8180_priv *priv = dev->priv;
 258        u8 cck_power, ofdm_power;
 259        const u8 *tmp;
 260        u32 reg;
 261        int i;
 262
 263        cck_power = priv->channels[channel - 1].hw_value & 0xFF;
 264        ofdm_power = priv->channels[channel - 1].hw_value >> 8;
 265
 266        cck_power = min(cck_power, (u8)35);
 267        ofdm_power = min(ofdm_power, (u8)35);
 268
 269        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
 270                         rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
 271
 272        if (channel == 14)
 273                tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
 274        else
 275                tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
 276
 277        for (i = 0; i < 8; i++)
 278                rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
 279
 280        msleep(1); /* FIXME: optional? */
 281
 282        /* TODO: use set_anaparam2 dev.c_func*/
 283        /* anaparam2 on */
 284        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
 285        reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
 286        rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
 287        rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
 288        rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
 289        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 290
 291        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
 292                         rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1);
 293
 294        tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
 295
 296        rtl8225_write_phy_ofdm(dev, 5, *tmp);
 297        rtl8225_write_phy_ofdm(dev, 7, *tmp);
 298
 299        msleep(1);
 300}
 301
 302static void rtl8225_rf_init(struct ieee80211_hw *dev)
 303{
 304        struct rtl8180_priv *priv = dev->priv;
 305        int i;
 306
 307        rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);
 308
 309        /* host_pci_init */
 310        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
 311        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
 312        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
 313        rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
 314        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 315        msleep(200);    /* FIXME: ehh?? */
 316        rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
 317
 318        rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
 319
 320        /* TODO: check if we need really to change BRSR to do RF config */
 321        rtl818x_ioread16(priv, &priv->map->BRSR);
 322        rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
 323        rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
 324        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
 325        rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
 326        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 327
 328        rtl8225_write(dev, 0x0, 0x067);
 329        rtl8225_write(dev, 0x1, 0xFE0);
 330        rtl8225_write(dev, 0x2, 0x44D);
 331        rtl8225_write(dev, 0x3, 0x441);
 332        rtl8225_write(dev, 0x4, 0x8BE);
 333        rtl8225_write(dev, 0x5, 0xBF0);         /* TODO: minipci */
 334        rtl8225_write(dev, 0x6, 0xAE6);
 335        rtl8225_write(dev, 0x7, rtl8225_chan[0]);
 336        rtl8225_write(dev, 0x8, 0x01F);
 337        rtl8225_write(dev, 0x9, 0x334);
 338        rtl8225_write(dev, 0xA, 0xFD4);
 339        rtl8225_write(dev, 0xB, 0x391);
 340        rtl8225_write(dev, 0xC, 0x050);
 341        rtl8225_write(dev, 0xD, 0x6DB);
 342        rtl8225_write(dev, 0xE, 0x029);
 343        rtl8225_write(dev, 0xF, 0x914); msleep(1);
 344
 345        rtl8225_write(dev, 0x2, 0xC4D); msleep(100);
 346
 347        rtl8225_write(dev, 0x0, 0x127);
 348
 349        for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
 350                rtl8225_write(dev, 0x1, i + 1);
 351                rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
 352        }
 353
 354        rtl8225_write(dev, 0x0, 0x027);
 355        rtl8225_write(dev, 0x0, 0x22F);
 356        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
 357
 358        for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
 359                rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
 360                msleep(1);
 361                rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
 362                msleep(1);
 363        }
 364
 365        msleep(1);
 366
 367        rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
 368        rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
 369        rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1);
 370        rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
 371        rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
 372        rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
 373        rtl8225_write_phy_ofdm(dev, 0x06, 0x00); msleep(1);
 374        rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
 375        rtl8225_write_phy_ofdm(dev, 0x08, 0x00); msleep(1);
 376        rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
 377        rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
 378        rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
 379        rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
 380        rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
 381        rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
 382        rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
 383        rtl8225_write_phy_ofdm(dev, 0x11, 0x03); msleep(1);
 384        rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
 385        rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
 386        rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
 387        rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
 388        rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
 389        rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
 390        rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
 391        rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
 392        rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
 393        rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1);
 394        rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
 395        rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
 396        rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
 397        rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
 398        rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
 399        rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
 400        rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
 401        rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
 402        rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
 403        rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
 404
 405        rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
 406        rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
 407        rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
 408        rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
 409        rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
 410        rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
 411        rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
 412        rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1);
 413        rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
 414        rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
 415        rtl8225_write_phy_cck(dev, 0x13, 0xd0);
 416        rtl8225_write_phy_cck(dev, 0x19, 0x00);
 417        rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
 418        rtl8225_write_phy_cck(dev, 0x1b, 0x08);
 419        rtl8225_write_phy_cck(dev, 0x40, 0x86);
 420        rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
 421        rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
 422        rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
 423        rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1);
 424        rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1);
 425        rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1);
 426        rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1);
 427        rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1);
 428        rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1);
 429        rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1);
 430        rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1);
 431        rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
 432
 433        rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); msleep(1);
 434
 435        rtl8225_rf_set_tx_power(dev, 1);
 436
 437        /* RX antenna default to A */
 438        rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);      /* B: 0xDB */
 439        rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);     /* B: 0x10 */
 440
 441        rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
 442        msleep(1);
 443        rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002);
 444        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
 445
 446        rtl8225_write(dev, 0x0c, 0x50);
 447        /* set OFDM initial gain */
 448        rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]);
 449        rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]);
 450        rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]);
 451        rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]);
 452        /* set CCK threshold */
 453        rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]);
 454}
 455
 456static const u8 rtl8225z2_tx_power_cck_ch14[] = {
 457        0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
 458};
 459
 460static const u8 rtl8225z2_tx_power_cck_B[] = {
 461        0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04
 462};
 463
 464static const u8 rtl8225z2_tx_power_cck_A[] = {
 465        0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04
 466};
 467
 468static const u8 rtl8225z2_tx_power_cck[] = {
 469        0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
 470};
 471
 472static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
 473{
 474        struct rtl8180_priv *priv = dev->priv;
 475        u8 cck_power, ofdm_power;
 476        const u8 *tmp;
 477        int i;
 478
 479        cck_power = priv->channels[channel - 1].hw_value & 0xFF;
 480        ofdm_power = priv->channels[channel - 1].hw_value >> 8;
 481
 482        if (channel == 14)
 483                tmp = rtl8225z2_tx_power_cck_ch14;
 484        else if (cck_power == 12)
 485                tmp = rtl8225z2_tx_power_cck_B;
 486        else if (cck_power == 13)
 487                tmp = rtl8225z2_tx_power_cck_A;
 488        else
 489                tmp = rtl8225z2_tx_power_cck;
 490
 491        for (i = 0; i < 8; i++)
 492                rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
 493
 494        cck_power = min(cck_power, (u8)35);
 495        if (cck_power == 13 || cck_power == 14)
 496                cck_power = 12;
 497        if (cck_power >= 15)
 498                cck_power -= 2;
 499
 500        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, cck_power);
 501        rtl818x_ioread8(priv, &priv->map->TX_GAIN_CCK);
 502        msleep(1);
 503
 504        ofdm_power = min(ofdm_power, (u8)35);
 505        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, ofdm_power);
 506
 507        rtl8225_write_phy_ofdm(dev, 2, 0x62);
 508        rtl8225_write_phy_ofdm(dev, 5, 0x00);
 509        rtl8225_write_phy_ofdm(dev, 6, 0x40);
 510        rtl8225_write_phy_ofdm(dev, 7, 0x00);
 511        rtl8225_write_phy_ofdm(dev, 8, 0x40);
 512
 513        msleep(1);
 514}
 515
 516static const u16 rtl8225z2_rxgain[] = {
 517        0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
 518        0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
 519        0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
 520        0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
 521        0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
 522        0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
 523        0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
 524        0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
 525        0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
 526        0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
 527        0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
 528        0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
 529};
 530
 531static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
 532{
 533        struct rtl8180_priv *priv = dev->priv;
 534        int i;
 535
 536        rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);
 537
 538        /* host_pci_init */
 539        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
 540        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
 541        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
 542        rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
 543        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 544        msleep(200);    /* FIXME: ehh?? */
 545        rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
 546
 547        rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00088008);
 548
 549        /* TODO: check if we need really to change BRSR to do RF config */
 550        rtl818x_ioread16(priv, &priv->map->BRSR);
 551        rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
 552        rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
 553        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
 554        rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
 555        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 556
 557        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
 558
 559        rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
 560        rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
 561        rtl8225_write(dev, 0x2, 0x44D); msleep(1);
 562        rtl8225_write(dev, 0x3, 0x441); msleep(1);
 563        rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
 564        rtl8225_write(dev, 0x5, 0xC72); msleep(1);
 565        rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
 566        rtl8225_write(dev, 0x7, 0x82A); msleep(1);
 567        rtl8225_write(dev, 0x8, 0x03F); msleep(1);
 568        rtl8225_write(dev, 0x9, 0x335); msleep(1);
 569        rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
 570        rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
 571        rtl8225_write(dev, 0xc, 0x850); msleep(1);
 572        rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
 573        rtl8225_write(dev, 0xe, 0x02B); msleep(1);
 574        rtl8225_write(dev, 0xf, 0x114); msleep(100);
 575
 576        if (!(rtl8225_read(dev, 6) & (1 << 7))) {
 577                rtl8225_write(dev, 0x02, 0x0C4D);
 578                msleep(200);
 579                rtl8225_write(dev, 0x02, 0x044D);
 580                msleep(100);
 581                /* TODO: readd calibration failure message when the calibration
 582                   check works */
 583        }
 584
 585        rtl8225_write(dev, 0x0, 0x1B7);
 586        rtl8225_write(dev, 0x3, 0x002);
 587        rtl8225_write(dev, 0x5, 0x004);
 588
 589        for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
 590                rtl8225_write(dev, 0x1, i + 1);
 591                rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
 592        }
 593
 594        rtl8225_write(dev, 0x0, 0x0B7); msleep(100);
 595        rtl8225_write(dev, 0x2, 0xC4D);
 596
 597        msleep(200);
 598        rtl8225_write(dev, 0x2, 0x44D);
 599        msleep(100);
 600
 601        rtl8225_write(dev, 0x00, 0x2BF);
 602        rtl8225_write(dev, 0xFF, 0xFFFF);
 603
 604        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
 605
 606        for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
 607                rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
 608                msleep(1);
 609                rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
 610                msleep(1);
 611        }
 612
 613        msleep(1);
 614
 615        rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
 616        rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
 617        rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1);
 618        rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
 619        rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
 620        rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
 621        rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
 622        rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
 623        rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
 624        rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
 625        rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
 626        rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
 627        rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
 628        rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
 629        rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
 630        rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
 631        rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
 632        rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
 633        rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1);
 634        rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
 635        rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
 636        rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
 637        rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
 638        rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
 639        rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
 640        rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
 641        rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
 642        rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
 643        rtl8225_write_phy_ofdm(dev, 0x1b, 0x11); msleep(1);
 644        rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
 645        rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1);
 646        rtl8225_write_phy_ofdm(dev, 0x1e, 0xb3); msleep(1);
 647        rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
 648        rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
 649        rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
 650        rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
 651        rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); /* FIXME: not needed? */
 652        rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
 653        rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
 654        rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
 655        rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
 656
 657        rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
 658        rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
 659        rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
 660        rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
 661        rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
 662        rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
 663        rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
 664        rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1);
 665        rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
 666        rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
 667        rtl8225_write_phy_cck(dev, 0x13, 0xd0);
 668        rtl8225_write_phy_cck(dev, 0x19, 0x00);
 669        rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
 670        rtl8225_write_phy_cck(dev, 0x1b, 0x08);
 671        rtl8225_write_phy_cck(dev, 0x40, 0x86);
 672        rtl8225_write_phy_cck(dev, 0x41, 0x8a); msleep(1);
 673        rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
 674        rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
 675        rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1);
 676        rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1);
 677        rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1);
 678        rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1);
 679        rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1);
 680        rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1);
 681        rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1);
 682        rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1);
 683        rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
 684
 685        rtl818x_iowrite8(priv, (u8 __iomem *)((void __iomem *)priv->map + 0x5B), 0x0D); msleep(1);
 686
 687        rtl8225z2_rf_set_tx_power(dev, 1);
 688
 689        /* RX antenna default to A */
 690        rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);      /* B: 0xDB */
 691        rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);     /* B: 0x10 */
 692
 693        rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
 694        msleep(1);
 695        rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002);
 696        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
 697}
 698
 699static void rtl8225_rf_stop(struct ieee80211_hw *dev)
 700{
 701        struct rtl8180_priv *priv = dev->priv;
 702        u8 reg;
 703
 704        rtl8225_write(dev, 0x4, 0x1f); msleep(1);
 705
 706        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
 707        reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
 708        rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
 709        rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF);
 710        rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF);
 711        rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
 712        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 713}
 714
 715static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
 716                                   struct ieee80211_conf *conf)
 717{
 718        struct rtl8180_priv *priv = dev->priv;
 719        int chan =
 720                ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
 721
 722        if (priv->rf->init == rtl8225_rf_init)
 723                rtl8225_rf_set_tx_power(dev, chan);
 724        else
 725                rtl8225z2_rf_set_tx_power(dev, chan);
 726
 727        rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
 728        msleep(10);
 729}
 730
 731static const struct rtl818x_rf_ops rtl8225_ops = {
 732        .name           = "rtl8225",
 733        .init           = rtl8225_rf_init,
 734        .stop           = rtl8225_rf_stop,
 735        .set_chan       = rtl8225_rf_set_channel,
 736};
 737
 738static const struct rtl818x_rf_ops rtl8225z2_ops = {
 739        .name           = "rtl8225z2",
 740        .init           = rtl8225z2_rf_init,
 741        .stop           = rtl8225_rf_stop,
 742        .set_chan       = rtl8225_rf_set_channel,
 743};
 744
 745const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
 746{
 747        struct rtl8180_priv *priv = dev->priv;
 748        u16 reg8, reg9;
 749
 750        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
 751        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
 752        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
 753        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 754        msleep(100);
 755
 756        rtl8225_write(dev, 0, 0x1B7);
 757
 758        reg8 = rtl8225_read(dev, 8);
 759        reg9 = rtl8225_read(dev, 9);
 760
 761        rtl8225_write(dev, 0, 0x0B7);
 762
 763        if (reg8 != 0x588 || reg9 != 0x700)
 764                return &rtl8225_ops;
 765
 766        return &rtl8225z2_ops;
 767}
 768