Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright(c) 2009-2010  Realtek Corporation.*/
0003 
0004 #include "../wifi.h"
0005 #include "../pci.h"
0006 #include "reg.h"
0007 #include "led.h"
0008 
0009 static void _rtl8821ae_init_led(struct ieee80211_hw *hw,
0010                 struct rtl_led *pled,
0011                 enum rtl_led_pin ledpin)
0012 {
0013     pled->hw = hw;
0014     pled->ledpin = ledpin;
0015     pled->ledon = false;
0016 }
0017 
0018 void rtl8821ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
0019 {
0020     u8 ledcfg;
0021     struct rtl_priv *rtlpriv = rtl_priv(hw);
0022 
0023     rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD,
0024         "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
0025 
0026     switch (pled->ledpin) {
0027     case LED_PIN_GPIO0:
0028         break;
0029     case LED_PIN_LED0:
0030         ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
0031         ledcfg &= ~BIT(6);
0032         rtl_write_byte(rtlpriv,
0033                    REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5));
0034         break;
0035     case LED_PIN_LED1:
0036         ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
0037         rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10);
0038         break;
0039     default:
0040         rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
0041             "switch case %#x not processed\n", pled->ledpin);
0042         break;
0043     }
0044     pled->ledon = true;
0045 }
0046 
0047 void rtl8812ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
0048 {
0049     u16 ledreg = REG_LEDCFG1;
0050     u8  ledcfg = 0;
0051     struct rtl_priv *rtlpriv = rtl_priv(hw);
0052 
0053     switch (pled->ledpin) {
0054     case LED_PIN_LED0:
0055         ledreg = REG_LEDCFG1;
0056         break;
0057 
0058     case LED_PIN_LED1:
0059         ledreg = REG_LEDCFG2;
0060         break;
0061 
0062     case LED_PIN_GPIO0:
0063     default:
0064         break;
0065     }
0066 
0067     rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD,
0068         "In SwLedOn, LedAddr:%X LEDPIN=%d\n",
0069         ledreg, pled->ledpin);
0070 
0071     ledcfg =  rtl_read_byte(rtlpriv, ledreg);
0072     ledcfg |= BIT(5); /*Set 0x4c[21]*/
0073     ledcfg &= ~(BIT(7) | BIT(6) | BIT(3) | BIT(2) | BIT(1) | BIT(0));
0074         /*Clear 0x4c[23:22] and 0x4c[19:16]*/
0075     rtl_write_byte(rtlpriv, ledreg, ledcfg); /*SW control led0 on.*/
0076     pled->ledon = true;
0077 }
0078 
0079 void rtl8821ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
0080 {
0081     struct rtl_priv *rtlpriv = rtl_priv(hw);
0082     u8 ledcfg;
0083 
0084     rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD,
0085         "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
0086 
0087     ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
0088 
0089     switch (pled->ledpin) {
0090     case LED_PIN_GPIO0:
0091         break;
0092     case LED_PIN_LED0:
0093         ledcfg &= 0xf0;
0094         if (rtlpriv->ledctl.led_opendrain) {
0095             ledcfg &= 0x90; /* Set to software control. */
0096             rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3)));
0097             ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
0098             ledcfg &= 0xFE;
0099             rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
0100         } else {
0101             ledcfg &= ~BIT(6);
0102             rtl_write_byte(rtlpriv, REG_LEDCFG2,
0103                        (ledcfg | BIT(3) | BIT(5)));
0104         }
0105         break;
0106     case LED_PIN_LED1:
0107         ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
0108         ledcfg &= 0x10; /* Set to software control. */
0109         rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3));
0110         break;
0111     default:
0112         rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
0113             "switch case %#x not processed\n", pled->ledpin);
0114         break;
0115     }
0116     pled->ledon = false;
0117 }
0118 
0119 void rtl8812ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
0120 {
0121     u16 ledreg = REG_LEDCFG1;
0122     struct rtl_priv *rtlpriv = rtl_priv(hw);
0123 
0124     switch (pled->ledpin) {
0125     case LED_PIN_LED0:
0126         ledreg = REG_LEDCFG1;
0127         break;
0128 
0129     case LED_PIN_LED1:
0130         ledreg = REG_LEDCFG2;
0131         break;
0132 
0133     case LED_PIN_GPIO0:
0134     default:
0135         break;
0136     }
0137 
0138     rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD,
0139         "In SwLedOff,LedAddr:%X LEDPIN=%d\n",
0140         ledreg, pled->ledpin);
0141     /*Open-drain arrangement for controlling the LED*/
0142     if (rtlpriv->ledctl.led_opendrain) {
0143         u8 ledcfg = rtl_read_byte(rtlpriv, ledreg);
0144 
0145         ledreg &= 0xd0; /* Set to software control.*/
0146         rtl_write_byte(rtlpriv, ledreg, (ledcfg | BIT(3)));
0147 
0148         /*Open-drain arrangement*/
0149         ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
0150         ledcfg &= 0xFE;/*Set GPIO[8] to input mode*/
0151         rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
0152     } else {
0153         rtl_write_byte(rtlpriv, ledreg, 0x28);
0154     }
0155 
0156     pled->ledon = false;
0157 }
0158 
0159 void rtl8821ae_init_sw_leds(struct ieee80211_hw *hw)
0160 {
0161     struct rtl_priv *rtlpriv = rtl_priv(hw);
0162 
0163     _rtl8821ae_init_led(hw, &rtlpriv->ledctl.sw_led0, LED_PIN_LED0);
0164     _rtl8821ae_init_led(hw, &rtlpriv->ledctl.sw_led1, LED_PIN_LED1);
0165 }
0166 
0167 static void _rtl8821ae_sw_led_control(struct ieee80211_hw *hw,
0168                       enum led_ctl_mode ledaction)
0169 {
0170     struct rtl_priv *rtlpriv = rtl_priv(hw);
0171     struct rtl_led *pled0 = &rtlpriv->ledctl.sw_led0;
0172     struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0173 
0174     switch (ledaction) {
0175     case LED_CTL_POWER_ON:
0176     case LED_CTL_LINK:
0177     case LED_CTL_NO_LINK:
0178         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
0179             rtl8812ae_sw_led_on(hw, pled0);
0180         else
0181             rtl8821ae_sw_led_on(hw, pled0);
0182         break;
0183     case LED_CTL_POWER_OFF:
0184         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
0185             rtl8812ae_sw_led_off(hw, pled0);
0186         else
0187             rtl8821ae_sw_led_off(hw, pled0);
0188         break;
0189     default:
0190         break;
0191     }
0192 }
0193 
0194 void rtl8821ae_led_control(struct ieee80211_hw *hw,
0195                enum led_ctl_mode ledaction)
0196 {
0197     struct rtl_priv *rtlpriv = rtl_priv(hw);
0198     struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
0199 
0200     if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
0201         (ledaction == LED_CTL_TX ||
0202          ledaction == LED_CTL_RX ||
0203          ledaction == LED_CTL_SITE_SURVEY ||
0204          ledaction == LED_CTL_LINK ||
0205          ledaction == LED_CTL_NO_LINK ||
0206          ledaction == LED_CTL_START_TO_LINK ||
0207          ledaction == LED_CTL_POWER_ON)) {
0208         return;
0209     }
0210     rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n",
0211         ledaction);
0212     _rtl8821ae_sw_led_control(hw, ledaction);
0213 }