Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
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_RTL8187)	+= rtl8187.o
+1 −0
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@ struct rtl8187_priv {
		__le16 bits16;
		__le32 bits32;
	} *io_dmabuf;
	bool rfkill_off;
};

void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
+16 −12
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#ifdef CONFIG_RTL8187_LEDS
#include "rtl8187_leds.h"
#endif
#include "rtl8187_rfkill.h"

MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
@@ -648,10 +649,10 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)

	/* setup card */
	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_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->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
@@ -674,11 +675,11 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)

	/* host_usb_init */
	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);
	rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7));
	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_iowrite16(priv, &priv->map->RFPinsOutput, 0x80);
	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80);
@@ -907,12 +908,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
	u32 reg;
	int ret;

	mutex_lock(&priv->conf_mutex);

	ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) :
				     rtl8187b_init_hw(dev);
	if (ret)
		return ret;

	mutex_lock(&priv->conf_mutex);
		goto rtl8187_start_exit;

	init_usb_anchor(&priv->anchored);
	priv->dev = dev;
@@ -939,8 +940,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
				  (7 << 21 /* MAX TX DMA */));
		rtl8187_init_urbs(dev);
		rtl8187b_init_status_urb(dev);
		mutex_unlock(&priv->conf_mutex);
		return 0;
		goto rtl8187_start_exit;
	}

	rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
@@ -984,9 +984,10 @@ static int rtl8187_start(struct ieee80211_hw *dev)
	reg |= RTL818X_CMD_RX_ENABLE;
	rtl818x_iowrite8(priv, &priv->map->CMD, reg);
	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)
@@ -1277,7 +1278,8 @@ static const struct ieee80211_ops rtl8187_ops = {
	.bss_info_changed	= rtl8187_bss_info_changed,
	.prepare_multicast	= rtl8187_prepare_multicast,
	.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)
@@ -1517,6 +1519,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
	reg &= 0xFF;
	rtl8187_leds_init(dev, reg);
#endif
	rtl8187_rfkill_init(dev);

	return 0;

@@ -1540,6 +1543,7 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf)
#ifdef CONFIG_RTL8187_LEDS
	rtl8187_leds_exit(dev);
#endif
	rtl8187_rfkill_exit(dev);
	ieee80211_unregister_hw(dev);

	priv = dev->priv;
+2 −2
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ static void led_turn_on(struct work_struct *work)
	mutex_lock(&priv->conf_mutex);
	switch (led->ledpin) {
	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);
		break;
	case LED_PIN_LED0:
@@ -80,7 +80,7 @@ static void led_turn_off(struct work_struct *work)
	mutex_lock(&priv->conf_mutex);
	switch (led->ledpin) {
	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);
		break;
	case LED_PIN_LED0:
+63 −0
Original line number Diff line number Diff line
/*
 * 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);
}
Loading