1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright(c) 2009-2010 Realtek Corporation.*/ 3 4 #include "../wifi.h" 5 #include "../pci.h" 6 #include "reg.h" 7 #include "led.h" 8 9 void rtl8821ae_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) 10 { 11 u8 ledcfg; 12 struct rtl_priv *rtlpriv = rtl_priv(hw); 13 14 rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, 15 "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); 16 17 switch (pin) { 18 case LED_PIN_GPIO0: 19 break; 20 case LED_PIN_LED0: 21 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); 22 ledcfg &= ~BIT(6); 23 rtl_write_byte(rtlpriv, 24 REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5)); 25 break; 26 case LED_PIN_LED1: 27 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); 28 rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10); 29 break; 30 default: 31 rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 32 "switch case %#x not processed\n", pin); 33 break; 34 } 35 } 36 37 void rtl8812ae_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) 38 { 39 u16 ledreg = REG_LEDCFG1; 40 u8 ledcfg = 0; 41 struct rtl_priv *rtlpriv = rtl_priv(hw); 42 43 switch (pin) { 44 case LED_PIN_LED0: 45 ledreg = REG_LEDCFG1; 46 break; 47 48 case LED_PIN_LED1: 49 ledreg = REG_LEDCFG2; 50 break; 51 52 case LED_PIN_GPIO0: 53 default: 54 break; 55 } 56 57 rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, 58 "In SwLedOn, LedAddr:%X LEDPIN=%d\n", 59 ledreg, pin); 60 61 ledcfg = rtl_read_byte(rtlpriv, ledreg); 62 ledcfg |= BIT(5); /*Set 0x4c[21]*/ 63 ledcfg &= ~(BIT(7) | BIT(6) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); 64 /*Clear 0x4c[23:22] and 0x4c[19:16]*/ 65 rtl_write_byte(rtlpriv, ledreg, ledcfg); /*SW control led0 on.*/ 66 } 67 68 void rtl8821ae_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) 69 { 70 struct rtl_priv *rtlpriv = rtl_priv(hw); 71 u8 ledcfg; 72 73 rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, 74 "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); 75 76 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); 77 78 switch (pin) { 79 case LED_PIN_GPIO0: 80 break; 81 case LED_PIN_LED0: 82 ledcfg &= 0xf0; 83 if (rtlpriv->ledctl.led_opendrain) { 84 ledcfg &= 0x90; /* Set to software control. */ 85 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3))); 86 ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG); 87 ledcfg &= 0xFE; 88 rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg); 89 } else { 90 ledcfg &= ~BIT(6); 91 rtl_write_byte(rtlpriv, REG_LEDCFG2, 92 (ledcfg | BIT(3) | BIT(5))); 93 } 94 break; 95 case LED_PIN_LED1: 96 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); 97 ledcfg &= 0x10; /* Set to software control. */ 98 rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3)); 99 break; 100 default: 101 rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 102 "switch case %#x not processed\n", pin); 103 break; 104 } 105 } 106 107 void rtl8812ae_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) 108 { 109 u16 ledreg = REG_LEDCFG1; 110 struct rtl_priv *rtlpriv = rtl_priv(hw); 111 112 switch (pin) { 113 case LED_PIN_LED0: 114 ledreg = REG_LEDCFG1; 115 break; 116 117 case LED_PIN_LED1: 118 ledreg = REG_LEDCFG2; 119 break; 120 121 case LED_PIN_GPIO0: 122 default: 123 break; 124 } 125 126 rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, 127 "In SwLedOff,LedAddr:%X LEDPIN=%d\n", 128 ledreg, pin); 129 /*Open-drain arrangement for controlling the LED*/ 130 if (rtlpriv->ledctl.led_opendrain) { 131 u8 ledcfg = rtl_read_byte(rtlpriv, ledreg); 132 133 ledreg &= 0xd0; /* Set to software control.*/ 134 rtl_write_byte(rtlpriv, ledreg, (ledcfg | BIT(3))); 135 136 /*Open-drain arrangement*/ 137 ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG); 138 ledcfg &= 0xFE;/*Set GPIO[8] to input mode*/ 139 rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg); 140 } else { 141 rtl_write_byte(rtlpriv, ledreg, 0x28); 142 } 143 } 144 145 static void _rtl8821ae_sw_led_control(struct ieee80211_hw *hw, 146 enum led_ctl_mode ledaction) 147 { 148 struct rtl_priv *rtlpriv = rtl_priv(hw); 149 enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; 150 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 151 152 switch (ledaction) { 153 case LED_CTL_POWER_ON: 154 case LED_CTL_LINK: 155 case LED_CTL_NO_LINK: 156 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 157 rtl8812ae_sw_led_on(hw, pin0); 158 else 159 rtl8821ae_sw_led_on(hw, pin0); 160 break; 161 case LED_CTL_POWER_OFF: 162 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 163 rtl8812ae_sw_led_off(hw, pin0); 164 else 165 rtl8821ae_sw_led_off(hw, pin0); 166 break; 167 default: 168 break; 169 } 170 } 171 172 void rtl8821ae_led_control(struct ieee80211_hw *hw, 173 enum led_ctl_mode ledaction) 174 { 175 struct rtl_priv *rtlpriv = rtl_priv(hw); 176 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 177 178 if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && 179 (ledaction == LED_CTL_TX || 180 ledaction == LED_CTL_RX || 181 ledaction == LED_CTL_SITE_SURVEY || 182 ledaction == LED_CTL_LINK || 183 ledaction == LED_CTL_NO_LINK || 184 ledaction == LED_CTL_START_TO_LINK || 185 ledaction == LED_CTL_POWER_ON)) { 186 return; 187 } 188 rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", 189 ledaction); 190 _rtl8821ae_sw_led_control(hw, ledaction); 191 } 192