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 if (cck_power > 15) 692 cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22; 693 else 694 cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7; 695 cck_power += priv->txpwr_base & 0xF; 696 cck_power = min(cck_power, (u8)35); 697 698 if (ofdm_power > 15) 699 ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25; 700 else 701 ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10; 702 ofdm_power += (priv->txpwr_base >> 4) & 0xF; 703 ofdm_power = min(ofdm_power, (u8)35); 704 705 if (channel == 14) 706 tmp = rtl8225z2_tx_power_cck_ch14; 707 else 708 tmp = rtl8225z2_tx_power_cck; 709 710 if (priv->hw_rev == RTL8187BvB) { 711 if (cck_power <= 6) 712 ; /* do nothing */ 713 else if (cck_power <= 11) 714 tmp += 8; 715 else 716 tmp += 16; 717 } else { 718 if (cck_power <= 5) 719 ; /* do nothing */ 720 else if (cck_power <= 11) 721 tmp += 8; 722 else if (cck_power <= 17) 723 tmp += 16; 724 else 725 tmp += 24; 726 } 727 728 for (i = 0; i < 8; i++) 729 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); 730 731 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 732 rtl8225z2_tx_gain_cck_ofdm[cck_power] << 1); 733 msleep(1); 734 735 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 736 rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1); 737 if (priv->hw_rev == RTL8187BvB) { 738 if (ofdm_power <= 11) { 739 rtl8225_write_phy_ofdm(dev, 0x87, 0x60); 740 rtl8225_write_phy_ofdm(dev, 0x89, 0x60); 741 } else { 742 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c); 743 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c); 744 } 745 } else { 746 if (ofdm_power <= 11) { 747 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c); 748 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c); 749 } else if (ofdm_power <= 17) { 750 rtl8225_write_phy_ofdm(dev, 0x87, 0x54); 751 rtl8225_write_phy_ofdm(dev, 0x89, 0x54); 752 } else { 753 rtl8225_write_phy_ofdm(dev, 0x87, 0x50); 754 rtl8225_write_phy_ofdm(dev, 0x89, 0x50); 755 } 756 } 757 msleep(1); 758 } 759 760 static const u16 rtl8225z2_rxgain[] = { 761 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, 762 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, 763 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, 764 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, 765 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, 766 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, 767 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, 768 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, 769 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, 770 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, 771 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, 772 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb 773 }; 774 775 static const u8 rtl8225z2_gain_bg[] = { 776 0x23, 0x15, 0xa5, /* -82-1dBm */ 777 0x23, 0x15, 0xb5, /* -82-2dBm */ 778 0x23, 0x15, 0xc5, /* -82-3dBm */ 779 0x33, 0x15, 0xc5, /* -78dBm */ 780 0x43, 0x15, 0xc5, /* -74dBm */ 781 0x53, 0x15, 0xc5, /* -70dBm */ 782 0x63, 0x15, 0xc5 /* -66dBm */ 783 }; 784 785 static void rtl8225z2_rf_init(struct ieee80211_hw *dev) 786 { 787 struct rtl8187_priv *priv = dev->priv; 788 int i; 789 790 rtl8225_write(dev, 0x0, 0x2BF); 791 rtl8225_write(dev, 0x1, 0xEE0); 792 rtl8225_write(dev, 0x2, 0x44D); 793 rtl8225_write(dev, 0x3, 0x441); 794 rtl8225_write(dev, 0x4, 0x8C3); 795 rtl8225_write(dev, 0x5, 0xC72); 796 rtl8225_write(dev, 0x6, 0x0E6); 797 rtl8225_write(dev, 0x7, 0x82A); 798 rtl8225_write(dev, 0x8, 0x03F); 799 rtl8225_write(dev, 0x9, 0x335); 800 rtl8225_write(dev, 0xa, 0x9D4); 801 rtl8225_write(dev, 0xb, 0x7BB); 802 rtl8225_write(dev, 0xc, 0x850); 803 rtl8225_write(dev, 0xd, 0xCDF); 804 rtl8225_write(dev, 0xe, 0x02B); 805 rtl8225_write(dev, 0xf, 0x114); 806 msleep(100); 807 808 rtl8225_write(dev, 0x0, 0x1B7); 809 810 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { 811 rtl8225_write(dev, 0x1, i + 1); 812 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); 813 } 814 815 rtl8225_write(dev, 0x3, 0x080); 816 rtl8225_write(dev, 0x5, 0x004); 817 rtl8225_write(dev, 0x0, 0x0B7); 818 rtl8225_write(dev, 0x2, 0xc4D); 819 820 msleep(200); 821 rtl8225_write(dev, 0x2, 0x44D); 822 msleep(100); 823 824 if (!(rtl8225_read(dev, 6) & (1 << 7))) { 825 rtl8225_write(dev, 0x02, 0x0C4D); 826 msleep(200); 827 rtl8225_write(dev, 0x02, 0x044D); 828 msleep(100); 829 if (!(rtl8225_read(dev, 6) & (1 << 7))) 830 wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", 831 rtl8225_read(dev, 6)); 832 } 833 834 msleep(200); 835 836 rtl8225_write(dev, 0x0, 0x2BF); 837 838 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { 839 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); 840 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); 841 } 842 843 msleep(1); 844 845 rtl8225_write_phy_ofdm(dev, 0x00, 0x01); 846 rtl8225_write_phy_ofdm(dev, 0x01, 0x02); 847 rtl8225_write_phy_ofdm(dev, 0x02, 0x42); 848 rtl8225_write_phy_ofdm(dev, 0x03, 0x00); 849 rtl8225_write_phy_ofdm(dev, 0x04, 0x00); 850 rtl8225_write_phy_ofdm(dev, 0x05, 0x00); 851 rtl8225_write_phy_ofdm(dev, 0x06, 0x40); 852 rtl8225_write_phy_ofdm(dev, 0x07, 0x00); 853 rtl8225_write_phy_ofdm(dev, 0x08, 0x40); 854 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); 855 rtl8225_write_phy_ofdm(dev, 0x0a, 0x08); 856 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); 857 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); 858 rtl8225_write_phy_ofdm(dev, 0x0d, 0x43); 859 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); 860 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); 861 rtl8225_write_phy_ofdm(dev, 0x10, 0x84); 862 rtl8225_write_phy_ofdm(dev, 0x11, 0x07); 863 rtl8225_write_phy_ofdm(dev, 0x12, 0x20); 864 rtl8225_write_phy_ofdm(dev, 0x13, 0x20); 865 rtl8225_write_phy_ofdm(dev, 0x14, 0x00); 866 rtl8225_write_phy_ofdm(dev, 0x15, 0x40); 867 rtl8225_write_phy_ofdm(dev, 0x16, 0x00); 868 rtl8225_write_phy_ofdm(dev, 0x17, 0x40); 869 rtl8225_write_phy_ofdm(dev, 0x18, 0xef); 870 rtl8225_write_phy_ofdm(dev, 0x19, 0x19); 871 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); 872 rtl8225_write_phy_ofdm(dev, 0x1b, 0x15); 873 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); 874 rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); 875 rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); 876 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); 877 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); 878 rtl8225_write_phy_ofdm(dev, 0x21, 0x17); 879 rtl8225_write_phy_ofdm(dev, 0x22, 0x16); 880 rtl8225_write_phy_ofdm(dev, 0x23, 0x80); 881 rtl8225_write_phy_ofdm(dev, 0x24, 0x46); 882 rtl8225_write_phy_ofdm(dev, 0x25, 0x00); 883 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); 884 rtl8225_write_phy_ofdm(dev, 0x27, 0x88); 885 886 rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]); 887 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]); 888 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]); 889 rtl8225_write_phy_ofdm(dev, 0x21, 0x37); 890 891 rtl8225_write_phy_cck(dev, 0x00, 0x98); 892 rtl8225_write_phy_cck(dev, 0x03, 0x20); 893 rtl8225_write_phy_cck(dev, 0x04, 0x7e); 894 rtl8225_write_phy_cck(dev, 0x05, 0x12); 895 rtl8225_write_phy_cck(dev, 0x06, 0xfc); 896 rtl8225_write_phy_cck(dev, 0x07, 0x78); 897 rtl8225_write_phy_cck(dev, 0x08, 0x2e); 898 rtl8225_write_phy_cck(dev, 0x10, 0x9b); 899 rtl8225_write_phy_cck(dev, 0x11, 0x88); 900 rtl8225_write_phy_cck(dev, 0x12, 0x47); 901 rtl8225_write_phy_cck(dev, 0x13, 0xd0); 902 rtl8225_write_phy_cck(dev, 0x19, 0x00); 903 rtl8225_write_phy_cck(dev, 0x1a, 0xa0); 904 rtl8225_write_phy_cck(dev, 0x1b, 0x08); 905 rtl8225_write_phy_cck(dev, 0x40, 0x86); 906 rtl8225_write_phy_cck(dev, 0x41, 0x8d); 907 rtl8225_write_phy_cck(dev, 0x42, 0x15); 908 rtl8225_write_phy_cck(dev, 0x43, 0x18); 909 rtl8225_write_phy_cck(dev, 0x44, 0x36); 910 rtl8225_write_phy_cck(dev, 0x45, 0x35); 911 rtl8225_write_phy_cck(dev, 0x46, 0x2e); 912 rtl8225_write_phy_cck(dev, 0x47, 0x25); 913 rtl8225_write_phy_cck(dev, 0x48, 0x1c); 914 rtl8225_write_phy_cck(dev, 0x49, 0x12); 915 rtl8225_write_phy_cck(dev, 0x4a, 0x09); 916 rtl8225_write_phy_cck(dev, 0x4b, 0x04); 917 rtl8225_write_phy_cck(dev, 0x4c, 0x05); 918 919 rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1); 920 921 rtl8225z2_rf_set_tx_power(dev, 1); 922 923 /* RX antenna default to A */ 924 rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */ 925 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */ 926 927 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ 928 msleep(1); 929 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); 930 } 931 932 static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev) 933 { 934 struct rtl8187_priv *priv = dev->priv; 935 int i; 936 937 rtl8225_write(dev, 0x0, 0x0B7); 938 rtl8225_write(dev, 0x1, 0xEE0); 939 rtl8225_write(dev, 0x2, 0x44D); 940 rtl8225_write(dev, 0x3, 0x441); 941 rtl8225_write(dev, 0x4, 0x8C3); 942 rtl8225_write(dev, 0x5, 0xC72); 943 rtl8225_write(dev, 0x6, 0x0E6); 944 rtl8225_write(dev, 0x7, 0x82A); 945 rtl8225_write(dev, 0x8, 0x03F); 946 rtl8225_write(dev, 0x9, 0x335); 947 rtl8225_write(dev, 0xa, 0x9D4); 948 rtl8225_write(dev, 0xb, 0x7BB); 949 rtl8225_write(dev, 0xc, 0x850); 950 rtl8225_write(dev, 0xd, 0xCDF); 951 rtl8225_write(dev, 0xe, 0x02B); 952 rtl8225_write(dev, 0xf, 0x114); 953 954 rtl8225_write(dev, 0x0, 0x1B7); 955 956 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { 957 rtl8225_write(dev, 0x1, i + 1); 958 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); 959 } 960 961 rtl8225_write(dev, 0x3, 0x080); 962 rtl8225_write(dev, 0x5, 0x004); 963 rtl8225_write(dev, 0x0, 0x0B7); 964 965 rtl8225_write(dev, 0x2, 0xC4D); 966 967 rtl8225_write(dev, 0x2, 0x44D); 968 rtl8225_write(dev, 0x0, 0x2BF); 969 970 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03); 971 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07); 972 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); 973 974 rtl8225_write_phy_ofdm(dev, 0x80, 0x12); 975 for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) { 976 rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]); 977 rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i); 978 rtl8225_write_phy_ofdm(dev, 0xE, 0); 979 } 980 rtl8225_write_phy_ofdm(dev, 0x80, 0x10); 981 982 for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++) 983 rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]); 984 985 rtl8225_write_phy_ofdm(dev, 0x97, 0x46); 986 rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6); 987 rtl8225_write_phy_ofdm(dev, 0x85, 0xfc); 988 rtl8225_write_phy_cck(dev, 0xc1, 0x88); 989 } 990 991 static void rtl8225_rf_stop(struct ieee80211_hw *dev) 992 { 993 rtl8225_write(dev, 0x4, 0x1f); 994 } 995 996 static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, 997 struct ieee80211_conf *conf) 998 { 999 struct rtl8187_priv *priv = dev->priv; 1000 int chan = 1001 ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); 1002 1003 if (priv->rf->init == rtl8225_rf_init) 1004 rtl8225_rf_set_tx_power(dev, chan); 1005 else if (priv->rf->init == rtl8225z2_rf_init) 1006 rtl8225z2_rf_set_tx_power(dev, chan); 1007 else 1008 rtl8225z2_b_rf_set_tx_power(dev, chan); 1009 1010 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); 1011 msleep(10); 1012 } 1013 1014 static const struct rtl818x_rf_ops rtl8225_ops = { 1015 .name = "rtl8225", 1016 .init = rtl8225_rf_init, 1017 .stop = rtl8225_rf_stop, 1018 .set_chan = rtl8225_rf_set_channel 1019 }; 1020 1021 static const struct rtl818x_rf_ops rtl8225z2_ops = { 1022 .name = "rtl8225z2", 1023 .init = rtl8225z2_rf_init, 1024 .stop = rtl8225_rf_stop, 1025 .set_chan = rtl8225_rf_set_channel 1026 }; 1027 1028 static const struct rtl818x_rf_ops rtl8225z2_b_ops = { 1029 .name = "rtl8225z2", 1030 .init = rtl8225z2_b_rf_init, 1031 .stop = rtl8225_rf_stop, 1032 .set_chan = rtl8225_rf_set_channel 1033 }; 1034 1035 const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev) 1036 { 1037 u16 reg8, reg9; 1038 struct rtl8187_priv *priv = dev->priv; 1039 1040 if (!priv->is_rtl8187b) { 1041 rtl8225_write(dev, 0, 0x1B7); 1042 1043 reg8 = rtl8225_read(dev, 8); 1044 reg9 = rtl8225_read(dev, 9); 1045 1046 rtl8225_write(dev, 0, 0x0B7); 1047 1048 if (reg8 != 0x588 || reg9 != 0x700) 1049 return &rtl8225_ops; 1050 1051 return &rtl8225z2_ops; 1052 } else 1053 return &rtl8225z2_b_ops; 1054 } 1055