aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRA-Jay Hung <Jay_Hung@ralinktech.com>2011-02-20 07:54:52 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-02-21 15:39:59 -0500
commitd96aa640967ab10641a0a389a4a1569efa54ac72 (patch)
tree31933f3ada13116abea5b37f3c161d96b7132785 /drivers
parent9e0bc671873c96104b8f793b03661f443e1c4b5a (diff)
rt2x00: Add antenna setting for RT3070/RT3090/RT3390 with RX antenna diversity support
For RT3070/RT3090/RT3390 with RX antenna diversity support, we must select default antenna using gpio control way even if we do not turn on antenna diversity feature. Seperate the meaning of TX/RX chain and antenna. Some chips use 2x2 TX/RX chain but may have 3 RX antennas or 1x1 TX/RX chain but may have 2 RX antennas to do antenna diversity. Signed-off-by: RA-Jay Hung <jay_hung@ralinktech.com> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c74
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h2
3 files changed, 70 insertions, 9 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index ec8159ce0ee8..ef8f605d1081 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -270,6 +270,7 @@
270 270
271/* 271/*
272 * GPIO_CTRL_CFG: 272 * GPIO_CTRL_CFG:
273 * GPIOD: GPIO direction, 0: Output, 1: Input
273 */ 274 */
274#define GPIO_CTRL_CFG 0x0228 275#define GPIO_CTRL_CFG 0x0228
275#define GPIO_CTRL_CFG_BIT0 FIELD32(0x00000001) 276#define GPIO_CTRL_CFG_BIT0 FIELD32(0x00000001)
@@ -281,6 +282,7 @@
281#define GPIO_CTRL_CFG_BIT6 FIELD32(0x00000040) 282#define GPIO_CTRL_CFG_BIT6 FIELD32(0x00000040)
282#define GPIO_CTRL_CFG_BIT7 FIELD32(0x00000080) 283#define GPIO_CTRL_CFG_BIT7 FIELD32(0x00000080)
283#define GPIO_CTRL_CFG_BIT8 FIELD32(0x00000100) 284#define GPIO_CTRL_CFG_BIT8 FIELD32(0x00000100)
285#define GPIO_CTRL_CFG_GPIOD FIELD32(0x00000800)
284 286
285/* 287/*
286 * MCU_CMD_CFG 288 * MCU_CMD_CFG
@@ -2068,6 +2070,7 @@ struct mac_iveiv_entry {
2068#define MCU_LED_LED_POLARITY 0x54 2070#define MCU_LED_LED_POLARITY 0x54
2069#define MCU_RADAR 0x60 2071#define MCU_RADAR 0x60
2070#define MCU_BOOT_SIGNAL 0x72 2072#define MCU_BOOT_SIGNAL 0x72
2073#define MCU_ANT_SELECT 0X73
2071#define MCU_BBP_SIGNAL 0x80 2074#define MCU_BBP_SIGNAL 0x80
2072#define MCU_POWER_SAVE 0x83 2075#define MCU_POWER_SAVE 0x83
2073 2076
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 7a68a67c506a..c62b4a593eb8 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1376,10 +1376,32 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
1376} 1376}
1377EXPORT_SYMBOL_GPL(rt2800_config_erp); 1377EXPORT_SYMBOL_GPL(rt2800_config_erp);
1378 1378
1379static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev,
1380 enum antenna ant)
1381{
1382 u32 reg;
1383 u8 eesk_pin = (ant == ANTENNA_A) ? 1 : 0;
1384 u8 gpio_bit3 = (ant == ANTENNA_A) ? 0 : 1;
1385
1386 if (rt2x00_is_pci(rt2x00dev)) {
1387 rt2800_register_read(rt2x00dev, E2PROM_CSR, &reg);
1388 rt2x00_set_field32(&reg, E2PROM_CSR_DATA_CLOCK, eesk_pin);
1389 rt2800_register_write(rt2x00dev, E2PROM_CSR, reg);
1390 } else if (rt2x00_is_usb(rt2x00dev))
1391 rt2800_mcu_request(rt2x00dev, MCU_ANT_SELECT, 0xff,
1392 eesk_pin, 0);
1393
1394 rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
1395 rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD, 0);
1396 rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT3, gpio_bit3);
1397 rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
1398}
1399
1379void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) 1400void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
1380{ 1401{
1381 u8 r1; 1402 u8 r1;
1382 u8 r3; 1403 u8 r3;
1404 u16 eeprom;
1383 1405
1384 rt2800_bbp_read(rt2x00dev, 1, &r1); 1406 rt2800_bbp_read(rt2x00dev, 1, &r1);
1385 rt2800_bbp_read(rt2x00dev, 3, &r3); 1407 rt2800_bbp_read(rt2x00dev, 3, &r3);
@@ -1387,7 +1409,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
1387 /* 1409 /*
1388 * Configure the TX antenna. 1410 * Configure the TX antenna.
1389 */ 1411 */
1390 switch ((int)ant->tx) { 1412 switch (ant->tx_chain_num) {
1391 case 1: 1413 case 1:
1392 rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); 1414 rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
1393 break; 1415 break;
@@ -1402,8 +1424,18 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
1402 /* 1424 /*
1403 * Configure the RX antenna. 1425 * Configure the RX antenna.
1404 */ 1426 */
1405 switch ((int)ant->rx) { 1427 switch (ant->rx_chain_num) {
1406 case 1: 1428 case 1:
1429 if (rt2x00_rt(rt2x00dev, RT3070) ||
1430 rt2x00_rt(rt2x00dev, RT3090) ||
1431 rt2x00_rt(rt2x00dev, RT3390)) {
1432 rt2x00_eeprom_read(rt2x00dev,
1433 EEPROM_NIC_CONF1, &eeprom);
1434 if (rt2x00_get_field16(eeprom,
1435 EEPROM_NIC_CONF1_ANT_DIVERSITY))
1436 rt2800_set_ant_diversity(rt2x00dev,
1437 rt2x00dev->default_ant.rx);
1438 }
1407 rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); 1439 rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
1408 break; 1440 break;
1409 case 2: 1441 case 2:
@@ -1449,13 +1481,13 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
1449{ 1481{
1450 rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); 1482 rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
1451 1483
1452 if (rt2x00dev->default_ant.tx == 1) 1484 if (rt2x00dev->default_ant.tx_chain_num == 1)
1453 rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1); 1485 rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1);
1454 1486
1455 if (rt2x00dev->default_ant.rx == 1) { 1487 if (rt2x00dev->default_ant.rx_chain_num == 1) {
1456 rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1); 1488 rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1);
1457 rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); 1489 rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
1458 } else if (rt2x00dev->default_ant.rx == 2) 1490 } else if (rt2x00dev->default_ant.rx_chain_num == 2)
1459 rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); 1491 rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
1460 1492
1461 if (rf->channel > 14) { 1493 if (rf->channel > 14) {
@@ -1602,13 +1634,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
1602 tx_pin = 0; 1634 tx_pin = 0;
1603 1635
1604 /* Turn on unused PA or LNA when not using 1T or 1R */ 1636 /* Turn on unused PA or LNA when not using 1T or 1R */
1605 if (rt2x00dev->default_ant.tx != 1) { 1637 if (rt2x00dev->default_ant.tx_chain_num == 2) {
1606 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1); 1638 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
1607 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1); 1639 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
1608 } 1640 }
1609 1641
1610 /* Turn on unused PA or LNA when not using 1T or 1R */ 1642 /* Turn on unused PA or LNA when not using 1T or 1R */
1611 if (rt2x00dev->default_ant.rx != 1) { 1643 if (rt2x00dev->default_ant.rx_chain_num == 2) {
1612 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); 1644 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
1613 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); 1645 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
1614 } 1646 }
@@ -3068,11 +3100,35 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
3068 /* 3100 /*
3069 * Identify default antenna configuration. 3101 * Identify default antenna configuration.
3070 */ 3102 */
3071 rt2x00dev->default_ant.tx = 3103 rt2x00dev->default_ant.tx_chain_num =
3072 rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH); 3104 rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH);
3073 rt2x00dev->default_ant.rx = 3105 rt2x00dev->default_ant.rx_chain_num =
3074 rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH); 3106 rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH);
3075 3107
3108 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
3109
3110 if (rt2x00_rt(rt2x00dev, RT3070) ||
3111 rt2x00_rt(rt2x00dev, RT3090) ||
3112 rt2x00_rt(rt2x00dev, RT3390)) {
3113 value = rt2x00_get_field16(eeprom,
3114 EEPROM_NIC_CONF1_ANT_DIVERSITY);
3115 switch (value) {
3116 case 0:
3117 case 1:
3118 case 2:
3119 rt2x00dev->default_ant.tx = ANTENNA_A;
3120 rt2x00dev->default_ant.rx = ANTENNA_A;
3121 break;
3122 case 3:
3123 rt2x00dev->default_ant.tx = ANTENNA_A;
3124 rt2x00dev->default_ant.rx = ANTENNA_B;
3125 break;
3126 }
3127 } else {
3128 rt2x00dev->default_ant.tx = ANTENNA_A;
3129 rt2x00dev->default_ant.rx = ANTENNA_A;
3130 }
3131
3076 /* 3132 /*
3077 * Read frequency offset and RF programming sequence. 3133 * Read frequency offset and RF programming sequence.
3078 */ 3134 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 39bc2faf1793..fd28836a0072 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -225,6 +225,8 @@ struct channel_info {
225struct antenna_setup { 225struct antenna_setup {
226 enum antenna rx; 226 enum antenna rx;
227 enum antenna tx; 227 enum antenna tx;
228 u8 rx_chain_num;
229 u8 tx_chain_num;
228}; 230};
229 231
230/* 232/*