1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2010 Realtek Corporation.*/
9 static void _rtl8821ae_init_led(struct ieee80211_hw
*hw
,
11 enum rtl_led_pin ledpin
)
14 pled
->ledpin
= ledpin
;
18 void rtl8821ae_sw_led_on(struct ieee80211_hw
*hw
, struct rtl_led
*pled
)
21 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
23 RT_TRACE(rtlpriv
, COMP_LED
, DBG_LOUD
,
24 "LedAddr:%X ledpin=%d\n", REG_LEDCFG2
, pled
->ledpin
);
26 switch (pled
->ledpin
) {
30 ledcfg
= rtl_read_byte(rtlpriv
, REG_LEDCFG2
);
32 rtl_write_byte(rtlpriv
,
33 REG_LEDCFG2
, (ledcfg
& 0xf0) | BIT(5));
36 ledcfg
= rtl_read_byte(rtlpriv
, REG_LEDCFG1
);
37 rtl_write_byte(rtlpriv
, REG_LEDCFG1
, ledcfg
& 0x10);
40 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_LOUD
,
41 "switch case %#x not processed\n", pled
->ledpin
);
47 void rtl8812ae_sw_led_on(struct ieee80211_hw
*hw
, struct rtl_led
*pled
)
49 u16 ledreg
= REG_LEDCFG1
;
51 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
53 switch (pled
->ledpin
) {
67 RT_TRACE(rtlpriv
, COMP_LED
, DBG_LOUD
,
68 "In SwLedOn, LedAddr:%X LEDPIN=%d\n",
69 ledreg
, pled
->ledpin
);
71 ledcfg
= rtl_read_byte(rtlpriv
, ledreg
);
72 ledcfg
|= BIT(5); /*Set 0x4c[21]*/
73 ledcfg
&= ~(BIT(7) | BIT(6) | BIT(3) | BIT(2) | BIT(1) | BIT(0));
74 /*Clear 0x4c[23:22] and 0x4c[19:16]*/
75 rtl_write_byte(rtlpriv
, ledreg
, ledcfg
); /*SW control led0 on.*/
79 void rtl8821ae_sw_led_off(struct ieee80211_hw
*hw
, struct rtl_led
*pled
)
81 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
84 RT_TRACE(rtlpriv
, COMP_LED
, DBG_LOUD
,
85 "LedAddr:%X ledpin=%d\n", REG_LEDCFG2
, pled
->ledpin
);
87 ledcfg
= rtl_read_byte(rtlpriv
, REG_LEDCFG2
);
89 switch (pled
->ledpin
) {
94 if (rtlpriv
->ledctl
.led_opendrain
) {
95 ledcfg
&= 0x90; /* Set to software control. */
96 rtl_write_byte(rtlpriv
, REG_LEDCFG2
, (ledcfg
|BIT(3)));
97 ledcfg
= rtl_read_byte(rtlpriv
, REG_MAC_PINMUX_CFG
);
99 rtl_write_byte(rtlpriv
, REG_MAC_PINMUX_CFG
, ledcfg
);
102 rtl_write_byte(rtlpriv
, REG_LEDCFG2
,
103 (ledcfg
| BIT(3) | BIT(5)));
107 ledcfg
= rtl_read_byte(rtlpriv
, REG_LEDCFG1
);
108 ledcfg
&= 0x10; /* Set to software control. */
109 rtl_write_byte(rtlpriv
, REG_LEDCFG1
, ledcfg
|BIT(3));
112 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_LOUD
,
113 "switch case %#x not processed\n", pled
->ledpin
);
119 void rtl8812ae_sw_led_off(struct ieee80211_hw
*hw
, struct rtl_led
*pled
)
121 u16 ledreg
= REG_LEDCFG1
;
122 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
124 switch (pled
->ledpin
) {
126 ledreg
= REG_LEDCFG1
;
130 ledreg
= REG_LEDCFG2
;
138 RT_TRACE(rtlpriv
, COMP_LED
, DBG_LOUD
,
139 "In SwLedOff,LedAddr:%X LEDPIN=%d\n",
140 ledreg
, pled
->ledpin
);
141 /*Open-drain arrangement for controlling the LED*/
142 if (rtlpriv
->ledctl
.led_opendrain
) {
143 u8 ledcfg
= rtl_read_byte(rtlpriv
, ledreg
);
145 ledreg
&= 0xd0; /* Set to software control.*/
146 rtl_write_byte(rtlpriv
, ledreg
, (ledcfg
| BIT(3)));
148 /*Open-drain arrangement*/
149 ledcfg
= rtl_read_byte(rtlpriv
, REG_MAC_PINMUX_CFG
);
150 ledcfg
&= 0xFE;/*Set GPIO[8] to input mode*/
151 rtl_write_byte(rtlpriv
, REG_MAC_PINMUX_CFG
, ledcfg
);
153 rtl_write_byte(rtlpriv
, ledreg
, 0x28);
159 void rtl8821ae_init_sw_leds(struct ieee80211_hw
*hw
)
161 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
163 _rtl8821ae_init_led(hw
, &rtlpriv
->ledctl
.sw_led0
, LED_PIN_LED0
);
164 _rtl8821ae_init_led(hw
, &rtlpriv
->ledctl
.sw_led1
, LED_PIN_LED1
);
167 static void _rtl8821ae_sw_led_control(struct ieee80211_hw
*hw
,
168 enum led_ctl_mode ledaction
)
170 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
171 struct rtl_led
*pled0
= &rtlpriv
->ledctl
.sw_led0
;
172 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
175 case LED_CTL_POWER_ON
:
177 case LED_CTL_NO_LINK
:
178 if (rtlhal
->hw_type
== HARDWARE_TYPE_RTL8812AE
)
179 rtl8812ae_sw_led_on(hw
, pled0
);
181 rtl8821ae_sw_led_on(hw
, pled0
);
183 case LED_CTL_POWER_OFF
:
184 if (rtlhal
->hw_type
== HARDWARE_TYPE_RTL8812AE
)
185 rtl8812ae_sw_led_off(hw
, pled0
);
187 rtl8821ae_sw_led_off(hw
, pled0
);
194 void rtl8821ae_led_control(struct ieee80211_hw
*hw
,
195 enum led_ctl_mode ledaction
)
197 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
198 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
200 if ((ppsc
->rfoff_reason
> RF_CHANGE_BY_PS
) &&
201 (ledaction
== LED_CTL_TX
||
202 ledaction
== LED_CTL_RX
||
203 ledaction
== LED_CTL_SITE_SURVEY
||
204 ledaction
== LED_CTL_LINK
||
205 ledaction
== LED_CTL_NO_LINK
||
206 ledaction
== LED_CTL_START_TO_LINK
||
207 ledaction
== LED_CTL_POWER_ON
)) {
210 RT_TRACE(rtlpriv
, COMP_LED
, DBG_LOUD
, "ledaction %d,\n",
212 _rtl8821ae_sw_led_control(hw
, ledaction
);