1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2026 Realtek Corporation
3 */
4
5 #include "core.h"
6 #include "debug.h"
7 #include "led.h"
8
rtw89_led_mc_brightness_set(struct led_classdev * led,enum led_brightness brightness)9 static int rtw89_led_mc_brightness_set(struct led_classdev *led,
10 enum led_brightness brightness)
11 {
12 struct led_classdev_mc *mcdev = lcdev_to_mccdev(led);
13 struct rtw89_led *rtw_led = container_of(mcdev, struct rtw89_led, led_mc);
14 struct rtw89_dev *rtwdev = container_of(rtw_led, struct rtw89_dev, led);
15 const struct rtw89_led_desc *desc = rtw_led->desc;
16 const struct rtw89_led_gpio_entry *e;
17 unsigned int i;
18
19 led_mc_calc_color_components(mcdev, brightness);
20
21 wiphy_lock(rtwdev->hw->wiphy);
22
23 for (i = 0; i < mcdev->num_colors; i++) {
24 e = &desc->gpios[i];
25 if (rtw_led->brightness_cache[i] == mcdev->subled_info[i].brightness) {
26 rtw89_debug(rtwdev, RTW89_DBG_LED,
27 "led_mc_set: pin=%u skip (no change)\n", e->pin);
28 continue;
29 }
30
31 rtw89_debug(rtwdev, RTW89_DBG_LED, "led_mc_set: pin=%u brightness=%u\n",
32 e->pin, mcdev->subled_info[i].brightness);
33 rtw89_led_gpio_set(rtwdev, e, mcdev->subled_info[i].brightness);
34 rtw_led->brightness_cache[i] = mcdev->subled_info[i].brightness;
35 }
36
37 wiphy_unlock(rtwdev->hw->wiphy);
38
39 return 0;
40 }
41
rtw89_led_mc_init(struct rtw89_dev * rtwdev,const struct rtw89_led_desc * desc)42 int rtw89_led_mc_init(struct rtw89_dev *rtwdev, const struct rtw89_led_desc *desc)
43 {
44 struct rtw89_led *rtw_led = &rtwdev->led;
45 struct led_classdev_mc *led_mc = &rtw_led->led_mc;
46 int i, ret;
47
48 led_mc->num_colors = desc->n_gpio;
49 led_mc->subled_info = rtw_led->subled;
50
51 for (i = 0; i < desc->n_gpio; i++) {
52 const struct rtw89_led_gpio_entry *e = &desc->gpios[i];
53
54 rtw_led->subled[i].color_index = e->color;
55 rtw_led->subled[i].intensity = e->intensity;
56 rtw_led->subled[i].brightness = 0;
57 rtw_led->subled[i].channel = i;
58
59 rtw89_led_gpio_config(rtwdev, e);
60 }
61
62 snprintf(rtw_led->name, sizeof(rtw_led->name), "rtw89-%s-multicolor",
63 wiphy_name(rtwdev->hw->wiphy));
64 led_mc->led_cdev.name = rtw_led->name;
65 led_mc->led_cdev.brightness_set_blocking = rtw89_led_mc_brightness_set;
66 led_mc->led_cdev.max_brightness = LED_ON;
67 led_mc->led_cdev.default_trigger = ieee80211_get_assoc_led_name(rtwdev->hw);
68
69 ret = led_classdev_multicolor_register(rtwdev->dev, led_mc);
70 if (ret)
71 rtw89_warn(rtwdev, "failed to register multicolor LED, ret=%d\n", ret);
72
73 return ret;
74 }
75
rtw89_led_mc_deinit(struct rtw89_dev * rtwdev)76 void rtw89_led_mc_deinit(struct rtw89_dev *rtwdev)
77 {
78 struct rtw89_led *rtw_led = &rtwdev->led;
79
80 led_classdev_multicolor_unregister(&rtw_led->led_mc);
81 }
82