0001
0002
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);
0073 ledcfg &= ~(BIT(7) | BIT(6) | BIT(3) | BIT(2) | BIT(1) | BIT(0));
0074
0075 rtl_write_byte(rtlpriv, ledreg, ledcfg);
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;
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;
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
0142 if (rtlpriv->ledctl.led_opendrain) {
0143 u8 ledcfg = rtl_read_byte(rtlpriv, ledreg);
0144
0145 ledreg &= 0xd0;
0146 rtl_write_byte(rtlpriv, ledreg, (ledcfg | BIT(3)));
0147
0148
0149 ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
0150 ledcfg &= 0xFE;
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 }