aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerton Ronaldo Krzesinski <herton@mandriva.com.br>2009-08-26 12:54:09 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-28 14:40:52 -0400
commitca9152e37f57259ca92486ca5753af16fd9155c6 (patch)
tree90b36f241e67ae2decf7043d78249591b09ad707
parent6a8171f261eec3577c2a5985e3a2b51377e48931 (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/Makefile2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c28
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.c4
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rfkill.c63
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rfkill.h8
-rw-r--r--drivers/net/wireless/rtl818x/rtl818x.h5
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 @@
1rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o 1rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
2rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o 2rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o rtl8187_rfkill.o
3 3
4obj-$(CONFIG_RTL8180) += rtl8180.o 4obj-$(CONFIG_RTL8180) += rtl8180.o
5obj-$(CONFIG_RTL8187) += rtl8187.o 5obj-$(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
138void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); 139void 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
36MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); 37MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
37MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); 38MODULE_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; 988rtl8187_start_exit:
989 mutex_unlock(&priv->conf_mutex);
990 return ret;
990} 991}
991 992
992static void rtl8187_stop(struct ieee80211_hw *dev) 993static 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
1283static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) 1285static 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
22static 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
33void 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
44void 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
60void 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
4void rtl8187_rfkill_init(struct ieee80211_hw *hw);
5void rtl8187_rfkill_poll(struct ieee80211_hw *hw);
6void 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;