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