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 Fingerstatic 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 Fingervoid 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 Fingervoid 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 Fingervoid rtl8187_rfkill_exit(struct ieee80211_hw *hw) 59f1d2b4d3SLarry Finger { 60f1d2b4d3SLarry Finger wiphy_rfkill_stop_polling(hw->wiphy); 61f1d2b4d3SLarry Finger } 62