162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2009-2010 Realtek Corporation.*/ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "../wifi.h" 562306a36Sopenharmony_ci#include "../pci.h" 662306a36Sopenharmony_ci#include "reg.h" 762306a36Sopenharmony_ci#include "led.h" 862306a36Sopenharmony_ci 962306a36Sopenharmony_civoid rtl8821ae_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) 1062306a36Sopenharmony_ci{ 1162306a36Sopenharmony_ci u8 ledcfg; 1262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, 1562306a36Sopenharmony_ci "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci switch (pin) { 1862306a36Sopenharmony_ci case LED_PIN_GPIO0: 1962306a36Sopenharmony_ci break; 2062306a36Sopenharmony_ci case LED_PIN_LED0: 2162306a36Sopenharmony_ci ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); 2262306a36Sopenharmony_ci ledcfg &= ~BIT(6); 2362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 2462306a36Sopenharmony_ci REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5)); 2562306a36Sopenharmony_ci break; 2662306a36Sopenharmony_ci case LED_PIN_LED1: 2762306a36Sopenharmony_ci ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); 2862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10); 2962306a36Sopenharmony_ci break; 3062306a36Sopenharmony_ci default: 3162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 3262306a36Sopenharmony_ci "switch case %#x not processed\n", pin); 3362306a36Sopenharmony_ci break; 3462306a36Sopenharmony_ci } 3562306a36Sopenharmony_ci} 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_civoid rtl8812ae_sw_led_on(struct ieee80211_hw *hw, enum rtl_led_pin pin) 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci u16 ledreg = REG_LEDCFG1; 4062306a36Sopenharmony_ci u8 ledcfg = 0; 4162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci switch (pin) { 4462306a36Sopenharmony_ci case LED_PIN_LED0: 4562306a36Sopenharmony_ci ledreg = REG_LEDCFG1; 4662306a36Sopenharmony_ci break; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci case LED_PIN_LED1: 4962306a36Sopenharmony_ci ledreg = REG_LEDCFG2; 5062306a36Sopenharmony_ci break; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci case LED_PIN_GPIO0: 5362306a36Sopenharmony_ci default: 5462306a36Sopenharmony_ci break; 5562306a36Sopenharmony_ci } 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, 5862306a36Sopenharmony_ci "In SwLedOn, LedAddr:%X LEDPIN=%d\n", 5962306a36Sopenharmony_ci ledreg, pin); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci ledcfg = rtl_read_byte(rtlpriv, ledreg); 6262306a36Sopenharmony_ci ledcfg |= BIT(5); /*Set 0x4c[21]*/ 6362306a36Sopenharmony_ci ledcfg &= ~(BIT(7) | BIT(6) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); 6462306a36Sopenharmony_ci /*Clear 0x4c[23:22] and 0x4c[19:16]*/ 6562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ledreg, ledcfg); /*SW control led0 on.*/ 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_civoid rtl8821ae_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 7162306a36Sopenharmony_ci u8 ledcfg; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, 7462306a36Sopenharmony_ci "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pin); 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci switch (pin) { 7962306a36Sopenharmony_ci case LED_PIN_GPIO0: 8062306a36Sopenharmony_ci break; 8162306a36Sopenharmony_ci case LED_PIN_LED0: 8262306a36Sopenharmony_ci ledcfg &= 0xf0; 8362306a36Sopenharmony_ci if (rtlpriv->ledctl.led_opendrain) { 8462306a36Sopenharmony_ci ledcfg &= 0x90; /* Set to software control. */ 8562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3))); 8662306a36Sopenharmony_ci ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG); 8762306a36Sopenharmony_ci ledcfg &= 0xFE; 8862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg); 8962306a36Sopenharmony_ci } else { 9062306a36Sopenharmony_ci ledcfg &= ~BIT(6); 9162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LEDCFG2, 9262306a36Sopenharmony_ci (ledcfg | BIT(3) | BIT(5))); 9362306a36Sopenharmony_ci } 9462306a36Sopenharmony_ci break; 9562306a36Sopenharmony_ci case LED_PIN_LED1: 9662306a36Sopenharmony_ci ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); 9762306a36Sopenharmony_ci ledcfg &= 0x10; /* Set to software control. */ 9862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3)); 9962306a36Sopenharmony_ci break; 10062306a36Sopenharmony_ci default: 10162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 10262306a36Sopenharmony_ci "switch case %#x not processed\n", pin); 10362306a36Sopenharmony_ci break; 10462306a36Sopenharmony_ci } 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_civoid rtl8812ae_sw_led_off(struct ieee80211_hw *hw, enum rtl_led_pin pin) 10862306a36Sopenharmony_ci{ 10962306a36Sopenharmony_ci u16 ledreg = REG_LEDCFG1; 11062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci switch (pin) { 11362306a36Sopenharmony_ci case LED_PIN_LED0: 11462306a36Sopenharmony_ci ledreg = REG_LEDCFG1; 11562306a36Sopenharmony_ci break; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci case LED_PIN_LED1: 11862306a36Sopenharmony_ci ledreg = REG_LEDCFG2; 11962306a36Sopenharmony_ci break; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci case LED_PIN_GPIO0: 12262306a36Sopenharmony_ci default: 12362306a36Sopenharmony_ci break; 12462306a36Sopenharmony_ci } 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, 12762306a36Sopenharmony_ci "In SwLedOff,LedAddr:%X LEDPIN=%d\n", 12862306a36Sopenharmony_ci ledreg, pin); 12962306a36Sopenharmony_ci /*Open-drain arrangement for controlling the LED*/ 13062306a36Sopenharmony_ci if (rtlpriv->ledctl.led_opendrain) { 13162306a36Sopenharmony_ci u8 ledcfg = rtl_read_byte(rtlpriv, ledreg); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci ledreg &= 0xd0; /* Set to software control.*/ 13462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ledreg, (ledcfg | BIT(3))); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci /*Open-drain arrangement*/ 13762306a36Sopenharmony_ci ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG); 13862306a36Sopenharmony_ci ledcfg &= 0xFE;/*Set GPIO[8] to input mode*/ 13962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg); 14062306a36Sopenharmony_ci } else { 14162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ledreg, 0x28); 14262306a36Sopenharmony_ci } 14362306a36Sopenharmony_ci} 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistatic void _rtl8821ae_sw_led_control(struct ieee80211_hw *hw, 14662306a36Sopenharmony_ci enum led_ctl_mode ledaction) 14762306a36Sopenharmony_ci{ 14862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 14962306a36Sopenharmony_ci enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; 15062306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci switch (ledaction) { 15362306a36Sopenharmony_ci case LED_CTL_POWER_ON: 15462306a36Sopenharmony_ci case LED_CTL_LINK: 15562306a36Sopenharmony_ci case LED_CTL_NO_LINK: 15662306a36Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 15762306a36Sopenharmony_ci rtl8812ae_sw_led_on(hw, pin0); 15862306a36Sopenharmony_ci else 15962306a36Sopenharmony_ci rtl8821ae_sw_led_on(hw, pin0); 16062306a36Sopenharmony_ci break; 16162306a36Sopenharmony_ci case LED_CTL_POWER_OFF: 16262306a36Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 16362306a36Sopenharmony_ci rtl8812ae_sw_led_off(hw, pin0); 16462306a36Sopenharmony_ci else 16562306a36Sopenharmony_ci rtl8821ae_sw_led_off(hw, pin0); 16662306a36Sopenharmony_ci break; 16762306a36Sopenharmony_ci default: 16862306a36Sopenharmony_ci break; 16962306a36Sopenharmony_ci } 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_civoid rtl8821ae_led_control(struct ieee80211_hw *hw, 17362306a36Sopenharmony_ci enum led_ctl_mode ledaction) 17462306a36Sopenharmony_ci{ 17562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 17662306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && 17962306a36Sopenharmony_ci (ledaction == LED_CTL_TX || 18062306a36Sopenharmony_ci ledaction == LED_CTL_RX || 18162306a36Sopenharmony_ci ledaction == LED_CTL_SITE_SURVEY || 18262306a36Sopenharmony_ci ledaction == LED_CTL_LINK || 18362306a36Sopenharmony_ci ledaction == LED_CTL_NO_LINK || 18462306a36Sopenharmony_ci ledaction == LED_CTL_START_TO_LINK || 18562306a36Sopenharmony_ci ledaction == LED_CTL_POWER_ON)) { 18662306a36Sopenharmony_ci return; 18762306a36Sopenharmony_ci } 18862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", 18962306a36Sopenharmony_ci ledaction); 19062306a36Sopenharmony_ci _rtl8821ae_sw_led_control(hw, ledaction); 19162306a36Sopenharmony_ci} 192