Commit ca9152e3 authored by Herton Ronaldo Krzesinski's avatar Herton Ronaldo Krzesinski Committed by John W. Linville

rtl8187: Implement rfkill support

This change implements rfkill support for RTL8187B and RTL8187L devices,
using new cfg80211 rfkill API.
Acked-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Tested-by: default avatarHin-Tak Leung <htl10@users.sourceforge.net>
Signed-off-by: default avatarHerton Ronaldo Krzesinski <herton@mandriva.com.br>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 6a8171f2
rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o rtl8187_rfkill.o
obj-$(CONFIG_RTL8180) += rtl8180.o obj-$(CONFIG_RTL8180) += rtl8180.o
obj-$(CONFIG_RTL8187) += rtl8187.o obj-$(CONFIG_RTL8187) += rtl8187.o
......
...@@ -133,6 +133,7 @@ struct rtl8187_priv { ...@@ -133,6 +133,7 @@ struct rtl8187_priv {
__le16 bits16; __le16 bits16;
__le32 bits32; __le32 bits32;
} *io_dmabuf; } *io_dmabuf;
bool rfkill_off;
}; };
void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#ifdef CONFIG_RTL8187_LEDS #ifdef CONFIG_RTL8187_LEDS
#include "rtl8187_leds.h" #include "rtl8187_leds.h"
#endif #endif
#include "rtl8187_rfkill.h"
MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
...@@ -648,10 +649,10 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev) ...@@ -648,10 +649,10 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
/* setup card */ /* setup card */
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
rtl818x_iowrite8(priv, &priv->map->GPIO, 0); rtl818x_iowrite8(priv, &priv->map->GPIO0, 0);
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
rtl818x_iowrite8(priv, &priv->map->GPIO, 1); rtl818x_iowrite8(priv, &priv->map->GPIO0, 1);
rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 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,11 +675,11 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
/* host_usb_init */ /* host_usb_init */
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
rtl818x_iowrite8(priv, &priv->map->GPIO, 0); rtl818x_iowrite8(priv, &priv->map->GPIO0, 0);
reg = rtl818x_ioread8(priv, (u8 *)0xFE53); reg = rtl818x_ioread8(priv, (u8 *)0xFE53);
rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7)); rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7));
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
rtl818x_iowrite8(priv, &priv->map->GPIO, 0x20); rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x20);
rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80); rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80);
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80); rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80);
...@@ -907,12 +908,12 @@ static int rtl8187_start(struct ieee80211_hw *dev) ...@@ -907,12 +908,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
u32 reg; u32 reg;
int ret; int ret;
mutex_lock(&priv->conf_mutex);
ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) : ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) :
rtl8187b_init_hw(dev); rtl8187b_init_hw(dev);
if (ret) if (ret)
return ret; goto rtl8187_start_exit;
mutex_lock(&priv->conf_mutex);
init_usb_anchor(&priv->anchored); init_usb_anchor(&priv->anchored);
priv->dev = dev; priv->dev = dev;
...@@ -939,8 +940,7 @@ static int rtl8187_start(struct ieee80211_hw *dev) ...@@ -939,8 +940,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
(7 << 21 /* MAX TX DMA */)); (7 << 21 /* MAX TX DMA */));
rtl8187_init_urbs(dev); rtl8187_init_urbs(dev);
rtl8187b_init_status_urb(dev); rtl8187b_init_status_urb(dev);
mutex_unlock(&priv->conf_mutex); goto rtl8187_start_exit;
return 0;
} }
rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
...@@ -984,9 +984,10 @@ static int rtl8187_start(struct ieee80211_hw *dev) ...@@ -984,9 +984,10 @@ static int rtl8187_start(struct ieee80211_hw *dev)
reg |= RTL818X_CMD_RX_ENABLE; reg |= RTL818X_CMD_RX_ENABLE;
rtl818x_iowrite8(priv, &priv->map->CMD, reg); rtl818x_iowrite8(priv, &priv->map->CMD, reg);
INIT_DELAYED_WORK(&priv->work, rtl8187_work); INIT_DELAYED_WORK(&priv->work, rtl8187_work);
mutex_unlock(&priv->conf_mutex);
return 0; rtl8187_start_exit:
mutex_unlock(&priv->conf_mutex);
return ret;
} }
static void rtl8187_stop(struct ieee80211_hw *dev) static void rtl8187_stop(struct ieee80211_hw *dev)
...@@ -1277,7 +1278,8 @@ static const struct ieee80211_ops rtl8187_ops = { ...@@ -1277,7 +1278,8 @@ static const struct ieee80211_ops rtl8187_ops = {
.bss_info_changed = rtl8187_bss_info_changed, .bss_info_changed = rtl8187_bss_info_changed,
.prepare_multicast = rtl8187_prepare_multicast, .prepare_multicast = rtl8187_prepare_multicast,
.configure_filter = rtl8187_configure_filter, .configure_filter = rtl8187_configure_filter,
.conf_tx = rtl8187_conf_tx .conf_tx = rtl8187_conf_tx,
.rfkill_poll = rtl8187_rfkill_poll
}; };
static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
...@@ -1517,6 +1519,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, ...@@ -1517,6 +1519,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
reg &= 0xFF; reg &= 0xFF;
rtl8187_leds_init(dev, reg); rtl8187_leds_init(dev, reg);
#endif #endif
rtl8187_rfkill_init(dev);
return 0; return 0;
...@@ -1540,6 +1543,7 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf) ...@@ -1540,6 +1543,7 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf)
#ifdef CONFIG_RTL8187_LEDS #ifdef CONFIG_RTL8187_LEDS
rtl8187_leds_exit(dev); rtl8187_leds_exit(dev);
#endif #endif
rtl8187_rfkill_exit(dev);
ieee80211_unregister_hw(dev); ieee80211_unregister_hw(dev);
priv = dev->priv; priv = dev->priv;
......
...@@ -42,7 +42,7 @@ static void led_turn_on(struct work_struct *work) ...@@ -42,7 +42,7 @@ static void led_turn_on(struct work_struct *work)
mutex_lock(&priv->conf_mutex); mutex_lock(&priv->conf_mutex);
switch (led->ledpin) { switch (led->ledpin) {
case LED_PIN_GPIO0: case LED_PIN_GPIO0:
rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01); rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01);
rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00); rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00);
break; break;
case LED_PIN_LED0: case LED_PIN_LED0:
...@@ -80,7 +80,7 @@ static void led_turn_off(struct work_struct *work) ...@@ -80,7 +80,7 @@ static void led_turn_off(struct work_struct *work)
mutex_lock(&priv->conf_mutex); mutex_lock(&priv->conf_mutex);
switch (led->ledpin) { switch (led->ledpin) {
case LED_PIN_GPIO0: case LED_PIN_GPIO0:
rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01); rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01);
rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01); rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01);
break; break;
case LED_PIN_LED0: case LED_PIN_LED0:
......
/*
* Linux RFKILL support for RTL8187
*
* Copyright (c) 2009 Herton Ronaldo Krzesinski <herton@mandriva.com.br>
*
* Based on the RFKILL handling in the r8187 driver, which is:
* Copyright (c) Realtek Semiconductor Corp. All rights reserved.
*
* Thanks to Realtek for their support!
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/types.h>
#include <linux/usb.h>
#include <net/mac80211.h>
#include "rtl8187.h"
static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv)
{
u8 gpio;
gpio = rtl818x_ioread8(priv, &priv->map->GPIO0);
rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~0x02);
gpio = rtl818x_ioread8(priv, &priv->map->GPIO1);
return gpio & 0x02;
}
void rtl8187_rfkill_init(struct ieee80211_hw *hw)
{
struct rtl8187_priv *priv = hw->priv;
priv->rfkill_off = rtl8187_is_radio_enabled(priv);
printk(KERN_INFO "rtl8187: wireless switch is %s\n",
priv->rfkill_off ? "on" : "off");
wiphy_rfkill_set_hw_state(hw->wiphy, !priv->rfkill_off);
wiphy_rfkill_start_polling(hw->wiphy);
}
void rtl8187_rfkill_poll(struct ieee80211_hw *hw)
{
bool enabled;
struct rtl8187_priv *priv = hw->priv;
mutex_lock(&priv->conf_mutex);
enabled = rtl8187_is_radio_enabled(priv);
if (unlikely(enabled != priv->rfkill_off)) {
priv->rfkill_off = enabled;
printk(KERN_INFO "rtl8187: wireless radio switch turned %s\n",
enabled ? "on" : "off");
wiphy_rfkill_set_hw_state(hw->wiphy, !enabled);
}
mutex_unlock(&priv->conf_mutex);
}
void rtl8187_rfkill_exit(struct ieee80211_hw *hw)
{
wiphy_rfkill_stop_polling(hw->wiphy);
}
#ifndef RTL8187_RFKILL_H
#define RTL8187_RFKILL_H
void rtl8187_rfkill_init(struct ieee80211_hw *hw);
void rtl8187_rfkill_poll(struct ieee80211_hw *hw);
void rtl8187_rfkill_exit(struct ieee80211_hw *hw);
#endif /* RTL8187_RFKILL_H */
...@@ -138,8 +138,9 @@ struct rtl818x_csr { ...@@ -138,8 +138,9 @@ struct rtl818x_csr {
__le32 RF_PARA; __le32 RF_PARA;
__le32 RF_TIMING; __le32 RF_TIMING;
u8 GP_ENABLE; u8 GP_ENABLE;
u8 GPIO; u8 GPIO0;
u8 reserved_12[2]; u8 GPIO1;
u8 reserved_12;
__le32 HSSI_PARA; __le32 HSSI_PARA;
u8 reserved_13[4]; u8 reserved_13[4];
u8 TX_AGC_CTL; u8 TX_AGC_CTL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment