linux/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/led.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2009-2012  Realtek Corporation.*/
   3
   4#include "../wifi.h"
   5#include "../pci.h"
   6#include "reg.h"
   7#include "led.h"
   8
   9static void _rtl8723e_init_led(struct ieee80211_hw *hw,
  10                               struct rtl_led *pled, enum rtl_led_pin ledpin)
  11{
  12        pled->hw = hw;
  13        pled->ledpin = ledpin;
  14        pled->ledon = false;
  15}
  16
  17void rtl8723e_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
  18{
  19        u8 ledcfg;
  20        struct rtl_priv *rtlpriv = rtl_priv(hw);
  21
  22        rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD,
  23                "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
  24
  25        switch (pled->ledpin) {
  26        case LED_PIN_GPIO0:
  27                break;
  28        case LED_PIN_LED0:
  29                ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
  30                ledcfg &= ~BIT(6);
  31                rtl_write_byte(rtlpriv,
  32                               REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5));
  33                break;
  34        case LED_PIN_LED1:
  35                ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
  36                rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10);
  37                break;
  38        default:
  39                pr_err("switch case %#x not processed\n",
  40                       pled->ledpin);
  41                break;
  42        }
  43        pled->ledon = true;
  44}
  45
  46void rtl8723e_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
  47{
  48        struct rtl_priv *rtlpriv = rtl_priv(hw);
  49        u8 ledcfg;
  50
  51        rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD,
  52                "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
  53
  54        ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
  55
  56        switch (pled->ledpin) {
  57        case LED_PIN_GPIO0:
  58                break;
  59        case LED_PIN_LED0:
  60                ledcfg &= 0xf0;
  61                if (rtlpriv->ledctl.led_opendrain) {
  62                        ledcfg &= 0x90; /* Set to software control. */
  63                        rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3)));
  64                        ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
  65                        ledcfg &= 0xFE;
  66                        rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
  67                } else {
  68                        ledcfg &= ~BIT(6);
  69                        rtl_write_byte(rtlpriv, REG_LEDCFG2,
  70                                        (ledcfg | BIT(3) | BIT(5)));
  71                }
  72                break;
  73        case LED_PIN_LED1:
  74                ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
  75                ledcfg &= 0x10; /* Set to software control. */
  76                rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3));
  77
  78                break;
  79        default:
  80                pr_err("switch case %#x not processed\n",
  81                       pled->ledpin);
  82                break;
  83        }
  84        pled->ledon = false;
  85}
  86
  87void rtl8723e_init_sw_leds(struct ieee80211_hw *hw)
  88{
  89        struct rtl_priv *rtlpriv = rtl_priv(hw);
  90
  91        _rtl8723e_init_led(hw, &rtlpriv->ledctl.sw_led0, LED_PIN_LED0);
  92        _rtl8723e_init_led(hw, &rtlpriv->ledctl.sw_led1, LED_PIN_LED1);
  93}
  94
  95static void _rtl8723e_sw_led_control(struct ieee80211_hw *hw,
  96                                     enum led_ctl_mode ledaction)
  97{
  98        struct rtl_priv *rtlpriv = rtl_priv(hw);
  99        struct rtl_led *pled0 = &rtlpriv->ledctl.sw_led0;
 100
 101        switch (ledaction) {
 102        case LED_CTL_POWER_ON:
 103        case LED_CTL_LINK:
 104        case LED_CTL_NO_LINK:
 105                rtl8723e_sw_led_on(hw, pled0);
 106                break;
 107        case LED_CTL_POWER_OFF:
 108                rtl8723e_sw_led_off(hw, pled0);
 109                break;
 110        default:
 111                break;
 112        }
 113}
 114
 115void rtl8723e_led_control(struct ieee80211_hw *hw,
 116                          enum led_ctl_mode ledaction)
 117{
 118        struct rtl_priv *rtlpriv = rtl_priv(hw);
 119        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 120
 121        if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
 122            (ledaction == LED_CTL_TX ||
 123             ledaction == LED_CTL_RX ||
 124             ledaction == LED_CTL_SITE_SURVEY ||
 125             ledaction == LED_CTL_LINK ||
 126             ledaction == LED_CTL_NO_LINK ||
 127             ledaction == LED_CTL_START_TO_LINK ||
 128             ledaction == LED_CTL_POWER_ON)) {
 129                return;
 130        }
 131        rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n",
 132                ledaction);
 133        _rtl8723e_sw_led_control(hw, ledaction);
 134}
 135