diff options
author | RA-Jay Hung <Jay_Hung@ralinktech.com> | 2011-02-20 07:54:52 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-21 15:39:59 -0500 |
commit | d96aa640967ab10641a0a389a4a1569efa54ac72 (patch) | |
tree | 31933f3ada13116abea5b37f3c161d96b7132785 /drivers | |
parent | 9e0bc671873c96104b8f793b03661f443e1c4b5a (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.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 74 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 2 |
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 | } |
1377 | EXPORT_SYMBOL_GPL(rt2800_config_erp); | 1377 | EXPORT_SYMBOL_GPL(rt2800_config_erp); |
1378 | 1378 | ||
1379 | static 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, ®); | ||
1388 | rt2x00_set_field32(®, 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, ®); | ||
1395 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD, 0); | ||
1396 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, gpio_bit3); | ||
1397 | rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
1398 | } | ||
1399 | |||
1379 | void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) | 1400 | void 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 { | |||
225 | struct antenna_setup { | 225 | struct 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 | /* |