diff options
author | Herton Ronaldo Krzesinski <herton@mandriva.com.br> | 2009-08-26 12:54:09 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-28 14:40:52 -0400 |
commit | ca9152e37f57259ca92486ca5753af16fd9155c6 (patch) | |
tree | 90b36f241e67ae2decf7043d78249591b09ad707 | |
parent | 6a8171f261eec3577c2a5985e3a2b51377e48931 (diff) |
rtl8187: Implement rfkill support
This change implements rfkill support for RTL8187B and RTL8187L devices,
using new cfg80211 rfkill API.
Acked-by: Larry Finger <Larry.Finger@lwfinger.net>
Tested-by: Hin-Tak Leung <htl10@users.sourceforge.net>
Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/rtl818x/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8187.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8187_dev.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8187_leds.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8187_rfkill.c | 63 | ||||
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8187_rfkill.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl818x.h | 5 |
7 files changed, 94 insertions, 17 deletions
diff --git a/drivers/net/wireless/rtl818x/Makefile b/drivers/net/wireless/rtl818x/Makefile index 37e3d4db0c40..93cbfbedb46d 100644 --- a/drivers/net/wireless/rtl818x/Makefile +++ b/drivers/net/wireless/rtl818x/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o | 1 | rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o |
2 | rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o | 2 | rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o rtl8187_rfkill.o |
3 | 3 | ||
4 | obj-$(CONFIG_RTL8180) += rtl8180.o | 4 | obj-$(CONFIG_RTL8180) += rtl8180.o |
5 | obj-$(CONFIG_RTL8187) += rtl8187.o | 5 | obj-$(CONFIG_RTL8187) += rtl8187.o |
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h index c09bfefc70f3..bf9175a8c1f4 100644 --- a/drivers/net/wireless/rtl818x/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187.h | |||
@@ -133,6 +133,7 @@ struct rtl8187_priv { | |||
133 | __le16 bits16; | 133 | __le16 bits16; |
134 | __le32 bits32; | 134 | __le32 bits32; |
135 | } *io_dmabuf; | 135 | } *io_dmabuf; |
136 | bool rfkill_off; | ||
136 | }; | 137 | }; |
137 | 138 | ||
138 | void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); | 139 | void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 5573e3476802..9679b29e1c49 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #ifdef CONFIG_RTL8187_LEDS | 32 | #ifdef CONFIG_RTL8187_LEDS |
33 | #include "rtl8187_leds.h" | 33 | #include "rtl8187_leds.h" |
34 | #endif | 34 | #endif |
35 | #include "rtl8187_rfkill.h" | ||
35 | 36 | ||
36 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); | 37 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); |
37 | MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); | 38 | MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); |
@@ -648,10 +649,10 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev) | |||
648 | 649 | ||
649 | /* setup card */ | 650 | /* setup card */ |
650 | rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); | 651 | rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); |
651 | rtl818x_iowrite8(priv, &priv->map->GPIO, 0); | 652 | rtl818x_iowrite8(priv, &priv->map->GPIO0, 0); |
652 | 653 | ||
653 | rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); | 654 | rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); |
654 | rtl818x_iowrite8(priv, &priv->map->GPIO, 1); | 655 | rtl818x_iowrite8(priv, &priv->map->GPIO0, 1); |
655 | rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); | 656 | rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); |
656 | 657 | ||
657 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); | 658 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); |
@@ -674,11 +675,11 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev) | |||
674 | 675 | ||
675 | /* host_usb_init */ | 676 | /* host_usb_init */ |
676 | rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); | 677 | rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); |
677 | rtl818x_iowrite8(priv, &priv->map->GPIO, 0); | 678 | rtl818x_iowrite8(priv, &priv->map->GPIO0, 0); |
678 | reg = rtl818x_ioread8(priv, (u8 *)0xFE53); | 679 | reg = rtl818x_ioread8(priv, (u8 *)0xFE53); |
679 | rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7)); | 680 | rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7)); |
680 | rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); | 681 | rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); |
681 | rtl818x_iowrite8(priv, &priv->map->GPIO, 0x20); | 682 | rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x20); |
682 | rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); | 683 | rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); |
683 | rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80); | 684 | rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80); |
684 | rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80); | 685 | rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80); |
@@ -907,12 +908,12 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
907 | u32 reg; | 908 | u32 reg; |
908 | int ret; | 909 | int ret; |
909 | 910 | ||
911 | mutex_lock(&priv->conf_mutex); | ||
912 | |||
910 | ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) : | 913 | ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) : |
911 | rtl8187b_init_hw(dev); | 914 | rtl8187b_init_hw(dev); |
912 | if (ret) | 915 | if (ret) |
913 | return ret; | 916 | goto rtl8187_start_exit; |
914 | |||
915 | mutex_lock(&priv->conf_mutex); | ||
916 | 917 | ||
917 | init_usb_anchor(&priv->anchored); | 918 | init_usb_anchor(&priv->anchored); |
918 | priv->dev = dev; | 919 | priv->dev = dev; |
@@ -939,8 +940,7 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
939 | (7 << 21 /* MAX TX DMA */)); | 940 | (7 << 21 /* MAX TX DMA */)); |
940 | rtl8187_init_urbs(dev); | 941 | rtl8187_init_urbs(dev); |
941 | rtl8187b_init_status_urb(dev); | 942 | rtl8187b_init_status_urb(dev); |
942 | mutex_unlock(&priv->conf_mutex); | 943 | goto rtl8187_start_exit; |
943 | return 0; | ||
944 | } | 944 | } |
945 | 945 | ||
946 | rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); | 946 | rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); |
@@ -984,9 +984,10 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
984 | reg |= RTL818X_CMD_RX_ENABLE; | 984 | reg |= RTL818X_CMD_RX_ENABLE; |
985 | rtl818x_iowrite8(priv, &priv->map->CMD, reg); | 985 | rtl818x_iowrite8(priv, &priv->map->CMD, reg); |
986 | INIT_DELAYED_WORK(&priv->work, rtl8187_work); | 986 | INIT_DELAYED_WORK(&priv->work, rtl8187_work); |
987 | mutex_unlock(&priv->conf_mutex); | ||
988 | 987 | ||
989 | return 0; | 988 | rtl8187_start_exit: |
989 | mutex_unlock(&priv->conf_mutex); | ||
990 | return ret; | ||
990 | } | 991 | } |
991 | 992 | ||
992 | static void rtl8187_stop(struct ieee80211_hw *dev) | 993 | static void rtl8187_stop(struct ieee80211_hw *dev) |
@@ -1277,7 +1278,8 @@ static const struct ieee80211_ops rtl8187_ops = { | |||
1277 | .bss_info_changed = rtl8187_bss_info_changed, | 1278 | .bss_info_changed = rtl8187_bss_info_changed, |
1278 | .prepare_multicast = rtl8187_prepare_multicast, | 1279 | .prepare_multicast = rtl8187_prepare_multicast, |
1279 | .configure_filter = rtl8187_configure_filter, | 1280 | .configure_filter = rtl8187_configure_filter, |
1280 | .conf_tx = rtl8187_conf_tx | 1281 | .conf_tx = rtl8187_conf_tx, |
1282 | .rfkill_poll = rtl8187_rfkill_poll | ||
1281 | }; | 1283 | }; |
1282 | 1284 | ||
1283 | static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) | 1285 | static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) |
@@ -1517,6 +1519,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1517 | reg &= 0xFF; | 1519 | reg &= 0xFF; |
1518 | rtl8187_leds_init(dev, reg); | 1520 | rtl8187_leds_init(dev, reg); |
1519 | #endif | 1521 | #endif |
1522 | rtl8187_rfkill_init(dev); | ||
1520 | 1523 | ||
1521 | return 0; | 1524 | return 0; |
1522 | 1525 | ||
@@ -1540,6 +1543,7 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf) | |||
1540 | #ifdef CONFIG_RTL8187_LEDS | 1543 | #ifdef CONFIG_RTL8187_LEDS |
1541 | rtl8187_leds_exit(dev); | 1544 | rtl8187_leds_exit(dev); |
1542 | #endif | 1545 | #endif |
1546 | rtl8187_rfkill_exit(dev); | ||
1543 | ieee80211_unregister_hw(dev); | 1547 | ieee80211_unregister_hw(dev); |
1544 | 1548 | ||
1545 | priv = dev->priv; | 1549 | priv = dev->priv; |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c index a6cfb7e77994..a1c670fc1552 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c | |||
@@ -42,7 +42,7 @@ static void led_turn_on(struct work_struct *work) | |||
42 | mutex_lock(&priv->conf_mutex); | 42 | mutex_lock(&priv->conf_mutex); |
43 | switch (led->ledpin) { | 43 | switch (led->ledpin) { |
44 | case LED_PIN_GPIO0: | 44 | case LED_PIN_GPIO0: |
45 | rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01); | 45 | rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01); |
46 | rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00); | 46 | rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00); |
47 | break; | 47 | break; |
48 | case LED_PIN_LED0: | 48 | case LED_PIN_LED0: |
@@ -80,7 +80,7 @@ static void led_turn_off(struct work_struct *work) | |||
80 | mutex_lock(&priv->conf_mutex); | 80 | mutex_lock(&priv->conf_mutex); |
81 | switch (led->ledpin) { | 81 | switch (led->ledpin) { |
82 | case LED_PIN_GPIO0: | 82 | case LED_PIN_GPIO0: |
83 | rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01); | 83 | rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01); |
84 | rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01); | 84 | rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01); |
85 | break; | 85 | break; |
86 | case LED_PIN_LED0: | 86 | case LED_PIN_LED0: |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c new file mode 100644 index 000000000000..9fab13e4004e --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Linux RFKILL support for RTL8187 | ||
3 | * | ||
4 | * Copyright (c) 2009 Herton Ronaldo Krzesinski <herton@mandriva.com.br> | ||
5 | * | ||
6 | * Based on the RFKILL handling in the r8187 driver, which is: | ||
7 | * Copyright (c) Realtek Semiconductor Corp. All rights reserved. | ||
8 | * | ||
9 | * Thanks to Realtek for their support! | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/types.h> | ||
17 | #include <linux/usb.h> | ||
18 | #include <net/mac80211.h> | ||
19 | |||
20 | #include "rtl8187.h" | ||
21 | |||
22 | static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv) | ||
23 | { | ||
24 | u8 gpio; | ||
25 | |||
26 | gpio = rtl818x_ioread8(priv, &priv->map->GPIO0); | ||
27 | rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~0x02); | ||
28 | gpio = rtl818x_ioread8(priv, &priv->map->GPIO1); | ||
29 | |||
30 | return gpio & 0x02; | ||
31 | } | ||
32 | |||
33 | void rtl8187_rfkill_init(struct ieee80211_hw *hw) | ||
34 | { | ||
35 | struct rtl8187_priv *priv = hw->priv; | ||
36 | |||
37 | priv->rfkill_off = rtl8187_is_radio_enabled(priv); | ||
38 | printk(KERN_INFO "rtl8187: wireless switch is %s\n", | ||
39 | priv->rfkill_off ? "on" : "off"); | ||
40 | wiphy_rfkill_set_hw_state(hw->wiphy, !priv->rfkill_off); | ||
41 | wiphy_rfkill_start_polling(hw->wiphy); | ||
42 | } | ||
43 | |||
44 | void rtl8187_rfkill_poll(struct ieee80211_hw *hw) | ||
45 | { | ||
46 | bool enabled; | ||
47 | struct rtl8187_priv *priv = hw->priv; | ||
48 | |||
49 | mutex_lock(&priv->conf_mutex); | ||
50 | enabled = rtl8187_is_radio_enabled(priv); | ||
51 | if (unlikely(enabled != priv->rfkill_off)) { | ||
52 | priv->rfkill_off = enabled; | ||
53 | printk(KERN_INFO "rtl8187: wireless radio switch turned %s\n", | ||
54 | enabled ? "on" : "off"); | ||
55 | wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); | ||
56 | } | ||
57 | mutex_unlock(&priv->conf_mutex); | ||
58 | } | ||
59 | |||
60 | void rtl8187_rfkill_exit(struct ieee80211_hw *hw) | ||
61 | { | ||
62 | wiphy_rfkill_stop_polling(hw->wiphy); | ||
63 | } | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.h b/drivers/net/wireless/rtl818x/rtl8187_rfkill.h new file mode 100644 index 000000000000..e12575e96d11 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef RTL8187_RFKILL_H | ||
2 | #define RTL8187_RFKILL_H | ||
3 | |||
4 | void rtl8187_rfkill_init(struct ieee80211_hw *hw); | ||
5 | void rtl8187_rfkill_poll(struct ieee80211_hw *hw); | ||
6 | void rtl8187_rfkill_exit(struct ieee80211_hw *hw); | ||
7 | |||
8 | #endif /* RTL8187_RFKILL_H */ | ||
diff --git a/drivers/net/wireless/rtl818x/rtl818x.h b/drivers/net/wireless/rtl818x/rtl818x.h index 562222e6cf1f..8522490d2e29 100644 --- a/drivers/net/wireless/rtl818x/rtl818x.h +++ b/drivers/net/wireless/rtl818x/rtl818x.h | |||
@@ -138,8 +138,9 @@ struct rtl818x_csr { | |||
138 | __le32 RF_PARA; | 138 | __le32 RF_PARA; |
139 | __le32 RF_TIMING; | 139 | __le32 RF_TIMING; |
140 | u8 GP_ENABLE; | 140 | u8 GP_ENABLE; |
141 | u8 GPIO; | 141 | u8 GPIO0; |
142 | u8 reserved_12[2]; | 142 | u8 GPIO1; |
143 | u8 reserved_12; | ||
143 | __le32 HSSI_PARA; | 144 | __le32 HSSI_PARA; |
144 | u8 reserved_13[4]; | 145 | u8 reserved_13[4]; |
145 | u8 TX_AGC_CTL; | 146 | u8 TX_AGC_CTL; |