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 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 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 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