rtl8225.c (32342B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Radio tuning for RTL8225 on RTL8187 4 * 5 * Copyright 2007 Michael Wu <flamingice@sourmilk.net> 6 * Copyright 2007 Andrea Merello <andrea.merello@gmail.com> 7 * 8 * Based on the r8187 driver, which is: 9 * Copyright 2005 Andrea Merello <andrea.merello@gmail.com>, et al. 10 * 11 * Magic delays, register offsets, and phy value tables below are 12 * taken from the original r8187 driver sources. Thanks to Realtek 13 * for their support! 14 */ 15 16#include <linux/usb.h> 17#include <net/mac80211.h> 18 19#include "rtl8187.h" 20#include "rtl8225.h" 21 22u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv, 23 u8 *addr, u8 idx) 24{ 25 u8 val; 26 27 mutex_lock(&priv->io_mutex); 28 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), 29 RTL8187_REQ_GET_REG, RTL8187_REQT_READ, 30 (unsigned long)addr, idx & 0x03, 31 &priv->io_dmabuf->bits8, sizeof(val), 500); 32 33 val = priv->io_dmabuf->bits8; 34 mutex_unlock(&priv->io_mutex); 35 36 return val; 37} 38 39u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv, 40 __le16 *addr, u8 idx) 41{ 42 __le16 val; 43 44 mutex_lock(&priv->io_mutex); 45 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), 46 RTL8187_REQ_GET_REG, RTL8187_REQT_READ, 47 (unsigned long)addr, idx & 0x03, 48 &priv->io_dmabuf->bits16, sizeof(val), 500); 49 50 val = priv->io_dmabuf->bits16; 51 mutex_unlock(&priv->io_mutex); 52 53 return le16_to_cpu(val); 54} 55 56u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv, 57 __le32 *addr, u8 idx) 58{ 59 __le32 val; 60 61 mutex_lock(&priv->io_mutex); 62 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), 63 RTL8187_REQ_GET_REG, RTL8187_REQT_READ, 64 (unsigned long)addr, idx & 0x03, 65 &priv->io_dmabuf->bits32, sizeof(val), 500); 66 67 val = priv->io_dmabuf->bits32; 68 mutex_unlock(&priv->io_mutex); 69 70 return le32_to_cpu(val); 71} 72 73void rtl818x_iowrite8_idx(struct rtl8187_priv *priv, 74 u8 *addr, u8 val, u8 idx) 75{ 76 mutex_lock(&priv->io_mutex); 77 78 priv->io_dmabuf->bits8 = val; 79 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), 80 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, 81 (unsigned long)addr, idx & 0x03, 82 &priv->io_dmabuf->bits8, sizeof(val), 500); 83 84 mutex_unlock(&priv->io_mutex); 85} 86 87void rtl818x_iowrite16_idx(struct rtl8187_priv *priv, 88 __le16 *addr, u16 val, u8 idx) 89{ 90 mutex_lock(&priv->io_mutex); 91 92 priv->io_dmabuf->bits16 = cpu_to_le16(val); 93 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), 94 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, 95 (unsigned long)addr, idx & 0x03, 96 &priv->io_dmabuf->bits16, sizeof(val), 500); 97 98 mutex_unlock(&priv->io_mutex); 99} 100 101void rtl818x_iowrite32_idx(struct rtl8187_priv *priv, 102 __le32 *addr, u32 val, u8 idx) 103{ 104 mutex_lock(&priv->io_mutex); 105 106 priv->io_dmabuf->bits32 = cpu_to_le32(val); 107 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), 108 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, 109 (unsigned long)addr, idx & 0x03, 110 &priv->io_dmabuf->bits32, sizeof(val), 500); 111 112 mutex_unlock(&priv->io_mutex); 113} 114 115static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data) 116{ 117 struct rtl8187_priv *priv = dev->priv; 118 u16 reg80, reg84, reg82; 119 u32 bangdata; 120 int i; 121 122 bangdata = (data << 4) | (addr & 0xf); 123 124 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3; 125 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); 126 127 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7); 128 129 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); 130 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7); 131 udelay(10); 132 133 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 134 udelay(2); 135 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); 136 udelay(10); 137 138 for (i = 15; i >= 0; i--) { 139 u16 reg = reg80 | (bangdata & (1 << i)) >> i; 140 141 if (i & 1) 142 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 143 144 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); 145 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); 146 147 if (!(i & 1)) 148 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 149 } 150 151 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 152 udelay(10); 153 154 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 155 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); 156} 157 158static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data) 159{ 160 struct rtl8187_priv *priv = dev->priv; 161 u16 reg80, reg82, reg84; 162 163 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); 164 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); 165 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); 166 167 reg80 &= ~(0x3 << 2); 168 reg84 &= ~0xF; 169 170 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x0007); 171 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x0007); 172 udelay(10); 173 174 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 175 udelay(2); 176 177 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); 178 udelay(10); 179 180 mutex_lock(&priv->io_mutex); 181 182 priv->io_dmabuf->bits16 = data; 183 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), 184 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, 185 addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data), 186 500); 187 188 mutex_unlock(&priv->io_mutex); 189 190 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 191 udelay(10); 192 193 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 194 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); 195} 196 197static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) 198{ 199 struct rtl8187_priv *priv = dev->priv; 200 201 if (priv->asic_rev) 202 rtl8225_write_8051(dev, addr, cpu_to_le16(data)); 203 else 204 rtl8225_write_bitbang(dev, addr, data); 205} 206 207static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) 208{ 209 struct rtl8187_priv *priv = dev->priv; 210 u16 reg80, reg82, reg84, out; 211 int i; 212 213 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); 214 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); 215 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); 216 217 reg80 &= ~0xF; 218 219 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F); 220 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F); 221 222 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 223 udelay(4); 224 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); 225 udelay(5); 226 227 for (i = 4; i >= 0; i--) { 228 u16 reg = reg80 | ((addr >> i) & 1); 229 230 if (!(i & 1)) { 231 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 232 udelay(1); 233 } 234 235 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 236 reg | (1 << 1)); 237 udelay(2); 238 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 239 reg | (1 << 1)); 240 udelay(2); 241 242 if (i & 1) { 243 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 244 udelay(1); 245 } 246 } 247 248 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 249 reg80 | (1 << 3) | (1 << 1)); 250 udelay(2); 251 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 252 reg80 | (1 << 3)); 253 udelay(2); 254 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 255 reg80 | (1 << 3)); 256 udelay(2); 257 258 out = 0; 259 for (i = 11; i >= 0; i--) { 260 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 261 reg80 | (1 << 3)); 262 udelay(1); 263 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 264 reg80 | (1 << 3) | (1 << 1)); 265 udelay(2); 266 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 267 reg80 | (1 << 3) | (1 << 1)); 268 udelay(2); 269 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 270 reg80 | (1 << 3) | (1 << 1)); 271 udelay(2); 272 273 if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1)) 274 out |= 1 << i; 275 276 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 277 reg80 | (1 << 3)); 278 udelay(2); 279 } 280 281 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 282 reg80 | (1 << 3) | (1 << 2)); 283 udelay(2); 284 285 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82); 286 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); 287 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0); 288 289 return out; 290} 291 292static const u16 rtl8225bcd_rxgain[] = { 293 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, 294 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, 295 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, 296 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, 297 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, 298 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, 299 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, 300 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, 301 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, 302 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, 303 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, 304 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb 305}; 306 307static const u8 rtl8225_agc[] = { 308 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 309 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, 310 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, 311 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 312 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 313 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, 314 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, 315 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 316 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 317 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 318 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 319 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 320 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 321 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 322 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 323 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 324}; 325 326static const u8 rtl8225_gain[] = { 327 0x23, 0x88, 0x7c, 0xa5, /* -82dBm */ 328 0x23, 0x88, 0x7c, 0xb5, /* -82dBm */ 329 0x23, 0x88, 0x7c, 0xc5, /* -82dBm */ 330 0x33, 0x80, 0x79, 0xc5, /* -78dBm */ 331 0x43, 0x78, 0x76, 0xc5, /* -74dBm */ 332 0x53, 0x60, 0x73, 0xc5, /* -70dBm */ 333 0x63, 0x58, 0x70, 0xc5, /* -66dBm */ 334}; 335 336static const u8 rtl8225_threshold[] = { 337 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd 338}; 339 340static const u8 rtl8225_tx_gain_cck_ofdm[] = { 341 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e 342}; 343 344static const u8 rtl8225_tx_power_cck[] = { 345 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, 346 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, 347 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, 348 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, 349 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, 350 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 351}; 352 353static const u8 rtl8225_tx_power_cck_ch14[] = { 354 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, 355 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, 356 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, 357 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, 358 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 359 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 360}; 361 362static const u8 rtl8225_tx_power_ofdm[] = { 363 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 364}; 365 366static const u32 rtl8225_chan[] = { 367 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c, 368 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72 369}; 370 371static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) 372{ 373 struct rtl8187_priv *priv = dev->priv; 374 u8 cck_power, ofdm_power; 375 const u8 *tmp; 376 u32 reg; 377 int i; 378 379 cck_power = priv->channels[channel - 1].hw_value & 0xF; 380 ofdm_power = priv->channels[channel - 1].hw_value >> 4; 381 382 cck_power = min(cck_power, (u8)11); 383 if (ofdm_power > (u8)15) 384 ofdm_power = 25; 385 else 386 ofdm_power += 10; 387 388 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 389 rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); 390 391 if (channel == 14) 392 tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8]; 393 else 394 tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8]; 395 396 for (i = 0; i < 8; i++) 397 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); 398 399 msleep(1); // FIXME: optional? 400 401 /* anaparam2 on */ 402 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 403 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 404 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 405 reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 406 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, 407 RTL8187_RTL8225_ANAPARAM2_ON); 408 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 409 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 410 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 411 412 rtl8225_write_phy_ofdm(dev, 2, 0x42); 413 rtl8225_write_phy_ofdm(dev, 6, 0x00); 414 rtl8225_write_phy_ofdm(dev, 8, 0x00); 415 416 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 417 rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1); 418 419 tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6]; 420 421 rtl8225_write_phy_ofdm(dev, 5, *tmp); 422 rtl8225_write_phy_ofdm(dev, 7, *tmp); 423 424 msleep(1); 425} 426 427static void rtl8225_rf_init(struct ieee80211_hw *dev) 428{ 429 struct rtl8187_priv *priv = dev->priv; 430 int i; 431 432 rtl8225_write(dev, 0x0, 0x067); 433 rtl8225_write(dev, 0x1, 0xFE0); 434 rtl8225_write(dev, 0x2, 0x44D); 435 rtl8225_write(dev, 0x3, 0x441); 436 rtl8225_write(dev, 0x4, 0x486); 437 rtl8225_write(dev, 0x5, 0xBC0); 438 rtl8225_write(dev, 0x6, 0xAE6); 439 rtl8225_write(dev, 0x7, 0x82A); 440 rtl8225_write(dev, 0x8, 0x01F); 441 rtl8225_write(dev, 0x9, 0x334); 442 rtl8225_write(dev, 0xA, 0xFD4); 443 rtl8225_write(dev, 0xB, 0x391); 444 rtl8225_write(dev, 0xC, 0x050); 445 rtl8225_write(dev, 0xD, 0x6DB); 446 rtl8225_write(dev, 0xE, 0x029); 447 rtl8225_write(dev, 0xF, 0x914); msleep(100); 448 449 rtl8225_write(dev, 0x2, 0xC4D); msleep(200); 450 rtl8225_write(dev, 0x2, 0x44D); msleep(200); 451 452 if (!(rtl8225_read(dev, 6) & (1 << 7))) { 453 rtl8225_write(dev, 0x02, 0x0c4d); 454 msleep(200); 455 rtl8225_write(dev, 0x02, 0x044d); 456 msleep(100); 457 if (!(rtl8225_read(dev, 6) & (1 << 7))) 458 wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", 459 rtl8225_read(dev, 6)); 460 } 461 462 rtl8225_write(dev, 0x0, 0x127); 463 464 for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) { 465 rtl8225_write(dev, 0x1, i + 1); 466 rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]); 467 } 468 469 rtl8225_write(dev, 0x0, 0x027); 470 rtl8225_write(dev, 0x0, 0x22F); 471 472 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { 473 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); 474 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); 475 } 476 477 msleep(1); 478 479 rtl8225_write_phy_ofdm(dev, 0x00, 0x01); 480 rtl8225_write_phy_ofdm(dev, 0x01, 0x02); 481 rtl8225_write_phy_ofdm(dev, 0x02, 0x42); 482 rtl8225_write_phy_ofdm(dev, 0x03, 0x00); 483 rtl8225_write_phy_ofdm(dev, 0x04, 0x00); 484 rtl8225_write_phy_ofdm(dev, 0x05, 0x00); 485 rtl8225_write_phy_ofdm(dev, 0x06, 0x40); 486 rtl8225_write_phy_ofdm(dev, 0x07, 0x00); 487 rtl8225_write_phy_ofdm(dev, 0x08, 0x40); 488 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); 489 rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); 490 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); 491 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); 492 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); 493 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); 494 rtl8225_write_phy_ofdm(dev, 0x10, 0x84); 495 rtl8225_write_phy_ofdm(dev, 0x11, 0x06); 496 rtl8225_write_phy_ofdm(dev, 0x12, 0x20); 497 rtl8225_write_phy_ofdm(dev, 0x13, 0x20); 498 rtl8225_write_phy_ofdm(dev, 0x14, 0x00); 499 rtl8225_write_phy_ofdm(dev, 0x15, 0x40); 500 rtl8225_write_phy_ofdm(dev, 0x16, 0x00); 501 rtl8225_write_phy_ofdm(dev, 0x17, 0x40); 502 rtl8225_write_phy_ofdm(dev, 0x18, 0xef); 503 rtl8225_write_phy_ofdm(dev, 0x19, 0x19); 504 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); 505 rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); 506 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); 507 rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); 508 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); 509 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); 510 rtl8225_write_phy_ofdm(dev, 0x21, 0x27); 511 rtl8225_write_phy_ofdm(dev, 0x22, 0x16); 512 rtl8225_write_phy_ofdm(dev, 0x24, 0x46); 513 rtl8225_write_phy_ofdm(dev, 0x25, 0x20); 514 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); 515 rtl8225_write_phy_ofdm(dev, 0x27, 0x88); 516 517 rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]); 518 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]); 519 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]); 520 rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]); 521 522 rtl8225_write_phy_cck(dev, 0x00, 0x98); 523 rtl8225_write_phy_cck(dev, 0x03, 0x20); 524 rtl8225_write_phy_cck(dev, 0x04, 0x7e); 525 rtl8225_write_phy_cck(dev, 0x05, 0x12); 526 rtl8225_write_phy_cck(dev, 0x06, 0xfc); 527 rtl8225_write_phy_cck(dev, 0x07, 0x78); 528 rtl8225_write_phy_cck(dev, 0x08, 0x2e); 529 rtl8225_write_phy_cck(dev, 0x10, 0x9b); 530 rtl8225_write_phy_cck(dev, 0x11, 0x88); 531 rtl8225_write_phy_cck(dev, 0x12, 0x47); 532 rtl8225_write_phy_cck(dev, 0x13, 0xd0); 533 rtl8225_write_phy_cck(dev, 0x19, 0x00); 534 rtl8225_write_phy_cck(dev, 0x1a, 0xa0); 535 rtl8225_write_phy_cck(dev, 0x1b, 0x08); 536 rtl8225_write_phy_cck(dev, 0x40, 0x86); 537 rtl8225_write_phy_cck(dev, 0x41, 0x8d); 538 rtl8225_write_phy_cck(dev, 0x42, 0x15); 539 rtl8225_write_phy_cck(dev, 0x43, 0x18); 540 rtl8225_write_phy_cck(dev, 0x44, 0x1f); 541 rtl8225_write_phy_cck(dev, 0x45, 0x1e); 542 rtl8225_write_phy_cck(dev, 0x46, 0x1a); 543 rtl8225_write_phy_cck(dev, 0x47, 0x15); 544 rtl8225_write_phy_cck(dev, 0x48, 0x10); 545 rtl8225_write_phy_cck(dev, 0x49, 0x0a); 546 rtl8225_write_phy_cck(dev, 0x4a, 0x05); 547 rtl8225_write_phy_cck(dev, 0x4b, 0x02); 548 rtl8225_write_phy_cck(dev, 0x4c, 0x05); 549 550 rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); 551 552 rtl8225_rf_set_tx_power(dev, 1); 553 554 /* RX antenna default to A */ 555 rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */ 556 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */ 557 558 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ 559 msleep(1); 560 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); 561 562 /* set sensitivity */ 563 rtl8225_write(dev, 0x0c, 0x50); 564 rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]); 565 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]); 566 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]); 567 rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]); 568 rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]); 569} 570 571static const u8 rtl8225z2_agc[] = { 572 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51, 0x4f, 573 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37, 574 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f, 575 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07, 576 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 577 0x01, 0x01, 0x01, 0x01, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 578 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 579 0x28, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, 580 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 581 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 582 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 583}; 584static const u8 rtl8225z2_ofdm[] = { 585 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60, 586 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 587 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26, 588 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3, 589 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f, 590 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00, 591 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e, 592 0x6d, 0x3c, 0xfb, 0x07 593}; 594 595static const u8 rtl8225z2_tx_power_cck_ch14[] = { 596 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00, 597 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, 598 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00, 599 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00 600}; 601 602static const u8 rtl8225z2_tx_power_cck[] = { 603 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04, 604 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03, 605 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03, 606 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03 607}; 608 609static const u8 rtl8225z2_tx_gain_cck_ofdm[] = { 610 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 611 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 612 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 613 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 614 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 615 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23 616}; 617 618static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) 619{ 620 struct rtl8187_priv *priv = dev->priv; 621 u8 cck_power, ofdm_power; 622 const u8 *tmp; 623 u32 reg; 624 int i; 625 626 cck_power = priv->channels[channel - 1].hw_value & 0xF; 627 ofdm_power = priv->channels[channel - 1].hw_value >> 4; 628 629 cck_power = min(cck_power, (u8)15); 630 cck_power += priv->txpwr_base & 0xF; 631 cck_power = min(cck_power, (u8)35); 632 633 if (ofdm_power > (u8)15) 634 ofdm_power = 25; 635 else 636 ofdm_power += 10; 637 ofdm_power += priv->txpwr_base >> 4; 638 ofdm_power = min(ofdm_power, (u8)35); 639 640 if (channel == 14) 641 tmp = rtl8225z2_tx_power_cck_ch14; 642 else 643 tmp = rtl8225z2_tx_power_cck; 644 645 for (i = 0; i < 8; i++) 646 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); 647 648 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 649 rtl8225z2_tx_gain_cck_ofdm[cck_power]); 650 msleep(1); 651 652 /* anaparam2 on */ 653 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 654 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 655 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 656 reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 657 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, 658 RTL8187_RTL8225_ANAPARAM2_ON); 659 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 660 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 661 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 662 663 rtl8225_write_phy_ofdm(dev, 2, 0x42); 664 rtl8225_write_phy_ofdm(dev, 5, 0x00); 665 rtl8225_write_phy_ofdm(dev, 6, 0x40); 666 rtl8225_write_phy_ofdm(dev, 7, 0x00); 667 rtl8225_write_phy_ofdm(dev, 8, 0x40); 668 669 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 670 rtl8225z2_tx_gain_cck_ofdm[ofdm_power]); 671 msleep(1); 672} 673 674static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel) 675{ 676 struct rtl8187_priv *priv = dev->priv; 677 u8 cck_power, ofdm_power; 678 const u8 *tmp; 679 int i; 680 681 cck_power = priv->channels[channel - 1].hw_value & 0xF; 682 ofdm_power = priv->channels[channel - 1].hw_value >> 4; 683 684 cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7; 685 cck_power += priv->txpwr_base & 0xF; 686 cck_power = min(cck_power, (u8)35); 687 688 if (ofdm_power > 15) 689 ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25; 690 else 691 ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10; 692 ofdm_power += (priv->txpwr_base >> 4) & 0xF; 693 ofdm_power = min(ofdm_power, (u8)35); 694 695 if (channel == 14) 696 tmp = rtl8225z2_tx_power_cck_ch14; 697 else 698 tmp = rtl8225z2_tx_power_cck; 699 700 if (priv->hw_rev == RTL8187BvB) { 701 if (cck_power <= 6) 702 ; /* do nothing */ 703 else if (cck_power <= 11) 704 tmp += 8; 705 else 706 tmp += 16; 707 } else { 708 if (cck_power <= 5) 709 ; /* do nothing */ 710 else if (cck_power <= 11) 711 tmp += 8; 712 else if (cck_power <= 17) 713 tmp += 16; 714 else 715 tmp += 24; 716 } 717 718 for (i = 0; i < 8; i++) 719 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); 720 721 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 722 rtl8225z2_tx_gain_cck_ofdm[cck_power] << 1); 723 msleep(1); 724 725 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 726 rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1); 727 if (priv->hw_rev == RTL8187BvB) { 728 if (ofdm_power <= 11) { 729 rtl8225_write_phy_ofdm(dev, 0x87, 0x60); 730 rtl8225_write_phy_ofdm(dev, 0x89, 0x60); 731 } else { 732 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c); 733 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c); 734 } 735 } else { 736 if (ofdm_power <= 11) { 737 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c); 738 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c); 739 } else if (ofdm_power <= 17) { 740 rtl8225_write_phy_ofdm(dev, 0x87, 0x54); 741 rtl8225_write_phy_ofdm(dev, 0x89, 0x54); 742 } else { 743 rtl8225_write_phy_ofdm(dev, 0x87, 0x50); 744 rtl8225_write_phy_ofdm(dev, 0x89, 0x50); 745 } 746 } 747 msleep(1); 748} 749 750static const u16 rtl8225z2_rxgain[] = { 751 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, 752 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, 753 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, 754 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, 755 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, 756 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, 757 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, 758 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, 759 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, 760 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, 761 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, 762 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb 763}; 764 765static const u8 rtl8225z2_gain_bg[] = { 766 0x23, 0x15, 0xa5, /* -82-1dBm */ 767 0x23, 0x15, 0xb5, /* -82-2dBm */ 768 0x23, 0x15, 0xc5, /* -82-3dBm */ 769 0x33, 0x15, 0xc5, /* -78dBm */ 770 0x43, 0x15, 0xc5, /* -74dBm */ 771 0x53, 0x15, 0xc5, /* -70dBm */ 772 0x63, 0x15, 0xc5 /* -66dBm */ 773}; 774 775static void rtl8225z2_rf_init(struct ieee80211_hw *dev) 776{ 777 struct rtl8187_priv *priv = dev->priv; 778 int i; 779 780 rtl8225_write(dev, 0x0, 0x2BF); 781 rtl8225_write(dev, 0x1, 0xEE0); 782 rtl8225_write(dev, 0x2, 0x44D); 783 rtl8225_write(dev, 0x3, 0x441); 784 rtl8225_write(dev, 0x4, 0x8C3); 785 rtl8225_write(dev, 0x5, 0xC72); 786 rtl8225_write(dev, 0x6, 0x0E6); 787 rtl8225_write(dev, 0x7, 0x82A); 788 rtl8225_write(dev, 0x8, 0x03F); 789 rtl8225_write(dev, 0x9, 0x335); 790 rtl8225_write(dev, 0xa, 0x9D4); 791 rtl8225_write(dev, 0xb, 0x7BB); 792 rtl8225_write(dev, 0xc, 0x850); 793 rtl8225_write(dev, 0xd, 0xCDF); 794 rtl8225_write(dev, 0xe, 0x02B); 795 rtl8225_write(dev, 0xf, 0x114); 796 msleep(100); 797 798 rtl8225_write(dev, 0x0, 0x1B7); 799 800 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { 801 rtl8225_write(dev, 0x1, i + 1); 802 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); 803 } 804 805 rtl8225_write(dev, 0x3, 0x080); 806 rtl8225_write(dev, 0x5, 0x004); 807 rtl8225_write(dev, 0x0, 0x0B7); 808 rtl8225_write(dev, 0x2, 0xc4D); 809 810 msleep(200); 811 rtl8225_write(dev, 0x2, 0x44D); 812 msleep(100); 813 814 if (!(rtl8225_read(dev, 6) & (1 << 7))) { 815 rtl8225_write(dev, 0x02, 0x0C4D); 816 msleep(200); 817 rtl8225_write(dev, 0x02, 0x044D); 818 msleep(100); 819 if (!(rtl8225_read(dev, 6) & (1 << 7))) 820 wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", 821 rtl8225_read(dev, 6)); 822 } 823 824 msleep(200); 825 826 rtl8225_write(dev, 0x0, 0x2BF); 827 828 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { 829 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); 830 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); 831 } 832 833 msleep(1); 834 835 rtl8225_write_phy_ofdm(dev, 0x00, 0x01); 836 rtl8225_write_phy_ofdm(dev, 0x01, 0x02); 837 rtl8225_write_phy_ofdm(dev, 0x02, 0x42); 838 rtl8225_write_phy_ofdm(dev, 0x03, 0x00); 839 rtl8225_write_phy_ofdm(dev, 0x04, 0x00); 840 rtl8225_write_phy_ofdm(dev, 0x05, 0x00); 841 rtl8225_write_phy_ofdm(dev, 0x06, 0x40); 842 rtl8225_write_phy_ofdm(dev, 0x07, 0x00); 843 rtl8225_write_phy_ofdm(dev, 0x08, 0x40); 844 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); 845 rtl8225_write_phy_ofdm(dev, 0x0a, 0x08); 846 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); 847 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); 848 rtl8225_write_phy_ofdm(dev, 0x0d, 0x43); 849 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); 850 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); 851 rtl8225_write_phy_ofdm(dev, 0x10, 0x84); 852 rtl8225_write_phy_ofdm(dev, 0x11, 0x07); 853 rtl8225_write_phy_ofdm(dev, 0x12, 0x20); 854 rtl8225_write_phy_ofdm(dev, 0x13, 0x20); 855 rtl8225_write_phy_ofdm(dev, 0x14, 0x00); 856 rtl8225_write_phy_ofdm(dev, 0x15, 0x40); 857 rtl8225_write_phy_ofdm(dev, 0x16, 0x00); 858 rtl8225_write_phy_ofdm(dev, 0x17, 0x40); 859 rtl8225_write_phy_ofdm(dev, 0x18, 0xef); 860 rtl8225_write_phy_ofdm(dev, 0x19, 0x19); 861 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); 862 rtl8225_write_phy_ofdm(dev, 0x1b, 0x15); 863 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); 864 rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); 865 rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); 866 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); 867 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); 868 rtl8225_write_phy_ofdm(dev, 0x21, 0x17); 869 rtl8225_write_phy_ofdm(dev, 0x22, 0x16); 870 rtl8225_write_phy_ofdm(dev, 0x23, 0x80); 871 rtl8225_write_phy_ofdm(dev, 0x24, 0x46); 872 rtl8225_write_phy_ofdm(dev, 0x25, 0x00); 873 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); 874 rtl8225_write_phy_ofdm(dev, 0x27, 0x88); 875 876 rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]); 877 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]); 878 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]); 879 rtl8225_write_phy_ofdm(dev, 0x21, 0x37); 880 881 rtl8225_write_phy_cck(dev, 0x00, 0x98); 882 rtl8225_write_phy_cck(dev, 0x03, 0x20); 883 rtl8225_write_phy_cck(dev, 0x04, 0x7e); 884 rtl8225_write_phy_cck(dev, 0x05, 0x12); 885 rtl8225_write_phy_cck(dev, 0x06, 0xfc); 886 rtl8225_write_phy_cck(dev, 0x07, 0x78); 887 rtl8225_write_phy_cck(dev, 0x08, 0x2e); 888 rtl8225_write_phy_cck(dev, 0x10, 0x9b); 889 rtl8225_write_phy_cck(dev, 0x11, 0x88); 890 rtl8225_write_phy_cck(dev, 0x12, 0x47); 891 rtl8225_write_phy_cck(dev, 0x13, 0xd0); 892 rtl8225_write_phy_cck(dev, 0x19, 0x00); 893 rtl8225_write_phy_cck(dev, 0x1a, 0xa0); 894 rtl8225_write_phy_cck(dev, 0x1b, 0x08); 895 rtl8225_write_phy_cck(dev, 0x40, 0x86); 896 rtl8225_write_phy_cck(dev, 0x41, 0x8d); 897 rtl8225_write_phy_cck(dev, 0x42, 0x15); 898 rtl8225_write_phy_cck(dev, 0x43, 0x18); 899 rtl8225_write_phy_cck(dev, 0x44, 0x36); 900 rtl8225_write_phy_cck(dev, 0x45, 0x35); 901 rtl8225_write_phy_cck(dev, 0x46, 0x2e); 902 rtl8225_write_phy_cck(dev, 0x47, 0x25); 903 rtl8225_write_phy_cck(dev, 0x48, 0x1c); 904 rtl8225_write_phy_cck(dev, 0x49, 0x12); 905 rtl8225_write_phy_cck(dev, 0x4a, 0x09); 906 rtl8225_write_phy_cck(dev, 0x4b, 0x04); 907 rtl8225_write_phy_cck(dev, 0x4c, 0x05); 908 909 rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1); 910 911 rtl8225z2_rf_set_tx_power(dev, 1); 912 913 /* RX antenna default to A */ 914 rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */ 915 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */ 916 917 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ 918 msleep(1); 919 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); 920} 921 922static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev) 923{ 924 struct rtl8187_priv *priv = dev->priv; 925 int i; 926 927 rtl8225_write(dev, 0x0, 0x0B7); 928 rtl8225_write(dev, 0x1, 0xEE0); 929 rtl8225_write(dev, 0x2, 0x44D); 930 rtl8225_write(dev, 0x3, 0x441); 931 rtl8225_write(dev, 0x4, 0x8C3); 932 rtl8225_write(dev, 0x5, 0xC72); 933 rtl8225_write(dev, 0x6, 0x0E6); 934 rtl8225_write(dev, 0x7, 0x82A); 935 rtl8225_write(dev, 0x8, 0x03F); 936 rtl8225_write(dev, 0x9, 0x335); 937 rtl8225_write(dev, 0xa, 0x9D4); 938 rtl8225_write(dev, 0xb, 0x7BB); 939 rtl8225_write(dev, 0xc, 0x850); 940 rtl8225_write(dev, 0xd, 0xCDF); 941 rtl8225_write(dev, 0xe, 0x02B); 942 rtl8225_write(dev, 0xf, 0x114); 943 944 rtl8225_write(dev, 0x0, 0x1B7); 945 946 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { 947 rtl8225_write(dev, 0x1, i + 1); 948 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); 949 } 950 951 rtl8225_write(dev, 0x3, 0x080); 952 rtl8225_write(dev, 0x5, 0x004); 953 rtl8225_write(dev, 0x0, 0x0B7); 954 955 rtl8225_write(dev, 0x2, 0xC4D); 956 957 rtl8225_write(dev, 0x2, 0x44D); 958 rtl8225_write(dev, 0x0, 0x2BF); 959 960 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03); 961 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07); 962 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); 963 964 rtl8225_write_phy_ofdm(dev, 0x80, 0x12); 965 for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) { 966 rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]); 967 rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i); 968 rtl8225_write_phy_ofdm(dev, 0xE, 0); 969 } 970 rtl8225_write_phy_ofdm(dev, 0x80, 0x10); 971 972 for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++) 973 rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]); 974 975 rtl8225_write_phy_ofdm(dev, 0x97, 0x46); 976 rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6); 977 rtl8225_write_phy_ofdm(dev, 0x85, 0xfc); 978 rtl8225_write_phy_cck(dev, 0xc1, 0x88); 979} 980 981static void rtl8225_rf_stop(struct ieee80211_hw *dev) 982{ 983 rtl8225_write(dev, 0x4, 0x1f); 984} 985 986static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, 987 struct ieee80211_conf *conf) 988{ 989 struct rtl8187_priv *priv = dev->priv; 990 int chan = 991 ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); 992 993 if (priv->rf->init == rtl8225_rf_init) 994 rtl8225_rf_set_tx_power(dev, chan); 995 else if (priv->rf->init == rtl8225z2_rf_init) 996 rtl8225z2_rf_set_tx_power(dev, chan); 997 else 998 rtl8225z2_b_rf_set_tx_power(dev, chan); 999 1000 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); 1001 msleep(10); 1002} 1003 1004static const struct rtl818x_rf_ops rtl8225_ops = { 1005 .name = "rtl8225", 1006 .init = rtl8225_rf_init, 1007 .stop = rtl8225_rf_stop, 1008 .set_chan = rtl8225_rf_set_channel 1009}; 1010 1011static const struct rtl818x_rf_ops rtl8225z2_ops = { 1012 .name = "rtl8225z2", 1013 .init = rtl8225z2_rf_init, 1014 .stop = rtl8225_rf_stop, 1015 .set_chan = rtl8225_rf_set_channel 1016}; 1017 1018static const struct rtl818x_rf_ops rtl8225z2_b_ops = { 1019 .name = "rtl8225z2", 1020 .init = rtl8225z2_b_rf_init, 1021 .stop = rtl8225_rf_stop, 1022 .set_chan = rtl8225_rf_set_channel 1023}; 1024 1025const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev) 1026{ 1027 u16 reg8, reg9; 1028 struct rtl8187_priv *priv = dev->priv; 1029 1030 if (!priv->is_rtl8187b) { 1031 rtl8225_write(dev, 0, 0x1B7); 1032 1033 reg8 = rtl8225_read(dev, 8); 1034 reg9 = rtl8225_read(dev, 9); 1035 1036 rtl8225_write(dev, 0, 0x0B7); 1037 1038 if (reg8 != 0x588 || reg9 != 0x700) 1039 return &rtl8225_ops; 1040 1041 return &rtl8225z2_ops; 1042 } else 1043 return &rtl8225z2_b_ops; 1044}