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

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

DEFINITIONS

This source file includes following definitions.
  1. rtl8187se_three_wire_io
  2. rtl8187se_rf_readreg
  3. rtl8187se_rf_writereg
  4. rtl8225se_write_zebra_agc
  5. rtl8187se_write_ofdm_config
  6. rtl8225sez2_rf_set_tx_power
  7. rtl8187se_write_rf_gain
  8. rtl8187se_write_initial_gain
  9. rtl8225se_rf_init
  10. rtl8225se_rf_stop
  11. rtl8225se_rf_set_channel
  12. rtl8187se_detect_rf

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 
   3 /* Radio tuning for RTL8225 on RTL8187SE
   4  *
   5  * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net>
   6  * Copyright 2014 Andrea Merello <andrea.merello@gmail.com>
   7  *
   8  * Based on the r8180 and Realtek r8187se drivers, which are:
   9  * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
  10  *
  11  * Also based on the rtl8187 driver, which is:
  12  * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
  13  * Copyright 2007 Andrea Merello <andrea.merello@gmail.com>
  14  */
  15 
  16 #include <net/mac80211.h>
  17 
  18 #include "rtl8180.h"
  19 #include "rtl8225se.h"
  20 
  21 #define PFX "rtl8225 (se) "
  22 
  23 static const u32 RF_GAIN_TABLE[] = {
  24         0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6,
  25         0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057,
  26         0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3,
  27         0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3,
  28         0x0183, 0x0163, 0x0143, 0x0123, 0x0103
  29 };
  30 
  31 static const u8 cck_ofdm_gain_settings[] = {
  32         0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
  33         0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
  34         0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
  35         0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  36         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
  37         0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
  38 };
  39 
  40 static const u8 rtl8225se_tx_gain_cck_ofdm[] = {
  41         0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
  42 };
  43 
  44 static const u8 rtl8225se_tx_power_cck[] = {
  45         0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
  46         0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
  47         0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
  48         0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
  49         0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
  50         0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
  51 };
  52 
  53 static const u8 rtl8225se_tx_power_cck_ch14[] = {
  54         0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
  55         0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
  56         0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
  57         0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
  58         0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
  59         0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
  60 };
  61 
  62 static const u8 rtl8225se_tx_power_ofdm[] = {
  63         0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
  64 };
  65 
  66 static const u32 rtl8225se_chan[] = {
  67         0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380,
  68         0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A,
  69 };
  70 
  71 static const u8 rtl8225sez2_tx_power_cck_ch14[] = {
  72         0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
  73 };
  74 
  75 static const u8 rtl8225sez2_tx_power_cck_B[] = {
  76         0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04
  77 };
  78 
  79 static const u8 rtl8225sez2_tx_power_cck_A[] = {
  80         0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04
  81 };
  82 
  83 static const u8 rtl8225sez2_tx_power_cck[] = {
  84         0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
  85 };
  86 
  87 static const u8 ZEBRA_AGC[] = {
  88         0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A,
  89         0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72,
  90         0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A,
  91         0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62,
  92         0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27,
  93         0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07,
  94         0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00,
  95         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  96         0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
  97         0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16,
  98         0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b,
  99         0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e,
 100         0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21,
 101         0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24,
 102         0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
 103         0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F
 104 };
 105 
 106 static const u8 OFDM_CONFIG[] = {
 107         0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50,
 108         0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00,
 109         0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26,
 110         0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB,
 111         0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00,
 112         0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00,
 113         0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
 114         0xD8, 0x3C, 0x7B, 0x10, 0x10
 115 };
 116 
 117 static void rtl8187se_three_wire_io(struct ieee80211_hw *dev, u8 *data,
 118                                     u8 len, bool write)
 119 {
 120         struct rtl8180_priv *priv = dev->priv;
 121         int i;
 122         u8 tmp;
 123 
 124         do {
 125                 for (i = 0; i < 5; i++) {
 126                         tmp = rtl818x_ioread8(priv, SW_3W_CMD1);
 127                         if (!(tmp & 0x3))
 128                                 break;
 129                         udelay(10);
 130                 }
 131                 if (i == 5)
 132                         wiphy_err(dev->wiphy, PFX
 133                                 "CmdReg: 0x%x RE/WE bits aren't clear\n", tmp);
 134 
 135                 tmp = rtl818x_ioread8(priv, &priv->map->rf_sw_config) | 0x02;
 136                 rtl818x_iowrite8(priv, &priv->map->rf_sw_config, tmp);
 137 
 138                 tmp = rtl818x_ioread8(priv, REG_ADDR1(0x84)) & 0xF7;
 139                 rtl818x_iowrite8(priv, REG_ADDR1(0x84), tmp);
 140                 if (write) {
 141                         if (len == 16) {
 142                                 rtl818x_iowrite16(priv, SW_3W_DB0,
 143                                   *(u16 *)data);
 144                         } else if (len == 64) {
 145                                 rtl818x_iowrite32(priv, SW_3W_DB0_4,
 146                                   *((u32 *)data));
 147                                 rtl818x_iowrite32(priv, SW_3W_DB1_4,
 148                                   *((u32 *)(data + 4)));
 149                         } else
 150                                 wiphy_err(dev->wiphy, PFX
 151                                         "Unimplemented length\n");
 152                 } else {
 153                         rtl818x_iowrite16(priv, SW_3W_DB0, *(u16 *)data);
 154                 }
 155                 if (write)
 156                         tmp = 2;
 157                 else
 158                         tmp = 1;
 159                 rtl818x_iowrite8(priv, SW_3W_CMD1, tmp);
 160                 for (i = 0; i < 5; i++) {
 161                         tmp = rtl818x_ioread8(priv, SW_3W_CMD1);
 162                         if (!(tmp & 0x3))
 163                                 break;
 164                         udelay(10);
 165                 }
 166                 rtl818x_iowrite8(priv, SW_3W_CMD1, 0);
 167                 if (!write) {
 168                         *((u16 *)data) = rtl818x_ioread16(priv, SI_DATA_REG);
 169                         *((u16 *)data) &= 0x0FFF;
 170                 }
 171         } while (0);
 172 }
 173 
 174 static u32 rtl8187se_rf_readreg(struct ieee80211_hw *dev, u8 addr)
 175 {
 176         u32 dataread = addr & 0x0F;
 177         rtl8187se_three_wire_io(dev, (u8 *)&dataread, 16, 0);
 178         return dataread;
 179 }
 180 
 181 static void rtl8187se_rf_writereg(struct ieee80211_hw *dev, u8 addr, u32 data)
 182 {
 183         u32 outdata = (data << 4) | (u32)(addr & 0x0F);
 184         rtl8187se_three_wire_io(dev, (u8 *)&outdata, 16, 1);
 185 }
 186 
 187 
 188 static void rtl8225se_write_zebra_agc(struct ieee80211_hw *dev)
 189 {
 190         int i;
 191 
 192         for (i = 0; i < 128; i++) {
 193                 rtl8225se_write_phy_ofdm(dev, 0xF, ZEBRA_AGC[i]);
 194                 rtl8225se_write_phy_ofdm(dev, 0xE, i+0x80);
 195                 rtl8225se_write_phy_ofdm(dev, 0xE, 0);
 196         }
 197 }
 198 
 199 static void rtl8187se_write_ofdm_config(struct ieee80211_hw *dev)
 200 {
 201         /* write OFDM_CONFIG table */
 202         int i;
 203 
 204         for (i = 0; i < 60; i++)
 205                 rtl8225se_write_phy_ofdm(dev, i, OFDM_CONFIG[i]);
 206 
 207 }
 208 
 209 static void rtl8225sez2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
 210 {
 211         struct rtl8180_priv *priv = dev->priv;
 212         u8 cck_power, ofdm_power;
 213 
 214         cck_power = priv->channels[channel - 1].hw_value & 0xFF;
 215         if (cck_power > 35)
 216                 cck_power = 35;
 217         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
 218                          cck_ofdm_gain_settings[cck_power]);
 219 
 220         usleep_range(1000, 5000);
 221         ofdm_power = priv->channels[channel - 1].hw_value >> 8;
 222         if (ofdm_power > 35)
 223                 ofdm_power = 35;
 224 
 225         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
 226                          cck_ofdm_gain_settings[ofdm_power]);
 227         if (ofdm_power < 12) {
 228                 rtl8225se_write_phy_ofdm(dev, 7, 0x5C);
 229                 rtl8225se_write_phy_ofdm(dev, 9, 0x5C);
 230         }
 231         if (ofdm_power < 18) {
 232                 rtl8225se_write_phy_ofdm(dev, 7, 0x54);
 233                 rtl8225se_write_phy_ofdm(dev, 9, 0x54);
 234         } else {
 235                 rtl8225se_write_phy_ofdm(dev, 7, 0x50);
 236                 rtl8225se_write_phy_ofdm(dev, 9, 0x50);
 237         }
 238 
 239         usleep_range(1000, 5000);
 240 }
 241 
 242 static void rtl8187se_write_rf_gain(struct ieee80211_hw *dev)
 243 {
 244         int i;
 245 
 246         for (i = 0; i <= 36; i++) {
 247                 rtl8187se_rf_writereg(dev, 0x01, i); mdelay(1);
 248                 rtl8187se_rf_writereg(dev, 0x02, RF_GAIN_TABLE[i]); mdelay(1);
 249         }
 250 }
 251 
 252 static void rtl8187se_write_initial_gain(struct ieee80211_hw *dev,
 253                                         int init_gain)
 254 {
 255         switch (init_gain) {
 256         default:
 257                 rtl8225se_write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
 258                 rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
 259                 rtl8225se_write_phy_ofdm(dev, 0x05, 0xFA); mdelay(1);
 260                 break;
 261         case 2:
 262                 rtl8225se_write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
 263                 rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
 264                 rtl8225se_write_phy_ofdm(dev, 0x05, 0xFA); mdelay(1);
 265                 break;
 266         case 3:
 267                 rtl8225se_write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
 268                 rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
 269                 rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1);
 270                 break;
 271         case 4:
 272                 rtl8225se_write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
 273                 rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
 274                 rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1);
 275                 break;
 276         case 5:
 277                 rtl8225se_write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
 278                 rtl8225se_write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
 279                 rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1);
 280                 break;
 281         case 6:
 282                 rtl8225se_write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
 283                 rtl8225se_write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
 284                 rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1);
 285                 break;
 286         case 7:
 287                 rtl8225se_write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
 288                 rtl8225se_write_phy_ofdm(dev, 0x24, 0xA6); mdelay(1);
 289                 rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1);
 290                 break;
 291         case 8:
 292                 rtl8225se_write_phy_ofdm(dev, 0x17, 0x66); mdelay(1);
 293                 rtl8225se_write_phy_ofdm(dev, 0x24, 0xB6); mdelay(1);
 294                 rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1);
 295                 break;
 296         }
 297 }
 298 
 299 void rtl8225se_rf_init(struct ieee80211_hw *dev)
 300 {
 301         struct rtl8180_priv *priv = dev->priv;
 302         u32 rf23, rf24;
 303         u8 d_cut = 0;
 304         u8 tmp;
 305 
 306         /* Page 1 */
 307         rtl8187se_rf_writereg(dev, 0x00, 0x013F); mdelay(1);
 308         rf23 = rtl8187se_rf_readreg(dev, 0x08); mdelay(1);
 309         rf24 = rtl8187se_rf_readreg(dev, 0x09); mdelay(1);
 310         if (rf23 == 0x0818 && rf24 == 0x070C)
 311                 d_cut = 1;
 312 
 313         wiphy_info(dev->wiphy, "RTL8225-SE version %s\n",
 314                 d_cut ? "D" : "not-D");
 315 
 316         /* Page 0: reg 0 - 15 */
 317         rtl8187se_rf_writereg(dev, 0x00, 0x009F); mdelay(1);
 318         rtl8187se_rf_writereg(dev, 0x01, 0x06E0); mdelay(1);
 319         rtl8187se_rf_writereg(dev, 0x02, 0x004D); mdelay(1);
 320         rtl8187se_rf_writereg(dev, 0x03, 0x07F1); mdelay(1);
 321         rtl8187se_rf_writereg(dev, 0x04, 0x0975); mdelay(1);
 322         rtl8187se_rf_writereg(dev, 0x05, 0x0C72); mdelay(1);
 323         rtl8187se_rf_writereg(dev, 0x06, 0x0AE6); mdelay(1);
 324         rtl8187se_rf_writereg(dev, 0x07, 0x00CA); mdelay(1);
 325         rtl8187se_rf_writereg(dev, 0x08, 0x0E1C); mdelay(1);
 326         rtl8187se_rf_writereg(dev, 0x09, 0x02F0); mdelay(1);
 327         rtl8187se_rf_writereg(dev, 0x0A, 0x09D0); mdelay(1);
 328         rtl8187se_rf_writereg(dev, 0x0B, 0x01BA); mdelay(1);
 329         rtl8187se_rf_writereg(dev, 0x0C, 0x0640); mdelay(1);
 330         rtl8187se_rf_writereg(dev, 0x0D, 0x08DF); mdelay(1);
 331         rtl8187se_rf_writereg(dev, 0x0E, 0x0020); mdelay(1);
 332         rtl8187se_rf_writereg(dev, 0x0F, 0x0990); mdelay(1);
 333         /* page 1: reg 16-30 */
 334         rtl8187se_rf_writereg(dev, 0x00, 0x013F); mdelay(1);
 335         rtl8187se_rf_writereg(dev, 0x03, 0x0806); mdelay(1);
 336         rtl8187se_rf_writereg(dev, 0x04, 0x03A7); mdelay(1);
 337         rtl8187se_rf_writereg(dev, 0x05, 0x059B); mdelay(1);
 338         rtl8187se_rf_writereg(dev, 0x06, 0x0081); mdelay(1);
 339         rtl8187se_rf_writereg(dev, 0x07, 0x01A0); mdelay(1);
 340         rtl8187se_rf_writereg(dev, 0x0A, 0x0001); mdelay(1);
 341         rtl8187se_rf_writereg(dev, 0x0B, 0x0418); mdelay(1);
 342         rtl8187se_rf_writereg(dev, 0x0C, 0x0FBE); mdelay(1);
 343         rtl8187se_rf_writereg(dev, 0x0D, 0x0008); mdelay(1);
 344         if (d_cut)
 345                 rtl8187se_rf_writereg(dev, 0x0E, 0x0807);
 346         else
 347                 rtl8187se_rf_writereg(dev, 0x0E, 0x0806);
 348         mdelay(1);
 349         rtl8187se_rf_writereg(dev, 0x0F, 0x0ACC); mdelay(1);
 350         rtl8187se_rf_writereg(dev, 0x00, 0x01D7); mdelay(1);
 351         rtl8187se_rf_writereg(dev, 0x03, 0x0E00); mdelay(1);
 352         rtl8187se_rf_writereg(dev, 0x04, 0x0E50); mdelay(1);
 353 
 354         rtl8187se_write_rf_gain(dev);
 355 
 356         rtl8187se_rf_writereg(dev, 0x05, 0x0203); mdelay(1);
 357         rtl8187se_rf_writereg(dev, 0x06, 0x0200); mdelay(1);
 358         rtl8187se_rf_writereg(dev, 0x00, 0x0137); mdelay(11);
 359         rtl8187se_rf_writereg(dev, 0x0D, 0x0008); mdelay(11);
 360         rtl8187se_rf_writereg(dev, 0x00, 0x0037); mdelay(11);
 361         rtl8187se_rf_writereg(dev, 0x04, 0x0160); mdelay(11);
 362         rtl8187se_rf_writereg(dev, 0x07, 0x0080); mdelay(11);
 363         rtl8187se_rf_writereg(dev, 0x02, 0x088D); msleep(221);
 364         rtl8187se_rf_writereg(dev, 0x00, 0x0137); mdelay(11);
 365         rtl8187se_rf_writereg(dev, 0x07, 0x0000); mdelay(1);
 366         rtl8187se_rf_writereg(dev, 0x07, 0x0180); mdelay(1);
 367         rtl8187se_rf_writereg(dev, 0x07, 0x0220); mdelay(1);
 368         rtl8187se_rf_writereg(dev, 0x07, 0x03E0); mdelay(1);
 369         rtl8187se_rf_writereg(dev, 0x06, 0x00C1); mdelay(1);
 370         rtl8187se_rf_writereg(dev, 0x0A, 0x0001); mdelay(1);
 371         if (priv->xtal_cal) {
 372                 tmp = (priv->xtal_in << 4) | (priv->xtal_out << 1) |
 373                       (1 << 11) | (1 << 9);
 374                 rtl8187se_rf_writereg(dev, 0x0F, tmp);
 375                 wiphy_info(dev->wiphy, "Xtal cal\n");
 376                 mdelay(1);
 377         } else {
 378                 wiphy_info(dev->wiphy, "NO Xtal cal\n");
 379                 rtl8187se_rf_writereg(dev, 0x0F, 0x0ACC);
 380                 mdelay(1);
 381         }
 382         /* page 0 */
 383         rtl8187se_rf_writereg(dev, 0x00, 0x00BF); mdelay(1);
 384         rtl8187se_rf_writereg(dev, 0x0D, 0x08DF); mdelay(1);
 385         rtl8187se_rf_writereg(dev, 0x02, 0x004D); mdelay(1);
 386         rtl8187se_rf_writereg(dev, 0x04, 0x0975); msleep(31);
 387         rtl8187se_rf_writereg(dev, 0x00, 0x0197); mdelay(1);
 388         rtl8187se_rf_writereg(dev, 0x05, 0x05AB); mdelay(1);
 389 
 390         rtl8187se_rf_writereg(dev, 0x00, 0x009F); mdelay(1);
 391         rtl8187se_rf_writereg(dev, 0x01, 0x0000); mdelay(1);
 392         rtl8187se_rf_writereg(dev, 0x02, 0x0000); mdelay(1);
 393         /* power save parameters */
 394         /* TODO: move to dev.c */
 395         rtl818x_iowrite8(priv, REG_ADDR1(0x024E),
 396                  rtl818x_ioread8(priv, REG_ADDR1(0x24E)) & 0x9F);
 397         rtl8225se_write_phy_cck(dev, 0x00, 0xC8);
 398         rtl8225se_write_phy_cck(dev, 0x06, 0x1C);
 399         rtl8225se_write_phy_cck(dev, 0x10, 0x78);
 400         rtl8225se_write_phy_cck(dev, 0x2E, 0xD0);
 401         rtl8225se_write_phy_cck(dev, 0x2F, 0x06);
 402         rtl8225se_write_phy_cck(dev, 0x01, 0x46);
 403 
 404         /* power control */
 405         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x10);
 406         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x1B);
 407 
 408         rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
 409         rtl8225se_write_phy_ofdm(dev, 0x00, 0x12);
 410 
 411         rtl8225se_write_zebra_agc(dev);
 412 
 413         rtl8225se_write_phy_ofdm(dev, 0x10, 0x00);
 414 
 415         rtl8187se_write_ofdm_config(dev);
 416 
 417         /* turn on RF */
 418         rtl8187se_rf_writereg(dev, 0x00, 0x009F); udelay(500);
 419         rtl8187se_rf_writereg(dev, 0x04, 0x0972); udelay(500);
 420         /* turn on RF again */
 421         rtl8187se_rf_writereg(dev, 0x00, 0x009F); udelay(500);
 422         rtl8187se_rf_writereg(dev, 0x04, 0x0972); udelay(500);
 423         /* turn on BB */
 424         rtl8225se_write_phy_ofdm(dev, 0x10, 0x40);
 425         rtl8225se_write_phy_ofdm(dev, 0x12, 0x40);
 426 
 427         rtl8187se_write_initial_gain(dev, 4);
 428 }
 429 
 430 void rtl8225se_rf_stop(struct ieee80211_hw *dev)
 431 {
 432         /* checked for 8187se */
 433         struct rtl8180_priv *priv = dev->priv;
 434 
 435         /* turn off BB RXIQ matrix to cut off rx signal */
 436         rtl8225se_write_phy_ofdm(dev, 0x10, 0x00);
 437         rtl8225se_write_phy_ofdm(dev, 0x12, 0x00);
 438         /* turn off RF */
 439         rtl8187se_rf_writereg(dev, 0x04, 0x0000);
 440         rtl8187se_rf_writereg(dev, 0x00, 0x0000);
 441 
 442         usleep_range(1000, 5000);
 443         /* turn off A/D and D/A */
 444         rtl8180_set_anaparam(priv, RTL8225SE_ANAPARAM_OFF);
 445         rtl8180_set_anaparam2(priv, RTL8225SE_ANAPARAM2_OFF);
 446 }
 447 
 448 void rtl8225se_rf_set_channel(struct ieee80211_hw *dev,
 449                                    struct ieee80211_conf *conf)
 450 {
 451         int chan =
 452                 ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
 453 
 454         rtl8225sez2_rf_set_tx_power(dev, chan);
 455         rtl8187se_rf_writereg(dev, 0x7, rtl8225se_chan[chan - 1]);
 456         if ((rtl8187se_rf_readreg(dev, 0x7) & 0x0F80) !=
 457                 rtl8225se_chan[chan - 1])
 458                 rtl8187se_rf_writereg(dev, 0x7, rtl8225se_chan[chan - 1]);
 459         usleep_range(10000, 20000);
 460 }
 461 
 462 static const struct rtl818x_rf_ops rtl8225se_ops = {
 463         .name           = "rtl8225-se",
 464         .init           = rtl8225se_rf_init,
 465         .stop           = rtl8225se_rf_stop,
 466         .set_chan       = rtl8225se_rf_set_channel,
 467 };
 468 
 469 const struct rtl818x_rf_ops *rtl8187se_detect_rf(struct ieee80211_hw *dev)
 470 {
 471         return &rtl8225se_ops;
 472 }

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