瀏覽代碼

rt2x00: Add RFKILL support to rt2500usb and rt73usb

Some very rare Ralink USB hardware exists which features
the RFKILL switch on the USB stick.
This patch adds the EEPROM check function to see if RFKILL
is supported and the polling function to rt2500usb and
rt73usb in order to support RFKILL for that hardware.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Ivo van Doorn 16 年之前
父節點
當前提交
7396faf4f3

+ 21 - 0
drivers/net/wireless/rt2x00/rt2500usb.c

@@ -280,6 +280,18 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = {
 };
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
 
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+	u16 reg;
+
+	rt2500usb_register_read(rt2x00dev, MAC_CSR19, &reg);
+	return rt2x00_get_field32(reg, MAC_CSR19_BIT7);
+}
+#else
+#define rt2500usb_rfkill_poll	NULL
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
 #ifdef CONFIG_RT2X00_LIB_LEDS
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt2500usb_brightness_set(struct led_classdev *led_cdev,
 static void rt2500usb_brightness_set(struct led_classdev *led_cdev,
 				     enum led_brightness brightness)
 				     enum led_brightness brightness)
@@ -1596,6 +1608,14 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
 				   LED_TYPE_ACTIVITY);
 				   LED_TYPE_ACTIVITY);
 #endif /* CONFIG_RT2X00_LIB_LEDS */
 #endif /* CONFIG_RT2X00_LIB_LEDS */
 
 
+	/*
+	 * Detect if this device has an hardware controlled radio.
+	 */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
 	/*
 	/*
 	 * Check if the BBP tuning should be disabled.
 	 * Check if the BBP tuning should be disabled.
 	 */
 	 */
@@ -1902,6 +1922,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
 	.uninitialize		= rt2x00usb_uninitialize,
 	.uninitialize		= rt2x00usb_uninitialize,
 	.clear_entry		= rt2x00usb_clear_entry,
 	.clear_entry		= rt2x00usb_clear_entry,
 	.set_device_state	= rt2500usb_set_device_state,
 	.set_device_state	= rt2500usb_set_device_state,
+	.rfkill_poll		= rt2500usb_rfkill_poll,
 	.link_stats		= rt2500usb_link_stats,
 	.link_stats		= rt2500usb_link_stats,
 	.reset_tuner		= rt2500usb_reset_tuner,
 	.reset_tuner		= rt2500usb_reset_tuner,
 	.link_tuner		= rt2500usb_link_tuner,
 	.link_tuner		= rt2500usb_link_tuner,

+ 8 - 0
drivers/net/wireless/rt2x00/rt2500usb.h

@@ -189,6 +189,14 @@
  * MAC_CSR19: GPIO control register.
  * MAC_CSR19: GPIO control register.
  */
  */
 #define MAC_CSR19			0x0426
 #define MAC_CSR19			0x0426
+#define MAC_CSR19_BIT0			FIELD32(0x0001)
+#define MAC_CSR19_BIT1			FIELD32(0x0002)
+#define MAC_CSR19_BIT2			FIELD32(0x0004)
+#define MAC_CSR19_BIT3			FIELD32(0x0008)
+#define MAC_CSR19_BIT4			FIELD32(0x0010)
+#define MAC_CSR19_BIT5			FIELD32(0x0020)
+#define MAC_CSR19_BIT6			FIELD32(0x0040)
+#define MAC_CSR19_BIT7			FIELD32(0x0080)
 
 
 /*
 /*
  * MAC_CSR20: LED control register.
  * MAC_CSR20: LED control register.

+ 21 - 0
drivers/net/wireless/rt2x00/rt73usb.c

@@ -186,6 +186,18 @@ static const struct rt2x00debug rt73usb_rt2x00debug = {
 };
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
 
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+
+	rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
+	return rt2x00_get_field32(reg, MAC_CSR13_BIT7);
+}
+#else
+#define rt73usb_rfkill_poll	NULL
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
 #ifdef CONFIG_RT2X00_LIB_LEDS
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt73usb_brightness_set(struct led_classdev *led_cdev,
 static void rt73usb_brightness_set(struct led_classdev *led_cdev,
 				   enum led_brightness brightness)
 				   enum led_brightness brightness)
@@ -1852,6 +1864,14 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE))
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE))
 		__set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
 		__set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
 
 
+	/*
+	 * Detect if this device has an hardware controlled radio.
+	 */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
 	/*
 	/*
 	 * Read frequency offset.
 	 * Read frequency offset.
 	 */
 	 */
@@ -2257,6 +2277,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
 	.uninitialize		= rt2x00usb_uninitialize,
 	.uninitialize		= rt2x00usb_uninitialize,
 	.clear_entry		= rt2x00usb_clear_entry,
 	.clear_entry		= rt2x00usb_clear_entry,
 	.set_device_state	= rt73usb_set_device_state,
 	.set_device_state	= rt73usb_set_device_state,
+	.rfkill_poll		= rt73usb_rfkill_poll,
 	.link_stats		= rt73usb_link_stats,
 	.link_stats		= rt73usb_link_stats,
 	.reset_tuner		= rt73usb_reset_tuner,
 	.reset_tuner		= rt73usb_reset_tuner,
 	.link_tuner		= rt73usb_link_tuner,
 	.link_tuner		= rt73usb_link_tuner,

+ 13 - 0
drivers/net/wireless/rt2x00/rt73usb.h

@@ -267,6 +267,19 @@ struct hw_pairwise_ta_entry {
  * MAC_CSR13: GPIO.
  * MAC_CSR13: GPIO.
  */
  */
 #define MAC_CSR13			0x3034
 #define MAC_CSR13			0x3034
+#define MAC_CSR13_BIT0			FIELD32(0x00000001)
+#define MAC_CSR13_BIT1			FIELD32(0x00000002)
+#define MAC_CSR13_BIT2			FIELD32(0x00000004)
+#define MAC_CSR13_BIT3			FIELD32(0x00000008)
+#define MAC_CSR13_BIT4			FIELD32(0x00000010)
+#define MAC_CSR13_BIT5			FIELD32(0x00000020)
+#define MAC_CSR13_BIT6			FIELD32(0x00000040)
+#define MAC_CSR13_BIT7			FIELD32(0x00000080)
+#define MAC_CSR13_BIT8			FIELD32(0x00000100)
+#define MAC_CSR13_BIT9			FIELD32(0x00000200)
+#define MAC_CSR13_BIT10			FIELD32(0x00000400)
+#define MAC_CSR13_BIT11			FIELD32(0x00000800)
+#define MAC_CSR13_BIT12			FIELD32(0x00001000)
 
 
 /*
 /*
  * MAC_CSR14: LED control register.
  * MAC_CSR14: LED control register.