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 9 static void _rtl92ce_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 17 void rtl92de_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 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", 23 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 31 if ((rtlpriv->efuse.eeprom_did == 0x8176) || 32 (rtlpriv->efuse.eeprom_did == 0x8193)) 33 /* BIT7 of REG_LEDCFG2 should be set to 34 * make sure we could emit the led2. */ 35 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) | 36 BIT(7) | BIT(5) | BIT(6)); 37 else 38 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) | 39 BIT(7) | BIT(5)); 40 break; 41 case LED_PIN_LED1: 42 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); 43 44 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); 45 break; 46 default: 47 pr_err("switch case %#x not processed\n", 48 pled->ledpin); 49 break; 50 } 51 pled->ledon = true; 52 } 53 54 void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) 55 { 56 struct rtl_priv *rtlpriv = rtl_priv(hw); 57 u8 ledcfg; 58 59 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", 60 REG_LEDCFG2, pled->ledpin); 61 62 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); 63 64 switch (pled->ledpin) { 65 case LED_PIN_GPIO0: 66 break; 67 case LED_PIN_LED0: 68 ledcfg &= 0xf0; 69 if (rtlpriv->ledctl.led_opendrain) 70 rtl_write_byte(rtlpriv, REG_LEDCFG2, 71 (ledcfg | BIT(1) | BIT(5) | BIT(6))); 72 else 73 rtl_write_byte(rtlpriv, REG_LEDCFG2, 74 (ledcfg | BIT(3) | BIT(5) | BIT(6))); 75 break; 76 case LED_PIN_LED1: 77 ledcfg &= 0x0f; 78 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); 79 break; 80 default: 81 pr_err("switch case %#x not processed\n", 82 pled->ledpin); 83 break; 84 } 85 pled->ledon = false; 86 } 87 88 void rtl92de_init_sw_leds(struct ieee80211_hw *hw) 89 { 90 struct rtl_priv *rtlpriv = rtl_priv(hw); 91 92 _rtl92ce_init_led(hw, &rtlpriv->ledctl.sw_led0, LED_PIN_LED0); 93 _rtl92ce_init_led(hw, &rtlpriv->ledctl.sw_led1, LED_PIN_LED1); 94 } 95 96 static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, 97 enum led_ctl_mode ledaction) 98 { 99 struct rtl_priv *rtlpriv = rtl_priv(hw); 100 struct rtl_led *pled0 = &rtlpriv->ledctl.sw_led0; 101 102 switch (ledaction) { 103 case LED_CTL_POWER_ON: 104 case LED_CTL_LINK: 105 case LED_CTL_NO_LINK: 106 rtl92de_sw_led_on(hw, pled0); 107 break; 108 case LED_CTL_POWER_OFF: 109 rtl92de_sw_led_off(hw, pled0); 110 break; 111 default: 112 break; 113 } 114 } 115 116 void rtl92de_led_control(struct ieee80211_hw *hw, 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 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction); 132 133 _rtl92ce_sw_led_control(hw, ledaction); 134 } 135