Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

wifi: rtl8xxxu: Fix LED control code of RTL8192FU

Some devices, like the Comfast CF-826F, use LED1, which already works.
Others, like Asus USB-N13 C1, use LED0, which doesn't work correctly.

Write the right values to the LED control registers to make LED0 work
as well.

This is unfortunately tested only with the Comfast CF-826F.

Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://msgid.link/7a2c3158-3a45-4466-b11e-fc09802b20e2@gmail.com

authored by

Bitterblue Smith and committed by
Kalle Valo
9475cc7a 1cd165ad

+38 -9
+23 -9
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192f.c
··· 2014 2014 struct rtl8xxxu_priv *priv = container_of(led_cdev, 2015 2015 struct rtl8xxxu_priv, 2016 2016 led_cdev); 2017 - u16 ledcfg; 2017 + u32 ledcfg; 2018 2018 2019 2019 /* Values obtained by observing the USB traffic from the Windows driver. */ 2020 2020 rtl8xxxu_write32(priv, REG_SW_GPIO_SHARE_CTRL_0, 0x20080); 2021 2021 rtl8xxxu_write32(priv, REG_SW_GPIO_SHARE_CTRL_1, 0x1b0000); 2022 2022 2023 - ledcfg = rtl8xxxu_read16(priv, REG_LEDCFG0); 2023 + ledcfg = rtl8xxxu_read32(priv, REG_LEDCFG0); 2024 + 2025 + /* Comfast CF-826F uses LED1. Asus USB-N13 C1 uses LED0. Set both. */ 2026 + 2027 + u32p_replace_bits(&ledcfg, LED_GPIO_ENABLE, LEDCFG0_LED2EN); 2028 + u32p_replace_bits(&ledcfg, LED_IO_MODE_OUTPUT, LEDCFG0_LED0_IO_MODE); 2029 + u32p_replace_bits(&ledcfg, LED_IO_MODE_OUTPUT, LEDCFG0_LED1_IO_MODE); 2024 2030 2025 2031 if (brightness == LED_OFF) { 2026 - /* Value obtained like above. */ 2027 - ledcfg = BIT(1) | BIT(7); 2032 + u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED0CM); 2033 + u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED0SV); 2034 + u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED1CM); 2035 + u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED1SV); 2028 2036 } else if (brightness == LED_ON) { 2029 - /* Value obtained like above. */ 2030 - ledcfg = BIT(1) | BIT(7) | BIT(11); 2037 + u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED0CM); 2038 + u32p_replace_bits(&ledcfg, LED_SW_ON, LEDCFG0_LED0SV); 2039 + u32p_replace_bits(&ledcfg, LED_MODE_SW_CTRL, LEDCFG0_LED1CM); 2040 + u32p_replace_bits(&ledcfg, LED_SW_ON, LEDCFG0_LED1SV); 2031 2041 } else if (brightness == RTL8XXXU_HW_LED_CONTROL) { 2032 - /* Value obtained by brute force. */ 2033 - ledcfg = BIT(8) | BIT(9); 2042 + u32p_replace_bits(&ledcfg, LED_MODE_TX_OR_RX_EVENTS, 2043 + LEDCFG0_LED0CM); 2044 + u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED0SV); 2045 + u32p_replace_bits(&ledcfg, LED_MODE_TX_OR_RX_EVENTS, 2046 + LEDCFG0_LED1CM); 2047 + u32p_replace_bits(&ledcfg, LED_SW_OFF, LEDCFG0_LED1SV); 2034 2048 } 2035 2049 2036 - rtl8xxxu_write16(priv, REG_LEDCFG0, ledcfg); 2050 + rtl8xxxu_write32(priv, REG_LEDCFG0, ledcfg); 2037 2051 2038 2052 return 0; 2039 2053 }
+15
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
··· 146 146 #define GPIO_INTM_EDGE_TRIG_IRQ BIT(9) 147 147 148 148 #define REG_LEDCFG0 0x004c 149 + #define LEDCFG0_LED0CM GENMASK(2, 0) 150 + #define LEDCFG0_LED1CM GENMASK(10, 8) 151 + #define LED_MODE_SW_CTRL 0x0 152 + #define LED_MODE_TX_OR_RX_EVENTS 0x3 153 + #define LEDCFG0_LED0SV BIT(3) 154 + #define LEDCFG0_LED1SV BIT(11) 155 + #define LED_SW_OFF 0x0 156 + #define LED_SW_ON 0x1 157 + #define LEDCFG0_LED0_IO_MODE BIT(7) 158 + #define LEDCFG0_LED1_IO_MODE BIT(15) 159 + #define LED_IO_MODE_OUTPUT 0x0 160 + #define LED_IO_MODE_INPUT 0x1 161 + #define LEDCFG0_LED2EN BIT(21) 162 + #define LED_GPIO_DISABLE 0x0 163 + #define LED_GPIO_ENABLE 0x1 149 164 #define LEDCFG0_DPDT_SELECT BIT(23) 150 165 #define REG_LEDCFG1 0x004d 151 166 #define LEDCFG1_HW_LED_CONTROL BIT(1)