1711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 2711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello/* Radio tuning for RTL8225 on RTL8187SE 3711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * 4711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net> 5711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * Copyright 2014 Andrea Merello <andrea.merello@gmail.com> 6711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * 7711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * Based on the r8180 and Realtek r8187se drivers, which are: 8711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al. 9711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * 10711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * Also based on the rtl8187 driver, which is: 11711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * Copyright 2007 Michael Wu <flamingice@sourmilk.net> 12711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * Copyright 2007 Andrea Merello <andrea.merello@gmail.com> 13711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * 14711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * This program is free software; you can redistribute it and/or modify 15711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * it under the terms of the GNU General Public License version 2 as 16711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello * published by the Free Software Foundation. 17711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello */ 18711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 19711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello#include <net/mac80211.h> 20711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 21711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello#include "rtl8180.h" 22711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello#include "rtl8225se.h" 23711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 24711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello#define PFX "rtl8225 (se) " 25711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 26711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u32 RF_GAIN_TABLE[] = { 27711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6, 28711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057, 29711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3, 30711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3, 31711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x0183, 0x0163, 0x0143, 0x0123, 0x0103 32711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 33711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 34711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u8 cck_ofdm_gain_settings[] = { 35711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 36711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 37711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 38711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 39711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 40711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 41711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 42711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 43711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u8 rtl8225se_tx_gain_cck_ofdm[] = { 44711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e 45711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 46711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 47711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u8 rtl8225se_tx_power_cck[] = { 48711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, 49711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, 50711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, 51711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, 52711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, 53711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 54711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 55711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 56711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u8 rtl8225se_tx_power_cck_ch14[] = { 57711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, 58711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, 59711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, 60711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, 61711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 62711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 63711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 64711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 65711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u8 rtl8225se_tx_power_ofdm[] = { 66711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 67711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 68711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 69711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u32 rtl8225se_chan[] = { 70711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380, 71711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A, 72711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 73711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 74711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u8 rtl8225sez2_tx_power_cck_ch14[] = { 75711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 76711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 77711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 78711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u8 rtl8225sez2_tx_power_cck_B[] = { 79711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04 80711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 81711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 82711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u8 rtl8225sez2_tx_power_cck_A[] = { 83711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 84711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 85711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 86711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u8 rtl8225sez2_tx_power_cck[] = { 87711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 88711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 89711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 90711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u8 ZEBRA_AGC[] = { 91711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 92711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 93711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 94711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 95711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27, 96711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07, 97711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 98711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 99711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 100711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, 101711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b, 102711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 103711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 104711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24, 105711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 106711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F 107711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 108711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 109711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const u8 OFDM_CONFIG[] = { 110711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50, 111711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 112711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26, 113711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB, 114711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00, 115711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00, 116711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e, 117711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 0xD8, 0x3C, 0x7B, 0x10, 0x10 118711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 119711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 120711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic void rtl8187se_three_wire_io(struct ieee80211_hw *dev, u8 *data, 121711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello u8 len, bool write) 122711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 123711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello struct rtl8180_priv *priv = dev->priv; 124711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello int i; 125711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello u8 tmp; 126711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 127711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello do { 128711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello for (i = 0; i < 5; i++) { 129711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello tmp = rtl818x_ioread8(priv, SW_3W_CMD1); 130711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (!(tmp & 0x3)) 131711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello break; 132711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello udelay(10); 133711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } 134711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (i == 5) 135711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello wiphy_err(dev->wiphy, PFX 136711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello "CmdReg: 0x%x RE/WE bits aren't clear\n", tmp); 137711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 138711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello tmp = rtl818x_ioread8(priv, &priv->map->rf_sw_config) | 0x02; 139711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite8(priv, &priv->map->rf_sw_config, tmp); 140711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 141711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello tmp = rtl818x_ioread8(priv, REG_ADDR1(0x84)) & 0xF7; 142711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite8(priv, REG_ADDR1(0x84), tmp); 143711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (write) { 144711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (len == 16) { 145711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite16(priv, SW_3W_DB0, 146711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello *(u16 *)data); 147711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } else if (len == 64) { 148711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite32(priv, SW_3W_DB0_4, 149711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello *((u32 *)data)); 150711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite32(priv, SW_3W_DB1_4, 151711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello *((u32 *)(data + 4))); 152711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } else 153711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello wiphy_err(dev->wiphy, PFX 154711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello "Unimplemented length\n"); 155711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } else { 156711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite16(priv, SW_3W_DB0, *(u16 *)data); 157711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } 158711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (write) 159711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello tmp = 2; 160711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello else 161711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello tmp = 1; 162711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite8(priv, SW_3W_CMD1, tmp); 163711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello for (i = 0; i < 5; i++) { 164711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello tmp = rtl818x_ioread8(priv, SW_3W_CMD1); 165711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (!(tmp & 0x3)) 166711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello break; 167711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello udelay(10); 168711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } 169711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite8(priv, SW_3W_CMD1, 0); 170711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (!write) { 171711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello *((u16 *)data) = rtl818x_ioread16(priv, SI_DATA_REG); 172711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello *((u16 *)data) &= 0x0FFF; 173711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } 174711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } while (0); 175711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 176711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 177711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic u32 rtl8187se_rf_readreg(struct ieee80211_hw *dev, u8 addr) 178711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 179711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello u32 dataread = addr & 0x0F; 180711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_three_wire_io(dev, (u8 *)&dataread, 16, 0); 181711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello return dataread; 182711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 183711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 184711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic void rtl8187se_rf_writereg(struct ieee80211_hw *dev, u8 addr, u32 data) 185711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 186711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello u32 outdata = (data << 4) | (u32)(addr & 0x0F); 187711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_three_wire_io(dev, (u8 *)&outdata, 16, 1); 188711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 189711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 190711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 191711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic void rtl8225se_write_zebra_agc(struct ieee80211_hw *dev) 192711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 193711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello int i; 194711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 195711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello for (i = 0; i < 128; i++) { 196711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0xF, ZEBRA_AGC[i]); 197711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0xE, i+0x80); 198711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0xE, 0); 199711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } 200711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 201711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 202711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic void rtl8187se_write_ofdm_config(struct ieee80211_hw *dev) 203711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 204711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* write OFDM_CONFIG table */ 205711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello int i; 206711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 207711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello for (i = 0; i < 60; i++) 208711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, i, OFDM_CONFIG[i]); 209711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 210711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 211711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 212711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic void rtl8225sez2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) 213711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 214711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello struct rtl8180_priv *priv = dev->priv; 215711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello u8 cck_power, ofdm_power; 216711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 217711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello cck_power = priv->channels[channel - 1].hw_value & 0xFF; 218711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (cck_power > 35) 219711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello cck_power = 35; 220711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 221711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello cck_ofdm_gain_settings[cck_power]); 222711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 223711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello usleep_range(1000, 5000); 224711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello ofdm_power = priv->channels[channel - 1].hw_value >> 8; 225711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (ofdm_power > 35) 226711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello ofdm_power = 35; 227711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 228711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 229711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello cck_ofdm_gain_settings[ofdm_power]); 230711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (ofdm_power < 12) { 231711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 7, 0x5C); 232711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 9, 0x5C); 233711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } 234711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (ofdm_power < 18) { 235711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 7, 0x54); 236711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 9, 0x54); 237711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } else { 238711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 7, 0x50); 239711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 9, 0x50); 240711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } 241711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 242711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello usleep_range(1000, 5000); 243711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 244711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 245711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic void rtl8187se_write_rf_gain(struct ieee80211_hw *dev) 246711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 247711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello int i; 248711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 249711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello for (i = 0; i <= 36; i++) { 250711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x01, i); mdelay(1); 251711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x02, RF_GAIN_TABLE[i]); mdelay(1); 252711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } 253711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 254711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 255711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic void rtl8187se_write_initial_gain(struct ieee80211_hw *dev, 256711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello int init_gain) 257711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 258711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello switch (init_gain) { 259711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello default: 260711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); 261711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); 262711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x05, 0xFA); mdelay(1); 263711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello break; 264711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello case 2: 265711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); 266711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); 267711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x05, 0xFA); mdelay(1); 268711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello break; 269711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello case 3: 270711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); 271711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); 272711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1); 273711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello break; 274711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello case 4: 275711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); 276711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); 277711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1); 278711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello break; 279711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello case 5: 280711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); 281711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); 282711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1); 283711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello break; 284711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello case 6: 285711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); 286711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); 287711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1); 288711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello break; 289711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello case 7: 290711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); 291711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x24, 0xA6); mdelay(1); 292711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1); 293711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello break; 294711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello case 8: 295711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x17, 0x66); mdelay(1); 296711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x24, 0xB6); mdelay(1); 297711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1); 298711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello break; 299711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } 300711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 301711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 302711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellovoid rtl8225se_rf_init(struct ieee80211_hw *dev) 303711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 304711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello struct rtl8180_priv *priv = dev->priv; 305711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello u32 rf23, rf24; 306711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello u8 d_cut = 0; 307711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello u8 tmp; 308711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 309711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* Page 1 */ 310711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x013F); mdelay(1); 311711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rf23 = rtl8187se_rf_readreg(dev, 0x08); mdelay(1); 312711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rf24 = rtl8187se_rf_readreg(dev, 0x09); mdelay(1); 313711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (rf23 == 0x0818 && rf24 == 0x070C) 314711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello d_cut = 1; 315711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 316711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello wiphy_info(dev->wiphy, "RTL8225-SE version %s\n", 317711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello d_cut ? "D" : "not-D"); 318711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 319711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* Page 0: reg 0 - 15 */ 320711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x009F); mdelay(1); 321711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x01, 0x06E0); mdelay(1); 322711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x02, 0x004D); mdelay(1); 323711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x03, 0x07F1); mdelay(1); 324711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x04, 0x0975); mdelay(1); 325711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x05, 0x0C72); mdelay(1); 326711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x06, 0x0AE6); mdelay(1); 327711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x07, 0x00CA); mdelay(1); 328711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x08, 0x0E1C); mdelay(1); 329711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x09, 0x02F0); mdelay(1); 330711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0A, 0x09D0); mdelay(1); 331711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0B, 0x01BA); mdelay(1); 332711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0C, 0x0640); mdelay(1); 333711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0D, 0x08DF); mdelay(1); 334711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0E, 0x0020); mdelay(1); 335711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0F, 0x0990); mdelay(1); 336711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* page 1: reg 16-30 */ 337711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x013F); mdelay(1); 338711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x03, 0x0806); mdelay(1); 339711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x04, 0x03A7); mdelay(1); 340711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x05, 0x059B); mdelay(1); 341711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x06, 0x0081); mdelay(1); 342711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x07, 0x01A0); mdelay(1); 343711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0A, 0x0001); mdelay(1); 344711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0B, 0x0418); mdelay(1); 345711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0C, 0x0FBE); mdelay(1); 346711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0D, 0x0008); mdelay(1); 347711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (d_cut) 348711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0E, 0x0807); 349711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello else 350711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0E, 0x0806); 351711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello mdelay(1); 352711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0F, 0x0ACC); mdelay(1); 353711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x01D7); mdelay(1); 354711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x03, 0x0E00); mdelay(1); 355711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x04, 0x0E50); mdelay(1); 356711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 357711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_write_rf_gain(dev); 358711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 359711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x05, 0x0203); mdelay(1); 360711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x06, 0x0200); mdelay(1); 361711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x0137); mdelay(11); 362711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0D, 0x0008); mdelay(11); 363711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x0037); mdelay(11); 364711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x04, 0x0160); mdelay(11); 365711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x07, 0x0080); mdelay(11); 366711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x02, 0x088D); mdelay(221); 367711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x0137); mdelay(11); 368711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x07, 0x0000); mdelay(1); 369711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x07, 0x0180); mdelay(1); 370711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x07, 0x0220); mdelay(1); 371711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x07, 0x03E0); mdelay(1); 372711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x06, 0x00C1); mdelay(1); 373711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0A, 0x0001); mdelay(1); 374711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if (priv->xtal_cal) { 375711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello tmp = (priv->xtal_in << 4) | (priv->xtal_out << 1) | 376711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello (1 << 11) | (1 << 9); 377711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0F, tmp); 378711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello wiphy_info(dev->wiphy, "Xtal cal\n"); 379711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello mdelay(1); 380711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } else { 381711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello wiphy_info(dev->wiphy, "NO Xtal cal\n"); 382711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0F, 0x0ACC); 383711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello mdelay(1); 384711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello } 385711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* page 0 */ 386711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x00BF); mdelay(1); 387711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x0D, 0x08DF); mdelay(1); 388711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x02, 0x004D); mdelay(1); 389711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x04, 0x0975); mdelay(31); 390711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x0197); mdelay(1); 391711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x05, 0x05AB); mdelay(1); 392711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 393711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x009F); mdelay(1); 394711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x01, 0x0000); mdelay(1); 395711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x02, 0x0000); mdelay(1); 396711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* power save parameters */ 397711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* TODO: move to dev.c */ 398711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite8(priv, REG_ADDR1(0x024E), 399711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_ioread8(priv, REG_ADDR1(0x24E)) & 0x9F); 400711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_cck(dev, 0x00, 0xC8); 401711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_cck(dev, 0x06, 0x1C); 402711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_cck(dev, 0x10, 0x78); 403711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_cck(dev, 0x2E, 0xD0); 404711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_cck(dev, 0x2F, 0x06); 405711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_cck(dev, 0x01, 0x46); 406711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 407711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* power control */ 408711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x10); 409711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x1B); 410711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 411711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); 412711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x00, 0x12); 413711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 414711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_zebra_agc(dev); 415711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 416711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x10, 0x00); 417711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 418711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_write_ofdm_config(dev); 419711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 420711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* turn on RF */ 421711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x009F); udelay(500); 422711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x04, 0x0972); udelay(500); 423711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* turn on RF again */ 424711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x009F); udelay(500); 425711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x04, 0x0972); udelay(500); 426711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* turn on BB */ 427711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x10, 0x40); 428711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x12, 0x40); 429711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 430711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_write_initial_gain(dev, 4); 431711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 432711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 433711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellovoid rtl8225se_rf_stop(struct ieee80211_hw *dev) 434711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 435711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* checked for 8187se */ 436711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello struct rtl8180_priv *priv = dev->priv; 437711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 438711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* turn off BB RXIQ matrix to cut off rx signal */ 439711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x10, 0x00); 440711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_write_phy_ofdm(dev, 0x12, 0x00); 441711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* turn off RF */ 442711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x04, 0x0000); 443711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x00, 0x0000); 444711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 445711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello usleep_range(1000, 5000); 446711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello /* turn off A/D and D/A */ 447711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8180_set_anaparam(priv, RTL8225SE_ANAPARAM_OFF); 448711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8180_set_anaparam2(priv, RTL8225SE_ANAPARAM2_OFF); 449711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 450711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 451711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellovoid rtl8225se_rf_set_channel(struct ieee80211_hw *dev, 452711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello struct ieee80211_conf *conf) 453711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 454711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello int chan = 455711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); 456711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 457711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225sez2_rf_set_tx_power(dev, chan); 458711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x7, rtl8225se_chan[chan - 1]); 459711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello if ((rtl8187se_rf_readreg(dev, 0x7) & 0x0F80) != 460711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8225se_chan[chan - 1]) 461711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello rtl8187se_rf_writereg(dev, 0x7, rtl8225se_chan[chan - 1]); 462711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello usleep_range(10000, 20000); 463711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 464711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 465711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merellostatic const struct rtl818x_rf_ops rtl8225se_ops = { 466711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello .name = "rtl8225-se", 467711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello .init = rtl8225se_rf_init, 468711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello .stop = rtl8225se_rf_stop, 469711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello .set_chan = rtl8225se_rf_set_channel, 470711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello}; 471711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello 472711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merelloconst struct rtl818x_rf_ops *rtl8187se_detect_rf(struct ieee80211_hw *dev) 473711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello{ 474711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello return &rtl8225se_ops; 475711d4ed38143a01b0f109e11e47e62e9f589d4e3Andrea Merello} 476