xref: /openbmc/linux/drivers/net/wireless/realtek/rtl818x/rtl8187/rfkill.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2f1d2b4d3SLarry Finger /*
3f1d2b4d3SLarry Finger  * Linux RFKILL support for RTL8187
4f1d2b4d3SLarry Finger  *
5f1d2b4d3SLarry Finger  * Copyright (c) 2009 Herton Ronaldo Krzesinski <herton@mandriva.com.br>
6f1d2b4d3SLarry Finger  *
7f1d2b4d3SLarry Finger  * Based on the RFKILL handling in the r8187 driver, which is:
8f1d2b4d3SLarry Finger  * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
9f1d2b4d3SLarry Finger  *
10f1d2b4d3SLarry Finger  * Thanks to Realtek for their support!
11f1d2b4d3SLarry Finger  */
12f1d2b4d3SLarry Finger 
13f1d2b4d3SLarry Finger #include <linux/types.h>
14f1d2b4d3SLarry Finger #include <linux/usb.h>
15f1d2b4d3SLarry Finger #include <net/mac80211.h>
16f1d2b4d3SLarry Finger 
17f1d2b4d3SLarry Finger #include "rtl8187.h"
18f1d2b4d3SLarry Finger #include "rfkill.h"
19f1d2b4d3SLarry Finger 
rtl8187_is_radio_enabled(struct rtl8187_priv * priv)20f1d2b4d3SLarry Finger static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv)
21f1d2b4d3SLarry Finger {
22f1d2b4d3SLarry Finger 	u8 gpio;
23f1d2b4d3SLarry Finger 
24f1d2b4d3SLarry Finger 	gpio = rtl818x_ioread8(priv, &priv->map->GPIO0);
25f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~priv->rfkill_mask);
26f1d2b4d3SLarry Finger 	gpio = rtl818x_ioread8(priv, &priv->map->GPIO1);
27f1d2b4d3SLarry Finger 
28f1d2b4d3SLarry Finger 	return gpio & priv->rfkill_mask;
29f1d2b4d3SLarry Finger }
30f1d2b4d3SLarry Finger 
rtl8187_rfkill_init(struct ieee80211_hw * hw)31f1d2b4d3SLarry Finger void rtl8187_rfkill_init(struct ieee80211_hw *hw)
32f1d2b4d3SLarry Finger {
33f1d2b4d3SLarry Finger 	struct rtl8187_priv *priv = hw->priv;
34f1d2b4d3SLarry Finger 
35f1d2b4d3SLarry Finger 	priv->rfkill_off = rtl8187_is_radio_enabled(priv);
36f1d2b4d3SLarry Finger 	printk(KERN_INFO "rtl8187: wireless switch is %s\n",
37f1d2b4d3SLarry Finger 	       priv->rfkill_off ? "on" : "off");
38f1d2b4d3SLarry Finger 	wiphy_rfkill_set_hw_state(hw->wiphy, !priv->rfkill_off);
39f1d2b4d3SLarry Finger 	wiphy_rfkill_start_polling(hw->wiphy);
40f1d2b4d3SLarry Finger }
41f1d2b4d3SLarry Finger 
rtl8187_rfkill_poll(struct ieee80211_hw * hw)42f1d2b4d3SLarry Finger void rtl8187_rfkill_poll(struct ieee80211_hw *hw)
43f1d2b4d3SLarry Finger {
44f1d2b4d3SLarry Finger 	bool enabled;
45f1d2b4d3SLarry Finger 	struct rtl8187_priv *priv = hw->priv;
46f1d2b4d3SLarry Finger 
47f1d2b4d3SLarry Finger 	mutex_lock(&priv->conf_mutex);
48f1d2b4d3SLarry Finger 	enabled = rtl8187_is_radio_enabled(priv);
49f1d2b4d3SLarry Finger 	if (unlikely(enabled != priv->rfkill_off)) {
50f1d2b4d3SLarry Finger 		priv->rfkill_off = enabled;
51f1d2b4d3SLarry Finger 		printk(KERN_INFO "rtl8187: wireless radio switch turned %s\n",
52f1d2b4d3SLarry Finger 		       enabled ? "on" : "off");
53f1d2b4d3SLarry Finger 		wiphy_rfkill_set_hw_state(hw->wiphy, !enabled);
54f1d2b4d3SLarry Finger 	}
55f1d2b4d3SLarry Finger 	mutex_unlock(&priv->conf_mutex);
56f1d2b4d3SLarry Finger }
57f1d2b4d3SLarry Finger 
rtl8187_rfkill_exit(struct ieee80211_hw * hw)58f1d2b4d3SLarry Finger void rtl8187_rfkill_exit(struct ieee80211_hw *hw)
59f1d2b4d3SLarry Finger {
60f1d2b4d3SLarry Finger 	wiphy_rfkill_stop_polling(hw->wiphy);
61f1d2b4d3SLarry Finger }
62