linux/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c
<<
>>
Prefs
   1
   2/*
   3 * Radio tuning for RTL8225 on RTL8180
   4 *
   5 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
   6 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
   7 *
   8 * Based on the r8180 driver, which is:
   9 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
  10 *
  11 * Thanks to Realtek for their support!
  12 *
  13 * This program is free software; you can redistribute it and/or modify
  14 * it under the terms of the GNU General Public License version 2 as
  15 * published by the Free Software Foundation.
  16 */
  17
  18#include <linux/init.h>
  19#include <linux/pci.h>
  20#include <linux/delay.h>
  21#include <net/mac80211.h>
  22
  23#include "rtl8180.h"
  24#include "rtl8180_rtl8225.h"
  25
  26static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
  27{
  28        struct rtl8180_priv *priv = dev->priv;
  29        u16 reg80, reg84, reg82;
  30        u32 bangdata;
  31        int i;
  32
  33        bangdata = (data << 4) | (addr & 0xf);
  34
  35        reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
  36        reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
  37
  38        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
  39
  40        reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
  41        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400);
  42        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  43        udelay(10);
  44
  45        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
  46        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  47        udelay(2);
  48        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
  49        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  50        udelay(10);
  51
  52        for (i = 15; i >= 0; i--) {
  53                u16 reg = reg80 | !!(bangdata & (1 << i));
  54
  55                if (i & 1)
  56                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
  57
  58                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
  59                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
  60
  61                if (!(i & 1))
  62                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
  63        }
  64
  65        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
  66        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  67        udelay(10);
  68
  69        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
  70        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400);
  71        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
  72}
  73
  74static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
  75{
  76        struct rtl8180_priv *priv = dev->priv;
  77        u16 reg80, reg82, reg84, out;
  78        int i;
  79
  80        reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
  81        reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
  82        reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400;
  83
  84        reg80 &= ~0xF;
  85
  86        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
  87        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
  88
  89        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
  90        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  91        udelay(4);
  92        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
  93        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
  94        udelay(5);
  95
  96        for (i = 4; i >= 0; i--) {
  97                u16 reg = reg80 | ((addr >> i) & 1);
  98
  99                if (!(i & 1)) {
 100                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
 101                        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 102                        udelay(1);
 103                }
 104
 105                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 106                                  reg | (1 << 1));
 107                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 108                udelay(2);
 109                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 110                                  reg | (1 << 1));
 111                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 112                udelay(2);
 113
 114                if (i & 1) {
 115                        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
 116                        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 117                        udelay(1);
 118                }
 119        }
 120
 121        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E);
 122        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E);
 123        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 124        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 125                          reg80 | (1 << 3) | (1 << 1));
 126        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 127        udelay(2);
 128        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 129                          reg80 | (1 << 3));
 130        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 131        udelay(2);
 132        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 133                          reg80 | (1 << 3));
 134        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 135        udelay(2);
 136
 137        out = 0;
 138        for (i = 11; i >= 0; i--) {
 139                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 140                                  reg80 | (1 << 3));
 141                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 142                udelay(1);
 143                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 144                                  reg80 | (1 << 3) | (1 << 1));
 145                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 146                udelay(2);
 147                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 148                                  reg80 | (1 << 3) | (1 << 1));
 149                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 150                udelay(2);
 151                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 152                                  reg80 | (1 << 3) | (1 << 1));
 153                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 154                udelay(2);
 155
 156                if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
 157                        out |= 1 << i;
 158
 159                rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 160                                  reg80 | (1 << 3));
 161                rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 162                udelay(2);
 163        }
 164
 165        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
 166                          reg80 | (1 << 3) | (1 << 2));
 167        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 168        udelay(2);
 169
 170        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
 171        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
 172        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
 173
 174        return out;
 175}
 176
 177static const u16 rtl8225bcd_rxgain[] = {
 178        0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
 179        0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
 180        0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
 181        0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
 182        0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
 183        0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
 184        0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
 185        0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
 186        0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
 187        0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
 188        0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
 189        0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
 190};
 191
 192static const u8 rtl8225_agc[] = {
 193        0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
 194        0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
 195        0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
 196        0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
 197        0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
 198        0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
 199        0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
 200        0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
 201        0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
 202        0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
 203        0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
 204        0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
 205        0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
 206        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 207        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 208        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
 209};
 210
 211static const u8 rtl8225_gain[] = {
 212        0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
 213        0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
 214        0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
 215        0x33, 0x80, 0x79, 0xc5, /* -78dbm */
 216        0x43, 0x78, 0x76, 0xc5, /* -74dbm */
 217        0x53, 0x60, 0x73, 0xc5, /* -70dbm */
 218        0x63, 0x58, 0x70, 0xc5, /* -66dbm */
 219};
 220
 221static const u8 rtl8225_threshold[] = {
 222        0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
 223};
 224
 225static const u8 rtl8225_tx_gain_cck_ofdm[] = {
 226        0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
 227};
 228
 229static const u8 rtl8225_tx_power_cck[] = {
 230        0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
 231        0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
 232        0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
 233        0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
 234        0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
 235        0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
 236};
 237
 238static const u8 rtl8225_tx_power_cck_ch14[] = {
 239        0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
 240        0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
 241        0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
 242        0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
 243        0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
 244        0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
 245};
 246
 247static const u8 rtl8225_tx_power_ofdm[] = {
 248        0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
 249};
 250
 251static const u32 rtl8225_chan[] = {
 252        0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
 253        0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
 254};
 255
 256static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
 257{
 258        struct rtl8180_priv *priv = dev->priv;
 259        u8 cck_power, ofdm_power;
 260        const u8 *tmp;
 261        u32 reg;
 262        int i;
 263
 264        cck_power = priv->channels[channel - 1].hw_value & 0xFF;
 265        ofdm_power = priv->channels[channel - 1].hw_value >> 8;
 266
 267        cck_power = min(cck_power, (u8)35);
 268        ofdm_power = min(ofdm_power, (u8)35);
 269
 270        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
 271                         rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
 272
 273        if (channel == 14)
 274                tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
 275        else
 276                tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
 277
 278        for (i = 0; i < 8; i++)
 279                rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
 280
 281        msleep(1); /* FIXME: optional? */
 282
 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 = ieee80211_frequency_to_channel(conf->channel->center_freq);
 720
 721        if (priv->rf->init == rtl8225_rf_init)
 722                rtl8225_rf_set_tx_power(dev, chan);
 723        else
 724                rtl8225z2_rf_set_tx_power(dev, chan);
 725
 726        rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
 727        msleep(10);
 728}
 729
 730static void rtl8225_rf_conf_erp(struct ieee80211_hw *dev,
 731                                struct ieee80211_bss_conf *info)
 732{
 733        struct rtl8180_priv *priv = dev->priv;
 734
 735        if (info->use_short_slot) {
 736                rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
 737                rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
 738                rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
 739                rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
 740                rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
 741        } else {
 742                rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
 743                rtl818x_iowrite8(priv, &priv->map->SIFS, 0x44);
 744                rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
 745                rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
 746                rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
 747        }
 748}
 749
 750static const struct rtl818x_rf_ops rtl8225_ops = {
 751        .name           = "rtl8225",
 752        .init           = rtl8225_rf_init,
 753        .stop           = rtl8225_rf_stop,
 754        .set_chan       = rtl8225_rf_set_channel,
 755        .conf_erp       = rtl8225_rf_conf_erp,
 756};
 757
 758static const struct rtl818x_rf_ops rtl8225z2_ops = {
 759        .name           = "rtl8225z2",
 760        .init           = rtl8225z2_rf_init,
 761        .stop           = rtl8225_rf_stop,
 762        .set_chan       = rtl8225_rf_set_channel,
 763        .conf_erp       = rtl8225_rf_conf_erp,
 764};
 765
 766const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
 767{
 768        struct rtl8180_priv *priv = dev->priv;
 769        u16 reg8, reg9;
 770
 771        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
 772        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
 773        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
 774        rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
 775        msleep(100);
 776
 777        rtl8225_write(dev, 0, 0x1B7);
 778
 779        reg8 = rtl8225_read(dev, 8);
 780        reg9 = rtl8225_read(dev, 9);
 781
 782        rtl8225_write(dev, 0, 0x0B7);
 783
 784        if (reg8 != 0x588 || reg9 != 0x700)
 785                return &rtl8225_ops;
 786
 787        return &rtl8225z2_ops;
 788}
 789