192 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 2009-2010 Realtek Corporation.*/3 4#include "../wifi.h"5#include "../pci.h"6#include "reg.h"7#include "led.h"8 9void 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 37void 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 68void 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 107void 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 145static 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 else159 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 else165 rtl8821ae_sw_led_off(hw, pin0);166 break;167 default:168 break;169 }170}171 172void 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